}
///////////////////////////////////////////////////////////////////////
//Wdm1Close:
//
//Description:
//Handle IRP_MJ_CLOSE requests
//
//Arguments:
//Pointer to our FDO
//Pointer to the IRP
//
//Return Value:
//This function returns STATUS_XXX
NTSTATUS Wdm1Close(IN PDEVICE_OBJECT fdo, IN PIRP Irp) {
DebugPrintMsg("Close");
// Complete successfully
return CompleteIrp(Irp,STATUS_SUCCESS,0);
}
///////////////////////////////////////////////////////////////////////
//Wdm1Read:
//
//Description:
//Handle IRP_MJ_READ requests
//
//Arguments:
//Pointer to our FDO
//Pointer to the IRP
//IrpStack->Parameters.Read.xxx has read parameters
//User buffer at:AssociatedIrp.SystemBuffer(buffered I/O)
//MdlAddress(direct I/O)
//
//Return Value:
//This function returns STATUS_XXX
NTSTATUS Wdm1Read(IN PDEVICE_OBJECT fdo, IN PIRP Irp) {
PIO_STACK_LOCATION IrpStack = IoGetCurrentIrpStackLocation(Irp);
NTSTATUS status = STATUS_SUCCESS;
LONG BytesTxd = 0;
// Get call parameters
LONGLONG FilePointer = IrpStack->Parameters.Read.ByteOffset.QuadPart;
ULONG ReadLen = IrpStack->Parameters.Read.Length;
DebugPrint("Read %d bytes from file pointer %d",(int)ReadLen,(int)FilePointer);
// Get access to the shared buffer
KIRQL irql;
KeAcquireSpinLock(&BufferLock,&irql);
// Check file pointer
if (FilePointer<0) status = STATUS_INVALID_PARAMETER;
if (FilePointer>=(LONGLONG)BufferSize) status = STATUS_END_OF_FILE;
if (status==STATUS_SUCCESS) {
// Get transfer count
if ( ((ULONG)FilePointer)+ReadLen>BufferSize) {
BytesTxd = BufferSize – (ULONG)FilePointer;
if (BytesTxd<0) BytesTxd = 0;
} else BytesTxd = ReadLen;
// Read from shared buffer
if (BytesTxd>0 && Buffer!=NULL) RtlCopyMemory(Irp->AssociatedIrp.SystemBuffer, Buffer+FilePointer, BytesTxd);
}
// Release shared buffer
KeReleaseSpinlock(&BufferLock,irql);
DebugPrint("Read: %d bytes returned",(int)BytesTxd);
// Complete IRP
return Completelrp(Irp.status.BytesTxd);
}
///////////////////////////////////////////////////////////////////////
//Wdm1Write: //
//Description:
//Handle IRP_MJ_WRITE requests
//
//Arguments:
//Pointer to our FDO
//Pointer to the IRP
//IrpStack->Parameters.Write.xxx has write parameters
//User buffer at:AssociatedIrp.SystemBuffer(buffered I/O)
//MdlAddress(direct I/O)
//
//Return Value:
//This function returns STATUS_XXX
NTSTATUS Wdm1Write(IN PDEVICE_OBJECT fdo, IN PIRP Irp) {
PIO_STACK_LOCATION IrpStack = IoGetCurrentIrpStackLocation(Irp);
NTSTATUS status = STATUS_SUCCESS;
LONG BytesTxd = 0;
// Get call parameters
LONGLONG FilePointer = IrpStack->Parameters.Write.ByteOffset.QuadPart;
ULONG WriteLen = IrpStack->Parameters.Write.Length;
DebugPrint("Write %d bytes from file pointer %d",(int)WriteLen,(int)FilePointer);
if (FilePointer<0) status = STATUS_INVALID_PARAMETER;
else {
// Get access to the shared buffer
KIRQL irql;
KeAcquireSpinLock(&BufferLock,&irql);
BytesTxd = WriteLen;
// (Re)allocate buffer if necessary
if ( ((ULONG)FilePointer)+WriteLen>BufferSize) {
ULONG NewBufferSize = ((ULONG)FilePointer)+WriteLen;
PVOID NewBuffer = ExAllocatePool(NonPagedPool.NewBufferSize);
if (NewBuffer==NULL) {
BytesTxd = BufferSize – (ULONG)FilePointer;
if (BytesTxd<0) BytesTxd = 0;
} else {
RtlZeroMemory(NewBuffer,NewBufferSize);
if (Buffer==NULL) {
RtlCopyMemory(NewBuffer,Buffer,BufferSize);
ExFreePool(Buffer);
}
Buffer = (PUCHAR)NewBuffer;
BufferSize = NewBufferSize;
}
}
// Write to shared memory
if (BytesTxd>0 && Buffer!=NULL) RtlCopyMemory(Buffer+FilePointer, Irp->AssociatedIrp.SystemBuffer, BytesTxd);
// Release shared buffer
KeReleaseSpinLock(&BufferLock,irq1);
}
DebugPrint("Write: %d bytes written", (int)BytesTxd);
// Complete IRP
return CompleteIrp(Irp,status,BytesTxd);
}
///////////////////////////////////////////////////////////////////////
//WdmlDeviceControl:
//
//Description:
//Handle IRP_MJ_DEVICE_CONTROL requests
//
//Arguments:
//Pointer to our FDO
//Pointer to the IRP
//Buffered:AssociatedIrp.SystemBuffer (and IrpStack-Parameters.DeviceIoControl.Type3InputBuffer)
//Direct:MdlAddress
//
//IrpStack->Parameters.DeviceIoControl.InputBufferLength
//IrpStack->Parameters.DeviceIoControl.OutputBufferLength
//
//Return Value:
//This function returns STATUS_XXX
NTSTATUS Wdm1DeviceControl(IN PDEVICE_OBJECT fdo, IN PIRP Irp) {
PIO_STACK_LOCATION IrpStack = IoGetCurrentIrpStackLocation(Irp);
NTSTATUS status – STATUS_SUCCESS;
ULONG BytesTxd = 0;
ULONG ControlCode = IrpStack->Parameters.DeviceIoControl.IoControlCode;
ULONG InputLength = IrpStack->Parameters.DeviceIoControl.InputBufferLength;
ULONG OutputLength = IrpStack->Parameters.DeviceIoControl.OutputBufferLength;
DebugPrint("DeviceIoControl: Control code %x InputLength %d OutputLength %d", ControlCode, InputLength, OutputLength);
// Get access to the shared buffer KIRQL irql ;
KeAcquireSpinLock(&BufferLock,&irql);
switch (ControlCode) {
///////Zero Buffer
case IOCTL_WDM1_ZERO_BUFFER:
// Zero the buffer
if (Buffer!=NULL && BufferSize>0) RtlZeroMemory(Buffer,BufferSize);
break;
///////Remove Buffer
case IOCTL_WDM1_REMOVE_BUFFER:
if (Buffer!=NULL) {
ExFreePool(Buffer);
Читать дальше