windows-nt/Source/XPSP1/NT/base/win32/fusion/sxs/sxsntrtl.cpp

208 lines
4.7 KiB
C++
Raw Normal View History

2020-09-26 03:20:57 -05:00
#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
}