符号 \??\HelloDDK -》\\.\
\??\HelloDDK ->\\.\HelloDDK -> C语言字符串 \\\\.\\HelloDDK
HANDLE hDevice =
CreateFile("\\\\.\\HelloDDK",
GENERIC_READ | GENERIC_WRITE,
0, // share mode none
NULL, // no security
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
NULL ); // no template
if (hDevice == INVALID_HANDLE_VALUE)
{
printf("Failed to obtain file handle to device: "
"%s with Win32 error code: %d\n",
"MyWDMDevice", GetLastError() );
return 1;
}
CloseHandle(hDevice);//触发MJ_CLEANUP MJ_CLOSE
设备对象一共有3中读写方式:
1)缓冲区方式读写
//创建设备
status = IoCreateDevice( pDriverObject,
sizeof(DEVICE_EXTENSION),
&(UNICODE_STRING)devName,
FILE_DEVICE_UNKNOWN,
0, TRUE,
&pDevObj );
if (!NT_SUCCESS(status))
return status;
pDevObj->Flags |= DO_BUFFERED_IO;
用程序提供缓冲区的数据复制到内核模式下的中,无论操作系统怎么切换,内核模式地址都不会改变
缺点: 影响了运行效率
下面为 利用缓冲区 方式读设备:(写入数据
pDriverObject->MajorFunction[IRP_MJ_READ] = HelloDDKRead;
IRP_MJ_READ 的派遣函数主要任务是把任务断的数据复制到AssociatedIrp.SystemBuffer
NTSTATUS HelloDDKRead(IN PDEV0CE_OBJECT pDevObj,
IN PIRP pIrp)
{
KdPrint(("Enter HelloDDKRead\n"));
//对一般IRP的简单操作,后面会介绍对IRP更复杂的操作
NTSTATUS status = STATUS_SUCCESS;
PIO_STACK_LOCATION stack = IoGetCurrentIrpStackLocation(pIrp);
ULONG ulReadLength = stack->Parameters.Read.Length;
// 完成IRP
//设置IRP完成状态
pIrp->IoStatus.Status = status;
//设置IRP操作了多少字节
pIrp->IoStatus.Information = ulReadLength; // bytes xfered
memset(pIrp->AssociatedIrp.SystemBuffer,0xAA,ulReadLength);
//处理IRP
IoCompleteRequest( pIrp, IO_NO_INCREMENT );
KdPrint(("Leave HelloDDKRead\n"));
return status;
}
下面为 程序 读取
HANDLE hDevice =
CreateFile("\\\\.\\HelloDDK",
GENERIC_READ | GENERIC_WRITE,
0, // share mode none
NULL, // no security
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
NULL ); // no template
if (hDevice == INVALID_HANDLE_VALUE)
{
printf("Failed to obtain file handle to device: "
"%s with Win32 error code: %d\n",
"MyWDMDevice", GetLastError() );
return 1;
}
UCHAR buffer[10];
ULONG ulRead;
BOOL bRet = ReadFile(hDevice,buffer,10,&ulRead,NULL);
if (bRet)
{
printf("Read %d bytes:",ulRead);
for (int i=0;i<(int)ulRead;i++)
{
printf("%02X ",buffer[i]);
}
printf("\n");
}
CloseHandle(hDevice);
return 0;
下面是程序写入设备 WriteFile 内部产生 IRP_MJ_WRITE 类型的IRP
派遣函数需要将传送进来的数据保存起来,以便读取该设备的时候读取
NTSTATUS HelloDDKWrite(IN PDEVICE_OBJECT pDevObj,
IN PIRP pIrp)
{
KdPrint(("Enter HelloDDKWrite\n"));
//对一般IRP的简单操作,后面会介绍对IRP更复杂的操作
NTSTATUS status = STATUS_SUCCESS;
PDEVICE_EXTENSION pDevExt = (PDEVICE_EXTENSION)pDevObj->DeviceExtension;
PIO_STACK_LOCATION stack = IoGetCurrentIrpStackLocation(pIrp);
ULONG ulWriteLength = stack->Parameters.Write.Length;
ULONG ulWriteOffset = (ULONG)stack->Parameters.Write.ByteOffset.QuadPart;
if (ulWriteOffset + ulWriteLength > 1024)
{
status = STATUS_FILE_INVALID;
ulWriteOffset = 0;
}
else
{
memcpy(pDevExt->buffer+ulWriteOffset,\
pIrp->AssociatedIrp.SystemBuffer,\
ulWriteLength);
status = STATUS_SUCCESS;
if (ulWriteLength + ulWriteOffset > pDevExt->File_length)
{
pDevExt->File_length = ulWriteLength + ulWriteOffset;
}
}
pIrp->IoStatus.Status = status;
pIrp->IoStatus.Information = ulWriteLength;
//处理IRP
IoCompleteRequest( pIrp, IO_NO_INCREMENT );
KdPrint(("Leave HelloDDKWrite\n"));
return status;
}