extern "C" {
#include <ntddk.h>
}
#include "Unicode.h"
#define MEMSIZE 25
typedef struct DEVICE_EXTENSION {
PDEVICE_OBJECT pDevice;
ULONG DeviceNumber;
CUString ustrDeviceName;
CUString ustrSymLinkName;
char *write;
char *read;
char *deviceBuffer;
char *devBufferEnd,*rtempBuffer,*wtempBuffer;
ULONG deviceBufferSize;
int memSize,freeSize;
ULONG rxSize,wxSize,wnewSize,rnewSize;
int wflag ,rflag,rpend,wpend ;
} DEVICE_EXTENSION, *PDEVICE_EXTENSION;
static VOID DriverUnload(PDRIVER_OBJECT );
NTSTATUS CreateDevice(IN PDRIVER_OBJECT pDriverObject,IN ULONG ulDeviceNumber);
NTSTATUS DispatchCreate(IN PDEVICE_OBJECT pDevObject,IN PIRP pIrp);
NTSTATUS DispatchClose(IN PDEVICE_OBJECT pDevObject,IN PIRP pIrp);
NTSTATUS DispatchWrite(IN PDEVICE_OBJECT pDevObject,IN PIRP pIrp);
NTSTATUS DispatchRead(IN PDEVICE_OBJECT pDevObject,IN PIRP pIrp);
//VOID StartIo(IN PDEVICE_OBJECT pDO, IN PIRP pIrp);
KEVENT rEvent,wEvent;
extern "C" NTSTATUS DriverEntry(IN PDRIVER_OBJECT pDriverObject,IN PUNICODE_STRING pRegistryPath)
{
ULONG ulDeviceNumber = 0;
NTSTATUS status;
DbgPrint("Pipe Driver's DriverEntry\n");
pDriverObject->DriverUnload = DriverUnload;
status=CreateDevice(pDriverObject,ulDeviceNumber);
pDriverObject->MajorFunction[IRP_MJ_CREATE]=DispatchCreate;
pDriverObject->MajorFunction[IRP_MJ_CLOSE]=DispatchClose;
pDriverObject->MajorFunction[IRP_MJ_READ]=DispatchRead;
pDriverObject->MajorFunction[IRP_MJ_WRITE]=DispatchWrite;
KeInitializeEvent(&wEvent,NotificationEvent ,FALSE);
KeInitializeEvent(&rEvent,NotificationEvent ,FALSE);
return status;
}
VOID DriverUnload(PDRIVER_OBJECT pDriverObject)
{
PDEVICE_OBJECT pNextObj;
pNextObj=pDriverObject->DeviceObject;
DbgPrint("Pipe DriverUnload\n");
while(pNextObj!=NULL)
{
PDEVICE_EXTENSION pDevExt=(PDEVICE_EXTENSION)pNextObj->DeviceExtension;
if (pDevExt->deviceBuffer != NULL)
{
ExFreePool(pDevExt->deviceBuffer);
pDevExt->deviceBuffer = NULL;
pDevExt->deviceBufferSize = 0;
DbgPrint("Memory will be Freed\n" );
}
UNICODE_STRING pLinkName=pDevExt->ustrSymLinkName;
IoDeleteSymbolicLink(&pLinkName);
pNextObj=pNextObj->NextDevice;
IoDeleteDevice(pDevExt->pDevice);
}
}
NTSTATUS CreateDevice(IN PDRIVER_OBJECT pDriverObject,IN ULONG ulDeviceNumber)
{
NTSTATUS status;
PDEVICE_OBJECT pDevObj;
PDEVICE_EXTENSION pDevExt;
DbgPrint("Pipe device\n");
CUString devName("\\Device\\PipeDevice");
devName+=CUString(ulDeviceNumber);
status=IoCreateDevice(pDriverObject,sizeof(DEVICE_EXTENSION),&(UNICODE_STRING)devName,
FILE_DEVICE_UNKNOWN,FILE_WRITE_ONCE_MEDIA,FALSE,&pDevObj);
if(!NT_SUCCESS(status))
return status;
pDevObj->Flags |= DO_BUFFERED_IO;
pDevExt=(PDEVICE_EXTENSION)pDevObj->DeviceExtension;
pDevExt->pDevice=pDevObj;
pDevExt->DeviceNumber=ulDeviceNumber;
pDevExt->ustrDeviceName=devName;
pDevExt->deviceBuffer=NULL;
pDevExt->deviceBufferSize=0;
pDevExt->memSize = MEMSIZE;
CUString symLinkName("\\??\\pipe");
symLinkName+=CUString(ulDeviceNumber+1);
pDevExt->ustrSymLinkName=symLinkName;
status=IoCreateSymbolicLink(&(UNICODE_STRING)symLinkName,
&(UNICODE_STRING)devName);
if(!NT_SUCCESS(status))
{
IoDeleteDevice(pDevObj);
return status;
}
pDevExt->deviceBuffer=(char *)ExAllocatePool(PagedPool,pDevExt->memSize + 1);
if(pDevExt->deviceBuffer==NULL)
return STATUS_INSUFFICIENT_RESOURCES;
DbgPrint("Memory will be Created with Add: %x\n",pDevExt->deviceBuffer);
pDevExt->deviceBufferSize=0;
pDevExt->write=pDevExt->read=pDevExt->deviceBuffer;
pDevExt->devBufferEnd = pDevExt->deviceBuffer + pDevExt->memSize ;
pDevExt->freeSize = MEMSIZE ;//pDevExt->memSize - pDevExt->deviceBufferSize;
pDevExt->rxSize = pDevExt->wxSize = pDevExt->wnewSize = pDevExt->rnewSize = 0;
pDevExt->rtempBuffer = pDevExt->wtempBuffer = NULL;
pDevExt->rflag = 0;
pDevExt->wflag = 1;
pDevExt->rpend = pDevExt->wpend = 0;
return STATUS_SUCCESS;
}
NTSTATUS DispatchCreate(IN PDEVICE_OBJECT pDevObj,IN PIRP pIrp)
{
pIrp->IoStatus.Status=STATUS_SUCCESS;
pIrp->IoStatus.Information =0;
IoCompleteRequest(pIrp,IO_NO_INCREMENT);
DbgPrint(("Dispatch Create function\n"));
return STATUS_SUCCESS;
}
NTSTATUS DispatchClose(IN PDEVICE_OBJECT pDevObject,IN PIRP pIrp)
{
pIrp->IoStatus.Status=STATUS_SUCCESS;
pIrp->IoStatus.Information=0;
IoCompleteRequest(pIrp,IO_NO_INCREMENT);
DbgPrint("DispatchClose Function\n");
return STATUS_SUCCESS;
}
NTSTATUS DispatchWrite(IN PDEVICE_OBJECT pDevObject,IN PIRP pIrp)
{
NTSTATUS status=STATUS_SUCCESS,wStatus;
PDEVICE_EXTENSION pDE=(PDEVICE_EXTENSION)pDevObject->DeviceExtension;
char *userBuffer;
PIO_STACK_LOCATION pIrpStack;
pIrpStack=IoGetCurrentIrpStackLocation(pIrp);
userBuffer=(char *)pIrp->AssociatedIrp.SystemBuffer;
ULONG xferSize=pIrpStack->Parameters.Write.Length;
pDE->wtempBuffer = userBuffer;
pDE->wnewSize = xferSize;
while(pDE->wnewSize >0)
{
pDE->wxSize = pDE->wnewSize;
if(pDE->wflag == 0)
{
KeResetEvent(&wEvent);
DbgPrint("Write in Sleep \n");
wStatus = KeWaitForSingleObject(&wEvent,Executive, KernelMode,FALSE,NULL);
}
if(pDE->write >= pDE->read)
pDE->wxSize = (pDE->wxSize <= (ULONG)(pDE->devBufferEnd - pDE->write)) ? pDE->wxSize : pDE->devBufferEnd-pDE->write;
else
pDE->wxSize = (pDE->wxSize <= (ULONG)(pDE->read - pDE->write)) ? pDE->wxSize : (pDE->read - pDE->write);
RtlCopyMemory(pDE->write,pDE->wtempBuffer,pDE->wxSize);
pDE->write += pDE->wxSize;
pDE->freeSize -= pDE->wxSize;
pDE->wnewSize -= pDE->wxSize;
pDE->wtempBuffer += pDE->wxSize;
pDE->deviceBufferSize += pDE->wxSize;
if(pDE->write >= pDE->devBufferEnd){
pDE->write = pDE->deviceBuffer;
}
//if(pDE->deviceBufferSize > 0)
if(pDE->freeSize <= 0)
{
pDE->freeSize = 0;
pDE->wflag = 0;
}
DbgPrint("device Buffer SIZE [%d]",pDE->deviceBufferSize);
KdPrint(("Free Size [%d]", pDE->freeSize));
KeSetEvent(&rEvent,0,FALSE);
pDE->rflag = 1;
}
//pDE->wtempBuffer = NULL;
pIrp->IoStatus.Status=status;
pIrp->IoStatus.Information=xferSize;
IoCompleteRequest(pIrp,IO_NO_INCREMENT);
IoStartNextPacket(pDevObject,NULL);
DbgPrint("\n WRITE FUNCTON \n");
return status;
}
NTSTATUS DispatchRead(IN PDEVICE_OBJECT pDevObject,IN PIRP pIrp)
{
NTSTATUS status=STATUS_SUCCESS,rStatus;
PDEVICE_EXTENSION pDE=(PDEVICE_EXTENSION)pDevObject->DeviceExtension;
char *userBuffer;
PIO_STACK_LOCATION pIrpStack;
pIrpStack=IoGetCurrentIrpStackLocation(pIrp);
userBuffer=(char *)pIrp->AssociatedIrp.SystemBuffer;
ULONG xferSize=pIrpStack->Parameters.Read.Length;
pDE->rnewSize = xferSize ; //pDE->deviceBufferSize;
pDE->rtempBuffer = userBuffer;
while(pDE->rnewSize > 0)
{
pDE->rxSize = pDE->rnewSize;
if(pDE->rflag ==0)
{
KeResetEvent(&rEvent);
DbgPrint("Read in Sleep \n");
rStatus = KeWaitForSingleObject(&rEvent,Executive, KernelMode,FALSE,NULL);
}
if(pDE->write <= pDE->read)
pDE->rxSize = (pDE->rxSize <= (ULONG)(pDE->devBufferEnd-pDE->read)) ? pDE->rxSize : (ULONG)(pDE->devBufferEnd-pDE->read);
else
pDE->rxSize = (pDE->rxSize <= (ULONG)(pDE->write - pDE->read)) ? pDE->rxSize : (ULONG)(pDE->write - pDE->read);
RtlCopyMemory(pDE->rtempBuffer,pDE->read,pDE->rxSize);
pDE->read += pDE->rxSize;
pDE->freeSize += pDE->rxSize;
pDE->rnewSize -= pDE->rxSize;
pDE->rtempBuffer += pDE->rxSize;
pDE->deviceBufferSize -= pDE->rxSize;
if(pDE->read >= pDE->devBufferEnd){
pDE->read = pDE->deviceBuffer;
DbgPrint("Buffer Initialized\n");
}
if(pDE->deviceBufferSize <= 0)
{
pDE->rflag = 0;
pDE->freeSize = pDE->memSize;
}
DbgPrint("device Buffer SIZE [%d]",pDE->deviceBufferSize);
DbgPrint("XferSize [%d]",pDE->rxSize);
KeSetEvent(&wEvent,0,FALSE);
pDE->wflag = 1;
}
pIrp->IoStatus.Status=status;
pIrp->IoStatus.Information=xferSize;
IoCompleteRequest(pIrp,IO_NO_INCREMENT);
IoStartNextPacket(pDevObject,NULL);
return status;
}
0 nhận xét:
Đăng nhận xét