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.

471 lines
14 KiB

  1. /*++
  2. Copyright (c) 1989 Microsoft Corporation
  3. Module Name:
  4. FsRtlP.c
  5. Abstract:
  6. This module declares the global data used by the FsRtl Module
  7. Author:
  8. Gary Kimura [GaryKi] 30-Jul-1990
  9. Revision History:
  10. --*/
  11. #include "FsRtlP.h"
  12. #define COMPATIBILITY_MODE_KEY_NAME L"\\Registry\\Machine\\System\\CurrentControlSet\\Control\\FileSystem"
  13. #define COMPATIBILITY_MODE_VALUE_NAME L"Win95TruncatedExtensions"
  14. #define KEY_WORK_AREA ((sizeof(KEY_VALUE_FULL_INFORMATION) + \
  15. sizeof(ULONG)) + 64)
  16. #ifdef FSRTLDBG
  17. LONG FsRtlDebugTraceLevel = 0x0000000f;
  18. LONG FsRtlDebugTraceIndent = 0;
  19. #endif // FSRTLDBG
  20. //
  21. // Local Support routine
  22. //
  23. NTSTATUS
  24. FsRtlGetCompatibilityModeValue (
  25. IN PUNICODE_STRING ValueName,
  26. IN OUT PULONG Value
  27. );
  28. #ifdef ALLOC_PRAGMA
  29. #pragma alloc_text(PAGE, FsRtlAllocateResource)
  30. #pragma alloc_text(INIT, FsRtlInitSystem)
  31. #pragma alloc_text(INIT, FsRtlGetCompatibilityModeValue)
  32. #endif
  33. //
  34. // Define the number of resources, a pointer to them and a counter for
  35. // resource selection.
  36. //
  37. #define FSRTL_NUMBER_OF_RESOURCES (16)
  38. PERESOURCE FsRtlPagingIoResources;
  39. #ifdef ALLOC_DATA_PRAGMA
  40. #pragma data_seg("PAGEDATA")
  41. #endif
  42. ULONG FsRtlPagingIoResourceSelector = 0;
  43. BOOLEAN FsRtlSafeExtensions = TRUE;
  44. #ifdef ALLOC_DATA_PRAGMA
  45. #pragma data_seg()
  46. #endif
  47. //
  48. // The global static legal ANSI character array. Wild characters
  49. // are not considered legal, they should be checked seperately if
  50. // allowed.
  51. //
  52. #define _FAT_ FSRTL_FAT_LEGAL
  53. #define _HPFS_ FSRTL_HPFS_LEGAL
  54. #define _NTFS_ FSRTL_NTFS_LEGAL
  55. #define _OLE_ FSRTL_OLE_LEGAL
  56. #define _WILD_ FSRTL_WILD_CHARACTER
  57. static const UCHAR LocalLegalAnsiCharacterArray[128] = {
  58. 0 , // 0x00 ^@
  59. _OLE_, // 0x01 ^A
  60. _OLE_, // 0x02 ^B
  61. _OLE_, // 0x03 ^C
  62. _OLE_, // 0x04 ^D
  63. _OLE_, // 0x05 ^E
  64. _OLE_, // 0x06 ^F
  65. _OLE_, // 0x07 ^G
  66. _OLE_, // 0x08 ^H
  67. _OLE_, // 0x09 ^I
  68. _OLE_, // 0x0A ^J
  69. _OLE_, // 0x0B ^K
  70. _OLE_, // 0x0C ^L
  71. _OLE_, // 0x0D ^M
  72. _OLE_, // 0x0E ^N
  73. _OLE_, // 0x0F ^O
  74. _OLE_, // 0x10 ^P
  75. _OLE_, // 0x11 ^Q
  76. _OLE_, // 0x12 ^R
  77. _OLE_, // 0x13 ^S
  78. _OLE_, // 0x14 ^T
  79. _OLE_, // 0x15 ^U
  80. _OLE_, // 0x16 ^V
  81. _OLE_, // 0x17 ^W
  82. _OLE_, // 0x18 ^X
  83. _OLE_, // 0x19 ^Y
  84. _OLE_, // 0x1A ^Z
  85. _OLE_, // 0x1B ESC
  86. _OLE_, // 0x1C FS
  87. _OLE_, // 0x1D GS
  88. _OLE_, // 0x1E RS
  89. _OLE_, // 0x1F US
  90. _FAT_ | _HPFS_ | _NTFS_ | _OLE_, // 0x20 space
  91. _FAT_ | _HPFS_ | _NTFS_ , // 0x21 !
  92. _WILD_| _OLE_, // 0x22 "
  93. _FAT_ | _HPFS_ | _NTFS_ | _OLE_, // 0x23 #
  94. _FAT_ | _HPFS_ | _NTFS_ | _OLE_, // 0x24 $
  95. _FAT_ | _HPFS_ | _NTFS_ | _OLE_, // 0x25 %
  96. _FAT_ | _HPFS_ | _NTFS_ | _OLE_, // 0x26 &
  97. _FAT_ | _HPFS_ | _NTFS_ | _OLE_, // 0x27 '
  98. _FAT_ | _HPFS_ | _NTFS_ | _OLE_, // 0x28 (
  99. _FAT_ | _HPFS_ | _NTFS_ | _OLE_, // 0x29 )
  100. _WILD_| _OLE_, // 0x2A *
  101. _HPFS_ | _NTFS_ | _OLE_, // 0x2B +
  102. _HPFS_ | _NTFS_ | _OLE_, // 0x2C ,
  103. _FAT_ | _HPFS_ | _NTFS_ | _OLE_, // 0x2D -
  104. _FAT_ | _HPFS_ | _NTFS_ , // 0x2E .
  105. 0 , // 0x2F /
  106. _FAT_ | _HPFS_ | _NTFS_ | _OLE_, // 0x30 0
  107. _FAT_ | _HPFS_ | _NTFS_ | _OLE_, // 0x31 1
  108. _FAT_ | _HPFS_ | _NTFS_ | _OLE_, // 0x32 2
  109. _FAT_ | _HPFS_ | _NTFS_ | _OLE_, // 0x33 3
  110. _FAT_ | _HPFS_ | _NTFS_ | _OLE_, // 0x34 4
  111. _FAT_ | _HPFS_ | _NTFS_ | _OLE_, // 0x35 5
  112. _FAT_ | _HPFS_ | _NTFS_ | _OLE_, // 0x36 6
  113. _FAT_ | _HPFS_ | _NTFS_ | _OLE_, // 0x37 7
  114. _FAT_ | _HPFS_ | _NTFS_ | _OLE_, // 0x38 8
  115. _FAT_ | _HPFS_ | _NTFS_ | _OLE_, // 0x39 9
  116. _NTFS_ , // 0x3A :
  117. _HPFS_ | _NTFS_ | _OLE_, // 0x3B ;
  118. _WILD_| _OLE_, // 0x3C <
  119. _HPFS_ | _NTFS_ | _OLE_, // 0x3D =
  120. _WILD_| _OLE_, // 0x3E >
  121. _WILD_| _OLE_, // 0x3F ?
  122. _FAT_ | _HPFS_ | _NTFS_ | _OLE_, // 0x40 @
  123. _FAT_ | _HPFS_ | _NTFS_ | _OLE_, // 0x41 A
  124. _FAT_ | _HPFS_ | _NTFS_ | _OLE_, // 0x42 B
  125. _FAT_ | _HPFS_ | _NTFS_ | _OLE_, // 0x43 C
  126. _FAT_ | _HPFS_ | _NTFS_ | _OLE_, // 0x44 D
  127. _FAT_ | _HPFS_ | _NTFS_ | _OLE_, // 0x45 E
  128. _FAT_ | _HPFS_ | _NTFS_ | _OLE_, // 0x46 F
  129. _FAT_ | _HPFS_ | _NTFS_ | _OLE_, // 0x47 G
  130. _FAT_ | _HPFS_ | _NTFS_ | _OLE_, // 0x48 H
  131. _FAT_ | _HPFS_ | _NTFS_ | _OLE_, // 0x49 I
  132. _FAT_ | _HPFS_ | _NTFS_ | _OLE_, // 0x4A J
  133. _FAT_ | _HPFS_ | _NTFS_ | _OLE_, // 0x4B K
  134. _FAT_ | _HPFS_ | _NTFS_ | _OLE_, // 0x4C L
  135. _FAT_ | _HPFS_ | _NTFS_ | _OLE_, // 0x4D M
  136. _FAT_ | _HPFS_ | _NTFS_ | _OLE_, // 0x4E N
  137. _FAT_ | _HPFS_ | _NTFS_ | _OLE_, // 0x4F O
  138. _FAT_ | _HPFS_ | _NTFS_ | _OLE_, // 0x50 P
  139. _FAT_ | _HPFS_ | _NTFS_ | _OLE_, // 0x51 Q
  140. _FAT_ | _HPFS_ | _NTFS_ | _OLE_, // 0x52 R
  141. _FAT_ | _HPFS_ | _NTFS_ | _OLE_, // 0x53 S
  142. _FAT_ | _HPFS_ | _NTFS_ | _OLE_, // 0x54 T
  143. _FAT_ | _HPFS_ | _NTFS_ | _OLE_, // 0x55 U
  144. _FAT_ | _HPFS_ | _NTFS_ | _OLE_, // 0x56 V
  145. _FAT_ | _HPFS_ | _NTFS_ | _OLE_, // 0x57 W
  146. _FAT_ | _HPFS_ | _NTFS_ | _OLE_, // 0x58 X
  147. _FAT_ | _HPFS_ | _NTFS_ | _OLE_, // 0x59 Y
  148. _FAT_ | _HPFS_ | _NTFS_ | _OLE_, // 0x5A Z
  149. _HPFS_ | _NTFS_ | _OLE_, // 0x5B [
  150. 0 , // 0x5C backslash
  151. _HPFS_ | _NTFS_ | _OLE_, // 0x5D ]
  152. _FAT_ | _HPFS_ | _NTFS_ | _OLE_, // 0x5E ^
  153. _FAT_ | _HPFS_ | _NTFS_ | _OLE_, // 0x5F _
  154. _FAT_ | _HPFS_ | _NTFS_ | _OLE_, // 0x60 `
  155. _FAT_ | _HPFS_ | _NTFS_ | _OLE_, // 0x61 a
  156. _FAT_ | _HPFS_ | _NTFS_ | _OLE_, // 0x62 b
  157. _FAT_ | _HPFS_ | _NTFS_ | _OLE_, // 0x63 c
  158. _FAT_ | _HPFS_ | _NTFS_ | _OLE_, // 0x64 d
  159. _FAT_ | _HPFS_ | _NTFS_ | _OLE_, // 0x65 e
  160. _FAT_ | _HPFS_ | _NTFS_ | _OLE_, // 0x66 f
  161. _FAT_ | _HPFS_ | _NTFS_ | _OLE_, // 0x67 g
  162. _FAT_ | _HPFS_ | _NTFS_ | _OLE_, // 0x68 h
  163. _FAT_ | _HPFS_ | _NTFS_ | _OLE_, // 0x69 i
  164. _FAT_ | _HPFS_ | _NTFS_ | _OLE_, // 0x6A j
  165. _FAT_ | _HPFS_ | _NTFS_ | _OLE_, // 0x6B k
  166. _FAT_ | _HPFS_ | _NTFS_ | _OLE_, // 0x6C l
  167. _FAT_ | _HPFS_ | _NTFS_ | _OLE_, // 0x6D m
  168. _FAT_ | _HPFS_ | _NTFS_ | _OLE_, // 0x6E n
  169. _FAT_ | _HPFS_ | _NTFS_ | _OLE_, // 0x6F o
  170. _FAT_ | _HPFS_ | _NTFS_ | _OLE_, // 0x70 p
  171. _FAT_ | _HPFS_ | _NTFS_ | _OLE_, // 0x71 q
  172. _FAT_ | _HPFS_ | _NTFS_ | _OLE_, // 0x72 r
  173. _FAT_ | _HPFS_ | _NTFS_ | _OLE_, // 0x73 s
  174. _FAT_ | _HPFS_ | _NTFS_ | _OLE_, // 0x74 t
  175. _FAT_ | _HPFS_ | _NTFS_ | _OLE_, // 0x75 u
  176. _FAT_ | _HPFS_ | _NTFS_ | _OLE_, // 0x76 v
  177. _FAT_ | _HPFS_ | _NTFS_ | _OLE_, // 0x77 w
  178. _FAT_ | _HPFS_ | _NTFS_ | _OLE_, // 0x78 x
  179. _FAT_ | _HPFS_ | _NTFS_ | _OLE_, // 0x79 y
  180. _FAT_ | _HPFS_ | _NTFS_ | _OLE_, // 0x7A z
  181. _FAT_ | _HPFS_ | _NTFS_ | _OLE_, // 0x7B {
  182. 0 | _OLE_, // 0x7C |
  183. _FAT_ | _HPFS_ | _NTFS_ | _OLE_, // 0x7D }
  184. _FAT_ | _HPFS_ | _NTFS_ | _OLE_, // 0x7E ~
  185. _FAT_ | _HPFS_ | _NTFS_ | _OLE_, // 0x7F 
  186. };
  187. UCHAR const* const FsRtlLegalAnsiCharacterArray = &LocalLegalAnsiCharacterArray[0];
  188. //
  189. // This routine is called during phase one initialization.
  190. //
  191. BOOLEAN
  192. FsRtlInitSystem (
  193. )
  194. {
  195. ULONG i;
  196. ULONG Value;
  197. UNICODE_STRING ValueName;
  198. extern KSEMAPHORE FsRtlpUncSemaphore;
  199. PAGED_CODE();
  200. //
  201. // Allocate and initialize all the paging Io resources
  202. //
  203. FsRtlPagingIoResources = FsRtlAllocatePool( NonPagedPool,
  204. FSRTL_NUMBER_OF_RESOURCES *
  205. sizeof(ERESOURCE) );
  206. for (i=0; i < FSRTL_NUMBER_OF_RESOURCES; i++) {
  207. ExInitializeResourceLite( &FsRtlPagingIoResources[i] );
  208. }
  209. //
  210. // Initialize the global tunneling structures.
  211. //
  212. FsRtlInitializeTunnels();
  213. //
  214. // Initialize the global filelock structures.
  215. //
  216. FsRtlInitializeFileLocks();
  217. //
  218. // Initialize the global largemcb structures.
  219. //
  220. FsRtlInitializeLargeMcbs();
  221. //
  222. // Initialize the semaphore used to guard loading of the MUP
  223. //
  224. KeInitializeSemaphore( &FsRtlpUncSemaphore, 1, MAXLONG );
  225. //
  226. // Pull the bit from the registry telling us whether to do a safe
  227. // or dangerous extension truncation.
  228. //
  229. ValueName.Buffer = COMPATIBILITY_MODE_VALUE_NAME;
  230. ValueName.Length = sizeof(COMPATIBILITY_MODE_VALUE_NAME) - sizeof(WCHAR);
  231. ValueName.MaximumLength = sizeof(COMPATIBILITY_MODE_VALUE_NAME);
  232. if (NT_SUCCESS(FsRtlGetCompatibilityModeValue( &ValueName, &Value )) &&
  233. (Value != 0)) {
  234. FsRtlSafeExtensions = FALSE;
  235. }
  236. //
  237. // Initialize the FsRtl stack overflow work QueueObject and thread.
  238. //
  239. if (!NT_SUCCESS(FsRtlInitializeWorkerThread())) {
  240. return FALSE;
  241. }
  242. //
  243. // Initialize the FsFilter component of FsRtl.
  244. //
  245. if (!NT_SUCCESS(FsFilterInit())) {
  246. return FALSE;
  247. }
  248. return TRUE;
  249. }
  250. PERESOURCE
  251. FsRtlAllocateResource (
  252. )
  253. /*++
  254. Routine Description:
  255. This routine is used to allocate a resource from the FsRtl pool.
  256. Arguments:
  257. Return Value:
  258. PERESOURCE - A pointer to the provided resource.
  259. --*/
  260. {
  261. PAGED_CODE();
  262. return &FsRtlPagingIoResources[ FsRtlPagingIoResourceSelector++ %
  263. FSRTL_NUMBER_OF_RESOURCES];
  264. }
  265. //
  266. // Local Support routine
  267. //
  268. NTSTATUS
  269. FsRtlGetCompatibilityModeValue (
  270. IN PUNICODE_STRING ValueName,
  271. IN OUT PULONG Value
  272. )
  273. /*++
  274. Routine Description:
  275. Given a unicode value name this routine will go into the registry
  276. location for the Chicago compatibilitymode information and get the
  277. value.
  278. Arguments:
  279. ValueName - the unicode name for the registry value located in the
  280. double space configuration location of the registry.
  281. Value - a pointer to the ULONG for the result.
  282. Return Value:
  283. NTSTATUS
  284. If STATUS_SUCCESSFUL is returned, the location *Value will be
  285. updated with the DWORD value from the registry. If any failing
  286. status is returned, this value is untouched.
  287. --*/
  288. {
  289. HANDLE Handle;
  290. NTSTATUS Status;
  291. ULONG RequestLength;
  292. ULONG ResultLength;
  293. UCHAR Buffer[KEY_WORK_AREA];
  294. UNICODE_STRING KeyName;
  295. OBJECT_ATTRIBUTES ObjectAttributes;
  296. PKEY_VALUE_FULL_INFORMATION KeyValueInformation;
  297. KeyName.Buffer = COMPATIBILITY_MODE_KEY_NAME;
  298. KeyName.Length = sizeof(COMPATIBILITY_MODE_KEY_NAME) - sizeof(WCHAR);
  299. KeyName.MaximumLength = sizeof(COMPATIBILITY_MODE_KEY_NAME);
  300. InitializeObjectAttributes(&ObjectAttributes,
  301. &KeyName,
  302. OBJ_CASE_INSENSITIVE,
  303. NULL,
  304. NULL);
  305. Status = ZwOpenKey(&Handle,
  306. KEY_READ,
  307. &ObjectAttributes);
  308. if (!NT_SUCCESS(Status)) {
  309. return Status;
  310. }
  311. RequestLength = KEY_WORK_AREA;
  312. KeyValueInformation = (PKEY_VALUE_FULL_INFORMATION)Buffer;
  313. while (1) {
  314. Status = ZwQueryValueKey(Handle,
  315. ValueName,
  316. KeyValueFullInformation,
  317. KeyValueInformation,
  318. RequestLength,
  319. &ResultLength);
  320. ASSERT( Status != STATUS_BUFFER_OVERFLOW );
  321. if (Status == STATUS_BUFFER_OVERFLOW) {
  322. //
  323. // Try to get a buffer big enough.
  324. //
  325. if (KeyValueInformation != (PKEY_VALUE_FULL_INFORMATION)Buffer) {
  326. ExFreePool(KeyValueInformation);
  327. }
  328. RequestLength += 256;
  329. KeyValueInformation = (PKEY_VALUE_FULL_INFORMATION)
  330. ExAllocatePoolWithTag(PagedPool,
  331. RequestLength,
  332. ' taF');
  333. if (!KeyValueInformation) {
  334. return STATUS_NO_MEMORY;
  335. }
  336. } else {
  337. break;
  338. }
  339. }
  340. ZwClose(Handle);
  341. if (NT_SUCCESS(Status)) {
  342. if (KeyValueInformation->DataLength != 0) {
  343. PULONG DataPtr;
  344. //
  345. // Return contents to the caller.
  346. //
  347. DataPtr = (PULONG)
  348. ((PUCHAR)KeyValueInformation + KeyValueInformation->DataOffset);
  349. *Value = *DataPtr;
  350. } else {
  351. //
  352. // Treat as if no value was found
  353. //
  354. Status = STATUS_OBJECT_NAME_NOT_FOUND;
  355. }
  356. }
  357. if (KeyValueInformation != (PKEY_VALUE_FULL_INFORMATION)Buffer) {
  358. ExFreePool(KeyValueInformation);
  359. }
  360. return Status;
  361. }