Windows NT 4.0 source code leak
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.
 
 
 
 
 
 

392 lines
10 KiB

/*++
Copyright (c) 1992 Microsoft Corporation
Module Name:
brwan.c
Abstract:
This module contains WAN support routines used by the
Browser service.
Author:
Larry Osterman (LarryO) 22-Nov-1992
Revision History:
--*/
#include "precomp.h"
#pragma hdrstop
//-------------------------------------------------------------------//
// //
// Local function prototypes //
// //
//-------------------------------------------------------------------//
NET_API_STATUS
BrAddDomainEntry(
IN PINTERIM_SERVER_LIST InterimServerList,
IN LPTSTR ConfigEntry
);
//-------------------------------------------------------------------//
// //
// Global variables //
// //
//-------------------------------------------------------------------//
//-------------------------------------------------------------------//
// //
// Global routines //
// //
//-------------------------------------------------------------------//
NET_API_STATUS NET_API_FUNCTION
I_BrowserrQueryOtherDomains(
IN BROWSER_IDENTIFY_HANDLE ServerName,
IN OUT LPSERVER_ENUM_STRUCT InfoStruct,
OUT LPDWORD TotalEntries
)
/*++
Routine Description:
This routine returns the list of "other domains" configured for this
machine. It is only valid on primary domain controllers. If it is called
on a machine that is not a PDC, it will return NERR_NotPrimary.
Arguments:
IN BROWSER_IDENTIFY_HANDLE ServerName - Ignored.
IN LPSERVER_ENUM_STRUCT InfoStruct - Returns the list of other domains
as a SERVER_INFO_100 structure.
OUT LPDWORD TotalEntries - Returns the total number of other domains.
Return Value:
NET_API_STATUS - The status of this request.
--*/
{
NET_API_STATUS Status;
LMDR_REQUEST_PACKET RequestPacket;
PDGRECEIVE_NAMES NameTable;
PVOID Buffer;
LPTSTR BufferEnd;
PSERVER_INFO_100 ServerInfo;
ULONG NumberOfOtherDomains;
ULONG BufferSizeNeeded;
ULONG i;
if (!BrInfo.IsPrimaryDomainController) {
return NERR_NotPrimary;
}
if (InfoStruct->Level != 100) {
return(ERROR_INVALID_LEVEL);
}
RequestPacket.Type = EnumerateNames;
RequestPacket.Version = LMDR_REQUEST_PACKET_VERSION;
RequestPacket.Level = 0;
RequestPacket.TransportName.Length = 0;
RequestPacket.TransportName.Buffer = NULL;
RequestPacket.Parameters.EnumerateNames.ResumeHandle = 0;
Status = DeviceControlGetInfo(BrDgReceiverDeviceHandle,
IOCTL_LMDR_ENUMERATE_NAMES,
&RequestPacket,
sizeof(RequestPacket),
(LPVOID *)&NameTable,
0xffffffff,
0,
NULL);
if (Status != NERR_Success) {
return Status;
}
NumberOfOtherDomains = 0;
BufferSizeNeeded = 0;
for (i = 0;i < RequestPacket.Parameters.EnumerateNames.EntriesRead ; i++) {
if (NameTable[i].Type == OtherDomain) {
NumberOfOtherDomains += 1;
BufferSizeNeeded += sizeof(SERVER_INFO_100)+NameTable[i].DGReceiverName.Length+sizeof(TCHAR);
}
}
*TotalEntries = NumberOfOtherDomains;
Buffer = MIDL_user_allocate(BufferSizeNeeded);
if (Buffer == NULL) {
MIDL_user_free(NameTable);
return(ERROR_NOT_ENOUGH_MEMORY);
}
ServerInfo = Buffer;
BufferEnd = (LPTSTR)((PCHAR)Buffer+BufferSizeNeeded);
for (i = 0;i < RequestPacket.Parameters.EnumerateNames.EntriesRead ; i++) {
if (NameTable[i].Type == OtherDomain) {
WCHAR NameBuffer[DNLEN+1];
//
// The name from the browser is not null terminated, so copy it
// to a local buffer and null terminate it.
//
RtlCopyMemory(NameBuffer, NameTable[i].DGReceiverName.Buffer, NameTable[i].DGReceiverName.Length);
NameBuffer[(NameTable[i].DGReceiverName.Length) / sizeof(TCHAR)] = UNICODE_NULL;
ServerInfo->sv100_platform_id = PLATFORM_ID_OS2;
ServerInfo->sv100_name = NameBuffer;
if (!NetpPackString(&ServerInfo->sv100_name,
(LPBYTE)(ServerInfo+1),
&BufferEnd)) {
MIDL_user_free(NameTable);
return(NERR_InternalError);
}
ServerInfo += 1;
}
}
MIDL_user_free(NameTable);
InfoStruct->ServerInfo.Level100->Buffer = Buffer;
InfoStruct->ServerInfo.Level100->EntriesRead = NumberOfOtherDomains;
Status = NERR_Success;
return Status;
}
NET_API_STATUS
BrWanInitialize(
VOID
)
{
NET_API_STATUS Status;
if (BrInfo.IsPrimaryDomainController) {
//
// Post a GetMasterAnnouncement request to the bowser on every appropriate
// transport.
//
Status = BrPostGetMasterAnnouncement();
}
return Status;
}
VOID
BrWanUninitialize(
VOID
)
{
return;
}
NET_API_STATUS
BrWanMasterInitialize(
IN PNETWORK Network
)
/*++
Routine Description:
This routine initializes the wan information for a new master.
--*/
{
LPTSTR PDCName = NULL;
LPBYTE Buffer = NULL;
PSERVER_INFO_100 ServerInfo;
NET_API_STATUS Status;
ULONG i;
ULONG EntriesRead;
ULONG TotalEntries;
//
// If we're not on the PDC, then all our initialization has been done.
//
if (BrInfo.IsPrimaryDomainController) {
return NERR_Success;
}
Status = NetGetDCName(NULL, NULL, (LPBYTE *)&PDCName);
//
// It is not an error to not be able to contact the PDC.
//
if (Status != NERR_Success) {
return NERR_Success;
}
Status = I_BrowserQueryOtherDomains(PDCName, &Buffer, &EntriesRead, &TotalEntries);
//
// We don't need the PDC name any more.
//
NetApiBufferFree(PDCName);
PDCName = NULL;
//
// It is also not an error to fail to query the other domains from the PDC.
//
if (Status != NERR_Success) {
return NERR_Success;
}
if (!LOCK_NETWORK(Network)) {
return NERR_InternalError;
}
try {
PLIST_ENTRY Entry;
PLIST_ENTRY NextEntry;
//
// Scan the other domains list and turn on the active bit for each
// other domain.
//
for (Entry = Network->OtherDomainsList.Flink;
Entry != &Network->OtherDomainsList ;
Entry = Entry->Flink) {
PNET_OTHER_DOMAIN OtherDomain = CONTAINING_RECORD(Entry, NET_OTHER_DOMAIN, Next);
OtherDomain->Flags |= OTHERDOMAIN_INVALID;
}
ServerInfo = (PSERVER_INFO_100)Buffer;
for (i = 0; i < EntriesRead; i++ ) {
//
// Add this as an other domain.
//
for (Entry = Network->OtherDomainsList.Flink;
Entry != &Network->OtherDomainsList ;
Entry = Entry->Flink) {
PNET_OTHER_DOMAIN OtherDomain = CONTAINING_RECORD(Entry, NET_OTHER_DOMAIN, Next);
//
// If this name is in the other domains list, it's not invalid
// and we should flag that we've seen the domain name.
//
if (!_wcsicmp(OtherDomain->Name, ServerInfo->sv100_name)) {
OtherDomain->Flags &= ~OTHERDOMAIN_INVALID;
ServerInfo->sv100_name = NULL;
}
}
ServerInfo ++;
}
//
// Scan the other domains list and remove any domains that are
// still marked as invalid.
//
for (Entry = Network->OtherDomainsList.Flink;
Entry != &Network->OtherDomainsList ;
Entry = NextEntry) {
PNET_OTHER_DOMAIN OtherDomain = CONTAINING_RECORD(Entry, NET_OTHER_DOMAIN, Next);
if (OtherDomain->Flags & OTHERDOMAIN_INVALID) {
NextEntry = Entry->Flink;
//
// Remove this entry from the list.
//
RemoveEntryList(Entry);
BrRemoveOtherDomain(Network, OtherDomain->Name);
MIDL_user_free(OtherDomain);
} else {
NextEntry = Entry->Flink;
}
}
//
// Now scan the domain list from the PDC and add any entries that
// weren't there already.
//
ServerInfo = (PSERVER_INFO_100)Buffer;
for (i = 0; i < EntriesRead; i++ ) {
if (ServerInfo->sv100_name != NULL) {
PNET_OTHER_DOMAIN OtherDomain = MIDL_user_allocate(sizeof(NET_OTHER_DOMAIN));
if (OtherDomain != NULL) {
Status = BrAddOtherDomain(Network, ServerInfo->sv100_name);
//
// If we were able to add the other domain, add it to our
// internal structure.
//
if (Status == NERR_Success) {
wcscpy(OtherDomain->Name, ServerInfo->sv100_name);
OtherDomain->Flags = 0;
InsertHeadList(&Network->OtherDomainsList, &OtherDomain->Next);
} else {
LPWSTR SubString[1];
SubString[0] = ServerInfo->sv100_name;
BrLogEvent(EVENT_BROWSER_OTHERDOMAIN_ADD_FAILED, Status, 1, SubString);
}
}
}
ServerInfo ++;
}
} finally {
UNLOCK_NETWORK(Network);
if (Buffer != NULL) {
MIDL_user_free(Buffer);
}
}
return NERR_Success;
}