Introduction
某些third-party api會在runtime去新增service,以減少使用者在安裝上的負擔。然而在系統重新啟動時,SCM會lock service database,如果新增service將會造成block。此源自: link
A service cannot call StartService during initialization. The reason is that the SCM locks the' service control database during initialization, so a call to StartService will block. After the service reports to the SCM that it has successfully started, it can call StartService.
因此,我們可以先檢查SCM database是否lock,再決定我們接下來該怎麼做。
How to?
要解決這問題,可以使用:
- API: QueryServiceLockStatus。
- Command line: sc querylock。
首先來看看QueryServiceLockStatus:
BOOL IsSCMRelease(){ SC_HANDLE hSCManager; LPQUERY_SERVICE_LOCK_STATUS hStatus; DWORD dwBytesNeeded; BOOL ret; hSCManager=OpenSCManager(NULL, NULL, SC_MANAGER_QUERY_LOCK_STATUS); if (hSCManager) { hStatus = (LPQUERY_SERVICE_LOCK_STATUS) LocalAlloc(LPTR, sizeof(QUERY_SERVICE_LOCK_STATUS)+256); if( hStatus == NULL ) { clog << "LocalAlloc failed. Error: " << GetLastError() << endl; return FALSE; } if( !QueryServiceLockStatus( hSCManager, hStatus, sizeof(QUERY_SERVICE_LOCK_STATUS)+256, &dwBytesNeeded)){ clog << "Can't query lock status. Error: " << GetLastError() << endl; ret = FALSE; } else { ret = hStatus->fIsLocked == 0; } CloseServiceHandle(hSCManager); LocalFree(hStatus); return ret; } clog << "Can't open SCManager." << endl; return FALSE; }
若透過command line:
C:\Users\tonylin>chcp 437 & sc querylock Active code page: 437 [SC] QueryServiceLockStatus SUCCESS IsLocked : FALSE LockOwner : LockDuration : 0 (seconds since acquired)
留言
張貼留言