mirror of
https://github.com/reactos/reactos.git
synced 2024-07-06 12:45:16 +00:00
[SERVICES] Set default status to SERVICE_START_PENDING when starting a service.
[SYSSETUP] Wait until PlugPlay service is up. Bug #4142. [UMPNPMGR] Update the service control manager's status information. Patches by Dmitry Gorbachev. svn path=/trunk/; revision=45626
This commit is contained in:
parent
84f7b6a683
commit
69a020df26
|
@ -51,12 +51,11 @@
|
||||||
|
|
||||||
/* GLOBALS ******************************************************************/
|
/* GLOBALS ******************************************************************/
|
||||||
|
|
||||||
static VOID CALLBACK
|
static VOID CALLBACK ServiceMain(DWORD, LPWSTR *);
|
||||||
ServiceMain(DWORD argc, LPTSTR *argv);
|
static WCHAR ServiceName[] = L"PlugPlay";
|
||||||
|
static SERVICE_TABLE_ENTRYW ServiceTable[] =
|
||||||
static SERVICE_TABLE_ENTRY ServiceTable[2] =
|
|
||||||
{
|
{
|
||||||
{TEXT("PlugPlay"), ServiceMain},
|
{ServiceName, ServiceMain},
|
||||||
{NULL, NULL}
|
{NULL, NULL}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -2446,63 +2445,36 @@ PnpEventThread(LPVOID lpParameter)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static VOID CALLBACK
|
static DWORD WINAPI
|
||||||
ServiceMain(DWORD argc, LPTSTR *argv)
|
ServiceControlHandler(DWORD dwControl,
|
||||||
|
DWORD dwEventType,
|
||||||
|
LPVOID lpEventData,
|
||||||
|
LPVOID lpContext)
|
||||||
{
|
{
|
||||||
HANDLE hThread;
|
/* FIXME */
|
||||||
DWORD dwThreadId;
|
DPRINT1("ServiceControlHandler() called (control code %lu)\n", dwControl);
|
||||||
|
return ERROR_SUCCESS;
|
||||||
UNREFERENCED_PARAMETER(argc);
|
|
||||||
UNREFERENCED_PARAMETER(argv);
|
|
||||||
|
|
||||||
DPRINT("ServiceMain() called\n");
|
|
||||||
|
|
||||||
hThread = CreateThread(NULL,
|
|
||||||
0,
|
|
||||||
PnpEventThread,
|
|
||||||
NULL,
|
|
||||||
0,
|
|
||||||
&dwThreadId);
|
|
||||||
if (hThread != NULL)
|
|
||||||
CloseHandle(hThread);
|
|
||||||
|
|
||||||
hThread = CreateThread(NULL,
|
|
||||||
0,
|
|
||||||
RpcServerThread,
|
|
||||||
NULL,
|
|
||||||
0,
|
|
||||||
&dwThreadId);
|
|
||||||
if (hThread != NULL)
|
|
||||||
CloseHandle(hThread);
|
|
||||||
|
|
||||||
hThread = CreateThread(NULL,
|
|
||||||
0,
|
|
||||||
DeviceInstallThread,
|
|
||||||
NULL,
|
|
||||||
0,
|
|
||||||
&dwThreadId);
|
|
||||||
if (hThread != NULL)
|
|
||||||
CloseHandle(hThread);
|
|
||||||
|
|
||||||
DPRINT("ServiceMain() done\n");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int
|
static DWORD
|
||||||
wmain(int argc, WCHAR *argv[])
|
ServiceInit(VOID)
|
||||||
{
|
{
|
||||||
BOOLEAN OldValue;
|
HANDLE hThread;
|
||||||
|
DWORD dwThreadId;
|
||||||
DWORD dwError;
|
DWORD dwError;
|
||||||
|
BOOLEAN OldValue;
|
||||||
UNREFERENCED_PARAMETER(argc);
|
|
||||||
UNREFERENCED_PARAMETER(argv);
|
|
||||||
|
|
||||||
DPRINT("Umpnpmgr: main() started\n");
|
|
||||||
|
|
||||||
/* We need this privilege for using CreateProcessAsUserW */
|
/* We need this privilege for using CreateProcessAsUserW */
|
||||||
RtlAdjustPrivilege(SE_ASSIGNPRIMARYTOKEN_PRIVILEGE, TRUE, FALSE, &OldValue);
|
RtlAdjustPrivilege(SE_ASSIGNPRIMARYTOKEN_PRIVILEGE,
|
||||||
|
TRUE,
|
||||||
|
FALSE,
|
||||||
|
&OldValue);
|
||||||
|
|
||||||
hInstallEvent = CreateEvent(NULL, TRUE, SetupIsActive()/*FALSE*/, NULL);
|
hInstallEvent = CreateEvent(NULL,
|
||||||
|
TRUE,
|
||||||
|
SetupIsActive()/*FALSE*/,
|
||||||
|
NULL);
|
||||||
if (hInstallEvent == NULL)
|
if (hInstallEvent == NULL)
|
||||||
{
|
{
|
||||||
dwError = GetLastError();
|
dwError = GetLastError();
|
||||||
|
@ -2510,7 +2482,10 @@ wmain(int argc, WCHAR *argv[])
|
||||||
return dwError;
|
return dwError;
|
||||||
}
|
}
|
||||||
|
|
||||||
hDeviceInstallListNotEmpty = CreateEvent(NULL, FALSE, FALSE, NULL);
|
hDeviceInstallListNotEmpty = CreateEvent(NULL,
|
||||||
|
FALSE,
|
||||||
|
FALSE,
|
||||||
|
NULL);
|
||||||
if (hDeviceInstallListNotEmpty == NULL)
|
if (hDeviceInstallListNotEmpty == NULL)
|
||||||
{
|
{
|
||||||
dwError = GetLastError();
|
dwError = GetLastError();
|
||||||
|
@ -2557,11 +2532,110 @@ wmain(int argc, WCHAR *argv[])
|
||||||
return dwError;
|
return dwError;
|
||||||
}
|
}
|
||||||
|
|
||||||
StartServiceCtrlDispatcher(ServiceTable);
|
hThread = CreateThread(NULL,
|
||||||
|
0,
|
||||||
|
PnpEventThread,
|
||||||
|
NULL,
|
||||||
|
0,
|
||||||
|
&dwThreadId);
|
||||||
|
if (hThread == NULL)
|
||||||
|
{
|
||||||
|
return GetLastError();
|
||||||
|
}
|
||||||
|
CloseHandle(hThread);
|
||||||
|
|
||||||
DPRINT("Umpnpmgr: main() done\n");
|
hThread = CreateThread(NULL,
|
||||||
|
0,
|
||||||
|
RpcServerThread,
|
||||||
|
NULL,
|
||||||
|
0,
|
||||||
|
&dwThreadId);
|
||||||
|
if (hThread == NULL)
|
||||||
|
{
|
||||||
|
return GetLastError();
|
||||||
|
}
|
||||||
|
CloseHandle(hThread);
|
||||||
|
|
||||||
ExitThread(0);
|
hThread = CreateThread(NULL,
|
||||||
|
0,
|
||||||
|
DeviceInstallThread,
|
||||||
|
NULL,
|
||||||
|
0,
|
||||||
|
&dwThreadId);
|
||||||
|
if (hThread == NULL)
|
||||||
|
{
|
||||||
|
return GetLastError();
|
||||||
|
}
|
||||||
|
CloseHandle(hThread);
|
||||||
|
|
||||||
|
return ERROR_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static VOID CALLBACK
|
||||||
|
ServiceMain(DWORD argc,
|
||||||
|
LPWSTR *argv)
|
||||||
|
{
|
||||||
|
SERVICE_STATUS ServiceStatus;
|
||||||
|
SERVICE_STATUS_HANDLE ServiceStatusHandle;
|
||||||
|
DWORD dwError;
|
||||||
|
|
||||||
|
UNREFERENCED_PARAMETER(argc);
|
||||||
|
UNREFERENCED_PARAMETER(argv);
|
||||||
|
|
||||||
|
DPRINT("ServiceMain() called\n");
|
||||||
|
|
||||||
|
ServiceStatusHandle = RegisterServiceCtrlHandlerExW(ServiceName,
|
||||||
|
ServiceControlHandler,
|
||||||
|
NULL);
|
||||||
|
if (!ServiceStatusHandle)
|
||||||
|
{
|
||||||
|
dwError = GetLastError();
|
||||||
|
DPRINT1("RegisterServiceCtrlHandlerW() failed! (Error %lu)\n", dwError);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
ServiceStatus.dwServiceType = SERVICE_WIN32_OWN_PROCESS;
|
||||||
|
ServiceStatus.dwCurrentState = SERVICE_START_PENDING;
|
||||||
|
ServiceStatus.dwControlsAccepted = 0;
|
||||||
|
ServiceStatus.dwWin32ExitCode = NO_ERROR;
|
||||||
|
ServiceStatus.dwServiceSpecificExitCode = 0;
|
||||||
|
ServiceStatus.dwCheckPoint = 0;
|
||||||
|
ServiceStatus.dwWaitHint = 2000;
|
||||||
|
|
||||||
|
SetServiceStatus(ServiceStatusHandle,
|
||||||
|
&ServiceStatus);
|
||||||
|
|
||||||
|
dwError = ServiceInit();
|
||||||
|
if (dwError != ERROR_SUCCESS)
|
||||||
|
{
|
||||||
|
DPRINT1("Service stopped\n");
|
||||||
|
ServiceStatus.dwCurrentState = SERVICE_STOPPED;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ServiceStatus.dwCurrentState = SERVICE_RUNNING;
|
||||||
|
}
|
||||||
|
|
||||||
|
SetServiceStatus(ServiceStatusHandle,
|
||||||
|
&ServiceStatus);
|
||||||
|
|
||||||
|
DPRINT("ServiceMain() done\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int
|
||||||
|
wmain(int argc,
|
||||||
|
WCHAR *argv[])
|
||||||
|
{
|
||||||
|
UNREFERENCED_PARAMETER(argc);
|
||||||
|
UNREFERENCED_PARAMETER(argv);
|
||||||
|
|
||||||
|
DPRINT1("Umpnpmgr: main() started\n");
|
||||||
|
|
||||||
|
StartServiceCtrlDispatcherW(ServiceTable);
|
||||||
|
|
||||||
|
DPRINT1("Umpnpmgr: main() done\n");
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1054,7 +1054,7 @@ ScmStartService(PSERVICE Service, DWORD argc, LPWSTR *argv)
|
||||||
{
|
{
|
||||||
Group->ServicesRunning = TRUE;
|
Group->ServicesRunning = TRUE;
|
||||||
}
|
}
|
||||||
Service->Status.dwCurrentState = SERVICE_RUNNING;
|
Service->Status.dwCurrentState = SERVICE_START_PENDING;
|
||||||
}
|
}
|
||||||
#if 0
|
#if 0
|
||||||
else
|
else
|
||||||
|
|
|
@ -20,7 +20,7 @@
|
||||||
* COPYRIGHT: See COPYING in the top level directory
|
* COPYRIGHT: See COPYING in the top level directory
|
||||||
* PROJECT: ReactOS system libraries
|
* PROJECT: ReactOS system libraries
|
||||||
* PURPOSE: System setup
|
* PURPOSE: System setup
|
||||||
* FILE: lib/syssetup/install.c
|
* FILE: dll/win32/syssetup/install.c
|
||||||
* PROGRAMER: Eric Kohl
|
* PROGRAMER: Eric Kohl
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
@ -473,30 +473,100 @@ InstallSysSetupInfComponents(VOID)
|
||||||
static BOOL
|
static BOOL
|
||||||
EnableUserModePnpManager(VOID)
|
EnableUserModePnpManager(VOID)
|
||||||
{
|
{
|
||||||
|
SERVICE_STATUS_PROCESS ServiceStatus;
|
||||||
SC_HANDLE hSCManager = NULL;
|
SC_HANDLE hSCManager = NULL;
|
||||||
SC_HANDLE hService = NULL;
|
SC_HANDLE hService = NULL;
|
||||||
|
DWORD dwStartTickCount;
|
||||||
|
DWORD dwOldCheckPoint;
|
||||||
|
DWORD BytesNeeded = 0;
|
||||||
|
DWORD dwWaitTime;
|
||||||
|
DWORD dwMaxWait;
|
||||||
BOOL ret = FALSE;
|
BOOL ret = FALSE;
|
||||||
|
|
||||||
hSCManager = OpenSCManager(NULL, NULL, 0);
|
hSCManager = OpenSCManager(NULL, NULL, 0);
|
||||||
if (hSCManager == NULL)
|
if (hSCManager == NULL)
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
|
|
||||||
hService = OpenServiceW(hSCManager, L"PlugPlay", SERVICE_CHANGE_CONFIG | SERVICE_START);
|
hService = OpenServiceW(hSCManager,
|
||||||
|
L"PlugPlay",
|
||||||
|
SERVICE_CHANGE_CONFIG | SERVICE_START | SERVICE_QUERY_STATUS);
|
||||||
if (hService == NULL)
|
if (hService == NULL)
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
|
|
||||||
ret = ChangeServiceConfigW(
|
ret = ChangeServiceConfigW(hService,
|
||||||
hService,
|
SERVICE_NO_CHANGE,
|
||||||
SERVICE_NO_CHANGE, SERVICE_AUTO_START, SERVICE_NO_CHANGE,
|
SERVICE_AUTO_START,
|
||||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL);
|
SERVICE_NO_CHANGE,
|
||||||
|
NULL, NULL, NULL,
|
||||||
|
NULL, NULL, NULL, NULL);
|
||||||
if (!ret)
|
if (!ret)
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
|
|
||||||
ret = StartServiceW(hService, 0, NULL);
|
ret = StartServiceW(hService, 0, NULL);
|
||||||
|
if (!ret)
|
||||||
|
{
|
||||||
|
/* If the service is already running, just return TRUE */
|
||||||
|
ret = GetLastError() == ERROR_SERVICE_ALREADY_RUNNING;
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = QueryServiceStatusEx(hService,
|
||||||
|
SC_STATUS_PROCESS_INFO,
|
||||||
|
(LPBYTE)&ServiceStatus,
|
||||||
|
sizeof(SERVICE_STATUS_PROCESS),
|
||||||
|
&BytesNeeded);
|
||||||
if (!ret)
|
if (!ret)
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
|
|
||||||
ret = TRUE;
|
/* We don't want to wait for more than 30 seconds */
|
||||||
|
dwMaxWait = 30000;
|
||||||
|
dwStartTickCount = GetTickCount();
|
||||||
|
|
||||||
|
/* Loop until it's running */
|
||||||
|
while (ServiceStatus.dwCurrentState != SERVICE_RUNNING)
|
||||||
|
{
|
||||||
|
dwOldCheckPoint = ServiceStatus.dwCheckPoint;
|
||||||
|
dwWaitTime = ServiceStatus.dwWaitHint / 10;
|
||||||
|
|
||||||
|
/* Get the latest status info */
|
||||||
|
if (!QueryServiceStatusEx(hService,
|
||||||
|
SC_STATUS_PROCESS_INFO,
|
||||||
|
(LPBYTE)&ServiceStatus,
|
||||||
|
sizeof(SERVICE_STATUS_PROCESS),
|
||||||
|
&BytesNeeded))
|
||||||
|
{
|
||||||
|
/* Something went wrong... */
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Is the service making progress? */
|
||||||
|
if (ServiceStatus.dwCheckPoint > dwOldCheckPoint)
|
||||||
|
{
|
||||||
|
/* It is, get the latest tickcount to reset the max wait time */
|
||||||
|
dwStartTickCount = GetTickCount();
|
||||||
|
dwOldCheckPoint = ServiceStatus.dwCheckPoint;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* It's not, make sure we haven't exceeded our wait time */
|
||||||
|
if (GetTickCount() >= dwStartTickCount + dwMaxWait)
|
||||||
|
{
|
||||||
|
/* We have, give up */
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Adjust the wait hint times */
|
||||||
|
if (dwWaitTime < 200)
|
||||||
|
dwWaitTime = 200;
|
||||||
|
else if (dwWaitTime > 10000)
|
||||||
|
dwWaitTime = 10000;
|
||||||
|
|
||||||
|
/* Wait before trying again */
|
||||||
|
Sleep(dwWaitTime);
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = ServiceStatus.dwCurrentState == SERVICE_RUNNING;
|
||||||
|
|
||||||
cleanup:
|
cleanup:
|
||||||
if (hSCManager != NULL)
|
if (hSCManager != NULL)
|
||||||
|
|
Loading…
Reference in a new issue