|
|
//++
//
// Copyright (C) Microsoft Corporation, 1987 - 1999
//
// Module Name:
//
// browser.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 "malloc.h"
#include "nbtutil.h"
NET_API_STATUS GetBrowserTransportList(OUT PLMDR_TRANSPORT_LIST *TransportList); //$review (nsun) there is a recursive calling of this function
NTSTATUS NettestBrowserSendDatagram( IN PLIST_ENTRY listNetbtTransports, IN PDSROLE_PRIMARY_DOMAIN_INFO_BASIC pPrimaryDomainInfo, IN PVOID ContextDomainInfo, IN ULONG IpAddress, IN LPWSTR UnicodeDestinationName, IN DGRECEIVER_NAME_TYPE NameType, IN LPWSTR pswzTransportName, IN LPSTR OemMailslotName, IN PVOID Buffer, IN ULONG BufferSize ); BOOL MailslotTest(NETDIAG_PARAMS* pParams, IN LPWSTR DestinationName, NETDIAG_RESULT* pResults);
BOOL BrowserTest( NETDIAG_PARAMS* pParams, NETDIAG_RESULT* pResults ) /*++
Routine Description:
Determine the machines role and membership.
Arguments:
None.
Return Value:
TRUE: Test suceeded. FALSE: Test failed
--*/ { NET_API_STATUS NetStatus; HRESULT hrRetVal = S_OK;
BOOL BrowserIsUp = TRUE; BOOL RedirIsUp = TRUE; PLMDR_TRANSPORT_LIST TransportList = NULL; PLMDR_TRANSPORT_LIST TransportEntry; LONG NetbtTransportCount; LONG RealNetbtTransportCount; PNETBT_TRANSPORT NetbtTransport; BOOL PrintIt; PWKSTA_TRANSPORT_INFO_0 pWti0 = NULL; DWORD EntriesRead; DWORD TotalEntries; DWORD i; WCHAR DestinationName[MAX_PATH+1]; BOOL MailslotTested = FALSE; PTESTED_DOMAIN TestedDomain; PLIST_ENTRY ListEntry;
USES_CONVERSION;
PrintStatusMessage( pParams, 4, IDS_BROWSER_STATUS_MSG ); pResults->Browser.fPerformed = TRUE;
InitializeListHead( &pResults->Browser.lmsgOutput );
//
// Ensure the workstation service is running.
//
NetStatus = IsServiceStarted( _T("LanmanWorkstation") );
if ( NetStatus != NO_ERROR ) { //IDS_BROWSER_13001 " [FATAL] Workstation service is not running. [%s]\n"
AddMessageToList( &pResults->Browser.lmsgOutput, Nd_Quiet, IDS_BROWSER_13001, NetStatusToString(NetStatus) ); hrRetVal = S_OK; goto Cleanup; }
if (!pResults->Global.fHasNbtEnabledInterface) { AddMessageToList( &pResults->Browser.lmsgOutput, Nd_Verbose, IDS_BROWSER_NETBT_DISABLED); pResults->Browser.fPerformed = FALSE; hrRetVal = S_OK; goto Cleanup; }
//
// Get the transports bound to the Redir
//
if ( pParams->fReallyVerbose ) { //IDS_BROWSER_13002 " List of transports currently bound to the Redir\n"
AddMessageToListId( &pResults->Browser.lmsgOutput, Nd_ReallyVerbose, IDS_BROWSER_13002 ); } else if ( pParams->fVerbose ) { //IDS_BROWSER_13003 " List of NetBt transports currently bound to the Redir\n"
AddMessageToListId( &pResults->Browser.lmsgOutput, Nd_Verbose, IDS_BROWSER_13003 ); }
NetStatus = NetWkstaTransportEnum( NULL, 0, (LPBYTE *)&pWti0, 0xFFFFFFFF, // MaxPreferredLength
&EntriesRead, &TotalEntries, NULL ); // Optional resume handle
if (NetStatus != NERR_Success) { //IDS_BROWSER_13004 " [FATAL] Unable to retrieve transport list from Redir. [%s]\n"
AddMessageToList( &pResults->Browser.lmsgOutput, Nd_Quiet, IDS_BROWSER_13004, NetStatusToString(NetStatus) ); hrRetVal = S_FALSE; RedirIsUp = FALSE; } else { NetbtTransportCount = 0; RealNetbtTransportCount = 0; for ( i = 0; i < EntriesRead; i++ ) { UNICODE_STRING ustrTransportName; LPTSTR pszTransportName;
RtlInitUnicodeString( &ustrTransportName, (LPWSTR)pWti0[i].wkti0_transport_name );
// Strip off the "\Device\" off of the beginning of
// the string
pszTransportName = W2T(MapGuidToServiceNameW(ustrTransportName.Buffer + 8));
PrintIt = FALSE;
if ( ustrTransportName.Length >= sizeof(NETBT_DEVICE_PREFIX) && _wcsnicmp( ustrTransportName.Buffer, NETBT_DEVICE_PREFIX, (sizeof(NETBT_DEVICE_PREFIX)/sizeof(WCHAR)-1)) == 0 ) {
//
// Determine if this Netbt transport really exists.
//
NetbtTransport = FindNetbtTransport( pResults, ustrTransportName.Buffer );
if ( NetbtTransport == NULL ) { //IDS_BROWSER_13005 " [FATAL] Transport %s is bound to the redir but is not a configured NetbtTransport."
AddMessageToList( &pResults->Browser.lmsgOutput, Nd_Quiet, IDS_BROWSER_13005, pszTransportName ); hrRetVal = S_FALSE; } else { if ( NetbtTransport->Flags & BOUND_TO_REDIR ) { //IDS_BROWSER_13006 " [WARNING] Transport %s is bound to redir more than once."
AddMessageToList( &pResults->Browser.lmsgOutput, Nd_Verbose, IDS_BROWSER_13006, pszTransportName ); } else { NetbtTransport->Flags |= BOUND_TO_REDIR; RealNetbtTransportCount ++; } }
//
// Count the found transports.
//
NetbtTransportCount ++; if ( pParams->fVerbose ) { PrintIt = TRUE; } }
//IDS_BROWSER_13007 " %s\n"
AddMessageToList( &pResults->Browser.lmsgOutput, PrintIt ? Nd_Verbose : Nd_ReallyVerbose, IDS_BROWSER_13007, pszTransportName);//&ustrTransportName );
}
//
// Ensure the redir is bound to some Netbt transports.
//
if ( NetbtTransportCount == 0 ) { //IDS_BROWSER_13008 " [FATAL] The redir isn't bound to any NetBt transports."
AddMessageToListId( &pResults->Browser.lmsgOutput, Nd_Quiet, IDS_BROWSER_13008); hrRetVal = S_FALSE; RedirIsUp = FALSE; } else { //IDS_BROWSER_13009 " The redir is bound to %ld NetBt transport%s.\n"
AddMessageToList( &pResults->Browser.lmsgOutput, Nd_Verbose, IDS_BROWSER_13009, NetbtTransportCount, NetbtTransportCount > 1 ? "s" : "" ); }
//
// Ensure the redir is bound to all of the Netbt transports.
//
if ( RealNetbtTransportCount != pResults->NetBt.cTransportCount ) { //IDS_BROWSER_13010 " [FATAL] The redir is only bound to %ld of the %ld NetBt transports."
AddMessageToList( &pResults->Browser.lmsgOutput, Nd_Quiet, IDS_BROWSER_13010, RealNetbtTransportCount, pResults->NetBt.cTransportCount ); hrRetVal = S_FALSE; } }
//
// Get the transports bound to the browser.
//
//IDS_BROWSER_13011 "\n"
AddMessageToListId( &pResults->Browser.lmsgOutput, Nd_Verbose, IDS_BROWSER_13011);
if ( pParams->fReallyVerbose ) //IDS_BROWSER_13012 " List of transports currently bound to the browser\n"
AddMessageToListId( &pResults->Browser.lmsgOutput, Nd_ReallyVerbose, IDS_BROWSER_13012 ); else if ( pParams->fVerbose ) //IDS_BROWSER_13013 " List of NetBt transports currently bound to the browser\n"
AddMessageToListId( &pResults->Browser.lmsgOutput, Nd_Verbose, IDS_BROWSER_13013 );
NetStatus = GetBrowserTransportList(&TransportList);
if (NetStatus != NERR_Success) { //IDS_BROWSER_13014 " [FATAL] Unable to retrieve transport list from browser. [%s]\n"
AddMessageToList( &pResults->Browser.lmsgOutput, Nd_Quiet, IDS_BROWSER_13014, NetStatusToString(NetStatus) ); hrRetVal = S_FALSE; BrowserIsUp = FALSE; } else { TransportEntry = TransportList;
NetbtTransportCount = 0; RealNetbtTransportCount = 0; while (TransportEntry != NULL) { UNICODE_STRING ustrTransportName; LPTSTR pszTransportName;
ustrTransportName.Buffer = TransportEntry->TransportName; ustrTransportName.Length = (USHORT)TransportEntry->TransportNameLength; ustrTransportName.MaximumLength = (USHORT)TransportEntry->TransportNameLength;
pszTransportName = W2T(MapGuidToServiceNameW(ustrTransportName.Buffer + 8));
PrintIt = FALSE; if ( ustrTransportName.Length >= sizeof(NETBT_DEVICE_PREFIX) && _wcsnicmp( ustrTransportName.Buffer, NETBT_DEVICE_PREFIX, (sizeof(NETBT_DEVICE_PREFIX)/sizeof(WCHAR)-1)) == 0 ) {
//
// Determine if this Netbt transport really exists.
//
NetbtTransport = FindNetbtTransport( pResults, ustrTransportName.Buffer );
if ( NetbtTransport == NULL ) { //IDS_BROWSER_13015 " [FATAL] Transport %s is bound to the browser but is not a configured NetbtTransport."
AddMessageToList( &pResults->Browser.lmsgOutput, Nd_Quiet, IDS_BROWSER_13015, pszTransportName ); hrRetVal = S_FALSE; } else { if ( NetbtTransport->Flags & BOUND_TO_BOWSER ) { //IDS_BROWSER_13016 " [FATAL] Transport %s is bound to browser more than once."
AddMessageToList( &pResults->Browser.lmsgOutput, Nd_Quiet, IDS_BROWSER_13016, pszTransportName ); hrRetVal = S_FALSE; } else { NetbtTransport->Flags |= BOUND_TO_BOWSER; RealNetbtTransportCount ++; }
}
//
// Count the found transports.
//
NetbtTransportCount ++; if ( pParams->fVerbose ) PrintIt = TRUE; }
//IDS_BROWSER_13017 " %s\n"
AddMessageToList( &pResults->Browser.lmsgOutput, PrintIt ? Nd_Verbose : Nd_ReallyVerbose, IDS_BROWSER_13017, pszTransportName );
if (TransportEntry->NextEntryOffset == 0) { TransportEntry = NULL; } else { TransportEntry = (PLMDR_TRANSPORT_LIST)((PCHAR)TransportEntry+TransportEntry->NextEntryOffset); } }
if ( NetbtTransportCount == 0 ) { //IDS_BROWSER_13018 " [FATAL] The browser isn't bound to any NetBt transports"
AddMessageToListId( &pResults->Browser.lmsgOutput, Nd_Quiet, IDS_BROWSER_13018 ); hrRetVal = S_FALSE; BrowserIsUp = FALSE; } else { //IDS_BROWSER_13019 " The browser is bound to %ld NetBt transport%s.\n"
AddMessageToList( &pResults->Browser.lmsgOutput, Nd_Verbose, IDS_BROWSER_13019, NetbtTransportCount, NetbtTransportCount > 1 ? "s" : "" ); }
//
// Ensure the browser is bound to all of the Netbt transports.
//
if ( RealNetbtTransportCount != pResults->NetBt.cTransportCount ) { //IDS_BROWSER_13020 " [FATAL] The browser is only bound to %ld of the %ld NetBt transports."
AddMessageToList( &pResults->Browser.lmsgOutput, Nd_Quiet, IDS_BROWSER_13020, RealNetbtTransportCount, pResults->NetBt.cTransportCount ); hrRetVal = FALSE; } }
//
// Ensure we can send mailslot messages. (DsGetDcName uses them.)
//
// Try sending to each of the tested domains.
//
for ( ListEntry = pResults->Global.listTestedDomains.Flink ; ListEntry != &pResults->Global.listTestedDomains ; ListEntry = ListEntry->Flink ) {
//
// Only test this domain if it is has a Netbios domain name
//
TestedDomain = CONTAINING_RECORD( ListEntry, TESTED_DOMAIN, Next );
if ( TestedDomain->NetbiosDomainName != NULL ) { //
// Send the message to the <DomainName>[1C] name
//
wcscpy( DestinationName, TestedDomain->NetbiosDomainName ); wcscat( DestinationName, L"*" ); if ( !MailslotTest( pParams, DestinationName, pResults ) ) { hrRetVal = S_FALSE; } else { USES_CONVERSION; //IDS_BROWSER_13021 "Mailslot test for %s passed.\n"
AddMessageToList( &pResults->Browser.lmsgOutput, Nd_ReallyVerbose, IDS_BROWSER_13021, W2CT(DestinationName)); } MailslotTested = TRUE; } }
//
// If we still haven't tested mailslots,
// test them by sending the message to our own computername.
//
//#ifdef notdef // crashes build 1728
if ( !MailslotTested ) { wcscpy( DestinationName, pResults->Global.swzNetBiosName ); if ( !MailslotTest( pParams, DestinationName, pResults ) ) { hrRetVal = S_FALSE; } MailslotTested = TRUE; } //#endif // notdef // crashes build 1728
Cleanup: if ( pWti0 ) { NetApiBufferFree( pWti0 ); }
if ( TransportList != NULL ) { NetApiBufferFree(TransportList); }
if ( FHrOK(hrRetVal) ) { PrintStatusMessage(pParams, 0, IDS_GLOBAL_PASS_NL); } else { PrintStatusMessage(pParams, 0, IDS_GLOBAL_FAIL_NL); }
pResults->Browser.hrTestResult = hrRetVal;
return hrRetVal; }
NET_API_STATUS GetBrowserTransportList( OUT PLMDR_TRANSPORT_LIST *TransportList )
/*++
Routine Description:
This routine returns the list of transports bound into the browser.
Arguments:
OUT PLMDR_TRANSPORT_LIST *TransportList - Transport list to return.
Return Value:
NET_API_STATUS - NERR_Success or reason for failure.
--*/
{
NET_API_STATUS NetStatus; HANDLE BrowserHandle; LMDR_REQUEST_PACKET RequestPacket;
NetStatus = OpenBrowser(&BrowserHandle);
if (NetStatus != NERR_Success) { DebugMessage2(" [FATAL] Unable to open browser driver. [%s]\n", NetStatusToString(NetStatus) ); return NetStatus; }
RequestPacket.Version = LMDR_REQUEST_PACKET_VERSION_DOM;
RequestPacket.Type = EnumerateXports;
RtlInitUnicodeString(&RequestPacket.TransportName, NULL); RtlInitUnicodeString(&RequestPacket.EmulatedDomainName, NULL);
NetStatus = DeviceControlGetInfo( BrowserHandle, IOCTL_LMDR_ENUMERATE_TRANSPORTS, &RequestPacket, sizeof(RequestPacket), (PVOID *)TransportList, 0xffffffff, 4096, NULL);
NtClose(BrowserHandle);
return NetStatus; }
BOOL MailslotTest( NETDIAG_PARAMS* pParams, IN LPWSTR DestinationName, NETDIAG_RESULT* pResults ) /*++
Routine Description:
Ensure we can send mailslot messages.
Test both via redir and browser.
Don't test responses (since that really tests if the DC is up).
Arguments:
DestinationName - Name to send the message to Name ends in * if destination is the [1c] name.
Return Value:
TRUE: Test suceeded. FALSE: Test failed
--*/ { BOOL RetVal = TRUE;
NET_API_STATUS NetStatus; NTSTATUS Status; HANDLE ResponseMailslotHandle = NULL; TCHAR ResponseMailslotName[MAX_PATH+1]; WCHAR NetlogonMailslotName[MAX_PATH+1];
WCHAR BrowserDestinationName[MAX_PATH+1]; DWORD BrowserDestinationNameLen; DGRECEIVER_NAME_TYPE NameType;
PVOID PingMessage = NULL; ULONG PingMessageSize = 0;
//
// Open a mailslot to get ping responses on.
//
//
NetStatus = NetpLogonCreateRandomMailslot( ResponseMailslotName, &ResponseMailslotHandle );
if (NetStatus != NO_ERROR ) { //IDS_BROWSER_13022 " [FATAL] Cannot create temp mailslot. [%s]\n"
AddMessageToList( &pResults->Browser.lmsgOutput, Nd_Quiet, IDS_BROWSER_13022, NetStatusToString(NetStatus) ); RetVal = FALSE; goto Cleanup; }
//
// Allocate a mailslot message to send
//
NetStatus = NetpDcBuildPing ( FALSE, // Not only PDC
0, // Retry count
pResults->Global.swzNetBiosName, //replace GlobalNetbiosComputerName,
NULL, // No Account name
ResponseMailslotName, 0, // no AllowableAccountControlBits,
NULL, // No Domain SID
0, // Not NT Version 5
&PingMessage, &PingMessageSize );
if ( NetStatus != NO_ERROR ) { //IDS_BROWSER_13023 " [FATAL] Cannot allocate mailslot message. [%s]\n"
AddMessageToList( &pResults->Browser.lmsgOutput, Nd_Quiet, IDS_BROWSER_13023, NetStatusToString(NetStatus) ); RetVal = FALSE; goto Cleanup; }
//
// Build the destination mailslot name.
//
NetlogonMailslotName[0] = '\\'; NetlogonMailslotName[1] = '\\'; wcscpy(NetlogonMailslotName + 2, DestinationName ); wcscat( NetlogonMailslotName, NETLOGON_LM_MAILSLOT_W );
//
// Send the mailslot via the redir.
//
NetStatus = NetpLogonWriteMailslot( NetlogonMailslotName, (PCHAR)PingMessage, PingMessageSize );
if ( NetStatus != NO_ERROR ) { //IDS_BROWSER_13024 " [FATAL] Cannot send mailslot message to '%ws' via redir. [%s]\n"
AddMessageToList( &pResults->Browser.lmsgOutput, Nd_Quiet, IDS_BROWSER_13024, NetlogonMailslotName, NetStatusToString(NetStatus) ); RetVal = FALSE; goto Cleanup; }
//
// Send the mailslot via the browser
//
// Avoid this test if this build has an old value for the IOCTL function
// code to the browser.
//
if ( _ttoi(pResults->Global.pszCurrentBuildNumber) < NTBUILD_BOWSER ) { if ( pParams->fReallyVerbose ) { //IDS_BROWSER_13025 " Cannot sending mailslot messages via the browser since this machine is running build %ld. [Test skipped.]\n"
AddMessageToList( &pResults->Browser.lmsgOutput, Nd_Quiet, IDS_BROWSER_13025, pResults->Global.pszCurrentBuildNumber ); } } else { wcscpy( BrowserDestinationName, DestinationName ); BrowserDestinationNameLen = wcslen(BrowserDestinationName);
if ( BrowserDestinationName[BrowserDestinationNameLen-1] == L'*' ) { BrowserDestinationName[BrowserDestinationNameLen-1] = L'\0'; NameType = DomainName; // [1c] name
} else { NameType = PrimaryDomain; // [00] name
}
Status = NettestBrowserSendDatagram( &pResults->NetBt.Transports, pResults->Global.pPrimaryDomainInfo, NULL, ALL_IP_TRANSPORTS, BrowserDestinationName, NameType, NULL, // All transports
NETLOGON_LM_MAILSLOT_A, PingMessage, PingMessageSize );
if ( !NT_SUCCESS(Status) ) { NetStatus = NetpNtStatusToApiStatus(Status); //IDS_BROWSER_13026 " [FATAL] Cannot send mailslot message to '%ws' via browser. [%s]\n"
AddMessageToList( &pResults->Browser.lmsgOutput, Nd_Quiet, IDS_BROWSER_13026, DestinationName, NetStatusToString(NetStatus) ); RetVal = FALSE; goto Cleanup; } }
Cleanup: if ( PingMessage != NULL ) { NetpMemoryFree( PingMessage ); } if ( ResponseMailslotHandle != NULL ) { CloseHandle(ResponseMailslotHandle); } return RetVal; }
NTSTATUS NettestBrowserSendDatagram( IN PLIST_ENTRY plistNetbtTransports, IN PDSROLE_PRIMARY_DOMAIN_INFO_BASIC pPrimaryDomainInfo, IN PVOID ContextDomainInfo, IN ULONG IpAddress, IN LPWSTR UnicodeDestinationName, IN DGRECEIVER_NAME_TYPE NameType, IN LPWSTR TransportName, IN LPSTR OemMailslotName, IN PVOID Buffer, IN ULONG BufferSize ) /*++
Routine Description:
Send the specified mailslot message to the specified mailslot on the specified server on the specified transport..
Arguments:
DomainInfo - Hosted domain sending the datagram
IpAddress - IpAddress of the machine to send the message to. If zero, UnicodeDestinationName must be specified. If ALL_IP_TRANSPORTS, UnicodeDestination must be specified but the datagram will only be sent on IP transports.
UnicodeDestinationName -- Name of the server to send to.
NameType -- Type of name represented by UnicodeDestinationName.
TransportName -- Name of the transport to send on. Use NULL to send on all transports.
OemMailslotName -- Name of the mailslot to send to.
Buffer -- Specifies a pointer to the mailslot message to send.
BufferSize -- Size in bytes of the mailslot message
Return Value:
Status of the operation.
STATUS_NETWORK_UNREACHABLE: Cannot write to network.
--*/ { PLMDR_REQUEST_PACKET RequestPacket = NULL; NET_API_STATUS NetStatus;
DWORD OemMailslotNameSize; DWORD TransportNameSize; DWORD DestinationNameSize; WCHAR IpAddressString[NL_IP_ADDRESS_LENGTH+1]; ULONG Information; HANDLE BrowserHandle = NULL;
NTSTATUS Status; LPBYTE Where; LONG test;
//
// If the transport isn't specified,
// send on all transports.
//
if ( TransportName == NULL ) { ULONG i; PLIST_ENTRY ListEntry; NTSTATUS SavedStatus = STATUS_NETWORK_UNREACHABLE;
//
// Loop through the list of netbt transports finding this one.
//
for ( ListEntry = plistNetbtTransports->Flink ; ListEntry != plistNetbtTransports ; ListEntry = ListEntry->Flink ) {
PNETBT_TRANSPORT NetbtTransport;
//
// If the transport names match,
// return the entry
//
NetbtTransport = CONTAINING_RECORD( ListEntry, NETBT_TRANSPORT, Next );
//
// Skip deleted transports.
//
if ( (NetbtTransport->Flags & BOUND_TO_BOWSER) == 0 ) { continue; }
Status = NettestBrowserSendDatagram( plistNetbtTransports, pPrimaryDomainInfo, ContextDomainInfo, IpAddress, UnicodeDestinationName, NameType, NetbtTransport->pswzTransportName, OemMailslotName, Buffer, BufferSize );
if ( NT_SUCCESS(Status) ) { // If any transport works, we've been successful
SavedStatus = STATUS_SUCCESS; } else { // Remember the real reason for the failure instead of the default failure status
// Remember only the first failure.
if ( SavedStatus == STATUS_NETWORK_UNREACHABLE ) { SavedStatus = Status; } }
} return SavedStatus; }
//
// Open a handle to the browser.
//
NetStatus = OpenBrowser(&BrowserHandle);
if (NetStatus != NERR_Success) { DebugMessage2(" [FATAL] Unable to open browser driver. [%s]\n", NetStatusToString(NetStatus)); Status = NetpApiStatusToNtStatus( NetStatus ); goto Cleanup; }
//
// Allocate a request packet.
//
OemMailslotNameSize = strlen(OemMailslotName) + 1; TransportNameSize = (wcslen(TransportName) + 1) * sizeof(WCHAR);
if ( UnicodeDestinationName == NULL ) { return STATUS_INTERNAL_ERROR; }
DestinationNameSize = wcslen(UnicodeDestinationName) * sizeof(WCHAR);
RequestPacket = NetpMemoryAllocate( sizeof(LMDR_REQUEST_PACKET) + TransportNameSize + OemMailslotNameSize + DestinationNameSize + sizeof(WCHAR) + (wcslen( pPrimaryDomainInfo->DomainNameFlat ) + 1) * sizeof(WCHAR) + sizeof(WCHAR)) ; // For alignment
if (RequestPacket == NULL) { Status = STATUS_NO_MEMORY; goto Cleanup; }
//
// Fill in the Request Packet.
//
RequestPacket->Type = Datagram; RequestPacket->Parameters.SendDatagram.DestinationNameType = NameType;
//
// Fill in the name of the machine to send the mailslot message to.
//
RequestPacket->Parameters.SendDatagram.NameLength = DestinationNameSize;
Where = (LPBYTE) RequestPacket->Parameters.SendDatagram.Name; RtlCopyMemory( Where, UnicodeDestinationName, DestinationNameSize ); Where += DestinationNameSize;
//
// Fill in the name of the mailslot to send to.
//
RequestPacket->Parameters.SendDatagram.MailslotNameLength = OemMailslotNameSize; strcpy( Where, OemMailslotName); Where += OemMailslotNameSize; Where = ROUND_UP_POINTER( Where, ALIGN_WCHAR );
//
// Fill in the TransportName
//
wcscpy( (LPWSTR) Where, TransportName); RtlInitUnicodeString( &RequestPacket->TransportName, (LPWSTR) Where ); Where += TransportNameSize;
//
// Copy the hosted domain name to the request packet.
//
//If the machine doesn't belong to a domain, we shouldn't get to here
assert(pPrimaryDomainInfo->DomainNameFlat); if (pPrimaryDomainInfo->DomainNameFlat) { wcscpy( (LPWSTR)Where, pPrimaryDomainInfo->DomainNameFlat ); RtlInitUnicodeString( &RequestPacket->EmulatedDomainName, (LPWSTR)Where ); Where += (wcslen( pPrimaryDomainInfo->DomainNameFlat ) + 1) * sizeof(WCHAR); }
//
// Send the request to the browser.
//
NetStatus = BrDgReceiverIoControl( BrowserHandle, IOCTL_LMDR_WRITE_MAILSLOT, RequestPacket, (ULONG)(Where - (LPBYTE)RequestPacket), Buffer, BufferSize, &Information );
if ( NetStatus != NO_ERROR ) { Status = NetpApiStatusToNtStatus( NetStatus ); }
//
// Free locally used resources.
//
Cleanup: if ( BrowserHandle != NULL ) { NtClose(BrowserHandle); }
if ( RequestPacket != NULL ) { NetpMemoryFree( RequestPacket ); }
return Status; }
void BrowserGlobalPrint(NETDIAG_PARAMS *pParams, NETDIAG_RESULT *pResults) { if (pParams->fVerbose || !FHrOK(pResults->Browser.hrTestResult)) { PrintNewLine(pParams, 2); PrintTestTitleResult(pParams, IDS_BROWSER_LONG, IDS_BROWSER_SHORT, pResults->Browser.fPerformed, pResults->Browser.hrTestResult, 0); } PrintMessageList(pParams, &pResults->Browser.lmsgOutput);
}
void BrowserPerInterfacePrint(NETDIAG_PARAMS *pParams, NETDIAG_RESULT *pResults, INTERFACE_RESULT *pInterfaceResults) { //no per interface results
}
void BrowserCleanup(NETDIAG_PARAMS *pParams, NETDIAG_RESULT *pResults) { MessageListCleanUp(&pResults->Browser.lmsgOutput); }
|