405 lines
11 KiB
C
405 lines
11 KiB
C
//++
|
|
//
|
|
// 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<EntriesRead; i++ )
|
|
{
|
|
UNICODE_STRING TransportName;
|
|
|
|
RtlInitUnicodeString( &TransportName, (LPWSTR)pWti0[i].wkti0_transport_name );
|
|
|
|
if ( TransportName.Length >= 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);
|
|
}
|
|
|