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

nt4/LoadUnload.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 <ntddk.h>
00021 #include "cbm_driver.h"
00022 #include <cbmioctl.h>
00023 
00024 #undef ExFreePool
00025 
00055 NTSTATUS
00056 AddDevice(IN PDRIVER_OBJECT DriverObject, IN PDEVICE_OBJECT PdoUNUSED, IN PCWSTR ParallelPortName)
00057 {
00058     PDEVICE_OBJECT fdo;
00059     UNICODE_STRING deviceNameNumber;
00060     UNICODE_STRING deviceNamePrefix;
00061     UNICODE_STRING deviceName;
00062     NTSTATUS ntStatus;
00063     WCHAR deviceNameNumberBuffer[50];
00064 
00066     static SHORT no = 0;
00067 
00068     FUNC_ENTER();
00069 
00070     UNREFERENCED_PARAMETER(PdoUNUSED);
00071 
00072     // Until now, no error has occurred
00073 
00074     ntStatus = STATUS_SUCCESS;
00075 
00076     // Create the name for the fdo
00077     // thus, this is a named driver
00078 
00079     DBG_IRQL( <= DISPATCH_LEVEL);
00080     RtlInitUnicodeString(&deviceNamePrefix, CBMDEVICENAME);
00081 
00082     // Convert variable no into a UNICODE_STRING
00083 
00084     deviceNameNumber.Length = 0;
00085     deviceNameNumber.MaximumLength = sizeof(deviceNameNumberBuffer);
00086     deviceNameNumber.Buffer = deviceNameNumberBuffer;
00087     DBG_IRQL( == PASSIVE_LEVEL);
00088     RtlIntegerToUnicodeString(no, 10, &deviceNameNumber);
00089 
00090     // Increment the number for the next device
00091 
00092     ++no;
00093 
00094     // Allocate enough space for the concatenation of deviceNamePrefix
00095     // and deviceNameNumber
00096 
00097     deviceName.MaximumLength = deviceNamePrefix.Length + deviceNameNumber.Length;
00098     deviceName.Buffer = (PWCHAR) ExAllocatePoolWithTag(NonPagedPool, 
00099         deviceName.MaximumLength, MTAG_DEVNAME);
00100 
00101     if (!deviceName.Buffer)
00102     {
00103         ntStatus = STATUS_INSUFFICIENT_RESOURCES;
00104         DBG_ERROR((DBG_PREFIX "Could not allocate memory for deviceName"))
00105         LogErrorString(NULL, CBM_START_FAILED, L"allocating memory for device name", NULL);
00106     }
00107 
00108     if (NT_SUCCESS(ntStatus))
00109     {
00110         // Concatenate both strings
00111 
00112         DBG_IRQL( < DISPATCH_LEVEL);
00113         RtlCopyUnicodeString(&deviceName, &deviceNamePrefix);
00114         DBG_IRQL( < DISPATCH_LEVEL);
00115         RtlAppendUnicodeStringToString(&deviceName, &deviceNameNumber);
00116 
00117         // create the FDO with the name just build
00118 
00119         DBG_IRQL( == PASSIVE_LEVEL);
00120         ntStatus = IoCreateDevice(DriverObject, sizeof(DEVICE_EXTENSION), &deviceName,
00121             FILE_DEVICE_UNKNOWN, FILE_DEVICE_SECURE_OPEN, TRUE, &fdo);
00122 
00123         if (!NT_SUCCESS(ntStatus))
00124         {
00125             DBG_ERROR((DBG_PREFIX "IoCreateDevice failed with 0x%08X - %s",
00126                 ntStatus, DebugNtStatus(ntStatus)));
00127             LogErrorString(NULL, CBM_START_FAILED, L"creation of the device object", NULL);
00128         }
00129     }
00130 
00131     if (NT_SUCCESS(ntStatus))
00132     {
00133         PDEVICE_EXTENSION pdx;
00134 
00135         // Initialization common to WDM and NT4 driver
00136 
00137         ntStatus = AddDeviceCommonInit(fdo, &deviceName, ParallelPortName);
00138 
00139         // mark that we are running the NT4 version of the driver
00140 
00141         pdx = fdo->DeviceExtension;
00142         pdx->IsNT4 = TRUE;
00143 
00144         if (!NT_SUCCESS(ntStatus))
00145         {
00146             // An error has occurred, thus, delete the device
00147 
00148             // If necessary, delete the buffer for the device name
00149 
00150             if (pdx->DeviceName.Buffer)
00151             {
00152                 DBG_IRQL( < DISPATCH_LEVEL);
00153                 ExFreePool(pdx->DeviceName.Buffer);
00154             }
00155 
00156             DBG_IRQL( == PASSIVE_LEVEL);
00157             IoDeleteDevice(fdo);
00158         }
00159     }
00160 
00161     FUNC_LEAVE_NTSTATUS(ntStatus);
00162 }
00163 
00164 static KMUTEX MutexDriverLoadUnload;
00165 
00178 VOID
00179 DriverUnload(IN PDRIVER_OBJECT DriverObject)
00180 {
00181     PDEVICE_OBJECT currentDevice;
00182 
00183     FUNC_ENTER();
00184 
00185     // Obtain the mutex that prevents premature unloading
00186 
00187     DBG_IRQL( < DISPATCH_LEVEL);
00188     KeWaitForMutexObject(&MutexDriverLoadUnload, Executive, KernelMode,
00189         FALSE, NULL);
00190 
00191     // Make sure every device object is deleted
00192 
00193     while (currentDevice = DriverObject->DeviceObject) 
00194     {
00195         PDEVICE_EXTENSION pdx = currentDevice->DeviceExtension;
00196 
00197         DBG_ASSERT(pdx);
00198 
00199         // Unlock the parallel port, if necessary
00200 
00201         if (pdx->ParallelPortIsLocked)
00202         {
00203             cbm_unlock_parport(pdx);
00204         }
00205 
00206         // Stop the thread of that device, if necessary
00207 
00208         cbm_stop_thread(pdx);
00209 
00210         // Uninitialize the parallel port, if necessary
00211 
00212         ParPortDeinit(pdx);
00213 
00214         // If a buffer for the device name has been allocated,
00215         // release that
00216 
00217         if (pdx->DeviceName.Buffer)
00218         {
00219             DBG_IRQL( < DISPATCH_LEVEL);
00220             ExFreePool(pdx->DeviceName.Buffer);
00221         }
00222 
00223         // Delete the device
00224         // This has to be done *after* the above, as the pdx
00225         // is not allowed to be accessed anymore here.
00226 
00227         DBG_IRQL( == PASSIVE_LEVEL);
00228         IoDeleteDevice(currentDevice);
00229     }
00230 
00231     // some more uninitialization, common to WDM and NT4 driver
00232 
00233     DriverCommonUninit();
00234 
00235 #if DBG
00236 
00237     DbgFreeMemoryBuffer();
00238 
00239 #endif
00240 
00241     // From now on, it is legal to be unloaded
00242 
00243     DBG_IRQL( <= DISPATCH_LEVEL);
00244     KeReleaseMutex(&MutexDriverLoadUnload, FALSE);
00245 
00246     FUNC_LEAVE();
00247 }
00248 
00271 NTSTATUS
00272 DriverEntry(IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING RegistryPath)
00273 {
00274     PENUMERATE enumerate;
00275     NTSTATUS ntStatus;
00276 
00277     FUNC_ENTER();
00278 
00279     // Initialize the debugging system
00280 
00281     DBG_INIT();
00282 
00283     // Initialize the mutex which should prevent premature unloading
00284 
00285     KeInitializeMutex(&MutexDriverLoadUnload, 0);
00286 
00287     // Now, obtain that mutex as first operation
00288 
00289     DBG_IRQL( < DISPATCH_LEVEL);
00290     KeWaitForMutexObject(&MutexDriverLoadUnload, Executive, KernelMode,
00291         FALSE, NULL);
00292 
00293 #if DBG
00294 
00295     DbgAllocateMemoryBuffer();
00296 
00297 #endif
00298 
00299     // Output a status message
00300 
00301     DBG_PRINT((DBG_PREFIX "CBM4NT.SYS " __DATE__ " " __TIME__));
00302 
00303     // Perform initialization common to NT4 and WDM driver
00304 
00305     ntStatus = DriverCommonInit(DriverObject, RegistryPath);
00306 
00307     // enumerate all parallel port drivers:
00308 
00309     ntStatus = ParPortEnumerateOpen(&enumerate);
00310 
00311     if (NT_SUCCESS(ntStatus))
00312     {
00313         PCWSTR DriverName;
00314 
00315         do 
00316         {
00317             ntStatus = ParPortEnumerate(enumerate,&DriverName);
00318 
00319             if (NT_SUCCESS(ntStatus) && *DriverName)
00320             {
00321                 DBG_SUCCESS((DBG_PREFIX "Drivername = \"%ws\"", DriverName));
00322                 AddDevice(DriverObject, NULL, DriverName);
00323             }
00324         } while (NT_SUCCESS(ntStatus) && *DriverName);
00325 
00326         ParPortEnumerateClose(enumerate);
00327     }
00328 
00329     // From now on, it is legal to be unloaded
00330 
00331     DBG_IRQL( <= DISPATCH_LEVEL);
00332     KeReleaseMutex(&MutexDriverLoadUnload, FALSE);
00333 
00334     FUNC_LEAVE_NTSTATUS_CONST(STATUS_SUCCESS);
00335 }

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