mirror of https://github.com/lianthony/NT4.0
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.
200 lines
3.9 KiB
200 lines
3.9 KiB
/*++
|
|
|
|
Microsoft Windows NT RPC Name Service
|
|
Copyright (c) 1995 Microsoft Corporation
|
|
|
|
Module Name:
|
|
|
|
respond.cxx
|
|
|
|
Abstract:
|
|
|
|
This file contains the code for responding to broadcasts from
|
|
name service clients looking for a locator service. This includes
|
|
|
|
1. implementations of two member functions of class Locator
|
|
|
|
2. a listener thread
|
|
|
|
Author:
|
|
|
|
Satish Thatte (SatishT) 08/21/95 Created all the code below except where
|
|
otherwise indicated.
|
|
|
|
--*/
|
|
|
|
#include <api.hxx>
|
|
#include <objects.hxx>
|
|
#include <var.hxx>
|
|
#include <locquery.h>
|
|
|
|
|
|
|
|
|
|
void
|
|
Locator::respondToLocatorSeeker(
|
|
IN QUERYLOCATOR Query
|
|
)
|
|
{
|
|
|
|
// first see if we should reply at all
|
|
|
|
// ignore messages to self. A request on a group mailslot
|
|
// will be delivered to the local slot too.
|
|
|
|
STRING_T szRequester; // name without whacks
|
|
|
|
if (hasWhacksInMachineName(Query.RequesterName))
|
|
szRequester = Query.RequesterName+2;
|
|
else szRequester = Query.RequesterName;
|
|
|
|
|
|
if (IsSelf(szRequester)) return;
|
|
|
|
// OK, now see if the request fits our status
|
|
|
|
switch (Query.MessageType) {
|
|
|
|
case QUERY_MASTER_LOCATOR:
|
|
if (!IsInMasterRole()) return;
|
|
else break;
|
|
|
|
case QUERY_BOUND_LOCATOR:
|
|
case QUERY_ANY_LOCATOR:
|
|
break;
|
|
|
|
case QUERY_DC_LOCATOR:
|
|
if (!(IsInDomain() && (IsInMasterRole() || IsInBackupRole())))
|
|
return;
|
|
else break;
|
|
|
|
default:
|
|
DBGOUT(BROADCAST, "Bogus Query MsgType=" << Query.MessageType << "\n\n");
|
|
return;
|
|
};
|
|
|
|
// OK, looks like we are going to reply
|
|
|
|
QUERYLOCATORREPLY Reply;
|
|
|
|
// fill in our name and other items
|
|
|
|
wcscpy(Reply.SenderName,TEXT("\\\\"));
|
|
wcscpy(Reply.SenderName+2,*myRpcLocator->getComputerName());
|
|
|
|
Reply.Uptime = CurrentTime() - StartTime;
|
|
|
|
if (IsInMasterRole())
|
|
Reply.Hint = REPLY_MASTER_LOCATOR;
|
|
|
|
else if (IsInDomain() && IsInBackupRole())
|
|
Reply.Hint = REPLY_DC_LOCATOR;
|
|
|
|
else Reply.Hint = REPLY_OTHER_LOCATOR;
|
|
|
|
// create the return Mailslot
|
|
|
|
STRING_T sz = catenate(TEXT("\\\\"),szRequester);
|
|
WRITE_MAIL_SLOT MSReply(sz, RESPONDERMSLOT_C);
|
|
delete [] sz;
|
|
|
|
// and write the reply
|
|
|
|
MSReply.Write((char *) &Reply, sizeof(Reply));
|
|
|
|
}
|
|
|
|
|
|
void
|
|
Locator::TryBroadcastingForMasterLocator(
|
|
)
|
|
{
|
|
QUERYLOCATOR Query;
|
|
QUERYLOCATORREPLY QueryReply;
|
|
|
|
if (!hMasterFinderSlot) {
|
|
return;
|
|
}
|
|
|
|
Query.SenderOsType = OS_NTWKGRP;
|
|
Query.MessageType = QUERY_MASTER_LOCATOR;
|
|
|
|
STRING_T myName = catenate(TEXT("\\\\"),*myRpcLocator->getComputerName());
|
|
wcscpy(Query.RequesterName,myName);
|
|
delete [] myName;
|
|
|
|
csMasterBroadcastGuard.Enter();
|
|
|
|
__try {
|
|
|
|
WRITE_MAIL_SLOT BSResponder(NULL,RESPONDERMSLOT_S);
|
|
|
|
BSResponder.Write((char *) &Query, sizeof(Query));
|
|
|
|
ULONG waitCur = INITIAL_MAILSLOT_READ_WAIT; // current wait time for replies
|
|
|
|
long cbRead = 0;
|
|
|
|
while (cbRead = hMasterFinderSlot->Read((char *) &QueryReply,
|
|
sizeof(QueryReply),
|
|
waitCur
|
|
)
|
|
)
|
|
{
|
|
if (
|
|
(QueryReply.Hint == REPLY_MASTER_LOCATOR) ||
|
|
(QueryReply.Hint == REPLY_DC_LOCATOR)
|
|
)
|
|
{
|
|
addMaster(QueryReply.SenderName + 2);
|
|
}
|
|
|
|
// halve the wait period everytime you get a response from the net
|
|
|
|
waitCur >>= 1;
|
|
}
|
|
}
|
|
|
|
__finally {
|
|
csMasterBroadcastGuard.Leave();
|
|
}
|
|
}
|
|
|
|
|
|
void
|
|
ResponderProcess(void*)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This thread creates a mailslot and listens for requests for locators,
|
|
responding if appropriate.
|
|
|
|
--*/
|
|
{
|
|
QUERYLOCATOR LocatorQuery;
|
|
|
|
DWORD dwMailSize;
|
|
|
|
// create a server (s) mailslot
|
|
|
|
READ_MAIL_SLOT hMailslotForQueries(RESPONDERMSLOT_S, sizeof(QUERYLOCATOR));
|
|
|
|
while (1) {
|
|
|
|
dwMailSize = hMailslotForQueries.Read(
|
|
(char *) &LocatorQuery,
|
|
sizeof(QUERYLOCATOR),
|
|
MAILSLOT_WAIT_FOREVER
|
|
);
|
|
|
|
if (dwMailSize != sizeof(QUERYLOCATOR))
|
|
continue; // strange query, ignore it
|
|
|
|
DBGOUT(BROADCAST, LocatorQuery.RequesterName << " sent query for locator" << "\n\n");
|
|
|
|
myRpcLocator->respondToLocatorSeeker(LocatorQuery);
|
|
}
|
|
|
|
}
|
|
|