//++ // // Copyright (C) Microsoft Corporation, 1987 - 1999 // // Module Name: // // nbttrprt.c // // Abstract: // // Queries into network drivers // // Author: // // Anilth - 4-20-1998 // // Environment: // // User mode only. // Contains NT-specific code. // // Revision History: // //-- #include "precomp.h" #include "nbtutil.h" BOOLEAN NlTransportGetIpAddress(IN LPWSTR TransportName, OUT PULONG IpAddress, IN OUT NETDIAG_RESULT *pResults); /*!-------------------------------------------------------------------------- NetBTTest Do whatever initialization Cliff's routines need that Karoly's will really do as a part of his tests. Arguments: None. Return Value: S_OK: Test suceeded. S_FALSE: Test failed Author: KennT ---------------------------------------------------------------------------*/ HRESULT NetBTTest(NETDIAG_PARAMS* pParams, NETDIAG_RESULT* pResults) { HRESULT hr = hrOK; NET_API_STATUS NetStatus; PWKSTA_TRANSPORT_INFO_0 pWti0 = NULL; DWORD EntriesRead; DWORD TotalEntries; DWORD i; PNETBT_TRANSPORT pNetbtTransport; LONG cNetbtTransportCount = 0; // // Generate a global list of NetbtTransports. // ?? Karoly, Please populate GlobalNetbtTransports and cNetbtTransportCount // using some mechanism lower level mechanism. // if (!pResults->Global.fHasNbtEnabledInterface) { pResults->NetBt.fPerformed = FALSE; //IDS_NETBT_SKIP SetMessage(&pResults->NetBt.msgTestResult, Nd_Verbose, IDS_NETBT_SKIP); return S_OK; } PrintStatusMessage(pParams,0, IDS_NETBT_STATUS_MSG); pResults->NetBt.fPerformed = TRUE; NetStatus = NetWkstaTransportEnum( NULL, 0, (LPBYTE *)&pWti0, 0xFFFFFFFF, // MaxPreferredLength &EntriesRead, &TotalEntries, NULL ); // Optional resume handle if (NetStatus != NERR_Success) { // IDS_NETBT_11403 " NetBt : [FATAL] Unable to retrieve transport list from Redir. [%s]\n" SetMessage(&pResults->NetBt.msgTestResult, Nd_Quiet, IDS_NETBT_11403, NetStatusToString(NetStatus)); // the test failed, but we can continue with the other tests hr = S_FALSE; } else { cNetbtTransportCount = 0; for ( i=0; i= sizeof(NETBT_DEVICE_PREFIX) && _wcsnicmp( TransportName.Buffer, NETBT_DEVICE_PREFIX, (sizeof(NETBT_DEVICE_PREFIX)/sizeof(WCHAR)-1)) == 0 ) { // // Determine if this is a duplicate transport // pNetbtTransport = FindNetbtTransport( pResults, TransportName.Buffer ); if ( pNetbtTransport != NULL ) { // IDS_NETBT_DUPLICATE " NetBt : [WARNING] Transport %-16.16wZ is a duplicate" PrintStatusMessage(pParams,0, IDS_NETBT_DUPLICATE, &TransportName); } else { // // Allocate a new netbt transport // pNetbtTransport = (PNETBT_TRANSPORT) Malloc( sizeof(NETBT_TRANSPORT) + TransportName.Length + sizeof(WCHAR)); if ( pNetbtTransport == NULL ) { // IDS_NETBT_11404 " NetBt : [FATAL] Out of memory." SetMessage(&pResults->NetBt.msgTestResult, Nd_Quiet, IDS_NETBT_11404); // the test failed, but we can continue with the other tests hr = S_FALSE; goto Cleanup; } ZeroMemory( pNetbtTransport, sizeof(NETBT_TRANSPORT) + TransportName.Length + sizeof(WCHAR)); wcscpy( pNetbtTransport->pswzTransportName, TransportName.Buffer ); pNetbtTransport->Flags = 0; if ( !NlTransportGetIpAddress( pNetbtTransport->pswzTransportName, &pNetbtTransport->IpAddress, pResults) ) { // the test failed, but we can continue with the other tests hr = S_FALSE; goto Cleanup; } InsertTailList( &pResults->NetBt.Transports, &pNetbtTransport->Next ); cNetbtTransportCount ++; } } } if ( cNetbtTransportCount == 0 ) { // IDS_NETBT_11405 " NetBt : [FATAL] No NetBt transports are configured" SetMessage(&pResults->NetBt.msgTestResult, Nd_Quiet, IDS_NETBT_11405); // the test failed, but we can continue with the other tests hr = S_FALSE; } else { int ids; TCHAR szBuffer[256]; if (cNetbtTransportCount > 1) { ids = IDS_NETBT_11406; // IDS_NETBT_11406 " %ld NetBt transport%s currently configured.\n" } else { ids = IDS_NETBT_11407; // IDS_NETBT_11407 " 1 NetBt transport currently configured.\n" } SetMessage(&pResults->NetBt.msgTestResult, Nd_Verbose, ids, cNetbtTransportCount); } } pResults->NetBt.cTransportCount = cNetbtTransportCount; Cleanup: if ( pWti0 ) { NetApiBufferFree( pWti0 ); } pResults->NetBt.hr = hr; return hr; } BOOLEAN NlTransportGetIpAddress( IN LPWSTR pswzTransportName, OUT PULONG IpAddress, IN OUT NETDIAG_RESULT *pResults ) /*++ Routine Description: Get the IP Address associated with the specified transport. Arguments: pswzTransportName - Name of the transport to query. IpAddress - IP address of the transport. Zero if the transport currently has no address or if the transport is not IP. Return Value: TRUE: transport is an IP transport --*/ { NTSTATUS Status; BOOLEAN RetVal = FALSE; IO_STATUS_BLOCK IoStatusBlock; OBJECT_ATTRIBUTES ObjectAttributes; UNICODE_STRING TransportNameString; HANDLE TransportHandle = NULL; ULONG IpAddresses[NBT_MAXIMUM_BINDINGS+1]; ULONG BytesReturned; // // Open the transport device directly. // *IpAddress = 0; RtlInitUnicodeString( &TransportNameString, pswzTransportName ); InitializeObjectAttributes( &ObjectAttributes, &TransportNameString, OBJ_CASE_INSENSITIVE, NULL, NULL ); Status = NtOpenFile( &TransportHandle, SYNCHRONIZE, &ObjectAttributes, &IoStatusBlock, 0, 0 ); if (NT_SUCCESS(Status)) { Status = IoStatusBlock.Status; } if (! NT_SUCCESS(Status)) { // IDS_NETBT_11408 " [FATAL] Cannot open netbt driver '%ws'\n" SetMessage(&pResults->NetBt.msgTestResult, Nd_Quiet, IDS_NETBT_11408, pswzTransportName); goto Cleanup; } // // Query the IP Address // if (!DeviceIoControl( TransportHandle, IOCTL_NETBT_GET_IP_ADDRS, NULL, 0, IpAddresses, sizeof(IpAddresses), &BytesReturned, NULL)) { TCHAR szBuffer[256]; Status = NetpApiStatusToNtStatus(GetLastError()); // IDS_NETBT_11409 " [FATAL] Cannot get IP address from netbt driver '%ws':" SetMessage(&pResults->NetBt.msgTestResult, Nd_Quiet, IDS_NETBT_11409, pswzTransportName); goto Cleanup; } // // Return IP Address // (Netbt returns the address in host order.) // *IpAddress = htonl(*IpAddresses); RetVal = TRUE; Cleanup: if ( TransportHandle != NULL ) { (VOID) NtClose( TransportHandle ); } return RetVal; } void NetBTGlobalPrint(NETDIAG_PARAMS *pParams, NETDIAG_RESULT *pResults) { PLIST_ENTRY ListEntry; PNETBT_TRANSPORT pNetbtTransport; if (pParams->fVerbose || !FHrOK(pResults->NetBt.hr)) { PrintNewLine(pParams, 2); PrintTestTitleResult(pParams, IDS_NETBT_LONG, IDS_NETBT_SHORT, pResults->NetBt.fPerformed, pResults->NetBt.hr, 0); } if ( pParams->fVerbose && pResults->NetBt.fPerformed) { // IDS_NETBT_11411 " List of NetBt transports currently configured.\n" PrintMessage(pParams, IDS_NETBT_11411); } // Iterate through the transports // for ( ListEntry = pResults->NetBt.Transports.Flink ; ListEntry != &pResults->NetBt.Transports ; ListEntry = ListEntry->Flink ) { // // If the transport names match, // return the entry // pNetbtTransport = CONTAINING_RECORD( ListEntry, NETBT_TRANSPORT, Next ); if (pParams->fVerbose) { // Strip off the "\Device\" off of the beginning of // the string // IDS_NETBT_11412 " %ws\n" PrintMessage(pParams, IDS_NETBT_11412, MapGuidToServiceNameW(pNetbtTransport->pswzTransportName+8)); } } PrintNdMessage(pParams, &pResults->NetBt.msgTestResult); } void NetBTPerInterfacePrint(NETDIAG_PARAMS *pParams, NETDIAG_RESULT *pResults, INTERFACE_RESULT *pInterfaceResults) { } void NetBTCleanup(NETDIAG_PARAMS *pParams, NETDIAG_RESULT *pResults) { PNETBT_TRANSPORT pNetbtTransport; PLIST_ENTRY pListEntry; PLIST_ENTRY pListHead = &pResults->NetBt.Transports; // Need to remove all entries from the list while (!IsListEmpty(pListHead)) { pListEntry = RemoveHeadList(pListHead); pNetbtTransport = CONTAINING_RECORD( pListEntry, NETBT_TRANSPORT, Next ); Free( pNetbtTransport ); } ClearMessage(&pResults->NetBt.msgTestResult); }