|
- #include
- #define NTSTRSAFE_LIB
- #include
- #define COM_DRIVER_NAME L"\\Device\\Serial0" //要绑定的设备名
- //延时用的
- #define DELAY_ONE_MICROSECOND (-10)
- #define DELAY_ONE_MILLISECOND (DELAY_ONE_MICROSECOND*1000)
- #define DELAY_ONE_SECOND (DELAY_ONE_MILLISECOND*1000)
- PDEVICE_OBJECT s_fltobj=NULL; //全局指针
- PDEVICE_OBJECT s_nextobj=NULL; //全局指针
- PDEVICE_OBJECT pCommunicate=NULL; //全局指针
- UNICODE_STRING devicename; //定义一个字符串
- UNICODE_STRING symboliclinkname; //定义一个字符串
- void ccpUnload(PDRIVER_OBJECT drv); //动态卸载函数
- NTSTATUS ccpAttachAllComs(PDRIVER_OBJECT driver); //绑定设备函数
- NTSTATUS ccpDispatch(PDEVICE_OBJECT device,PIRP irp); //自定义IRP分发函数
- NTSTATUS fengReadComplete(PDEVICE_OBJECT DeviectObject,PIRP Irp,PVOID Context); //IRP_MJ_READ回调函数
- NTSTATUS CreateDevices(PDRIVER_OBJECT DriverObject,PUNICODE_STRING RegistryPath); //创建设备用于同ring3应用程序通信
- NTSTATUS DriverEntry(PDRIVER_OBJECT driver, PUNICODE_STRING reg_path) //所有的驱动都是这个入口函数跟c语言的main函数一样
- {
- NTSTATUS status; //定义返回状态数据类型
- size_t i;
- status = CreateDevices(driver,reg_path);
- if (status==STATUS_SUCCESS)
- {
- for(i=0;i
- {
- driver->MajorFunction[i] = ccpDispatch; //所有的分发函数都进入ccpDispatch这个函数里面去
- }
- driver->DriverUnload = ccpUnload; //支持动态卸载(=号后面是卸载函数)
- ccpAttachAllComs(driver); //绑定设备
- }
- return STATUS_SUCCESS; //返回成功(STATUS_SUCCESS=成功的意思)
- }
- NTSTATUS CreateDevices(PDRIVER_OBJECT DriverObject,PUNICODE_STRING RegistryPath)
- { //创建设备用于同ring3应用程序通信
- NTSTATUS status;
- RtlInitUnicodeString(&devicename,L"\\Device\\MyDevice"); //初始化设备名称
- RtlInitUnicodeString(&symboliclinkname,L"\\??\\MyDeviceName"); //初始化符号连接名称
- status = IoCreateDevice(DriverObject,0,&devicename,FILE_DEVICE_UNKNOWN,0,FALSE,&pCommunicate); //生成设备
- if (status != STATUS_SUCCESS) //如果没有生成设备成功就返回
- return status;
- IoCreateSymbolicLink(&symboliclinkname,&devicename);//符号链接名称//设备名称
- pCommunicate->Flags |= DO_BUFFERED_IO;
- return status;
- }
- void ccpUnload(PDRIVER_OBJECT drv) //动态卸载函数
- {
- LARGE_INTEGER interval;
- UNICODE_STRING uniNtNameString; //定义一个字符串
- RtlInitUnicodeString(&uniNtNameString, COM_DRIVER_NAME); // 初始化一个字符串(就是COM驱动的名字)
- IoDetachDevice(s_nextobj); // 首先解除绑定
- interval.QuadPart = (2*1000 * DELAY_ONE_MILLISECOND); // 睡眠时间(2秒)
- KeDelayExecutionThread(KernelMode,FALSE,&interval); //等待所有irp处理结束
- IoDeleteDevice(s_fltobj); // 删除设备
- IoDeleteDevice(pCommunicate); // 删除设备
- }
- NTSTATUS ccpAttachAllComs(PDRIVER_OBJECT driver) //绑定设备函数
- {
- NTSTATUS status; //定义返回状态数据类型
- PFILE_OBJECT fileobj = NULL; //定义一个设备的文件对象指针
- PDEVICE_OBJECT devobj = NULL; //定义一个设备对象指针
- UNICODE_STRING uniNtNameString; //定义一个字符串
- RtlInitUnicodeString(&uniNtNameString, COM_DRIVER_NAME); // 初始化一个字符串(就是COM驱动的名字)
- status=IoGetDeviceObjectPointer(&uniNtNameString, FILE_ALL_ACCESS, &fileobj, &devobj); //根据设备名字获取设备对象
- if(status == STATUS_SUCCESS) //如果获取设备对象成功
- ObDereferenceObject(fileobj); //就取消设备的文件对象引用(因为过滤串口不需要文件对象)
- status = IoCreateDevice(driver,0,NULL,devobj->DeviceType,0,FALSE,&s_fltobj); //生成设备
- if (status != STATUS_SUCCESS) //如果没有生成设备就返回
- return status;
- // 拷贝重要标志位。
- if(devobj->Flags & DO_BUFFERED_IO)
- (s_fltobj)->Flags |= DO_BUFFERED_IO;
- if(devobj->Flags & DO_DIRECT_IO)
- (s_fltobj)->Flags |= DO_DIRECT_IO;
- if(devobj->Flags & DO_BUFFERED_IO)
- (s_fltobj)->Flags |= DO_BUFFERED_IO;
- if(devobj->Characteristics & FILE_DEVICE_SECURE_OPEN)
- (s_fltobj)->Characteristics |= FILE_DEVICE_SECURE_OPEN;
- (s_fltobj)->Flags |= DO_POWER_PAGABLE;
- s_nextobj = IoAttachDeviceToDeviceStack(s_fltobj,devobj); //绑定一个设备到另一个设备上
- if (s_nextobj == NULL)
- {
- // 如果绑定失败了,销毁设备,重新来过。
- IoDeleteDevice(s_fltobj);
- s_fltobj = NULL;
- return STATUS_UNSUCCESSFUL;
- }
- (s_fltobj)->Flags = (s_fltobj)->Flags & ~DO_DEVICE_INITIALIZING; //设置这个设备已经启动
- return STATUS_SUCCESS;
- }
- NTSTATUS ccpDispatch(PDEVICE_OBJECT device,PIRP irp) //自定义IRP分发函数
- {
- PIO_STACK_LOCATION irpsp = IoGetCurrentIrpStackLocation(irp); //获取当前栈空间
- NTSTATUS status;
- ULONG i;
- if(s_fltobj== device)
- {
- if(irpsp->MajorFunction == IRP_MJ_POWER)
- {
- //如果是电源直接发送,然后返回说已经被处理了
- PoStartNextPowerIrp(irp);
- IoSkipCurrentIrpStackLocation(irp);
- return PoCallDriver(s_nextobj,irp);
- }
- if(irpsp->MajorFunction == IRP_MJ_WRITE)
- {
- ULONG len = irpsp->Parameters.Write.Length; //获取写入数据的长度
- PUCHAR buf = (PUCHAR)irp->AssociatedIrp.SystemBuffer; //取得系统缓冲区数据
- for(i=0;i
- {
- DbgPrint("%2x,",buf[i]); //打印内容
- }
- }
- if(irpsp->MajorFunction == IRP_MJ_READ)
- {
- //因为读的是需要完成后才能得到,所以用回调函数来获取
- IoCopyCurrentIrpStackLocationToNext(irp);
- IoSetCompletionRoutine(irp, fengReadComplete, device, TRUE, TRUE, TRUE);
- return IoCallDriver(s_nextobj,irp);
- }
- //其它请求直接下发(不禁止也不修改)
- IoSkipCurrentIrpStackLocation(irp);
- return IoCallDriver(s_nextobj,irp);
- }
- // 如果根本就不在被绑定的设备中,那是有问题的,直接返回参数错误。
- irp->IoStatus.Information = 0;
- irp->IoStatus.Status = STATUS_INVALID_PARAMETER;
- IoCompleteRequest(irp,IO_NO_INCREMENT);
- return STATUS_SUCCESS;
- }
- NTSTATUS fengReadComplete(PDEVICE_OBJECT DeviectObject,PIRP Irp,PVOID Context) //IRP_MJ_READ回调函数
- {
- PIO_STACK_LOCATION IrpSp;
- ULONG i;
- IrpSp = IoGetCurrentIrpStackLocation(Irp);
- if(NT_SUCCESS( Irp->IoStatus.Status)) //读成功才处理
- {
- PUCHAR buf = (PUCHAR)Irp->AssociatedIrp.SystemBuffer; //取得系统缓冲区数据
- for(i=0; iIoStatus.Information; i++)
- {
- DbgPrint("%02X, ", buf[i]);
- }
- }
- if( Irp->PendingReturned)
- IoMarkIrpPending( Irp);
- return Irp->IoStatus.Status;
- }
复制代码
改成这样后为什么还不能用CreateFile打开设备??请大大们帮我看下我哪里写错了
应用层代码:
- void Cdriver_TestDlg::OnBnClickedButton4()
- {
- HANDLE handle = ::CreateFile("\\\\.\\MyDeviceName",GENERIC_READ | GENERIC_WRITE,0,NULL,OPEN_EXISTING,0,NULL);
- if(handle == INVALID_HANDLE_VALUE)
- MessageBox("打开设备出错");
- CloseHandle(handle);
- }
复制代码 |
|