Source code of Windows XP (NT5)
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.

207 lines
4.7 KiB

  1. #include "stdinc.h"
  2. #include "sxsp.h"
  3. #include "windows.h"
  4. #include "ntexapi.h"
  5. #define HASH_ALGORITHM HASH_STRING_ALGORITHM_X65599
  6. ULONG
  7. SxspSetLastNTError(
  8. NTSTATUS Status
  9. );
  10. BOOL
  11. SxspGetAssemblyRootDirectoryHelper(
  12. SIZE_T CchBuffer,
  13. WCHAR Buffer[],
  14. SIZE_T *CchWritten
  15. )
  16. {
  17. UNICODE_STRING Src, Dst;
  18. NTSTATUS Status;
  19. ULONG Length = 0;
  20. BOOL fSuccess = FALSE;
  21. ::FusionpDbgPrintEx(
  22. FUSION_DBG_LEVEL_ENTEREXIT,
  23. "SXS.DLL: Entering SxspGetAssemblyRootDirectoryHelper()\n");
  24. if ((CchBuffer == 0) && (CchWritten == NULL))
  25. {
  26. ::SxspSetLastNTError(STATUS_INVALID_PARAMETER);
  27. goto Exit;
  28. }
  29. if ((CchBuffer != 0) && (Buffer == NULL))
  30. {
  31. ::SxspSetLastNTError(STATUS_INVALID_PARAMETER);
  32. goto Exit;
  33. }
  34. Dst.Length = 0;
  35. if (CchBuffer != 0)
  36. Dst.MaximumLength = static_cast<USHORT>((CchBuffer - 1) * sizeof(WCHAR));
  37. else
  38. Dst.MaximumLength = 0;
  39. Dst.Buffer = Buffer;
  40. Src.Buffer = (PWSTR) g_AlternateAssemblyStoreRoot;
  41. if (Src.Buffer != NULL)
  42. {
  43. Src.Length = (USHORT) (wcslen(Src.Buffer) * sizeof(WCHAR));
  44. Src.MaximumLength = Src.Length;
  45. }
  46. else
  47. {
  48. Src.Buffer = L"%SystemRoot%\\WinSxS\\";
  49. Src.Length = sizeof(L"%SystemRoot%\\WinSxS\\") - sizeof(WCHAR);
  50. Src.MaximumLength = Src.Length;
  51. }
  52. Status = ::FusionpRtlExpandEnvironmentStrings_U(NULL, &Src, &Dst, &Length);
  53. if (!NT_SUCCESS(Status))
  54. {
  55. if (Status != STATUS_BUFFER_TOO_SMALL)
  56. {
  57. ::FusionpDbgPrintEx(
  58. FUSION_DBG_LEVEL_ERROR,
  59. "SXS.DLL: Unable to expand environment strings; NTSTATUS = 0x%08lx\n", Status);
  60. SxspSetLastNTError(Status);
  61. goto Exit;
  62. }
  63. if (CchWritten != NULL)
  64. *CchWritten = (Length / sizeof(WCHAR));
  65. goto Exit;
  66. }
  67. else
  68. {
  69. Dst.Buffer[Dst.Length / sizeof(WCHAR)] = UNICODE_NULL;
  70. if (CchWritten != NULL)
  71. *CchWritten = Dst.Length / sizeof(WCHAR);
  72. }
  73. fSuccess = TRUE;
  74. Exit:
  75. if (fSuccess)
  76. ::FusionpDbgPrintEx(
  77. FUSION_DBG_LEVEL_ENTEREXIT,
  78. "SXS.DLL: SxspGetAssemblyRootDirectoryHelper() successful; exiting function.\n");
  79. else
  80. {
  81. if (::FusionpGetLastWin32Error() != ERROR_INSUFFICIENT_BUFFER)
  82. {
  83. ::FusionpDbgPrintEx(
  84. FUSION_DBG_LEVEL_ERROREXITPATH,
  85. "SXS.DLL: SxspGetAssemblyRootDirectoryHelper() failed; ::FusionpGetLastWin32Error() = %d\n", ::FusionpGetLastWin32Error());
  86. }
  87. }
  88. return fSuccess;
  89. }
  90. ULONG
  91. SxspSetLastNTError(
  92. NTSTATUS Status
  93. )
  94. {
  95. ULONG dwErrorCode;
  96. dwErrorCode = ::FusionpRtlNtStatusToDosError(Status);
  97. ::FusionpSetLastWin32Error(dwErrorCode);
  98. return dwErrorCode;
  99. }
  100. BOOL
  101. SxspHashString(
  102. PCWSTR String,
  103. SIZE_T cch,
  104. PULONG HashValue,
  105. bool CaseInsensitive
  106. )
  107. {
  108. UNICODE_STRING s;
  109. NTSTATUS Status = STATUS_SUCCESS;
  110. s.MaximumLength = static_cast<USHORT>(cch * sizeof(WCHAR));
  111. s.Length = s.MaximumLength;
  112. s.Buffer = const_cast<PWSTR>(String);
  113. Status = ::FusionpRtlHashUnicodeString(&s, CaseInsensitive, HASH_ALGORITHM, HashValue);
  114. if (!NT_SUCCESS(Status))
  115. ::SxspSetLastNTError(Status);
  116. return (NT_SUCCESS(Status));
  117. }
  118. ULONG
  119. SxspGetHashAlgorithm(VOID)
  120. {
  121. return HASH_ALGORITHM;
  122. }
  123. BOOL
  124. SxspCreateLocallyUniqueId(
  125. OUT PSXSP_LOCALLY_UNIQUE_ID psxsLuid
  126. )
  127. {
  128. BOOL fSuccess = FALSE;
  129. NTSTATUS status;
  130. status = ::FusionpNtAllocateLocallyUniqueId(&psxsLuid->Luid);
  131. if (!NT_SUCCESS(status))
  132. {
  133. ::SxspSetLastNTError(status);
  134. goto Exit;
  135. }
  136. psxsLuid->Type = esxspLuid;
  137. fSuccess = TRUE;
  138. Exit:
  139. return fSuccess;
  140. }
  141. BOOL
  142. SxspFormatLocallyUniqueId(
  143. IN const SXSP_LOCALLY_UNIQUE_ID &rsxsLuid,
  144. OUT CBaseStringBuffer &rbuffUidBuffer
  145. )
  146. {
  147. FN_PROLOG_WIN32
  148. switch (rsxsLuid.Type)
  149. {
  150. case esxspGuid:
  151. IFW32FALSE_EXIT(::SxspFormatGUID(rsxsLuid.Guid, rbuffUidBuffer));
  152. break;
  153. case esxspLuid:
  154. {
  155. ULARGE_INTEGER uli;
  156. CStringBufferAccessor acc;
  157. uli.LowPart = rsxsLuid.Luid.LowPart;
  158. uli.HighPart = rsxsLuid.Luid.HighPart;
  159. IFW32FALSE_EXIT(rbuffUidBuffer.Win32ResizeBuffer(sizeof(ULONGLONG) * CHAR_BIT, eDoNotPreserveBufferContents));
  160. // better to have all digits, no minus sign probably, for consistent names
  161. acc.Attach(&rbuffUidBuffer);
  162. //
  163. // This would be a good place to use RtlInt64ToUnicodeString, at least
  164. // #if !SXSP_DOWNLEVEL..
  165. //
  166. _ui64tow(uli.QuadPart, acc.GetBufferPtr(), 10);
  167. acc.Detach();
  168. break;
  169. }
  170. }
  171. FN_EPILOG
  172. }