#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((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(cch * sizeof(WCHAR)); s.Length = s.MaximumLength; s.Buffer = const_cast(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 }