~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~ [ freetext search ] ~ [ file search ] ~

Wine Cross Reference
wine/programs/msiexec/service.c

Version: ~ [ wine-1.1.33 ] ~ [ wine-1.1.32 ] ~ [ wine-1.1.31 ] ~ [ wine-1.1.30 ] ~ [ wine-1.1.29 ] ~ [ wine-1.1.28 ] ~ [ wine-1.1.27 ] ~ [ wine-1.1.26 ] ~ [ wine-1.1.25 ] ~ [ wine-1.1.24 ] ~ [ wine-1.1.23 ] ~ [ wine-1.1.22 ] ~ [ wine-1.1.21 ] ~ [ wine-1.1.20 ] ~ [ wine-1.1.19 ] ~ [ wine-1.1.18 ] ~ [ wine-1.1.17 ] ~ [ wine-1.1.16 ] ~ [ wine-1.1.15 ] ~ [ wine-1.1.14 ] ~ [ wine-1.1.13 ] ~ [ wine-1.1.12 ] ~ [ wine-1.1.11 ] ~ [ wine-1.1.10 ] ~ [ wine-1.1.9 ] ~ [ wine-1.1.8 ] ~ [ wine-1.1.7 ] ~ [ wine-1.0.1 ] ~ [ wine-1.1.6 ] ~ [ wine-1.1.5 ] ~ [ wine-1.1.4 ] ~ [ wine-1.1.3 ] ~ [ wine-1.1.2 ] ~ [ wine-1.1.1 ] ~ [ wine-1.1.0 ] ~ [ wine-1.0 ] ~

  1 /*
  2  * msiexec.exe implementation
  3  *
  4  * Copyright 2007 Google (James Hawkins)
  5  *
  6  * This library is free software; you can redistribute it and/or
  7  * modify it under the terms of the GNU Lesser General Public
  8  * License as published by the Free Software Foundation; either
  9  * version 2.1 of the License, or (at your option) any later version.
 10  *
 11  * This library is distributed in the hope that it will be useful,
 12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
 13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 14  * Lesser General Public License for more details.
 15  *
 16  * You should have received a copy of the GNU Lesser General Public
 17  * License along with this library; if not, write to the Free Software
 18  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
 19  */
 20 
 21 #define WIN32_LEAN_AND_MEAN
 22 
 23 #include <windows.h>
 24 #include <stdio.h>
 25 
 26 #include "wine/debug.h"
 27 
 28 WINE_DEFAULT_DEBUG_CHANNEL(msiexec);
 29 
 30 static SERVICE_STATUS_HANDLE hstatus;
 31 
 32 static HANDLE thread;
 33 static HANDLE kill_event;
 34 
 35 static void KillService(void)
 36 {
 37     WINE_TRACE("Killing service\n");
 38     SetEvent(kill_event);
 39 }
 40 
 41 static BOOL UpdateSCMStatus(DWORD dwCurrentState, DWORD dwWin32ExitCode,
 42                             DWORD dwServiceSpecificExitCode)
 43 {
 44     SERVICE_STATUS status;
 45 
 46     status.dwServiceType = SERVICE_WIN32_OWN_PROCESS;
 47     status.dwCurrentState = dwCurrentState;
 48 
 49     if (dwCurrentState == SERVICE_START_PENDING)
 50         status.dwControlsAccepted = 0;
 51     else
 52     {
 53         status.dwControlsAccepted = SERVICE_ACCEPT_STOP |
 54                                     SERVICE_ACCEPT_PAUSE_CONTINUE |
 55                                     SERVICE_ACCEPT_SHUTDOWN;
 56     }
 57 
 58     if (dwServiceSpecificExitCode == 0)
 59     {
 60         status.dwWin32ExitCode = dwWin32ExitCode;
 61     }
 62     else
 63     {
 64         status.dwWin32ExitCode = ERROR_SERVICE_SPECIFIC_ERROR;
 65     }
 66 
 67     status.dwServiceSpecificExitCode = dwServiceSpecificExitCode;
 68     status.dwCheckPoint = 0;
 69     status.dwWaitHint = 0;
 70 
 71     if (!SetServiceStatus(hstatus, &status))
 72     {
 73         fprintf(stderr, "Failed to set service status\n");
 74         KillService();
 75         return FALSE;
 76     }
 77 
 78     return TRUE;
 79 }
 80 
 81 static void WINAPI ServiceCtrlHandler(DWORD code)
 82 {
 83     WINE_TRACE("%d\n", code);
 84 
 85     switch (code)
 86     {
 87         case SERVICE_CONTROL_SHUTDOWN:
 88         case SERVICE_CONTROL_STOP:
 89             UpdateSCMStatus(SERVICE_STOP_PENDING, NO_ERROR, 0);
 90             KillService();
 91             return;
 92         default:
 93             fprintf(stderr, "Unhandled service control code: %d\n", code);
 94             break;
 95     }
 96 
 97     UpdateSCMStatus(SERVICE_RUNNING, NO_ERROR, 0);
 98 }
 99 
100 static DWORD WINAPI ServiceExecutionThread(LPVOID param)
101 {
102     while (TRUE)
103     {
104         /* do nothing */
105     }
106 
107     return 0;
108 }
109 
110 static BOOL StartServiceThread(void)
111 {
112     DWORD id;
113 
114     thread = CreateThread(0, 0, ServiceExecutionThread, 0, 0, &id);
115     if (!thread)
116     {
117         fprintf(stderr, "Failed to create thread\n");
118         return FALSE;
119     }
120 
121     return TRUE;
122 }
123 
124 static void WINAPI ServiceMain(DWORD argc, LPSTR *argv)
125 {
126     hstatus = RegisterServiceCtrlHandlerA("MSIServer", ServiceCtrlHandler);
127     if (!hstatus)
128     {
129         fprintf(stderr, "Failed to register service ctrl handler\n");
130         return;
131     }
132 
133     UpdateSCMStatus(SERVICE_START_PENDING, NO_ERROR, 0);
134 
135     kill_event = CreateEventW(0, TRUE, FALSE, 0);
136     if (!kill_event)
137     {
138         fprintf(stderr, "Failed to create event\n");
139         KillService();
140         return;
141     }
142 
143     if (!StartServiceThread())
144     {
145         KillService();
146         return;
147     }
148 
149     UpdateSCMStatus(SERVICE_RUNNING, NO_ERROR, 0);
150 
151     WaitForSingleObject(kill_event, INFINITE);
152     KillService();
153 }
154 
155 DWORD DoService(void)
156 {
157     char service_name[] = "MSIServer";
158 
159     const SERVICE_TABLE_ENTRYA service[] =
160     {
161         {service_name, ServiceMain},
162         {NULL, NULL},
163     };
164 
165     WINE_TRACE("Starting MSIServer service\n");
166 
167     if (!StartServiceCtrlDispatcherA(service))
168     {
169         fprintf(stderr, "Failed to start MSIServer service\n");
170         return 1;
171     }
172 
173     return 0;
174 }
175 

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~ [ freetext search ] ~ [ file search ] ~

This page was automatically generated by the LXR engine.
Visit the LXR main site for more information.