00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00021 #include <windows.h>
00022 #include <stdio.h>
00023 #include <stdlib.h>
00024 #include <direct.h>
00025
00026 #include "cbmioctl.h"
00027 #include "version.h"
00028 #include "arch.h"
00029
00030 #include <getopt.h>
00031
00033 #define DBG_USERMODE
00034
00036 #define DBG_PROGNAME "INSTCBM.EXE"
00037
00039 #define DBG_IS_DEBUG_C
00040
00041 #include "debug.h"
00042
00043 #include "instcbm.h"
00044
00055 PCHAR
00056 FormatErrorMessage(DWORD Error)
00057 {
00058 static char ErrorMessageBuffer[2048];
00059 int n;
00060
00061
00062
00063 n = FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS | FORMAT_MESSAGE_MAX_WIDTH_MASK,
00064 NULL,
00065 Error,
00066 MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
00067 (LPTSTR) &ErrorMessageBuffer,
00068 sizeof(ErrorMessageBuffer)-1,
00069 NULL);
00070
00071
00072
00073 ErrorMessageBuffer[n] = 0;
00074
00075 return ErrorMessageBuffer;
00076 }
00077
00079 typedef
00080 enum osversion_e
00081 {
00082 WINUNSUPPORTED,
00083 WINNT3,
00084 WINNT4,
00085 WIN2000,
00086 WINXP,
00087 WINNEWER
00088 } osversion_t;
00089
00090
00099 static osversion_t
00100 GetOsVersion(VOID)
00101 {
00102 OSVERSIONINFO ovi;
00103 osversion_t retValue;
00104
00105 FUNC_ENTER();
00106
00107
00108
00109 retValue = WINUNSUPPORTED;
00110
00111
00112
00113 ovi.dwOSVersionInfoSize = sizeof(ovi);
00114
00115 if (GetVersionEx(&ovi))
00116 {
00117 DBGDO(char *platform = "";)
00118
00119 switch (ovi.dwPlatformId)
00120 {
00121 case VER_PLATFORM_WIN32s:
00122 DBGDO(platform = "WIN32s (huh?)";)
00123 break;
00124
00125 case VER_PLATFORM_WIN32_WINDOWS:
00126 DBGDO(platform = "Win 95/98/Me";)
00127 break;
00128
00129 case VER_PLATFORM_WIN32_NT:
00130 DBGDO(platform = "Win NT/2K/XP";)
00131
00132 switch (ovi.dwMajorVersion)
00133 {
00134 case 0: case 1: case 2:
00135
00136 break;
00137
00138 case 3:
00139
00140 retValue = WINNT3;
00141 DBG_PRINT((DBG_PREFIX "Running on NT 3.x!"));
00142 printf("You're using Windows NT 3.%02u. These versions are untested, but they might work.\n"
00143 "If it works for you, I would be very happy if you contact me and tell me!\n",
00144 ovi.dwMinorVersion);
00145 break;
00146
00147 case 4:
00148 retValue = WINNT4;
00149 break;
00150
00151 case 5:
00152 switch (ovi.dwMinorVersion)
00153 {
00154 case 0: retValue = WIN2000; break;
00155 case 1: retValue = WINXP; break;
00156 default: retValue = WINNEWER; break;
00157 }
00158 break;
00159
00160 default:
00161
00162
00163
00164
00165 retValue = WINNEWER;
00166 break;
00167 }
00168 break;
00169
00170 default:
00171 DBGDO(platform = "unknown (huh?)";)
00172 break;
00173 }
00174
00175 DBG_SUCCESS((DBG_PREFIX "OS VERSION: %u.%u.%u %s (%s)",
00176 ovi.dwMajorVersion, ovi.dwMinorVersion, ovi.dwBuildNumber,
00177 platform, ovi.szCSDVersion));
00178 }
00179
00180 FUNC_LEAVE_TYPE(retValue, osversion_t, "%u");
00181 }
00182
00184 static VOID
00185 version(VOID)
00186 {
00187 FUNC_ENTER();
00188
00189 printf("instcbm Version " OPENCBM_VERSION ", built on " __DATE__ " at " __TIME__ "\n");
00190
00191 FUNC_LEAVE();
00192 }
00193
00195 static VOID
00196 usage(VOID)
00197 {
00198 FUNC_ENTER();
00199
00200 version();
00201
00202 printf("\nUsage: instcbm [options]\n"
00203 "Install the cbm4win driver on the system, or remove it.\n"
00204 "\n"
00205 "Options:\n"
00206 " -h, --help display this help and exit\n"
00207 " -V, --version display version information about cbm4win\n"
00208 " -r, --remove remove (uninstall) the driver\n"
00209 " -e, --enumpport re-enumerate the parallel port driver\n"
00210 " -u, --update update parameters if driver is already installed.\n"
00211 " -l, --lpt=no set default LPT port\n"
00212 " -t, --cabletype=TYPE set cabletype to 'auto', 'xa1541' or 'xm1541'.\n"
00213 " If not specified, --cabletype=auto is assumed.\n"
00214 " -L, --lock=WHAT automatically lock the driver 'yes' or not 'no'.\n"
00215 " If not specified, --lock=yes is assumed.\n"
00216 " -n, --nocopy do not copy the driver files into the system directory\n"
00217 " -c, --check only check if the installation is ok\n"
00218 #ifdef _X86_
00219 " -F, --forcent4 force NT4 driver on a Win 2000, XP, or newer systems\n"
00220 " (NOT RECOMMENDED!)\n"
00221 #endif
00222 " -A, --automatic (default) automatically start the driver on system boot.\n"
00223 " The driver can be used from a normal user, no need for\n"
00224 " administrator rights.\n"
00225 " The opposite of --on-demand.\n"
00226 " -O, --on-demand start the driver only on demand.\n"
00227 " The opposite of --automatic.\n"
00228 "\n");
00229
00230 FUNC_LEAVE();
00231 }
00232
00234 static VOID
00235 hint(char *s)
00236 {
00237 fprintf(stderr, "Try `%s' --help for more information.\n", s);
00238 }
00239
00241 typedef
00242 struct parameter_s
00243 {
00245 BOOL NoExecute;
00246
00248 BOOL ExecuteParameterGiven;
00249
00251 BOOL Remove;
00252
00254 BOOL EnumerateParport;
00255
00257 BOOL NoCopy;
00258
00260 BOOL ForceNt4;
00261
00263 BOOL Update;
00264
00266 BOOL CheckInstall;
00267
00269 ULONG Lpt;
00270
00272 ULONG IecCableType;
00273
00275 ULONG PermanentlyLock;
00276
00278 BOOL AutomaticOrOnDemandStart;
00279
00281 BOOL AutomaticStart;
00282
00283 #if DBG
00284
00286 BOOL OutputDebuggingBuffer;
00287
00289 BOOL DebugFlagsDriverWereGiven;
00290
00292 BOOL DebugFlagsDllWereGiven;
00293
00295 BOOL DebugFlagsInstallWereGiven;
00296
00298 ULONG DebugFlagsDriver;
00299
00301 ULONG DebugFlagsDll;
00302
00304 ULONG DebugFlagsInstall;
00305
00306 #endif // #if DBG
00307
00309 osversion_t OsVersion;
00310 } parameter_t;
00311
00343 static BOOL
00344 processNumber(const PCHAR Argument, PCHAR *NextChar, PBOOL ParameterGiven, PULONG ParameterValue)
00345 {
00346 PCHAR p;
00347 BOOL error;
00348 int base;
00349
00350 FUNC_ENTER();
00351
00352 DBG_ASSERT(ParameterValue != NULL);
00353
00354 error = FALSE;
00355 p = Argument;
00356
00357 if (p)
00358 {
00359
00360
00361 switch (*p)
00362 {
00363 case 0:
00364 error = TRUE;
00365 break;
00366
00367 case '0':
00368 switch (*++p)
00369 {
00370 case 'x': case 'X':
00371 base = 16;
00372 ++p;
00373 break;
00374
00375 default:
00376 base = 8;
00377 break;
00378 };
00379 break;
00380
00381 default:
00382 base = 10;
00383 break;
00384 }
00385
00386
00387
00388 if (!error)
00389 {
00390 *ParameterValue = strtoul(p, &p, base);
00391
00392 if (NextChar)
00393 {
00394 error = ((*p != 0) && (*p != ',')) ? TRUE : FALSE;
00395 }
00396 else
00397 {
00398 error = *p != 0 ? TRUE : FALSE;
00399 }
00400
00401 if (!error)
00402 {
00403 if (NextChar != NULL)
00404 {
00405 *NextChar = p + ((*p) ? 1 : 0);
00406 }
00407
00408 if (ParameterGiven != NULL)
00409 {
00410 *ParameterGiven = TRUE;
00411 }
00412 }
00413 }
00414 }
00415
00416 FUNC_LEAVE_BOOL(error);
00417 }
00418
00436 static BOOL
00437 processargs(int Argc, char **Argv, parameter_t *Parameter)
00438 {
00439 BOOL error;
00440 int c;
00441
00442 struct option longopts[] =
00443 {
00444 { "help", no_argument, NULL, 'h' },
00445 { "version", no_argument, NULL, 'V' },
00446 { "remove", no_argument, NULL, 'r' },
00447 { "enumpport", no_argument, NULL, 'e' },
00448 #ifdef _X86_
00449 { "forcent4", no_argument, NULL, 'F' },
00450 #endif // #ifdef _X86_
00451 { "lpt", required_argument, NULL, 'l' },
00452 { "update", no_argument, NULL, 'u' },
00453 { "check", no_argument, NULL, 'c' },
00454 { "cabletype", required_argument, NULL, 't' },
00455 { "lock", required_argument, NULL, 'L' },
00456 #if DBG
00457 { "debugflags", required_argument, NULL, 'D' },
00458 { "buffer", no_argument, NULL, 'B' },
00459 #endif // #if DBG
00460 { "nocopy", no_argument, NULL, 'n' },
00461 { "automatic", no_argument, NULL, 'A' },
00462 { "on-demand", no_argument, NULL, 'O' },
00463 { NULL, 0, NULL, 0 }
00464 };
00465
00466 const char shortopts[] = "hrel:nuct:L:AOV"
00467 #ifdef _X86_
00468 "F"
00469 #endif // #ifdef _X86_
00470
00471 #if DBG
00472 "D:B"
00473 #endif // #if DBG
00474 ;
00475
00476 FUNC_ENTER();
00477
00478 error = FALSE;
00479
00480
00481
00482 DBG_ASSERT(Parameter);
00483 memset(Parameter, 0, sizeof(*Parameter));
00484
00485
00486
00487 Parameter->Lpt = (ULONG) -1;
00488
00489
00490
00491 Parameter->IecCableType = (ULONG) -2;
00492
00493
00494
00495 Parameter->PermanentlyLock = (ULONG) -1;
00496
00497
00498
00499 Parameter->AutomaticStart = TRUE;
00500
00501 #if DBG
00502
00503
00504
00505 Parameter->DebugFlagsDriverWereGiven = FALSE;
00506 Parameter->DebugFlagsDllWereGiven = FALSE;
00507
00508 #endif // #if DBG
00509
00510 while ((c=getopt_long(Argc, Argv, shortopts, longopts, NULL)) != -1)
00511 {
00512 switch (c)
00513 {
00514 case 'h':
00515 usage();
00516 Parameter->NoExecute = TRUE;
00517 break;
00518
00519 case 'V':
00520 version();
00521 Parameter->NoExecute = TRUE;
00522 break;
00523
00524 case 'r':
00525 if (Parameter->ExecuteParameterGiven)
00526 {
00527 error = TRUE;
00528 printf("Colliding parameters were given, aborting!");
00529 hint(Argv[0]);
00530 }
00531 else
00532 {
00533 Parameter->ExecuteParameterGiven = TRUE;
00534 Parameter->Remove = TRUE;
00535 }
00536 break;
00537
00538 case 'e':
00539 if (Parameter->ExecuteParameterGiven)
00540 {
00541 error = TRUE;
00542 printf("Colliding parameters were given, aborting!");
00543 hint(Argv[0]);
00544 }
00545 else
00546 {
00547 Parameter->ExecuteParameterGiven = TRUE;
00548 Parameter->EnumerateParport = TRUE;
00549 }
00550 break;
00551
00552 case 't':
00553 if (optarg == NULL)
00554 Parameter->IecCableType = -1;
00555 else if (strcmp(optarg, "xa1541") == 0)
00556 Parameter->IecCableType = 1;
00557 else if (strcmp(optarg, "xm1541") == 0)
00558 Parameter->IecCableType = 0;
00559 else if (strcmp(optarg, "auto") == 0)
00560 Parameter->IecCableType = -1;
00561 else
00562 {
00563 fprintf(stderr, "you must specify 'xa1541', 'xm1541' or 'auto' for --cabletype\n");
00564 error = TRUE;
00565 }
00566 break;
00567
00568 case 'L':
00569 if (optarg == NULL
00570 || (strcmp(optarg, "+") == 0)
00571 || (strcmp(optarg, "yes") == 0)
00572 || (strcmp(optarg, "true") == 0)
00573 )
00574 {
00575 Parameter->PermanentlyLock = 1;
00576 }
00577 else if (optarg != NULL &&
00578 ( (strcmp(optarg, "-") == 0)
00579 || (strcmp(optarg, "no") == 0)
00580 || (strcmp(optarg, "false") == 0)
00581 )
00582 )
00583 {
00584 Parameter->PermanentlyLock = 0;
00585 }
00586 else
00587 {
00588 fprintf(stderr, "you must specify 'yes' or 'no' for --lock\n");
00589 error = TRUE;
00590 }
00591 break;
00592
00593 case 'n':
00594 Parameter->NoCopy = TRUE;
00595 break;
00596
00597 case 'c':
00598 Parameter->CheckInstall = TRUE;
00599 break;
00600
00601 #ifdef _X86_
00602 case 'F':
00603 if (Parameter->ExecuteParameterGiven)
00604 {
00605 error = TRUE;
00606 printf("Colliding parameters were given, aborting!");
00607 hint(Argv[0]);
00608 }
00609 else
00610 {
00611 Parameter->ExecuteParameterGiven = TRUE;
00612 Parameter->ForceNt4 = TRUE;
00613 Parameter->Remove = FALSE;
00614 }
00615 break;
00616 #endif // #ifdef _X86_
00617
00618 case 'l':
00619 error = processNumber(optarg, NULL, NULL, &Parameter->Lpt);
00620 break;
00621
00622 #if DBG
00623
00624 case 'D':
00625 {
00626 PCHAR next;
00627
00628 error = processNumber(optarg, &next, &Parameter->DebugFlagsDriverWereGiven,
00629 &Parameter->DebugFlagsDriver);
00630
00631 if (!error && next && *next)
00632 {
00633 error = processNumber(next, &next, &Parameter->DebugFlagsDllWereGiven,
00634 &Parameter->DebugFlagsDll);
00635 }
00636
00637 if (!error && next && *next)
00638 {
00639 error = processNumber(next, NULL, &Parameter->DebugFlagsInstallWereGiven,
00640 &Parameter->DebugFlagsInstall);
00641
00642 if (!error && Parameter->DebugFlagsInstallWereGiven)
00643 {
00644 DbgFlags = Parameter->DebugFlagsInstall;
00645 }
00646 }
00647 DBG_PRINT((DBG_PREFIX "error = %s, 1st = %08x (%s), 2nd = %08x (%s), 3rd = %08x (%s)",
00648 error ? "TRUE" : "FALSE",
00649 Parameter->DebugFlagsDriver, Parameter->DebugFlagsDriverWereGiven ? "TRUE" : "FALSE",
00650 Parameter->DebugFlagsDll, Parameter->DebugFlagsDllWereGiven ? "TRUE" : "FALSE",
00651 Parameter->DebugFlagsInstall, Parameter->DebugFlagsInstallWereGiven ? "TRUE" : "FALSE"));
00652 }
00653 break;
00654
00655 case 'B':
00656 Parameter->OutputDebuggingBuffer = TRUE;
00657 Parameter->NoExecute = TRUE;
00658 break;
00659
00660 #endif // #if DBG
00661
00662 case 'u':
00663 Parameter->Update = TRUE;
00664 break;
00665
00666 case 'A':
00667 if (Parameter->AutomaticOrOnDemandStart)
00668 {
00669 fprintf(stderr, "--automatic and --on-demand cannot be specified at the same time!\n");
00670 error = TRUE;
00671 }
00672 else
00673 {
00674 Parameter->AutomaticStart = TRUE;
00675 Parameter->AutomaticOrOnDemandStart = TRUE;
00676 }
00677 break;
00678
00679 case 'O':
00680 if (Parameter->AutomaticOrOnDemandStart)
00681 {
00682 fprintf(stderr, "--automatic and --on-demand cannot be specified at the same time!\n");
00683 error = TRUE;
00684 }
00685 else
00686 {
00687 Parameter->AutomaticStart = FALSE;
00688 Parameter->AutomaticOrOnDemandStart = TRUE;
00689 }
00690 break;
00691
00692 default:
00693 error = TRUE;
00694 hint(Argv[0]);
00695 break;
00696 }
00697 }
00698
00699 FUNC_LEAVE_BOOL(error);
00700 }
00701
00717 static char *
00718 AllocateConcatenatedString(const char *String1, const char *String2)
00719 {
00720 char *string;
00721
00722 FUNC_ENTER();
00723
00724 DBG_ASSERT(String1 != NULL);
00725 DBG_ASSERT(String2 != NULL);
00726
00727 string = malloc(strlen(String1) + strlen(String2) + 1);
00728
00729 if (string)
00730 {
00731 strcpy(string, String1);
00732 strcat(string, String2);
00733
00734 DBG_ASSERT(strlen(string) == strlen(String1) + strlen(String2));
00735 }
00736
00737 FUNC_LEAVE_STRING(string);
00738 }
00739
00762 static int
00763 CopyFileToNewPath(const char *SourcePath, const char *DestPath, const char *Filename, const int ErrorCode)
00764 {
00765 char *sourceFile = NULL;
00766 char *destFile = NULL;
00767 int error = 0;
00768
00769 FUNC_ENTER();
00770
00771 sourceFile = AllocateConcatenatedString(SourcePath, Filename);
00772 destFile = AllocateConcatenatedString(DestPath, Filename);
00773
00774 if (sourceFile && destFile)
00775 {
00776 DBG_PRINT((DBG_PREFIX "Copying '%s' to '%s'", sourceFile, destFile));
00777
00778 printf("Copying '%s' to '%s'", sourceFile, destFile);
00779 if (!CopyFile(sourceFile, destFile, FALSE))
00780 {
00781 error = ErrorCode;
00782 DBG_PRINT((DBG_PREFIX "--> FAILED!" ));
00783 printf(" FAILED!\n");
00784 }
00785 else
00786 {
00787 printf("\n");
00788 }
00789 }
00790 else
00791 {
00792 DBG_ERROR((DBG_PREFIX "Error allocating memory buffers for copying '%s'!", Filename));
00793 fprintf(stderr, "Error allocating memory buffers for copying '%s'.\n", Filename);
00794 }
00795
00796 if (sourceFile)
00797 free(sourceFile);
00798
00799 if (destFile)
00800 free(destFile);
00801
00802 FUNC_LEAVE_INT(error);
00803 }
00804
00816 static VOID
00817 DeleteFileInDirectory(const char *Path, const char *Filename)
00818 {
00819 char *file = NULL;
00820
00821 FUNC_ENTER();
00822
00823 do {
00824 file = AllocateConcatenatedString(Path, Filename);
00825
00826 if (!file)
00827 break;
00828
00829 DBG_PRINT((DBG_PREFIX "Trying to delete %s", file));
00830
00831 DeleteFile(file);
00832
00833 } while (0);
00834
00835 if (file)
00836 free(file);
00837
00838 FUNC_LEAVE();
00839 }
00840
00853 static int
00854 RemoveDriver(parameter_t *Parameter)
00855 {
00856 char *driverSystemPath = NULL;
00857 char *driverPath = NULL;
00858
00859 FUNC_ENTER();
00860
00861 UNREFERENCED_PARAMETER(Parameter);
00862
00863 do {
00864 char tmpPathString[MAX_PATH];
00865
00866 if (!CbmCheckPresence(OPENCBM_DRIVERNAME))
00867 {
00868 printf("No driver installed, cannot remove.\n");
00869 break;
00870 }
00871
00872 printf("REMOVING driver...\n");
00873
00874 CbmRemove(OPENCBM_DRIVERNAME);
00875
00876
00877
00878
00879
00880 GetSystemDirectory(tmpPathString, sizeof(tmpPathString));
00881 driverSystemPath = AllocateConcatenatedString(tmpPathString, "\\");
00882 driverPath = AllocateConcatenatedString(tmpPathString, "\\DRIVERS\\");
00883
00884 if (!driverSystemPath || !driverPath)
00885 break;
00886
00887
00888
00889 DeleteFileInDirectory(driverSystemPath, "OPENCBM.DLL");
00890
00891
00892
00893 DeleteFileInDirectory(driverSystemPath, "OPENCBMVDD.DLL");
00894
00895
00896
00897 DeleteFileInDirectory(driverPath, "CBM4NT.SYS");
00898
00899
00900
00901 DeleteFileInDirectory(driverPath, "CBM4WDM.SYS");
00902
00903 } while (0);
00904
00905 if (driverSystemPath)
00906 free(driverSystemPath);
00907
00908 if (driverPath)
00909 free(driverPath);
00910
00911 FUNC_LEAVE_INT(0);
00912 }
00913
00926 static int
00927 CheckDriver(parameter_t *Parameter)
00928 {
00929 int error;
00930
00931 FUNC_ENTER();
00932
00933 UNREFERENCED_PARAMETER(Parameter);
00934
00935 DBG_PRINT((DBG_PREFIX "Checking configuration for cbm4win"));
00936 printf("Checking configuration for cbm4win\n");
00937
00938 if (CbmCheckCorrectInstallation())
00939 {
00940 DBG_PRINT((DBG_PREFIX "There were errors in the current configuration."
00941 "Please fix them before trying to use the driver!"));
00942 printf("*** There were errors in the current configuration.\n"
00943 "*** Please fix them before trying to use the driver!");
00944 error = 11;
00945 }
00946 else
00947 {
00948 error = 0;
00949 DBG_PRINT((DBG_PREFIX "No problems found in current configuration"));
00950 printf("No problems found in current configuration\n\n");
00951
00961 }
00962
00963 FUNC_LEAVE_INT(error);
00964 }
00965
00978 static int
00979 EnumParportDriver(parameter_t *Parameter)
00980 {
00981 FUNC_ENTER();
00982
00983 UNREFERENCED_PARAMETER(Parameter);
00984
00985 DBG_PRINT((DBG_PREFIX "Re-enumerating parallel port driver"));
00986 printf("Re-enumerating parallel port driver\n");
00987
00988 CbmParportRestart();
00989
00990 FUNC_LEAVE_INT(0);
00991 }
00992
01005 static int
01006 CopyDriverFiles(parameter_t *Parameter)
01007 {
01008 char tmpPathString[MAX_PATH];
01009
01010 char *driverSystemPath = NULL;
01011 char *driverPath = NULL;
01012 char *driverLocalPath = NULL;
01013 char *driverFilename = NULL;
01014
01015 const char *driverToUse;
01016
01017 int error = 0;
01018
01019 FUNC_ENTER();
01020
01021 printf("Installing driver...\n");
01022
01023 do {
01024
01025
01026
01027
01028 if (GetCurrentDirectory(sizeof(tmpPathString), tmpPathString) == 0)
01029 {
01030 DBG_PRINT((DBG_PREFIX "Could not determine the current working directory!"));
01031 printf("Could not determine the current working directory!\n");
01032 error = 4;
01033 break;
01034 }
01035
01036 driverLocalPath = AllocateConcatenatedString(tmpPathString, "\\");
01037
01038
01039
01040
01041
01042 GetSystemDirectory(tmpPathString, sizeof(tmpPathString));
01043 driverSystemPath = AllocateConcatenatedString(tmpPathString, "\\");
01044 driverPath = AllocateConcatenatedString(tmpPathString, "\\DRIVERS\\");
01045
01046 if (!driverLocalPath || !driverSystemPath || !driverPath)
01047 {
01048 DBG_ERROR((DBG_PREFIX "error allocating memory for the paths" ));
01049 fprintf(stderr, "error allocating memory for the paths\n");
01050 error = 15;
01051 break;
01052 }
01053
01054
01055
01056
01057
01058 driverToUse = ((Parameter->OsVersion > WINNT4) && !Parameter->ForceNt4) ? "cbm4wdm.sys" : "cbm4nt.sys";
01059
01060 printf("Using driver '%s'\n", driverLocalPath);
01061
01062
01063
01064
01065
01066 if (!Parameter->NoCopy)
01067 {
01068
01069
01070 if ((error = CopyFileToNewPath(driverLocalPath, driverPath, driverToUse, 6)) != 0)
01071 break;
01072
01073 if ((error = CopyFileToNewPath(driverLocalPath, driverSystemPath, "opencbm.dll", 7)) != 0)
01074 break;
01075
01076 #ifdef _X86_
01077 if ((error = CopyFileToNewPath(driverLocalPath, driverSystemPath, "opencbmvdd.dll", 10)) != 0)
01078 break;
01079 #endif // #ifdef _X86_
01080 }
01081
01082 printf("\n");
01083
01084
01085
01086
01087
01088 driverFilename = AllocateConcatenatedString(Parameter->NoCopy ? driverLocalPath : driverPath, driverToUse);
01089
01090 if (!driverFilename)
01091 {
01092 error = 14;
01093 break;
01094 }
01095
01096 CbmInstall(OPENCBM_DRIVERNAME, driverFilename, Parameter->AutomaticStart);
01097
01098 } while (0);
01099
01100 if (driverSystemPath)
01101 free(driverSystemPath);
01102
01103 if (driverPath)
01104 free(driverPath);
01105
01106 if (driverFilename)
01107 free(driverFilename);
01108
01109 if (driverLocalPath)
01110 free(driverLocalPath);
01111
01112 FUNC_LEAVE_INT(error);
01113 }
01114
01127 static int
01128 InstallDriver(parameter_t *Parameter)
01129 {
01130 int error = 0;
01131
01132 FUNC_ENTER();
01133
01134 do {
01135 if (CbmCheckPresence(OPENCBM_DRIVERNAME))
01136 {
01137 printf("Driver is already installed, remove it before you try a new installation,\n"
01138 "or use the --update option!\n");
01139 error = 8;
01140 break;
01141 }
01142
01143 if ((error = CopyDriverFiles(Parameter)) != 0)
01144 break;
01145
01146 if (!CbmUpdateParameter(Parameter->Lpt,
01147 Parameter->IecCableType, Parameter->PermanentlyLock,
01148 #if DBG
01149 Parameter->DebugFlagsDriverWereGiven, Parameter->DebugFlagsDriver,
01150 Parameter->DebugFlagsDllWereGiven, Parameter->DebugFlagsDll
01151 #else
01152 0, 0, 0, 0
01153 #endif
01154 ))
01155 {
01156 error = 9;
01157 break;
01158 }
01159
01160 printf("\n");
01161
01162 if ((error = CheckDriver(Parameter)) != 0)
01163 break;
01164
01165 } while (0);
01166
01167 FUNC_LEAVE_INT(error);
01168 }
01169
01182 static int
01183 UpdateDriver(parameter_t *Parameter)
01184 {
01185 int error = 0;
01186
01187 FUNC_ENTER();
01188
01189 do {
01190 if (!CbmCheckPresence(OPENCBM_DRIVERNAME))
01191 {
01192 printf("Driver is not installed, cannot update the parameters,\n");
01193 error = 12;
01194 break;
01195 }
01196
01197 if (!CbmUpdateParameter(Parameter->Lpt,
01198 Parameter->IecCableType, Parameter->PermanentlyLock,
01199 #if DBG
01200 Parameter->DebugFlagsDriverWereGiven, Parameter->DebugFlagsDriver,
01201 Parameter->DebugFlagsDllWereGiven, Parameter->DebugFlagsDll
01202 #else
01203 0, 0, 0, 0
01204 #endif
01205 ))
01206 {
01207 error = 13;
01208 break;
01209 }
01210
01211 printf("\n");
01212 error = CheckDriver(Parameter);
01213
01214 } while (0);
01215
01216 FUNC_LEAVE_INT(error);
01217 }
01218
01232 static BOOL
01233 NeededAccessRights(VOID)
01234 {
01235 SC_HANDLE scManager;
01236
01237 FUNC_ENTER();
01238
01239
01240
01241
01242 scManager = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);
01243
01244 if (scManager)
01245 {
01246 CloseServiceHandle(scManager);
01247 }
01248
01249 FUNC_LEAVE_BOOL(scManager ? TRUE : FALSE);
01250 }
01251
01265 int __cdecl
01266 main(int Argc, char **Argv)
01267 {
01268 parameter_t parameter;
01269 int retValue = 0;
01270
01271 FUNC_ENTER();
01272
01273 do {
01274 if (processargs(Argc, Argv, ¶meter))
01275 {
01276 DBG_PRINT((DBG_PREFIX "Error processing command line arguments"));
01277 retValue = 1;
01278 break;
01279 }
01280
01281 parameter.OsVersion = GetOsVersion();
01282
01283 if (parameter.OsVersion == WINUNSUPPORTED)
01284 {
01285 DBG_PRINT((DBG_PREFIX "This version of Windows is not supported!"));
01286 printf("Sorry, this version of Windows is not supported!\n");
01287 retValue = 2;
01288 break;
01289 }
01290
01291 if (parameter.NoExecute)
01292 break;
01293
01294 if (!NeededAccessRights())
01295 {
01296 DBG_PRINT((DBG_PREFIX "You do not have necessary privileges. "
01297 "Please try installing only as administrator."));
01298 printf("You do not have necessary privileges.\n"
01299 "Please try installing only as administrator.\n");
01300
01301 retValue = 3;
01302 break;
01303 }
01304
01305
01306
01307
01308
01309 if (parameter.CheckInstall)
01310 {
01311 retValue = CheckDriver(¶meter);
01312 }
01313 else if (parameter.Remove)
01314 {
01315
01316
01317 retValue = RemoveDriver(¶meter);
01318 }
01319 else if (parameter.EnumerateParport)
01320 {
01321
01322
01323 retValue = EnumParportDriver(¶meter);
01324 }
01325 else if (parameter.Update)
01326 {
01327
01328
01329 retValue = UpdateDriver(¶meter);
01330 }
01331 else
01332 {
01333
01334
01335 retValue = InstallDriver(¶meter);
01336 }
01337 } while (0);
01338
01339 #if DBG
01340
01341 if (parameter.OutputDebuggingBuffer)
01342 {
01343 CbmOutputDebuggingBuffer();
01344 }
01345
01346 #endif // #if DBG
01347
01348 FUNC_LEAVE_INT(retValue);
01349 }