Source code of Windows XP (NT5)
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.
 
 
 
 
 
 

1058 lines
26 KiB

/*
* server.cxx
*/
#ifdef UNICODE
#define _UNICODE 1
#endif
#include "server.hxx"
#include "factory.hxx"
#include "tchar.h"
long ObjectCount = 0;
TCHAR * AtStorageFileName = TEXT("c:\\tmp\\atbits.dat");
#ifdef USERPCPERFDOMAIN
TCHAR * UserName = TEXT("rpcperf\\oleuser");
#else
TCHAR * UserName = TEXT("redmond\\oleuser");
#endif
TCHAR * Password = TEXT("TwoFor1");
TCHAR * ServiceName = TEXT("ActTestService");
TCHAR * ServiceDisplayName = TEXT("ActTestService");
BOOL fStartedAsService = FALSE;
HANDLE hStopServiceEvent;
#ifdef FREETHREADED
HANDLE hFreeThreadEvent;
#endif
SERVICE_STATUS SStatus;
SERVICE_STATUS_HANDLE hService;
BOOL InstallService(TCHAR * );
HKEY ghClsidRootKey = 0;
HKEY ghAppIDRootKey = 0;
DWORD RegHandleLocal;
DWORD RegHandleRemote;
DWORD RegHandleAtStorage;
DWORD RegHandlePreConfig;
DWORD RegHandleRunAsLoggedOn;
DWORD RegHandleService;
DWORD RegHandleServerOnly;
unsigned uClassIndex = 0;
//+---------------------------------------------------------------------------
//
// Function: main
//
// Synopsis: main entry point for SCM
//
// History: 1-18-96 stevebl Created
//
//----------------------------------------------------------------------------
void _cdecl RealMain( int argc, char ** argv )
{
HRESULT hr;
MSG msg;
if ( (argc > 1) &&
((strcmp(argv[1],"-?") == 0) || (strcmp(argv[1],"/?") == 0)) )
PrintUsageAndExit();
if ( (argc > 1) && (strcmp(argv[1],"-r") == 0) )
{
DebuggerType eDebug = same_debugger;
int n;
n = 2;
if ( n < argc )
{
if (strcmp(argv[n],"-d") == 0)
eDebug = windbg_debugger;
else if (strcmp(argv[n],"-n") == 0 )
eDebug = ntsd_debugger;
else if (strcmp(argv[n],"-x") == 0 )
eDebug = clear_debugger;
}
if ( hr = InitializeRegistry( eDebug ) )
printf("InitializeRegistry failed with %08x\n", hr);
else
printf("Registry updated successfully.\n");
return;
}
// Started manually. Don't go away.
if ( (argc == 1) && ! fStartedAsService )
ObjectCount = 1;
if ( ! fStartedAsService )
{
if ( (argc >= 3 && strcmp(argv[2], "-Embedding") == 0) )
uClassIndex = argv[1][0] - '0';
else
uClassIndex = 0;
}
if ( fStartedAsService )
{
uClassIndex = 8;
#ifdef NT351
hr = E_FAIL;
#else
hr = CoInitializeEx(NULL, COINIT_MULTITHREADED);
#endif
}
else
{
#ifdef FREETHREADED
hFreeThreadEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
hr = CoInitializeEx(NULL,COINIT_MULTITHREADED);
#else
hr = CoInitialize(NULL);
#endif
}
if ( FAILED(hr) )
{
printf( "Server: CoInitialize failed(%x)\n", hr );
return;
}
if (0 == uClassIndex || 2 == uClassIndex)
{
hr = CoRegisterClassObject( CLSID_ActLocal,
(IUnknown *)new FactoryLocal(),
CLSCTX_LOCAL_SERVER,
REGCLS_MULTIPLEUSE,
&RegHandleLocal );
if ( FAILED(hr) )
{
printf("Server: CoRegisterClassObject failed %x\n", hr);
CoUninitialize();
return;
}
}
if (0 == uClassIndex || 3 == uClassIndex)
{
hr = CoRegisterClassObject( CLSID_ActRemote,
(IUnknown *)new FactoryRemote(),
CLSCTX_LOCAL_SERVER,
REGCLS_MULTIPLEUSE,
&RegHandleRemote );
if ( FAILED(hr) )
{
printf("Server: CoRegisterClassObject failed %x\n", hr);
if (0 == uClassIndex)
{
CoRevokeClassObject( RegHandleLocal );
}
CoUninitialize();
return;
}
}
if (0 == uClassIndex || 4 == uClassIndex)
{
hr = CoRegisterClassObject( CLSID_ActAtStorage,
(IUnknown *)new FactoryAtStorage(),
CLSCTX_LOCAL_SERVER,
REGCLS_MULTIPLEUSE,
&RegHandleAtStorage );
if ( FAILED(hr) )
{
printf("Server: CoRegisterClassObject failed %x\n", hr);
if (0 == uClassIndex)
{
CoRevokeClassObject( RegHandleLocal );
CoRevokeClassObject( RegHandleRemote );
}
CoUninitialize();
return;
}
}
if (0 == uClassIndex || 6 == uClassIndex)
{
hr = CoRegisterClassObject( CLSID_ActPreConfig,
(IUnknown *)new FactoryAtStorage(),
CLSCTX_LOCAL_SERVER,
REGCLS_MULTIPLEUSE,
&RegHandlePreConfig );
if ( FAILED(hr) )
{
printf("Server: CoRegisterClassObject failed %x\n", hr);
if (0 == uClassIndex)
{
CoRevokeClassObject( RegHandleLocal );
CoRevokeClassObject( RegHandleRemote );
CoRevokeClassObject( RegHandleAtStorage );
}
CoUninitialize();
return;
}
}
if (0 == uClassIndex || 7 == uClassIndex)
{
hr = CoRegisterClassObject( CLSID_ActRunAsLoggedOn,
(IUnknown *)new FactoryAtStorage(),
CLSCTX_LOCAL_SERVER,
REGCLS_MULTIPLEUSE,
&RegHandleRunAsLoggedOn );
if ( FAILED(hr) )
{
printf("Server: CoRegisterClassObject failed %x\n", hr);
if (0 == uClassIndex)
{
CoRevokeClassObject( RegHandleLocal );
CoRevokeClassObject( RegHandleRemote );
CoRevokeClassObject( RegHandleAtStorage );
CoRevokeClassObject( RegHandlePreConfig );
}
CoUninitialize();
return;
}
}
if (0 == uClassIndex || 9 == uClassIndex)
{
hr = CoRegisterClassObject( CLSID_ActServerOnly,
(IUnknown *)new FactoryAtStorage(),
CLSCTX_LOCAL_SERVER,
REGCLS_MULTIPLEUSE,
&RegHandleServerOnly );
if ( FAILED(hr) )
{
printf("Server: CoRegisterClassObject failed %x\n", hr);
if (0 == uClassIndex)
{
CoRevokeClassObject( RegHandleLocal );
CoRevokeClassObject( RegHandleRemote );
CoRevokeClassObject( RegHandleAtStorage );
CoRevokeClassObject( RegHandlePreConfig );
CoRevokeClassObject( RegHandleRunAsLoggedOn );
}
CoUninitialize();
return;
}
}
if (fStartedAsService)
{
hr = CoRegisterClassObject( CLSID_ActService,
(IUnknown *)new FactoryAtStorage(),
CLSCTX_LOCAL_SERVER,
REGCLS_MULTIPLEUSE,
&RegHandleService );
if ( FAILED(hr) )
{
CoUninitialize();
return;
}
WaitForSingleObject(hStopServiceEvent, INFINITE);
}
else
{
#ifdef FREETHREADED
WaitForSingleObject(hFreeThreadEvent, INFINITE);
//
// Make sure the thread who signaled the event executes for a while
// before we exit.
//
Sleep(100);
#else
// Only do message loop if apartment threaded non-service.
while (GetMessage(&msg, NULL, 0, 0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
#endif
}
CoUninitialize();
return;
}
int gargc;
char * gargv[100];
BOOL UpdateStatus(DWORD dwState)
{
if (SERVICE_RUNNING == SStatus.dwCurrentState &&
SERVICE_START_PENDING == dwState)
{
return(TRUE);
}
SStatus.dwCurrentState = dwState;
if (SERVICE_START_PENDING == dwState ||
SERVICE_STOP_PENDING == dwState)
{
SStatus.dwCheckPoint++;
SStatus.dwWaitHint = 1;
}
else
{
SStatus.dwCheckPoint = 0;
SStatus.dwWaitHint = 0;
}
return(SetServiceStatus(hService, &SStatus));
}
DWORD StartMyMain(void * pArg)
{
// reconstruct the command line args and call the real main
RealMain(gargc, gargv);
UpdateStatus(SERVICE_STOPPED);
return(0);
}
void Handler(DWORD fdwControl)
{
switch (fdwControl)
{
case SERVICE_CONTROL_STOP:
UpdateStatus(SERVICE_STOP_PENDING);
SetEvent(hStopServiceEvent);
break;
case SERVICE_CONTROL_INTERROGATE:
UpdateStatus(SERVICE_RUNNING);
break;
default:
break;
}
}
//+---------------------------------------------------------------------------
//
// Function: ServiceMain
//
// Synopsis: main entry point for service
//
// History: 1-18-96 stevebl Created
//
//----------------------------------------------------------------------------
void ServiceMain(DWORD argc, LPTSTR * argv)
{
fStartedAsService = TRUE;
// register the service handler
hService = RegisterServiceCtrlHandler(ServiceName, Handler);
if (!hService)
return;
SStatus.dwServiceType = SERVICE_WIN32_OWN_PROCESS |
SERVICE_INTERACTIVE_PROCESS,
SStatus.dwControlsAccepted = SERVICE_CONTROL_STOP |
SERVICE_CONTROL_INTERROGATE;
SStatus.dwWin32ExitCode = NO_ERROR;
SStatus.dwServiceSpecificExitCode = 0;
SStatus.dwCheckPoint = 0;
SStatus.dwWaitHint = 0;
if (!UpdateStatus(SERVICE_START_PENDING))
return;
// create an event to signal when the service is to stop
hStopServiceEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
if (!hStopServiceEvent)
{
return;
}
UpdateStatus(SERVICE_RUNNING);
StartMyMain( NULL );
}
void _cdecl main( int argc, char ** argv)
{
if (argc > 1 && strcmp(argv[1], "8") == 0)
{
gargc = argc;
// save the command line arguments
gargc = (int) argc;
if (gargc > 100)
{
gargc = 100;
}
for (int k = 1; k <= gargc; k++)
{
gargv[k-1] = (char *) malloc(strlen(argv[k-1]) + 1);
strcpy(gargv[k-1], argv[k-1]);
}
// Start as a service
SERVICE_TABLE_ENTRY ServiceStart[2];
ServiceStart[0].lpServiceName = ServiceName;
ServiceStart[0].lpServiceProc = ServiceMain;
ServiceStart[1].lpServiceName = NULL;
ServiceStart[1].lpServiceProc = NULL;
if (!StartServiceCtrlDispatcher (ServiceStart))
{
ExitProcess(GetLastError());
}
ExitProcess(0);
}
else
{
// start as a regular app
RealMain(argc, argv);
}
}
long InitializeRegistry( DebuggerType eDebugServer )
{
long RegStatus;
ulong Disposition;
HKEY hActKey;
HKEY hDebugKey;
HANDLE hFile;
TCHAR Path[256];
TCHAR * pwszServerExe;
TCHAR * pwszDebuggerName;
DWORD DebugFlags;
if ( ! GetModuleFileName( 0, Path, sizeof(Path) ) )
return ERROR_BAD_PATHNAME;
hFile = CreateFile( AtStorageFileName,
GENERIC_WRITE,
0,
NULL,
CREATE_ALWAYS,
0,
0 );
if ( hFile == INVALID_HANDLE_VALUE )
{
printf("Couldn't create file %ws\n", AtStorageFileName );
return GetLastError();
}
CloseHandle( hFile );
RegStatus = RegOpenKeyEx( HKEY_CLASSES_ROOT,
TEXT("CLSID"),
0,
KEY_ALL_ACCESS,
&ghClsidRootKey );
if ( RegStatus != ERROR_SUCCESS )
return RegStatus;
RegStatus = RegOpenKeyEx( HKEY_CLASSES_ROOT,
TEXT("APPID"),
0,
KEY_ALL_ACCESS,
&ghAppIDRootKey );
if ( RegStatus != ERROR_SUCCESS )
return RegStatus;
DeleteClsidKey( ClsidGoober32String );
DeleteClsidKey( ClsidActLocalString );
DeleteClsidKey( ClsidActRemoteString );
DeleteClsidKey( ClsidActAtStorageString );
DeleteClsidKey( ClsidActInprocString );
DeleteClsidKey( ClsidActPreConfigString );
DeleteClsidKey( ClsidActRunAsLoggedOnString );
DeleteClsidKey( ClsidActServiceString );
DeleteClsidKey( ClsidActServerOnlyString );
//
// Local CLSID entries.
//
_tcscat(Path, TEXT(" 2"));
RegStatus = SetClsidRegKeyAndStringValue(
ClsidActLocalString,
TEXT("LocalServer32"),
Path,
NULL,
NULL );
if ( RegStatus != ERROR_SUCCESS )
return RegStatus;
RegStatus = SetAppIDSecurity( ClsidActLocalString );
if ( RegStatus != ERROR_SUCCESS )
return RegStatus;
//
// Remote CLSID entries.
//
Path[_tcslen(Path)-1] = TEXT('3');
RegStatus = SetClsidRegKeyAndStringValue(
ClsidActRemoteString,
TEXT("LocalServer32"),
Path,
NULL,
NULL );
if ( RegStatus != ERROR_SUCCESS )
return RegStatus;
RegStatus = SetAppIDSecurity( ClsidActRemoteString );
if ( RegStatus != ERROR_SUCCESS )
return RegStatus;
//
// AtStorage CLSID entries.
//
Path[_tcslen(Path)-1] = TEXT('4');
RegStatus = SetClsidRegKeyAndStringValue(
ClsidActAtStorageString,
TEXT("LocalServer32"),
Path,
NULL,
NULL );
if ( RegStatus != ERROR_SUCCESS )
return RegStatus;
RegStatus = SetAppIDSecurity( ClsidActAtStorageString );
if ( RegStatus != ERROR_SUCCESS )
return RegStatus;
//
// RunAs CLSID entries.'
//
Path[_tcslen(Path)-1] = TEXT('6');
RegStatus = SetClsidRegKeyAndStringValue(
ClsidActPreConfigString,
TEXT("LocalServer32"),
Path,
NULL,
NULL );
if ( RegStatus != ERROR_SUCCESS )
return RegStatus;
RegStatus = SetAppIDRegKeyAndNamedValue(
ClsidActPreConfigString,
TEXT("RunAs"),
UserName,
NULL );
if ( RegStatus != ERROR_SUCCESS )
return RegStatus;
RegStatus = SetAppIDSecurity( ClsidActPreConfigString );
if ( RegStatus != ERROR_SUCCESS )
return RegStatus;
if (!SetPassword(ClsidActPreConfigString, Password))
return(FALSE);
if (!AddBatchPrivilege( UserName ) )
return(FALSE);
//
// RunAs logged on user CLSID entries.
//
Path[_tcslen(Path)-1] = TEXT('7');
RegStatus = SetClsidRegKeyAndStringValue(
ClsidActRunAsLoggedOnString,
TEXT("LocalServer32"),
Path,
NULL,
NULL );
if ( RegStatus != ERROR_SUCCESS )
return RegStatus;
RegStatus = SetAppIDRegKeyAndNamedValue(
ClsidActRunAsLoggedOnString,
TEXT("RunAs"),
TEXT("Interactive User"),
NULL );
if ( RegStatus != ERROR_SUCCESS )
return RegStatus;
RegStatus = SetAppIDSecurity( ClsidActRunAsLoggedOnString );
if ( RegStatus != ERROR_SUCCESS )
return RegStatus;
//
// Service CLSID entries.
//
RegStatus = SetAppIDRegKeyAndNamedValue(
ClsidActServiceString,
TEXT("LocalService"),
ServiceName,
NULL );
if ( RegStatus != ERROR_SUCCESS )
return RegStatus;
RegStatus = SetAppIDSecurity( ClsidActServiceString );
if ( RegStatus != ERROR_SUCCESS )
return RegStatus;
// Get the services key
HKEY hServices;
RegStatus = RegOpenKeyEx( HKEY_LOCAL_MACHINE,
TEXT("SYSTEM\\CurrentControlSet\\Services"),
0,
KEY_READ | KEY_QUERY_VALUE | KEY_ENUMERATE_SUB_KEYS,
&hServices );
if ( RegStatus != ERROR_SUCCESS )
return RegStatus;
Path[_tcslen(Path)-1] = TEXT('8');
if (!InstallService(Path))
return TRUE;
//
// Server only CLSID entry.
//
Path[_tcslen(Path)-1] = TEXT('9');
RegStatus = SetClsidRegKeyAndStringValue(
ClsidActServerOnlyString,
TEXT("LocalServer32"),
Path,
NULL,
NULL );
if ( RegStatus != ERROR_SUCCESS )
return RegStatus;
RegStatus = SetAppIDSecurity( ClsidActServerOnlyString );
if ( RegStatus != ERROR_SUCCESS )
return RegStatus;
//
// Add entries to launch server in debugger.
//
if ( eDebugServer == same_debugger )
return ERROR_SUCCESS;
Path[_tcslen(Path)-2] = 0;
pwszServerExe = Path + _tcslen(Path);
while ( (pwszServerExe > Path) && (pwszServerExe[-1] != TEXT('\\')) )
pwszServerExe--;
RegStatus = RegOpenKeyEx(
HKEY_LOCAL_MACHINE,
TEXT("SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion"),
0,
KEY_ALL_ACCESS,
&hDebugKey );
if ( RegStatus != ERROR_SUCCESS )
return RegStatus;
RegStatus = RegCreateKeyEx(
hDebugKey,
TEXT("Image File Execution Options"),
0,
TEXT("REG_SZ"),
REG_OPTION_NON_VOLATILE,
KEY_ALL_ACCESS,
NULL,
&hDebugKey,
&Disposition );
if ( RegStatus != ERROR_SUCCESS )
return RegStatus;
if ( eDebugServer == clear_debugger )
{
RegDeleteKey( hDebugKey, pwszServerExe );
return ERROR_SUCCESS;
}
RegStatus = RegCreateKeyEx(
hDebugKey,
pwszServerExe,
0,
TEXT("REG_SZ"),
REG_OPTION_NON_VOLATILE,
KEY_ALL_ACCESS,
NULL,
&hDebugKey,
&Disposition );
if ( RegStatus != ERROR_SUCCESS )
return RegStatus;
if ( eDebugServer == ntsd_debugger )
{
pwszDebuggerName = TEXT("ntsd.exe -d");
}
else
{
pwszDebuggerName = TEXT("windbg.exe");
}
DebugFlags = 0x10f0;
RegStatus = RegSetValueEx(
hDebugKey,
TEXT("Debugger"),
0,
REG_SZ,
(const BYTE *)pwszDebuggerName,
(_tcslen(pwszDebuggerName) + 1) * sizeof(TCHAR) );
if ( RegStatus != ERROR_SUCCESS )
return RegStatus;
RegStatus = RegSetValueEx(
hDebugKey,
TEXT("GlobalFlag"),
0,
REG_DWORD,
(const BYTE *)&DebugFlags,
sizeof(DWORD) );
if ( RegStatus != ERROR_SUCCESS )
return RegStatus;
return ERROR_SUCCESS;
}
long SetClsidRegKeyAndStringValue(
TCHAR * pwszClsid,
TCHAR * pwszKey,
TCHAR * pwszValue,
HKEY * phClsidKey,
HKEY * phNewKey )
{
long RegStatus;
DWORD Disposition;
HKEY hClsidKey;
if ( phClsidKey )
*phClsidKey = 0;
if ( phNewKey )
*phNewKey = 0;
RegStatus = RegCreateKeyEx(
ghClsidRootKey,
pwszClsid,
0,
TEXT("REG_SZ"),
REG_OPTION_NON_VOLATILE,
KEY_ALL_ACCESS,
NULL,
&hClsidKey,
&Disposition );
if ( RegStatus != ERROR_SUCCESS )
return RegStatus;
if ( phClsidKey )
*phClsidKey = hClsidKey;
return SetRegKeyAndStringValue(
hClsidKey,
pwszKey,
pwszValue,
phNewKey );
}
long SetAppIDRegKeyAndNamedValue(
TCHAR * pwszAppID,
TCHAR * pwszKey,
TCHAR * pwszValue,
HKEY * phClsidKey )
{
long RegStatus;
DWORD Disposition;
HKEY hClsidKey;
if ( phClsidKey )
*phClsidKey = 0;
// first, make sure the clsid has appid={appid}
RegStatus = RegCreateKeyEx(
ghClsidRootKey,
pwszAppID,
0,
TEXT("REG_SZ"),
REG_OPTION_NON_VOLATILE,
KEY_ALL_ACCESS,
NULL,
&hClsidKey,
&Disposition );
if ( RegStatus != ERROR_SUCCESS )
return RegStatus;
RegStatus = SetNamedStringValue(
hClsidKey,
TEXT("AppID"),
pwszAppID );
if ( RegStatus != ERROR_SUCCESS )
return RegStatus;
RegStatus = RegCreateKeyEx(
ghAppIDRootKey,
pwszAppID,
0,
TEXT("REG_SZ"),
REG_OPTION_NON_VOLATILE,
KEY_ALL_ACCESS,
NULL,
&hClsidKey,
&Disposition );
if ( RegStatus != ERROR_SUCCESS )
return RegStatus;
if ( phClsidKey )
*phClsidKey = hClsidKey;
return SetNamedStringValue(
hClsidKey,
pwszKey,
pwszValue );
}
long SetNamedStringValue(
HKEY hKey,
TCHAR * pwszKey,
TCHAR * pwszValue )
{
long RegStatus;
DWORD Disposition;
RegStatus = RegSetValueEx(
hKey,
pwszKey,
0,
REG_SZ,
(const BYTE *)pwszValue,
(_tcslen(pwszValue) + 1) * sizeof(TCHAR) );
return RegStatus;
}
long SetRegKeyAndStringValue(
HKEY hKey,
TCHAR * pwszKey,
TCHAR * pwszValue,
HKEY * phNewKey )
{
long RegStatus;
DWORD Disposition;
HKEY hNewKey;
if ( phNewKey )
*phNewKey = 0;
RegStatus = RegCreateKeyEx(
hKey,
pwszKey,
0,
TEXT("REG_SZ"),
REG_OPTION_NON_VOLATILE,
KEY_ALL_ACCESS,
NULL,
&hNewKey,
&Disposition );
if ( RegStatus != ERROR_SUCCESS )
return RegStatus;
RegStatus = RegSetValueEx(
hNewKey,
TEXT(""),
0,
REG_SZ,
(const BYTE *)pwszValue,
(_tcslen(pwszValue) + 1) * sizeof(TCHAR) );
if ( phNewKey )
*phNewKey = hNewKey;
return RegStatus;
}
BOOL InstallService(TCHAR * Path)
{
#ifndef CHICO
SC_HANDLE hManager = OpenSCManager(
NULL,
NULL,
SC_MANAGER_ALL_ACCESS);
if (NULL == hManager)
{
printf("OpenSCManager returned %d\n",GetLastError());
return(FALSE);
}
SC_HANDLE hService = OpenService(
hManager,
ServiceName,
SERVICE_ALL_ACCESS);
if (NULL != hService)
{
if (!ChangeServiceConfig(
hService,
SERVICE_WIN32_OWN_PROCESS |
SERVICE_INTERACTIVE_PROCESS,
SERVICE_DEMAND_START,
SERVICE_ERROR_NORMAL,
Path,
NULL,
NULL,
NULL,
NULL,
NULL,
ServiceDisplayName
)
)
{
printf("ChangeService returned %d\n",GetLastError());
CloseServiceHandle(hService);
CloseServiceHandle(hManager);
return(FALSE);
}
return(TRUE);
}
hService = CreateService(
hManager,
ServiceName,
ServiceDisplayName,
SERVICE_ALL_ACCESS,
SERVICE_WIN32_OWN_PROCESS |
SERVICE_INTERACTIVE_PROCESS,
SERVICE_DEMAND_START,
SERVICE_ERROR_NORMAL,
Path,
NULL,
NULL,
NULL,
NULL,
NULL);
if (NULL == hService)
{
printf("CreateService returned %d\n",GetLastError());
CloseServiceHandle(hManager);
return(FALSE);
}
CloseServiceHandle(hService);
CloseServiceHandle(hManager);
#endif
return(TRUE);
}
void PrintUsageAndExit()
{
printf("Usage : actsrv [-r [-d | -n | -x]]\n");
printf("\t-r : Make necessary registry changes.\n");
printf("\t-d : Register server to start in windbg.\n");
printf("\t-n : Register server to start with ntsd -d.\n");
printf("\t-x : Register server and clear debugger.\n");
ExitProcess(0);
}
void ShutDown()
{
// The last object has been destroyed.
if (fStartedAsService)
{
CoRevokeClassObject( RegHandleService );
}
switch( uClassIndex )
{
case 0 :
CoRevokeClassObject( RegHandleLocal );
CoRevokeClassObject( RegHandleRemote );
CoRevokeClassObject( RegHandleAtStorage );
CoRevokeClassObject( RegHandlePreConfig );
CoRevokeClassObject( RegHandleRunAsLoggedOn );
CoRevokeClassObject( RegHandleServerOnly );
break;
case 2:
CoRevokeClassObject( RegHandleLocal );
break;
case 3:
CoRevokeClassObject( RegHandleRemote );
break;
case 4:
CoRevokeClassObject( RegHandleAtStorage );
break;
case 6:
CoRevokeClassObject( RegHandlePreConfig );
break;
case 7 :
CoRevokeClassObject( RegHandleRunAsLoggedOn );
break;
case 9 :
CoRevokeClassObject( RegHandleServerOnly );
break;
}
if (fStartedAsService)
{
SetEvent(hStopServiceEvent);
}
else
{
#ifdef FREETHREADED
SetEvent(hFreeThreadEvent);
#else
PostQuitMessage(0);
#endif
}
}