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

startstop.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 "cbmioctl.h"
00024 
00025 #include "instcbm.h"
00026 
00027 #include "i_opencbm.h"
00028 
00029 #include "version.h"
00030 
00032 #define DBG_USERMODE
00033 
00035 #define DBG_PROGNAME "INSTCBM.EXE"
00036 
00037 #include "debug.h"
00038 
00049 VOID
00050 OutputPathString(IN PCHAR Text, IN PCHAR Path)
00051 {
00052     FUNC_ENTER();
00053 
00054     DBG_PRINT((DBG_PREFIX "%s%s", Text, Path));
00055     printf("%s%s\n", Text, Path);
00056 
00057     FUNC_LEAVE();
00058 }
00059 
00071 static VOID
00072 OutputVersionString(IN PCHAR Text, IN ULONG Version, IN ULONG VersionEx)
00073 {
00074     char buffer[100];
00075     char buffer2[100];
00076 
00077     FUNC_ENTER();
00078 
00079     if (Version != 0)
00080     {
00081         char patchlevelVersion[4] = "pl0";
00082 
00083         if (CBMT_I_INSTALL_OUT_GET_VERSION_EX_BUGFIX(VersionEx) != 0)
00084         {
00085             patchlevelVersion[2] = 
00086                 (char) (CBMT_I_INSTALL_OUT_GET_VERSION_EX_BUGFIX(VersionEx) + '0');
00087         }
00088         else
00089         {
00090             patchlevelVersion[0] = 0;
00091         }
00092 
00093         _snprintf(buffer2, sizeof(buffer)-1,
00094             (CBMT_I_INSTALL_OUT_GET_VERSION_DEVEL(Version) 
00095                 ? "%u.%u.%u.%u" 
00096                 : "%u.%u.%u"),
00097             (unsigned int) CBMT_I_INSTALL_OUT_GET_VERSION_MAJOR(Version),
00098             (unsigned int) CBMT_I_INSTALL_OUT_GET_VERSION_MINOR(Version),
00099             (unsigned int) CBMT_I_INSTALL_OUT_GET_VERSION_SUBMINOR(Version),
00100             (unsigned int) CBMT_I_INSTALL_OUT_GET_VERSION_DEVEL(Version));
00101 
00102         _snprintf(buffer, sizeof(buffer)-1,
00103             (CBMT_I_INSTALL_OUT_GET_VERSION_DEVEL(Version) 
00104                 ? "%s%s (Development)" 
00105                 : "%s%s"),
00106             buffer2,
00107             patchlevelVersion);
00108     }
00109     else
00110     {
00111         _snprintf(buffer, sizeof(buffer)-1, "COULD NOT DETERMINE VERSION");
00112     }
00113     buffer[sizeof(buffer)-1] = 0;
00114 
00115     OutputPathString(Text, buffer);
00116 
00117     FUNC_LEAVE();
00118 }
00119 
00130 static BOOL
00131 CheckVersions(PCBMT_I_INSTALL_OUT InstallOutBuffer)
00132 {
00133     ULONG instcbmVersion;
00134     ULONG instcbmVersionEx;
00135     DWORD startMode;
00136     DWORD lptPort;
00137     DWORD lptLocking;
00138     DWORD cableType;
00139     char dllPath[MAX_PATH] = "<unknown>";
00140     char driverPath[MAX_PATH] = "<unknown>";
00141     BOOL error;
00142 
00143     FUNC_ENTER();
00144 
00145     error = FALSE;
00146 
00147     // Default value for unset/unconfigured registry settings
00148 
00149     startMode = -1;
00150     lptPort = 0;
00151     lptLocking = 1;
00152     cableType = -1;
00153 
00154     // Try to find out the version and path of the DLL
00155 
00156     {
00157         HMODULE handleDll;
00158 
00159         // Try to load the DLL. If this succeeds, get the version information
00160         // from there
00161 
00162         handleDll = LoadLibrary("OPENCBM.DLL");
00163 
00164         if (handleDll)
00165         {
00166             P_CBM_I_DRIVER_INSTALL p_cbm_i_driver_install;
00167             CBMT_I_INSTALL_OUT dllInstallOutBuffer;
00168             DWORD length;
00169 
00170             memset(&dllInstallOutBuffer, 0, sizeof(dllInstallOutBuffer));
00171 
00172             p_cbm_i_driver_install = 
00173                 (P_CBM_I_DRIVER_INSTALL) GetProcAddress(handleDll, "cbm_i_driver_install");
00174 
00175             if (p_cbm_i_driver_install)
00176             {
00177                 p_cbm_i_driver_install((PULONG) &dllInstallOutBuffer, sizeof(dllInstallOutBuffer));
00178 
00179                 if (   (InstallOutBuffer->DriverVersion == dllInstallOutBuffer.DriverVersion)
00180                     && (InstallOutBuffer->DriverVersionEx == dllInstallOutBuffer.DriverVersionEx)
00181                    )
00182                 {
00183                     InstallOutBuffer->DllVersion   = dllInstallOutBuffer.DllVersion;
00184                     InstallOutBuffer->DllVersionEx = dllInstallOutBuffer.DllVersionEx;
00185                 }
00186                 else
00187                 {
00188                     error = TRUE;
00189                 }
00190             }
00191             else
00192             {
00193                 error = TRUE;
00194             }
00195 
00196             length = GetModuleFileName(handleDll, dllPath, sizeof(dllPath));
00197 
00198             if (length >= sizeof(dllPath))
00199             {
00200                 dllPath[sizeof(dllPath)-1] = 0;
00201             }
00202 
00203             FreeLibrary(handleDll);
00204         }
00205         else
00206         {
00207             error = TRUE;
00208         }
00209     }
00210 
00211     // Try to find the path to the driver
00212 
00213     {
00214         HKEY regKey;
00215 
00216         if (RegOpenKeyEx(HKEY_LOCAL_MACHINE,
00217                          CBM_REGKEY_SERVICE,
00218                          0,
00219                          KEY_QUERY_VALUE,
00220                          &regKey)
00221            )
00222         {
00223             DBG_WARN((DBG_PREFIX "RegOpenKeyEx() failed!"));
00224             error = TRUE;
00225         }
00226         else
00227         {
00228             DWORD regLength;
00229             DWORD regReturn;
00230             DWORD regType;
00231             char driverPathFromRegistry[MAX_PATH];
00232 
00233             // now, get the number of the port to use
00234 
00235             regLength = sizeof(driverPathFromRegistry);
00236 
00237             regReturn = RegQueryValueEx(regKey, "ImagePath", NULL, &regType, 
00238                 (LPBYTE)driverPathFromRegistry, &regLength);
00239 
00240             if (regReturn != ERROR_SUCCESS)
00241             {
00242                 error = TRUE;
00243 
00244                 DBG_ERROR((DBG_PREFIX "No HKLM\\" CBM_REGKEY_SERVICE "\\ImagePath"
00245                     " value: %s", FormatErrorMessage(regReturn)));
00246             }
00247             else
00248             {
00249                 char *pColon;
00250 
00251                 // Make sure there is a trailing zero
00252 
00253                 driverPathFromRegistry[sizeof(driverPathFromRegistry)-1] = 0;
00254 
00255                 // Find out if there is a colon ":" in the path
00256 
00257                 pColon = strchr(driverPathFromRegistry, ':');
00258 
00259                 if (pColon)
00260                 {
00261                     // There is a colon, that is, the path is absolute
00262 
00263                     if (strncmp(driverPathFromRegistry, "\\??\\", sizeof("\\??\\")-1) == 0)
00264                     {
00265                         // There is the \??\ prefix, skip that
00266 
00267                         strncpy(driverPath, &driverPathFromRegistry[sizeof("\\??\\")-1],
00268                             sizeof(driverPath));
00269                     }
00270                     else
00271                     {
00272                         strncpy(driverPath, driverPathFromRegistry, sizeof(driverPath));
00273                     }
00274                 }
00275                 else
00276                 {
00277                     int lengthString;
00278 
00279                     // There is no colon, that is, the path is relative (to the windows directory)
00280                     // Thus, make sure the windows directory is appended in front of it
00281 
00282                     lengthString = GetWindowsDirectory(driverPath, sizeof(driverPath));
00283 
00284                     if ((lengthString != 0) && (lengthString < sizeof(driverPath)))
00285                     {
00286                         strncat(&driverPath[lengthString], "\\", sizeof(driverPath)-lengthString);
00287                         ++lengthString;
00288 
00289                         strncat(&driverPath[lengthString], driverPathFromRegistry,
00290                             sizeof(driverPath)-lengthString);
00291                     }
00292                 }
00293             }
00294 
00295             // find out the start mode of the driver
00296 
00297             RegGetDWORD(regKey, "Start", &startMode);
00298 
00299             // find out the default lpt port of the driver
00300 
00301             RegGetDWORD(regKey, CBM_REGKEY_SERVICE_DEFAULTLPT, &lptPort);
00302 
00303             // find out the configured LPT port locking behaviour
00304 
00305             RegGetDWORD(regKey, CBM_REGKEY_SERVICE_PERMLOCK, &lptLocking);
00306 
00307             // find out the configured cable type
00308 
00309             RegGetDWORD(regKey, CBM_REGKEY_SERVICE_IECCABLE, &cableType);
00310 
00311             // We're done, close the registry handle.
00312 
00313             RegCloseKey(regKey);
00314         }
00315     }
00316 
00317     // Print out the configuration we just obtained
00318 
00319     printf("\n\nThe following configuration is used:\n\n");
00320 
00321     instcbmVersion =
00322         CBMT_I_INSTALL_OUT_MAKE_VERSION(CBM4WIN_VERSION_MAJOR,
00323                                         CBM4WIN_VERSION_MINOR,
00324                                         CBM4WIN_VERSION_SUBMINOR,
00325                                         CBM4WIN_VERSION_DEVEL);
00326 
00327     instcbmVersionEx =
00328         CBMT_I_INSTALL_OUT_MAKE_VERSION_EX(CBM4WIN_VERSION_PATCHLEVEL);
00329 
00330     OutputVersionString("INSTCBM version: ", instcbmVersion, instcbmVersionEx);
00331 
00332     OutputVersionString("Driver version:  ", InstallOutBuffer->DriverVersion,
00333         InstallOutBuffer->DriverVersionEx);
00334     OutputPathString   ("Driver path:     ", driverPath);
00335     OutputVersionString("DLL version:     ", InstallOutBuffer->DllVersion,
00336         InstallOutBuffer->DllVersionEx);
00337     OutputPathString   ("DLL path:        ", dllPath);
00338 
00339     printf("\n");
00340 
00341     if (   (instcbmVersion   != InstallOutBuffer->DllVersion)
00342         || (instcbmVersionEx != InstallOutBuffer->DllVersionEx)
00343         || (instcbmVersion   != InstallOutBuffer->DriverVersion)
00344         || (instcbmVersionEx != InstallOutBuffer->DriverVersionEx)
00345        )
00346     {
00347         error = TRUE;
00348         printf("There are mixed versions, THIS IS NOT RECOMMENDED!\n\n");
00349     }
00350 
00351     printf("Driver configuration:\n");
00352     DBG_PRINT((DBG_PREFIX "Driver configuration:"));
00353 
00354     printf(               "  Default port: ........ LPT%i\n", lptPort ? lptPort : 1);
00355     DBG_PRINT((DBG_PREFIX "  Default port: ........ LPT%i", lptPort ? lptPort : 1));
00356 
00357     {
00358         const char *startModeName;
00359 
00360         switch (startMode)
00361         {
00362             case -1:
00363                 startModeName = "NO ENTRY FOUND!";
00364                 break; 
00365 
00366             case SERVICE_BOOT_START:
00367                 startModeName = "boot";
00368                 break;
00369 
00370             case SERVICE_SYSTEM_START:
00371                 startModeName = "system";
00372                 break;
00373 
00374             case SERVICE_AUTO_START:
00375                 startModeName = "auto";
00376                 break;
00377 
00378             case SERVICE_DEMAND_START:
00379                 startModeName = "demand";
00380                 break;
00381 
00382             case SERVICE_DISABLED:
00383                 startModeName = "disabled";
00384                 break;
00385 
00386             default:
00387                 startModeName = "<UNKNOWN>";
00388                 break;
00389         }
00390 
00391         printf("  Driver start mode: ... %s (%i)\n", startModeName, startMode);
00392         DBG_PRINT((DBG_PREFIX "  Driver start mode: ... %s (%i)", startModeName,
00393             startMode));
00394     }
00395 
00396     printf(               "  LPT port locking: .... %s\n", lptLocking ? "yes" : "no");
00397     DBG_PRINT((DBG_PREFIX "  LPT port locking: .... %s", lptLocking ? "yes" : "no"));
00398 
00399     {
00400         const char *cableTypeName;
00401 
00402         switch (cableType)
00403         {
00404             case -1:
00405                 cableTypeName = "auto";
00406                 break; 
00407 
00408             case 0:
00409                 cableTypeName = "xm1541";
00410                 break;
00411 
00412             case 1:
00413                 cableTypeName = "xa1541";
00414                 break;
00415 
00416             default:
00417                 cableTypeName = "<UNKNOWN>";
00418                 break;
00419         }
00420 
00421         printf("  Cable type: .......... %s (%i)\n\n", cableTypeName, cableType);
00422         DBG_PRINT((DBG_PREFIX "  Cable type: .......... %s (%i)", cableTypeName,
00423             cableType));
00424     }
00425 
00426     FUNC_LEAVE_BOOL(error);
00427 }
00443 BOOL
00444 CbmCheckCorrectInstallation(VOID)
00445 {
00446     CBMT_I_INSTALL_OUT outBuffer;
00447     BOOL error;
00448     BOOL driverAlreadyStarted = FALSE;
00449     int tries;
00450 
00451     FUNC_ENTER();
00452 
00453     memset(&outBuffer, 0, sizeof(outBuffer));
00454 
00455     for (tries = 1; tries >= 0; --tries)
00456     {
00457         if (driverAlreadyStarted)
00458             cbm_i_driver_stop();
00459 
00460         error = cbm_i_driver_start() ? FALSE : TRUE;
00461         driverAlreadyStarted = TRUE;
00462 
00463         if (error)
00464         {
00465             DBG_PRINT((DBG_PREFIX "Driver or DLL not correctly installed."));
00466             printf("Driver or DLL not correctly installed.\n");
00467             break;
00468         }
00469         else
00470         {
00471             error = cbm_i_i_driver_install((PULONG) &outBuffer, sizeof(outBuffer));
00472             outBuffer.DllVersion = 0;
00473 
00474             if (error)
00475             {
00476                 DBG_PRINT((DBG_PREFIX "Driver problem: Could not check install."));
00477                 printf("Driver problem: Could not check install.\n");
00478                 break;
00479             }
00480 
00481             // did we fail to gather an interrupt?
00482 
00483             if (outBuffer.ErrorFlags & CBM_I_DRIVER_INSTALL_0M_NO_INTERRUPT)
00484             {
00485                 if (tries > 0)
00486                 {
00487                     //
00488                     // stop the driver to be able to restart the parallel port
00489                     //
00490 
00491                     cbm_i_driver_stop();
00492                     driverAlreadyStarted = FALSE;
00493 
00494                     //
00495                     // No IRQ available: Try to restart the parallel port to enable it.
00496                     //
00497 
00498                     printf("Please wait some seconds...\n");
00499                     CbmParportRestart();
00500                 }
00501                 else
00502                 {
00503                     DBG_PRINT((DBG_PREFIX "No interrupt available."));
00504                     printf("\n*** Could not get an interrupt. Please try again after a reboot.\n");
00505                     error = TRUE;
00506                 }
00507             }
00508             else
00509             {
00510                 // no problem, we can stop the loop
00511 
00512                 break;
00513             }
00514         }
00515     }
00516 
00517     //
00518     // If the driver is not set to be started automatically, stop it now
00519     //
00520 
00521     if (!IsDriverStartedAutomatically())
00522     {
00523         cbm_i_driver_stop();
00524     }
00525 
00526     if (CheckVersions(&outBuffer))
00527     {
00528         error = TRUE;
00529     }
00530 
00531     FUNC_LEAVE_BOOL(error);
00532 }

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