Author: dgorbachev Date: Thu Feb 18 03:28:51 2010 New Revision: 45606
URL: http://svn.reactos.org/svn/reactos?rev=45606&view=rev Log: [SYSSETUP] Wait until PlugPlay service is up. Bug #4142.
Modified: branches/arwinss/reactos/dll/win32/syssetup/install.c
Modified: branches/arwinss/reactos/dll/win32/syssetup/install.c URL: http://svn.reactos.org/svn/reactos/branches/arwinss/reactos/dll/win32/sysset... ============================================================================== --- branches/arwinss/reactos/dll/win32/syssetup/install.c [iso-8859-1] (original) +++ branches/arwinss/reactos/dll/win32/syssetup/install.c [iso-8859-1] Thu Feb 18 03:28:51 2010 @@ -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,103 @@ 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)