|
@@ -16,115 +16,108 @@ SERVICE_STATUS_HANDLE gSvcStatusHandle;
|
|
|
|
|
|
|
|
VOID WINAPI ServiceCtrlHandler(DWORD dwCtrl)
|
|
VOID WINAPI ServiceCtrlHandler(DWORD dwCtrl)
|
|
|
{
|
|
{
|
|
|
- // Handle the requested control code.
|
|
|
|
|
|
|
+ // Handle the requested control code.
|
|
|
|
|
|
|
|
- switch(dwCtrl)
|
|
|
|
|
|
|
+ switch (dwCtrl)
|
|
|
{
|
|
{
|
|
|
- case SERVICE_CONTROL_STOP:
|
|
|
|
|
- case SERVICE_CONTROL_SHUTDOWN:
|
|
|
|
|
|
|
+ case SERVICE_CONTROL_STOP:
|
|
|
|
|
+ case SERVICE_CONTROL_SHUTDOWN:
|
|
|
|
|
|
|
|
- ServiceShutdown = TRUE;
|
|
|
|
|
- ReportServiceStatus(SERVICE_STOP_PENDING, NO_ERROR, 0);
|
|
|
|
|
|
|
+ ServiceShutdown = TRUE;
|
|
|
|
|
+ ReportServiceStatus(SERVICE_STOP_PENDING, NO_ERROR, 0);
|
|
|
|
|
|
|
|
- // Remove PID file and free ressources
|
|
|
|
|
- cleanup();
|
|
|
|
|
-# ifdef USE_MSRPC
|
|
|
|
|
- ReportServiceStatus(SERVICE_STOPPED, NO_ERROR, 0);
|
|
|
|
|
-# endif // !USE_MSRPC
|
|
|
|
|
- return;
|
|
|
|
|
|
|
+ // Remove PID file and free ressources
|
|
|
|
|
+ cleanup();
|
|
|
|
|
+# if __CYGWIN__ || defined(USE_MSRPC)
|
|
|
|
|
+ ReportServiceStatus(SERVICE_STOPPED, NO_ERROR, 0);
|
|
|
|
|
+# endif // __CYGWIN__
|
|
|
|
|
|
|
|
- default:
|
|
|
|
|
- break;
|
|
|
|
|
|
|
+ default:
|
|
|
|
|
+ break;
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
static VOID WINAPI ServiceMain(const int argc_unused, CARGV argv_unused)
|
|
static VOID WINAPI ServiceMain(const int argc_unused, CARGV argv_unused)
|
|
|
{
|
|
{
|
|
|
- // Register the handler function for the service
|
|
|
|
|
-
|
|
|
|
|
- gSvcStatusHandle = RegisterServiceCtrlHandler(
|
|
|
|
|
- NT_SERVICE_NAME,
|
|
|
|
|
- ServiceCtrlHandler
|
|
|
|
|
- );
|
|
|
|
|
|
|
+ // Register the handler function for the service
|
|
|
|
|
|
|
|
- if(!gSvcStatusHandle)
|
|
|
|
|
- {
|
|
|
|
|
- //ServiceReportEvent(RegisterServiceCtrlHandler);
|
|
|
|
|
- return;
|
|
|
|
|
- }
|
|
|
|
|
|
|
+ if (!((gSvcStatusHandle = RegisterServiceCtrlHandler(NT_SERVICE_NAME, ServiceCtrlHandler))))
|
|
|
|
|
+ {
|
|
|
|
|
+ return;
|
|
|
|
|
+ }
|
|
|
|
|
|
|
|
- // These SERVICE_STATUS members remain as set here
|
|
|
|
|
|
|
+ // These SERVICE_STATUS members remain as set here
|
|
|
|
|
|
|
|
- gSvcStatus.dwServiceType = SERVICE_WIN32_OWN_PROCESS;
|
|
|
|
|
- gSvcStatus.dwServiceSpecificExitCode = 0;
|
|
|
|
|
|
|
+ gSvcStatus.dwServiceType = SERVICE_WIN32_OWN_PROCESS;
|
|
|
|
|
+ gSvcStatus.dwServiceSpecificExitCode = 0;
|
|
|
|
|
|
|
|
- // Run the actual program
|
|
|
|
|
- ReportServiceStatus(SERVICE_STOPPED, newmain(), 3000);
|
|
|
|
|
|
|
+ // Run the actual program
|
|
|
|
|
+ ReportServiceStatus(SERVICE_STOPPED, newmain(), 3000);
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
SERVICE_TABLE_ENTRY NTServiceDispatchTable[] = {
|
|
SERVICE_TABLE_ENTRY NTServiceDispatchTable[] = {
|
|
|
- {
|
|
|
|
|
- (LPSTR)NT_SERVICE_NAME,
|
|
|
|
|
- (LPSERVICE_MAIN_FUNCTION) ServiceMain
|
|
|
|
|
- },
|
|
|
|
|
- {
|
|
|
|
|
- NULL,
|
|
|
|
|
- NULL
|
|
|
|
|
- }
|
|
|
|
|
|
|
+ {
|
|
|
|
|
+ (LPSTR)NT_SERVICE_NAME,
|
|
|
|
|
+ (LPSERVICE_MAIN_FUNCTION)ServiceMain
|
|
|
|
|
+ },
|
|
|
|
|
+ {
|
|
|
|
|
+ NULL,
|
|
|
|
|
+ NULL
|
|
|
|
|
+ }
|
|
|
};
|
|
};
|
|
|
|
|
|
|
|
VOID ReportServiceStatus(const DWORD dwCurrentState, const DWORD dwWin32ExitCode, const DWORD dwWaitHint)
|
|
VOID ReportServiceStatus(const DWORD dwCurrentState, const DWORD dwWin32ExitCode, const DWORD dwWaitHint)
|
|
|
{
|
|
{
|
|
|
- static DWORD dwCheckPoint = 1;
|
|
|
|
|
|
|
+ static DWORD dwCheckPoint = 1;
|
|
|
|
|
|
|
|
- // Fill in the SERVICE_STATUS structure.
|
|
|
|
|
|
|
+ // Fill in the SERVICE_STATUS structure.
|
|
|
|
|
|
|
|
- gSvcStatus.dwCurrentState = dwCurrentState;
|
|
|
|
|
- gSvcStatus.dwWin32ExitCode = dwWin32ExitCode;
|
|
|
|
|
- gSvcStatus.dwWaitHint = dwWaitHint;
|
|
|
|
|
|
|
+ gSvcStatus.dwCurrentState = dwCurrentState;
|
|
|
|
|
+ gSvcStatus.dwWin32ExitCode = dwWin32ExitCode;
|
|
|
|
|
+ gSvcStatus.dwWaitHint = dwWaitHint;
|
|
|
|
|
|
|
|
- if (dwCurrentState == SERVICE_START_PENDING)
|
|
|
|
|
- gSvcStatus.dwControlsAccepted = 0;
|
|
|
|
|
- else
|
|
|
|
|
- gSvcStatus.dwControlsAccepted = SERVICE_ACCEPT_STOP;
|
|
|
|
|
|
|
+ if (dwCurrentState == SERVICE_START_PENDING)
|
|
|
|
|
+ gSvcStatus.dwControlsAccepted = 0;
|
|
|
|
|
+ else
|
|
|
|
|
+ gSvcStatus.dwControlsAccepted = SERVICE_ACCEPT_STOP;
|
|
|
|
|
|
|
|
- if ( (dwCurrentState == SERVICE_RUNNING) ||
|
|
|
|
|
- (dwCurrentState == SERVICE_STOPPED) )
|
|
|
|
|
- gSvcStatus.dwCheckPoint = 0;
|
|
|
|
|
- else
|
|
|
|
|
- gSvcStatus.dwCheckPoint = dwCheckPoint++;
|
|
|
|
|
|
|
+ if ((dwCurrentState == SERVICE_RUNNING) ||
|
|
|
|
|
+ (dwCurrentState == SERVICE_STOPPED))
|
|
|
|
|
+ gSvcStatus.dwCheckPoint = 0;
|
|
|
|
|
+ else
|
|
|
|
|
+ gSvcStatus.dwCheckPoint = dwCheckPoint++;
|
|
|
|
|
|
|
|
- // Report the status of the service to the SCM.
|
|
|
|
|
- SetServiceStatus(gSvcStatusHandle, &gSvcStatus);
|
|
|
|
|
|
|
+ // Report the status of the service to the SCM.
|
|
|
|
|
+ SetServiceStatus(gSvcStatusHandle, &gSvcStatus);
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
/*VOID ServiceReportEvent(char *szFunction)
|
|
/*VOID ServiceReportEvent(char *szFunction)
|
|
|
{
|
|
{
|
|
|
- HANDLE hEventSource;
|
|
|
|
|
- const char *eventStrings[2];
|
|
|
|
|
- TCHAR Buffer[80];
|
|
|
|
|
-
|
|
|
|
|
- hEventSource = RegisterEventSource(NULL, NT_SERVICE_NAME);
|
|
|
|
|
-
|
|
|
|
|
- if (hEventSource)
|
|
|
|
|
- {
|
|
|
|
|
- snprintf(Buffer, 80, "%s failed with %d", szFunction, GetLastError());
|
|
|
|
|
-
|
|
|
|
|
- eventStrings[0] = NT_SERVICE_NAME;
|
|
|
|
|
- eventStrings[1] = Buffer;
|
|
|
|
|
-
|
|
|
|
|
- ReportEvent(hEventSource, // event log handle
|
|
|
|
|
- EVENTLOG_ERROR_TYPE, // event type
|
|
|
|
|
- 0, // event category
|
|
|
|
|
- 00, // event identifier
|
|
|
|
|
- NULL, // no security identifier
|
|
|
|
|
- 2, // size of lpszStrings array
|
|
|
|
|
- 0, // no binary data
|
|
|
|
|
- eventStrings, // array of strings
|
|
|
|
|
- NULL); // no binary data
|
|
|
|
|
-
|
|
|
|
|
- DeregisterEventSource(hEventSource);
|
|
|
|
|
- }
|
|
|
|
|
|
|
+ HANDLE hEventSource;
|
|
|
|
|
+ const char *eventStrings[2];
|
|
|
|
|
+ TCHAR Buffer[80];
|
|
|
|
|
+
|
|
|
|
|
+ hEventSource = RegisterEventSource(NULL, NT_SERVICE_NAME);
|
|
|
|
|
+
|
|
|
|
|
+ if (hEventSource)
|
|
|
|
|
+ {
|
|
|
|
|
+ snprintf(Buffer, 80, "%s failed with %d", szFunction, GetLastError());
|
|
|
|
|
+
|
|
|
|
|
+ eventStrings[0] = NT_SERVICE_NAME;
|
|
|
|
|
+ eventStrings[1] = Buffer;
|
|
|
|
|
+
|
|
|
|
|
+ ReportEvent(hEventSource, // event log handle
|
|
|
|
|
+ EVENTLOG_ERROR_TYPE, // event type
|
|
|
|
|
+ 0, // event category
|
|
|
|
|
+ 00, // event identifier
|
|
|
|
|
+ NULL, // no security identifier
|
|
|
|
|
+ 2, // size of lpszStrings array
|
|
|
|
|
+ 0, // no binary data
|
|
|
|
|
+ eventStrings, // array of strings
|
|
|
|
|
+ NULL); // no binary data
|
|
|
|
|
+
|
|
|
|
|
+ DeregisterEventSource(hEventSource);
|
|
|
|
|
+ }
|
|
|
}*/
|
|
}*/
|
|
|
|
|
|
|
|
//Returns 0=Error, 1=Success, 2=Doesn't exist
|
|
//Returns 0=Error, 1=Success, 2=Doesn't exist
|
|
@@ -146,12 +139,12 @@ static uint_fast8_t OpenAndRemoveService(DWORD *dwPreviousState, SC_HANDLE *schS
|
|
|
closeManager = TRUE;
|
|
closeManager = TRUE;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- *schSCManager = OpenSCManager(
|
|
|
|
|
- NULL, // local computer
|
|
|
|
|
- NULL, // ServicesActive database
|
|
|
|
|
- SC_MANAGER_ALL_ACCESS); // full access rights
|
|
|
|
|
|
|
+ *schSCManager = OpenSCManager(
|
|
|
|
|
+ NULL, // local computer
|
|
|
|
|
+ NULL, // ServicesActive database
|
|
|
|
|
+ SC_MANAGER_ALL_ACCESS); // full access rights
|
|
|
|
|
|
|
|
- if (!*schSCManager) return 0;
|
|
|
|
|
|
|
+ if (!*schSCManager) return 0;
|
|
|
|
|
|
|
|
if (!((installedService = OpenService(*schSCManager, NT_SERVICE_NAME, SERVICE_ALL_ACCESS))))
|
|
if (!((installedService = OpenService(*schSCManager, NT_SERVICE_NAME, SERVICE_ALL_ACCESS))))
|
|
|
{
|
|
{
|
|
@@ -182,86 +175,86 @@ static uint_fast8_t OpenAndRemoveService(DWORD *dwPreviousState, SC_HANDLE *schS
|
|
|
|
|
|
|
|
static VOID ServiceInstaller(const char *restrict ServiceUser, const char *const ServicePassword)
|
|
static VOID ServiceInstaller(const char *restrict ServiceUser, const char *const ServicePassword)
|
|
|
{
|
|
{
|
|
|
- SC_HANDLE schSCManager;
|
|
|
|
|
- SC_HANDLE schService;
|
|
|
|
|
- char szPath[MAX_PATH] = "\"";
|
|
|
|
|
-
|
|
|
|
|
- if (!GetModuleFileName(NULL, szPath + sizeof(char), MAX_PATH - 1))
|
|
|
|
|
- {
|
|
|
|
|
- errorout("Cannot install service (%d)\n", (uint32_t)GetLastError());
|
|
|
|
|
- return;
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- strcat(szPath,"\"");
|
|
|
|
|
-
|
|
|
|
|
- int i;
|
|
|
|
|
- for (i = 1; i < global_argc; i ++)
|
|
|
|
|
- {
|
|
|
|
|
- // Strip unneccessary parameters, especially the password
|
|
|
|
|
- if (!strcmp(global_argv[i], "-s")) continue;
|
|
|
|
|
-
|
|
|
|
|
- if (!strcmp(global_argv[i], "-W") ||
|
|
|
|
|
- !strcmp(global_argv[i], "-U"))
|
|
|
|
|
- {
|
|
|
|
|
- i++;
|
|
|
|
|
- continue;
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- strcat(szPath, " ");
|
|
|
|
|
-
|
|
|
|
|
- if (strchr(global_argv[i], ' '))
|
|
|
|
|
- {
|
|
|
|
|
- strcat(szPath, "\"");
|
|
|
|
|
- strcat(szPath, global_argv[i]);
|
|
|
|
|
- strcat(szPath, "\"");
|
|
|
|
|
- }
|
|
|
|
|
- else
|
|
|
|
|
- strcat(szPath, global_argv[i]);
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- // Get a handle to the SCM database.
|
|
|
|
|
|
|
+ SC_HANDLE schSCManager;
|
|
|
|
|
+ SC_HANDLE schService;
|
|
|
|
|
+ char szPath[MAX_PATH] = "\"";
|
|
|
|
|
+
|
|
|
|
|
+ if (!GetModuleFileName(NULL, szPath + sizeof(char), MAX_PATH - 1))
|
|
|
|
|
+ {
|
|
|
|
|
+ errorout("Cannot install service (%d)\n", (uint32_t)GetLastError());
|
|
|
|
|
+ return;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ strcat(szPath, "\"");
|
|
|
|
|
+
|
|
|
|
|
+ int i;
|
|
|
|
|
+ for (i = 1; i < global_argc; i++)
|
|
|
|
|
+ {
|
|
|
|
|
+ // Strip unneccessary parameters, especially the password
|
|
|
|
|
+ if (!strcmp(global_argv[i], "-s")) continue;
|
|
|
|
|
+
|
|
|
|
|
+ if (!strcmp(global_argv[i], "-W") ||
|
|
|
|
|
+ !strcmp(global_argv[i], "-U"))
|
|
|
|
|
+ {
|
|
|
|
|
+ i++;
|
|
|
|
|
+ continue;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ strcat(szPath, " ");
|
|
|
|
|
+
|
|
|
|
|
+ if (strchr(global_argv[i], ' '))
|
|
|
|
|
+ {
|
|
|
|
|
+ strcat(szPath, "\"");
|
|
|
|
|
+ strcat(szPath, global_argv[i]);
|
|
|
|
|
+ strcat(szPath, "\"");
|
|
|
|
|
+ }
|
|
|
|
|
+ else
|
|
|
|
|
+ strcat(szPath, global_argv[i]);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // Get a handle to the SCM database.
|
|
|
|
|
|
|
|
SERVICE_STATUS status;
|
|
SERVICE_STATUS status;
|
|
|
DWORD dwPreviousState;
|
|
DWORD dwPreviousState;
|
|
|
|
|
|
|
|
- if (!OpenAndRemoveService(&dwPreviousState, &schSCManager))
|
|
|
|
|
- {
|
|
|
|
|
- errorout("Service removal failed (%d)\n", (uint32_t)GetLastError());
|
|
|
|
|
- return;
|
|
|
|
|
- }
|
|
|
|
|
|
|
+ if (!OpenAndRemoveService(&dwPreviousState, &schSCManager))
|
|
|
|
|
+ {
|
|
|
|
|
+ errorout("Service removal failed (%d)\n", (uint32_t)GetLastError());
|
|
|
|
|
+ return;
|
|
|
|
|
+ }
|
|
|
|
|
|
|
|
char *tempUser = NULL;
|
|
char *tempUser = NULL;
|
|
|
|
|
|
|
|
if (ServiceUser)
|
|
if (ServiceUser)
|
|
|
- {
|
|
|
|
|
- // Shortcuts for some well known users
|
|
|
|
|
- if (!strcasecmp(ServiceUser, "/l")) ServiceUser="NT AUTHORITY\\LocalService";
|
|
|
|
|
- if (!strcasecmp(ServiceUser, "/n")) ServiceUser="NT AUTHORITY\\NetworkService";
|
|
|
|
|
-
|
|
|
|
|
- // Allow Local Users without .\ , e.g. "johndoe" instead of ".\johndoe"
|
|
|
|
|
- if (!strchr(ServiceUser, '\\'))
|
|
|
|
|
- {
|
|
|
|
|
- tempUser = (char*)vlmcsd_malloc(strlen(ServiceUser) + 3);
|
|
|
|
|
- strcpy(tempUser, ".\\");
|
|
|
|
|
- strcat(tempUser, ServiceUser);
|
|
|
|
|
- ServiceUser = tempUser;
|
|
|
|
|
- }
|
|
|
|
|
- }
|
|
|
|
|
|
|
+ {
|
|
|
|
|
+ // Shortcuts for some well known users
|
|
|
|
|
+ if (!strcasecmp(ServiceUser, "/l")) ServiceUser = "NT AUTHORITY\\LocalService";
|
|
|
|
|
+ if (!strcasecmp(ServiceUser, "/n")) ServiceUser = "NT AUTHORITY\\NetworkService";
|
|
|
|
|
+
|
|
|
|
|
+ // Allow Local Users without .\ , e.g. "johndoe" instead of ".\johndoe"
|
|
|
|
|
+ if (!strchr(ServiceUser, '\\'))
|
|
|
|
|
+ {
|
|
|
|
|
+ tempUser = (char*)vlmcsd_malloc(strlen(ServiceUser) + 3);
|
|
|
|
|
+ strcpy(tempUser, ".\\");
|
|
|
|
|
+ strcat(tempUser, ServiceUser);
|
|
|
|
|
+ ServiceUser = tempUser;
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
|
|
|
schService = CreateService(
|
|
schService = CreateService(
|
|
|
- schSCManager, // SCM database
|
|
|
|
|
- NT_SERVICE_NAME, // name of service
|
|
|
|
|
- NT_SERVICE_DISPLAY_NAME, // service name to display
|
|
|
|
|
- SERVICE_ALL_ACCESS, // desired access
|
|
|
|
|
- SERVICE_WIN32_OWN_PROCESS, // service type
|
|
|
|
|
- SERVICE_AUTO_START, // start type
|
|
|
|
|
- SERVICE_ERROR_NORMAL, // error control type
|
|
|
|
|
- szPath, // path to service's binary
|
|
|
|
|
- NULL, // no load ordering group
|
|
|
|
|
- NULL, // no tag identifier
|
|
|
|
|
- "tcpip\0", // depends on TCP/IP
|
|
|
|
|
- ServiceUser, // LocalSystem account
|
|
|
|
|
- ServicePassword); // no password
|
|
|
|
|
|
|
+ schSCManager, // SCM database
|
|
|
|
|
+ NT_SERVICE_NAME, // name of service
|
|
|
|
|
+ NT_SERVICE_DISPLAY_NAME, // service name to display
|
|
|
|
|
+ SERVICE_ALL_ACCESS, // desired access
|
|
|
|
|
+ SERVICE_WIN32_OWN_PROCESS, // service type
|
|
|
|
|
+ SERVICE_AUTO_START, // start type
|
|
|
|
|
+ SERVICE_ERROR_NORMAL, // error control type
|
|
|
|
|
+ szPath, // path to service's binary
|
|
|
|
|
+ NULL, // no load ordering group
|
|
|
|
|
+ NULL, // no tag identifier
|
|
|
|
|
+ "tcpip\0", // depends on TCP/IP
|
|
|
|
|
+ ServiceUser, // LocalSystem account
|
|
|
|
|
+ ServicePassword); // no password
|
|
|
|
|
|
|
|
# if __clang__ && (__CYGWIN__ || __MINGW64__ )
|
|
# if __clang__ && (__CYGWIN__ || __MINGW64__ )
|
|
|
// Workaround for clang not understanding some GCC asm syntax used in <w32api/psdk_inc/intrin-impl.h>
|
|
// Workaround for clang not understanding some GCC asm syntax used in <w32api/psdk_inc/intrin-impl.h>
|
|
@@ -271,43 +264,43 @@ static VOID ServiceInstaller(const char *restrict ServiceUser, const char *const
|
|
|
# endif
|
|
# endif
|
|
|
if (tempUser) free(tempUser);
|
|
if (tempUser) free(tempUser);
|
|
|
|
|
|
|
|
- if (schService == NULL)
|
|
|
|
|
- {
|
|
|
|
|
- errorout("CreateService failed (%u)\n", (uint32_t)GetLastError());
|
|
|
|
|
- CloseServiceHandle(schSCManager);
|
|
|
|
|
- return;
|
|
|
|
|
- }
|
|
|
|
|
- else
|
|
|
|
|
- {
|
|
|
|
|
- errorout("Service installed successfully\n");
|
|
|
|
|
-
|
|
|
|
|
- if (dwPreviousState == SERVICE_RUNNING)
|
|
|
|
|
- {
|
|
|
|
|
- printf("Restarting " NT_SERVICE_NAME " service => ");
|
|
|
|
|
- status.dwCurrentState = SERVICE_STOPPED;
|
|
|
|
|
-
|
|
|
|
|
- if (StartService(schService, 0, NULL))
|
|
|
|
|
- {
|
|
|
|
|
- for (i = 0; i < 10; i++)
|
|
|
|
|
- {
|
|
|
|
|
- if (!QueryServiceStatus(schService, &status) || status.dwCurrentState != SERVICE_START_PENDING) break;
|
|
|
|
|
- Sleep(100);
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- if (status.dwCurrentState == SERVICE_RUNNING)
|
|
|
|
|
- printf("Success\n");
|
|
|
|
|
- else if (status.dwCurrentState == SERVICE_START_PENDING)
|
|
|
|
|
- printf("Not ready within a second\n");
|
|
|
|
|
- else
|
|
|
|
|
- errorout("Error\n");
|
|
|
|
|
- }
|
|
|
|
|
- else
|
|
|
|
|
- errorout("Error %u\n", (uint32_t)GetLastError());
|
|
|
|
|
- }
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- CloseServiceHandle(schService);
|
|
|
|
|
- CloseServiceHandle(schSCManager);
|
|
|
|
|
|
|
+ if (schService == NULL)
|
|
|
|
|
+ {
|
|
|
|
|
+ errorout("CreateService failed (%u)\n", (uint32_t)GetLastError());
|
|
|
|
|
+ CloseServiceHandle(schSCManager);
|
|
|
|
|
+ return;
|
|
|
|
|
+ }
|
|
|
|
|
+ else
|
|
|
|
|
+ {
|
|
|
|
|
+ errorout("Service installed successfully\n");
|
|
|
|
|
+
|
|
|
|
|
+ if (dwPreviousState == SERVICE_RUNNING)
|
|
|
|
|
+ {
|
|
|
|
|
+ printf("Restarting " NT_SERVICE_NAME " service => ");
|
|
|
|
|
+ status.dwCurrentState = SERVICE_STOPPED;
|
|
|
|
|
+
|
|
|
|
|
+ if (StartService(schService, 0, NULL))
|
|
|
|
|
+ {
|
|
|
|
|
+ for (i = 0; i < 10; i++)
|
|
|
|
|
+ {
|
|
|
|
|
+ if (!QueryServiceStatus(schService, &status) || status.dwCurrentState != SERVICE_START_PENDING) break;
|
|
|
|
|
+ Sleep(100);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ if (status.dwCurrentState == SERVICE_RUNNING)
|
|
|
|
|
+ printf("Success\n");
|
|
|
|
|
+ else if (status.dwCurrentState == SERVICE_START_PENDING)
|
|
|
|
|
+ printf("Not ready within a second\n");
|
|
|
|
|
+ else
|
|
|
|
|
+ errorout("Error\n");
|
|
|
|
|
+ }
|
|
|
|
|
+ else
|
|
|
|
|
+ errorout("Error %u\n", (uint32_t)GetLastError());
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ CloseServiceHandle(schService);
|
|
|
|
|
+ CloseServiceHandle(schSCManager);
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
int NtServiceInstallation(const int_fast8_t installService, const char *restrict ServiceUser, const char *const ServicePassword)
|
|
int NtServiceInstallation(const int_fast8_t installService, const char *restrict ServiceUser, const char *const ServicePassword)
|
|
@@ -322,7 +315,7 @@ int NtServiceInstallation(const int_fast8_t installService, const char *restrict
|
|
|
|
|
|
|
|
if (installService == 2) // Remove
|
|
if (installService == 2) // Remove
|
|
|
{
|
|
{
|
|
|
- switch(OpenAndRemoveService(NULL, NULL))
|
|
|
|
|
|
|
+ switch (OpenAndRemoveService(NULL, NULL))
|
|
|
{
|
|
{
|
|
|
case 0:
|
|
case 0:
|
|
|
errorout("Error removing service %s\n", NT_SERVICE_NAME);
|
|
errorout("Error removing service %s\n", NT_SERVICE_NAME);
|