Leaked source code of windows server 2003
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

  1. /*
  2. Copyright (c) Microsoft Corporation
  3. */
  4. #include "stdinc.h"
  5. #include "sxsp.h"
  6. #include "windows.h"
  7. #include "ntexapi.h"
  8. #define HASH_ALGORITHM HASH_STRING_ALGORITHM_X65599
  9. ULONG
  10. SxspSetLastNTError(
  11. NTSTATUS Status
  12. );
  13. BOOL
  14. SxspGetAssemblyRootDirectoryHelper(
  15. SIZE_T CchBuffer,
  16. WCHAR Buffer[],
  17. SIZE_T *CchWritten
  18. )
  19. {
  20. BOOL fSuccess = FALSE;
  21. const PCWSTR NtSystemRoot = USER_SHARED_DATA->NtSystemRoot;
  22. const SIZE_T cchSystemRoot = wcslen(NtSystemRoot);
  23. #define SLASH_WINSXS_SLASH L"\\WinSxS\\"
  24. const SIZE_T cch = cchSystemRoot + (NUMBER_OF(SLASH_WINSXS_SLASH) - 1);
  25. if ((CchBuffer == 0) && (CchWritten == NULL))
  26. {
  27. ::SxspSetLastNTError(STATUS_INVALID_PARAMETER);
  28. goto Exit;
  29. }
  30. if ((CchBuffer != 0) && (Buffer == NULL))
  31. {
  32. ::SxspSetLastNTError(STATUS_INVALID_PARAMETER);
  33. goto Exit;
  34. }
  35. if (cch > CchBuffer)
  36. {
  37. if (CchWritten != NULL)
  38. {
  39. *CchWritten = cch;
  40. }
  41. if (Buffer != NULL)
  42. {
  43. ::SxspSetLastNTError(STATUS_BUFFER_TOO_SMALL);
  44. }
  45. else
  46. {
  47. fSuccess = TRUE;
  48. }
  49. goto Exit;
  50. }
  51. memcpy(Buffer, NtSystemRoot, cchSystemRoot * sizeof(WCHAR));
  52. memcpy(Buffer + cchSystemRoot, SLASH_WINSXS_SLASH, sizeof(SLASH_WINSXS_SLASH));
  53. fSuccess = TRUE;
  54. Exit:
  55. return fSuccess;
  56. }
  57. ULONG
  58. SxspSetLastNTError(
  59. NTSTATUS Status
  60. )
  61. {
  62. ULONG dwErrorCode;
  63. dwErrorCode = ::FusionpRtlNtStatusToDosError(Status);
  64. ::FusionpSetLastWin32Error(dwErrorCode);
  65. return dwErrorCode;
  66. }
  67. BOOL
  68. SxspHashString(
  69. PCWSTR String,
  70. SIZE_T cch,
  71. PULONG HashValue,
  72. bool CaseInsensitive
  73. )
  74. {
  75. UNICODE_STRING s;
  76. NTSTATUS Status = STATUS_SUCCESS;
  77. s.MaximumLength = static_cast<USHORT>(cch * sizeof(WCHAR));
  78. // check for overflow
  79. if (s.MaximumLength != (cch * sizeof(WCHAR)))
  80. {
  81. ::SxspSetLastNTError(STATUS_NAME_TOO_LONG);
  82. return FALSE;
  83. }
  84. s.Length = s.MaximumLength;
  85. s.Buffer = const_cast<PWSTR>(String);
  86. Status = ::FusionpRtlHashUnicodeString(&s, CaseInsensitive, HASH_ALGORITHM, HashValue);
  87. if (!NT_SUCCESS(Status))
  88. ::SxspSetLastNTError(Status);
  89. return (NT_SUCCESS(Status));
  90. }
  91. ULONG
  92. SxspGetHashAlgorithm(VOID)
  93. {
  94. return HASH_ALGORITHM;
  95. }
  96. BOOL
  97. SxspCreateLocallyUniqueId(
  98. OUT PSXSP_LOCALLY_UNIQUE_ID psxsLuid
  99. )
  100. {
  101. FN_PROLOG_WIN32
  102. static WORD s_wMilliseconds = 0;
  103. static ULONG s_ulUniquification = 0;
  104. SYSTEMTIME stLocalTime;
  105. PARAMETER_CHECK(psxsLuid != NULL);
  106. GetSystemTime(&stLocalTime);
  107. IFW32FALSE_EXIT(SystemTimeToTzSpecificLocalTime(NULL, &stLocalTime, &psxsLuid->stTimeStamp));
  108. if (psxsLuid->stTimeStamp.wMilliseconds == s_wMilliseconds)
  109. {
  110. s_ulUniquification = ::SxspInterlockedIncrement(&s_ulUniquification);
  111. }
  112. else
  113. {
  114. s_wMilliseconds = psxsLuid->stTimeStamp.wMilliseconds;
  115. s_ulUniquification = 0;
  116. }
  117. psxsLuid->ulUniquifier = s_ulUniquification;
  118. FN_EPILOG
  119. }
  120. #define CHARS_IN_TIMESTAMP (4 + (2*5) + 3 + 10) // 8 * 4 + 4
  121. BOOL
  122. SxspFormatLocallyUniqueId(
  123. IN const SXSP_LOCALLY_UNIQUE_ID &rsxsLuid,
  124. OUT CBaseStringBuffer &rbuffUidBuffer
  125. )
  126. {
  127. FN_PROLOG_WIN32
  128. if (rbuffUidBuffer.GetBufferCb() < CHARS_IN_TIMESTAMP)
  129. {
  130. IFW32FALSE_EXIT(rbuffUidBuffer.Win32ResizeBuffer(
  131. CHARS_IN_TIMESTAMP,
  132. eDoNotPreserveBufferContents));
  133. }
  134. else
  135. {
  136. //
  137. // The caller may have previously grown the buffer
  138. // larger because they are putting in the
  139. // unique id followed by additional text. Don't
  140. // change the size on them.
  141. //
  142. }
  143. IFW32FALSE_EXIT(rbuffUidBuffer.Win32Format(
  144. L"%04u%02u%02u%02u%02u%02u%03u.%u",
  145. rsxsLuid.stTimeStamp.wYear,
  146. rsxsLuid.stTimeStamp.wMonth,
  147. rsxsLuid.stTimeStamp.wDay,
  148. rsxsLuid.stTimeStamp.wHour,
  149. rsxsLuid.stTimeStamp.wMinute,
  150. rsxsLuid.stTimeStamp.wSecond,
  151. rsxsLuid.stTimeStamp.wMilliseconds,
  152. rsxsLuid.ulUniquifier));
  153. FN_EPILOG
  154. }