diff options
Diffstat (limited to 'private/oleutest/act/server/server.cxx')
-rw-r--r-- | private/oleutest/act/server/server.cxx | 1033 |
1 files changed, 1033 insertions, 0 deletions
diff --git a/private/oleutest/act/server/server.cxx b/private/oleutest/act/server/server.cxx new file mode 100644 index 000000000..7b400bc7d --- /dev/null +++ b/private/oleutest/act/server/server.cxx @@ -0,0 +1,1033 @@ +/* + * 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"); + +TCHAR * UserName = TEXT("redmond\\oleuser"); +TCHAR * Password = TEXT("stocksplit"); +TCHAR * ServiceName = TEXT("ActTestService"); +TCHAR * ServiceDisplayName = TEXT("ActTestService"); +BOOL fStartedAsService = FALSE; +HANDLE hStopServiceEvent; +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 + { + hr = CoInitialize(NULL); + } + + 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 + { + // only do message loop if not a service + while (GetMessage(&msg, NULL, 0, 0)) + { + TranslateMessage(&msg); + DispatchMessage(&msg); + } + } + + 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 + { + PostQuitMessage(0); + } +} |