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

libcommon/init.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 
00020 #include <wdm.h>
00021 #include "cbm_driver.h"
00022 #include "iec.h"
00023 
00027 static UNICODE_STRING ServiceKeyRegistryPath;
00028 
00055 VOID
00056 cbm_init_registry(IN PUNICODE_STRING RegistryPath, IN PDEVICE_EXTENSION Pdx)
00057 {
00058     NTSTATUS ntStatus;
00059 
00060     FUNC_ENTER();
00061 
00062     ntStatus = STATUS_SUCCESS;
00063 
00064     if (RegistryPath)
00065     {
00066         // Copy the registry path to the location
00067 
00068         DBG_ASSERT(ServiceKeyRegistryPath.Buffer == 0);
00069 
00070         // Allocate memory for the registry path
00071 
00072         ServiceKeyRegistryPath.Buffer = ExAllocatePoolWithTag(PagedPool, 
00073             RegistryPath->Length, MTAG_SERVKEY);
00074 
00075         // Copy the registry path into the variable
00076 
00077         if (ServiceKeyRegistryPath.Buffer)
00078         {
00079             ServiceKeyRegistryPath.MaximumLength = 
00080             ServiceKeyRegistryPath.Length = RegistryPath->Length;
00081 
00082             RtlCopyUnicodeString(&ServiceKeyRegistryPath, RegistryPath);
00083         }
00084         else
00085         {
00086             // No memory could be allocateed, mark the
00087             // length of the string appropriately
00088 
00089             ServiceKeyRegistryPath.MaximumLength = 
00090             ServiceKeyRegistryPath.Length = 0;
00091         }
00092     }
00093 
00094     // If there is some registry path given, read from that
00095 
00096     if (ServiceKeyRegistryPath.Length != 0 && ServiceKeyRegistryPath.Buffer != NULL)
00097     {
00098         HANDLE hKey;
00099 
00100         // Open the registry for reading
00101 
00102         ntStatus = cbm_registry_open_for_read(&hKey, &ServiceKeyRegistryPath);
00103 
00104         if (NT_SUCCESS(ntStatus))
00105         {
00106             // the cable type
00107 
00108             ULONG iecCable = IEC_CABLETYPE_AUTO;
00109 
00110 #if DBG
00111             // In debugging versions, make sure the DebugFlags
00112             // are read from the registry
00113 
00114             cbm_registry_read_ulong(hKey, L"DebugFlags", &DbgFlags);
00115 
00116 #endif // #if DBG
00117 
00118             if (Pdx)
00119             {
00120                 //
00121                 // update the cable type
00122                 //
00123 
00124                 cbm_registry_read_ulong(hKey, L"CableType", &iecCable);
00125 
00126                 cbmiec_set_cabletype(Pdx, iecCable);
00127 
00128                 //
00129                 // update if we are requested to permanently lock the parallel port
00130                 //
00131 
00132                 iecCable = 1; // default is: Yes, lock
00133                 cbm_registry_read_ulong(hKey, L"PermanentlyLock", &iecCable);
00134                 Pdx->ParallelPortLock = iecCable ? TRUE : FALSE;
00135 
00136             }
00137 
00138             // initialize the libiec library
00139 
00140             cbmiec_global_init(&hKey);
00141 
00142             // we're done with the registry
00143 
00144             cbm_registry_close(hKey);
00145         }
00146         else
00147         {
00148             // An error occured. 
00149             // In this case, initialize the libiec with defaults
00150 
00151             cbmiec_global_init(NULL);
00152         }
00153     }
00154     else
00155     {
00156         // No registry path is given.
00157         // In this case, initialize the libiec with defaults
00158 
00159         cbmiec_global_init(NULL);
00160     }
00161 
00162     //
00163     // If requested by the registry, lock the parallel port
00164     //
00165 
00166     if (Pdx && Pdx->ParallelPortLock && Pdx->ParallelPortIsLocked == FALSE)
00167     {
00168         cbm_lock_parport(Pdx);
00169     }
00170 
00171     FUNC_LEAVE();
00172 }
00173 
00190 NTSTATUS
00191 DriverCommonInit(IN PDRIVER_OBJECT Driverobject, IN PUNICODE_STRING RegistryPath)
00192 {
00193     FUNC_ENTER();
00194 
00195     // If performance evaluation is active, initialize that
00196 
00197     PERF_INIT();
00198 
00199     // Initialize the settings from the registry
00200 
00201     cbm_init_registry(RegistryPath, NULL);
00202 
00203     // set the function pointers to our driver
00204 
00205     Driverobject->DriverUnload = DriverUnload;
00206     Driverobject->MajorFunction[IRP_MJ_CREATE] = cbm_createopenclose;
00207     Driverobject->MajorFunction[IRP_MJ_CLOSE] = cbm_createopenclose;
00208     Driverobject->MajorFunction[IRP_MJ_CLEANUP] = cbm_cleanup;
00209     Driverobject->MajorFunction[IRP_MJ_READ] = cbm_readwrite;
00210     Driverobject->MajorFunction[IRP_MJ_WRITE] = cbm_readwrite;
00211     Driverobject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = cbm_devicecontrol;
00212 
00213     FUNC_LEAVE_NTSTATUS_CONST(STATUS_SUCCESS);
00214 }
00215 
00223 VOID
00224 DriverCommonUninit(VOID)
00225 {
00226     FUNC_ENTER();
00227 
00228     // If performance evaluation is active, stop it
00229 
00230     PERF_SAVE();
00231 
00232     // If we allocated memory for the service key registry
00233     // path, free that memory.
00234 
00235     if (ServiceKeyRegistryPath.Buffer)
00236     {
00237         ExFreePool(ServiceKeyRegistryPath.Buffer);
00238         DBGDO(ServiceKeyRegistryPath.Buffer = NULL; 
00239         ServiceKeyRegistryPath.MaximumLength = ServiceKeyRegistryPath.Length = 0);
00240     }
00241 
00242     FUNC_LEAVE();
00243 }
00244 
00276 NTSTATUS
00277 AddDeviceCommonInit(IN PDEVICE_OBJECT Fdo, IN PUNICODE_STRING DeviceName, 
00278                     IN PCWSTR ParallelPortName)
00279 {
00280     PDEVICE_EXTENSION pdx;
00281     UNICODE_STRING parallelPortName;
00282     NTSTATUS ntStatus;
00283 
00284     FUNC_ENTER();
00285 
00286     // Initialize the Device Extension
00287 
00288     pdx = Fdo->DeviceExtension;
00289 
00290     // make sure the device extension is initialized to zero
00291 
00292     RtlZeroMemory(pdx, sizeof(*pdx));
00293 
00294     // Store the name in the device extension
00295 
00296     pdx->DeviceName.Buffer = DeviceName->Buffer;
00297     pdx->DeviceName.Length = DeviceName->Length;
00298     pdx->DeviceName.MaximumLength = DeviceName->MaximumLength;
00299 
00300     // a back-pointer to the fdo contained in the extension
00301 
00302     pdx->Fdo = Fdo;
00303 
00304     // Initialize the QUEUE object
00305 
00306     QueueInit(&pdx->IrpQueue, cbm_startio);
00307 
00308     // we want to do buffered I/O
00309     // since we are not passing very big portions of data,
00310     // the speed disadvantage is not that big
00311 
00312     Fdo->Flags |= DO_BUFFERED_IO;
00313 
00314     // Generate a UNICODE_STRING containing the name of the
00315     // parallel port driver
00316 
00317     parallelPortName.Buffer = (PWSTR) ParallelPortName;
00318     parallelPortName.Length = (USHORT) wcslen(ParallelPortName) * sizeof(WCHAR);
00319     parallelPortName.MaximumLength = parallelPortName.Length;
00320 
00321     // Mark if we are running on an machine with more than one processor
00322 
00323 /*
00324 #ifdef COMPILE_W98_API
00325     pdx->IsSMP = 0;
00326 #elif COMPILE_W2K_API
00327     pdx->IsSMP = (*KeNumberProcessors > 1) ? TRUE : FALSE;
00328 #else
00329     pdx->IsSMP = (KeNumberProcessors > 1) ? TRUE : FALSE;
00330 #endif
00331 */
00332     pdx->IsSMP = (CbmGetNumberProcessors() > 1) ? TRUE : FALSE;
00333 
00334     // Initialize the parallel port information
00335 
00336     ntStatus = ParPortInit(&parallelPortName, pdx);
00337 
00338     if (!NT_SUCCESS(ntStatus))
00339     {
00340         DBG_ERROR((DBG_PREFIX "ParPortInit() FAILED, deleting device"));
00341         LogErrorString(Fdo, CBM_START_FAILED, L"initialization of the parallel port.", NULL);
00342     }
00343 
00344     // Now, start the worker thread
00345 
00346     if (NT_SUCCESS(ntStatus))
00347     {
00348         ntStatus = cbm_start_thread(pdx);
00349     }
00350 
00351     // Now, log success to the event logger if we succeeded.
00352     // If we failed, the FDO will be deleted soon.
00353 
00354     if (NT_SUCCESS(ntStatus))
00355     {
00356         LogErrorOnly(Fdo, CBM_STARTED);
00357     }
00358 
00359     FUNC_LEAVE_NTSTATUS(ntStatus);
00360 }

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