208 lines
4.7 KiB
C++
208 lines
4.7 KiB
C++
#include "stdinc.h"
|
|
#include "sxsp.h"
|
|
#include "windows.h"
|
|
#include "ntexapi.h"
|
|
|
|
#define HASH_ALGORITHM HASH_STRING_ALGORITHM_X65599
|
|
|
|
ULONG
|
|
SxspSetLastNTError(
|
|
NTSTATUS Status
|
|
);
|
|
|
|
BOOL
|
|
SxspGetAssemblyRootDirectoryHelper(
|
|
SIZE_T CchBuffer,
|
|
WCHAR Buffer[],
|
|
SIZE_T *CchWritten
|
|
)
|
|
{
|
|
UNICODE_STRING Src, Dst;
|
|
NTSTATUS Status;
|
|
ULONG Length = 0;
|
|
BOOL fSuccess = FALSE;
|
|
|
|
::FusionpDbgPrintEx(
|
|
FUSION_DBG_LEVEL_ENTEREXIT,
|
|
"SXS.DLL: Entering SxspGetAssemblyRootDirectoryHelper()\n");
|
|
|
|
if ((CchBuffer == 0) && (CchWritten == NULL))
|
|
{
|
|
::SxspSetLastNTError(STATUS_INVALID_PARAMETER);
|
|
goto Exit;
|
|
}
|
|
|
|
if ((CchBuffer != 0) && (Buffer == NULL))
|
|
{
|
|
::SxspSetLastNTError(STATUS_INVALID_PARAMETER);
|
|
goto Exit;
|
|
}
|
|
|
|
Dst.Length = 0;
|
|
|
|
if (CchBuffer != 0)
|
|
Dst.MaximumLength = static_cast<USHORT>((CchBuffer - 1) * sizeof(WCHAR));
|
|
else
|
|
Dst.MaximumLength = 0;
|
|
|
|
Dst.Buffer = Buffer;
|
|
|
|
Src.Buffer = (PWSTR) g_AlternateAssemblyStoreRoot;
|
|
|
|
if (Src.Buffer != NULL)
|
|
{
|
|
Src.Length = (USHORT) (wcslen(Src.Buffer) * sizeof(WCHAR));
|
|
Src.MaximumLength = Src.Length;
|
|
}
|
|
else
|
|
{
|
|
Src.Buffer = L"%SystemRoot%\\WinSxS\\";
|
|
Src.Length = sizeof(L"%SystemRoot%\\WinSxS\\") - sizeof(WCHAR);
|
|
Src.MaximumLength = Src.Length;
|
|
}
|
|
|
|
Status = ::FusionpRtlExpandEnvironmentStrings_U(NULL, &Src, &Dst, &Length);
|
|
if (!NT_SUCCESS(Status))
|
|
{
|
|
if (Status != STATUS_BUFFER_TOO_SMALL)
|
|
{
|
|
::FusionpDbgPrintEx(
|
|
FUSION_DBG_LEVEL_ERROR,
|
|
"SXS.DLL: Unable to expand environment strings; NTSTATUS = 0x%08lx\n", Status);
|
|
|
|
SxspSetLastNTError(Status);
|
|
goto Exit;
|
|
}
|
|
|
|
if (CchWritten != NULL)
|
|
*CchWritten = (Length / sizeof(WCHAR));
|
|
|
|
goto Exit;
|
|
}
|
|
else
|
|
{
|
|
Dst.Buffer[Dst.Length / sizeof(WCHAR)] = UNICODE_NULL;
|
|
|
|
if (CchWritten != NULL)
|
|
*CchWritten = Dst.Length / sizeof(WCHAR);
|
|
}
|
|
|
|
fSuccess = TRUE;
|
|
|
|
Exit:
|
|
if (fSuccess)
|
|
::FusionpDbgPrintEx(
|
|
FUSION_DBG_LEVEL_ENTEREXIT,
|
|
"SXS.DLL: SxspGetAssemblyRootDirectoryHelper() successful; exiting function.\n");
|
|
else
|
|
{
|
|
if (::FusionpGetLastWin32Error() != ERROR_INSUFFICIENT_BUFFER)
|
|
{
|
|
::FusionpDbgPrintEx(
|
|
FUSION_DBG_LEVEL_ERROREXITPATH,
|
|
"SXS.DLL: SxspGetAssemblyRootDirectoryHelper() failed; ::FusionpGetLastWin32Error() = %d\n", ::FusionpGetLastWin32Error());
|
|
}
|
|
}
|
|
|
|
return fSuccess;
|
|
}
|
|
|
|
ULONG
|
|
SxspSetLastNTError(
|
|
NTSTATUS Status
|
|
)
|
|
{
|
|
ULONG dwErrorCode;
|
|
dwErrorCode = ::FusionpRtlNtStatusToDosError(Status);
|
|
::FusionpSetLastWin32Error(dwErrorCode);
|
|
return dwErrorCode;
|
|
}
|
|
|
|
BOOL
|
|
SxspHashString(
|
|
PCWSTR String,
|
|
SIZE_T cch,
|
|
PULONG HashValue,
|
|
bool CaseInsensitive
|
|
)
|
|
{
|
|
UNICODE_STRING s;
|
|
NTSTATUS Status = STATUS_SUCCESS;
|
|
|
|
s.MaximumLength = static_cast<USHORT>(cch * sizeof(WCHAR));
|
|
s.Length = s.MaximumLength;
|
|
s.Buffer = const_cast<PWSTR>(String);
|
|
|
|
Status = ::FusionpRtlHashUnicodeString(&s, CaseInsensitive, HASH_ALGORITHM, HashValue);
|
|
if (!NT_SUCCESS(Status))
|
|
::SxspSetLastNTError(Status);
|
|
|
|
return (NT_SUCCESS(Status));
|
|
}
|
|
|
|
ULONG
|
|
SxspGetHashAlgorithm(VOID)
|
|
{
|
|
return HASH_ALGORITHM;
|
|
}
|
|
|
|
BOOL
|
|
SxspCreateLocallyUniqueId(
|
|
OUT PSXSP_LOCALLY_UNIQUE_ID psxsLuid
|
|
)
|
|
{
|
|
BOOL fSuccess = FALSE;
|
|
NTSTATUS status;
|
|
|
|
status = ::FusionpNtAllocateLocallyUniqueId(&psxsLuid->Luid);
|
|
if (!NT_SUCCESS(status))
|
|
{
|
|
::SxspSetLastNTError(status);
|
|
goto Exit;
|
|
}
|
|
psxsLuid->Type = esxspLuid;
|
|
fSuccess = TRUE;
|
|
Exit:
|
|
return fSuccess;
|
|
}
|
|
|
|
BOOL
|
|
SxspFormatLocallyUniqueId(
|
|
IN const SXSP_LOCALLY_UNIQUE_ID &rsxsLuid,
|
|
OUT CBaseStringBuffer &rbuffUidBuffer
|
|
)
|
|
{
|
|
FN_PROLOG_WIN32
|
|
|
|
switch (rsxsLuid.Type)
|
|
{
|
|
case esxspGuid:
|
|
IFW32FALSE_EXIT(::SxspFormatGUID(rsxsLuid.Guid, rbuffUidBuffer));
|
|
break;
|
|
|
|
case esxspLuid:
|
|
{
|
|
ULARGE_INTEGER uli;
|
|
CStringBufferAccessor acc;
|
|
|
|
uli.LowPart = rsxsLuid.Luid.LowPart;
|
|
uli.HighPart = rsxsLuid.Luid.HighPart;
|
|
|
|
IFW32FALSE_EXIT(rbuffUidBuffer.Win32ResizeBuffer(sizeof(ULONGLONG) * CHAR_BIT, eDoNotPreserveBufferContents));
|
|
|
|
// better to have all digits, no minus sign probably, for consistent names
|
|
acc.Attach(&rbuffUidBuffer);
|
|
|
|
//
|
|
// This would be a good place to use RtlInt64ToUnicodeString, at least
|
|
// #if !SXSP_DOWNLEVEL..
|
|
//
|
|
_ui64tow(uli.QuadPart, acc.GetBufferPtr(), 10);
|
|
acc.Detach();
|
|
break;
|
|
}
|
|
}
|
|
|
|
FN_EPILOG
|
|
}
|