Return-Path: Delivered-To: apmail-commons-commits-archive@minotaur.apache.org Received: (qmail 82368 invoked from network); 15 Mar 2010 07:43:00 -0000 Received: from unknown (HELO mail.apache.org) (140.211.11.3) by 140.211.11.9 with SMTP; 15 Mar 2010 07:43:00 -0000 Received: (qmail 77878 invoked by uid 500); 15 Mar 2010 07:42:14 -0000 Delivered-To: apmail-commons-commits-archive@commons.apache.org Received: (qmail 77726 invoked by uid 500); 15 Mar 2010 07:42:14 -0000 Mailing-List: contact commits-help@commons.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: dev@commons.apache.org Delivered-To: mailing list commits@commons.apache.org Received: (qmail 77719 invoked by uid 99); 15 Mar 2010 07:42:13 -0000 Received: from nike.apache.org (HELO nike.apache.org) (192.87.106.230) by apache.org (qpsmtpd/0.29) with ESMTP; Mon, 15 Mar 2010 07:42:13 +0000 X-ASF-Spam-Status: No, hits=-2000.0 required=10.0 tests=ALL_TRUSTED X-Spam-Check-By: apache.org Received: from [140.211.11.4] (HELO eris.apache.org) (140.211.11.4) by apache.org (qpsmtpd/0.29) with ESMTP; Mon, 15 Mar 2010 07:42:10 +0000 Received: by eris.apache.org (Postfix, from userid 65534) id 6BE5C238899B; Mon, 15 Mar 2010 07:41:49 +0000 (UTC) Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: svn commit: r923104 - in /commons/proper/daemon/trunk: RELEASE-NOTES.txt src/native/nt/procrun/src/service.c Date: Mon, 15 Mar 2010 07:41:49 -0000 To: commits@commons.apache.org From: mturk@apache.org X-Mailer: svnmailer-1.0.8 Message-Id: <20100315074149.6BE5C238899B@eris.apache.org> X-Virus-Checked: Checked by ClamAV on apache.org Author: mturk Date: Mon Mar 15 07:41:49 2010 New Revision: 923104 URL: http://svn.apache.org/viewvc?rev=923104&view=rev Log: Fix DAEMON-108 by stopping dependent service first Modified: commons/proper/daemon/trunk/RELEASE-NOTES.txt commons/proper/daemon/trunk/src/native/nt/procrun/src/service.c Modified: commons/proper/daemon/trunk/RELEASE-NOTES.txt URL: http://svn.apache.org/viewvc/commons/proper/daemon/trunk/RELEASE-NOTES.txt?rev=923104&r1=923103&r2=923104&view=diff ============================================================================== --- commons/proper/daemon/trunk/RELEASE-NOTES.txt (original) +++ commons/proper/daemon/trunk/RELEASE-NOTES.txt Mon Mar 15 07:41:49 2010 @@ -35,7 +35,7 @@ NEW FEATURES: BUG FIXES: -1.0.3: DAEMON-139 +1.0.3: DAEMON-108, DAEMON-139 1.0.2: DAEMON-16, DAEMON-31, DAEMON-40, DAEMON-45, DAEMON-49, DAEMON-60, DAEMON-84, DAEMON-90, DAEMON-91, DAEMON-92, DAEMON-93, DAEMON-94, Modified: commons/proper/daemon/trunk/src/native/nt/procrun/src/service.c URL: http://svn.apache.org/viewvc/commons/proper/daemon/trunk/src/native/nt/procrun/src/service.c?rev=923104&r1=923103&r2=923104&view=diff ============================================================================== --- commons/proper/daemon/trunk/src/native/nt/procrun/src/service.c (original) +++ commons/proper/daemon/trunk/src/native/nt/procrun/src/service.c Mon Mar 15 07:41:49 2010 @@ -235,6 +235,104 @@ apxServiceSetOptions(APXHANDLE hService, NULL, NULL); } +static BOOL +__apxStopDependentServices(LPAPXSERVICE lpService) +{ + DWORD i; + DWORD dwBytesNeeded; + DWORD dwCount; + + LPENUM_SERVICE_STATUS lpDependencies = NULL; + ENUM_SERVICE_STATUS ess; + SC_HANDLE hDepService; + SERVICE_STATUS_PROCESS ssp; + + DWORD dwStartTime = GetTickCount(); + /* Use the 30-second time-out */ + DWORD dwTimeout = 30000; + + /* Pass a zero-length buffer to get the required buffer size. + */ + if (EnumDependentServices(lpService->hService, + SERVICE_ACTIVE, + lpDependencies, 0, + &dwBytesNeeded, + &dwCount)) { + /* If the Enum call succeeds, then there are no dependent + * services, so do nothing. + */ + return TRUE; + } + else { + if (GetLastError() != ERROR_MORE_DATA) + return FALSE; // Unexpected error + + /* Allocate a buffer for the dependencies. + */ + lpDependencies = (LPENUM_SERVICE_STATUS) HeapAlloc(GetProcessHeap(), + HEAP_ZERO_MEMORY, + dwBytesNeeded); + if (!lpDependencies) + return FALSE; + + __try { + /* Enumerate the dependencies. */ + if (!EnumDependentServices(lpService->hService, + SERVICE_ACTIVE, + lpDependencies, + dwBytesNeeded, + &dwBytesNeeded, + &dwCount)) + return FALSE; + + for (i = 0; i < dwCount; i++) { + ess = *(lpDependencies + i); + /* Open the service. */ + hDepService = OpenService(lpService->hManager, + ess.lpServiceName, + SERVICE_STOP | SERVICE_QUERY_STATUS); + + if (!hDepService) + return FALSE; + + __try { + /* Send a stop code. */ + if (!ControlService(hDepService, + SERVICE_CONTROL_STOP, + (LPSERVICE_STATUS) &ssp)) + return FALSE; + + /* Wait for the service to stop. */ + while (ssp.dwCurrentState != SERVICE_STOPPED) { + Sleep(ssp.dwWaitHint); + if (!QueryServiceStatusEx(hDepService, + SC_STATUS_PROCESS_INFO, + (LPBYTE)&ssp, + sizeof(SERVICE_STATUS_PROCESS), + &dwBytesNeeded)) + return FALSE; + + if (ssp.dwCurrentState == SERVICE_STOPPED) + break; + + if (GetTickCount() - dwStartTime > dwTimeout) + return FALSE; + } + } + __finally { + /* Always release the service handle. */ + CloseServiceHandle(hDepService); + } + } + } + __finally { + /* Always free the enumeration buffer. */ + HeapFree(GetProcessHeap(), 0, lpDependencies); + } + } + return TRUE; +} + BOOL apxServiceControl(APXHANDLE hService, DWORD dwControl, UINT uMsg, LPAPXFNCALLBACK fnControlCallback, @@ -313,8 +411,16 @@ apxServiceControl(APXHANDLE hService, DW if (dwControl == SERVICE_CONTROL_CONTINUE && stStatus.dwCurrentState != SERVICE_PAUSED) bStatus = StartService(lpService->hService, 0, NULL); - else - bStatus = ControlService(lpService->hService, dwControl, &stStatus); + else { + bStatus = TRUE; + if (dwControl == SERVICE_CONTROL_STOP) { + /* First stop dependent services + */ + bStatus = __apxStopDependentServices(lpService); + } + if (bStatus) + bStatus = ControlService(lpService->hService, dwControl, &stStatus); + } dwStart = GetTickCount(); dwCheck = stStatus.dwCheckPoint; if (bStatus) {