|
|
#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 }
|