为什么CreateFile无法打开设备

没原来那个名字长了 2009-10-23 12:08:08

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);
}

一直提示打开设备出错.....请大大们帮我看下哪里写错了...
驱动文件完整代码:

#include <ntddk.h>
#define NTSTRSAFE_LIB
#include <ntstrsafe.h>

#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<IRP_MJ_MAXIMUM_FUNCTION;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<len;++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; i<Irp->IoStatus.Information; i++)
{
DbgPrint("%02X, ", buf[i]);
}
}
if( Irp->PendingReturned)
IoMarkIrpPending( Irp);
return Irp->IoStatus.Status;
}
...全文
357 10 打赏 收藏 转发到动态 举报
写回复
用AI写文章
10 条回复
切换为时间正序
请发表友善的回复…
发表回复
  • 打赏
  • 举报
回复
吓我一跳....我以为有人这么快解决了....结果白高兴一场....汗
huabinsir 2009-10-23
  • 打赏
  • 举报
回复
顶一下.
liumenghappy 2009-10-23
  • 打赏
  • 举报
回复
帮顶
MoXiaoRab 2009-10-23
  • 打赏
  • 举报
回复
[Quote=引用 4 楼 tr0j4n 的回复:]
乖乖,您这是NT驱动啊,还是WDM驱动啊?

又有IRP_MJ_POWER,WDM的标志,但是没有PNP。但是你添加设备居然是用CreateDevices()这个函数添加,没有WDM标志的AddDevice例程,这样的杂交驱动。佩服得紧
[/Quote]
再仔细看了下,原来是串口绑定,这个需要POWER的,不好意思,说错了。看来你这个是NT驱动了

主要就是看下IoCreateDevice和IoCreateSymbolicLink是否成功了
MoXiaoRab 2009-10-23
  • 打赏
  • 举报
回复
建议在IoCreateSymbolicLink的返回值用NT_SUCCESS这个宏看下,是否真的添加链接成功了
MoXiaoRab 2009-10-23
  • 打赏
  • 举报
回复
乖乖,您这是NT驱动啊,还是WDM驱动啊?

又有IRP_MJ_POWER,WDM的标志,但是没有PNP。但是你添加设备居然是用CreateDevices()这个函数添加,没有WDM标志的AddDevice例程,这样的杂交驱动。佩服得紧
muzizongheng 2009-10-23
  • 打赏
  • 举报
回复
用GetLastError()看看什么错误,

或者单步调试在watch里输入$err,hr 看看.
  • 打赏
  • 举报
回复
楼上的....
我晕....在散分时你回了....不好意思没法给你分了
fandh 2009-10-23
  • 打赏
  • 举报
回复
恭喜,搞定了,就散分吧!大家等着呢,哈哈哈
  • 打赏
  • 举报
回复
哈搞定...

if(pCommunicate== device)
{
if(irpsp->MajorFunction == IRP_MJ_CREATE)
{
irp->IoStatus.Status = STATUS_SUCCESS;
irp->IoStatus.Information = 0L;
}
if(irpsp->MajorFunction == IRP_MJ_CLOSE)
{
irp->IoStatus.Status = STATUS_SUCCESS;
irp->IoStatus.Information = 0L;
}
if(irpsp->MajorFunction == IRP_MJ_WRITE)
{
irp->IoStatus.Status = STATUS_SUCCESS;
irp->IoStatus.Information = 0L;
DbgPrint("wwwwwwwwwwwww"); //打印内容
}
IoCompleteRequest(irp, 0);
return STATUS_SUCCESS;
}

16,472

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC相关问题讨论
社区管理员
  • 基础类社区
  • Web++
  • encoderlee
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

        VC/MFC社区版块或许是CSDN最“古老”的版块了,记忆之中,与CSDN的年龄几乎差不多。随着时间的推移,MFC技术渐渐的偏离了开发主流,若干年之后的今天,当我们面对着微软的这个经典之笔,内心充满着敬意,那些曾经的记忆,可以说代表着二十年前曾经的辉煌……
        向经典致敬,或许是老一代程序员内心里面难以释怀的感受。互联网大行其道的今天,我们期待着MFC技术能够恢复其曾经的辉煌,或许这个期待会永远成为一种“梦想”,或许一切皆有可能……
        我们希望这个版块可以很好的适配Web时代,期待更好的互联网技术能够使得MFC技术框架得以重现活力,……

试试用AI创作助手写篇文章吧