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.

671 lines
14 KiB

  1. /*++
  2. Copyright (c) 1992 Microsoft Corporation
  3. Module Name:
  4. regsup.c
  5. Abstract:
  6. This module contains routine that interact with registry.
  7. Author:
  8. Manny Weiser (mannyw) 30-Mar-92
  9. Revision History:
  10. --*/
  11. #include "mup.h"
  12. //#include "stdlib.h"
  13. //#include "zwapi.h"
  14. //
  15. // The debug trace level
  16. //
  17. #define Dbg (DEBUG_TRACE_FSCONTROL)
  18. //
  19. // local procedure prototypes
  20. //
  21. #if DBG
  22. VOID
  23. MupGetDebugFlags(void);
  24. #endif
  25. VOID
  26. DfsGetEventLogValue(VOID);
  27. VOID
  28. DfsGetEventLogValue(VOID);
  29. VOID
  30. InitializeProvider(
  31. PWCH ProviderName,
  32. ULONG Priority
  33. );
  34. VOID
  35. AddUnregisteredProvider(
  36. PWCH providerName,
  37. ULONG priority
  38. );
  39. #ifdef ALLOC_PRAGMA
  40. #pragma alloc_text( PAGE, AddUnregisteredProvider )
  41. #pragma alloc_text( PAGE, InitializeProvider )
  42. #pragma alloc_text( PAGE, MupCheckForUnregisteredProvider )
  43. #pragma alloc_text( PAGE, MupGetProviderInformation )
  44. #pragma alloc_text( PAGE, DfsGetEventLogValue )
  45. #if DBG
  46. #pragma alloc_text( PAGE, MupGetDebugFlags )
  47. #endif
  48. #endif
  49. VOID
  50. MupGetProviderInformation (
  51. VOID
  52. )
  53. /*++
  54. Routine Description:
  55. This routine reads MUP information from the registry and saves it for
  56. future use.
  57. Arguments:
  58. None.
  59. Return Value:
  60. None.
  61. --*/
  62. {
  63. HANDLE handle;
  64. NTSTATUS status;
  65. UNICODE_STRING valueName;
  66. UNICODE_STRING keyName;
  67. OBJECT_ATTRIBUTES objectAttributes;
  68. PVOID buffer = NULL;
  69. PWCH providerName;
  70. ULONG lengthRequired;
  71. BOOLEAN done;
  72. ULONG priority;
  73. PWCH sep;
  74. PAGED_CODE();
  75. RtlInitUnicodeString( &keyName, L"\\Registry\\Machine\\System\\CurrentControlSet\\Control\\Networkprovider\\Order" );
  76. InitializeObjectAttributes(
  77. &objectAttributes,
  78. &keyName,
  79. OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE,
  80. 0,
  81. NULL
  82. );
  83. status = ZwOpenKey(
  84. &handle,
  85. KEY_QUERY_VALUE,
  86. &objectAttributes
  87. );
  88. if ( !NT_SUCCESS( status )) {
  89. return;
  90. }
  91. RtlInitUnicodeString( &valueName, L"ProviderOrder" );
  92. status = ZwQueryValueKey(
  93. handle,
  94. &valueName,
  95. KeyValueFullInformation,
  96. buffer,
  97. 0,
  98. &lengthRequired
  99. );
  100. if ( status == STATUS_BUFFER_TOO_SMALL ) {
  101. buffer = ExAllocatePoolWithTag( PagedPool, lengthRequired + 2, ' puM');
  102. if ( buffer == NULL) {
  103. ZwClose( handle );
  104. return;
  105. }
  106. status = ZwQueryValueKey(
  107. handle,
  108. &valueName,
  109. KeyValueFullInformation,
  110. buffer,
  111. lengthRequired,
  112. &lengthRequired
  113. );
  114. }
  115. ZwClose( handle );
  116. if ( !NT_SUCCESS( status) ) {
  117. if ( buffer != NULL ) {
  118. ExFreePool( buffer );
  119. }
  120. return;
  121. }
  122. //
  123. // Scan the ordered list of providers, and create record for each.
  124. //
  125. providerName = (PWCH)((PCHAR)buffer + ((PKEY_VALUE_FULL_INFORMATION)buffer)->DataOffset);
  126. done = FALSE;
  127. priority = 0;
  128. while ( !done ) {
  129. sep = wcschr( providerName, L',');
  130. if ( sep == NULL ) {
  131. done = TRUE;
  132. } else {
  133. *sep = L'\0';
  134. }
  135. InitializeProvider( providerName, priority );
  136. priority++;
  137. providerName = sep+1;
  138. }
  139. ExFreePool( buffer );
  140. return;
  141. }
  142. VOID
  143. InitializeProvider(
  144. PWCH ProviderName,
  145. ULONG Priority
  146. )
  147. /*++
  148. Routine Description:
  149. This routine reads provider information out of the registry and
  150. creates an unregistered provider entry.
  151. Arguments:
  152. ProviderName - The registry name for the provider.
  153. Priority - The priority to assign to this provider.
  154. Return Value:
  155. None.
  156. --*/
  157. {
  158. UNICODE_STRING keyName;
  159. PVOID buffer = NULL;
  160. ULONG bufferLength;
  161. NTSTATUS status;
  162. OBJECT_ATTRIBUTES objectAttributes;
  163. ULONG lengthRequired;
  164. UNICODE_STRING valueName;
  165. HANDLE handle;
  166. PAGED_CODE();
  167. //
  168. // Allocate space for the registry string
  169. //
  170. bufferLength = sizeof( L"\\Registry\\Machine\\System\\CurrentControlSet\\Services\\" ) +
  171. wcslen( ProviderName ) * sizeof( WCHAR ) +
  172. sizeof( L"\\NetworkProvider" );
  173. buffer = ExAllocatePoolWithTag( PagedPool, bufferLength, ' puM' );
  174. if ( buffer == NULL ) {
  175. return;
  176. }
  177. //
  178. // Build the registry string
  179. //
  180. RtlMoveMemory(
  181. buffer,
  182. L"\\Registry\\Machine\\System\\CurrentControlSet\\Services\\",
  183. sizeof( L"\\Registry\\Machine\\System\\CurrentControlSet\\Services\\" )
  184. );
  185. keyName.Buffer = buffer;
  186. keyName.MaximumLength = (USHORT)bufferLength;
  187. keyName.Length = sizeof( L"\\Registry\\Machine\\System\\CurrentControlSet\\Services\\" ) - 2;
  188. status = RtlAppendUnicodeToString( &keyName, ProviderName );
  189. ASSERT( NT_SUCCESS( status ) );
  190. status = RtlAppendUnicodeToString( &keyName, L"\\NetworkProvider" );
  191. ASSERT( NT_SUCCESS( status ) );
  192. InitializeObjectAttributes(
  193. &objectAttributes,
  194. &keyName,
  195. OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE,
  196. 0,
  197. NULL
  198. );
  199. status = ZwOpenKey(
  200. &handle,
  201. KEY_QUERY_VALUE,
  202. &objectAttributes
  203. );
  204. ExFreePool( buffer );
  205. if ( !NT_SUCCESS( status )) {
  206. return;
  207. }
  208. buffer = NULL;
  209. RtlInitUnicodeString( &valueName, L"DeviceName" );
  210. status = ZwQueryValueKey(
  211. handle,
  212. &valueName,
  213. KeyValueFullInformation,
  214. buffer,
  215. 0,
  216. &lengthRequired
  217. );
  218. if ( status == STATUS_BUFFER_TOO_SMALL ) {
  219. buffer = ExAllocatePoolWithTag( PagedPool, lengthRequired + 2, ' puM' );
  220. if ( buffer == NULL) {
  221. return;
  222. }
  223. status = ZwQueryValueKey(
  224. handle,
  225. &valueName,
  226. KeyValueFullInformation,
  227. buffer,
  228. lengthRequired,
  229. &lengthRequired
  230. );
  231. }
  232. if ( !NT_SUCCESS( status) ) {
  233. if ( buffer != NULL ) {
  234. ExFreePool( buffer );
  235. }
  236. ZwClose( handle );
  237. return;
  238. }
  239. //
  240. // Wahoo! We actually have the device name in hand. Add the
  241. // provider to the unregistered list.
  242. //
  243. AddUnregisteredProvider(
  244. (PWCH)((PCHAR)buffer + ((PKEY_VALUE_FULL_INFORMATION)buffer)->DataOffset),
  245. Priority
  246. );
  247. ExFreePool( buffer );
  248. ZwClose( handle );
  249. return;
  250. }
  251. PUNC_PROVIDER
  252. MupCheckForUnregisteredProvider(
  253. PUNICODE_STRING DeviceName
  254. )
  255. /*++
  256. Routine Description:
  257. This routine checks the list of unregistered providers for one whose
  258. device name matches the provider attempting to register.
  259. If one is found it is dequeued from the list of unregistered providers.
  260. Arguments:
  261. DeviceName - The device name of the registering provider.
  262. Return Value:
  263. UNC_PROVIDER - A pointer to the matching unregistered provider, or
  264. NULL if no match is found.
  265. --*/
  266. {
  267. PLIST_ENTRY listEntry;
  268. PUNC_PROVIDER uncProvider;
  269. PAGED_CODE();
  270. MupAcquireGlobalLock();
  271. for (listEntry = MupProviderList.Flink;
  272. listEntry != &MupProviderList;
  273. listEntry = listEntry->Flink ) {
  274. uncProvider = CONTAINING_RECORD( listEntry, UNC_PROVIDER, ListEntry );
  275. if(uncProvider->Registered == FALSE) {
  276. //
  277. // If we find a match take it out of the list, and
  278. // return it to the caller.
  279. //
  280. if ( RtlEqualUnicodeString( DeviceName, &uncProvider->DeviceName, TRUE )) {
  281. uncProvider->BlockHeader.BlockState = BlockStateActive;
  282. MupReleaseGlobalLock();
  283. return uncProvider;
  284. }
  285. }
  286. }
  287. MupReleaseGlobalLock();
  288. return NULL;
  289. }
  290. VOID
  291. AddUnregisteredProvider(
  292. PWCH ProviderName,
  293. ULONG Priority
  294. )
  295. /*++
  296. Routine Description:
  297. This routine queues an unregistered provider on a list.
  298. Arguments:
  299. ProviderName - The device name of the provider. (from the registry)
  300. Priority - A priority for the provider.
  301. Return Value:
  302. None.
  303. --*/
  304. {
  305. ULONG nameLength;
  306. PUNC_PROVIDER uncProvider;
  307. PAGED_CODE();
  308. nameLength = wcslen( ProviderName ) * 2;
  309. try {
  310. uncProvider = MupAllocateUncProvider( nameLength );
  311. if (uncProvider != NULL) {
  312. uncProvider->DeviceName.MaximumLength = (USHORT)nameLength;
  313. uncProvider->DeviceName.Length = (USHORT)nameLength;
  314. uncProvider->DeviceName.Buffer = (PWCH)(uncProvider + 1);
  315. uncProvider->Priority = Priority;
  316. RtlMoveMemory(
  317. (PVOID)(uncProvider + 1),
  318. ProviderName,
  319. nameLength
  320. );
  321. MupAcquireGlobalLock();
  322. InsertTailList( &MupProviderList, &uncProvider->ListEntry );
  323. MupReleaseGlobalLock();
  324. }
  325. } except ( EXCEPTION_EXECUTE_HANDLER ) {
  326. NOTHING;
  327. }
  328. }
  329. VOID
  330. DfsGetEventLogValue(VOID)
  331. /*++
  332. Routine Description:
  333. This routine checks registry keys to set the event logging level
  334. Arguments:
  335. None
  336. Return Value:
  337. None
  338. --*/
  339. {
  340. NTSTATUS status;
  341. HANDLE DfsRegHandle;
  342. OBJECT_ATTRIBUTES ObjAttr;
  343. ULONG ValueSize;
  344. UNICODE_STRING DfsRegKey;
  345. UNICODE_STRING DfsValueName;
  346. struct {
  347. KEY_VALUE_PARTIAL_INFORMATION Info;
  348. ULONG Buffer;
  349. } DfsValue;
  350. PAGED_CODE();
  351. RtlInitUnicodeString(
  352. &DfsRegKey,
  353. L"\\Registry\\Machine\\SOFTWARE\\MicroSoft\\Windows NT\\CurrentVersion\\Diagnostics");
  354. InitializeObjectAttributes(
  355. &ObjAttr,
  356. &DfsRegKey,
  357. OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE,
  358. 0,
  359. NULL);
  360. status = ZwOpenKey(
  361. &DfsRegHandle,
  362. KEY_QUERY_VALUE,
  363. &ObjAttr);
  364. if (!NT_SUCCESS(status))
  365. return;
  366. RtlInitUnicodeString(&DfsValueName, L"RunDiagnosticLoggingGlobal");
  367. status = ZwQueryValueKey(
  368. DfsRegHandle,
  369. &DfsValueName,
  370. KeyValuePartialInformation,
  371. (PVOID) &DfsValue,
  372. sizeof(DfsValue),
  373. &ValueSize);
  374. if (NT_SUCCESS(status) && DfsValue.Info.Type == REG_DWORD) {
  375. DfsEventLog = *((PULONG) DfsValue.Info.Data);
  376. goto Cleanup;
  377. }
  378. RtlInitUnicodeString(&DfsValueName, L"RunDiagnosticLoggingDfs");
  379. status = ZwQueryValueKey(
  380. DfsRegHandle,
  381. &DfsValueName,
  382. KeyValuePartialInformation,
  383. (PVOID) &DfsValue,
  384. sizeof(DfsValue),
  385. &ValueSize);
  386. if (NT_SUCCESS(status) && DfsValue.Info.Type == REG_DWORD)
  387. DfsEventLog = *((PULONG) DfsValue.Info.Data);
  388. Cleanup:
  389. ZwClose( DfsRegHandle );
  390. }
  391. #if DBG
  392. VOID
  393. MupGetDebugFlags(
  394. VOID
  395. )
  396. /*++
  397. Routine Description:
  398. This routine reads MUP debug flag settings from the registry
  399. Arguments:
  400. None.
  401. Return Value:
  402. None.
  403. --*/
  404. {
  405. HANDLE handle;
  406. NTSTATUS status;
  407. UNICODE_STRING valueName;
  408. UNICODE_STRING keyName;
  409. OBJECT_ATTRIBUTES objectAttributes;
  410. PWCH providerName;
  411. ULONG lengthRequired;
  412. ULONG Flags = 0;
  413. union {
  414. KEY_VALUE_FULL_INFORMATION;
  415. UCHAR buffer[ sizeof( KEY_VALUE_FULL_INFORMATION ) + 100 ];
  416. } keyValueInformation;
  417. PAGED_CODE();
  418. //
  419. // Get MupDebugTraceLevel
  420. //
  421. RtlInitUnicodeString(
  422. &keyName,
  423. L"\\Registry\\Machine\\System\\CurrentControlSet\\Services\\Dfs");
  424. InitializeObjectAttributes(
  425. &objectAttributes,
  426. &keyName,
  427. OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE,
  428. 0,
  429. NULL);
  430. status = ZwOpenKey(
  431. &handle,
  432. KEY_QUERY_VALUE,
  433. &objectAttributes);
  434. if (!NT_SUCCESS(status))
  435. goto GetNext;
  436. RtlInitUnicodeString( &valueName, L"MupDebugTraceLevel" );
  437. status = ZwQueryValueKey(
  438. handle,
  439. &valueName,
  440. KeyValueFullInformation,
  441. &keyValueInformation,
  442. sizeof(keyValueInformation),
  443. &lengthRequired
  444. );
  445. if (
  446. NT_SUCCESS(status) &&
  447. keyValueInformation.Type == REG_DWORD &&
  448. keyValueInformation.DataLength != 0
  449. ) {
  450. Flags = *(PULONG)(((PUCHAR)(&keyValueInformation)) + keyValueInformation.DataOffset);
  451. DfsDebugTraceLevel = Flags;
  452. }
  453. ZwClose( handle );
  454. GetNext:
  455. //
  456. // Now get MupVerbose
  457. //
  458. RtlInitUnicodeString(
  459. &keyName,
  460. L"\\Registry\\Machine\\System\\CurrentControlSet\\Services\\Dfs");
  461. InitializeObjectAttributes(
  462. &objectAttributes,
  463. &keyName,
  464. OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE,
  465. 0,
  466. NULL);
  467. status = ZwOpenKey(
  468. &handle,
  469. KEY_QUERY_VALUE,
  470. &objectAttributes);
  471. if (!NT_SUCCESS(status))
  472. return;
  473. RtlInitUnicodeString( &valueName, L"MupVerbose" );
  474. status = ZwQueryValueKey(
  475. handle,
  476. &valueName,
  477. KeyValueFullInformation,
  478. &keyValueInformation,
  479. sizeof(keyValueInformation),
  480. &lengthRequired
  481. );
  482. if (
  483. NT_SUCCESS(status) &&
  484. keyValueInformation.Type == REG_DWORD &&
  485. keyValueInformation.DataLength != 0
  486. ) {
  487. Flags = *(PULONG)(((PUCHAR)(&keyValueInformation)) + keyValueInformation.DataOffset);
  488. MupVerbose = Flags;
  489. }
  490. ZwClose( handle );
  491. return;
  492. }
  493. #endif // DBG