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

service.c
Go to the documentation of this file.
00001 /*
00002  * ServiceMain function for qmgr running within svchost
00003  *
00004  * Copyright 2007 (C) Google (Roy Shea)
00005  *
00006  * This library is free software; you can redistribute it and/or
00007  * modify it under the terms of the GNU Lesser General Public
00008  * License as published by the Free Software Foundation; either
00009  * version 2.1 of the License, or (at your option) any later version.
00010  *
00011  * This library is distributed in the hope that it will be useful,
00012  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00013  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00014  * Lesser General Public License for more details.
00015  *
00016  * You should have received a copy of the GNU Lesser General Public
00017  * License along with this library; if not, write to the Free Software
00018  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
00019  */
00020 
00021 #include "windef.h"
00022 #include "objbase.h"
00023 #include "winsvc.h"
00024 #include "bits.h"
00025 
00026 #include "qmgr.h"
00027 #include "wine/debug.h"
00028 
00029 WINE_DEFAULT_DEBUG_CHANNEL(qmgr);
00030 
00031 HANDLE stop_event = NULL;
00032 
00033 static SERVICE_STATUS_HANDLE status_handle;
00034 static SERVICE_STATUS status;
00035 
00036 static VOID
00037 UpdateStatus(DWORD dwCurrentState, DWORD dwWin32ExitCode, DWORD dwWaitHint)
00038 {
00039     status.dwServiceType = SERVICE_WIN32_OWN_PROCESS;
00040     status.dwCurrentState = dwCurrentState;
00041     if (dwCurrentState == SERVICE_START_PENDING)
00042         status.dwControlsAccepted = 0;
00043     else
00044         status.dwControlsAccepted
00045             = (SERVICE_ACCEPT_STOP | SERVICE_ACCEPT_PAUSE_CONTINUE
00046                | SERVICE_ACCEPT_SHUTDOWN);
00047     status.dwWin32ExitCode = 0;
00048     status.dwServiceSpecificExitCode = 0;
00049     status.dwCheckPoint = 0;
00050     status.dwWaitHint = dwWaitHint;
00051 
00052     if (!SetServiceStatus(status_handle, &status)) {
00053         ERR("failed to set service status\n");
00054         SetEvent(stop_event);
00055     }
00056 }
00057 
00058 /* Handle incoming ControlService signals */
00059 static DWORD WINAPI
00060 ServiceHandler(DWORD ctrl, DWORD event_type, LPVOID event_data, LPVOID context)
00061 {
00062     switch (ctrl) {
00063     case SERVICE_CONTROL_STOP:
00064     case SERVICE_CONTROL_SHUTDOWN:
00065         TRACE("shutting down service\n");
00066         UpdateStatus(SERVICE_STOP_PENDING, NO_ERROR, 0);
00067         SetEvent(stop_event);
00068         break;
00069     default:
00070         FIXME("ignoring handle service ctrl %x\n", ctrl);
00071         UpdateStatus(status.dwCurrentState, NO_ERROR, 0);
00072         break;
00073     }
00074 
00075     return NO_ERROR;
00076 }
00077 
00078 /* Main thread of the service */
00079 static BOOL
00080 StartCount(void)
00081 {
00082     HRESULT hr;
00083     DWORD dwReg;
00084 
00085     TRACE("\n");
00086 
00087     hr = CoInitializeEx(NULL, COINIT_MULTITHREADED);
00088     if (FAILED(hr))
00089         return FALSE;
00090 
00091     hr = CoInitializeSecurity(NULL, -1, NULL, NULL, RPC_C_AUTHN_LEVEL_NONE,
00092                               RPC_C_IMP_LEVEL_IMPERSONATE, NULL, EOAC_NONE,
00093                               NULL);
00094     if (FAILED(hr))
00095         return FALSE;
00096 
00097     hr = CoRegisterClassObject(&CLSID_BackgroundCopyManager,
00098                                (IUnknown *) &BITS_ClassFactory,
00099                                CLSCTX_LOCAL_SERVER, REGCLS_MULTIPLEUSE,
00100                                &dwReg);
00101     if (FAILED(hr))
00102         return FALSE;
00103 
00104     return TRUE;
00105 }
00106 
00107 /* Service entry point */
00108 VOID WINAPI
00109 ServiceMain(DWORD dwArgc, LPWSTR *lpszArgv)
00110 {
00111     HANDLE fileTxThread;
00112     static const WCHAR qmgr_nameW[] = {'B','I','T','S',0};
00113     DWORD threadId;
00114     TRACE("\n");
00115 
00116     stop_event = CreateEventW(NULL, TRUE, FALSE, NULL);
00117     if (!stop_event) {
00118         ERR("failed to create stop_event\n");
00119         return;
00120     }
00121 
00122     status_handle = RegisterServiceCtrlHandlerExW(qmgr_nameW, ServiceHandler, NULL);
00123     if (!status_handle) {
00124         ERR("failed to register handler: %u\n", GetLastError());
00125         return;
00126     }
00127 
00128     UpdateStatus(SERVICE_START_PENDING, NO_ERROR, 3000);
00129     if (!StartCount()) {
00130         ERR("failed starting service thread\n");
00131         UpdateStatus(SERVICE_STOPPED, NO_ERROR, 0);
00132         return;
00133     }
00134 
00135     globalMgr.jobEvent = CreateEventW(NULL, TRUE, FALSE, NULL);
00136     if (!globalMgr.jobEvent) {
00137         ERR("Couldn't create event: error %d\n", GetLastError());
00138         UpdateStatus(SERVICE_STOPPED, NO_ERROR, 0);
00139         return;
00140     }
00141 
00142     fileTxThread = CreateThread(NULL, 0, fileTransfer, NULL, 0, &threadId);
00143     if (!fileTxThread)
00144     {
00145         ERR("Failed starting file transfer thread\n");
00146         UpdateStatus(SERVICE_STOPPED, NO_ERROR, 0);
00147         return;
00148     }
00149 
00150     UpdateStatus(SERVICE_RUNNING, NO_ERROR, 0);
00151 
00152     WaitForSingleObject(fileTxThread, INFINITE);
00153     UpdateStatus(SERVICE_STOPPED, NO_ERROR, 0);
00154     CloseHandle(stop_event);
00155     TRACE("service stoped\n");
00156 
00157     CoUninitialize();
00158 }

Generated on Sun May 27 2012 04:18:48 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.