OpenCBM
service.c
Go to the documentation of this file.
1 /*
2  * This program is free software; you can redistribute it and/or
3  * modify it under the terms of the GNU General Public License
4  * as published by the Free Software Foundation; either version
5  * 2 of the License, or (at your option) any later version.
6  *
7  * Copyright 2004, 2008, 2012 Spiro Trikaliotis
8  *
9  */
10 
20 #include <windows.h>
21 #include <stdio.h>
22 #include "cbmioctl.h"
23 
24 // #include "instcbm.h"
25 
26 #include "i_opencbm.h"
27 
28 #include "libmisc.h"
29 
31 #define DBG_USERMODE
32 
34 #define DBG_PROGNAME "OPENCBM-XA1541.DLL"
35 
36 #include "debug.h"
37 
54 static VOID
55 RegSetDWORD(HKEY RegKey, char *SubKey, DWORD Value)
56 {
57  DWORD rc;
58 
59  FUNC_ENTER();
60 
61  DBG_PRINT((DBG_PREFIX "Setting %s to %u", SubKey, Value));
62 
63  rc = RegSetValueEx(RegKey, SubKey, 0, REG_DWORD, (LPBYTE)&Value, 4);
64 
65  DBG_ASSERT(rc == ERROR_SUCCESS);
66 
67  FUNC_LEAVE();
68 }
69 
86 static VOID
87 RegSetEXPANDSZ(HKEY RegKey, char *SubKey, IN LPCTSTR Value)
88 {
89  DWORD rc;
90 
91  FUNC_ENTER();
92 
93  rc = RegSetValueEx(RegKey, SubKey, 0, REG_EXPAND_SZ, Value, strlen(Value)+1);
94 
95  DBG_ASSERT(rc == ERROR_SUCCESS);
96 
97  FUNC_LEAVE();
98 }
99 
100 
113 static BOOL
114 CreateLogRegistryKeys(IN LPCTSTR ServiceExe)
115 {
116  DWORD dwDisposition;
117  HKEY RegKey;
118  BOOL error;
119 
120  FUNC_ENTER();
121 
122  error = TRUE;
123 
124  do {
125 
126  // Open a registry key to HKLM<%REGKEY_EVENTLOG%>
127 
128  if (RegCreateKeyEx(HKEY_LOCAL_MACHINE,
130  0,
131  NULL,
132  REG_OPTION_NON_VOLATILE,
133  KEY_SET_VALUE,
134  NULL,
135  &RegKey,
136  &dwDisposition
137  )
138  )
139  {
140  RegKey = NULL;
141  break;
142  }
143 
144  // Store the path to the file which contains the event service entries
145 
146  RegSetEXPANDSZ(RegKey, "EventMessageFile", ServiceExe);
147 
148  // The written "FACILITY" is 0x07 (FACILITY_PARALLEL_ERROR_CODE)
149 
150  RegSetDWORD(RegKey, "TypesSupported", 0x07);
151 
152  error = FALSE;
153 
154  } while (0);
155 
156  // We're done, close the registry handle.
157 
158  if (RegKey) {
159  RegCloseKey(RegKey);
160  }
161 
162  FUNC_LEAVE_BOOL(error);
163 }
164 
196 static BOOL
197 CreateDefaultRegistryKeys(IN ULONG DefaultLpt,
198  IN ULONG IecCableType,
199  IN ULONG PermanentlyLock,
200  IN BOOL DebugFlagsDriverPresent, IN ULONG DebugFlagsDriver,
201  IN BOOL DebugFlagsDllPresent, IN ULONG DebugFlagsDll)
202 {
203  BOOLEAN success;
204  HKEY RegKey;
205 
206  FUNC_ENTER();
207 
208  success = FALSE;
209 
210  // Open a registry key to HKLM<%CBM_REGKEY_SERVICE%>
211 
212  if (RegOpenKeyEx(HKEY_LOCAL_MACHINE,
214  0,
215  KEY_ALL_ACCESS,
216  &RegKey)
217  != ERROR_SUCCESS)
218 
219  {
220  DWORD error = GetLastError();
221 
222  DBG_WARN((DBG_PREFIX "COULD NOT OPEN HKLM\\" CBM_REGKEY_SERVICE " (0x%x) '%s'",
223  error, cbmlibmisc_format_error_message(error)));
224  printf("WARNING: COULD NOT OPEN HKLM\\" CBM_REGKEY_SERVICE " (0x%x) '%s'\n",
225  error, cbmlibmisc_format_error_message(error));
226  }
227  else
228  {
229  // Set the value for DefaultLpt
230 
231  if (DefaultLpt != -1)
232  {
233  RegSetDWORD(RegKey, CBM_REGKEY_SERVICE_DEFAULTLPT, DefaultLpt);
234  }
235 
236  if (IecCableType != IEC_CABLETYPE_UNSPEC)
237  {
238  RegSetDWORD(RegKey, CBM_REGKEY_SERVICE_IECCABLE, IecCableType);
239  }
240 
241  if (PermanentlyLock != -1)
242  {
243  RegSetDWORD(RegKey, CBM_REGKEY_SERVICE_PERMLOCK, PermanentlyLock);
244  }
245 
246 #if DBG
247 
248  // Set the value for the DebugFlags
249 
250  if (DebugFlagsDriverPresent)
251  {
252  RegSetDWORD(RegKey, CBM_REGKEY_SERVICE_DEBUGFLAGS, DebugFlagsDriver);
253  }
254 
255  if (DebugFlagsDllPresent)
256  {
257  RegSetDWORD(RegKey, CBM_REGKEY_SERVICE_DLL_DEBUGFLAGS, DebugFlagsDll);
258  }
259 
260 #endif // #if DBG
261 
262  // We're done, close the registry handle.
263 
264  RegCloseKey(RegKey);
265 
266  success = TRUE;
267  }
268 
269  FUNC_LEAVE_BOOL(success);
270 }
271 
272 
293 BOOL
294 CbmInstall(IN LPCTSTR DriverName, IN LPCTSTR ServiceExe, IN BOOL AutomaticStart)
295 {
296  SC_HANDLE scManager;
297  SC_HANDLE scService;
298  DWORD lasterror;
299  BOOL error;
300 
301  FUNC_ENTER();
302 
303  error = FALSE;
304 
305  scManager = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);
306 
307  if (scManager)
308  {
309  // Create the service
310 
311  scService = CreateService(scManager, DriverName, DriverName,
312  SERVICE_ALL_ACCESS, SERVICE_KERNEL_DRIVER,
313  AutomaticStart ? SERVICE_AUTO_START : SERVICE_DEMAND_START,
314  SERVICE_ERROR_NORMAL, ServiceExe,
315  "Extended base", NULL, "+Parallel arbitrator\0Parport\0",
316  NULL, NULL);
317 
318  if (scService == NULL)
319  {
320  lasterror = GetLastError();
321 
322  if (lasterror == ERROR_SERVICE_EXISTS)
323  {
324  // This is not an error, so process it differently from the others.
325 
326  DBG_WARN((DBG_PREFIX "CreateService (0x%02x) '%s'",
327  lasterror, cbmlibmisc_format_error_message(lasterror)));
328  printf("WARNING: opencbm is already installed!\n");
329  }
330  else
331  {
332  DBG_ERROR((DBG_PREFIX "CreateService (0x%02x) '%s'",
333  lasterror, cbmlibmisc_format_error_message(lasterror)));
334  printf("ERROR: CreateService (0x%02x) '%s'\n",
335  lasterror, cbmlibmisc_format_error_message(lasterror));
336 
337  error = TRUE;
338  }
339  }
340  else
341  {
342  DBG_SUCCESS((DBG_PREFIX "CreateService"));
343  CloseServiceHandle(scService);
344  }
345 
346  // Create the registry setting for the default LPT port
347 
348  CreateDefaultRegistryKeys(-1, -2, -1, FALSE, 0, FALSE, 0);
349 
350  CloseServiceHandle(scManager);
351 
352  // Create the registry settings for being able to output to the
353  // event service
354 
355  error = CreateLogRegistryKeys(ServiceExe);
356 
357  // If the driver is to be started automatically, start it now
358 
359  if (AutomaticStart)
360  {
362  }
363  }
364  else
365  {
366  error = TRUE;
367  }
368 
369  FUNC_LEAVE_BOOL(error);
370 }
371 
372 
403 BOOL
404 CbmUpdateParameter(IN ULONG DefaultLpt,
405  IN ULONG IecCableType,
406  IN ULONG PermanentlyLock,
407  IN BOOL DebugFlagsDriverPresent, IN ULONG DebugFlagsDriver,
408  IN BOOL DebugFlagsDllPresent, IN ULONG DebugFlagsDll)
409 {
410  BOOL ret;
411 
412  FUNC_ENTER();
413 
414  ret = CreateDefaultRegistryKeys(DefaultLpt, IecCableType, PermanentlyLock,
415  DebugFlagsDriverPresent, DebugFlagsDriver,
416  DebugFlagsDllPresent, DebugFlagsDll);
417 
418 // CbmInstallUpdate();
419 
420  FUNC_LEAVE_BOOL(ret);
421 }
422 
423 
436 BOOL
437 CbmRemove(IN LPCTSTR DriverName)
438 {
439  SC_HANDLE scManager;
440  SC_HANDLE scService;
441  BOOL ret;
442 
443  FUNC_ENTER();
444 
445  // Make sure the driver is stopped before being unloaded
446 
447  cbm_driver_stop();
448 
449  scManager = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);
450 
451  if (scManager)
452  {
453  scService = OpenService(scManager, DriverName, SERVICE_ALL_ACCESS);
454 
455  if (scService == NULL)
456  {
457  DWORD error = GetLastError();
458 
459  DBG_ERROR((DBG_PREFIX "OpenService (0x%02x) '%s'", error, cbmlibmisc_format_error_message(error)));
460  printf("ERROR: OpenService (0x%02x) '%s'\n", error, cbmlibmisc_format_error_message(error));
461  FUNC_LEAVE_BOOL(FALSE);
462  }
463 
464  ret = DeleteService(scService);
465 
466  if (ret)
467  {
468  DBG_SUCCESS((DBG_PREFIX "DeleteService"));
469  printf("DeleteService SUCCESS\n");
470  }
471  else
472  {
473  DWORD error = GetLastError();
474 
475  DBG_ERROR((DBG_PREFIX "DeleteService (0x%02x) '%s'", error, cbmlibmisc_format_error_message(error)));
476  printf("ERROR: DeleteService (0x%02x) '%s'\n", error, cbmlibmisc_format_error_message(error));
477  }
478 
479  CloseServiceHandle(scService);
480 
481 
482  // Remove the registry settings which were created for the event service
483 
484  RegDeleteKey(HKEY_LOCAL_MACHINE, REGKEY_EVENTLOG);
485 
486  CloseServiceHandle(scManager);
487  }
488  else
489  {
490  ret = FALSE;
491  }
492 
493  FUNC_LEAVE_BOOL(ret);
494 }
495 
496 
509 BOOL
510 CbmCheckPresence(IN LPCTSTR DriverName)
511 {
512  SC_HANDLE scManager;
513  SC_HANDLE scService;
514 
515  FUNC_ENTER();
516 
517  scService = NULL;
518 
519  scManager = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);
520 
521  if (scManager)
522  {
523  scService = OpenService(scManager, DriverName, SERVICE_ALL_ACCESS);
524 
525  if (scService != NULL)
526  {
527  CloseServiceHandle(scService);
528  }
529 
530  CloseServiceHandle(scManager);
531  }
532 
533  FUNC_LEAVE_BOOL(scService ? TRUE : FALSE);
534 }
#define REGKEY_EVENTLOG
Definition: i_opencbm.h:57
#define DBG_WARN(_xxx)
Definition: debug.h:395
BOOL CbmRemove(IN LPCTSTR DriverName)
Remove the driver.
Definition: service.c:437
Define makros for debugging purposes.
#define CBM_REGKEY_SERVICE
Definition: cbmioctl.h:38
#define CBM_REGKEY_SERVICE_IECCABLE
Definition: cbmioctl.h:46
Define the IOCTL codes for the opencbm driver.
#define CBM_REGKEY_SERVICE_DEFAULTLPT
Definition: cbmioctl.h:42
#define CBM_REGKEY_SERVICE_PERMLOCK
Definition: cbmioctl.h:50
#define FUNC_LEAVE()
Definition: debug.h:349
#define CBM_REGKEY_SERVICE_DEBUGFLAGS
Definition: cbmioctl.h:53
#define DBG_ASSERT(_xxx)
Definition: debug.h:401
#define FUNC_LEAVE_BOOL(_xxx)
Definition: debug.h:354
#define DBG_ERROR(_xxx)
Definition: debug.h:397
#define DBG_SUCCESS(_xxx)
Definition: debug.h:393
BOOL CbmInstall(IN LPCTSTR DriverName, IN LPCTSTR ServiceExe, IN BOOL AutomaticStart)
Install the driver.
Definition: service.c:294
#define FUNC_ENTER()
Definition: debug.h:347
#define DBG_PREFIX
Definition: debug.h:320
#define CBM_REGKEY_SERVICE_DLL_DEBUGFLAGS
Definition: cbmioctl.h:56
BOOL cbm_driver_stop(VOID)
Stop a device driver.
Definition: i_opencbm.c:639
BOOL cbm_driver_start(VOID)
Start a device driver.
Definition: i_opencbm.c:564
Internal API for opencbm installation.
BOOL CbmUpdateParameter(IN ULONG DefaultLpt, IN ULONG IecCableType, IN ULONG PermanentlyLock, IN BOOL DebugFlagsDriverPresent, IN ULONG DebugFlagsDriver, IN BOOL DebugFlagsDllPresent, IN ULONG DebugFlagsDll)
Update the parameter of the driver.
Definition: service.c:404
Some functions for string handling.
char * cbmlibmisc_format_error_message(unsigned int ErrorNumber)
Format a returned error code into a string.
#define DBG_PRINT(_xxx)
Definition: debug.h:403
BOOL CbmCheckPresence(IN LPCTSTR DriverName)
Check for the presence of the driver.
Definition: service.c:510