一个加密狗的驱动源码

#define DONG_NT_DEVICE_NAME L"\\Device\\DongLpt"
#define DONG_NT_PORT_DEVICE_NAME L"\\Device\\ParallelPort"
#define DONG_WIN32_DEVICE_NAME L"\\DosDevices\\DongLpt"
#define DONG_DOS_DEVICES L"\\DosDevices\\"
#define DONG_DRIVER_NAME L"DongLpt"

#define DONG_MAX_NAME_LENGTH 50


NTSTATUS
DriverEntry(
IN PDRIVER_OBJECT pDriverObject,
IN PUNICODE_STRING pRegistryPath
)
{
ULONG NtDeviceNumber, NumParallelPorts;
NTSTATUS status = STATUS_SUCCESS;

DongInitializeEventLog(pDriverObject);

// Export other driver entry points...
pDriverObject->DriverUnload = DongDriverUnload;

pDriverObject->MajorFunction[ IRP_MJ_CREATE ] = DongDispatchOpen;
pDriverObject->MajorFunction[ IRP_MJ_CLOSE ] = DongDispatchClose;
pDriverObject->MajorFunction[ IRP_MJ_WRITE ] = DongDispatchWrite;
pDriverObject->MajorFunction[ IRP_MJ_READ ] = DongDispatchRead;
pDriverObject->MajorFunction[ IRP_MJ_CLEANUP ] = DongDispatchCleanup;

// Initialize a Device object for each parallel port
NumParallelPorts = IoGetConfigurationInformation()->ParallelCount;

for( NtDeviceNumber=0; NtDeviceNumberFlags |= DO_BUFFERED_IO;

/////////////////////////////////////////////////////////////////////////
// Initialize the Device Extension

pDevExt = pDevObj->DeviceExtension;
RtlZeroMemory(pDevExt, sizeof(DEVICE_EXTENSION));

pDevExt->DeviceObject = pDevObj;
pDevExt->NtDeviceNumber = NtDeviceNumber;

/////////////////////////////////////////////////////////////////////////
// Attach to parport device
portName.Length = 0;
   RtlAppendUnicodeToString( &portName, DONG_NT_PORT_DEVICE_NAME);
number.Length = 0;
RtlIntegerToUnicodeString( NtDeviceNumber, 10, &number);
RtlAppendUnicodeStringToString( &portName, &number);

status = IoGetDeviceObjectPointer(&portName, FILE_READ_ATTRIBUTES,
&pFileObject,
&pDevExt->PortDeviceObject);
if (!NT_SUCCESS(status))
{
IoDeleteDevice(pDevObj);
DongReportUnexpectedFailure(DONG_ERRORLOG_INIT,DONG_INIT_IoGetDeviceObjectPointer);
return status;
}

ObReferenceObjectByPointer( pDevExt->PortDeviceObject,FILE_READ_ATTRIBUTES,
NULL,KernelMode);
ObDereferenceObject(pFileObject);

pDevExt->DeviceObject->StackSize = pDevExt->PortDeviceObject->StackSize + 1;

// Get the port information from the port device object.
status = DongGetPortInfoFromPortDevice(pDevExt);
if (!NT_SUCCESS(status))
{
IoDeleteDevice(pDevObj);
return status;
}

/////////////////////////////////////////////////////////////////////////
   // Form the Win32 symbolic link name.

linkName.Length = 0;
RtlAppendUnicodeToString( &linkName, DONG_WIN32_DEVICE_NAME);
number.Length = 0;
RtlIntegerToUnicodeString( NtDeviceNumber + 1, 10, &number);
RtlAppendUnicodeStringToString( &linkName, &number);

// Create a symbolic link so our device is visible to Win32...
status = IoCreateSymbolicLink( &linkName, &deviceName);
if( !NT_SUCCESS(status))
{
IoDeleteDevice( pDevObj );
DongReportUnexpectedFailure(DONG_ERRORLOG_INIT,DONG_INIT_IoCreateSymbolicLink);
return status;
}

return status;
}

static NTSTATUS
DongGetPortInfoFromPortDevice(
IN OUT  PDEVICE_EXTENSION   pDevExt
)
{
KEVENT                      event;
PIRP                        irp;
PARALLEL_PORT_INFORMATION   portInfo;
IO_STATUS_BLOCK             ioStatus;
NTSTATUS                    status;

/////////////////////////////////////////////////////////////////////////
// Get parallel port information

KeInitializeEvent(&event, NotificationEvent, FALSE);

irp = IoBuildDeviceIoControlRequest(
IOCTL_INTERNAL_GET_PARALLEL_PORT_INFO,
pDevExt->PortDeviceObject,
NULL, 0, &portInfo,
sizeof(PARALLEL_PORT_INFORMATION),
TRUE, &event, &ioStatus);

if (!irp)
{
DongReportUnexpectedFailure(DONG_ERRORLOG_INIT,DONG_INIT_IoBuildDeviceIoControlRequest);
return STATUS_INSUFFICIENT_RESOURCES;
}

status = IoCallDriver(pDevExt->PortDeviceObject, irp);

if (!NT_SUCCESS(status))
{
DongReportUnexpectedFailure(DONG_ERRORLOG_INIT,DONG_INIT_IoCallDriver);
return status;
}

status = KeWaitForSingleObject(&event, Executive, KernelMode, FALSE, NULL);

if (!NT_SUCCESS(status))
{
DongReportUnexpectedFailure(DONG_ERRORLOG_INIT,DONG_INIT_KeWaitForSingleObject);
return status;
}

pDevExt->OriginalController = portInfo.OriginalController;
pDevExt->Controller = portInfo.Controller;
pDevExt->SpanOfController = portInfo.SpanOfController;
pDevExt->FreePort = portInfo.FreePort;
pDevExt->TryAllocatePort = portInfo.TryAllocatePort;
pDevExt->PortContext = portInfo.Context;

// Check register span
if (pDevExt->SpanOfController < DONG_REGISTER_SPAN)
{
DongReportUnexpectedFailure(DONG_ERRORLOG_INIT,DONG_INIT_RegisterSpan);
return STATUS_INSUFFICIENT_RESOURCES;
}

return STATUS_SUCCESS;
}