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.

1098 lines
25 KiB

  1. /*++
  2. Copyright (c) 1991 Microsoft Corporation
  3. Module Name:
  4. Registry.c
  5. Abstract:
  6. This contains all routines necessary to load the lana number to device pathname
  7. mapping and the Lana Enum record.
  8. Author:
  9. Colin Watson (colinw) 14-Mar-1992
  10. Revision History:
  11. Notes:
  12. The fcb holds an area for registry workspace. this is where the strings
  13. used to hold the DriverNames will be held in a single allocation.
  14. build with -DUTILITY to run as a test application.
  15. --*/
  16. #include "Nb.h"
  17. //#include <zwapi.h>
  18. //#include <stdlib.h>
  19. #include <crt\stdlib.h>
  20. #define DEFAULT_VALUE_SIZE 4096
  21. #define ROUNDUP_TO_LONG(x) (((x) + sizeof(PVOID) - 1) & ~(sizeof(PVOID) - 1))
  22. #ifdef UTILITY
  23. #define ZwClose NtClose
  24. #define ZwCreateKey NtCreateKey
  25. #define ZwOpenKey NtOpenKey
  26. #define ZwQueryValueKey NtQueryValueKey
  27. #define ExFreePool free
  28. #endif
  29. //
  30. // Local functions used to access the registry.
  31. //
  32. NTSTATUS
  33. NbOpenRegistry(
  34. IN PUNICODE_STRING BaseName,
  35. OUT PHANDLE LinkageHandle,
  36. OUT PHANDLE ParametersHandle
  37. );
  38. VOID
  39. NbCloseRegistry(
  40. IN HANDLE LinkageHandle,
  41. IN HANDLE ParametersHandle
  42. );
  43. NTSTATUS
  44. NbReadLinkageInformation(
  45. IN HANDLE LinkageHandle,
  46. IN HANDLE ParametersHandle,
  47. IN PFCB pfcb,
  48. IN BOOL bDeviceCreate
  49. );
  50. ULONG
  51. NbReadSingleParameter(
  52. IN HANDLE ParametersHandle,
  53. IN PWCHAR ValueName,
  54. IN LONG DefaultValue
  55. );
  56. BOOLEAN
  57. NbCheckLana (
  58. PUNICODE_STRING DeviceName
  59. );
  60. //
  61. // Local function used to determine is specified device is Pnp enabled
  62. //
  63. #ifdef ALLOC_PRAGMA
  64. #pragma alloc_text(PAGE, GetIrpStackSize)
  65. #pragma alloc_text(PAGE, ReadRegistry)
  66. #pragma alloc_text(PAGE, NbFreeRegistryInfo)
  67. #pragma alloc_text(PAGE, NbOpenRegistry)
  68. #pragma alloc_text(PAGE, NbCloseRegistry)
  69. #pragma alloc_text(PAGE, NbReadLinkageInformation)
  70. #pragma alloc_text(PAGE, NbReadSingleParameter)
  71. #pragma alloc_text(PAGE, NbCheckLana)
  72. #endif
  73. CCHAR
  74. GetIrpStackSize(
  75. IN PUNICODE_STRING RegistryPath,
  76. IN CCHAR DefaultValue
  77. )
  78. /*++
  79. Routine Description:
  80. This routine is called by NbCreateDeviceContext to get the IRP
  81. stack size to be "exported" by the NetBIOS device.
  82. Arguments:
  83. RegistryPath - The name of Nb's node in the registry.
  84. DefaultValue - IRP stack size to be used if no registry value present.
  85. Return Value:
  86. CCHAR - IRP stack size to be stored in the device object.
  87. --*/
  88. {
  89. HANDLE LinkageHandle;
  90. HANDLE ParametersHandle;
  91. NTSTATUS Status;
  92. ULONG stackSize;
  93. PAGED_CODE();
  94. Status = NbOpenRegistry (RegistryPath, &LinkageHandle, &ParametersHandle);
  95. if (Status != STATUS_SUCCESS) {
  96. return DefaultValue;
  97. }
  98. //
  99. // Read the stack size value from the registry.
  100. //
  101. stackSize = NbReadSingleParameter(
  102. ParametersHandle,
  103. REGISTRY_IRP_STACK_SIZE,
  104. DefaultValue );
  105. if ( stackSize > 255 ) {
  106. stackSize = 255;
  107. }
  108. NbCloseRegistry (LinkageHandle, ParametersHandle);
  109. return (CCHAR)stackSize;
  110. }
  111. NTSTATUS
  112. ReadRegistry(
  113. IN PUNICODE_STRING pusRegistryPath,
  114. IN PFCB NewFcb,
  115. IN BOOLEAN bDeviceCreate
  116. )
  117. /*++
  118. Routine Description:
  119. This routine is called by Nb to get information from the registry,
  120. starting at RegistryPath to get the parameters.
  121. Arguments:
  122. DeviceContext - Supplies RegistryPath. The name of Nb's node in the registry.
  123. NewFcb - Destination for the configuration information.
  124. Return Value:
  125. NTSTATUS - STATUS_SUCCESS if everything OK, STATUS_INSUFFICIENT_RESOURCES
  126. otherwise.
  127. --*/
  128. {
  129. HANDLE LinkageHandle;
  130. HANDLE ParametersHandle;
  131. NTSTATUS Status;
  132. PAGED_CODE();
  133. NewFcb->RegistrySpace = NULL; // No registry workspace.
  134. NewFcb->LanaEnum.length = 0;
  135. Status = NbOpenRegistry ( pusRegistryPath, &LinkageHandle, &ParametersHandle);
  136. if (Status != STATUS_SUCCESS) {
  137. return STATUS_UNSUCCESSFUL;
  138. }
  139. //
  140. // Read in the NDIS binding information (if none is present
  141. // the array will be filled with all known drivers).
  142. //
  143. Status = NbReadLinkageInformation (
  144. LinkageHandle,
  145. ParametersHandle,
  146. NewFcb,
  147. bDeviceCreate);
  148. NbCloseRegistry (LinkageHandle, ParametersHandle);
  149. return Status;
  150. }
  151. //----------------------------------------------------------------------------
  152. // GetLanaMap
  153. //
  154. // retrieves the lana map structure.
  155. // Allocates the memory required for the lana map structure that must be
  156. // deallocated after use.
  157. //----------------------------------------------------------------------------
  158. NTSTATUS
  159. GetLanaMap(
  160. IN PUNICODE_STRING pusRegistryPath,
  161. IN OUT PKEY_VALUE_FULL_INFORMATION * ppkvfi
  162. )
  163. {
  164. HANDLE hLinkage = NULL;
  165. HANDLE hParameters = NULL;
  166. NTSTATUS nsStatus;
  167. PKEY_VALUE_FULL_INFORMATION pkvfiValue = NULL;
  168. ULONG ulValueSize;
  169. PWSTR wsLanaMapName = REGISTRY_LANA_MAP;
  170. UNICODE_STRING usLanaMap;
  171. ULONG ulBytesWritten;
  172. PAGED_CODE();
  173. do
  174. {
  175. *ppkvfi = NULL;
  176. //
  177. // open registry keys
  178. //
  179. nsStatus = NbOpenRegistry ( pusRegistryPath, &hLinkage, &hParameters );
  180. if ( !NT_SUCCESS( nsStatus ) )
  181. {
  182. break;
  183. }
  184. //
  185. // allocate for lana map.
  186. //
  187. pkvfiValue = ExAllocatePoolWithTag(
  188. PagedPool, MAXIMUM_LANA * sizeof( LANA_MAP ), 'rSBN'
  189. );
  190. if ( pkvfiValue == NULL )
  191. {
  192. nsStatus = STATUS_UNSUCCESSFUL;
  193. NbPrint( (
  194. "GetLanaMap : Allocation failed for %d bytes\n", DEFAULT_VALUE_SIZE
  195. ) );
  196. break;
  197. }
  198. ulValueSize = MAXIMUM_LANA * sizeof( LANA_MAP );
  199. //
  200. // query "LanaMap" value
  201. //
  202. RtlInitUnicodeString (&usLanaMap, wsLanaMapName);
  203. nsStatus = ZwQueryValueKey(
  204. hLinkage,
  205. &usLanaMap,
  206. KeyValueFullInformation,
  207. pkvfiValue,
  208. ulValueSize,
  209. &ulBytesWritten
  210. );
  211. if (!NT_SUCCESS(nsStatus))
  212. {
  213. NbPrint ( (
  214. "GetLanaMap : failed querying lana map key %x", nsStatus
  215. ) );
  216. break;
  217. }
  218. if ( ulBytesWritten == 0 )
  219. {
  220. nsStatus = STATUS_UNSUCCESSFUL;
  221. NbPrint ( ("GetLanaMap : querying lana map key returned 0 bytes") );
  222. break;
  223. }
  224. *ppkvfi = pkvfiValue;
  225. NbCloseRegistry (hLinkage, hParameters);
  226. return nsStatus;
  227. } while (FALSE);
  228. if ( pkvfiValue != NULL )
  229. {
  230. ExFreePool( pkvfiValue );
  231. }
  232. NbCloseRegistry (hLinkage, hParameters);
  233. return nsStatus;
  234. }
  235. //----------------------------------------------------------------------------
  236. // GetMaxLana
  237. //
  238. // retrieves the MaxLana value from the netbios parameters key.
  239. //----------------------------------------------------------------------------
  240. NTSTATUS
  241. GetMaxLana(
  242. IN PUNICODE_STRING pusRegistryPath,
  243. IN OUT PULONG pulMaxLana
  244. )
  245. {
  246. HANDLE hLinkage = NULL;
  247. HANDLE hParameters = NULL;
  248. NTSTATUS nsStatus;
  249. UCHAR ucBuffer[ 256 ];
  250. PKEY_VALUE_FULL_INFORMATION pkvfiValue =
  251. (PKEY_VALUE_FULL_INFORMATION) ucBuffer;
  252. ULONG ulValueSize;
  253. PWSTR wsMaxLana = REGISTRY_MAX_LANA;
  254. UNICODE_STRING usMaxLana;
  255. ULONG ulBytesWritten;
  256. PAGED_CODE();
  257. do
  258. {
  259. *pulMaxLana = 0;
  260. //
  261. // open registry keys
  262. //
  263. nsStatus = NbOpenRegistry ( pusRegistryPath, &hLinkage, &hParameters );
  264. if ( !NT_SUCCESS( nsStatus ) )
  265. {
  266. NbPrint( ("GetMaxLana : Failed to open registry" ) );
  267. nsStatus = STATUS_UNSUCCESSFUL;
  268. break;
  269. }
  270. //
  271. // allocate for key value.
  272. //
  273. ulValueSize = sizeof( ucBuffer );
  274. //
  275. // query "MaxLana" value
  276. //
  277. RtlInitUnicodeString (&usMaxLana, wsMaxLana);
  278. nsStatus = ZwQueryValueKey(
  279. hParameters,
  280. &usMaxLana,
  281. KeyValueFullInformation,
  282. pkvfiValue,
  283. ulValueSize,
  284. &ulBytesWritten
  285. );
  286. if (!NT_SUCCESS(nsStatus))
  287. {
  288. NbPrint ( (
  289. "GetMaxLana : failed querying lana map key %x", nsStatus
  290. ) );
  291. break;
  292. }
  293. if ( ulBytesWritten == 0 )
  294. {
  295. NbPrint ( ("GetMaxLana : querying lana map key returned 0 bytes") );
  296. nsStatus = STATUS_UNSUCCESSFUL;
  297. break;
  298. }
  299. *pulMaxLana = *( (PULONG) ( (PUCHAR) pkvfiValue + pkvfiValue-> DataOffset ) );
  300. NbCloseRegistry (hLinkage, hParameters);
  301. return nsStatus;
  302. } while ( FALSE );
  303. NbCloseRegistry (hLinkage, hParameters);
  304. return nsStatus;
  305. }
  306. VOID
  307. NbFreeRegistryInfo (
  308. IN PFCB pfcb
  309. )
  310. /*++
  311. Routine Description:
  312. This routine is called by Nb to get free any storage that was allocated
  313. by NbConfigureTransport in producing the specified CONFIG_DATA structure.
  314. Arguments:
  315. ConfigurationInfo - A pointer to the configuration information structure.
  316. Return Value:
  317. None.
  318. --*/
  319. {
  320. PAGED_CODE();
  321. if ( pfcb->RegistrySpace != NULL ) {
  322. ExFreePool( pfcb->RegistrySpace );
  323. pfcb->RegistrySpace = NULL;
  324. }
  325. }
  326. NTSTATUS
  327. NbOpenRegistry(
  328. IN PUNICODE_STRING BaseName,
  329. OUT PHANDLE LinkageHandle,
  330. OUT PHANDLE ParametersHandle
  331. )
  332. /*++
  333. Routine Description:
  334. This routine is called by Nb to open the registry. If the registry
  335. tree exists, then it opens it and returns an error. If not, it
  336. creates the appropriate keys in the registry, opens it, and
  337. returns STATUS_SUCCESS.
  338. NOTE: If the key "ClearRegistry" exists in ntuser.cfg, then
  339. this routine will remove any existing registry values for Nb
  340. (but still create the tree if it doesn't exist) and return
  341. FALSE.
  342. Arguments:
  343. BaseName - Where in the registry to start looking for the information.
  344. LinkageHandle - Returns the handle used to read linkage information.
  345. ParametersHandle - Returns the handle used to read other
  346. parameters.
  347. Return Value:
  348. The status of the request.
  349. --*/
  350. {
  351. HANDLE NbConfigHandle;
  352. NTSTATUS Status;
  353. HANDLE LinkHandle;
  354. HANDLE ParamHandle;
  355. PWSTR LinkageString = REGISTRY_LINKAGE;
  356. PWSTR ParametersString = REGISTRY_PARAMETERS;
  357. UNICODE_STRING LinkageKeyName;
  358. UNICODE_STRING ParametersKeyName;
  359. OBJECT_ATTRIBUTES TmpObjectAttributes;
  360. ULONG Disposition;
  361. PAGED_CODE();
  362. //
  363. // Open the registry for the initial string.
  364. //
  365. InitializeObjectAttributes(
  366. &TmpObjectAttributes,
  367. BaseName, // name
  368. OBJ_CASE_INSENSITIVE, // attributes
  369. NULL, // root
  370. NULL // security descriptor
  371. );
  372. Status = ZwCreateKey(
  373. &NbConfigHandle,
  374. KEY_WRITE,
  375. &TmpObjectAttributes,
  376. 0, // title index
  377. NULL, // class
  378. 0, // create options
  379. &Disposition); // disposition
  380. if (!NT_SUCCESS(Status)) {
  381. return STATUS_UNSUCCESSFUL;
  382. }
  383. //
  384. // Open the Nb linkages key.
  385. //
  386. RtlInitUnicodeString (&LinkageKeyName, LinkageString);
  387. InitializeObjectAttributes(
  388. &TmpObjectAttributes,
  389. &LinkageKeyName, // name
  390. OBJ_CASE_INSENSITIVE, // attributes
  391. NbConfigHandle, // root
  392. NULL // security descriptor
  393. );
  394. Status = ZwOpenKey(
  395. &LinkHandle,
  396. KEY_READ,
  397. &TmpObjectAttributes);
  398. if (!NT_SUCCESS(Status)) {
  399. ZwClose (NbConfigHandle);
  400. return Status;
  401. }
  402. //
  403. // Now open the parameters key.
  404. //
  405. RtlInitUnicodeString (&ParametersKeyName, ParametersString);
  406. InitializeObjectAttributes(
  407. &TmpObjectAttributes,
  408. &ParametersKeyName, // name
  409. OBJ_CASE_INSENSITIVE, // attributes
  410. NbConfigHandle, // root
  411. NULL // security descriptor
  412. );
  413. Status = ZwOpenKey(
  414. &ParamHandle,
  415. KEY_READ,
  416. &TmpObjectAttributes);
  417. if (!NT_SUCCESS(Status)) {
  418. ZwClose (LinkHandle);
  419. ZwClose (NbConfigHandle);
  420. return Status;
  421. }
  422. *LinkageHandle = LinkHandle;
  423. *ParametersHandle = ParamHandle;
  424. //
  425. // All keys successfully opened or created.
  426. //
  427. ZwClose (NbConfigHandle);
  428. return STATUS_SUCCESS;
  429. } /* NbOpenRegistry */
  430. VOID
  431. NbCloseRegistry(
  432. IN HANDLE LinkageHandle,
  433. IN HANDLE ParametersHandle
  434. )
  435. /*++
  436. Routine Description:
  437. This routine is called by Nb to close the registry. It closes
  438. the handles passed in and does any other work needed.
  439. Arguments:
  440. LinkageHandle - The handle used to read linkage information.
  441. ParametersHandle - The handle used to read other parameters.
  442. Return Value:
  443. None.
  444. --*/
  445. {
  446. PAGED_CODE();
  447. ZwClose (LinkageHandle);
  448. ZwClose (ParametersHandle);
  449. } /* NbCloseRegistry */
  450. NTSTATUS
  451. NbReadLinkageInformation(
  452. IN HANDLE LinkageHandle,
  453. IN HANDLE ParametersHandle,
  454. IN PFCB pfcb,
  455. IN BOOL bCreateDevice
  456. )
  457. /*++
  458. Routine Description:
  459. This routine is called by Nb to read its linkage information
  460. from the registry. If there is none present, then ConfigData
  461. is filled with a list of all the adapters that are known
  462. to Nb.
  463. Arguments:
  464. LinkageHandle - Supplies the Linkage key in netbios
  465. ParametersHandle
  466. pfcb - Describes Nb's current configuration.
  467. Return Value:
  468. Status
  469. --*/
  470. {
  471. PWSTR BindName = REGISTRY_BIND;
  472. UNICODE_STRING BindString;
  473. NTSTATUS Status;
  474. PKEY_VALUE_FULL_INFORMATION Value = NULL;
  475. ULONG ValueSize;
  476. PWSTR LanaMapName = REGISTRY_LANA_MAP;
  477. UNICODE_STRING LanaMapString;
  478. PLANA_MAP pLanaMap;
  479. ULONG BytesWritten;
  480. UINT ConfigBindings = 0;
  481. PWSTR CurBindValue;
  482. UINT index;
  483. PAGED_CODE();
  484. pfcb->MaxLana = NbReadSingleParameter( ParametersHandle, REGISTRY_MAX_LANA, -1 );
  485. if (pfcb->MaxLana > MAXIMUM_LANA) {
  486. return STATUS_INVALID_PARAMETER;
  487. }
  488. NbPrint( (
  489. "Netbios : NbReadLinkageInformation : MaxLana = %d\n",
  490. pfcb-> MaxLana
  491. ) );
  492. //
  493. // Read the "Bind" key.
  494. //
  495. RtlInitUnicodeString (&BindString, BindName);
  496. #ifdef UTILITY
  497. Value = malloc( DEFAULT_VALUE_SIZE);
  498. #else
  499. Value = ExAllocatePoolWithTag(PagedPool, DEFAULT_VALUE_SIZE, 'rSBN');
  500. #endif
  501. if ( Value == NULL ) {
  502. return STATUS_INSUFFICIENT_RESOURCES;
  503. }
  504. ValueSize = DEFAULT_VALUE_SIZE;
  505. pfcb->RegistrySpace = NULL;
  506. try {
  507. Status = ZwQueryValueKey(
  508. LinkageHandle,
  509. &BindString,
  510. KeyValueFullInformation,
  511. Value,
  512. ValueSize,
  513. &BytesWritten
  514. );
  515. if ( Status == STATUS_BUFFER_OVERFLOW) {
  516. ExFreePool( Value );
  517. // Now request with exactly the right size
  518. ValueSize = BytesWritten;
  519. #ifdef UTILITY
  520. Value = malloc( ValueSize);
  521. #else
  522. Value = ExAllocatePoolWithTag(PagedPool, ValueSize, 'rSBN');
  523. #endif
  524. if ( Value == NULL ) {
  525. try_return( Status = STATUS_INSUFFICIENT_RESOURCES);
  526. }
  527. Status = ZwQueryValueKey(
  528. LinkageHandle,
  529. &BindString,
  530. KeyValueFullInformation,
  531. Value,
  532. ValueSize,
  533. &BytesWritten
  534. );
  535. }
  536. if (!NT_SUCCESS(Status)) {
  537. try_return( Status );
  538. }
  539. if ( BytesWritten == 0 ) {
  540. try_return( Status = STATUS_ILL_FORMED_SERVICE_ENTRY);
  541. }
  542. //
  543. // Alloc space for Registry stuff as well as pDriverName array.
  544. //
  545. #ifdef UTILITY
  546. pfcb->RegistrySpace = malloc(ROUNDUP_TO_LONG(BytesWritten - Value->DataOffset) +
  547. (sizeof(UNICODE_STRING) * (pfcb->MaxLana+1)));
  548. #else
  549. pfcb->RegistrySpace = ExAllocatePoolWithTag(PagedPool,
  550. ROUNDUP_TO_LONG(BytesWritten - Value->DataOffset) +
  551. (sizeof(UNICODE_STRING) * (pfcb->MaxLana+1)), 'rSBN');
  552. #endif
  553. if ( pfcb->RegistrySpace == NULL ) {
  554. try_return( Status = STATUS_INSUFFICIENT_RESOURCES);
  555. }
  556. RtlMoveMemory(pfcb->RegistrySpace,
  557. (PUCHAR)Value + Value->DataOffset,
  558. BytesWritten - Value->DataOffset);
  559. pfcb->pDriverName =
  560. (PUNICODE_STRING) ((PBYTE) pfcb->RegistrySpace +
  561. ROUNDUP_TO_LONG(BytesWritten-Value->DataOffset));
  562. //
  563. // Read the "LanaMap" key into Storage.
  564. //
  565. RtlInitUnicodeString (&LanaMapString, LanaMapName);
  566. Status = ZwQueryValueKey(
  567. LinkageHandle,
  568. &LanaMapString,
  569. KeyValueFullInformation,
  570. Value,
  571. ValueSize,
  572. &BytesWritten
  573. );
  574. if (!NT_SUCCESS(Status)) {
  575. try_return( Status );
  576. }
  577. if ( BytesWritten == 0 ) {
  578. try_return( Status = STATUS_ILL_FORMED_SERVICE_ENTRY);
  579. }
  580. // Point pLanaMap at the data from the registry.
  581. pLanaMap = (PLANA_MAP)((PUCHAR)Value + Value->DataOffset);
  582. //
  583. // For each binding, initialize the drivername string.
  584. //
  585. for ( index = 0 ; index <= pfcb->MaxLana ; index++ ) {
  586. // Initialize unused drivernames to NULL name
  587. RtlInitUnicodeString (&pfcb->pDriverName[index], NULL);
  588. }
  589. CurBindValue = (PWCHAR)pfcb->RegistrySpace;
  590. IF_NBDBG( NB_DEBUG_FILE )
  591. {
  592. NbPrint( ("NETBIOS: Enumerating lanas ...\n") );
  593. }
  594. while (*CurBindValue != 0) {
  595. if ((ConfigBindings > pfcb->MaxLana) ||
  596. (pLanaMap[ConfigBindings].Lana > pfcb->MaxLana)) {
  597. try_return( Status = STATUS_INVALID_PARAMETER);
  598. }
  599. RtlInitUnicodeString (
  600. &pfcb->pDriverName[pLanaMap[ConfigBindings].Lana],
  601. CurBindValue);
  602. //
  603. // Only non PNP devices are created here. PnP devices
  604. // are created as required in the bind handler in file.c
  605. //
  606. // V Raman
  607. //
  608. if ( bCreateDevice &&
  609. pLanaMap[ConfigBindings].Enum != FALSE ) {
  610. if (NbCheckLana (
  611. &pfcb->pDriverName[pLanaMap[ConfigBindings].Lana]))
  612. {
  613. //
  614. // Record that the lana number is enabled
  615. //
  616. pfcb->LanaEnum.lana[pfcb->LanaEnum.length] =
  617. pLanaMap[ConfigBindings].Lana;
  618. pfcb->LanaEnum.length++;
  619. IF_NBDBG( NB_DEBUG_FILE )
  620. {
  621. NbPrint( ("NETBIOS: Lana %d (%ls) added OK.\n",
  622. pLanaMap[ConfigBindings].Lana, CurBindValue) );
  623. }
  624. }
  625. else
  626. {
  627. IF_NBDBG( NB_DEBUG_FILE )
  628. {
  629. NbPrint( ("NETBIOS: Lana's %d %ls could not be opened.\n",
  630. pLanaMap[ConfigBindings].Lana, CurBindValue) );
  631. }
  632. }
  633. }
  634. else
  635. {
  636. IF_NBDBG( NB_DEBUG_FILE )
  637. {
  638. NbPrint( ("NbReadLinkageInformation : Lana %d (%ls) is not enumerated.\n",
  639. pLanaMap[ConfigBindings].Lana, CurBindValue) );
  640. }
  641. }
  642. ++ConfigBindings;
  643. //
  644. // Now advance the "Bind" value.
  645. //
  646. CurBindValue += wcslen(CurBindValue) + 1;
  647. }
  648. try_return( Status = STATUS_SUCCESS);
  649. try_exit:NOTHING;
  650. } finally {
  651. if ( !NT_SUCCESS(Status) ) {
  652. ExFreePool( pfcb->RegistrySpace );
  653. pfcb->RegistrySpace = NULL;
  654. }
  655. if ( Value != NULL ) {
  656. ExFreePool( Value );
  657. }
  658. }
  659. return Status;
  660. } /* NbReadLinkageInformation */
  661. ULONG
  662. NbReadSingleParameter(
  663. IN HANDLE ParametersHandle,
  664. IN PWCHAR ValueName,
  665. IN LONG DefaultValue
  666. )
  667. /*++
  668. Routine Description:
  669. This routine is called by Nb to read a single parameter
  670. from the registry. If the parameter is found it is stored
  671. in Data.
  672. Arguments:
  673. ParametersHandle - A pointer to the open registry.
  674. ValueName - The name of the value to search for.
  675. DefaultValue - The default value.
  676. Return Value:
  677. The value to use; will be the default if the value is not
  678. found or is not in the correct range.
  679. --*/
  680. {
  681. ULONG InformationBuffer[16]; // declare ULONG to get it aligned
  682. PKEY_VALUE_FULL_INFORMATION Information =
  683. (PKEY_VALUE_FULL_INFORMATION)InformationBuffer;
  684. UNICODE_STRING ValueKeyName;
  685. ULONG InformationLength;
  686. LONG ReturnValue;
  687. NTSTATUS Status;
  688. PAGED_CODE();
  689. RtlInitUnicodeString (&ValueKeyName, ValueName);
  690. Status = ZwQueryValueKey(
  691. ParametersHandle,
  692. &ValueKeyName,
  693. KeyValueFullInformation,
  694. (PVOID)Information,
  695. sizeof (InformationBuffer),
  696. &InformationLength);
  697. if ((Status == STATUS_SUCCESS) && (Information->DataLength == sizeof(ULONG))) {
  698. RtlMoveMemory(
  699. (PVOID)&ReturnValue,
  700. ((PUCHAR)Information) + Information->DataOffset,
  701. sizeof(ULONG));
  702. if (ReturnValue < 0) {
  703. ReturnValue = DefaultValue;
  704. }
  705. } else {
  706. ReturnValue = DefaultValue;
  707. }
  708. return ReturnValue;
  709. } /* NbReadSingleParameter */
  710. BOOLEAN
  711. NbCheckLana (
  712. PUNICODE_STRING DeviceName
  713. )
  714. /*++
  715. Routine Description:
  716. This routine uses the transport to create an entry in the NetBIOS
  717. table with the value of "Name". It will re-use an existing entry if
  718. "Name" already exists.
  719. Note: This synchronous call may take a number of seconds. If this matters
  720. then the caller should specify ASYNCH and a post routine so that it is
  721. performed by the thread created by the netbios dll routines.
  722. If pdncb == NULL then a special handle is returned that is capable of
  723. administering the transport. For example to execute an ASTAT.
  724. Arguments:
  725. FileHandle - Pointer to where the filehandle is to be returned.
  726. *Object - Pointer to where the file object pointer is to be stored
  727. pfcb - supplies the device names for the lana number.
  728. LanNumber - supplies the network adapter to be opened.
  729. pdncb - Pointer to either an NCB or NULL.
  730. Return Value:
  731. The function value is the status of the operation.
  732. --*/
  733. {
  734. IO_STATUS_BLOCK IoStatusBlock;
  735. NTSTATUS Status;
  736. OBJECT_ATTRIBUTES ObjectAttributes;
  737. HANDLE FileHandle;
  738. PAGED_CODE();
  739. InitializeObjectAttributes (
  740. &ObjectAttributes,
  741. DeviceName,
  742. 0,
  743. NULL,
  744. NULL);
  745. Status = ZwCreateFile (
  746. &FileHandle,
  747. GENERIC_READ | GENERIC_WRITE, // desired access.
  748. &ObjectAttributes, // object attributes.
  749. &IoStatusBlock, // returned status information.
  750. NULL, // Allocation size (unused).
  751. FILE_ATTRIBUTE_NORMAL, // file attributes.
  752. FILE_SHARE_WRITE,
  753. FILE_CREATE,
  754. 0, // create options.
  755. NULL,
  756. 0
  757. );
  758. if ( NT_SUCCESS( Status )) {
  759. Status = IoStatusBlock.Status;
  760. }
  761. if (NT_SUCCESS( Status )) {
  762. NTSTATUS localstatus;
  763. localstatus = ZwClose( FileHandle);
  764. ASSERT(NT_SUCCESS(localstatus));
  765. return TRUE;
  766. }
  767. else {
  768. NbPrint( (
  769. "NbCheckLana : Create file failed for %s with code %x iostatus %x\n",
  770. DeviceName-> Buffer, Status, IoStatusBlock.Status
  771. ) );
  772. return FALSE;
  773. }
  774. }
  775. #ifdef UTILITY
  776. void
  777. _cdecl
  778. main (argc, argv)
  779. int argc;
  780. char *argv[];
  781. {
  782. DEVICE_CONTEXT DeviceContext;
  783. FCB NewFcb;
  784. RtlInitUnicodeString(&DeviceContext.RegistryPath, L"\\Registry\\Machine\\System\\CurrentControlSet\\Services\\Netbios");
  785. ReadRegistry(
  786. &DeviceContext,
  787. &NewFcb
  788. );
  789. }
  790. #endif