OpenCBM
lib/plugin/xa1541/WINDOWS/install.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 2008 Spiro Trikaliotis
8 */
9 
19 #include <windows.h>
20 #include <windowsx.h>
21 
23 #define DBG_USERMODE
24 
26 #ifndef DBG_PROGNAME
27  #define DBG_PROGNAME "OPENCBM-XA1541.DLL"
28 #endif // #ifndef DBG_PROGNAME
29 
30 #include "debug.h"
31 
32 #include <stdio.h>
33 #include <stdlib.h>
34 
35 #include <getopt.h>
36 
37 #include "cbmioctl.h"
38 #include "i_opencbm.h"
39 #include "libmisc.h"
40 #include "version.h"
41 
42 #define OPENCBM_PLUGIN 1
44 #include "archlib.h"
45 #include "archlib-windows.h"
46 
47 
49 typedef
50 struct xa1541_parameter_s
51 {
54 
56  BOOL ForceNt4;
57 
59  ULONG Lpt;
60 
63 
66 
69 
72 
74  osversion_t OsVersion;
75 
77 
78 
79 static const struct option longopts[] =
80 {
81  { "help", no_argument, NULL, 'h' },
82  { "version", no_argument, NULL, 'V' },
83 
84 // { "enumpport", no_argument, NULL, 'e' },
85 #ifdef _X86_
86  { "forcent4", no_argument, NULL, 'F' },
87 #endif // #ifdef _X86_
88  { "lpt", required_argument, NULL, 'l' },
89  { "cabletype", required_argument, NULL, 't' },
90  { "lock", required_argument, NULL, 'L' },
91 #if DBG
92  { "debugflags", required_argument, NULL, 'D' },
93  { "buffer", no_argument, NULL, 'B' },
94 #endif // #if DBG
95  { "automatic", no_argument, NULL, 'A' },
96  { "on-demand", no_argument, NULL, 'O' },
97 
98  { NULL, 0, NULL, 0 }
99 };
100 
101 static const char shortopts[] = "-hVFl:t:L:DBAO";
102 
103 static const char usagetext[] =
104  "\n\nUsage: instcbm [options] xa1541 [plugin-options]\n"
105  "Install the XA1541 plugin and driver on the system, or remove it.\n"
106  "\n"
107  "plugin-options is one of:\n"
108  " -h, --help display this help and exit\n"
109  " -V, --version display version information about cbm4win\n"
110 // " -e, --enumpport re-enumerate the parallel port driver\n"
111  " -l, --lpt=no set default LPT port\n"
112  " -t, --cabletype=TYPE set cabletype to 'auto', 'xa1541' or 'xm1541'.\n"
113  " If not specified, --cabletype=auto is assumed.\n"
114  " -L, --lock=WHAT automatically lock the driver 'yes' or not 'no'.\n"
115  " If not specified, --lock=yes is assumed.\n"
116 #ifdef _X86_
117  " -F, --forcent4 force NT4 driver on a Win 2000, XP, or newer systems\n"
118  " (NOT RECOMMENDED!)\n"
119 #endif // #ifdef _X86_
120  " -A, --automatic (default) automatically start the driver on system boot.\n"
121  " The driver can be used from a normal user, no need for\n"
122  " administrator rights.\n"
123  " The opposite of --on-demand.\n"
124  " -O, --on-demand start the driver only on demand.\n"
125  " The opposite of --automatic.\n"
126  "\n";
127 
128 
129 static opencbm_plugin_install_neededfiles_t NeededFilesXA1541[] =
130 {
131  { SYSTEM_DIR, "opencbm-xa1541.dll", NULL },
132  { DRIVER_DIR, "cbm4wdm.sys", NULL }, /* this MUST be the same index as driver_cbm4wdm is defined */
133 #ifdef _X86_
134  { DRIVER_DIR, "cbm4nt.sys", NULL }, /* this MUST be the same index as driver_cbm4nt is defined */
135 #endif
136  { LIST_END, "", NULL }
137 };
138 
140 typedef
141 enum driver_to_use_e {
143 #ifdef _X86_
144  driver_cbm4nt = 2
145 #endif
147 
150 static void
151 hint(void)
152 {
153  fprintf(stderr, "Try \"instcbm xa1541 --help\" for more information.\n");
154 }
155 
156 
159 static VOID
160 version(VOID)
161 {
162  printf("opencbm xa1541 plugin version " /* OPENCBM_VERSION */ ", built on " __DATE__ " at " __TIME__ "\n");
163 }
164 
167 static void
168 usage(void)
169 {
170  version();
171 
172  printf("%s", usagetext);
173 }
174 
175 
207 static BOOL
208 processNumber(const PCHAR Argument, PCHAR *NextChar, PBOOL ParameterGiven, PULONG ParameterValue)
209 {
210  PCHAR p;
211  BOOL error;
212  int base;
213 
214  FUNC_ENTER();
215 
216  DBG_ASSERT(ParameterValue != NULL);
217 
218  error = FALSE;
219  p = Argument;
220 
221  if (p)
222  {
223  // Find out which base to use (0***, 0x***, or anything else)
224 
225  switch (*p)
226  {
227  case 0:
228  error = TRUE;
229  break;
230 
231  case '0':
232  switch (*++p)
233  {
234  case 'x': case 'X':
235  base = 16;
236  ++p;
237  break;
238 
239  default:
240  base = 8;
241  break;
242  };
243  break;
244 
245  default:
246  base = 10;
247  break;
248  }
249 
250  // Convert the value
251 
252  if (!error)
253  {
254  *ParameterValue = strtoul(p, &p, base);
255 
256  if (NextChar)
257  {
258  error = ((*p != 0) && (*p != ',')) ? TRUE : FALSE;
259  }
260  else
261  {
262  error = *p != 0 ? TRUE : FALSE;
263  }
264 
265  if (!error)
266  {
267  if (NextChar != NULL)
268  {
269  *NextChar = p + ((*p) ? 1 : 0);
270  }
271 
272  if (ParameterGiven != NULL)
273  {
274  *ParameterGiven = TRUE;
275  }
276  }
277  }
278  }
279 
280  FUNC_LEAVE_BOOL(error);
281 }
282 
283 /*-------------------------------------------------------------------*/
284 /*--------- OPENCBM INSTALL HELPER FUNCTIONS ------------------------*/
285 
292 unsigned int CBMAPIDECL
294 {
295  int error = 0;
296  char **localOptarg = Data->OptArg;
297 
298  xa1541_parameter_t *parameter = Data->OptionMemory;
299 
300  BOOL quitLocalProcessing = FALSE;
301 
302  FUNC_ENTER();
303 
304  DBG_ASSERT(Data);
305 
306 
307  do {
308  int c;
309 
310  /* special handling for first call: Determine the length of the OptionMemory to be allocated */
311 
312  if (Data->Argc == 0) {
313  error = sizeof(xa1541_parameter_t);
314  break;
315  }
316 
317  DBG_ASSERT(Data->OptionMemory != NULL);
318  DBG_ASSERT(Data->GetoptLongCallback != NULL);
319  DBG_ASSERT(Data->OptInd != NULL);
320  DBG_ASSERT(Data->OptErr != NULL);
321  DBG_ASSERT(Data->OptOpt != NULL);
322  DBG_ASSERT(Data->InstallParameter != NULL);
323 
324  /* as we are interested in the OS version for installation, copy it */
325 
326  parameter->OsVersion = Data->InstallParameter->OsVersion;
327 
328 
329  // We have not specified an LPT port yet
330 
331  parameter->Lpt = (ULONG) -1;
332 
333  // No IEC cable type was specified
334 
335  parameter->IecCableType = IEC_CABLETYPE_UNSPEC;
336 
337  // It was not specified if the driver is to be permenently locked
338 
339  parameter->PermanentlyLock = (ULONG) -1;
340 
341  // set the default: automaticstart -A
342 
343  parameter->AutomaticStart = TRUE;
344 
345 
346  if (Data->Argv) {
347  while ( ! quitLocalProcessing && (c = Data->GetoptLongCallback(Data->Argc, Data->Argv, shortopts, longopts)) != -1) {
348  switch (c) {
349  case 'h':
350  usage();
351  Data->InstallParameter->NoExecute = TRUE;
352  break;
353 
354  case 'V':
355  version();
356  Data->InstallParameter->NoExecute = TRUE;
357  break;
358 
359  case 't':
360  if ((*localOptarg == NULL) || (strcmp(*localOptarg, "auto") == 0))
361  parameter->IecCableType = IEC_CABLETYPE_AUTO;
362  else if (strcmp(*localOptarg, "xa1541") == 0)
363  parameter->IecCableType = IEC_CABLETYPE_XA;
364  else if (strcmp(*localOptarg, "xm1541") == 0)
365  parameter->IecCableType = IEC_CABLETYPE_XM;
366  else
367  {
368  fprintf(stderr, "you must specify 'xa1541', 'xm1541' or 'auto' for --cabletype\n");
369  error = TRUE;
370  }
371  break;
372 
373  case 'L':
374  if (*localOptarg == NULL
375  || (strcmp(*localOptarg, "+") == 0)
376  || (strcmp(*localOptarg, "yes") == 0)
377  || (strcmp(*localOptarg, "true") == 0)
378  )
379  {
380  parameter->PermanentlyLock = 1;
381  }
382  else if (*localOptarg != NULL &&
383  ( (strcmp(*localOptarg, "-") == 0)
384  || (strcmp(*localOptarg, "no") == 0)
385  || (strcmp(*localOptarg, "false") == 0)
386  )
387  )
388  {
389  parameter->PermanentlyLock = 0;
390  }
391  else
392  {
393  fprintf(stderr, "you must specify 'yes' or 'no' for --lock\n");
394  error = TRUE;
395  }
396  break;
397 
398 #ifdef _X86_
399  case 'F':
400  if (Data->InstallParameter->ExecuteParameterGiven)
401  {
402  error = TRUE;
403  printf("Colliding parameters were given, aborting!");
404  hint();
405  }
406  else
407  {
408  Data->InstallParameter->ExecuteParameterGiven = TRUE;
409  parameter->ForceNt4 = TRUE;
410  //parameter->Remove = FALSE;
411  }
412  break;
413 #endif // #ifdef _X86_
414 
415  case 'l':
416  error = processNumber(*localOptarg, NULL, NULL, &parameter->Lpt);
417  break;
418 
419  case 'A':
420  if (parameter->AutomaticOrOnDemandStart)
421  {
422  fprintf(stderr, "--automatic and --on-demand cannot be specified at the same time!\n");
423  error = TRUE;
424  }
425  else
426  {
427  parameter->AutomaticStart = TRUE;
428  parameter->AutomaticOrOnDemandStart = TRUE;
429  }
430  break;
431 
432  case 'O':
433  if (parameter->AutomaticOrOnDemandStart)
434  {
435  fprintf(stderr, "--automatic and --on-demand cannot be specified at the same time!\n");
436  error = TRUE;
437  }
438  else
439  {
440  parameter->AutomaticStart = FALSE;
441  parameter->AutomaticOrOnDemandStart = TRUE;
442  }
443  break;
444 
445  case 1:
446  quitLocalProcessing = 1;
447  -- * Data->OptInd;
448  break;
449 
450  default:
451  fprintf(stderr, "error...\n");
452  error = TRUE;
453  hint();
454  break;
455  }
456  }
457  }
458 
459  } while (0);
460 
461  FUNC_LEAVE_UINT(error);
462 }
463 
470 BOOL CBMAPIDECL
472 {
473  BOOL error = TRUE;
474  char * driverLocation = NULL;
475 
476 
477  FUNC_ENTER();
478 
479  DBG_PRINT((DBG_PREFIX "-- xa1541.install" ));
480 
481  do {
482  cbm_install_parameter_plugin_t * pluginInstallParameter = Context;
483  xa1541_parameter_t *parameter;
484  driver_to_use_t driverToUse;
485 
486  if (pluginInstallParameter == NULL || pluginInstallParameter->OptionMemory == NULL) {
487  break;
488  }
489 
490  parameter = pluginInstallParameter->OptionMemory;
491 
492  //
493  // Find out which driver to use (cbm4wdm.sys, cbm4nt.sys)
494  //
495 
496 #ifdef _X86_
497  driverToUse = ((parameter->OsVersion > WINNT4) && ! parameter->ForceNt4) ? driver_cbm4wdm : driver_cbm4nt;
498 #else
499  driverToUse = driver_cbm4wdm;
500 #endif
501 
502  driverLocation = cbmlibmisc_strcat(
503  pluginInstallParameter->NeededFiles[driverToUse].FileLocationString,
504  pluginInstallParameter->NeededFiles[driverToUse].Filename);
505 
506  if (driverLocation == NULL) {
507  DBG_ERROR((DBG_PREFIX "Could not get the location of the driver file, aborting."));
508  fprintf(stderr, "Could not get the location of the driver file, aborting.\n");
509  break;
510  }
511 
512  printf("Using driver '%s'\n", driverLocation);
513 
514  error = CbmInstall(OPENCBM_DRIVERNAME, driverLocation, parameter->AutomaticStart);
515 
516  if (error) {
517  break;
518  }
519 
520  error = CbmCheckDriver();
521 
522  if (error) {
523  break;
524  }
525 
526  } while (0);
527 
528  cbmlibmisc_strfree(driverLocation);
529 
530  FUNC_LEAVE_BOOL(error);
531 }
532 
539 BOOL CBMAPIDECL
541 {
542  BOOL error = TRUE;
543 
544  FUNC_ENTER();
545 
546  DBG_PRINT((DBG_PREFIX "-- xa1541.uninstall" ));
547 
548  do {
549  cbm_install_parameter_plugin_t * pluginInstallParameter = Context;
550  xa1541_parameter_t *parameter;
551 
552  if (pluginInstallParameter == NULL || pluginInstallParameter->OptionMemory == NULL) {
553  break;
554  }
555 
556  parameter = pluginInstallParameter->OptionMemory;
557 
558 
560  {
561  printf("No driver installed, cannot remove.\n");
562  error = FALSE;
563  break;
564  }
565 
566  printf("REMOVING driver...\n");
567 
569 
570  error = FALSE;
571 
572  } while (0);
573 
574  FUNC_LEAVE_BOOL(error);
575 }
576 
585 unsigned int CBMAPIDECL
586 opencbm_plugin_install_get_needed_files(CbmPluginInstallProcessCommandlineData_t * Data, opencbm_plugin_install_neededfiles_t * Destination)
587 {
588  unsigned int size = sizeof(NeededFilesXA1541);
589  xa1541_parameter_t *parameter = Data->OptionMemory;
590 
591  FUNC_ENTER();
592 
593  do {
594  if (NULL == Destination) {
595  break;
596  }
597 
598  memcpy(Destination, NeededFilesXA1541, size);
599 
600  } while (0);
601 
602  FUNC_LEAVE_UINT(size);
603 }
driver_to_use_e
use WDM driver or NT4 driver
struct cbm_install_parameter_plugin_s cbm_install_parameter_plugin_t
Definition: instcbm.h:27
struct xa1541_parameter_s xa1541_parameter_t
The parameter which are given on the command-line.
BOOL CbmCheckPresence(IN LPCTSTR DriverName)
Check for the presence of the driver.
Definition: service.c:510
Define makros for debugging purposes.
enum driver_to_use_e driver_to_use_t
use WDM driver or NT4 driver
struct CbmPluginInstallProcessCommandlineData_s CbmPluginInstallProcessCommandlineData_t
Definition: instcbm.h:25
#define CBMAPIDECL
Definition: opencbm.h:85
void cbmlibmisc_strfree(const char *String)
Free a string.
Definition: libstring.c:172
enum iec_cabletype IEC_CABLETYPE
#define OPENCBM_DRIVERNAME
Definition: cbmioctl.h:59
BOOL CBMAPIDECL opencbm_plugin_install_do_uninstall(void *Context)
@@@
Define the IOCTL codes for the opencbm driver.
BOOL CbmRemove(IN LPCTSTR DriverName)
Remove the driver.
Definition: service.c:437
#define FUNC_LEAVE_UINT(_xxx)
Definition: debug.h:360
Definition: getopt.h:94
unsigned int CBMAPIDECL opencbm_plugin_install_get_needed_files(CbmPluginInstallProcessCommandlineData_t *Data, opencbm_plugin_install_neededfiles_t *Destination)
@@@
#define DBG_ASSERT(_xxx)
Definition: debug.h:401
#define FUNC_LEAVE_BOOL(_xxx)
Definition: debug.h:354
char * cbmlibmisc_strcat(const char *First, const char *Second)
Concatenate two strings.
Definition: libstring.c:202
unsigned int CBMAPIDECL opencbm_plugin_install_process_commandline(CbmPluginInstallProcessCommandlineData_t *Data)
@@@
#define DBG_ERROR(_xxx)
Definition: debug.h:397
Defining OpenCBM version.
#define FUNC_ENTER()
Definition: debug.h:347
#define DBG_PREFIX
Definition: debug.h:320
BOOL CbmInstall(IN LPCTSTR DriverName, IN LPCTSTR ServiceExe, IN BOOL AutomaticStart)
Install the driver.
Definition: service.c:294
int CbmCheckDriver(void)
Check for the correct installation.
Definition: startstop.c:465
BOOL CBMAPIDECL opencbm_plugin_install_do_install(void *Context)
@@@
Internal API for opencbm installation.
Some functions for string handling.
The parameter which are given on the command-line.
#define DBG_PRINT(_xxx)
Definition: debug.h:403