You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
179 lines
4.2 KiB
179 lines
4.2 KiB
/*
|
|
Copyright (c) Microsoft Corporation
|
|
*/
|
|
#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
|
|
)
|
|
{
|
|
BOOL fSuccess = FALSE;
|
|
const PCWSTR NtSystemRoot = USER_SHARED_DATA->NtSystemRoot;
|
|
const SIZE_T cchSystemRoot = wcslen(NtSystemRoot);
|
|
#define SLASH_WINSXS_SLASH L"\\WinSxS\\"
|
|
const SIZE_T cch = cchSystemRoot + (NUMBER_OF(SLASH_WINSXS_SLASH) - 1);
|
|
|
|
if ((CchBuffer == 0) && (CchWritten == NULL))
|
|
{
|
|
::SxspSetLastNTError(STATUS_INVALID_PARAMETER);
|
|
goto Exit;
|
|
}
|
|
|
|
if ((CchBuffer != 0) && (Buffer == NULL))
|
|
{
|
|
::SxspSetLastNTError(STATUS_INVALID_PARAMETER);
|
|
goto Exit;
|
|
}
|
|
|
|
if (cch > CchBuffer)
|
|
{
|
|
if (CchWritten != NULL)
|
|
{
|
|
*CchWritten = cch;
|
|
}
|
|
if (Buffer != NULL)
|
|
{
|
|
::SxspSetLastNTError(STATUS_BUFFER_TOO_SMALL);
|
|
}
|
|
else
|
|
{
|
|
fSuccess = TRUE;
|
|
}
|
|
goto Exit;
|
|
}
|
|
|
|
memcpy(Buffer, NtSystemRoot, cchSystemRoot * sizeof(WCHAR));
|
|
memcpy(Buffer + cchSystemRoot, SLASH_WINSXS_SLASH, sizeof(SLASH_WINSXS_SLASH));
|
|
|
|
fSuccess = TRUE;
|
|
Exit:
|
|
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));
|
|
// check for overflow
|
|
if (s.MaximumLength != (cch * sizeof(WCHAR)))
|
|
{
|
|
::SxspSetLastNTError(STATUS_NAME_TOO_LONG);
|
|
return FALSE;
|
|
}
|
|
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
|
|
)
|
|
{
|
|
FN_PROLOG_WIN32
|
|
static WORD s_wMilliseconds = 0;
|
|
static ULONG s_ulUniquification = 0;
|
|
SYSTEMTIME stLocalTime;
|
|
|
|
PARAMETER_CHECK(psxsLuid != NULL);
|
|
|
|
GetSystemTime(&stLocalTime);
|
|
IFW32FALSE_EXIT(SystemTimeToTzSpecificLocalTime(NULL, &stLocalTime, &psxsLuid->stTimeStamp));
|
|
|
|
if (psxsLuid->stTimeStamp.wMilliseconds == s_wMilliseconds)
|
|
{
|
|
s_ulUniquification = ::SxspInterlockedIncrement(&s_ulUniquification);
|
|
}
|
|
else
|
|
{
|
|
s_wMilliseconds = psxsLuid->stTimeStamp.wMilliseconds;
|
|
s_ulUniquification = 0;
|
|
}
|
|
|
|
psxsLuid->ulUniquifier = s_ulUniquification;
|
|
|
|
FN_EPILOG
|
|
}
|
|
|
|
#define CHARS_IN_TIMESTAMP (4 + (2*5) + 3 + 10) // 8 * 4 + 4
|
|
|
|
BOOL
|
|
SxspFormatLocallyUniqueId(
|
|
IN const SXSP_LOCALLY_UNIQUE_ID &rsxsLuid,
|
|
OUT CBaseStringBuffer &rbuffUidBuffer
|
|
)
|
|
{
|
|
FN_PROLOG_WIN32
|
|
|
|
if (rbuffUidBuffer.GetBufferCb() < CHARS_IN_TIMESTAMP)
|
|
{
|
|
IFW32FALSE_EXIT(rbuffUidBuffer.Win32ResizeBuffer(
|
|
CHARS_IN_TIMESTAMP,
|
|
eDoNotPreserveBufferContents));
|
|
}
|
|
else
|
|
{
|
|
//
|
|
// The caller may have previously grown the buffer
|
|
// larger because they are putting in the
|
|
// unique id followed by additional text. Don't
|
|
// change the size on them.
|
|
//
|
|
}
|
|
|
|
IFW32FALSE_EXIT(rbuffUidBuffer.Win32Format(
|
|
L"%04u%02u%02u%02u%02u%02u%03u.%u",
|
|
rsxsLuid.stTimeStamp.wYear,
|
|
rsxsLuid.stTimeStamp.wMonth,
|
|
rsxsLuid.stTimeStamp.wDay,
|
|
rsxsLuid.stTimeStamp.wHour,
|
|
rsxsLuid.stTimeStamp.wMinute,
|
|
rsxsLuid.stTimeStamp.wSecond,
|
|
rsxsLuid.stTimeStamp.wMilliseconds,
|
|
rsxsLuid.ulUniquifier));
|
|
|
|
FN_EPILOG
|
|
}
|