326 lines
9.1 KiB
C
326 lines
9.1 KiB
C
|
|
|||
|
/*++
|
|||
|
|
|||
|
Copyright (c) 1991 Microsoft Corporation
|
|||
|
|
|||
|
Module Name:
|
|||
|
|
|||
|
brdmmstr.c
|
|||
|
|
|||
|
Abstract:
|
|||
|
|
|||
|
This module contains the routines to manage a domain master browser server
|
|||
|
|
|||
|
Author:
|
|||
|
|
|||
|
Rita Wong (ritaw) 20-Feb-1991
|
|||
|
|
|||
|
Revision History:
|
|||
|
|
|||
|
--*/
|
|||
|
|
|||
|
#include "precomp.h"
|
|||
|
#pragma hdrstop
|
|||
|
|
|||
|
//-------------------------------------------------------------------//
|
|||
|
// //
|
|||
|
// Local structure definitions //
|
|||
|
// //
|
|||
|
//-------------------------------------------------------------------//
|
|||
|
|
|||
|
//-------------------------------------------------------------------//
|
|||
|
// //
|
|||
|
// Local function prototypes //
|
|||
|
// //
|
|||
|
//-------------------------------------------------------------------//
|
|||
|
|
|||
|
VOID
|
|||
|
GetMasterAnnouncementCompletion (
|
|||
|
IN PVOID Ctx
|
|||
|
);
|
|||
|
|
|||
|
typedef struct _BROWSER_GET_MASTER_ANNOUNCEMENT_CONTEXT {
|
|||
|
PDOMAIN_INFO DomainInfo;
|
|||
|
HANDLE EventHandle;
|
|||
|
NET_API_STATUS NetStatus;
|
|||
|
} BROWSER_GET_MASTER_ANNOUNCEMENT_CONTEXT, *PBROWSER_GET_MASTER_ANNOUNCEMENT_CONTEXT;
|
|||
|
|
|||
|
NET_API_STATUS
|
|||
|
PostGetMasterAnnouncement (
|
|||
|
PNETWORK Network
|
|||
|
)
|
|||
|
/*++
|
|||
|
|
|||
|
Routine Description:
|
|||
|
|
|||
|
Ensure the GetMasterAnnouncement request is posted for a particular network.
|
|||
|
|
|||
|
Arguments:
|
|||
|
|
|||
|
None.
|
|||
|
|
|||
|
Return Value:
|
|||
|
|
|||
|
Status - The status of the operation.
|
|||
|
|
|||
|
--*/
|
|||
|
{
|
|||
|
NET_API_STATUS NetStatus = NERR_Success;
|
|||
|
|
|||
|
#ifdef ENABLE_PSEUDO_BROWSER
|
|||
|
if ( BrInfo.PseudoServerLevel == BROWSER_PSEUDO ) {
|
|||
|
// No master announcement handling for a phase out server
|
|||
|
return NERR_Success;
|
|||
|
}
|
|||
|
#endif
|
|||
|
|
|||
|
if (!LOCK_NETWORK(Network)) {
|
|||
|
return NERR_InternalError;
|
|||
|
}
|
|||
|
|
|||
|
if ( (Network->Flags & NETWORK_PDC) != 0 &&
|
|||
|
(Network->Flags & NETWORK_WANNISH) != 0 ) {
|
|||
|
|
|||
|
if (!(Network->Flags & NETWORK_GET_MASTER_ANNOUNCE_POSTED)) {
|
|||
|
|
|||
|
BrPrint(( BR_MASTER,
|
|||
|
"%ws: %ws: Doing PostGetMasterAnnouncement\n",
|
|||
|
Network->DomainInfo->DomUnicodeDomainName,
|
|||
|
Network->NetworkName.Buffer));
|
|||
|
|
|||
|
NetStatus = BrIssueAsyncBrowserIoControl(Network,
|
|||
|
IOCTL_LMDR_WAIT_FOR_MASTER_ANNOUNCE,
|
|||
|
GetMasterAnnouncementCompletion,
|
|||
|
NULL
|
|||
|
);
|
|||
|
|
|||
|
if ( NetStatus == NERR_Success ) {
|
|||
|
Network->Flags |= NETWORK_GET_MASTER_ANNOUNCE_POSTED;
|
|||
|
}
|
|||
|
} else {
|
|||
|
BrPrint(( BR_MASTER,
|
|||
|
"%ws: %ws: PostGetMasterAnnouncement already posted.\n",
|
|||
|
Network->DomainInfo->DomUnicodeDomainName,
|
|||
|
Network->NetworkName.Buffer));
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
UNLOCK_NETWORK(Network);
|
|||
|
return NetStatus;
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
VOID
|
|||
|
GetMasterAnnouncementCompletion (
|
|||
|
IN PVOID Ctx
|
|||
|
)
|
|||
|
/*++
|
|||
|
|
|||
|
Routine Description:
|
|||
|
|
|||
|
This function is the completion routine for a master announcement. It is
|
|||
|
called whenever a master announcement is received for a particular network.
|
|||
|
|
|||
|
Arguments:
|
|||
|
|
|||
|
Ctx - Context block for request.
|
|||
|
|
|||
|
Return Value:
|
|||
|
|
|||
|
None.
|
|||
|
|
|||
|
--*/
|
|||
|
|
|||
|
|
|||
|
{
|
|||
|
PVOID ServerList = NULL;
|
|||
|
ULONG EntriesRead;
|
|||
|
ULONG TotalEntries;
|
|||
|
NET_API_STATUS Status = NERR_Success;
|
|||
|
PBROWSERASYNCCONTEXT Context = Ctx;
|
|||
|
PLMDR_REQUEST_PACKET MasterAnnouncement = Context->RequestPacket;
|
|||
|
PNETWORK Network = Context->Network;
|
|||
|
LPTSTR RemoteMasterName = NULL;
|
|||
|
BOOLEAN NetLocked = FALSE;
|
|||
|
BOOLEAN NetReferenced = FALSE;
|
|||
|
|
|||
|
|
|||
|
try {
|
|||
|
//
|
|||
|
// Ensure the network wasn't deleted from under us.
|
|||
|
//
|
|||
|
if ( BrReferenceNetwork( Network ) == NULL ) {
|
|||
|
try_return(NOTHING);
|
|||
|
}
|
|||
|
NetReferenced = TRUE;
|
|||
|
|
|||
|
if (!LOCK_NETWORK(Network)){
|
|||
|
try_return(NOTHING);
|
|||
|
}
|
|||
|
NetLocked = TRUE;
|
|||
|
|
|||
|
Network->Flags &= ~NETWORK_GET_MASTER_ANNOUNCE_POSTED;
|
|||
|
|
|||
|
//
|
|||
|
// The request failed for some reason - just return immediately.
|
|||
|
//
|
|||
|
|
|||
|
if (!NT_SUCCESS(Context->IoStatusBlock.Status)) {
|
|||
|
try_return(NOTHING);
|
|||
|
}
|
|||
|
|
|||
|
Status = PostGetMasterAnnouncement(Network);
|
|||
|
|
|||
|
if (Status != NERR_Success) {
|
|||
|
BrPrint(( BR_CRITICAL,
|
|||
|
"%ws: %ws: Unable to re-issue GetMasterAnnouncement request: %lx\n",
|
|||
|
Network->DomainInfo->DomUnicodeDomainName,
|
|||
|
Network->NetworkName.Buffer,
|
|||
|
Status));
|
|||
|
|
|||
|
try_return(NOTHING);
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
RemoteMasterName = MIDL_user_allocate(MasterAnnouncement->Parameters.WaitForMasterAnnouncement.MasterNameLength+3*sizeof(TCHAR));
|
|||
|
|
|||
|
if (RemoteMasterName == NULL) {
|
|||
|
try_return(NOTHING);
|
|||
|
}
|
|||
|
|
|||
|
RemoteMasterName[0] = TEXT('\\');
|
|||
|
RemoteMasterName[1] = TEXT('\\');
|
|||
|
|
|||
|
STRNCPY(&RemoteMasterName[2],
|
|||
|
MasterAnnouncement->Parameters.WaitForMasterAnnouncement.Name,
|
|||
|
MasterAnnouncement->Parameters.WaitForMasterAnnouncement.MasterNameLength/sizeof(TCHAR));
|
|||
|
|
|||
|
RemoteMasterName[(MasterAnnouncement->Parameters.WaitForMasterAnnouncement.MasterNameLength/sizeof(TCHAR))+2] = UNICODE_NULL;
|
|||
|
|
|||
|
BrPrint(( BR_MASTER,
|
|||
|
"%ws: %ws: GetMasterAnnouncement: Got a master browser announcement from %ws\n",
|
|||
|
Network->DomainInfo->DomUnicodeDomainName,
|
|||
|
Network->NetworkName.Buffer,
|
|||
|
RemoteMasterName));
|
|||
|
|
|||
|
UNLOCK_NETWORK(Network);
|
|||
|
|
|||
|
NetLocked = FALSE;
|
|||
|
|
|||
|
//
|
|||
|
// Remote the api and pull the browse list from the remote server.
|
|||
|
//
|
|||
|
|
|||
|
Status = RxNetServerEnum(RemoteMasterName,
|
|||
|
Network->NetworkName.Buffer,
|
|||
|
101,
|
|||
|
(LPBYTE *)&ServerList,
|
|||
|
0xffffffff,
|
|||
|
&EntriesRead,
|
|||
|
&TotalEntries,
|
|||
|
SV_TYPE_LOCAL_LIST_ONLY,
|
|||
|
NULL,
|
|||
|
NULL
|
|||
|
);
|
|||
|
|
|||
|
if ((Status == NERR_Success) || (Status == ERROR_MORE_DATA)) {
|
|||
|
|
|||
|
if (!LOCK_NETWORK(Network)) {
|
|||
|
try_return(NOTHING);
|
|||
|
}
|
|||
|
|
|||
|
NetLocked = TRUE;
|
|||
|
|
|||
|
Status = MergeServerList(&Network->BrowseTable,
|
|||
|
101,
|
|||
|
ServerList,
|
|||
|
EntriesRead,
|
|||
|
TotalEntries
|
|||
|
);
|
|||
|
|
|||
|
UNLOCK_NETWORK(Network);
|
|||
|
|
|||
|
NetLocked = FALSE;
|
|||
|
|
|||
|
(void) NetApiBufferFree( ServerList );
|
|||
|
ServerList = NULL;
|
|||
|
|
|||
|
} else {
|
|||
|
|
|||
|
BrPrint(( BR_MASTER,
|
|||
|
"%ws: %ws: GetMasterAnnouncement: Cannot get server list from %ws (%ld)\n",
|
|||
|
Network->DomainInfo->DomUnicodeDomainName,
|
|||
|
Network->NetworkName.Buffer,
|
|||
|
RemoteMasterName,
|
|||
|
Status ));
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// Remote the api and pull the browse list from the remote server.
|
|||
|
//
|
|||
|
|
|||
|
Status = RxNetServerEnum(RemoteMasterName,
|
|||
|
Network->NetworkName.Buffer,
|
|||
|
101,
|
|||
|
(LPBYTE *)&ServerList,
|
|||
|
0xffffffff,
|
|||
|
&EntriesRead,
|
|||
|
&TotalEntries,
|
|||
|
SV_TYPE_LOCAL_LIST_ONLY | SV_TYPE_DOMAIN_ENUM,
|
|||
|
NULL,
|
|||
|
NULL
|
|||
|
);
|
|||
|
|
|||
|
if ((Status == NERR_Success) || (Status == ERROR_MORE_DATA)) {
|
|||
|
|
|||
|
if (!LOCK_NETWORK(Network)) {
|
|||
|
try_return(NOTHING);
|
|||
|
}
|
|||
|
|
|||
|
NetLocked = TRUE;
|
|||
|
|
|||
|
Status = MergeServerList(&Network->DomainList,
|
|||
|
101,
|
|||
|
ServerList,
|
|||
|
EntriesRead,
|
|||
|
TotalEntries
|
|||
|
);
|
|||
|
|
|||
|
} else {
|
|||
|
|
|||
|
BrPrint(( BR_MASTER,
|
|||
|
"%ws: %ws: GetMasterAnnouncement: Cannot get domain list from %ws (%ld)\n",
|
|||
|
Network->DomainInfo->DomUnicodeDomainName,
|
|||
|
Network->NetworkName.Buffer,
|
|||
|
RemoteMasterName,
|
|||
|
Status ));
|
|||
|
}
|
|||
|
|
|||
|
try_exit:NOTHING;
|
|||
|
} finally {
|
|||
|
|
|||
|
if (NetLocked) {
|
|||
|
UNLOCK_NETWORK(Network);
|
|||
|
}
|
|||
|
|
|||
|
if ( NetReferenced ) {
|
|||
|
BrDereferenceNetwork( Network );
|
|||
|
}
|
|||
|
|
|||
|
if (RemoteMasterName != NULL) {
|
|||
|
MIDL_user_free(RemoteMasterName);
|
|||
|
}
|
|||
|
|
|||
|
MIDL_user_free(Context);
|
|||
|
|
|||
|
if ( ServerList != NULL ) {
|
|||
|
(void) NetApiBufferFree( ServerList );
|
|||
|
}
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
return;
|
|||
|
|
|||
|
}
|