extern "C"
{
#include <NTDDK.h>
#include <myioctl.h>
}
#include <Unicode.h>
typedef struct _DEVICE_EXTENSION
{
PDEVICE_OBJECT pDevice;
ULONG DeviceNumber;
CUString DeviceName;
CUString SymLinkName;
PCHAR deviceBuffer;
ULONG deviceBufferSize;
ULONG xferSize;
ULONG CurrentSize;
ULONG currentrpos;
ULONG currentwpos;
} DEVICE_EXTENSION, *PDEVICE_EXTENSION;
static NTSTATUS CreateDevice (IN PDRIVER_OBJECT pDriverObject,IN ULONG DeviceNumber);
NTSTATUS DispatchRead( IN PDEVICE_OBJECT pDO,IN PIRP pIrp);
NTSTATUS DispatchWrite( IN PDEVICE_OBJECT pDO, IN PIRP pIrp);
NTSTATUS DispatchCreate(IN PDEVICE_OBJECT DeviceObject,IN PIRP pIrp);
NTSTATUS DispatchClose(IN PDEVICE_OBJECT DeviceObject,IN PIRP pIrp);
NTSTATUS DispatchIoControl(IN PDEVICE_OBJECT pDO,IN PIRP pIrp );
static VOID DriverUnload (IN PDRIVER_OBJECT pDriverObject);
extern "C" NTSTATUS DriverEntry (IN PDRIVER_OBJECT pDriverObject,
IN PUNICODE_STRING pRegistryPath)
{
ULONG ulDeviceNumber = 0;
NTSTATUS status;
DbgPrint(("Driver Entry Called"));
pDriverObject->MajorFunction[IRP_MJ_CREATE] = DispatchCreate;
pDriverObject->MajorFunction[IRP_MJ_CLOSE] = DispatchClose;
pDriverObject->MajorFunction[IRP_MJ_READ] = DispatchRead;
pDriverObject->MajorFunction[IRP_MJ_WRITE] = DispatchWrite;
pDriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = DispatchIoControl;
pDriverObject->DriverUnload = DriverUnload;
status = CreateDevice(pDriverObject, ulDeviceNumber);
return status;
}
NTSTATUS CreateDevice (IN PDRIVER_OBJECT pDriverObject, IN ULONG ulDeviceNumber)
{
NTSTATUS status;
PDEVICE_OBJECT pDevObj;
PDEVICE_EXTENSION pDevExt;
CUString devName("\\Device\\MINIMAL");
devName += CUString(ulDeviceNumber);
status =IoCreateDevice( pDriverObject,sizeof(DEVICE_EXTENSION),
&(UNICODE_STRING)devName,FILE_DEVICE_UNKNOWN,0,TRUE,&pDevObj );
if (!NT_SUCCESS(status))
return status;
DbgPrint(("device is created"));
pDevExt = (PDEVICE_EXTENSION)pDevObj->DeviceExtension;
pDevExt->pDevice = pDevObj;
pDevExt->DeviceNumber = ulDeviceNumber;
pDevExt->DeviceName = devName;
CUString symLinkName("\\??\\MIN");
symLinkName += CUString(ulDeviceNumber+1);
pDevExt->SymLinkName = symLinkName;
pDevObj->Flags |= DO_BUFFERED_IO;
status = IoCreateSymbolicLink( &(UNICODE_STRING)symLinkName, &(UNICODE_STRING)devName );
pDevExt->xferSize = 8192;
pDevExt->deviceBuffer = (PCHAR)ExAllocatePool(PagedPool,pDevExt->xferSize);
pDevExt->CurrentSize = 0;
pDevExt->currentrpos = 0;
pDevExt->currentwpos = 0;
if (pDevExt->deviceBuffer == NULL)
{
status = STATUS_INSUFFICIENT_RESOURCES;
pDevExt->xferSize = 0;
DbgPrint("Buffer is failed");
}
if (!NT_SUCCESS(status))
{
IoDeleteDevice( pDevObj );
return status;
}
return STATUS_SUCCESS;
}
NTSTATUS DispatchCreate(IN PDEVICE_OBJECT DeviceObject,IN PIRP pIrp)
{
PDEVICE_EXTENSION pDevExt = (PDEVICE_EXTENSION)DeviceObject->DeviceExtension;
pIrp->IoStatus.Status = STATUS_SUCCESS;
pIrp->IoStatus.Information = 0;
DbgPrint("flags is %x",DeviceObject->Characteristics);
if((pIrp -> Flags & IRP_WRITE_OPERATION) == IRP_WRITE_OPERATION)
DbgPrint(("WRITE ONLYOUTBUFFER->osize=pDE->xferSize; CALLED"));
IoCompleteRequest(pIrp,IO_NO_INCREMENT);
DbgPrint(("CREATE CALLED"));
return STATUS_SUCCESS;
}
NTSTATUS DispatchIoControl(IN PDEVICE_OBJECT pDO,IN PIRP pIrp )
{
NTSTATUS status = STATUS_SUCCESS;
PDEVICE_EXTENSION pDE=(PDEVICE_EXTENSION)pDO->DeviceExtension;
PCHAR temp;
ULONG inSize;
ULONG outSize;
ULONG controlCode;
IN_BUFFER *PIN_BUFFER;
OUT_BUFFER *POUT_BUFFER;
PIO_STACK_LOCATION pIrpStack;
pIrpStack = IoGetCurrentIrpStackLocation( pIrp );
PIN_BUFFER = (struct _IN_BUFFER *)pIrp->AssociatedIrp.SystemBuffer;
POUT_BUFFER = (struct _OUT_BUFFER *)pIrp->UserBuffer;
controlCode = pIrpStack->Parameters.DeviceIoControl.IoControlCode;
inSize = pIrpStack->Parameters.DeviceIoControl.InputBufferLength;
outSize = pIrpStack->Parameters.DeviceIoControl.OutputBufferLength;
if (inSize < sizeof(PIN_BUFFER) ||outSize < sizeof(POUT_BUFFER))
{
status = STATUS_INVALID_BUFFER_SIZE;
return status;
}
switch(controlCode)
{
case IOCTL_GET_SIZE:
POUT_BUFFER->devBufferSize=pDE->xferSize;
break;
case IOCTL_SET_SIZE:
temp = (PCHAR)ExAllocatePool(PagedPool,pDE->xferSize);
RtlCopyMemory(temp,pDE->deviceBuffer,pDE->xferSize);
ExFreePool( pDE->deviceBuffer );
pDE->xferSize=PIN_BUFFER->devBufferSize;
DbgPrint(("Buffer Size sufficient"));
pDE->deviceBuffer = (PCHAR)ExAllocatePool(PagedPool,pDE->xferSize);
RtlCopyMemory(pDE->deviceBuffer,temp,pDE->xferSize);
POUT_BUFFER->devBufferSize=pDE->xferSize;
break;
default:
status = STATUS_INVALID_DEVICE_REQUEST;
break;
}
pIrp->IoStatus.Information = 0;
IoCompleteRequest( pIrp, IO_NO_INCREMENT );
return status;
}
NTSTATUS DispatchClose(IN PDEVICE_OBJECT DeviceObject,IN PIRP pIrp)
{
PDEVICE_EXTENSION pDE = (PDEVICE_EXTENSION)DeviceObject->DeviceExtension;
pIrp->IoStatus.Status = STATUS_SUCCESS;
pIrp->IoStatus.Information = 0;
ExFreePool( pDE->deviceBuffer );
IoCompleteRequest(pIrp,IO_NO_INCREMENT);
DbgPrint(("CLOSE CALLED"));
return STATUS_SUCCESS;
}
NTSTATUS DispatchRead(IN PDEVICE_OBJECT pDO,IN PIRP pIrp)
{
NTSTATUS status = STATUS_SUCCESS;
PCHAR userBuffer;
ULONG xferSize;
PIO_STACK_LOCATION pIrpStack = IoGetCurrentIrpStackLocation( pIrp );
PDEVICE_EXTENSION pDE = (PDEVICE_EXTENSION)pDO->DeviceExtension;
xferSize = pIrpStack->Parameters.Read.Length;
userBuffer = (PCHAR)pIrp->AssociatedIrp.SystemBuffer;
if(pDE->currentrpos >= pDE->CurrentSize)
goto out;
if(xferSize + pDE->currentrpos > pDE -> CurrentSize)
xferSize = pDE->CurrentSize-pDE->currentrpos;
RtlCopyMemory(userBuffer,pDE->deviceBuffer+ pDE->currentrpos,xferSize);
pIrp->IoStatus.Status = status;
pIrp->IoStatus.Information = xferSize;
pDE->currentrpos += xferSize;
out:
DbgPrint(("Read entry called"));
IoCompleteRequest( pIrp, IO_NO_INCREMENT );
return status;
}
NTSTATUS DispatchWrite(IN PDEVICE_OBJECT pDO, IN PIRP pIrp)
{
NTSTATUS status = STATUS_SUCCESS;
PCHAR userBuffer;
ULONG xferSize;
PDEVICE_EXTENSION pDE;
PIO_STACK_LOCATION pIrpStack;
pIrpStack = IoGetCurrentIrpStackLocation( pIrp );
pDE = (PDEVICE_EXTENSION)pDO->DeviceExtension;
xferSize = pIrpStack->Parameters.Write.Length;
userBuffer =(PCHAR)pIrp->AssociatedIrp.SystemBuffer;
if (userBuffer == NULL)
{
status = STATUS_INSUFFICIENT_RESOURCES;
xferSize = 0;
DbgPrint("Userbuffer is Failed");
goto out;
}
if(pDE->currentwpos >= pDE->xferSize)
goto out;
if(pDE->currentwpos+xferSize > pDE -> xferSize)
xferSize = pDE -> xferSize - pDE->currentwpos;
RtlCopyMemory( pDE->deviceBuffer, userBuffer,xferSize );
pIrp->IoStatus.Status = status;
pIrp->IoStatus.Information = xferSize;
pDE->CurrentSize += xferSize;
pDE->currentwpos += xferSize;
out:
DbgPrint(("Write entry called"));
IoCompleteRequest( pIrp, IO_NO_INCREMENT );
return status;
}
VOID DriverUnload (IN PDRIVER_OBJECT pDriverObject)
{
PDEVICE_OBJECT pDevObj;
PDEVICE_EXTENSION pDevExt;
UNICODE_STRING pLinkName;
pDevObj= pDriverObject->DeviceObject;
pDevExt = (PDEVICE_EXTENSION)pDevObj->DeviceExtension;
pLinkName = pDevExt->SymLinkName;
IoDeleteSymbolicLink(&pLinkName);
pDevExt->SymLinkName.Free();
pDevExt->DeviceName.Free();
IoDeleteDevice( pDevExt->pDevice );
DbgPrint(("Driver Unload completed"));
}
{
#include <NTDDK.h>
#include <myioctl.h>
}
#include <Unicode.h>
typedef struct _DEVICE_EXTENSION
{
PDEVICE_OBJECT pDevice;
ULONG DeviceNumber;
CUString DeviceName;
CUString SymLinkName;
PCHAR deviceBuffer;
ULONG deviceBufferSize;
ULONG xferSize;
ULONG CurrentSize;
ULONG currentrpos;
ULONG currentwpos;
} DEVICE_EXTENSION, *PDEVICE_EXTENSION;
static NTSTATUS CreateDevice (IN PDRIVER_OBJECT pDriverObject,IN ULONG DeviceNumber);
NTSTATUS DispatchRead( IN PDEVICE_OBJECT pDO,IN PIRP pIrp);
NTSTATUS DispatchWrite( IN PDEVICE_OBJECT pDO, IN PIRP pIrp);
NTSTATUS DispatchCreate(IN PDEVICE_OBJECT DeviceObject,IN PIRP pIrp);
NTSTATUS DispatchClose(IN PDEVICE_OBJECT DeviceObject,IN PIRP pIrp);
NTSTATUS DispatchIoControl(IN PDEVICE_OBJECT pDO,IN PIRP pIrp );
static VOID DriverUnload (IN PDRIVER_OBJECT pDriverObject);
extern "C" NTSTATUS DriverEntry (IN PDRIVER_OBJECT pDriverObject,
IN PUNICODE_STRING pRegistryPath)
{
ULONG ulDeviceNumber = 0;
NTSTATUS status;
DbgPrint(("Driver Entry Called"));
pDriverObject->MajorFunction[IRP_MJ_CREATE] = DispatchCreate;
pDriverObject->MajorFunction[IRP_MJ_CLOSE] = DispatchClose;
pDriverObject->MajorFunction[IRP_MJ_READ] = DispatchRead;
pDriverObject->MajorFunction[IRP_MJ_WRITE] = DispatchWrite;
pDriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = DispatchIoControl;
pDriverObject->DriverUnload = DriverUnload;
status = CreateDevice(pDriverObject, ulDeviceNumber);
return status;
}
NTSTATUS CreateDevice (IN PDRIVER_OBJECT pDriverObject, IN ULONG ulDeviceNumber)
{
NTSTATUS status;
PDEVICE_OBJECT pDevObj;
PDEVICE_EXTENSION pDevExt;
CUString devName("\\Device\\MINIMAL");
devName += CUString(ulDeviceNumber);
status =IoCreateDevice( pDriverObject,sizeof(DEVICE_EXTENSION),
&(UNICODE_STRING)devName,FILE_DEVICE_UNKNOWN,0,TRUE,&pDevObj );
if (!NT_SUCCESS(status))
return status;
DbgPrint(("device is created"));
pDevExt = (PDEVICE_EXTENSION)pDevObj->DeviceExtension;
pDevExt->pDevice = pDevObj;
pDevExt->DeviceNumber = ulDeviceNumber;
pDevExt->DeviceName = devName;
CUString symLinkName("\\??\\MIN");
symLinkName += CUString(ulDeviceNumber+1);
pDevExt->SymLinkName = symLinkName;
pDevObj->Flags |= DO_BUFFERED_IO;
status = IoCreateSymbolicLink( &(UNICODE_STRING)symLinkName, &(UNICODE_STRING)devName );
pDevExt->xferSize = 8192;
pDevExt->deviceBuffer = (PCHAR)ExAllocatePool(PagedPool,pDevExt->xferSize);
pDevExt->CurrentSize = 0;
pDevExt->currentrpos = 0;
pDevExt->currentwpos = 0;
if (pDevExt->deviceBuffer == NULL)
{
status = STATUS_INSUFFICIENT_RESOURCES;
pDevExt->xferSize = 0;
DbgPrint("Buffer is failed");
}
if (!NT_SUCCESS(status))
{
IoDeleteDevice( pDevObj );
return status;
}
return STATUS_SUCCESS;
}
NTSTATUS DispatchCreate(IN PDEVICE_OBJECT DeviceObject,IN PIRP pIrp)
{
PDEVICE_EXTENSION pDevExt = (PDEVICE_EXTENSION)DeviceObject->DeviceExtension;
pIrp->IoStatus.Status = STATUS_SUCCESS;
pIrp->IoStatus.Information = 0;
DbgPrint("flags is %x",DeviceObject->Characteristics);
if((pIrp -> Flags & IRP_WRITE_OPERATION) == IRP_WRITE_OPERATION)
DbgPrint(("WRITE ONLYOUTBUFFER->osize=pDE->xferSize; CALLED"));
IoCompleteRequest(pIrp,IO_NO_INCREMENT);
DbgPrint(("CREATE CALLED"));
return STATUS_SUCCESS;
}
NTSTATUS DispatchIoControl(IN PDEVICE_OBJECT pDO,IN PIRP pIrp )
{
NTSTATUS status = STATUS_SUCCESS;
PDEVICE_EXTENSION pDE=(PDEVICE_EXTENSION)pDO->DeviceExtension;
PCHAR temp;
ULONG inSize;
ULONG outSize;
ULONG controlCode;
IN_BUFFER *PIN_BUFFER;
OUT_BUFFER *POUT_BUFFER;
PIO_STACK_LOCATION pIrpStack;
pIrpStack = IoGetCurrentIrpStackLocation( pIrp );
PIN_BUFFER = (struct _IN_BUFFER *)pIrp->AssociatedIrp.SystemBuffer;
POUT_BUFFER = (struct _OUT_BUFFER *)pIrp->UserBuffer;
controlCode = pIrpStack->Parameters.DeviceIoControl.IoControlCode;
inSize = pIrpStack->Parameters.DeviceIoControl.InputBufferLength;
outSize = pIrpStack->Parameters.DeviceIoControl.OutputBufferLength;
if (inSize < sizeof(PIN_BUFFER) ||outSize < sizeof(POUT_BUFFER))
{
status = STATUS_INVALID_BUFFER_SIZE;
return status;
}
switch(controlCode)
{
case IOCTL_GET_SIZE:
POUT_BUFFER->devBufferSize=pDE->xferSize;
break;
case IOCTL_SET_SIZE:
temp = (PCHAR)ExAllocatePool(PagedPool,pDE->xferSize);
RtlCopyMemory(temp,pDE->deviceBuffer,pDE->xferSize);
ExFreePool( pDE->deviceBuffer );
pDE->xferSize=PIN_BUFFER->devBufferSize;
DbgPrint(("Buffer Size sufficient"));
pDE->deviceBuffer = (PCHAR)ExAllocatePool(PagedPool,pDE->xferSize);
RtlCopyMemory(pDE->deviceBuffer,temp,pDE->xferSize);
POUT_BUFFER->devBufferSize=pDE->xferSize;
break;
default:
status = STATUS_INVALID_DEVICE_REQUEST;
break;
}
pIrp->IoStatus.Information = 0;
IoCompleteRequest( pIrp, IO_NO_INCREMENT );
return status;
}
NTSTATUS DispatchClose(IN PDEVICE_OBJECT DeviceObject,IN PIRP pIrp)
{
PDEVICE_EXTENSION pDE = (PDEVICE_EXTENSION)DeviceObject->DeviceExtension;
pIrp->IoStatus.Status = STATUS_SUCCESS;
pIrp->IoStatus.Information = 0;
ExFreePool( pDE->deviceBuffer );
IoCompleteRequest(pIrp,IO_NO_INCREMENT);
DbgPrint(("CLOSE CALLED"));
return STATUS_SUCCESS;
}
NTSTATUS DispatchRead(IN PDEVICE_OBJECT pDO,IN PIRP pIrp)
{
NTSTATUS status = STATUS_SUCCESS;
PCHAR userBuffer;
ULONG xferSize;
PIO_STACK_LOCATION pIrpStack = IoGetCurrentIrpStackLocation( pIrp );
PDEVICE_EXTENSION pDE = (PDEVICE_EXTENSION)pDO->DeviceExtension;
xferSize = pIrpStack->Parameters.Read.Length;
userBuffer = (PCHAR)pIrp->AssociatedIrp.SystemBuffer;
if(pDE->currentrpos >= pDE->CurrentSize)
goto out;
if(xferSize + pDE->currentrpos > pDE -> CurrentSize)
xferSize = pDE->CurrentSize-pDE->currentrpos;
RtlCopyMemory(userBuffer,pDE->deviceBuffer+ pDE->currentrpos,xferSize);
pIrp->IoStatus.Status = status;
pIrp->IoStatus.Information = xferSize;
pDE->currentrpos += xferSize;
out:
DbgPrint(("Read entry called"));
IoCompleteRequest( pIrp, IO_NO_INCREMENT );
return status;
}
NTSTATUS DispatchWrite(IN PDEVICE_OBJECT pDO, IN PIRP pIrp)
{
NTSTATUS status = STATUS_SUCCESS;
PCHAR userBuffer;
ULONG xferSize;
PDEVICE_EXTENSION pDE;
PIO_STACK_LOCATION pIrpStack;
pIrpStack = IoGetCurrentIrpStackLocation( pIrp );
pDE = (PDEVICE_EXTENSION)pDO->DeviceExtension;
xferSize = pIrpStack->Parameters.Write.Length;
userBuffer =(PCHAR)pIrp->AssociatedIrp.SystemBuffer;
if (userBuffer == NULL)
{
status = STATUS_INSUFFICIENT_RESOURCES;
xferSize = 0;
DbgPrint("Userbuffer is Failed");
goto out;
}
if(pDE->currentwpos >= pDE->xferSize)
goto out;
if(pDE->currentwpos+xferSize > pDE -> xferSize)
xferSize = pDE -> xferSize - pDE->currentwpos;
RtlCopyMemory( pDE->deviceBuffer, userBuffer,xferSize );
pIrp->IoStatus.Status = status;
pIrp->IoStatus.Information = xferSize;
pDE->CurrentSize += xferSize;
pDE->currentwpos += xferSize;
out:
DbgPrint(("Write entry called"));
IoCompleteRequest( pIrp, IO_NO_INCREMENT );
return status;
}
VOID DriverUnload (IN PDRIVER_OBJECT pDriverObject)
{
PDEVICE_OBJECT pDevObj;
PDEVICE_EXTENSION pDevExt;
UNICODE_STRING pLinkName;
pDevObj= pDriverObject->DeviceObject;
pDevExt = (PDEVICE_EXTENSION)pDevObj->DeviceExtension;
pLinkName = pDevExt->SymLinkName;
IoDeleteSymbolicLink(&pLinkName);
pDevExt->SymLinkName.Free();
pDevExt->DeviceName.Free();
IoDeleteDevice( pDevExt->pDevice );
DbgPrint(("Driver Unload completed"));
}
0 nhận xét:
Đăng nhận xét