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.

1046 lines
30 KiB

  1. /*************************************************************************
  2. *
  3. * tdnetb.c
  4. *
  5. * NETBIOS transport specific routines for TDI interface.
  6. *
  7. * Copyright 1998, Microsoft
  8. *
  9. *************************************************************************/
  10. #include <ntddk.h>
  11. #include <tdi.h>
  12. #include <winstaw.h>
  13. #define _DEFCHARINFO_
  14. #include <icadd.h>
  15. #include <ctxdd.h>
  16. #include <sdapi.h>
  17. #include <td.h>
  18. #include "tdtdi.h"
  19. #include "tdnetb.h"
  20. #ifdef _HYDRA_
  21. // This becomes the device name
  22. PWCHAR ModuleName = L"tdnetb";
  23. #endif
  24. /*=============================================================================
  25. == External Functions Defined
  26. =============================================================================*/
  27. NTSTATUS TdiDeviceOpen( PTD, PSD_OPEN );
  28. NTSTATUS TdiDeviceClose( PTD, PSD_CLOSE );
  29. NTSTATUS TdiDeviceOpenEndpoint( PTD, PVOID, ULONG );
  30. NTSTATUS TdiDeviceBuildTransportNameAndAddress( PTD, PICA_STACK_ADDRESS,
  31. PUNICODE_STRING,
  32. PTRANSPORT_ADDRESS *, PULONG );
  33. NTSTATUS TdiDeviceBuildWildcardAddress( PTD, PTRANSPORT_ADDRESS *, PULONG );
  34. NTSTATUS TdiDeviceWaitForDatagramConnection( PTD, PFILE_OBJECT, PDEVICE_OBJECT,
  35. PTRANSPORT_ADDRESS *, PULONG );
  36. NTSTATUS TdiDeviceCompleteDatagramConnection( PTD, PFILE_OBJECT, PDEVICE_OBJECT, PTRANSPORT_ADDRESS, ULONG );
  37. NTSTATUS TdiDeviceConnectionSend( PTD );
  38. NTSTATUS TdiDeviceReadComplete( PTD, PUCHAR, PULONG );
  39. /*=============================================================================
  40. == External Functions Referenced
  41. =============================================================================*/
  42. NTSTATUS MemoryAllocate( ULONG, PVOID * );
  43. VOID MemoryFree( PVOID );
  44. /*=============================================================================
  45. == Internal Functions Defined
  46. =============================================================================*/
  47. NTSTATUS _NetBiosGetTransportName( PTD, LONG, PUNICODE_STRING );
  48. NTSTATUS _GetComputerName( PTD, PUNICODE_STRING );
  49. VOID GetGUID( PUNICODE_STRING ,int);
  50. NTSTATUS
  51. _OpenRegKey(
  52. PHANDLE HandlePtr,
  53. PWCHAR KeyName
  54. );
  55. NTSTATUS
  56. _GetRegDWORDValue(
  57. HANDLE KeyHandle,
  58. PWCHAR ValueName,
  59. PULONG ValueData
  60. );
  61. NTSTATUS
  62. _GetRegStringValue(
  63. HANDLE KeyHandle,
  64. PWCHAR ValueName,
  65. PKEY_VALUE_PARTIAL_INFORMATION *ValueData,
  66. PUSHORT ValueSize
  67. );
  68. NTSTATUS
  69. _GetRegMultiSZValue(
  70. HANDLE KeyHandle,
  71. PWCHAR ValueName,
  72. PUNICODE_STRING ValueData
  73. );
  74. NTSTATUS
  75. _GetRegSZValue(
  76. HANDLE KeyHandle,
  77. PWCHAR ValueName,
  78. PUNICODE_STRING ValueData,
  79. PULONG ValueType
  80. );
  81. PWCHAR
  82. _EnumRegMultiSz(
  83. PWCHAR MszString,
  84. ULONG MszStringLength,
  85. ULONG StringIndex
  86. );
  87. /*=============================================================================
  88. == Global variables
  89. =============================================================================*/
  90. /*
  91. * Define variables used by tdicommon code
  92. */
  93. USHORT TdiDeviceEndpointType = TdiConnectionStream;
  94. USHORT TdiDeviceAddressType = TDI_ADDRESS_TYPE_NETBIOS;
  95. USHORT TdiDeviceInBufHeader = 0;
  96. // ULONG TdiDeviceMaxTransportAddressLength = sizeof(TA_NETBIOS_ADDRESS);
  97. /*******************************************************************************
  98. *
  99. * TdiDeviceOpen
  100. *
  101. * Allocate and initialize private data structures
  102. *
  103. * ENTRY:
  104. * pTd (input)
  105. * Pointer to TD data structure
  106. * pSdOpen (input/output)
  107. * Points to the parameter structure SD_OPEN.
  108. *
  109. * EXIT:
  110. * STATUS_SUCCESS - no error
  111. *
  112. ******************************************************************************/
  113. NTSTATUS
  114. TdiDeviceOpen( PTD pTd, PSD_OPEN pSdOpen )
  115. {
  116. return( STATUS_SUCCESS );
  117. }
  118. /*******************************************************************************
  119. *
  120. * TdiDeviceClose
  121. *
  122. * Close transport driver
  123. *
  124. * NOTE: this must not close the current connection endpoint
  125. *
  126. * ENTRY:
  127. * pTd (input)
  128. * Pointer to TD data structure
  129. * pSdClose (input/output)
  130. * Points to the parameter structure SD_CLOSE.
  131. *
  132. * EXIT:
  133. * STATUS_SUCCESS - no error
  134. *
  135. ******************************************************************************/
  136. NTSTATUS
  137. TdiDeviceClose( PTD pTd, PSD_CLOSE pSdClose )
  138. {
  139. return( STATUS_SUCCESS );
  140. }
  141. /*******************************************************************************
  142. *
  143. * TdiDeviceOpenEndpoint
  144. *
  145. * Open an existing endpoint
  146. *
  147. * ENTRY:
  148. * pTd (input)
  149. * Pointer to TD data structure
  150. * pIcaEndpoint (input)
  151. * Pointer to ICA endpoint structure
  152. * IcaEndpointLength (input)
  153. * length of endpoint data
  154. *
  155. * EXIT:
  156. * STATUS_SUCCESS - no error
  157. *
  158. ******************************************************************************/
  159. NTSTATUS
  160. TdiDeviceOpenEndpoint(
  161. PTD pTd,
  162. PVOID pIcaEndpoint,
  163. ULONG IcaEndpointLength
  164. )
  165. {
  166. return( STATUS_SUCCESS );
  167. }
  168. /*****************************************************************************
  169. *
  170. * TdiDeviceBuildTransportNameAndAddress
  171. *
  172. * Build the Transport Name and Address given an optional ICA_STACK_ADDRESS,
  173. * or the Lana value from the pTd->Params structure.
  174. *
  175. * ENTRY:
  176. *
  177. * pTd (input)
  178. * pointer to TD data structure
  179. * pLocalAddress (input)
  180. * pointer to local address to use (OPTIONAL)
  181. * pTransportName (output)
  182. * pointer to UNICODE_STRING to return transport name
  183. * NOTE: the buffer pointed to be pTransportName->Buffer must
  184. * be free'd by the caller
  185. * ppTransportAddress (output)
  186. * pointer to location to return TRANSPORT_ADDRESS structure
  187. * NOTE: the transport address buffer must be free'd by the caller
  188. * pTransportAddressLength (output)
  189. * pointer to location to return TransportAddress length
  190. *
  191. * EXIT:
  192. * STATUS_SUCCESS - Success
  193. *
  194. ****************************************************************************/
  195. NTSTATUS
  196. TdiDeviceBuildTransportNameAndAddress(
  197. PTD pTd,
  198. PICA_STACK_ADDRESS pLocalAddress,
  199. PUNICODE_STRING pTransportName,
  200. PTRANSPORT_ADDRESS *ppTransportAddress,
  201. PULONG pTransportAddressLength
  202. )
  203. {
  204. PTDI_ADDRESS_NETBIOS pNetbiosAddress;
  205. PWCHAR pComputerName;
  206. NTSTATUS Status;
  207. /*
  208. * For NetBios, the transport device name is determined from
  209. * the specified LanAdapter (Lana) number.
  210. */
  211. Status = _NetBiosGetTransportName( pTd, pTd->Params.Network.LanAdapter,
  212. pTransportName );
  213. if ( !NT_SUCCESS( Status ) )
  214. goto badtransportname;
  215. /*
  216. * Allocate a transport address structure
  217. */
  218. *pTransportAddressLength = sizeof(TRANSPORT_ADDRESS) +
  219. sizeof(TDI_ADDRESS_NETBIOS);
  220. Status = MemoryAllocate( *pTransportAddressLength, ppTransportAddress );
  221. if ( !NT_SUCCESS( Status ) )
  222. goto badmalloc;
  223. /*
  224. * Initialize the static part of the transport address
  225. */
  226. (*ppTransportAddress)->TAAddressCount = 1;
  227. (*ppTransportAddress)->Address[0].AddressLength = sizeof(TDI_ADDRESS_NETBIOS);
  228. (*ppTransportAddress)->Address[0].AddressType = TDI_ADDRESS_TYPE_NETBIOS;
  229. pNetbiosAddress = (PTDI_ADDRESS_NETBIOS)(*ppTransportAddress)->Address[0].Address;
  230. /*
  231. * If a local address is specified, then use it.
  232. */
  233. if ( pLocalAddress ) {
  234. /*
  235. * Skip over the address family(type) data (bytes 0&1) of the
  236. * local address struct, and copy the remainder of the address
  237. * directly to the Address field of the TransportAddress struct.
  238. */
  239. ASSERT( *(PUSHORT)pLocalAddress == TDI_ADDRESS_TYPE_NETBIOS );
  240. RtlCopyMemory( pNetbiosAddress, &((PCHAR)pLocalAddress)[2], sizeof(TDI_ADDRESS_NETBIOS) );
  241. /*
  242. * There was no local address specified.
  243. * Use the local ComputerName to build the NetBios name.
  244. */
  245. } else {
  246. ANSI_STRING ansiString;
  247. UNICODE_STRING unicodeString;
  248. Status = _GetComputerName( pTd, &unicodeString );
  249. if ( !NT_SUCCESS( Status ) )
  250. goto badcomputername;
  251. pNetbiosAddress->NetbiosNameType = TDI_ADDRESS_NETBIOS_TYPE_UNIQUE;
  252. /*
  253. * Now convert ComputerName from unicode to ansi and
  254. * store it in the NetBios name field of the transport address.
  255. */
  256. ansiString.Length = 0;
  257. ansiString.MaximumLength = sizeof(pNetbiosAddress->NetbiosName);
  258. ansiString.Buffer = pNetbiosAddress->NetbiosName;
  259. RtlUnicodeStringToAnsiString( &ansiString, &unicodeString, FALSE );
  260. RtlFillMemory( &pNetbiosAddress->NetbiosName[ansiString.Length],
  261. sizeof(pNetbiosAddress->NetbiosName) - ansiString.Length,
  262. '.' );
  263. pNetbiosAddress->NetbiosName[15] = '\0';
  264. }
  265. return( STATUS_SUCCESS );
  266. /*=============================================================================
  267. == Error returns
  268. =============================================================================*/
  269. badcomputername:
  270. MemoryFree( *ppTransportAddress );
  271. badmalloc:
  272. MemoryFree( pTransportName->Buffer );
  273. badtransportname:
  274. return( Status );
  275. }
  276. /*****************************************************************************
  277. *
  278. * TdiDeviceBuildWildcardAddress
  279. *
  280. * Build a wildcard Address for this protocol.
  281. *
  282. * ENTRY:
  283. *
  284. * pTd (input)
  285. * pointer to TD data structure
  286. * ppWildcardAddress (output)
  287. * pointer to location to return TRANSPORT_ADDRESS structure
  288. * NOTE: the transport address buffer must be free'd by the caller
  289. * pWildcardAddressLength (output)
  290. * pointer to location to return TransportAddress length
  291. *
  292. * EXIT:
  293. * STATUS_SUCCESS - Success
  294. *
  295. ****************************************************************************/
  296. NTSTATUS
  297. TdiDeviceBuildWildcardAddress(
  298. PTD pTd,
  299. PTRANSPORT_ADDRESS *ppWildcardAddress,
  300. PULONG pWildcardAddressLength
  301. )
  302. {
  303. PTDI_ADDRESS_NETBIOS pNetbiosAddress;
  304. UNICODE_STRING unicodeString;
  305. ANSI_STRING ansiString;
  306. PWCHAR pComputerName;
  307. NTSTATUS Status;
  308. /*
  309. * Allocate a transport address structure
  310. */
  311. *pWildcardAddressLength = sizeof(TRANSPORT_ADDRESS) +
  312. sizeof(TDI_ADDRESS_NETBIOS);
  313. Status = MemoryAllocate( *pWildcardAddressLength, ppWildcardAddress );
  314. if ( !NT_SUCCESS( Status ) )
  315. return( Status );
  316. /*
  317. * Initialize the static part of the transport address
  318. */
  319. (*ppWildcardAddress)->TAAddressCount = 1;
  320. (*ppWildcardAddress)->Address[0].AddressLength = sizeof(TDI_ADDRESS_NETBIOS);
  321. (*ppWildcardAddress)->Address[0].AddressType = TDI_ADDRESS_TYPE_NETBIOS;
  322. pNetbiosAddress = (PTDI_ADDRESS_NETBIOS)(*ppWildcardAddress)->Address[0].Address;
  323. pNetbiosAddress->NetbiosNameType = TDI_ADDRESS_NETBIOS_TYPE_GROUP;
  324. RtlZeroMemory( pNetbiosAddress->NetbiosName,
  325. sizeof(pNetbiosAddress->NetbiosName) );
  326. Status = _GetComputerName( pTd, &unicodeString );
  327. if ( !NT_SUCCESS( Status ) ) {
  328. MemoryFree( *ppWildcardAddress );
  329. return( Status );
  330. }
  331. /*
  332. * Now convert ComputerName from unicode to ansi and
  333. * store it in the NetBios name field of the transport address.
  334. */
  335. ansiString.Length = 0;
  336. ansiString.MaximumLength = sizeof(pNetbiosAddress->NetbiosName);
  337. ansiString.Buffer = pNetbiosAddress->NetbiosName;
  338. RtlUnicodeStringToAnsiString( &ansiString, &unicodeString, FALSE );
  339. #ifdef notdef
  340. RtlFillMemory( &pNetbiosAddress->NetbiosName[ansiString.Length],
  341. sizeof(pNetbiosAddress->NetbiosName) - ansiString.Length,
  342. '.' );
  343. pNetbiosAddress->NetbiosName[15] = '\0';
  344. #endif
  345. return( STATUS_SUCCESS );
  346. }
  347. /*****************************************************************************
  348. *
  349. * TdiDeviceWaitForDatagramConnection
  350. *
  351. * Wait for a datagram connection request, validate it,
  352. * and return the remote transport address of the connection.
  353. *
  354. * ENTRY:
  355. *
  356. * pTd (input)
  357. * pointer to TD data structure
  358. * pFileObject (input)
  359. * pointer to file object to wait for a connection on
  360. * ppRemoteAddress (output)
  361. * pointer to location to return TRANSPORT_ADDRESS structure
  362. * NOTE: the transport address buffer must be free'd by the caller
  363. * pRemoteAddressLength (output)
  364. * pointer to location to return RemoteAddress length
  365. *
  366. * EXIT:
  367. * STATUS_SUCCESS - Success
  368. *
  369. ****************************************************************************/
  370. NTSTATUS
  371. TdiDeviceWaitForDatagramConnection(
  372. PTD pTd,
  373. PFILE_OBJECT pFileObject,
  374. PDEVICE_OBJECT pDeviceObject,
  375. PTRANSPORT_ADDRESS *ppRemoteAddress,
  376. PULONG pRemoteAddressLength
  377. )
  378. {
  379. return( STATUS_NOT_SUPPORTED );
  380. }
  381. /*****************************************************************************
  382. *
  383. * TdiDeviceCompleteDatagramConnection
  384. *
  385. * Do any final work to complete a datagram connection.
  386. *
  387. * ENTRY:
  388. *
  389. * pTd (input)
  390. * pointer to TD data structure
  391. * pFileObject (input)
  392. * pointer to file object for this connection
  393. *
  394. * EXIT:
  395. * STATUS_SUCCESS - Success
  396. *
  397. ****************************************************************************/
  398. NTSTATUS
  399. TdiDeviceCompleteDatagramConnection(
  400. PTD pTd,
  401. PFILE_OBJECT pFileObject,
  402. PDEVICE_OBJECT pDeviceObject,
  403. PTRANSPORT_ADDRESS pTransportAddress,
  404. ULONG TransportAddressLength
  405. )
  406. {
  407. return( STATUS_NOT_SUPPORTED );
  408. }
  409. /*******************************************************************************
  410. *
  411. * TdiDeviceConnectionSend
  412. *
  413. * Initialize host module data structure
  414. * -- this structure gets sent to the client
  415. *
  416. *
  417. * ENTRY:
  418. * pTd (input)
  419. * Pointer to td data structure
  420. *
  421. * EXIT:
  422. * STATUS_SUCCESS - no error
  423. *
  424. ******************************************************************************/
  425. NTSTATUS
  426. TdiDeviceConnectionSend( PTD pTd )
  427. {
  428. PCLIENTMODULES pClient;
  429. /*
  430. * Get pointer to client structure
  431. */
  432. pClient = pTd->pClient;
  433. /*
  434. * Initialize Td host module structure
  435. */
  436. pClient->TdVersionL = VERSION_HOSTL_TDNETB;
  437. pClient->TdVersionH = VERSION_HOSTH_TDNETB;
  438. pClient->TdVersion = VERSION_HOSTH_TDNETB;
  439. return( STATUS_SUCCESS );
  440. }
  441. /*******************************************************************************
  442. *
  443. * TdiDeviceReadComplete
  444. *
  445. * Do any read complete processing
  446. *
  447. *
  448. * ENTRY:
  449. * pTd (input)
  450. * Pointer to td data structure
  451. * pBuffer (input)
  452. * Pointer to input buffer
  453. * pByteCount (input/output)
  454. * Pointer to location containing byte count read
  455. *
  456. * EXIT:
  457. * STATUS_SUCCESS - no error
  458. *
  459. ******************************************************************************/
  460. NTSTATUS
  461. TdiDeviceReadComplete( PTD pTd, PUCHAR pBuffer, PULONG pByteCount )
  462. {
  463. return( STATUS_SUCCESS );
  464. }
  465. /*******************************************************************************
  466. *
  467. * _NetBiosGetTransportName
  468. *
  469. * Read netbios registry entries to find the transport device name
  470. * for the specified LanAdapter number.
  471. *
  472. * ENTRY:
  473. * pTd (input)
  474. * Pointer to td data structure
  475. * Lana (input)
  476. * Lan Adapter number
  477. * pTransportName (output)
  478. * pointer to UNICODE_STRING to return transport name
  479. * NOTE: the buffer pointed to be pTransportName->Buffer must
  480. * be free'd by the caller
  481. *
  482. * EXIT:
  483. * STATUS_SUCCESS - no error
  484. *
  485. ******************************************************************************/
  486. #if 0
  487. NTSTATUS
  488. _NetBiosGetTransportName(
  489. PTD pTd,
  490. LONG Lana,
  491. PUNICODE_STRING pTransportName
  492. )
  493. {
  494. UNICODE_STRING nameString;
  495. OBJECT_ATTRIBUTES objectAttributes;
  496. HANDLE netbiosKey = NULL;
  497. ULONG providerListLength;
  498. PKEY_VALUE_PARTIAL_INFORMATION pProviderNameInfo = NULL;
  499. ULONG lanaMapLength;
  500. PKEY_VALUE_PARTIAL_INFORMATION pLanaMapInfo = NULL;
  501. PLANA_MAP pLanaMap;
  502. int ProviderCount;
  503. int i;
  504. PWSTR currentProviderName;
  505. NTSTATUS Status;
  506. //
  507. // Read the registry for information on all Netbios providers,
  508. // including Lana numbers, protocol numbers, and provider device
  509. // names. First, open the Netbios key in the registry.
  510. //
  511. RtlInitUnicodeString( &nameString, NETBIOS_KEY );
  512. InitializeObjectAttributes(
  513. &objectAttributes,
  514. &nameString,
  515. OBJ_CASE_INSENSITIVE,
  516. (HANDLE) NULL,
  517. (PSECURITY_DESCRIPTOR) NULL
  518. );
  519. Status = ZwOpenKey( &netbiosKey, KEY_READ, &objectAttributes );
  520. if ( !NT_SUCCESS( Status ) )
  521. return( Status );
  522. //
  523. // Determine the size of the provider names. We need this so
  524. // that we can allocate enough memory to hold it.
  525. //
  526. providerListLength = 0;
  527. RtlInitUnicodeString( &nameString, L"Bind" );
  528. Status = ZwQueryValueKey( netbiosKey,
  529. &nameString,
  530. KeyValuePartialInformation,
  531. NULL,
  532. 0,
  533. &providerListLength
  534. );
  535. if ( Status != STATUS_BUFFER_TOO_SMALL )
  536. return( Status );
  537. //
  538. // Allocate enough memory to hold the mapping.
  539. //
  540. Status = MemoryAllocate( providerListLength, &pProviderNameInfo );
  541. if ( !NT_SUCCESS( Status ) )
  542. goto error_exit;
  543. //
  544. // Get the list of transports from the registry.
  545. //
  546. Status = ZwQueryValueKey( netbiosKey,
  547. &nameString,
  548. KeyValuePartialInformation,
  549. pProviderNameInfo,
  550. providerListLength,
  551. &providerListLength
  552. );
  553. if ( !NT_SUCCESS( Status ) ) {
  554. MemoryFree( pProviderNameInfo );
  555. return( Status );
  556. }
  557. //
  558. // Determine the size of the Lana map. We need this so that we
  559. // can allocate enough memory to hold it.
  560. //
  561. lanaMapLength = 0;
  562. RtlInitUnicodeString( &nameString, L"LanaMap" );
  563. Status = ZwQueryValueKey( netbiosKey,
  564. &nameString,
  565. KeyValuePartialInformation,
  566. NULL,
  567. 0,
  568. &lanaMapLength
  569. );
  570. if ( Status != STATUS_BUFFER_TOO_SMALL ) {
  571. MemoryFree( pProviderNameInfo );
  572. return( Status );
  573. }
  574. //
  575. // Allocate enough memory to hold the Lana map.
  576. //
  577. Status = MemoryAllocate( lanaMapLength, &pLanaMapInfo );
  578. if ( !NT_SUCCESS( Status ) )
  579. goto error_exit;
  580. //
  581. // Get the list of transports from the registry.
  582. //
  583. Status = ZwQueryValueKey( netbiosKey,
  584. &nameString,
  585. KeyValuePartialInformation,
  586. pLanaMapInfo,
  587. lanaMapLength,
  588. &lanaMapLength
  589. );
  590. if ( !NT_SUCCESS( Status ) ) {
  591. MemoryFree( pLanaMapInfo );
  592. MemoryFree( pProviderNameInfo );
  593. return( Status );
  594. }
  595. //
  596. // Determine the number of Netbios providers loaded on the system.
  597. //
  598. ProviderCount = (int) (lanaMapLength / sizeof(LANA_MAP));
  599. //
  600. // Fill in the array of provider information.
  601. //
  602. Status = STATUS_DEVICE_DOES_NOT_EXIST;
  603. pLanaMap = (PLANA_MAP)pLanaMapInfo->Data;
  604. for ( currentProviderName = (PWSTR)pProviderNameInfo->Data, i = 0;
  605. *currentProviderName != UNICODE_NULL && i < ProviderCount;
  606. currentProviderName += wcslen( currentProviderName ) + 1, i++ ) {
  607. if ( pLanaMap[i].Lana == Lana && pLanaMap[i].Enum ) {
  608. pTransportName->Length = wcslen( currentProviderName ) *
  609. sizeof(UNICODE_NULL);
  610. pTransportName->MaximumLength = pTransportName->Length +
  611. sizeof(UNICODE_NULL);
  612. Status = MemoryAllocate( pTransportName->MaximumLength,
  613. &pTransportName->Buffer );
  614. if ( !NT_SUCCESS( Status ) )
  615. break;
  616. wcscpy( pTransportName->Buffer, currentProviderName );
  617. Status = STATUS_SUCCESS;
  618. break;
  619. }
  620. }
  621. MemoryFree( pLanaMapInfo );
  622. MemoryFree( pProviderNameInfo );
  623. ZwClose( netbiosKey );
  624. return( Status );
  625. /*=============================================================================
  626. == Error returns
  627. =============================================================================*/
  628. error_exit:
  629. if ( netbiosKey != NULL ) {
  630. ZwClose( netbiosKey );
  631. }
  632. if ( pProviderNameInfo != NULL ) {
  633. MemoryFree( pProviderNameInfo );
  634. }
  635. if ( pLanaMapInfo != NULL ) {
  636. MemoryFree( pLanaMapInfo );
  637. }
  638. return( Status );
  639. }
  640. #endif
  641. NTSTATUS
  642. _NetBiosGetTransportName(
  643. PTD pTd,
  644. LONG Lana,
  645. PUNICODE_STRING pTransportName
  646. )
  647. {
  648. UNICODE_STRING nameString;
  649. OBJECT_ATTRIBUTES objectAttributes;
  650. HANDLE netbiosKey = NULL;
  651. ULONG providerListLength;
  652. PKEY_VALUE_PARTIAL_INFORMATION pProviderNameInfo = NULL;
  653. int ProviderCount;
  654. ULONG lanaMapLength;
  655. PKEY_VALUE_PARTIAL_INFORMATION pLanaMapInfo = NULL;
  656. PLANA_MAP pLanaMap;
  657. int i;
  658. USHORT Len;
  659. PWSTR currentProviderName;
  660. NTSTATUS Status;
  661. UNICODE_STRING RouteString;
  662. PWCHAR GUIDStr;
  663. RtlInitUnicodeString( &RouteString , NULL );
  664. GetGUID( &RouteString , Lana );
  665. Len = RouteString.Length;
  666. GUIDStr = RouteString.Buffer;
  667. if (Len < (2 * sizeof(UNICODE_NULL)))
  668. {
  669. // The GUID not present - That means the device no longer exists
  670. Status = STATUS_DEVICE_DOES_NOT_EXIST;
  671. goto error_exit;
  672. }
  673. //
  674. // Read the registry for information on all Netbios providers,
  675. // including Lana numbers, protocol numbers, and provider device
  676. // names. First, open the Netbios key in the registry.
  677. //
  678. RtlInitUnicodeString( &nameString, NETBIOS_KEY );
  679. InitializeObjectAttributes(
  680. &objectAttributes,
  681. &nameString,
  682. OBJ_CASE_INSENSITIVE,
  683. (HANDLE) NULL,
  684. (PSECURITY_DESCRIPTOR) NULL
  685. );
  686. Status = ZwOpenKey( &netbiosKey, KEY_READ, &objectAttributes );
  687. if ( !NT_SUCCESS( Status ) )
  688. return( Status );
  689. //
  690. // Determine the size of the provider names. We need this so
  691. // that we can allocate enough memory to hold it.
  692. //
  693. providerListLength = 0;
  694. RtlInitUnicodeString( &nameString, L"Bind" );
  695. Status = ZwQueryValueKey( netbiosKey,
  696. &nameString,
  697. KeyValuePartialInformation,
  698. NULL,
  699. 0,
  700. &providerListLength
  701. );
  702. if ( Status != STATUS_BUFFER_TOO_SMALL )
  703. return( Status );
  704. //
  705. // Allocate enough memory to hold the mapping.
  706. //
  707. Status = MemoryAllocate( providerListLength, &pProviderNameInfo );
  708. if ( !NT_SUCCESS( Status ) )
  709. goto error_exit;
  710. //
  711. // Get the list of transports from the registry.
  712. //
  713. Status = ZwQueryValueKey( netbiosKey,
  714. &nameString,
  715. KeyValuePartialInformation,
  716. pProviderNameInfo,
  717. providerListLength,
  718. &providerListLength
  719. );
  720. if ( !NT_SUCCESS( Status ) ) {
  721. MemoryFree( pProviderNameInfo );
  722. return( Status );
  723. }
  724. //
  725. // Determine the size of the Lana map. We need this so that we
  726. // can allocate enough memory to hold it.
  727. //
  728. lanaMapLength = 0;
  729. RtlInitUnicodeString( &nameString, L"LanaMap" );
  730. Status = ZwQueryValueKey( netbiosKey,
  731. &nameString,
  732. KeyValuePartialInformation,
  733. NULL,
  734. 0,
  735. &lanaMapLength
  736. );
  737. if ( Status != STATUS_BUFFER_TOO_SMALL ) {
  738. MemoryFree( pProviderNameInfo );
  739. return( Status );
  740. }
  741. //
  742. // Allocate enough memory to hold the Lana map.
  743. //
  744. Status = MemoryAllocate( lanaMapLength, &pLanaMapInfo );
  745. if ( !NT_SUCCESS( Status ) )
  746. goto error_exit;
  747. //
  748. // Get the list of transports from the registry.
  749. //
  750. Status = ZwQueryValueKey( netbiosKey,
  751. &nameString,
  752. KeyValuePartialInformation,
  753. pLanaMapInfo,
  754. lanaMapLength,
  755. &lanaMapLength
  756. );
  757. if ( !NT_SUCCESS( Status ) ) {
  758. MemoryFree( pLanaMapInfo );
  759. MemoryFree( pProviderNameInfo );
  760. return( Status );
  761. }
  762. //
  763. // Determine the number of Netbios providers loaded on the system.
  764. //
  765. ProviderCount = (int) (lanaMapLength / sizeof(LANA_MAP));
  766. //
  767. // Fill in the array of provider information.
  768. //
  769. Status = STATUS_DEVICE_DOES_NOT_EXIST;
  770. pLanaMap = (PLANA_MAP)pLanaMapInfo->Data;
  771. Len = Len/sizeof(WCHAR); // convert length from bytes to WCHARs
  772. #if 0
  773. DbgPrint("GUIDStr=%ws, Len=%d\n",GUIDStr, Len);
  774. #endif
  775. for ( currentProviderName = (PWSTR)pProviderNameInfo->Data, i = 0;
  776. *currentProviderName != UNICODE_NULL && i < ProviderCount;
  777. currentProviderName += wcslen( currentProviderName ) + 1, i++ ) {
  778. #if 0
  779. DbgPrint("currentProviderName: %ws\n",currentProviderName);
  780. DbgPrint("i=%d, pLanaMap.Enum=%d\n", i, pLanaMap[i].Enum);
  781. DbgPrint("wcscmp str=%ws\n",currentProviderName+wcslen(currentProviderName)-Len);
  782. #endif
  783. if ((pLanaMap[i].Enum) &&
  784. (Len <=wcslen(currentProviderName)) &&
  785. (!wcsncmp((currentProviderName+wcslen(currentProviderName)-Len), GUIDStr, Len)))
  786. {
  787. pTransportName->Length = wcslen( currentProviderName ) *
  788. sizeof(UNICODE_NULL);
  789. pTransportName->MaximumLength = pTransportName->Length +
  790. sizeof(UNICODE_NULL);
  791. Status = MemoryAllocate( pTransportName->MaximumLength,
  792. &pTransportName->Buffer );
  793. if ( !NT_SUCCESS( Status ) )
  794. break;
  795. wcscpy( pTransportName->Buffer, currentProviderName );
  796. Status = STATUS_SUCCESS;
  797. break;
  798. }
  799. }
  800. MemoryFree( pLanaMapInfo );
  801. MemoryFree( pProviderNameInfo );
  802. ZwClose( netbiosKey );
  803. return( Status );
  804. /*=============================================================================
  805. == Error returns
  806. =============================================================================*/
  807. error_exit:
  808. if ( netbiosKey != NULL ) {
  809. ZwClose( netbiosKey );
  810. }
  811. if ( pProviderNameInfo != NULL ) {
  812. MemoryFree( pProviderNameInfo );
  813. }
  814. if ( pLanaMapInfo != NULL ) {
  815. MemoryFree( pLanaMapInfo );
  816. }
  817. return( Status );
  818. }
  819. /*******************************************************************************
  820. *
  821. * _GetComputerName
  822. *
  823. * Read computer name from the registry
  824. *
  825. * ENTRY:
  826. * pTd (input)
  827. * Pointer to td data structure
  828. * pComputerName (output)
  829. * pointer to UNICODE_STRING to return computer name
  830. * NOTE: the buffer pointed to be pComputerName->Buffer must
  831. * be free'd by the caller
  832. *
  833. * EXIT:
  834. * STATUS_SUCCESS - no error
  835. *
  836. ******************************************************************************/
  837. NTSTATUS
  838. _GetComputerName(
  839. PTD pTd,
  840. PUNICODE_STRING pComputerName
  841. )
  842. {
  843. UNICODE_STRING nameString;
  844. OBJECT_ATTRIBUTES objectAttributes;
  845. HANDLE hKey;
  846. WCHAR ComputerNameBuffer[256];
  847. PKEY_VALUE_PARTIAL_INFORMATION pComputerNameInfo;
  848. ULONG returnLength;
  849. NTSTATUS Status;
  850. /*
  851. * Try to open the ActiveComputerName key.
  852. * If this fails, attempt to open the static key.
  853. */
  854. RtlInitUnicodeString( &nameString, VOLATILE_COMPUTERNAME );
  855. InitializeObjectAttributes( &objectAttributes,
  856. &nameString,
  857. OBJ_CASE_INSENSITIVE,
  858. NULL,
  859. NULL
  860. );
  861. Status = ZwOpenKey( &hKey, KEY_READ, &objectAttributes );
  862. if ( !NT_SUCCESS( Status ) ) {
  863. RtlInitUnicodeString( &nameString, NON_VOLATILE_COMPUTERNAME );
  864. InitializeObjectAttributes( &objectAttributes,
  865. &nameString,
  866. OBJ_CASE_INSENSITIVE,
  867. NULL,
  868. NULL
  869. );
  870. Status = ZwOpenKey( &hKey, KEY_READ, &objectAttributes );
  871. }
  872. if ( !NT_SUCCESS( Status ) )
  873. return( Status );
  874. /*
  875. * Now get the ComputerName value
  876. */
  877. RtlInitUnicodeString( &nameString, COMPUTERNAME_VALUE );
  878. Status = ZwQueryValueKey( hKey,
  879. &nameString,
  880. KeyValuePartialInformation,
  881. ComputerNameBuffer,
  882. sizeof(ComputerNameBuffer),
  883. &returnLength
  884. );
  885. ZwClose( hKey );
  886. if ( !NT_SUCCESS( Status ) )
  887. return( Status );
  888. /*
  889. * Allocate a buffer to return the ComputerName string,
  890. * initialize the return unicode string, and copy the computer name.
  891. */
  892. pComputerNameInfo = (PKEY_VALUE_PARTIAL_INFORMATION)ComputerNameBuffer;
  893. Status = MemoryAllocate( pComputerNameInfo->DataLength,
  894. &pComputerName->Buffer );
  895. if ( !NT_SUCCESS( Status ) )
  896. return( Status );
  897. RtlCopyMemory( pComputerName->Buffer, pComputerNameInfo->Data,
  898. pComputerNameInfo->DataLength );
  899. pComputerName->Length =
  900. pComputerName->MaximumLength =
  901. (USHORT)(pComputerNameInfo->DataLength - sizeof(UNICODE_NULL));
  902. return( STATUS_SUCCESS );
  903. }