Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygenservice.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
1.7.6.1
|