OpenCBM
instcbm.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, 2009 Spiro Trikaliotis
8  * Additions Copyright 2013 Arnd Menge
9  *
10  */
11 
21 #include <windows.h>
22 #include <stdio.h>
23 #include <stdlib.h>
24 #include <direct.h>
25 
26 #include "arch.h"
27 #include "cbmioctl.h"
28 #include "i_opencbm.h"
29 #include "libmisc.h"
30 #include "opencbm-plugin.h"
31 #include "opencbm-plugin-install.h"
32 #include "version.h"
33 
34 #include <getopt.h>
35 
37 #define DBG_USERMODE
38 
40 #define DBG_PROGNAME "INSTCBM.EXE"
41 
43 #define DBG_IS_DEBUG_C
44 
46 #define KERNEL32_DLL "kernel32.dll"
47 #define KERNEL32API_GetNativeSystemInfo "GetNativeSystemInfo"
48 typedef void (WINAPI* PGetNativeSystemInfo)(LPSYSTEM_INFO);
49 
50 #include "debug.h"
51 
52 #include "instcbm.h"
53 
54 // defines for older DDKs
55 #ifndef VER_SUITE_WH_SERVER
56 #define VER_SUITE_WH_SERVER 0x00008000
57 #endif
58 
59 #ifndef SM_SERVERR2
60 #define SM_SERVERR2 89
61 #endif
62 
63 #ifndef VER_SUITE_STORAGE_SERVER
64 #define VER_SUITE_STORAGE_SERVER 0x00002000
65 #endif
66 
67 static BOOL
68 SelfInitGenericOpenCBM(HMODULE OpenCbmDllHandle, const char * DefaultPluginname, BOOL NoCopy);
69 
83 static BOOL
84 NeededAccessRights(VOID)
85 {
86  SC_HANDLE scManager;
87 
88  FUNC_ENTER();
89 
90  // Check if we have arbitrary execute rights.
91  // For this, open the service control manager
92 
93  scManager = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);
94 
95  if (scManager)
96  {
97  CloseServiceHandle(scManager);
98  }
99 
100  FUNC_LEAVE_BOOL(scManager ? TRUE : FALSE);
101 }
102 
112 void GetProcessorArchitecture(WORD wProcessorArchitecture, char szOS[])
113 {
114  if (wProcessorArchitecture == PROCESSOR_ARCHITECTURE_IA64)
115  strcat(szOS, TEXT(" IA64"));
116  else if (wProcessorArchitecture == PROCESSOR_ARCHITECTURE_AMD64)
117  strcat(szOS, TEXT(" x64"));
118  else if (wProcessorArchitecture == PROCESSOR_ARCHITECTURE_INTEL)
119  strcat(szOS, TEXT(" x86"));
120  else
121  strcat(szOS, TEXT(" (?)"));
122 }
123 
132 static osversion_t
133 GetOsVersion(VOID)
134 {
135  SYSTEM_INFO si;
136  OSVERSIONINFOEX ovi;
137  OSVERSIONINFOEXW osvi = { sizeof(osvi), 0, 0, 0, 0, {0}, 0, 0 };
138  osversion_t retValue;
139  char szOS[1024] = {0};
140  PGetNativeSystemInfo pGetNativeSystemInfo;
141  ULONGLONG ConditionMask;
142  BOOL isServer;
143 
144  FUNC_ENTER();
145 
146  // If we do not find anything, it will be an unsupported OS version
147 
148  retValue = WINUNSUPPORTED;
149 
150  ZeroMemory(&si, sizeof(SYSTEM_INFO));
151  ZeroMemory(&ovi, sizeof(OSVERSIONINFOEX));
152 
153  pGetNativeSystemInfo = (PGetNativeSystemInfo) GetProcAddress(GetModuleHandle(KERNEL32_DLL), KERNEL32API_GetNativeSystemInfo);
154  if (pGetNativeSystemInfo != NULL)
155  pGetNativeSystemInfo(&si);
156  else
157  GetSystemInfo(&si);
158 
159  ovi.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX);
160 
161  // Check out the operating system version
162 
163  if (GetVersionEx((OSVERSIONINFO*)&ovi))
164  {
165  DBGDO(char *platform = "";)
166 
167  strcpy(szOS, TEXT("Microsoft "));
168 
169  switch (ovi.dwPlatformId)
170  {
171  case VER_PLATFORM_WIN32s:
172  DBGDO(platform = "WIN32s (huh?)";)
173  break;
174 
175  case VER_PLATFORM_WIN32_WINDOWS:
176  DBGDO(platform = "Win 95/98/Me";)
177  break;
178 
179  case VER_PLATFORM_WIN32_NT:
180  DBGDO(platform = "Win NT/2K/XP";)
181 
182  switch (ovi.dwMajorVersion)
183  {
184  case 0: case 1: case 2: /* SHOULD NOT OCCUR AT ALL! */
185  /* unsupported */
186  retValue = WINUNSUPPORTED;
187  DBG_PRINT((DBG_PREFIX "Running on NT %u.%02u, that is, *BEFORE* 3.x! "
188  "Something is going wrong here...",
189  ovi.dwMajorVersion, ovi.dwMinorVersion));
190  fprintf(stderr, "You're using Windows NT %u.%02u. THESE VERSIONS SHOULD NOT EXIST!\n",
191  ovi.dwMajorVersion, ovi.dwMinorVersion);
192  break;
193 
194  case 3:
195  /* NT 3.x versions are untested */
196  retValue = WINNT3;
197  DBG_PRINT((DBG_PREFIX "Running on NT 3.x!"));
198  printf("You're using Windows NT 3.%02u. These versions are untested, but they might work.\n"
199  "If it works for you, I would be very happy if you contact me and tell me!\n",
200  ovi.dwMinorVersion);
201  break;
202 
203  case 4:
204  retValue = WINNT4;
205  break;
206 
207  case 5:
208  switch (ovi.dwMinorVersion)
209  {
210  case 0:
211  strcat(szOS, TEXT("Windows 2000"));
212  if (ovi.wProductType != VER_NT_WORKSTATION)
213  strcat(szOS, TEXT(" Server"));
214  GetProcessorArchitecture(si.wProcessorArchitecture, szOS);
215  retValue = WIN2000;
216  break;
217  case 1:
218  strcat(szOS, TEXT("Windows XP"));
219  GetProcessorArchitecture(si.wProcessorArchitecture, szOS);
220  retValue = WINXP;
221  break;
222  case 2:
223  if (GetSystemMetrics(SM_SERVERR2))
224  strcat(szOS, TEXT("Windows Server 2003 R2"));
225  else if (ovi.wSuiteMask & VER_SUITE_STORAGE_SERVER)
226  strcat(szOS, TEXT("Windows Storage Server 2003"));
227  else if (ovi.wSuiteMask & VER_SUITE_WH_SERVER)
228  strcat(szOS, TEXT("Windows Home Server"));
229  else if (ovi.wProductType == VER_NT_WORKSTATION && (si.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_AMD64))
230  strcat(szOS, TEXT("Windows XP Professional x64"));
231  else
232  strcat(szOS, TEXT("Windows Server 2003"));
233 
234  if (ovi.wProductType != VER_NT_WORKSTATION)
235  GetProcessorArchitecture(si.wProcessorArchitecture, szOS);
236 
237  retValue = WINXP; // Set to WINXP for now.
238  break;
239  default:
240  retValue = WINNEWER;
241  }
242  break;
243 
244  case 6:
245  if ((ovi.dwMinorVersion == 0) || (ovi.dwMinorVersion == 1) || (ovi.dwMinorVersion == 2))
246  {
247  if (ovi.dwMinorVersion == 0)
248  {
249  if (ovi.wProductType == VER_NT_WORKSTATION)
250  strcat(szOS, TEXT("Windows Vista"));
251  else
252  strcat(szOS, TEXT("Windows Server 2008"));
253  retValue = WINVISTA;
254  }
255  else if (ovi.dwMinorVersion == 1)
256  {
257  if (ovi.wProductType == VER_NT_WORKSTATION)
258  strcat(szOS, TEXT("Windows 7"));
259  else
260  strcat(szOS, TEXT("Windows Server 2008 R2"));
261  retValue = WIN7;
262  }
263  else if (ovi.dwMinorVersion == 2)
264  {
265 #if _MSC_VER <= 1200
266  /*
267  * as MSVC6 does not know about the functions
268  * VerifyVersionInfo() and VerSetConditionMask(), skip this test
269  */
270  ConditionMask = 0;
271  isServer = FALSE;
272  retValue = WINNEWER;
273 #else
274  osvi.wProductType = VER_NT_WORKSTATION;
275  ConditionMask = VerSetConditionMask( 0, VER_PRODUCT_TYPE, VER_EQUAL );
276  isServer = !VerifyVersionInfoW(&osvi, VER_PRODUCT_TYPE, ConditionMask);
277 
278  osvi.dwMajorVersion = 6;
279  osvi.dwMinorVersion = 3;
280  osvi.dwBuildNumber = 9600;
281 
282  ConditionMask = VerSetConditionMask(
283  VerSetConditionMask(
284  VerSetConditionMask(0, VER_MAJORVERSION, VER_EQUAL),
285  VER_MINORVERSION, VER_EQUAL),
286  VER_BUILDNUMBER, VER_EQUAL);
287 
288  if (VerifyVersionInfoW(&osvi, VER_MAJORVERSION | VER_MINORVERSION | VER_BUILDNUMBER, ConditionMask))
289  {
290  if (!isServer)
291  strcat(szOS, TEXT("Windows 8.1"));
292  else
293  strcat(szOS, TEXT("Windows Server 2012 R2"));
294 
295  retValue = WIN8_1;
296  }
297 
298  if (retValue == WINUNSUPPORTED)
299  {
300  if (!isServer)
301  strcat(szOS, TEXT("Windows 8"));
302  else
303  strcat(szOS, TEXT("Windows Server 2012"));
304 
305  retValue = WIN8;
306  }
307 #endif
308  }
309 
310  GetProcessorArchitecture(si.wProcessorArchitecture, szOS);
311  break;
312  }
313 
314  /* else */
315  /* FALL THROUGH */
316 
317  default:
318  // This is a version of Windows we do not know; anyway, since
319  // it is NT based, and it's major version is >= 7, we support it
320  // anyway!
321 
322  retValue = WINNEWER;
323 
324  DBG_PRINT((DBG_PREFIX "Running on NT %u.%02u.",
325  ovi.dwMajorVersion, ovi.dwMinorVersion));
326  fprintf(stderr, "You're using Windows NT %u.%02u.\n"
327  "I do not know it, but OpenCBM should work, anyway.\n",
328  ovi.dwMajorVersion, ovi.dwMinorVersion);
329  break;
330  }
331  break;
332 
333  default:
334  DBGDO(platform = "unknown (huh?)";)
335  break;
336  }
337 
338  DBG_SUCCESS((DBG_PREFIX "OS VERSION: %u.%u.%u %s (%s)",
339  ovi.dwMajorVersion, ovi.dwMinorVersion, ovi.dwBuildNumber,
340  platform, ovi.szCSDVersion));
341 
342 // printf("OS: %s %s\n", szOS, NeededAccessRights() ? "[admin]" : "[no admin rights]");
343 
344  }
345 
346  FUNC_LEAVE_TYPE(retValue, osversion_t, "%u");
347 }
348 
350 static VOID
351 version(VOID)
352 {
353  FUNC_ENTER();
354 
355  printf("instcbm Version " OPENCBM_VERSION ", built on " __DATE__ " at " __TIME__ "\n");
356 
357  FUNC_LEAVE();
358 }
359 
361 static VOID
362 usage(VOID)
363 {
364  FUNC_ENTER();
365 
366  version();
367 
368  printf("\nUsage: instcbm [options] pluginname [plugin-options] [pluginname [plugin-options] ...]\n"
369  "Install OpenCBM and one or more plugins on the system, or remove it.\n"
370  "\n"
371  "pluginname is the name of the plugin to install. Any subsequent option is\n"
372  "passed to the plugin, and it will have a different meaning! See the\n"
373  "description of each plugin for details.\n"
374  "\n"
375  "Options:\n"
376  " -h, --help display this help and exit\n"
377  " -V, --version display version information about OpenCBM\n"
378  " -r, --remove remove (uninstall) OpenCBM or a plugin\n"
379  " -u, --update update parameters if driver is already installed.\n"
380  " -c, --check only check if the installation is ok\n"
381  " -n, --nocopy do not copy the driver files into the system directory\n"
382  "\n");
383  FUNC_LEAVE();
384 }
385 
387 static VOID
388 hint(const char *s)
389 {
390  fprintf(stderr, "Try `%s' --help for more information.\n", s);
391 }
392 
424 static BOOL
425 processNumber(const PCHAR Argument, PCHAR *NextChar, PBOOL ParameterGiven, PULONG ParameterValue)
426 {
427  PCHAR p;
428  BOOL error;
429  int base;
430 
431  FUNC_ENTER();
432 
433  DBG_ASSERT(ParameterValue != NULL);
434 
435  error = FALSE;
436  p = Argument;
437 
438  if (p)
439  {
440  // Find out which base to use (0***, 0x***, or anything else)
441 
442  switch (*p)
443  {
444  case 0:
445  error = TRUE;
446  break;
447 
448  case '0':
449  switch (*++p)
450  {
451  case 'x': case 'X':
452  base = 16;
453  ++p;
454  break;
455 
456  default:
457  base = 8;
458  break;
459  };
460  break;
461 
462  default:
463  base = 10;
464  break;
465  }
466 
467  // Convert the value
468 
469  if (!error)
470  {
471  *ParameterValue = strtoul(p, &p, base);
472 
473  if (NextChar)
474  {
475  error = ((*p != 0) && (*p != ',')) ? TRUE : FALSE;
476  }
477  else
478  {
479  error = *p != 0 ? TRUE : FALSE;
480  }
481 
482  if (!error)
483  {
484  if (NextChar != NULL)
485  {
486  *NextChar = p + ((*p) ? 1 : 0);
487  }
488 
489  if (ParameterGiven != NULL)
490  {
491  *ParameterGiven = TRUE;
492  }
493  }
494  }
495  }
496 
497  FUNC_LEAVE_BOOL(error);
498 }
499 
521 static BOOL
522 enforceOnlyOneExecutingCommand(cbm_install_parameter_t *Parameter, const char *ExecutableName)
523 {
524  BOOL error = FALSE;
525 
526  FUNC_ENTER();
527 
528  if (Parameter->ExecuteParameterGiven)
529  {
530  error = TRUE;
531  printf("Colliding parameters were given, aborting!");
532  hint(ExecutableName);
533  }
534  Parameter->ExecuteParameterGiven = TRUE;
535 
536  FUNC_LEAVE_BOOL(error);
537 }
538 
539 /* ------------------------------------------------------------------------------------- */
540 
558 static BOOL
559 processargs(int Argc, char **Argv, cbm_install_parameter_t *Parameter)
560 {
561  BOOL error;
562  int option;
563 
564  struct option longopts[] =
565  {
566  { "help", no_argument, NULL, 'h' },
567  { "version", no_argument, NULL, 'V' },
568  { "remove", no_argument, NULL, 'r' },
569  { "purge", no_argument, NULL, 'p' },
570  { "update", no_argument, NULL, 'u' },
571  { "check", no_argument, NULL, 'c' },
572  { "nocopy", no_argument, NULL, 'n' },
573  { "adapter", required_argument, NULL, '@' },
574 #if DBG
575  { "debugflags", required_argument, NULL, 'D' },
576  { "buffer", no_argument, NULL, 'B' },
577 #endif // #if DBG
578  { NULL, 0, NULL, 0 }
579  };
580 
581  const char shortopts[] = "-hVrpucn@:"
582 
583 #if DBG
584  "D:B"
585 #endif // #if DBG
586  ;
587 
588  BOOL quitGlobalProcessing = FALSE;
589 
590  FUNC_ENTER();
591 
592  error = FALSE;
593 
594  Parameter->Install = TRUE;
595 
596 
597  DBG_ASSERT(Parameter);
598 
599  while ( ! quitGlobalProcessing && (option = getopt_long(Argc, Argv, shortopts, longopts, NULL)) != -1)
600  {
601  switch (option)
602  {
603  case 'h':
604  usage();
605  Parameter->NoExecute = TRUE;
606  Parameter->Install = FALSE;
607  break;
608 
609  case 'V':
610  version();
611  Parameter->NoExecute = TRUE;
612  Parameter->Install = FALSE;
613  break;
614 
615  case 'r':
616  error = enforceOnlyOneExecutingCommand(Parameter, Argv[0]) || error;
617  Parameter->Remove = TRUE;
618  Parameter->Install = FALSE;
619  break;
620 
621  case 'p':
622  if (Parameter->Remove) {
623  Parameter->Purge = TRUE;
624  }
625  else {
626  error = TRUE;
627  printf("--purge only allowed after --remove, aborting!");
628  hint(Argv[0]);
629  }
630  break;
631 
632  case 'u':
633  Parameter->Update = TRUE;
634  Parameter->Install = FALSE;
635  break;
636 
637  case 'c':
638  Parameter->CheckInstall = TRUE;
639  Parameter->Install = FALSE;
640  break;
641 
642  case 'n':
643  Parameter->NoCopy = TRUE;
644  break;
645 
646  case '@': /* choose adapter */
647  if (Parameter->DefaultAdapter == NULL) {
648  Parameter->DefaultAdapter = cbmlibmisc_strdup(optarg);
649  }
650  else {
651  printf("--adapter/-@ given more than once.");
652  hint(Argv[0]);
653  exit(1);
654  }
655  break;
656 #if DBG
657  case 'D':
658  {
659  PCHAR next;
660 
661  error = processNumber(optarg, &next, &Parameter->DebugFlagsDriverWereGiven,
662  &Parameter->DebugFlagsDriver);
663 
664  if (!error && next && *next)
665  {
666  error = processNumber(next, &next, &Parameter->DebugFlagsDllWereGiven,
667  &Parameter->DebugFlagsDll);
668  }
669 
670  if (!error && next && *next)
671  {
672  error = processNumber(next, NULL, &Parameter->DebugFlagsInstallWereGiven,
673  &Parameter->DebugFlagsInstall);
674 
675  if (!error && Parameter->DebugFlagsInstallWereGiven)
676  {
677  DbgFlags = Parameter->DebugFlagsInstall;
678  }
679  }
680  DBG_PRINT((DBG_PREFIX "error = %s, 1st = %08x (%s), 2nd = %08x (%s), 3rd = %08x (%s)",
681  error ? "TRUE" : "FALSE",
682  Parameter->DebugFlagsDriver, Parameter->DebugFlagsDriverWereGiven ? "TRUE" : "FALSE",
683  Parameter->DebugFlagsDll, Parameter->DebugFlagsDllWereGiven ? "TRUE" : "FALSE",
684  Parameter->DebugFlagsInstall, Parameter->DebugFlagsInstallWereGiven ? "TRUE" : "FALSE"));
685  }
686  break;
687 
688  case 'B':
689  Parameter->OutputDebuggingBuffer = TRUE;
690  Parameter->NoExecute = TRUE;
691  Parameter->Install = FALSE;
692  break;
693 
694 #endif // #if DBG
695 
696  case 1: /* This is not a parameter, thus, it is the name of the plugin to process */
697  quitGlobalProcessing = TRUE;
698  --optind;
699  break;
700 
701  default:
702  error = TRUE;
703  hint(Argv[0]);
704  break;
705  }
706  }
707 
708 
709  while (! error && Argv[optind++]) {
710  error = error || ProcessPluginCommandlineAndAddIt(Parameter, Argv[optind - 1], Argc, Argv);
711  }
712 
713  if (Parameter->PluginList == NULL && ! error) {
714 
715  Parameter->NoExplicitPluginGiven = TRUE;
716 
717  if (Parameter->Install) {
718  printf("ERROR: No plugin given.\n\n"
719  "Since version 0.5.0 of OpenCBM, instcbm supports different plugins\n"
720  "that correspond to different cables, connected via parallel port\n"
721  "or via USB.\n\n"
722  "As instcbm cannot guess which cable are available, you have to\n"
723  "specifiy which plugin (='cable support software') you want to use.\n"
724  "\n"
725  "You have to specify it on the command-line.\n\n"
726  "Available options are:\n"
727  "\txa1541\tfor XA1541, XM1541, XAP1541 and XMP1541 cables (parallel port).\n"
728  "\txu1541\tfor XU1541 cable (cheap USB solution, with restrictions)\n"
729  "\txum1541\tfor XUM1541 cable (include ZoomFloppy).\n"
730  "\n"
731  "If you are upgrading from OpenCBM 0.4.2 or earlier, with the same cable\n"
732  "as before, you most probably want to use the command line:\n\tinstcbm xa1541\n"
733  "\n"
734  "If you have the ZoomFloppy, you most probably want the command line\n"
735  "\tinstcbm xum1541\n"
736  );
737  error = 1;
738  /* error = get_all_plugins(Parameter); */
739  }
740  else {
741  error = get_all_installed_plugins(Parameter);
742  }
743  }
744 
745  if (!error && Parameter->DefaultAdapter && ! Parameter->Update && ! Parameter->Install ) {
746  printf("--adapter/-@ only allowed when installing or updating, aborting!");
747  hint(Argv[0]);
748  error = 1;
749  }
750 
751  if (!error && !Parameter->PluginList) {
752  printf("No plugins detected, have to abort...\n");
753  error = 1;
754  }
755 
756  if (!error && Parameter->Install && ! Parameter->DefaultAdapter && Parameter->PluginList->Name) {
757  /* generate a default adapter: The first one given */
758  Parameter->DefaultAdapter = cbmlibmisc_strdup(Parameter->PluginList->Name);
759  }
760 
767  FUNC_LEAVE_BOOL(error);
768 }
769 
789 static int
790 CopyFileToNewPath(const char *SourcePath, const char *DestPath, const char *Filename)
791 {
792  char *sourceFile = NULL;
793  char *destFile = NULL;
794  int error = 0;
795 
796  FUNC_ENTER();
797 
798  sourceFile = cbmlibmisc_strcat(SourcePath, Filename);
799  destFile = cbmlibmisc_strcat(DestPath, Filename);
800 
801  if (sourceFile && destFile)
802  {
803  DBG_PRINT((DBG_PREFIX "Copying '%s' to '%s'", sourceFile, destFile));
804 
805  printf("Copying '%s' to '%s'", sourceFile, destFile);
806  if (!CopyFile(sourceFile, destFile, FALSE))
807  {
808  error = 1;
809  DBG_PRINT((DBG_PREFIX "--> FAILED!" ));
810  printf(" FAILED!\n");
811  }
812  else
813  {
814  printf("\n");
815  }
816  }
817  else
818  {
819  DBG_ERROR((DBG_PREFIX "Error allocating memory buffers for copying '%s'!", Filename));
820  fprintf(stderr, "Error allocating memory buffers for copying '%s'.\n", Filename);
821  }
822 
823  if (sourceFile) {
824  cbmlibmisc_strfree(sourceFile);
825  }
826 
827  if (destFile) {
828  cbmlibmisc_strfree(destFile);
829  }
830 
831  FUNC_LEAVE_INT(error);
832 }
833 
844 static char *
845 GetWorkingDirectory(void)
846 {
847  char * tmpPathString;
848  unsigned int stringLength;
849  BOOL error = TRUE;
850 
851  FUNC_ENTER();
852 
853  do {
854 
855  //
856  // determine the length of the string
857  //
858 
859  stringLength = GetCurrentDirectory(0, NULL);
860 
861  //
862  // Allocate memory for the working directory
863  //
864 
865  tmpPathString = cbmlibmisc_stralloc(stringLength + 1);
866 
867  if (tmpPathString == NULL)
868  {
869  break;
870  }
871 
872  //
873  // determine the working directory
874  //
875 
876  if (GetCurrentDirectory(stringLength, tmpPathString) == 0)
877  {
878  DBG_PRINT((DBG_PREFIX "Could not determine the current working directory!"));
879  printf("Could not determine the current working directory!\n");
880  break;
881  }
882 
883  DBG_ASSERT(strlen(tmpPathString) < stringLength);
884 
885  strcat(tmpPathString, "\\");
886 
887  error = FALSE;
888 
889  } while (0);
890 
891  if (error)
892  {
893  cbmlibmisc_strfree(tmpPathString);
894  tmpPathString = NULL;
895  }
896 
897  FUNC_LEAVE_STRING(tmpPathString);
898 }
899 
910 static char *
911 GetWindowsSystemDirectory(void)
912 {
913 #ifdef USE_FAKE_WIN_DIRECTORY_AS_COPY_TARGET
914  FUNC_LEAVE_STRING(cbmlibmisc_strdup(USE_FAKE_WIN_DIRECTORY_AS_COPY_TARGET "\\System32\\"));
915 #else
916  char * tmpPathString;
917  unsigned int stringLength;
918  BOOL error = TRUE;
919 
920  FUNC_ENTER();
921 
922  do {
923 
924  //
925  // determine the length of the string
926  //
927 
928  stringLength = GetSystemDirectory(NULL, 0);
929 
930  //
931  // Allocate memory for the system directory
932  //
933 
934  tmpPathString = cbmlibmisc_stralloc(stringLength + 1);
935 
936  if (tmpPathString == NULL)
937  {
938  break;
939  }
940 
941  //
942  // determine the system directory
943  //
944 
945  if (GetSystemDirectory(tmpPathString, stringLength) == 0)
946  {
947  DBG_PRINT((DBG_PREFIX "Could not determine the current windows system directory!"));
948  printf("Could not determine the current windows system directory!\n");
949  break;
950  }
951 
952  DBG_ASSERT(strlen(tmpPathString) < stringLength);
953 
954  strcat(tmpPathString, "\\");
955 
956  error = FALSE;
957 
958  } while (0);
959 
960  if (error)
961  {
962  cbmlibmisc_strfree(tmpPathString);
963  tmpPathString = NULL;
964  }
965 
966  FUNC_LEAVE_STRING(tmpPathString);
967 #endif
968 }
969 
980 static char *
981 GetWindowsDriverDirectory(void)
982 {
983  char * tmpPathString = NULL;
984  char * driverPathString = NULL;
985 
986  FUNC_ENTER();
987 
988  do {
989  tmpPathString = GetWindowsSystemDirectory();
990  if (tmpPathString == NULL) {
991  break;
992  }
993 
994  driverPathString = cbmlibmisc_strcat(tmpPathString, "DRIVERS\\");
995  } while (0);
996 
997  cbmlibmisc_strfree(tmpPathString);
998 
999  FUNC_LEAVE_STRING(driverPathString);
1000 }
1001 
1014 static int
1015 UpdateOpenCBM(cbm_install_parameter_t *Parameter)
1016 {
1017  int error = 0;
1018  HMODULE openCbmDllHandle = NULL;
1019 
1020  FUNC_ENTER();
1021 
1022  do {
1023  openCbmDllHandle = LoadLocalOpenCBMDll();
1024  if (openCbmDllHandle == NULL) {
1025  DBG_PRINT((DBG_PREFIX "Could not open the OpenCBM DLL."));
1026  fprintf(stderr, "Could not open the OpenCBM DLL.");
1027  break;
1028  }
1029 
1030  error = SelfInitGenericOpenCBM(openCbmDllHandle,
1031  Parameter->DefaultAdapter,
1032  Parameter->NoCopy);
1033  if (error) {
1034  break;
1035  }
1036 
1037  } while (0);
1038 
1039  if (openCbmDllHandle) {
1040  FreeLibrary(openCbmDllHandle);
1041  }
1042 
1043  FUNC_LEAVE_INT(error);
1044 }
1045 
1047 static opencbm_plugin_install_neededfiles_t NeededFilesGeneric[] =
1048 {
1049  { SYSTEM_DIR, "opencbm.dll" },
1050 #ifdef _X86_
1051  { SYSTEM_DIR, "opencbmvdd.dll" },
1052 #endif // #ifdef _X86_
1053  { LIST_END, "" }
1054 };
1055 
1081 static char *
1082 GetPathForNeededFile(opencbm_plugin_install_neededfiles_t * NeededFile, const char * PluginName, const char * WorkingDirectory, const char * SystemDirectory, const char * DriverDirectory)
1083 {
1084  char * filepath = NULL;
1085 
1086  FUNC_ENTER();
1087 
1088  do {
1089  /* if we already have a copy of the path, use that */
1090 
1091  if (NeededFile->FileLocationString != NULL) {
1092  filepath = cbmlibmisc_strdup(NeededFile->FileLocationString);
1093  break;
1094  }
1095 
1096  switch (NeededFile->FileLocation)
1097  {
1098  case LOCAL_PLUGIN_DIR:
1099  if (NULL != PluginName) {
1100  filepath = cbmlibmisc_strcat(WorkingDirectory, PluginName);
1101  }
1102  break;
1103 
1104  case LOCAL_DIR:
1105  filepath = cbmlibmisc_strdup(WorkingDirectory);
1106  break;
1107 
1108  case SYSTEM_DIR:
1109  filepath = cbmlibmisc_strdup(SystemDirectory);
1110  break;
1111 
1112  case DRIVER_DIR:
1113  filepath = cbmlibmisc_strdup(DriverDirectory);
1114  break;
1115 
1116  default:
1117  DBG_ASSERT(("wrong enum in neededfiles array!", 0));
1118  break;
1119  }
1120 
1121  if (filepath == NULL)
1122  {
1123  DBG_ASSERT(("internal error on building file path!", 0));
1124  }
1125 
1126  /* take a copy of the path so we can refer to it later */
1127 
1128  NeededFile->FileLocationString = cbmlibmisc_strdup(filepath);
1129 
1130  } while (0);
1131 
1132  FUNC_LEAVE_STRING(filepath);
1133 }
1134 
1159 static char *
1160 GetFilenameForNeededFile(opencbm_plugin_install_neededfiles_t * NeededFile, const char * PluginName, const char * WorkingDirectory, const char * SystemDirectory, const char * DriverDirectory)
1161 {
1162  char * filename = NULL;
1163  char * path = NULL;
1164 
1165  FUNC_ENTER();
1166 
1167  path = GetPathForNeededFile(NeededFile, PluginName, WorkingDirectory, SystemDirectory, DriverDirectory);
1168 
1169  if (NULL != path)
1170  {
1171  filename = cbmlibmisc_strcat(path, NeededFile->Filename);
1172  cbmlibmisc_strfree(path);
1173  }
1174 
1175  if (filename == NULL)
1176  {
1177  DBG_ASSERT(("internal error on building file name!", 0));
1178  }
1179 
1180  FUNC_LEAVE_STRING(filename);
1181 }
1182 
1193 static BOOL
1194 AreNeededFilesPresent(opencbm_plugin_install_neededfiles_t NeededFiles[])
1195 {
1196  BOOL isPresent = FALSE;
1197 
1198  char * workingDirectory = NULL;
1199  char * systemDirectory = NULL;
1200  char * driverDirectory = NULL;
1201 
1202  opencbm_plugin_install_neededfiles_t * neededfiles;
1203 
1204  DWORD fileattributes;
1205 
1206  FUNC_ENTER();
1207 
1208  do {
1209  workingDirectory = GetWorkingDirectory();
1210  systemDirectory = GetWindowsSystemDirectory();
1211  driverDirectory = GetWindowsDriverDirectory();
1212 
1213  if ( ! workingDirectory || ! systemDirectory || ! driverDirectory)
1214  break;
1215 
1216  printf("Working directory = '%s',\n"
1217  "system directory = '%s',\n"
1218  "driver directory = '%s'.\n",
1219  workingDirectory, systemDirectory, driverDirectory);
1220 
1221  //
1222  // Check if the necessary files all exist
1223  //
1224 
1225  isPresent = TRUE; // assume all files are available
1226 
1227  for (neededfiles = NeededFiles; neededfiles->FileLocation != LIST_END; neededfiles++)
1228  {
1229  char * filename;
1230 
1231  filename = GetFilenameForNeededFile(neededfiles, NULL, workingDirectory, systemDirectory, driverDirectory);
1232 
1233  fileattributes = GetFileAttributes(filename);
1234 
1235  /*
1236  * Yes, this constant 0xFFFFFFFF is defined for the function failing,
1237  * not ((DWORD)-1) as one might expect.
1238  * Thus, this most probably holds even for 64 bit platforms
1239  */
1240  if (fileattributes == 0xFFFFFFFF)
1241  {
1242  DBG_PRINT((DBG_PREFIX "File '%s' not found.", filename));
1243  isPresent = FALSE;
1244  }
1245 
1246  cbmlibmisc_strfree(filename);
1247  }
1248  } while (0);
1249 
1250  cbmlibmisc_strfree(workingDirectory);
1251  cbmlibmisc_strfree(systemDirectory);
1252  cbmlibmisc_strfree(driverDirectory);
1253 
1254  FUNC_LEAVE_BOOL(isPresent);
1255 }
1256 
1263 static BOOL
1264 IsPresentGenericOpenCBM(void)
1265 {
1266  FUNC_ENTER();
1267  FUNC_LEAVE_BOOL(AreNeededFilesPresent(NeededFilesGeneric));
1268 }
1269 
1281 typedef BOOL HandleNeededFilesCallback_t(const char * DestinationPath, const char * File);
1282 
1303 static BOOL
1304 HandleNeededFiles(opencbm_plugin_install_neededfiles_t NeededFiles[], const char ** PathToInstalledPluginFile, HandleNeededFilesCallback_t * Callback)
1305 {
1306  char * workingDirectory = NULL;
1307  char * systemDirectory = NULL;
1308  char * driverDirectory = NULL;
1309 
1310  char * destinationPath = NULL;
1311 
1312  BOOL error = FALSE;
1313 
1314  opencbm_plugin_install_neededfiles_t * neededfiles;
1315 
1316  FUNC_ENTER();
1317 
1318  if (PathToInstalledPluginFile != NULL)
1319  {
1320  *PathToInstalledPluginFile = NULL;
1321  }
1322 
1323  do
1324  {
1325  workingDirectory = GetWorkingDirectory();
1326  systemDirectory = GetWindowsSystemDirectory();
1327  driverDirectory = GetWindowsDriverDirectory();
1328 
1329  for (neededfiles = NeededFiles; (neededfiles->FileLocation != LIST_END) && ! error; neededfiles++)
1330  {
1331  destinationPath = GetPathForNeededFile(neededfiles, NULL, workingDirectory, systemDirectory, driverDirectory);
1332 
1333  error = Callback(destinationPath, neededfiles->Filename);
1334 
1335  if (PathToInstalledPluginFile && *PathToInstalledPluginFile == NULL) {
1336  *PathToInstalledPluginFile = cbmlibmisc_strcat(destinationPath, neededfiles->Filename);
1337  }
1338 
1339  cbmlibmisc_strfree(destinationPath);
1340 
1341  destinationPath = NULL;
1342 
1343  if (error)
1344  break;
1345  }
1346 
1347  if (error)
1348  break;
1349 
1350  } while (0);
1351 
1352 
1353  cbmlibmisc_strfree(workingDirectory);
1354  cbmlibmisc_strfree(systemDirectory);
1355  cbmlibmisc_strfree(driverDirectory);
1356 
1357  FUNC_LEAVE_BOOL(error);
1358 }
1359 
1371 static BOOL
1372 CopyNeededFilesCallback(const char * DestinationPath, const char * File)
1373 {
1374  FUNC_ENTER();
1375 
1376  FUNC_LEAVE_BOOL(CopyFileToNewPath(".\\", DestinationPath, File));
1377 }
1378 
1395 static BOOL
1396 CopyNeededFiles(opencbm_plugin_install_neededfiles_t NeededFiles[], const char ** PathToInstalledPluginFile)
1397 {
1398  FUNC_ENTER();
1399 
1400  FUNC_LEAVE_BOOL(HandleNeededFiles(NeededFiles, PathToInstalledPluginFile, CopyNeededFilesCallback));
1401 }
1402 
1409 static HMODULE
1410 LoadOpenCBMDll(BOOL AtSystemDirectory)
1411 {
1412  char * systemDirectory = NULL;
1413  char * dllPath = NULL;
1414  HMODULE dll = NULL;
1415 
1416  FUNC_ENTER();
1417 
1418  do {
1419  if (AtSystemDirectory) {
1420  /*
1421  * make sure to load the right DLL in the system directory
1422  */
1423 
1424  systemDirectory = GetWindowsSystemDirectory();
1425  }
1426  else {
1427  /*
1428  * make sure to load the local DLL
1429  */
1430 
1431  systemDirectory = cbmlibmisc_strdup("./");
1432  }
1433 
1434  if ( systemDirectory == NULL) {
1435  break;
1436  }
1437 
1438  dllPath = cbmlibmisc_strcat(systemDirectory, "opencbm.dll");
1439  if (dllPath == NULL) {
1440  break;
1441  }
1442 
1443  /* now, load the correct DLL ... */
1444 
1445  dll = LoadLibrary(dllPath);
1446  if (dll == NULL) {
1447  break;
1448  }
1449  } while (0);
1450 
1451  if (dllPath != NULL) {
1452  cbmlibmisc_strfree(dllPath);
1453  }
1454 
1455  if (systemDirectory != NULL) {
1456  cbmlibmisc_strfree(systemDirectory);
1457  }
1458 
1459  FUNC_LEAVE_HMODULE(dll);
1460 }
1461 
1466 static HMODULE
1467 LoadDestinationOpenCBMDll(void)
1468 {
1469  FUNC_ENTER();
1470 
1471  FUNC_LEAVE_HMODULE(LoadOpenCBMDll(TRUE));
1472 }
1473 
1478 HMODULE
1480 {
1481  FUNC_ENTER();
1482 
1483  FUNC_LEAVE_HMODULE(LoadOpenCBMDll(FALSE));
1484 }
1485 
1496 static BOOL
1497 SelfInitGenericOpenCBM(HMODULE OpenCbmDllHandle, const char * DefaultPluginname, BOOL NoCopy)
1498 {
1499  BOOL error = TRUE;
1500  opencbm_plugin_install_generic_t * opencbm_plugin_install_generic = NULL;
1501  unsigned int DefaultLocation;
1502 
1503  FUNC_ENTER();
1504 
1505  DefaultLocation = NoCopy ? INDEX_DEFAULT_FILENAME_LOCAL : INDEX_DEFAULT_FILENAME_WINDIR;
1506 
1507  do {
1508  /* ... get the address of opencbm_plugin_install_generic() ... */
1509 
1510  opencbm_plugin_install_generic = (void *) GetProcAddress(OpenCbmDllHandle,
1511  "opencbm_plugin_install_generic");
1512 
1513  if (opencbm_plugin_install_generic == NULL) {
1514  DBG_PRINT((DBG_PREFIX "Could not get address of "
1515  "opencbm.dll::opencbm_plugin_install_generic()."));
1516  fprintf(stderr, "Could not get address of "
1517  "opencbm.dll::opencbm_plugin_install_generic().\n");
1518  break;
1519  }
1520 
1521  /* ... and execute it */
1522  error = opencbm_plugin_install_generic(DefaultPluginname, DefaultLocation);
1523 
1524  } while (0);
1525 
1526  FUNC_LEAVE_BOOL(error);
1527 }
1528 
1537 static BOOL
1538 CopyGenericOpenCBM(HMODULE OpenCbmDllHandle, cbm_install_parameter_t *Parameter)
1539 {
1540  BOOL error = TRUE;
1541 
1542  FUNC_ENTER();
1543 
1544  do {
1545  error = CopyNeededFiles(NeededFilesGeneric, NULL);
1546  if (error) {
1547  break;
1548  }
1549 
1550  error = SelfInitGenericOpenCBM(OpenCbmDllHandle, NULL, Parameter->NoCopy);
1551  if (error) {
1552  break;
1553  }
1554 
1555  } while (0);
1556 
1557  FUNC_LEAVE_BOOL(error);
1558 }
1559 
1568 static HMODULE
1569 LoadPluginDll(const char * PluginName, const char * PathToPluginDllFile)
1570 {
1571  HMODULE pluginDll = NULL;
1572 
1573  UINT oldErrorMode;
1574 
1575  FUNC_ENTER();
1576 
1577  /*
1578  * Load the DLL. Make sure that we do not get a warning dialog
1579  * if a dependancy DLL is not found.
1580  */
1581 
1582  oldErrorMode = SetErrorMode(SEM_FAILCRITICALERRORS);
1583 
1584  pluginDll = LoadLibrary(PathToPluginDllFile);
1585 
1586  SetErrorMode(oldErrorMode);
1587 
1588  if (pluginDll == NULL) {
1589  fprintf(stderr, "Error loading plugin '%s' at '%s'.\n", PluginName, PathToPluginDllFile);
1590  DBG_ERROR((DBG_PREFIX "Error loading plugin '%s' at '%s'.", PluginName, PathToPluginDllFile));
1591  }
1592 
1593  FUNC_LEAVE_HMODULE(pluginDll);
1594 }
1595 
1600 static void
1601 FreePluginDll(HMODULE PluginDll)
1602 {
1603  FUNC_ENTER();
1604 
1605  FreeLibrary(PluginDll);
1606 
1607  FUNC_LEAVE();
1608 }
1609 
1618 static void *
1619 GetPluginFunctionAddress(HMODULE PluginDll, const char * FunctionName)
1620 {
1621  void * pointer;
1622 
1623  FUNC_ENTER();
1624 
1625  pointer = GetProcAddress(PluginDll, FunctionName);
1626 
1627  FUNC_LEAVE_PTR(pointer, void*);
1628 }
1629 
1644 static BOOL
1645 PluginExecuteFunction(const char * PluginName,
1646  const char * PathToPluginDllFile,
1647  const char * FunctionName,
1648  BOOL (*Callback)(const char * PluginName, void * FunctionPointer, void * Context),
1649  void * Context)
1650 {
1651  BOOL error = TRUE;
1652  HMODULE pluginDll = NULL;
1653 
1654  FUNC_ENTER();
1655 
1656  do {
1657  void * functionPointer = NULL;
1658 
1659  pluginDll = LoadPluginDll(PluginName, PathToPluginDllFile);
1660 
1661  if (pluginDll == NULL) {
1662  break;
1663  }
1664 
1665  functionPointer = GetPluginFunctionAddress(pluginDll, FunctionName);
1666 
1667  error = Callback(PluginName, functionPointer, Context);
1668 
1669  } while (0);
1670 
1671  if (pluginDll) {
1672  FreePluginDll(pluginDll);
1673  }
1674 
1675  FUNC_LEAVE_BOOL(error);
1676 }
1677 
1688 static BOOL
1689 perform_opencbm_plugin_install_do_install(const char * PluginName, void * FunctionPointer, void * Context)
1690 {
1691  opencbm_plugin_install_do_install_t * opencbm_plugin_install_do_install = FunctionPointer;
1692 
1693  BOOL error = TRUE;
1694 
1695  FUNC_ENTER();
1696 
1697  do {
1698  if (opencbm_plugin_install_do_install == NULL) {
1699  break;
1700  }
1701 
1702  error = opencbm_plugin_install_do_install(Context);
1703 
1704  if (error) {
1705  DBG_ERROR((DBG_PREFIX "Installation of plugin '%s' failed!", PluginName));
1706  fprintf(stderr, "Installation of plugin '%s' failed!\n", PluginName);
1707  break;
1708  }
1709 
1710  } while (0);
1711 
1712  FUNC_LEAVE_BOOL(error);
1713 }
1714 
1716 typedef
1721 
1730 static BOOL
1731 InstallPluginCallback(cbm_install_parameter_plugin_t * PluginInstallParameter, void * Context)
1732 {
1733  InstallPluginCallback_context_t * context = Context;
1734 
1735  BOOL error = TRUE;
1736 
1737  opencbm_plugin_install_plugin_data_t * opencbm_plugin_install_plugin_data = NULL;
1738 
1739  const char * pathToInstalledPluginFile = NULL;
1740 
1741 
1742  FUNC_ENTER();
1743 
1744  do {
1745  printf("++++ Install: '%s' with filename '%s'.\n", PluginInstallParameter->Name, PluginInstallParameter->FileName);
1746 
1747  if ( context->Parameter->NoCopy) {
1748  char * workingDirectory = GetWorkingDirectory();
1749 
1750  pathToInstalledPluginFile = cbmlibmisc_strcat(workingDirectory, PluginInstallParameter->FileName);
1751  cbmlibmisc_strfree(workingDirectory);
1752  }
1753  else {
1754  if ( CopyNeededFiles(PluginInstallParameter->NeededFiles, &pathToInstalledPluginFile) ) {
1755  break;
1756  }
1757  }
1758 
1759  if ( pathToInstalledPluginFile == NULL ) {
1760  break;
1761  }
1762 
1763  opencbm_plugin_install_plugin_data = (void *) GetProcAddress(context->OpenCbmDllHandle,
1764  "opencbm_plugin_install_plugin_data");
1765 
1766  if (opencbm_plugin_install_plugin_data == NULL) {
1767  DBG_PRINT((DBG_PREFIX "Could not get address of "
1768  "opencbm.dll::opencbm_plugin_install_plugin_data()"));
1769  fprintf(stderr, "Could not get address of "
1770  "opencbm.dll::opencbm_plugin_install_plugin_data()");
1771  break;
1772  }
1773 
1774  error = opencbm_plugin_install_plugin_data(PluginInstallParameter->Name, pathToInstalledPluginFile, PluginInstallParameter->OptionMemory);
1775 
1776  if (error) {
1777  break;
1778  }
1779 
1780  /*
1781  * Tell the plugin to self-init itself
1782  */
1783 
1784  error = PluginExecuteFunction(PluginInstallParameter->Name,
1785  pathToInstalledPluginFile,
1786  "opencbm_plugin_install_do_install",
1787  perform_opencbm_plugin_install_do_install,
1788  PluginInstallParameter);
1789 
1790  } while (0);
1791 
1792  cbmlibmisc_strfree(pathToInstalledPluginFile);
1793 
1794  FUNC_LEAVE_BOOL(error);
1795 }
1796 
1812 static int
1813 InstallOpenCBM(cbm_install_parameter_t *Parameter)
1814 {
1815  HMODULE openCbmDllHandle = NULL;
1816  int error = 1;
1817 
1818  FUNC_ENTER();
1819 
1820  do {
1821  InstallPluginCallback_context_t callbackContext;
1822 
1823  memset(&callbackContext, 0, sizeof(callbackContext));
1824 
1825  openCbmDllHandle = LoadLocalOpenCBMDll();
1826  if (openCbmDllHandle == NULL) {
1827  DBG_PRINT((DBG_PREFIX "Could not open the OpenCBM DLL."));
1828  fprintf(stderr, "Could not open the OpenCBM DLL.");
1829  break;
1830  }
1831 
1832  if ( Parameter->NoCopy ) {
1833  error = SelfInitGenericOpenCBM(openCbmDllHandle, NULL, Parameter->NoCopy);
1834  }
1835  else if ( ! IsPresentGenericOpenCBM() )
1836  {
1837  // install generic OpenCBM files
1838 
1839  if ( CopyGenericOpenCBM(openCbmDllHandle, Parameter) ) {
1840  break;
1841  }
1842  }
1843 
1844  callbackContext.OpenCbmDllHandle = openCbmDllHandle;
1845  callbackContext.Parameter = Parameter;
1846 
1847  error = PluginForAll(Parameter, InstallPluginCallback, &callbackContext);
1848 
1849  error = UpdateOpenCBM(Parameter) || error;
1850 
1851  } while (0);
1852 
1853  if (openCbmDllHandle) {
1854  FreeLibrary(openCbmDllHandle);
1855  }
1856 
1857  FUNC_LEAVE_INT(error);
1858 }
1859 
1872 static BOOL
1873 RemoveOpenCbmFilesCallback(const char * DestinationPath, const char * Filename)
1874 {
1875  char * fileToDelete = NULL;
1876  BOOL error = TRUE;
1877 
1878  FUNC_ENTER();
1879 
1880  do
1881  {
1882  fileToDelete = cbmlibmisc_strcat(DestinationPath, Filename);
1883 
1884  if (fileToDelete)
1885  {
1886  DBG_PRINT((DBG_PREFIX "Trying to delete '%s'.", fileToDelete));
1887 
1888  fprintf(stderr, "Trying to delete '%s'.\n", fileToDelete);
1889  DeleteFile(fileToDelete);
1890  error = 0;
1891  }
1892 
1893  } while (0);
1894 
1895  cbmlibmisc_strfree(fileToDelete);
1896 
1897  FUNC_LEAVE_BOOL(error);
1898 }
1899 
1906 static BOOL
1907 RemoveOpenCbmFiles(opencbm_plugin_install_neededfiles_t NeededFiles[])
1908 {
1909  FUNC_ENTER();
1910 
1911  FUNC_LEAVE_BOOL(HandleNeededFiles(NeededFiles, NULL, RemoveOpenCbmFilesCallback));
1912 }
1913 
1924 static BOOL
1925 perform_opencbm_plugin_install_do_uninstall(const char * PluginName, void * FunctionPointer, void * Context)
1926 {
1927  opencbm_plugin_install_do_uninstall_t * opencbm_plugin_install_do_uninstall = FunctionPointer;
1928 
1929  BOOL error = TRUE;
1930 
1931  FUNC_ENTER();
1932 
1933  do {
1934  if (opencbm_plugin_install_do_uninstall == NULL) {
1935  break;
1936  }
1937 
1938  error = opencbm_plugin_install_do_uninstall(Context);
1939 
1940  if (error) {
1941  DBG_ERROR((DBG_PREFIX "Uninstallation of plugin '%s' failed!", PluginName));
1942  fprintf(stderr, "Uninstallation of plugin '%s' failed!\n", PluginName);
1943  break;
1944  }
1945 
1946  } while (0);
1947 
1948  FUNC_LEAVE_BOOL(error);
1949 }
1950 
1959 static BOOL
1960 RemovePluginCallback(cbm_install_parameter_plugin_t * PluginInstallParameter, void * Context)
1961 {
1962  InstallPluginCallback_context_t * context = Context;
1963 
1964  BOOL error = TRUE;
1965 
1966  FUNC_ENTER();
1967 
1968  do {
1969  error = PluginExecuteFunction(PluginInstallParameter->Name,
1970  PluginInstallParameter->FileName,
1971  "opencbm_plugin_install_do_uninstall",
1972  perform_opencbm_plugin_install_do_uninstall,
1973  PluginInstallParameter);
1974 
1975  if (error) {
1976  break;
1977  }
1978 
1979  error = RemoveOpenCbmFiles(PluginInstallParameter->NeededFiles);
1980  if (error) {
1981  break;
1982  }
1983 
1984  } while (0);
1985 
1986  FUNC_LEAVE_BOOL(error);
1987 }
1988 
1989 
1996 static BOOL
1997 RemoveGenericOpenCBM(HMODULE OpenCbmDllHandle)
1998 {
1999  BOOL error = TRUE;
2000 
2001  FUNC_ENTER();
2002 
2003  do {
2004  error = RemoveOpenCbmFiles(NeededFilesGeneric);
2005  if (error) {
2006  break;
2007  }
2008 
2009  } while (0);
2010 
2011  FUNC_LEAVE_BOOL(error);
2012 }
2013 
2026 static int
2027 RemoveOpenCBM(cbm_install_parameter_t *Parameter)
2028 {
2029  HMODULE openCbmDllHandle = NULL;
2030  int error = 1;
2031 
2032  FUNC_ENTER();
2033 
2042  do {
2043  InstallPluginCallback_context_t callbackContext;
2044 
2045  memset(&callbackContext, 0, sizeof(callbackContext));
2046 
2047  openCbmDllHandle = LoadLocalOpenCBMDll();
2048  if (openCbmDllHandle == NULL) {
2049  DBG_PRINT((DBG_PREFIX "Could not open the OpenCBM DLL."));
2050  fprintf(stderr, "Could not open the OpenCBM DLL.");
2051  break;
2052  }
2053 
2054  if ( ! IsPresentGenericOpenCBM() ) {
2055  DBG_PRINT((DBG_PREFIX "trying to remove OpenCBM, but it is not installed!"));
2056  fprintf(stderr, "trying to remove OpenCBM, but it is not installed!\n");
2057  error = 0;
2058  break;
2059  }
2060 
2061  callbackContext.OpenCbmDllHandle = openCbmDllHandle;
2062  callbackContext.Parameter = Parameter;
2063 
2064  // Remove all plugins first
2065 
2066  error = PluginForAll(Parameter, RemovePluginCallback, &callbackContext);
2067 
2068  if (error) {
2069  break;
2070  }
2071 
2072  // remove generic OpenCBM files
2073 
2074  if ( RemoveGenericOpenCBM(openCbmDllHandle) ) {
2075  break;
2076  }
2077 
2078  error = 0;
2079 
2080  } while (0);
2081 
2082  if (openCbmDllHandle) {
2083  FreeLibrary(openCbmDllHandle);
2084  }
2085 
2086  FUNC_LEAVE_INT(error);
2087 }
2088 
2089 /*
2090  This function checks if the driver was correctly installed.
2091 
2092  \param Parameter
2093  Pointer to parameter_t struct which contains the
2094  description of the parameters given on the command-line.
2095 
2096  \param PluginNames
2097  Array of pointers to strings which holds the names of all plugins to process.
2098  This array has to be finished by a NULL pointer.
2099 
2100  \return
2101  Return value which will be given on return from main().
2102  That is, 0 on success, everything else indicates an error.
2103 */
2104 static int
2105 CheckOpenCBM(cbm_install_parameter_t *Parameter)
2106 {
2107  int success = 0;
2108 
2109  FUNC_ENTER();
2110 
2111  do {
2112 
2114 
2115  } while (0);
2116 
2117  FUNC_LEAVE_INT(success);
2118 }
2119 
2133 int __cdecl
2134 main(int Argc, char **Argv)
2135 {
2136  cbm_install_parameter_t parameter;
2137  int retValue = 0;
2138 
2139  FUNC_ENTER();
2140 
2141  /* initialize parameters */
2142 
2143  memset(&parameter, 0, sizeof(parameter));
2144  parameter.PluginList = NULL;
2145 
2146  do {
2147  parameter.OsVersion = GetOsVersion();
2148 
2149  if (parameter.OsVersion == WINUNSUPPORTED) {
2150  DBG_PRINT((DBG_PREFIX "This version of Windows is not supported!"));
2151  printf("Sorry, this version of Windows is not supported!\n");
2152  retValue = 2;
2153  break;
2154  }
2155 
2156  if (processargs(Argc, Argv, &parameter)) {
2157  DBG_PRINT((DBG_PREFIX "Error processing command line arguments."));
2158  fprintf(stderr, "Error processing command line arguments.\n");
2159  retValue = 1;
2160  break;
2161  }
2162 
2163  if (parameter.NoExecute) {
2164  break;
2165  }
2166 
2167  if (parameter.AdminNeeded && !NeededAccessRights()) {
2168  DBG_PRINT((DBG_PREFIX "You do not have necessary privileges. "
2169  "Please try installing only as administrator."));
2170  printf("You do not have necessary privileges.\n"
2171  "Please try installing only as administrator.\n");
2172 
2173  retValue = 3;
2174  break;
2175  }
2176 
2177  //
2178  // execute the command
2179  //
2180 
2181  if (parameter.CheckInstall) {
2182  retValue = CheckOpenCBM(&parameter);
2183  }
2184  else if (parameter.Remove) {
2185  // The driver should be removed
2186 
2187  retValue = RemoveOpenCBM(&parameter);
2188  }
2189  else if (parameter.Update) {
2190  // Update driver parameters
2191 
2192  retValue = UpdateOpenCBM(&parameter);
2193  }
2194  else if (parameter.Install) {
2195  // The driver should be installed
2196 
2197  retValue = InstallOpenCBM(&parameter);
2198  }
2199  else {
2200  fprintf(stderr, "Internal problem: Which command has been given to instcbm?\n");
2201  DBG_PRINT((DBG_PREFIX "Internal problem: Which command has been given to instcbm?"));
2202  }
2203  } while (0);
2204 
2205 #if DBG
2206 
2207  if (parameter.OutputDebuggingBuffer)
2208  {
2209 // @@@ CbmOutputDebuggingBuffer();
2210  }
2211 
2212 #endif // #if DBG
2213 
2214  PluginListFree(&parameter);
2215 
2216  FUNC_LEAVE_INT(retValue);
2217 }
#define DBGDO(_xxx)
Definition: debug.h:409
#define KERNEL32_DLL
Definition: instcbm.c:46
struct cbm_install_parameter_plugin_s cbm_install_parameter_plugin_t
Definition: instcbm.h:27
#define FUNC_LEAVE_INT(_xxx)
Definition: debug.h:358
Header for installation routines.
char * cbmlibmisc_strdup(const char *const OldString)
Duplicate a given string.
Definition: libstring.c:84
#define FUNC_LEAVE_HMODULE(_xxx)
Definition: debug.h:387
Define makros for debugging purposes.
unsigned long DbgFlags
BOOL PluginForAll(cbm_install_parameter_t *InstallParameter, PluginForAll_Callback_t *Callback, void *Context)
Execute a callback function for all plugins in the plugin list.
Definition: plugin.c:663
void cbmlibmisc_strfree(const char *String)
Free a string.
Definition: libstring.c:172
#define WINAPI
Definition: opencbm.h:86
HMODULE LoadLocalOpenCBMDll(void)
@@@
Definition: instcbm.c:1479
#define FUNC_LEAVE_TYPE(_xxx, _TYPE, _FORMAT)
Definition: debug.h:374
Plugin DLL interface.
BOOL CBMAPIDECL opencbm_plugin_install_do_uninstall(void *Context)
@@@
Define the IOCTL codes for the opencbm driver.
#define FUNC_LEAVE()
Definition: debug.h:349
Definition: getopt.h:94
struct cbm_install_parameter_s cbm_install_parameter_t
Definition: instcbm.h:23
#define FUNC_LEAVE_PTR(_xxx, _TYPE)
Definition: debug.h:376
BOOL HandleNeededFilesCallback_t(const char *DestinationPath, const char *File)
Type of the callback function for HandleNeededFiles()
Definition: instcbm.c:1281
char * cbmlibmisc_stralloc(unsigned int Length)
allocate memory for a string of a given size
Definition: libstring.c:41
BOOL ProcessPluginCommandlineAndAddIt(cbm_install_parameter_t *Parameter, const char *const Plugin, int Argc, char *const Argv[])
Process the command-line parameters for a plugin and add that plugin to the plugin list...
Definition: plugin.c:447
struct InstallPluginCallback_context_s InstallPluginCallback_context_t
@@@
#define DBG_ASSERT(_xxx)
Definition: debug.h:401
BOOL get_all_installed_plugins(cbm_install_parameter_t *InstallParameter)
Get all the installed plugins.
Definition: plugin.c:596
#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
BOOL CBMAPIDECL opencbm_plugin_install_generic(const char *DefaultPluginname, unsigned int DefaultLocation)
@@@
#define DBG_ERROR(_xxx)
Definition: debug.h:397
#define DBG_SUCCESS(_xxx)
Definition: debug.h:393
Plugin DLL interface.
cbm_install_parameter_t * Parameter
Definition: instcbm.c:1719
Defining OpenCBM version.
#define FUNC_ENTER()
Definition: debug.h:347
#define DBG_PREFIX
Definition: debug.h:320
#define FUNC_LEAVE_STRING(_xxx)
Definition: debug.h:368
BOOL CBMAPIDECL opencbm_plugin_install_plugin_data(const char *Pluginname, const char *Filepath, const CbmPluginInstallProcessCommandlineData_t *CommandlineData)
@@@
Define makros and functions which account for differences between the different architectures.
BOOL CBMAPIDECL opencbm_plugin_install_do_install(void *Context)
@@@
Internal API for opencbm installation.
Some functions for string handling.
void PluginListFree(cbm_install_parameter_t *InstallParameter)
Free all the memory occupied by plugin management.
Definition: plugin.c:214
#define DBG_PRINT(_xxx)
Definition: debug.h:403
int __cdecl main(int Argc, char **Argv)
Main function.
Definition: instcbm.c:2134