ReactOS Fundraising Campaign 2012
 
€ 4,410 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

start.c
Go to the documentation of this file.
00001 /*
00002  * PROJECT:     ReactOS Services
00003  * LICENSE:     GPL - See COPYING in the top level directory
00004  * FILE:        base/applications/mscutils/servman/start.c
00005  * PURPOSE:     Start a service
00006  * COPYRIGHT:   Copyright 2005-2010 Ged Murphy <gedmurphy@reactos.org>
00007  *
00008  */
00009 
00010 #include "precomp.h"
00011 
00012 static BOOL
00013 DoStartService(PMAIN_WND_INFO Info,
00014                HWND hProgress,
00015                LPWSTR lpStartParams)
00016 {
00017     SC_HANDLE hSCManager;
00018     SC_HANDLE hService;
00019     SERVICE_STATUS_PROCESS ServiceStatus;
00020     DWORD BytesNeeded = 0;
00021     DWORD dwStartTickCount;
00022     DWORD dwOldCheckPoint;
00023     DWORD dwWaitTime;
00024     DWORD dwMaxWait;
00025     BOOL bRet = FALSE;
00026 
00027     BOOL bWhiteSpace = TRUE;
00028     LPWSTR lpChar;
00029     DWORD dwArgsCount = 0;
00030     LPCWSTR *lpArgsVector = NULL;
00031 
00032     if (lpStartParams != NULL)
00033     {
00034         /* Count the number of arguments */
00035         lpChar = lpStartParams;
00036         while (*lpChar != 0)
00037         {
00038             if (iswspace(*lpChar))
00039             {
00040                 bWhiteSpace = TRUE;
00041             }
00042             else
00043             {
00044                 if (bWhiteSpace == TRUE)
00045                 {
00046                     dwArgsCount++;
00047                     bWhiteSpace = FALSE;
00048                 }
00049             }
00050 
00051             lpChar++;
00052         }
00053 
00054         /* Allocate the arguments vector and add one for the service name */
00055         lpArgsVector = LocalAlloc(LMEM_FIXED, (dwArgsCount + 1) * sizeof(LPCWSTR));
00056         if (!lpArgsVector)
00057             return FALSE;
00058 
00059         /* Make the service name the first argument */
00060         lpArgsVector[0] = Info->pCurrentService->lpServiceName;
00061 
00062         /* Fill the arguments vector */
00063         dwArgsCount = 1;
00064         bWhiteSpace = TRUE;
00065         lpChar = lpStartParams;
00066         while (*lpChar != 0)
00067         {
00068             if (iswspace(*lpChar))
00069             {
00070                 *lpChar = 0;
00071                 bWhiteSpace = TRUE;
00072             }
00073             else
00074             {
00075                 if (bWhiteSpace == TRUE)
00076                 {
00077                     lpArgsVector[dwArgsCount] = lpChar;
00078                     dwArgsCount++;
00079                     bWhiteSpace = FALSE;
00080                 }
00081             }
00082 
00083             lpChar++;
00084         }
00085     }
00086 
00087     hSCManager = OpenSCManager(NULL,
00088                                NULL,
00089                                SC_MANAGER_CONNECT);
00090     if (hSCManager)
00091     {
00092         hService = OpenService(hSCManager,
00093                                Info->pCurrentService->lpServiceName,
00094                                SERVICE_START | SERVICE_QUERY_STATUS);
00095         if (hService)
00096         {
00097             if (hProgress)
00098             {
00099                 /* Increment the progress bar */
00100                 IncrementProgressBar(hProgress, DEFAULT_STEP);
00101             }
00102 
00103             /* Start the service */
00104             bRet = StartService(hService,
00105                                 dwArgsCount,
00106                                 lpArgsVector);
00107             if (!bRet && GetLastError() == ERROR_SERVICE_ALREADY_RUNNING)
00108             {
00109                 /* If it's already running, just return TRUE */
00110                 bRet = TRUE;
00111             }
00112             else if (bRet)
00113             {
00114                 bRet = FALSE;
00115 
00116                 /* Get the service status to check if it's running */
00117                 if (QueryServiceStatusEx(hService,
00118                                          SC_STATUS_PROCESS_INFO,
00119                                          (LPBYTE)&ServiceStatus,
00120                                          sizeof(SERVICE_STATUS_PROCESS),
00121                                          &BytesNeeded))
00122                 {
00123                     /* We don't want to wait for more than 30 seconds */
00124                     dwMaxWait = 30000;
00125                     dwStartTickCount = GetTickCount();
00126 
00127                     /* Loop until it's running */
00128                     while (ServiceStatus.dwCurrentState != SERVICE_RUNNING)
00129                     {
00130                         dwOldCheckPoint = ServiceStatus.dwCheckPoint;
00131                         dwWaitTime = ServiceStatus.dwWaitHint / 10;
00132 
00133                         /* Get the latest status info */
00134                         if (!QueryServiceStatusEx(hService,
00135                                                   SC_STATUS_PROCESS_INFO,
00136                                                   (LPBYTE)&ServiceStatus,
00137                                                   sizeof(SERVICE_STATUS_PROCESS),
00138                                                   &BytesNeeded))
00139                         {
00140                             /* Something went wrong... */
00141                             break;
00142                         }
00143 
00144                         /* Is the service making progress? */
00145                         if (ServiceStatus.dwCheckPoint > dwOldCheckPoint)
00146                         {
00147                             /* It is, get the latest tickcount to reset the max wait time */
00148                             dwStartTickCount = GetTickCount();
00149                             dwOldCheckPoint = ServiceStatus.dwCheckPoint;
00150                             IncrementProgressBar(hProgress, DEFAULT_STEP);
00151                         }
00152                         else
00153                         {
00154                             /* It's not, make sure we haven't exceeded our wait time */
00155                             if (GetTickCount() >= dwStartTickCount + dwMaxWait)
00156                             {
00157                                 /* We have, give up */
00158                                 break;
00159                             }
00160                         }
00161 
00162                         /* Adjust the wait hint times */
00163                         if (dwWaitTime < 200)
00164                             dwWaitTime = 200;
00165                         else if (dwWaitTime > 10000)
00166                             dwWaitTime = 10000;
00167 
00168                         /* Wait before trying again */
00169                         Sleep(dwWaitTime);
00170                     }
00171                 }
00172 
00173                 if (ServiceStatus.dwCurrentState == SERVICE_RUNNING)
00174                 {
00175                     bRet = TRUE;
00176                 }
00177             }
00178 
00179             CloseServiceHandle(hService);
00180         }
00181 
00182         CloseServiceHandle(hSCManager);
00183     }
00184 
00185     if (lpArgsVector)
00186         LocalFree(lpArgsVector);
00187 
00188     return bRet;
00189 }
00190 
00191 BOOL
00192 DoStart(PMAIN_WND_INFO Info, LPWSTR lpStartParams)
00193 {
00194     HWND hProgress;
00195     BOOL bRet = FALSE;
00196 
00197     /* Create a progress window to track the progress of the stopping service */
00198     hProgress = CreateProgressDialog(Info->hMainWnd,
00199                                      IDS_PROGRESS_INFO_START);
00200     if (hProgress)
00201     {
00202         /* Set the service name and reset the progress bag */
00203         InitializeProgressDialog(hProgress, Info->pCurrentService->lpServiceName);
00204 
00205         /* Start the requested service */
00206         bRet = DoStartService(Info, hProgress, lpStartParams);
00207 
00208         /* Complete and destroy the progress bar */
00209         DestroyProgressDialog(hProgress, bRet);
00210     }
00211 
00212     return bRet;
00213 }
00214 

Generated on Sat May 26 2012 04:15:58 for ReactOS by doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.