Code Samples From A Device Driver

Initial Method Executed By API Call

Responsibility: Responds To Specific API Command. Calls Protocol Manager.

void ProcessControlRequest(IN PDEVICE_OBJECT DeviceObject,
IN PIO_STACK_LOCATION IORequestPacketStack,
IN PIRP IORequestPacket)
{
DriverData = (DriverDataType *) DeviceObject->DeviceExtension ;

ControlCode = IORequestPacketStack->Parameters.DeviceIoControl.IoControlCode ;

InputBuffer = (DataBufferType *)IORequestPacket->AssociatedIrp.SystemBuffer ;
OutputBuffer = (DataBufferType *)IORequestPacket->AssociatedIrp.SystemBuffer ;

switch (ControlCode)
{
case IOCTL_CMD_WRITE_SCALE:
KeAcquireSpinLock(&DriverData->SpinLock,&CurrentIRQL) ;
DriverData->ScaleNumber = InputBuffer->WriteData.ScaleNumber ;
DriverData->ScaleValue[DriverData->ScaleNumber] = InputBuffer->WriteData.ScaleValue ;
KeReleaseSpinLock(&DriverData->SpinLock,CurrentIRQL) ;

WriteDataToDevice(DeviceObject) ;

IORequestPacket->IoStatus.Status = STATUS_SUCCESS ;
IORequestPacket->IoStatus.Information = sizeof(DataBufferType) ;
IoCompleteRequest(IORequestPacket,IO_NO_INCREMENT) ;

break ;

default:
IORequestPacket->IoStatus.Status = STATUS_SUCCESS ;
IORequestPacket->IoStatus.Information = 0 ;
IoCompleteRequest(IORequestPacket,IO_NO_INCREMENT) ;
break ;
}
}
The Protocol Manager

Responsibility: Handles High Level Issues. Calls Hardware Manager.

void WriteDataToDevice( IN PDEVICE_OBJECT DeviceObject )
{
DriverData = (DriverDataType *) DeviceObject->DeviceExtension ;

KeAcquireSpinLock(&DriverData->SpinLock,&CurrentIRQL) ;

ScaleNumber = DriverData->ScaleNumber ;
ScaleValue = DriverData->ScaleValue[ScaleNumber] ;

WriteDataOutput( DeviceObject, ScaleNumber, ScaleValue) ;

KeReleaseSpinLock(&DriverData->SpinLock,CurrentIRQL) ;
}
The Hardware Manager

Responsibility: Computes Hardware Parameters. Calls Hardware Mechanics Manager.

void WriteDataOutput( IN PDEVICE_OBJECT DeviceObject,
IN int ScaleNumber,
IN OutputValueType OutputValue)
{
DriverData = (DriverDataType *) DeviceObject->DeviceExtension ;

DetermineScaleOffset( ScaleNumber , &DataOutputRegisterOffset ) ;

CurrentRegister = (DataRegisterType)DriverData->DataOutputRegisterFile + DataOutputRegisterOffset ;

WriteDataToRegister( CurrentRegister , OutputValue ) ;
}
The Hardware Mechanics Manager

Responsibility: Performs Actual Hardware Interaction.

void WriteDataToRegister( DataRegisterType CurrentRegister, OutputValueType OutputValue )
{
High = (unsigned long)OutputValue + 8388608L;
High = _lrotr(High,16);
High = High & 0x0000ff;

Middle = OutputValue + 8388608L;
Middle = _lrotr(Middle,8);
Middle = Middle & 0x0000ff;

Low = (OutputValue + 8388608L) & 0x0000ff;

WRITE_PORT_UCHAR( CurrentRegister , (unsigned char)Low ) ;
WaitForTimeoutDelay(TIMEOUT_DELAY) ;
WRITE_PORT_UCHAR( CurrentRegister , (unsigned char)Middle ) ;
WaitForTimeoutDelay(TIMEOUT_DELAY) ;
WRITE_PORT_UCHAR( CurrentRegister , (unsigned char)High ) ;
WaitForTimeoutDelay(TIMEOUT_DELAY) ;
WRITE_PORT_UCHAR( CurrentRegister , (unsigned char)Low ) ;
WaitForTimeoutDelay(TIMEOUT_DELAY) ;
WRITE_PORT_UCHAR( CurrentRegister + 1 , 8 ) ;
WaitForTimeoutDelay(TIMEOUT_DELAY) ;
}
Return