Windows NT 4.0 source code leak
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.

416 lines
8.7 KiB

4 years ago
  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. VOID
  22. InitializeProvider(
  23. PWCH ProviderName,
  24. ULONG Priority
  25. );
  26. VOID
  27. AddUnregisteredProvider(
  28. PWCH providerName,
  29. ULONG priority
  30. );
  31. #ifdef ALLOC_PRAGMA
  32. #pragma alloc_text( PAGE, AddUnregisteredProvider )
  33. #pragma alloc_text( PAGE, InitializeProvider )
  34. #pragma alloc_text( PAGE, MupCheckForUnregisteredProvider )
  35. #pragma alloc_text( PAGE, MupGetProviderInformation )
  36. #endif
  37. VOID
  38. MupGetProviderInformation (
  39. VOID
  40. )
  41. /*++
  42. Routine Description:
  43. This routine reads MUP information from the registry and saves it for
  44. future use.
  45. Arguments:
  46. None.
  47. Return Value:
  48. None.
  49. --*/
  50. {
  51. HANDLE handle;
  52. NTSTATUS status;
  53. UNICODE_STRING valueName;
  54. UNICODE_STRING keyName;
  55. OBJECT_ATTRIBUTES objectAttributes;
  56. PVOID buffer = NULL;
  57. PWCH providerName;
  58. ULONG lengthRequired;
  59. BOOLEAN done;
  60. ULONG priority;
  61. PWCH sep;
  62. PAGED_CODE();
  63. RtlInitUnicodeString( &keyName, L"\\Registry\\Machine\\System\\CurrentControlSet\\Control\\Networkprovider\\Order" );
  64. InitializeObjectAttributes(
  65. &objectAttributes,
  66. &keyName,
  67. OBJ_CASE_INSENSITIVE,
  68. 0,
  69. NULL
  70. );
  71. status = ZwOpenKey(
  72. &handle,
  73. KEY_QUERY_VALUE,
  74. &objectAttributes
  75. );
  76. if ( !NT_SUCCESS( status )) {
  77. return;
  78. }
  79. RtlInitUnicodeString( &valueName, L"ProviderOrder" );
  80. status = ZwQueryValueKey(
  81. handle,
  82. &valueName,
  83. KeyValueFullInformation,
  84. buffer,
  85. 0,
  86. &lengthRequired
  87. );
  88. if ( status == STATUS_BUFFER_TOO_SMALL ) {
  89. buffer = ExAllocatePoolWithTag( PagedPool, lengthRequired + 2, ' puM');
  90. if ( buffer == NULL) {
  91. return;
  92. }
  93. status = ZwQueryValueKey(
  94. handle,
  95. &valueName,
  96. KeyValueFullInformation,
  97. buffer,
  98. lengthRequired,
  99. &lengthRequired
  100. );
  101. }
  102. ZwClose( handle );
  103. if ( !NT_SUCCESS( status) ) {
  104. if ( buffer != NULL ) {
  105. ExFreePool( buffer );
  106. }
  107. return;
  108. }
  109. //
  110. // Scan the ordered list of providers, and create record for each.
  111. //
  112. providerName = (PWCH)((PCHAR)buffer + ((PKEY_VALUE_FULL_INFORMATION)buffer)->DataOffset);
  113. done = FALSE;
  114. priority = 0;
  115. while ( !done ) {
  116. sep = wcschr( providerName, L',');
  117. if ( sep == NULL ) {
  118. done = TRUE;
  119. } else {
  120. *sep = L'\0';
  121. }
  122. InitializeProvider( providerName, priority );
  123. priority++;
  124. providerName = sep+1;
  125. }
  126. ExFreePool( buffer );
  127. return;
  128. }
  129. VOID
  130. InitializeProvider(
  131. PWCH ProviderName,
  132. ULONG Priority
  133. )
  134. /*++
  135. Routine Description:
  136. This routine reads provider information out of the registry and
  137. creates an unregistered provider entry.
  138. Arguments:
  139. ProviderName - The registry name for the provider.
  140. Priority - The priority to assign to this provider.
  141. Return Value:
  142. None.
  143. --*/
  144. {
  145. UNICODE_STRING keyName;
  146. PVOID buffer = NULL;
  147. ULONG bufferLength;
  148. NTSTATUS status;
  149. OBJECT_ATTRIBUTES objectAttributes;
  150. ULONG lengthRequired;
  151. UNICODE_STRING valueName;
  152. HANDLE handle;
  153. PAGED_CODE();
  154. //
  155. // Allocate space for the registry string
  156. //
  157. bufferLength = sizeof( L"\\Registry\\Machine\\System\\CurrentControlSet\\Services\\" ) +
  158. wcslen( ProviderName ) * sizeof( WCHAR ) +
  159. sizeof( L"\\NetworkProvider" );
  160. buffer = ExAllocatePoolWithTag( PagedPool, bufferLength, ' puM' );
  161. if ( buffer == NULL ) {
  162. return;
  163. }
  164. //
  165. // Build the registry string
  166. //
  167. RtlMoveMemory(
  168. buffer,
  169. L"\\Registry\\Machine\\System\\CurrentControlSet\\Services\\",
  170. sizeof( L"\\Registry\\Machine\\System\\CurrentControlSet\\Services\\" )
  171. );
  172. keyName.Buffer = buffer;
  173. keyName.MaximumLength = (USHORT)bufferLength;
  174. keyName.Length = sizeof( L"\\Registry\\Machine\\System\\CurrentControlSet\\Services\\" ) - 2;
  175. status = RtlAppendUnicodeToString( &keyName, ProviderName );
  176. ASSERT( NT_SUCCESS( status ) );
  177. status = RtlAppendUnicodeToString( &keyName, L"\\NetworkProvider" );
  178. ASSERT( NT_SUCCESS( status ) );
  179. InitializeObjectAttributes(
  180. &objectAttributes,
  181. &keyName,
  182. OBJ_CASE_INSENSITIVE,
  183. 0,
  184. NULL
  185. );
  186. status = ZwOpenKey(
  187. &handle,
  188. KEY_QUERY_VALUE,
  189. &objectAttributes
  190. );
  191. ExFreePool( buffer );
  192. if ( !NT_SUCCESS( status )) {
  193. return;
  194. }
  195. buffer = NULL;
  196. RtlInitUnicodeString( &valueName, L"DeviceName" );
  197. status = ZwQueryValueKey(
  198. handle,
  199. &valueName,
  200. KeyValueFullInformation,
  201. buffer,
  202. 0,
  203. &lengthRequired
  204. );
  205. if ( status == STATUS_BUFFER_TOO_SMALL ) {
  206. buffer = ExAllocatePoolWithTag( PagedPool, lengthRequired + 2, ' puM' );
  207. if ( buffer == NULL) {
  208. return;
  209. }
  210. status = ZwQueryValueKey(
  211. handle,
  212. &valueName,
  213. KeyValueFullInformation,
  214. buffer,
  215. lengthRequired,
  216. &lengthRequired
  217. );
  218. }
  219. if ( !NT_SUCCESS( status) ) {
  220. if ( buffer != NULL ) {
  221. ExFreePool( buffer );
  222. }
  223. ZwClose( handle );
  224. return;
  225. }
  226. //
  227. // Wahoo! We actually have the device name in hand. Add the
  228. // provider to the unregistered list.
  229. //
  230. AddUnregisteredProvider(
  231. (PWCH)((PCHAR)buffer + ((PKEY_VALUE_FULL_INFORMATION)buffer)->DataOffset),
  232. Priority
  233. );
  234. ExFreePool( buffer );
  235. ZwClose( handle );
  236. return;
  237. }
  238. PUNC_PROVIDER
  239. MupCheckForUnregisteredProvider(
  240. PUNICODE_STRING DeviceName
  241. )
  242. /*++
  243. Routine Description:
  244. This routine checks the list of unregistered providers for one whose
  245. device name matches the provider attempting to register.
  246. If one is found it is dequeued from the list of unregistered providers.
  247. Arguments:
  248. DeviceName - The device name of the registering provider.
  249. Return Value:
  250. UNC_PROVIDER - A pointer to the matching unregistered provider, or
  251. NULL if no match is found.
  252. --*/
  253. {
  254. PLIST_ENTRY listEntry;
  255. PUNC_PROVIDER uncProvider;
  256. PAGED_CODE();
  257. MupAcquireGlobalLock();
  258. for (listEntry = MupUnregisteredProviderList.Flink;
  259. listEntry != &MupUnregisteredProviderList;
  260. listEntry = listEntry->Flink ) {
  261. uncProvider = CONTAINING_RECORD( listEntry, UNC_PROVIDER, ListEntry );
  262. //
  263. // If we find a match take it out of the unregistered list, and
  264. // return it to the caller.
  265. //
  266. if ( RtlEqualUnicodeString( DeviceName, &uncProvider->DeviceName, TRUE )) {
  267. RemoveEntryList( listEntry );
  268. uncProvider->BlockHeader.BlockState = BlockStateActive;
  269. MupReleaseGlobalLock();
  270. return uncProvider;
  271. }
  272. }
  273. MupReleaseGlobalLock();
  274. return NULL;
  275. }
  276. VOID
  277. AddUnregisteredProvider(
  278. PWCH ProviderName,
  279. ULONG Priority
  280. )
  281. /*++
  282. Routine Description:
  283. This routine queues an unregistered provider on a list.
  284. Arguments:
  285. ProviderName - The device name of the provider. (from the registry)
  286. Priority - A priority for the provider.
  287. Return Value:
  288. None.
  289. --*/
  290. {
  291. ULONG nameLength;
  292. PUNC_PROVIDER uncProvider;
  293. PAGED_CODE();
  294. nameLength = wcslen( ProviderName ) * 2;
  295. try {
  296. uncProvider = MupAllocateUncProvider( nameLength );
  297. uncProvider->DeviceName.MaximumLength = (USHORT)nameLength;
  298. uncProvider->DeviceName.Length = (USHORT)nameLength;
  299. uncProvider->DeviceName.Buffer = (PWCH)(uncProvider + 1);
  300. uncProvider->Priority = Priority;
  301. RtlMoveMemory(
  302. (PVOID)(uncProvider + 1),
  303. ProviderName,
  304. nameLength
  305. );
  306. MupAcquireGlobalLock();
  307. InsertTailList( &MupUnregisteredProviderList, &uncProvider->ListEntry );
  308. MupReleaseGlobalLock();
  309. } except ( EXCEPTION_EXECUTE_HANDLER ) {
  310. NOTHING;
  311. }
  312. }