[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:
Eric Kohl 2010-02-19 20:03:11 +00:00
parent 84f7b6a683
commit 69a020df26
3 changed files with 209 additions and 65 deletions

View file

@ -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;
}

View file

@ -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

View file

@ -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)