mirror of
https://github.com/reactos/reactos.git
synced 2025-02-23 08:55:19 +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
3 changed files with 209 additions and 65 deletions
|
@ -51,12 +51,11 @@
|
|||
|
||||
/* GLOBALS ******************************************************************/
|
||||
|
||||
static VOID CALLBACK
|
||||
ServiceMain(DWORD argc, LPTSTR *argv);
|
||||
|
||||
static SERVICE_TABLE_ENTRY ServiceTable[2] =
|
||||
static VOID CALLBACK ServiceMain(DWORD, LPWSTR *);
|
||||
static WCHAR ServiceName[] = L"PlugPlay";
|
||||
static SERVICE_TABLE_ENTRYW ServiceTable[] =
|
||||
{
|
||||
{TEXT("PlugPlay"), ServiceMain},
|
||||
{ServiceName, ServiceMain},
|
||||
{NULL, NULL}
|
||||
};
|
||||
|
||||
|
@ -2446,63 +2445,36 @@ PnpEventThread(LPVOID lpParameter)
|
|||
}
|
||||
|
||||
|
||||
static VOID CALLBACK
|
||||
ServiceMain(DWORD argc, LPTSTR *argv)
|
||||
static DWORD WINAPI
|
||||
ServiceControlHandler(DWORD dwControl,
|
||||
DWORD dwEventType,
|
||||
LPVOID lpEventData,
|
||||
LPVOID lpContext)
|
||||
{
|
||||
HANDLE hThread;
|
||||
DWORD dwThreadId;
|
||||
|
||||
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");
|
||||
/* FIXME */
|
||||
DPRINT1("ServiceControlHandler() called (control code %lu)\n", dwControl);
|
||||
return ERROR_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
wmain(int argc, WCHAR *argv[])
|
||||
static DWORD
|
||||
ServiceInit(VOID)
|
||||
{
|
||||
BOOLEAN OldValue;
|
||||
HANDLE hThread;
|
||||
DWORD dwThreadId;
|
||||
DWORD dwError;
|
||||
|
||||
UNREFERENCED_PARAMETER(argc);
|
||||
UNREFERENCED_PARAMETER(argv);
|
||||
|
||||
DPRINT("Umpnpmgr: main() started\n");
|
||||
BOOLEAN OldValue;
|
||||
|
||||
/* 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)
|
||||
{
|
||||
dwError = GetLastError();
|
||||
|
@ -2510,7 +2482,10 @@ wmain(int argc, WCHAR *argv[])
|
|||
return dwError;
|
||||
}
|
||||
|
||||
hDeviceInstallListNotEmpty = CreateEvent(NULL, FALSE, FALSE, NULL);
|
||||
hDeviceInstallListNotEmpty = CreateEvent(NULL,
|
||||
FALSE,
|
||||
FALSE,
|
||||
NULL);
|
||||
if (hDeviceInstallListNotEmpty == NULL)
|
||||
{
|
||||
dwError = GetLastError();
|
||||
|
@ -2557,11 +2532,110 @@ wmain(int argc, WCHAR *argv[])
|
|||
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;
|
||||
}
|
||||
|
|
|
@ -1054,7 +1054,7 @@ ScmStartService(PSERVICE Service, DWORD argc, LPWSTR *argv)
|
|||
{
|
||||
Group->ServicesRunning = TRUE;
|
||||
}
|
||||
Service->Status.dwCurrentState = SERVICE_RUNNING;
|
||||
Service->Status.dwCurrentState = SERVICE_START_PENDING;
|
||||
}
|
||||
#if 0
|
||||
else
|
||||
|
|
|
@ -20,7 +20,7 @@
|
|||
* COPYRIGHT: See COPYING in the top level directory
|
||||
* PROJECT: ReactOS system libraries
|
||||
* PURPOSE: System setup
|
||||
* FILE: lib/syssetup/install.c
|
||||
* FILE: dll/win32/syssetup/install.c
|
||||
* PROGRAMER: Eric Kohl
|
||||
*/
|
||||
|
||||
|
@ -473,30 +473,100 @@ InstallSysSetupInfComponents(VOID)
|
|||
static BOOL
|
||||
EnableUserModePnpManager(VOID)
|
||||
{
|
||||
SERVICE_STATUS_PROCESS ServiceStatus;
|
||||
SC_HANDLE hSCManager = NULL;
|
||||
SC_HANDLE hService = NULL;
|
||||
DWORD dwStartTickCount;
|
||||
DWORD dwOldCheckPoint;
|
||||
DWORD BytesNeeded = 0;
|
||||
DWORD dwWaitTime;
|
||||
DWORD dwMaxWait;
|
||||
BOOL ret = FALSE;
|
||||
|
||||
hSCManager = OpenSCManager(NULL, NULL, 0);
|
||||
if (hSCManager == NULL)
|
||||
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)
|
||||
goto cleanup;
|
||||
|
||||
ret = ChangeServiceConfigW(
|
||||
hService,
|
||||
SERVICE_NO_CHANGE, SERVICE_AUTO_START, SERVICE_NO_CHANGE,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL);
|
||||
ret = ChangeServiceConfigW(hService,
|
||||
SERVICE_NO_CHANGE,
|
||||
SERVICE_AUTO_START,
|
||||
SERVICE_NO_CHANGE,
|
||||
NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL);
|
||||
if (!ret)
|
||||
goto cleanup;
|
||||
|
||||
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)
|
||||
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:
|
||||
if (hSCManager != NULL)
|
||||
|
|
Loading…
Reference in a new issue