00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00027 #include <windows.h>
00028 #include <windowsx.h>
00029
00031 #define DBG_USERMODE
00032
00034 #ifndef DBG_PROGNAME
00035 #define DBG_PROGNAME "OPENCBM.DLL"
00036 #endif // #ifndef DBG_PROGNAME
00037
00038 #include "debug.h"
00039
00040 #include <winioctl.h>
00041 #include "cbmioctl.h"
00042
00043 #include <stdlib.h>
00044 #include <stddef.h>
00045
00046 #include "i_opencbm.h"
00047
00048 #include "version.h"
00049 #include "archlib.h"
00050
00051
00052
00053
00054
00076 LONG
00077 RegGetDWORD(IN HKEY RegKey, IN char *SubKey, OUT LPDWORD Value)
00078 {
00079 DWORD valueLen;
00080 DWORD lpType;
00081 DWORD value;
00082 DWORD rc;
00083
00084 FUNC_ENTER();
00085
00086 FUNC_PARAM((DBG_PREFIX "Subkey = '%s'", SubKey));
00087
00088 valueLen = sizeof(value);
00089
00090 rc = RegQueryValueEx(RegKey, SubKey, NULL, &lpType, (LPBYTE)&value, &valueLen);
00091
00092 DBG_ASSERT(valueLen == 4);
00093
00094 if ((rc == ERROR_SUCCESS) && (valueLen == 4))
00095 {
00096 DBG_SUCCESS((DBG_PREFIX "RegGetDWORD"));
00097 *Value = value;
00098 }
00099 else
00100 {
00101 DBG_ERROR((DBG_PREFIX "RegGetDWORD failed, returning -1"));
00102 rc = -1;
00103 }
00104
00105 FUNC_LEAVE_INT(rc);
00106 }
00107
00108
00122 static int
00123 cbm_get_default_port(VOID)
00124 {
00125 DWORD ret;
00126 HKEY regKey;
00127
00128 FUNC_ENTER();
00129
00130 DBG_PPORT((DBG_PREFIX "cbm_get_default_port()"));
00131
00132
00133
00134 if (RegOpenKeyEx(HKEY_LOCAL_MACHINE,
00135 CBM_REGKEY_SERVICE,
00136 0,
00137 KEY_QUERY_VALUE,
00138 ®Key)
00139 )
00140 {
00141 DBG_WARN((DBG_PREFIX "RegOpenKeyEx() failed!"));
00142 FUNC_LEAVE_BOOL(FALSE);
00143 }
00144
00145
00146
00147 if (RegGetDWORD(regKey, CBM_REGKEY_SERVICE_DEFAULTLPT, &ret) != ERROR_SUCCESS)
00148 {
00149 DBG_WARN((DBG_PREFIX "No " CBM_REGKEY_SERVICE "\\" CBM_REGKEY_SERVICE_DEFAULTLPT
00150 " value, setting 0."));
00151 ret = 0;
00152 }
00153
00154
00155
00156 RegCloseKey(regKey);
00157
00158 DBG_PPORT((DBG_PREFIX "RETURN: cbm_get_default_port() == %u", ret));
00159
00160 FUNC_LEAVE_INT(ret);
00161 }
00162
00163 #if DBG
00164
00171 VOID
00172 cbm_i_get_debugging_flags(VOID)
00173 {
00174 DWORD ret;
00175 HKEY RegKey;
00176
00177 FUNC_ENTER();
00178
00179
00180
00181 if (RegOpenKeyEx(HKEY_LOCAL_MACHINE,
00182 CBM_REGKEY_SERVICE,
00183 0,
00184 KEY_QUERY_VALUE,
00185 &RegKey)
00186 )
00187 {
00188 DBG_WARN((DBG_PREFIX "RegOpenKeyEx() failed!"));
00189 FUNC_LEAVE();
00190 }
00191
00192
00193
00194 if (RegGetDWORD(RegKey, CBM_REGKEY_SERVICE_DLL_DEBUGFLAGS, &ret) != ERROR_SUCCESS)
00195 {
00196 DBG_WARN((DBG_PREFIX "No " CBM_REGKEY_SERVICE "\\" CBM_REGKEY_SERVICE_DLL_DEBUGFLAGS
00197 " value, leaving default."));
00198 }
00199 else
00200 {
00201 DbgFlags = ret;
00202 }
00203
00204
00205
00206 RegCloseKey(RegKey);
00207
00208 FUNC_LEAVE();
00209 }
00210
00211 #endif // #if DBG
00212
00229 const char *
00230 cbmarch_get_driver_name(int PortNumber)
00231 {
00233 static char driverName[] = "\\\\.\\opencbm0";
00234 char *ret;
00235
00236 FUNC_ENTER();
00237
00238 ret = NULL;
00239
00244 if (PortNumber <= 10)
00245 {
00246 if (PortNumber == 0)
00247 {
00248
00249
00250 PortNumber = cbm_get_default_port();
00251 }
00252
00253 driverName[strlen(driverName)-1] = (PortNumber ? PortNumber-1 : 0) + '0';
00254 ret = driverName;
00255 }
00256
00257 FUNC_LEAVE_STRING(ret);
00258 }
00259
00280 int
00281 cbmarch_driver_open(CBM_FILE *HandleDevice, int PortNumber)
00282 {
00283 const char *driverName;
00284
00285 FUNC_ENTER();
00286
00287
00288
00289 driverName = cbmarch_get_driver_name(PortNumber);
00290
00291 if (driverName == NULL)
00292 {
00293
00294
00295 *HandleDevice = INVALID_HANDLE_VALUE;
00296 }
00297 else
00298 {
00299
00300
00301 *HandleDevice = CreateFile(driverName,
00302 GENERIC_READ | GENERIC_WRITE,
00303 0,
00304 NULL,
00305 OPEN_EXISTING,
00306 FILE_ATTRIBUTE_NORMAL,
00307 NULL);
00308 }
00309
00310 DBG_ASSERT(*HandleDevice != INVALID_HANDLE_VALUE);
00311
00312 FUNC_LEAVE_INT(*HandleDevice == INVALID_HANDLE_VALUE);
00313 }
00314
00329 void
00330 cbmarch_driver_close(CBM_FILE HandleDevice)
00331 {
00332 FUNC_ENTER();
00333
00334 DBG_ASSERT(HandleDevice != 0);
00335
00336 CloseHandle(HandleDevice);
00337
00338 FUNC_LEAVE();
00339 }
00340
00381 BOOL
00382 cbm_ioctl(IN CBM_FILE HandleDevice, IN DWORD ControlCode,
00383 #if DBG
00384 IN char *TextControlCode,
00385 #endif
00386 IN PVOID InBuffer, IN ULONG InBufferSize, OUT PVOID OutBuffer, IN ULONG OutBufferSize)
00387 {
00388 DWORD dwBytesReturned;
00389
00390 BOOL returnValue;
00391
00392 FUNC_ENTER();
00393
00394
00395
00396 returnValue = DeviceIoControl(HandleDevice, ControlCode, InBuffer, InBufferSize,
00397 OutBuffer, OutBufferSize, &dwBytesReturned, NULL);
00398
00399
00400
00401 if (!returnValue)
00402 {
00403 DBG_ERROR((DBG_PREFIX "%s: Error code = %u", TextControlCode, GetLastError()));
00404 }
00405 else
00406 {
00407
00408
00409 if (dwBytesReturned != OutBufferSize)
00410 {
00411 DBG_WARN((DBG_PREFIX "%s: OutBufferSize = %u, but dwBytesReturned = %u",
00412 TextControlCode, OutBufferSize, dwBytesReturned));
00413 }
00414 }
00415
00416 FUNC_LEAVE_BOOL(returnValue);
00417 }
00418
00419
00420
00421
00422
00434 BOOL
00435 cbm_i_driver_start(VOID)
00436 {
00437 SC_HANDLE schManager;
00438 SC_HANDLE schService;
00439 DWORD err;
00440 BOOL ret;
00441
00442 FUNC_ENTER();
00443
00444 ret = TRUE;
00445
00446 schManager = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);
00447
00448 if (schManager == NULL)
00449 {
00450 DBG_ERROR((DBG_PREFIX "Could not open service control manager!"));
00451 FUNC_LEAVE_BOOL(FALSE);
00452 }
00453
00454 schService = OpenService(schManager, OPENCBM_DRIVERNAME, SERVICE_ALL_ACCESS);
00455
00456 if (schService == NULL)
00457 {
00458 DBG_ERROR((DBG_PREFIX "OpenService (0x%02x)", GetLastError()));
00459 FUNC_LEAVE_BOOL(FALSE);
00460 }
00461
00462 ret = StartService(schService, 0, NULL);
00463
00464 if (ret)
00465 {
00466 DBG_SUCCESS((DBG_PREFIX "StartService"));
00467 }
00468 else
00469 {
00470 err = GetLastError();
00471
00472 if (err == ERROR_SERVICE_ALREADY_RUNNING)
00473 {
00474
00475
00476
00477
00478 DBG_WARN((DBG_PREFIX "StartService, (ERROR_SERVICE_ALREADY_RUNNING)"));
00479
00480 ret = TRUE;
00481 }
00482 else
00483 {
00484 DBG_ERROR((DBG_PREFIX "StartService (0x%02x)", err));
00485 }
00486 }
00487
00488 CloseServiceHandle(schService);
00489
00490
00491
00492 CloseServiceHandle(schManager);
00493
00494 FUNC_LEAVE_BOOL(ret);
00495 }
00496
00497
00509 BOOL
00510 cbm_i_driver_stop(VOID)
00511 {
00512 SERVICE_STATUS serviceStatus;
00513 SC_HANDLE schManager;
00514 SC_HANDLE schService;
00515 BOOL ret;
00516
00517 FUNC_ENTER();
00518
00519 schManager = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);
00520
00521 schService = OpenService(schManager, OPENCBM_DRIVERNAME, SERVICE_ALL_ACCESS);
00522
00523 if (schManager == NULL)
00524 {
00525 DBG_ERROR((DBG_PREFIX "Could not open service control manager!"));
00526 FUNC_LEAVE_BOOL(FALSE);
00527 }
00528
00529 if (schService == NULL)
00530 {
00531 DBG_ERROR((DBG_PREFIX "OpenService (0x%02x)", GetLastError()));
00532 FUNC_LEAVE_BOOL(FALSE);
00533 }
00534
00535 ret = ControlService(schService, SERVICE_CONTROL_STOP, &serviceStatus);
00536
00537 if (ret)
00538 {
00539 DBG_SUCCESS((DBG_PREFIX "ControlService"));
00540 }
00541 else
00542 {
00543 DBG_ERROR((DBG_PREFIX "ControlService (0x%02x)", GetLastError()));
00544 }
00545
00546 CloseServiceHandle(schService);
00547
00548
00549
00550 CloseServiceHandle(schManager);
00551
00552 FUNC_LEAVE_BOOL(ret);
00553 }
00554
00574 BOOL
00575 cbm_i_i_driver_install(OUT PULONG Buffer, IN ULONG BufferLen)
00576 {
00577 PCBMT_I_INSTALL_OUT outBuffer;
00578 CBM_FILE HandleDevice;
00579
00580 FUNC_ENTER();
00581
00582 DBG_ASSERT(Buffer != NULL);
00583 DBG_ASSERT(BufferLen >= sizeof(ULONG));
00584
00585 outBuffer = (PCBMT_I_INSTALL_OUT) Buffer;
00586
00587 DBG_ASSERT(outBuffer != NULL);
00588
00589 if (cbmarch_driver_open(&HandleDevice, 0) == 0)
00590 {
00591 outBuffer->ErrorFlags = CBM_I_DRIVER_INSTALL_0_IOCTL_FAILED;
00592 cbm_ioctl(HandleDevice, CBMCTRL(I_INSTALL), NULL, 0, Buffer, BufferLen);
00593 cbmarch_driver_close(HandleDevice);
00594 }
00595 else
00596 {
00597 outBuffer->ErrorFlags = CBM_I_DRIVER_INSTALL_0_FAILED;
00598 DBG_ERROR((DBG_PREFIX "Driver could not be openend"));
00599 }
00600
00601
00602
00603 if (BufferLen >= sizeof(outBuffer->DllVersion) + offsetof(CBMT_I_INSTALL_OUT, DllVersion))
00604 {
00605 outBuffer->DllVersion =
00606 CBMT_I_INSTALL_OUT_MAKE_VERSION(CBM4WIN_VERSION_MAJOR, CBM4WIN_VERSION_MINOR,
00607 CBM4WIN_VERSION_SUBMINOR, CBM4WIN_VERSION_DEVEL);
00608 }
00609
00610
00611
00612 if (BufferLen >= sizeof(outBuffer->DllVersionEx) + offsetof(CBMT_I_INSTALL_OUT, DllVersionEx))
00613 {
00614 outBuffer->DllVersionEx =
00615 CBMT_I_INSTALL_OUT_MAKE_VERSION_EX(CBM4WIN_VERSION_PATCHLEVEL);
00616 }
00617
00618 FUNC_LEAVE_INT(
00619 ( (outBuffer->ErrorFlags != CBM_I_DRIVER_INSTALL_0_IOCTL_FAILED)
00620 && (outBuffer->ErrorFlags != CBM_I_DRIVER_INSTALL_0_FAILED)
00621 ) ? FALSE : TRUE);
00622 }
00623
00633 BOOL
00634 IsDriverStartedAutomatically(VOID)
00635 {
00636 DWORD ret;
00637 BOOL automaticStart;
00638 HKEY regKey;
00639
00640 FUNC_ENTER();
00641
00642 automaticStart = FALSE;
00643
00644 if (RegOpenKeyEx(HKEY_LOCAL_MACHINE,
00645 CBM_REGKEY_SERVICE,
00646 0,
00647 KEY_QUERY_VALUE,
00648 ®Key)
00649 )
00650 {
00651 DBG_WARN((DBG_PREFIX "RegOpenKeyEx() failed!"));
00652 FUNC_LEAVE_BOOL(FALSE);
00653 }
00654
00655
00656
00657 if (RegGetDWORD(regKey, "Start", &ret) != ERROR_SUCCESS)
00658 {
00659 DBG_ERROR((DBG_PREFIX "No " CBM_REGKEY_SERVICE "\\Start value!"));
00660 }
00661 else
00662 {
00663 if (ret == SERVICE_AUTO_START)
00664 {
00665 automaticStart = TRUE;
00666 }
00667 }
00668
00669
00670
00671 RegCloseKey(regKey);
00672
00673 FUNC_LEAVE_BOOL(automaticStart);
00674 }