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.

404 lines
11 KiB

  1. //++
  2. //
  3. // Copyright (C) Microsoft Corporation, 1987 - 1999
  4. //
  5. // Module Name:
  6. //
  7. // nbttrprt.c
  8. //
  9. // Abstract:
  10. //
  11. // Queries into network drivers
  12. //
  13. // Author:
  14. //
  15. // Anilth - 4-20-1998
  16. //
  17. // Environment:
  18. //
  19. // User mode only.
  20. // Contains NT-specific code.
  21. //
  22. // Revision History:
  23. //
  24. //--
  25. #include "precomp.h"
  26. #include "nbtutil.h"
  27. BOOLEAN NlTransportGetIpAddress(IN LPWSTR TransportName,
  28. OUT PULONG IpAddress,
  29. IN OUT NETDIAG_RESULT *pResults);
  30. /*!--------------------------------------------------------------------------
  31. NetBTTest
  32. Do whatever initialization Cliff's routines need that Karoly's will really
  33. do as a part of his tests.
  34. Arguments:
  35. None.
  36. Return Value:
  37. S_OK: Test suceeded.
  38. S_FALSE: Test failed
  39. Author: KennT
  40. ---------------------------------------------------------------------------*/
  41. HRESULT
  42. NetBTTest(NETDIAG_PARAMS* pParams, NETDIAG_RESULT* pResults)
  43. {
  44. HRESULT hr = hrOK;
  45. NET_API_STATUS NetStatus;
  46. PWKSTA_TRANSPORT_INFO_0 pWti0 = NULL;
  47. DWORD EntriesRead;
  48. DWORD TotalEntries;
  49. DWORD i;
  50. PNETBT_TRANSPORT pNetbtTransport;
  51. LONG cNetbtTransportCount = 0;
  52. //
  53. // Generate a global list of NetbtTransports.
  54. // ?? Karoly, Please populate GlobalNetbtTransports and cNetbtTransportCount
  55. // using some mechanism lower level mechanism.
  56. //
  57. if (!pResults->Global.fHasNbtEnabledInterface)
  58. {
  59. pResults->NetBt.fPerformed = FALSE;
  60. //IDS_NETBT_SKIP
  61. SetMessage(&pResults->NetBt.msgTestResult,
  62. Nd_Verbose,
  63. IDS_NETBT_SKIP);
  64. return S_OK;
  65. }
  66. PrintStatusMessage(pParams,0, IDS_NETBT_STATUS_MSG);
  67. pResults->NetBt.fPerformed = TRUE;
  68. NetStatus = NetWkstaTransportEnum(
  69. NULL,
  70. 0,
  71. (LPBYTE *)&pWti0,
  72. 0xFFFFFFFF, // MaxPreferredLength
  73. &EntriesRead,
  74. &TotalEntries,
  75. NULL ); // Optional resume handle
  76. if (NetStatus != NERR_Success)
  77. {
  78. // IDS_NETBT_11403 " NetBt : [FATAL] Unable to retrieve transport list from Redir. [%s]\n"
  79. SetMessage(&pResults->NetBt.msgTestResult,
  80. Nd_Quiet,
  81. IDS_NETBT_11403, NetStatusToString(NetStatus));
  82. // the test failed, but we can continue with the other tests
  83. hr = S_FALSE;
  84. }
  85. else
  86. {
  87. cNetbtTransportCount = 0;
  88. for ( i=0; i<EntriesRead; i++ )
  89. {
  90. UNICODE_STRING TransportName;
  91. RtlInitUnicodeString( &TransportName, (LPWSTR)pWti0[i].wkti0_transport_name );
  92. if ( TransportName.Length >= sizeof(NETBT_DEVICE_PREFIX) &&
  93. _wcsnicmp( TransportName.Buffer, NETBT_DEVICE_PREFIX, (sizeof(NETBT_DEVICE_PREFIX)/sizeof(WCHAR)-1)) == 0 ) {
  94. //
  95. // Determine if this is a duplicate transport
  96. //
  97. pNetbtTransport = FindNetbtTransport( pResults, TransportName.Buffer );
  98. if ( pNetbtTransport != NULL )
  99. {
  100. // IDS_NETBT_DUPLICATE " NetBt : [WARNING] Transport %-16.16wZ is a duplicate"
  101. PrintStatusMessage(pParams,0, IDS_NETBT_DUPLICATE,
  102. &TransportName);
  103. }
  104. else
  105. {
  106. //
  107. // Allocate a new netbt transport
  108. //
  109. pNetbtTransport = (PNETBT_TRANSPORT) Malloc(
  110. sizeof(NETBT_TRANSPORT) +
  111. TransportName.Length + sizeof(WCHAR));
  112. if ( pNetbtTransport == NULL )
  113. {
  114. // IDS_NETBT_11404 " NetBt : [FATAL] Out of memory."
  115. SetMessage(&pResults->NetBt.msgTestResult,
  116. Nd_Quiet,
  117. IDS_NETBT_11404);
  118. // the test failed, but we can continue with the other tests
  119. hr = S_FALSE;
  120. goto Cleanup;
  121. }
  122. ZeroMemory( pNetbtTransport,
  123. sizeof(NETBT_TRANSPORT) +
  124. TransportName.Length + sizeof(WCHAR));
  125. wcscpy( pNetbtTransport->pswzTransportName, TransportName.Buffer );
  126. pNetbtTransport->Flags = 0;
  127. if ( !NlTransportGetIpAddress( pNetbtTransport->pswzTransportName,
  128. &pNetbtTransport->IpAddress,
  129. pResults) )
  130. {
  131. // the test failed, but we can continue with the other tests
  132. hr = S_FALSE;
  133. goto Cleanup;
  134. }
  135. InsertTailList( &pResults->NetBt.Transports,
  136. &pNetbtTransport->Next );
  137. cNetbtTransportCount ++;
  138. }
  139. }
  140. }
  141. if ( cNetbtTransportCount == 0 )
  142. {
  143. // IDS_NETBT_11405 " NetBt : [FATAL] No NetBt transports are configured"
  144. SetMessage(&pResults->NetBt.msgTestResult,
  145. Nd_Quiet,
  146. IDS_NETBT_11405);
  147. // the test failed, but we can continue with the other tests
  148. hr = S_FALSE;
  149. }
  150. else
  151. {
  152. int ids;
  153. TCHAR szBuffer[256];
  154. if (cNetbtTransportCount > 1)
  155. {
  156. ids = IDS_NETBT_11406;
  157. // IDS_NETBT_11406 " %ld NetBt transport%s currently configured.\n"
  158. }
  159. else
  160. {
  161. ids = IDS_NETBT_11407;
  162. // IDS_NETBT_11407 " 1 NetBt transport currently configured.\n"
  163. }
  164. SetMessage(&pResults->NetBt.msgTestResult,
  165. Nd_Verbose,
  166. ids,
  167. cNetbtTransportCount);
  168. }
  169. }
  170. pResults->NetBt.cTransportCount = cNetbtTransportCount;
  171. Cleanup:
  172. if ( pWti0 )
  173. {
  174. NetApiBufferFree( pWti0 );
  175. }
  176. pResults->NetBt.hr = hr;
  177. return hr;
  178. }
  179. BOOLEAN
  180. NlTransportGetIpAddress(
  181. IN LPWSTR pswzTransportName,
  182. OUT PULONG IpAddress,
  183. IN OUT NETDIAG_RESULT *pResults
  184. )
  185. /*++
  186. Routine Description:
  187. Get the IP Address associated with the specified transport.
  188. Arguments:
  189. pswzTransportName - Name of the transport to query.
  190. IpAddress - IP address of the transport.
  191. Zero if the transport currently has no address or
  192. if the transport is not IP.
  193. Return Value:
  194. TRUE: transport is an IP transport
  195. --*/
  196. {
  197. NTSTATUS Status;
  198. BOOLEAN RetVal = FALSE;
  199. IO_STATUS_BLOCK IoStatusBlock;
  200. OBJECT_ATTRIBUTES ObjectAttributes;
  201. UNICODE_STRING TransportNameString;
  202. HANDLE TransportHandle = NULL;
  203. ULONG IpAddresses[NBT_MAXIMUM_BINDINGS+1];
  204. ULONG BytesReturned;
  205. //
  206. // Open the transport device directly.
  207. //
  208. *IpAddress = 0;
  209. RtlInitUnicodeString( &TransportNameString, pswzTransportName );
  210. InitializeObjectAttributes(
  211. &ObjectAttributes,
  212. &TransportNameString,
  213. OBJ_CASE_INSENSITIVE,
  214. NULL,
  215. NULL );
  216. Status = NtOpenFile(
  217. &TransportHandle,
  218. SYNCHRONIZE,
  219. &ObjectAttributes,
  220. &IoStatusBlock,
  221. 0,
  222. 0 );
  223. if (NT_SUCCESS(Status)) {
  224. Status = IoStatusBlock.Status;
  225. }
  226. if (! NT_SUCCESS(Status))
  227. {
  228. // IDS_NETBT_11408 " [FATAL] Cannot open netbt driver '%ws'\n"
  229. SetMessage(&pResults->NetBt.msgTestResult,
  230. Nd_Quiet,
  231. IDS_NETBT_11408,
  232. pswzTransportName);
  233. goto Cleanup;
  234. }
  235. //
  236. // Query the IP Address
  237. //
  238. if (!DeviceIoControl( TransportHandle,
  239. IOCTL_NETBT_GET_IP_ADDRS,
  240. NULL,
  241. 0,
  242. IpAddresses,
  243. sizeof(IpAddresses),
  244. &BytesReturned,
  245. NULL))
  246. {
  247. TCHAR szBuffer[256];
  248. Status = NetpApiStatusToNtStatus(GetLastError());
  249. // IDS_NETBT_11409 " [FATAL] Cannot get IP address from netbt driver '%ws':"
  250. SetMessage(&pResults->NetBt.msgTestResult,
  251. Nd_Quiet,
  252. IDS_NETBT_11409,
  253. pswzTransportName);
  254. goto Cleanup;
  255. }
  256. //
  257. // Return IP Address
  258. // (Netbt returns the address in host order.)
  259. //
  260. *IpAddress = htonl(*IpAddresses);
  261. RetVal = TRUE;
  262. Cleanup:
  263. if ( TransportHandle != NULL )
  264. {
  265. (VOID) NtClose( TransportHandle );
  266. }
  267. return RetVal;
  268. }
  269. void NetBTGlobalPrint(NETDIAG_PARAMS *pParams, NETDIAG_RESULT *pResults)
  270. {
  271. PLIST_ENTRY ListEntry;
  272. PNETBT_TRANSPORT pNetbtTransport;
  273. if (pParams->fVerbose || !FHrOK(pResults->NetBt.hr))
  274. {
  275. PrintNewLine(pParams, 2);
  276. PrintTestTitleResult(pParams,
  277. IDS_NETBT_LONG,
  278. IDS_NETBT_SHORT,
  279. pResults->NetBt.fPerformed,
  280. pResults->NetBt.hr,
  281. 0);
  282. }
  283. if ( pParams->fVerbose && pResults->NetBt.fPerformed)
  284. {
  285. // IDS_NETBT_11411 " List of NetBt transports currently configured.\n"
  286. PrintMessage(pParams, IDS_NETBT_11411);
  287. }
  288. // Iterate through the transports
  289. //
  290. for ( ListEntry = pResults->NetBt.Transports.Flink ;
  291. ListEntry != &pResults->NetBt.Transports ;
  292. ListEntry = ListEntry->Flink )
  293. {
  294. //
  295. // If the transport names match,
  296. // return the entry
  297. //
  298. pNetbtTransport = CONTAINING_RECORD( ListEntry, NETBT_TRANSPORT, Next );
  299. if (pParams->fVerbose)
  300. {
  301. // Strip off the "\Device\" off of the beginning of
  302. // the string
  303. // IDS_NETBT_11412 " %ws\n"
  304. PrintMessage(pParams, IDS_NETBT_11412,
  305. MapGuidToServiceNameW(pNetbtTransport->pswzTransportName+8));
  306. }
  307. }
  308. PrintNdMessage(pParams, &pResults->NetBt.msgTestResult);
  309. }
  310. void NetBTPerInterfacePrint(NETDIAG_PARAMS *pParams, NETDIAG_RESULT *pResults, INTERFACE_RESULT *pInterfaceResults)
  311. {
  312. }
  313. void NetBTCleanup(NETDIAG_PARAMS *pParams, NETDIAG_RESULT *pResults)
  314. {
  315. PNETBT_TRANSPORT pNetbtTransport;
  316. PLIST_ENTRY pListEntry;
  317. PLIST_ENTRY pListHead = &pResults->NetBt.Transports;
  318. // Need to remove all entries from the list
  319. while (!IsListEmpty(pListHead))
  320. {
  321. pListEntry = RemoveHeadList(pListHead);
  322. pNetbtTransport = CONTAINING_RECORD( pListEntry, NETBT_TRANSPORT, Next );
  323. Free( pNetbtTransport );
  324. }
  325. ClearMessage(&pResults->NetBt.msgTestResult);
  326. }