Main Page | Data Structures | Directories | File List | Data Fields | Globals | Related Pages

instcbm.c

Go to the documentation of this file.
00001 /*
00002  *  This program is free software; you can redistribute it and/or
00003  *  modify it under the terms of the GNU General Public License
00004  *  as published by the Free Software Foundation; either version
00005  *  2 of the License, or (at your option) any later version.
00006  *
00007  *  Copyright 2004 Spiro Trikaliotis
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     // Format the message
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), // Default language
00067         (LPTSTR) &ErrorMessageBuffer,
00068         sizeof(ErrorMessageBuffer)-1,
00069         NULL);
00070 
00071     // make sure there is a trailing zero
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     // If we do not find anything, it will be an unsupported OS version
00108 
00109     retValue = WINUNSUPPORTED;
00110 
00111     // Check out the operating system version
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: /* SHOULD NOT OCCUR AT ALL! */
00135                 /* unsupported */
00136                 break;
00137 
00138             case 3:
00139                 /* NT 3.x versions are untested */
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; // comment below for default dwMajorversion applies here, too
00157                 }
00158                 break;
00159 
00160             default:
00161                 // This is a version of Windows we do not know; anyway, since
00162                 // it is NT based, and it's major version is >= 5, we support it
00163                 // anyway!
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 // #ifdef _X86_
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         // Find out which base to use (0***, 0x***, or anything else)
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         // Convert the value
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     // Clear the Parameter set 
00481 
00482     DBG_ASSERT(Parameter);
00483     memset(Parameter, 0, sizeof(*Parameter));
00484 
00485     // We have not specified an LPT port yet
00486 
00487     Parameter->Lpt = (ULONG) -1;
00488 
00489     // No IEC cable type was specified
00490 
00491     Parameter->IecCableType = (ULONG) -2;
00492 
00493     // It was not specified if the driver is to be permenently locked
00494 
00495     Parameter->PermanentlyLock = (ULONG) -1;
00496 
00497     // set the default: automaticstart -A
00498 
00499     Parameter->AutomaticStart = TRUE;
00500 
00501 #if DBG
00502 
00503     // Until now, no DebugFlags were on the line
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         // Now, check if we copied the driver and the DLL into the
00877         // system directory. If this is the case, delete them from
00878         // there.
00879 
00880         GetSystemDirectory(tmpPathString, sizeof(tmpPathString));
00881         driverSystemPath = AllocateConcatenatedString(tmpPathString, "\\");
00882         driverPath = AllocateConcatenatedString(tmpPathString, "\\DRIVERS\\");
00883 
00884         if (!driverSystemPath || !driverPath)
00885             break;
00886 
00887         // try to delete opencbm.dll
00888 
00889         DeleteFileInDirectory(driverSystemPath, "OPENCBM.DLL");
00890 
00891         // try to delete opencbmvdd.dll
00892 
00893         DeleteFileInDirectory(driverSystemPath, "OPENCBMVDD.DLL");
00894 
00895         // try to delete cbm4nt.sys
00896 
00897         DeleteFileInDirectory(driverPath, "CBM4NT.SYS");
00898 
00899         // try to delete cbm4wdm.sys
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         // First of all, determine the current working directory
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         // Get the system directory
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         // Find out which driver to use (cbm4wdm.sys, cbm4nt.sys)
01056         //
01057         
01058         driverToUse = ((Parameter->OsVersion > WINNT4) && !Parameter->ForceNt4) ? "cbm4wdm.sys" : "cbm4nt.sys";
01059 
01060         printf("Using driver '%s'\n", driverLocalPath);
01061 
01062         //
01063         // If we have to copy the files, perform the copy operation for them.
01064         //
01065 
01066         if (!Parameter->NoCopy)
01067         {
01068             // copy the driver into the appropriate directory
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         // Install the driver
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 // #if DBG
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 // #if DBG
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     // Check if we have arbitrary execute rights.
01240     // For this, open the service control manager
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, &parameter))
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         // execute the command
01307         //
01308 
01309         if (parameter.CheckInstall)
01310         {
01311             retValue = CheckDriver(&parameter);
01312         }
01313         else if (parameter.Remove)
01314         {
01315             // The driver should be removed
01316 
01317             retValue = RemoveDriver(&parameter);
01318         }
01319         else if (parameter.EnumerateParport)
01320         {
01321             // The driver should be removed
01322 
01323             retValue = EnumParportDriver(&parameter);
01324         }
01325         else if (parameter.Update)
01326         {
01327             // Update driver parameters
01328 
01329             retValue = UpdateDriver(&parameter);
01330         }
01331         else
01332         {
01333             // The driver should be installed
01334 
01335             retValue = InstallDriver(&parameter);
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 }

Generated on Sun Apr 30 18:45:53 2006 for opencbm by  doxygen 1.4.2