summaryrefslogtreecommitdiffstats
path: root/private/oleutest/act/server/server.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'private/oleutest/act/server/server.cxx')
-rw-r--r--private/oleutest/act/server/server.cxx1033
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);
+ }
+}