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  * msiexec.exe implementation
00003  *
00004  * Copyright 2007 Google (James Hawkins)
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 #define WIN32_LEAN_AND_MEAN
00022 
00023 #include <windows.h>
00024 #include <stdio.h>
00025 
00026 #include "wine/debug.h"
00027 
00028 WINE_DEFAULT_DEBUG_CHANNEL(msiexec);
00029 
00030 static SERVICE_STATUS_HANDLE hstatus;
00031 
00032 static HANDLE thread;
00033 static HANDLE kill_event;
00034 
00035 static void KillService(void)
00036 {
00037     WINE_TRACE("Killing service\n");
00038     SetEvent(kill_event);
00039 }
00040 
00041 static BOOL UpdateSCMStatus(DWORD dwCurrentState, DWORD dwWin32ExitCode,
00042                             DWORD dwServiceSpecificExitCode)
00043 {
00044     SERVICE_STATUS status;
00045 
00046     status.dwServiceType = SERVICE_WIN32_OWN_PROCESS;
00047     status.dwCurrentState = dwCurrentState;
00048 
00049     if (dwCurrentState == SERVICE_START_PENDING)
00050         status.dwControlsAccepted = 0;
00051     else
00052     {
00053         status.dwControlsAccepted = SERVICE_ACCEPT_STOP |
00054                                     SERVICE_ACCEPT_PAUSE_CONTINUE |
00055                                     SERVICE_ACCEPT_SHUTDOWN;
00056     }
00057 
00058     if (dwServiceSpecificExitCode == 0)
00059     {
00060         status.dwWin32ExitCode = dwWin32ExitCode;
00061     }
00062     else
00063     {
00064         status.dwWin32ExitCode = ERROR_SERVICE_SPECIFIC_ERROR;
00065     }
00066 
00067     status.dwServiceSpecificExitCode = dwServiceSpecificExitCode;
00068     status.dwCheckPoint = 0;
00069     status.dwWaitHint = 0;
00070 
00071     if (!SetServiceStatus(hstatus, &status))
00072     {
00073         fprintf(stderr, "Failed to set service status\n");
00074         KillService();
00075         return FALSE;
00076     }
00077 
00078     return TRUE;
00079 }
00080 
00081 static void WINAPI ServiceCtrlHandler(DWORD code)
00082 {
00083     WINE_TRACE("%d\n", code);
00084 
00085     switch (code)
00086     {
00087         case SERVICE_CONTROL_SHUTDOWN:
00088         case SERVICE_CONTROL_STOP:
00089             UpdateSCMStatus(SERVICE_STOP_PENDING, NO_ERROR, 0);
00090             KillService();
00091             return;
00092         default:
00093             fprintf(stderr, "Unhandled service control code: %d\n", code);
00094             break;
00095     }
00096 
00097     UpdateSCMStatus(SERVICE_RUNNING, NO_ERROR, 0);
00098 }
00099 
00100 static DWORD WINAPI ServiceExecutionThread(LPVOID param)
00101 {
00102     while (TRUE)
00103     {
00104         /* do nothing */
00105     }
00106 
00107     return 0;
00108 }
00109 
00110 static BOOL StartServiceThread(void)
00111 {
00112     DWORD id;
00113 
00114     thread = CreateThread(0, 0, ServiceExecutionThread, 0, 0, &id);
00115     if (!thread)
00116     {
00117         fprintf(stderr, "Failed to create thread\n");
00118         return FALSE;
00119     }
00120 
00121     return TRUE;
00122 }
00123 
00124 static void WINAPI ServiceMain(DWORD argc, LPSTR *argv)
00125 {
00126     hstatus = RegisterServiceCtrlHandlerA("MSIServer", ServiceCtrlHandler);
00127     if (!hstatus)
00128     {
00129         fprintf(stderr, "Failed to register service ctrl handler\n");
00130         return;
00131     }
00132 
00133     UpdateSCMStatus(SERVICE_START_PENDING, NO_ERROR, 0);
00134 
00135     kill_event = CreateEventW(0, TRUE, FALSE, 0);
00136     if (!kill_event)
00137     {
00138         fprintf(stderr, "Failed to create event\n");
00139         KillService();
00140         return;
00141     }
00142 
00143     if (!StartServiceThread())
00144     {
00145         KillService();
00146         return;
00147     }
00148 
00149     UpdateSCMStatus(SERVICE_RUNNING, NO_ERROR, 0);
00150 
00151     WaitForSingleObject(kill_event, INFINITE);
00152     KillService();
00153 }
00154 
00155 DWORD DoService(void)
00156 {
00157     char service_name[] = "MSIServer";
00158 
00159     const SERVICE_TABLE_ENTRYA service[] =
00160     {
00161         {service_name, ServiceMain},
00162         {NULL, NULL},
00163     };
00164 
00165     WINE_TRACE("Starting MSIServer service\n");
00166 
00167     if (!StartServiceCtrlDispatcherA(service))
00168     {
00169         fprintf(stderr, "Failed to start MSIServer service\n");
00170         return 1;
00171     }
00172 
00173     return 0;
00174 }

Generated on Wed May 23 2012 04:16:51 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.