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.
421 lines
9.1 KiB
421 lines
9.1 KiB
/*++
|
|
|
|
Microsoft Windows NT RPC Name Service
|
|
Copyright (c) 1995 Microsoft Corporation
|
|
|
|
Module Name:
|
|
|
|
locator.cxx
|
|
|
|
Abstract:
|
|
|
|
This file contains server initialization and other RPC control
|
|
functions. It also supplies all the necessities for running the
|
|
locator as a system service, including the main service thread
|
|
and service control functionality.
|
|
|
|
Author:
|
|
|
|
Satish R. Thatte -- 9/14/1995 Created all the code below except where
|
|
otherwise indicated.
|
|
|
|
--*/
|
|
|
|
typedef long NTSTATUS;
|
|
|
|
#include <windows.h>
|
|
#include <nsisvr.h>
|
|
#include <nsiclt.h>
|
|
#include <nsimgm.h>
|
|
#include <loctoloc.h>
|
|
|
|
#include <objects.hxx>
|
|
#include <api.hxx>
|
|
#include <switch.hxx>
|
|
#include <objbase.h>
|
|
|
|
ULONG StartTime; // time the locator started
|
|
|
|
SERVICE_STATUS ssServiceStatus;
|
|
SERVICE_STATUS_HANDLE sshServiceHandle;
|
|
|
|
Locator *myRpcLocator; // the primary state of the locator
|
|
CReadWriteSection rwEntryGuard; // single shared guard for all local entries
|
|
CReadWriteSection rwCacheEntryGuard; // single shared guard for all cached entries
|
|
CReadWriteSection rwFullEntryGuard; // single shared guard for all full entries
|
|
CPrivateCriticalSection csBindingBroadcastGuard;
|
|
CPrivateCriticalSection csMasterBroadcastGuard;
|
|
|
|
HANDLE hHeapHandle;
|
|
|
|
#if DBG
|
|
CDebugStream debugOut; // this carries no state
|
|
#endif
|
|
|
|
unsigned char ** ppszDomainName; // name of current domain
|
|
|
|
/* this is used by Steve's switch processing code */
|
|
|
|
int fService = TRUE; // running as a service
|
|
long waitOnRead = 3000L; // time to wait on reading reply back
|
|
int fNet = 1; // enable network functionality
|
|
DWORD maxCacheAge; // ignored for now -- look in class Locator
|
|
char * pszOtherDomain; // ASCII other domain to look.
|
|
char * pszDebugName = "locator.log"; // debug log file name
|
|
int debug = -1; // debug trace level
|
|
|
|
SwitchList aSwitchs = {
|
|
|
|
{"/debug:*", ProcessInt, &debug,},
|
|
{"/logfile:*", ProcessChar, &pszDebugName,},
|
|
{"/expirationage:*", ProcessLong, &maxCacheAge,},
|
|
{"/querytimeout:*", ProcessLong, &waitOnRead,},
|
|
{"/noservice", ProcessResetFlag, &fService,},
|
|
{"/nonet", ProcessResetFlag, &fNet,},
|
|
{"/otherdomain:*", ProcessChar, &pszOtherDomain,},
|
|
{0}
|
|
};
|
|
|
|
/* end of items for Steve's switch processing code */
|
|
|
|
|
|
|
|
void SetStatus();
|
|
|
|
void
|
|
init(
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
miscellaneous initialization code
|
|
|
|
--*/
|
|
|
|
{
|
|
}
|
|
|
|
void
|
|
StopLocator(
|
|
IN char * szReason,
|
|
IN long code
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Die a graceful death
|
|
|
|
Arguments:
|
|
|
|
szReason - Text message for death
|
|
|
|
code - option error code
|
|
|
|
--*/
|
|
{
|
|
|
|
ssServiceStatus.dwCurrentState = SERVICE_STOPPED;
|
|
|
|
if (code) {
|
|
ssServiceStatus.dwWin32ExitCode = ERROR_SERVICE_SPECIFIC_ERROR;
|
|
ssServiceStatus.dwServiceSpecificExitCode = code;
|
|
}
|
|
else ssServiceStatus.dwWin32ExitCode = GetLastError();
|
|
|
|
if (fService && sshServiceHandle)
|
|
SetStatus();
|
|
|
|
ExitProcess(code);
|
|
}
|
|
|
|
void
|
|
SetStatus(
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Set the lanman service status.
|
|
|
|
--*/
|
|
{
|
|
ASSERT(sshServiceHandle,"NT Service Handle Corrupted\n");
|
|
|
|
if (! SetServiceStatus( sshServiceHandle, &ssServiceStatus))
|
|
StopLocator("SetServiceStatus", 0);
|
|
}
|
|
|
|
|
|
void QueryProcess(void*);
|
|
void ResponderProcess(void*);
|
|
|
|
|
|
void
|
|
StartServer(
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Call the runtime to create the server for the locator, the runtime
|
|
will create it own threads to use to service calls.
|
|
|
|
Returns:
|
|
|
|
Never returns.
|
|
|
|
--*/
|
|
{
|
|
RPC_STATUS result;
|
|
|
|
SECURITY_DESCRIPTOR SecurityDescriptor;
|
|
|
|
init();
|
|
|
|
if (result = RpcServerRegisterIf(NsiS_ServerIfHandle, NULL, NULL))
|
|
StopLocator("RpcServerRegisterIf", result);
|
|
|
|
if (result = RpcServerRegisterIf(NsiC_ServerIfHandle, NULL, NULL))
|
|
StopLocator("RpcServerRegisterIf", result);
|
|
|
|
if (result = RpcServerRegisterIf(NsiM_ServerIfHandle, NULL, NULL))
|
|
StopLocator("RpcServerRegisterIf", result);
|
|
|
|
if (result = RpcServerRegisterIf(LocToLoc_ServerIfHandle, NULL, NULL))
|
|
StopLocator("RpcServerRegisterIf", result);
|
|
|
|
InitializeSecurityDescriptor(
|
|
&SecurityDescriptor,
|
|
SECURITY_DESCRIPTOR_REVISION
|
|
);
|
|
|
|
SetSecurityDescriptorDacl (
|
|
&SecurityDescriptor,
|
|
TRUE, // Dacl present
|
|
(PACL)NULL, // NULL Dacl
|
|
FALSE // Not defaulted
|
|
);
|
|
|
|
|
|
if (result = RpcServerUseProtseqEp(TEXT("ncacn_np"), // use named pipes for now
|
|
RPC_NS_MAX_CALLS,
|
|
TEXT("\\pipe\\locator"),
|
|
&SecurityDescriptor
|
|
))
|
|
{
|
|
StopLocator("RpcServerUseProtseqEp Pipe", result);
|
|
}
|
|
|
|
HANDLE pThreadHandle;
|
|
|
|
unsigned long ThreadID;
|
|
|
|
pThreadHandle = CreateThread(0, 0,
|
|
(LPTHREAD_START_ROUTINE) QueryProcess, NULL, 0, &ThreadID);
|
|
|
|
if (!pThreadHandle)
|
|
StopLocator("CreateThread ", 0);
|
|
|
|
pThreadHandle = CreateThread(0, 0,
|
|
(LPTHREAD_START_ROUTINE) ResponderProcess, NULL, 0, &ThreadID);
|
|
|
|
if (!pThreadHandle)
|
|
StopLocator("CreateThread ", 0);
|
|
|
|
if (result = RpcServerListen(
|
|
1, // min call threads
|
|
RPC_NS_MAX_THREADS, // max call threads
|
|
1 // don't wait yet
|
|
)
|
|
)
|
|
StopLocator("RpcServerListen", result);
|
|
}
|
|
|
|
|
|
|
|
void __stdcall
|
|
LocatorControl(
|
|
IN DWORD opCode // function that we are to carry out.
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This function responses the service control requests.
|
|
|
|
Arguments:
|
|
|
|
opCode - Function that we are to carry out.
|
|
|
|
--*/
|
|
{
|
|
RPC_STATUS status;
|
|
|
|
switch(opCode) {
|
|
|
|
case SERVICE_CONTROL_STOP:
|
|
|
|
// Announce that the service is shutting down
|
|
|
|
ssServiceStatus.dwCurrentState = SERVICE_STOP_PENDING;
|
|
ssServiceStatus.dwWaitHint = 3000;
|
|
status = RpcMgmtStopServerListening(0);
|
|
break;
|
|
|
|
|
|
case SERVICE_CONTROL_INTERROGATE:
|
|
|
|
// Do nothing; the status gets announced below
|
|
|
|
break ;
|
|
|
|
}
|
|
|
|
SetStatus();
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
LocatorServiceMain(
|
|
DWORD argc,
|
|
LPTSTR *argv
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This is main function for the locator service.
|
|
When we are started as a service, the service control creates a new
|
|
thread and calls this function.
|
|
|
|
Arguments:
|
|
|
|
argc - argument count
|
|
|
|
argv - vector of argument pointers
|
|
|
|
--*/
|
|
{
|
|
|
|
// Set up the service info structure to indicate the status.
|
|
|
|
ssServiceStatus.dwServiceType = SERVICE_WIN32;
|
|
ssServiceStatus.dwCurrentState = SERVICE_START_PENDING;
|
|
ssServiceStatus.dwControlsAccepted = SERVICE_ACCEPT_STOP |
|
|
SERVICE_ACCEPT_PAUSE_CONTINUE;
|
|
ssServiceStatus.dwWin32ExitCode = 0;
|
|
ssServiceStatus.dwCheckPoint = 0;
|
|
ssServiceStatus.dwWaitHint = 0;
|
|
|
|
#if DBG
|
|
CoInitialize(NULL);
|
|
#endif
|
|
|
|
// Set up control handler
|
|
|
|
if (! (sshServiceHandle = RegisterServiceCtrlHandler (
|
|
TEXT("locator"), LocatorControl)))
|
|
|
|
StopLocator("RegisterServiceCtrlHandler", 0);
|
|
|
|
// Start the RPC server
|
|
|
|
SetStatus();
|
|
StartServer();
|
|
|
|
ssServiceStatus.dwCurrentState = SERVICE_RUNNING;
|
|
SetStatus();
|
|
RpcMgmtWaitServerListen(); // OK, wait now
|
|
|
|
DBGOUT(-1, "Deleting myRpcLocator\n\n");
|
|
delete myRpcLocator;
|
|
|
|
DBGOUT(MEM2, CRemoteLookupHandle::ulHandleCount << " CRemoteLookupHandles Leaked\n\n");
|
|
|
|
DBGOUT(MEM2, CRemoteObjectInqHandle::ulHandleCount << " CRemoteObjectInqHandles Leaked\n\n");
|
|
|
|
DBGOUT(MEM1, CCompleteHandle<NSI_BINDING_VECTOR_T>::ulHandleCount
|
|
<< " Complete Binding Handles Leaked\n\n");
|
|
|
|
DBGOUT(MEM1, CCompleteHandle<GUID>::ulHandleCount
|
|
<< " Complete Object Handles Leaked\n\n");
|
|
|
|
|
|
DBGOUT(-1, "Calling CoUninitialize\n\n");
|
|
|
|
#if DBG
|
|
CoUninitialize();
|
|
#endif
|
|
|
|
ssServiceStatus.dwCurrentState = SERVICE_STOPPED;
|
|
SetStatus();
|
|
}
|
|
|
|
|
|
int __cdecl
|
|
main (
|
|
IN int cArgs,
|
|
IN char* *pszArgs
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Entry point for the locator server, Initialize data
|
|
structures and start the various threads of excution.
|
|
|
|
Arguments:
|
|
|
|
cArgs - number of argument.
|
|
|
|
pszArgs - vector of arguments.
|
|
|
|
--*/
|
|
{
|
|
int Status = 0;
|
|
|
|
myRpcLocator = new Locator; // initialize the state
|
|
|
|
hHeapHandle = GetProcessHeap();
|
|
|
|
static SERVICE_TABLE_ENTRY ServiceEntry [] = {
|
|
{TEXT("locator"), (LPSERVICE_MAIN_FUNCTION) LocatorServiceMain}, // only entry item
|
|
{NULL,NULL} // end of table
|
|
};
|
|
|
|
StartTime = CurrentTime();
|
|
|
|
char * badArg = ProcessArgs(aSwitchs, ++pszArgs);
|
|
|
|
// Bail out on bad arguments.
|
|
|
|
if (badArg) {
|
|
char Buffer[200];
|
|
fService = FALSE;
|
|
|
|
strcpy(Buffer,"Command Line Error: ");
|
|
strcat(Buffer,badArg);
|
|
|
|
StopLocator(Buffer, 0);
|
|
}
|
|
|
|
// Start the RPC service now if not running under the service controller
|
|
|
|
if (!fService) {
|
|
StartServer(); // this doesn't wait
|
|
RpcMgmtWaitServerListen(); // OK, wait now
|
|
}
|
|
|
|
// else call (give this thread to) the service controller
|
|
|
|
else StartServiceCtrlDispatcher(ServiceEntry);
|
|
|
|
return(0);
|
|
|
|
}
|
|
|