能力值:
( LV2,RANK:10 )
|
-
-
2 楼
这么神奇。
我倒是经常在函数返回一个正确的句柄的时候GetLastError返回ERROR_FILE_NOT_FOUND
主要是在打开一个已存在的内存映射对象或者已经打开的管道的时候。
这个时候我总是很洁癖的把ERROR_FILE_NOT_FOUND通过SetLastError给清了。
|
能力值:
( LV2,RANK:10 )
|
-
-
3 楼
errorcode 为0 表示 操作已成功完成
这到底是什么意思
设备确实创建了 符号链接也创建了 DeviceTree里都能看到
但是CreateFile返回 INVALID_HANDLE_VALUE
而且句柄也是无效不能使用
返回的errorcode 是0
而且 debugview显示 没进入过设置的IRP_MJ_CREATE分发函数
因为没打印信息
|
能力值:
( LV2,RANK:10 )
|
-
-
4 楼
0就是没错误。不过要在正确的线程调用,每个线程之间得到的GetLastError的值是互相独立的。
能不能发一下你的代码,主要是比较感兴趣。。
驱动开发刚刚入门,现阶段想做个在内核截获CreateFile,ReadFile,WriteFile等调用的东西来虚拟一个文件。
|
能力值:
( LV2,RANK:10 )
|
-
-
5 楼
#define IOCTL_TEST1 CTL_CODE(FILE_DEVICE_UNKNOWN,0x821,METHOD_BUFFERED,FILE_ANY_ACCESS)
//#include <wdm.h>
#include<Ntddk.h>
typedef struct _MY_DRIVER_EXTENSION
{
int x;
}MY_DRIVER_EXTENSION,*PMY_PDRIVER_EXTENSION;
typedef struct _MY_DEVICE_EXTENSION
{
PDEVICE_OBJECT pDevbj;
UNICODE_STRING DeviceName;
UNICODE_STRING UserSymbolicName;
}MY_DEVICE_EXTENSION,*PMY_DEVICE_EXTENSION;
//NTSTATUS MyWdmAddDevice(PDRIVER_OBJECT DriverObject,PDEVICE_OBJECT physicalDeviceObject);
//NTSTATUS MyWdmPnp(PDEVICE_OBJECT DeviceObject,PIRP Trp);
void MyWdmUnload(PDRIVER_OBJECT DriverObject);
NTSTATUS MyWdmCreate(PDEVICE_OBJECT DeviceObject,PIRP Irp);
NTSTATUS MyWdmDispatch(PDEVICE_OBJECT DeviceObject,PIRP Trp);
static VOID NTAPI SearchForLegacyDrivers(IN PDRIVER_OBJECT DriverObject,IN PVOID Context, IN ULONG Count);
#pragma code_seg("INIT")
extern "C"
NTSTATUS DriverEntry(PDRIVER_OBJECT pDriverObject,PUNICODE_STRING RegistryPath)
{
KdPrint(("EnterDriverEntry\n"));
//pDriverObject->DriverExtension->AddDevice=MyWdmAddDevice;
//pDriverObject->MajorFunction[IRP_MJ_PNP]=MyWdmPnp;
pDriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL]=MyWdmDispatch;
pDriverObject->MajorFunction[IRP_MJ_CREATE]=MyWdmCreate;
pDriverObject->MajorFunction[IRP_MJ_READ]=MyWdmDispatch;
pDriverObject->MajorFunction[IRP_MJ_CLOSE]=MyWdmDispatch;
pDriverObject->MajorFunction[IRP_MJ_WRITE]=MyWdmDispatch;
pDriverObject->DriverUnload = MyWdmUnload;
PMY_PDRIVER_EXTENSION MyDriverExtension;
NTSTATUS Status;
Status=IoAllocateDriverObjectExtension(pDriverObject,pDriverObject,sizeof(MY_DRIVER_EXTENSION),(PVOID*)&MyDriverExtension);
if(!NT_SUCCESS(Status))
{
KdPrint(("allocate for DriverExtension faild"));
return Status;
}
IoRegisterDriverReinitialization(pDriverObject,SearchForLegacyDrivers,MyDriverExtension);
KdPrint(("leave DriverEntry"));
return STATUS_SUCCESS;
DbgPrint("leave enter driver entry ");
}
#pragma code_seg("PAGE")
static VOID SearchForLegacyDrivers(IN PDRIVER_OBJECT pDriverObject,IN PVOID Context, IN ULONG Count)
{
NTSTATUS Status;
UNICODE_STRING DevName;
PDEVICE_OBJECT pDevObj;
PMY_DEVICE_EXTENSION pDevExt;
DbgPrint("print enter SearchForLegacyDrivers ");
KdPrint(("enter SearchForLegacyDrivers"));
RtlInitUnicodeString(&DevName,L"\\Device\\MyWdmDevice");
PMY_PDRIVER_EXTENSION pDriverExtension=(PMY_PDRIVER_EXTENSION)Context;
Status=IoCreateDevice(pDriverObject,sizeof(MY_DEVICE_EXTENSION),&DevName,FILE_DEVICE_UNKNOWN,0,FALSE,&pDevObj);
if (!NT_SUCCESS(Status))
{
IoDeleteDevice(pDevObj);
KdPrint((" create device faild "));
return ;
}
KdPrint(("Create Device Success"));
pDevObj->Flags|=DO_BUFFERED_IO; //决定了设备的访问类型
pDevExt=(PMY_DEVICE_EXTENSION)pDevObj->DeviceExtension;
pDevExt->pDevbj=pDevObj;
pDevExt->DeviceName=DevName;
UNICODE_STRING SymLinkName;
RtlInitUnicodeString(&SymLinkName,L"\\DosDevices\\MyLegacyDriver");
pDevExt->UserSymbolicName=SymLinkName;
Status=IoCreateSymbolicLink(&SymLinkName,&DevName);
if (!NT_SUCCESS(Status))
{
IoDeleteDevice(pDevObj);
KdPrint((" create symbolic faild "));
return;
}
KdPrint(("Create symbolic success"));
return;
}
/*
#pragma code_seg("PAGE")
NTSTATUS MyWdmAddDevice(PDRIVER_OBJECT DriverObject,PDEVICE_OBJECT physicalDeviceObject)
{
return STATUS_SUCCESS;
}
#pragma code_seg("PAGE")
NTSTATUS MyWdmPnp(PDEVICE_OBJECT DeviceObject,PIRP Trp) //老式驱动没有这两项
{
}
*/
#pragma code_seg("PAGE")
NTSTATUS MyWdmRead(PDEVICE_OBJECT DeviceObject,PIRP Irp)
{
KdPrint(("enter MyWdmRead"));
NTSTATUS Status=STATUS_SUCCESS;
PIO_STACK_LOCATION stack=IoGetCurrentIrpStackLocation(Irp);
ULONG ulReadLength =stack->Parameters.Read.Length; //得到要读的字节数
Irp->IoStatus.Status=Status;
Irp->IoStatus.Information=ulReadLength;
memset(Irp->AssociatedIrp.SystemBuffer,0xAA,ulReadLength);
IoCompleteRequest(Irp,IO_NO_INCREMENT);
KdPrint(("leave MyWdmRead "));
return Status;
}
#pragma code_seg("PAGE")
NTSTATUS MyWdmWrite(PDEVICE_OBJECT DeviceObject,PIRP Irp)
{
KdPrint(("enter MyWdmWrite"));
PIO_STACK_LOCATION stack= IoGetCurrentIrpStackLocation(Irp);
ULONG ulWriteLength= stack->Parameters.Write.Length; //得到要写的长度
ULONG ulWriteOffset= (ULONG)stack->Parameters.Write.ByteOffset.QuadPart;
OBJECT_ATTRIBUTES objectAttributes;
HANDLE myfile;
NTSTATUS Status;
IO_STATUS_BLOCK iostatus;
UNICODE_STRING file_name_path;
RtlInitUnicodeString( &file_name_path, L"\\??\\d:\\1.log" );
Status=ZwCreateFile( &myfile, GENERIC_WRITE,
&objectAttributes,
&iostatus,
NULL,
FILE_ATTRIBUTE_NORMAL,
FILE_SHARE_READ,
FILE_OPEN_IF,
FILE_SYNCHRONOUS_IO_NONALERT,
NULL,
0 );
if (!NT_SUCCESS(Status))
{
return STATUS_UNSUCCESSFUL;
}
LARGE_INTEGER LGINOffset;
LGINOffset.QuadPart=ulWriteLength;
Status=ZwWriteFile(myfile,0,0,0,&iostatus,Irp->AssociatedIrp.SystemBuffer,ulWriteLength,&LGINOffset,0);
if(NT_SUCCESS(Status))
{
KdPrint(("Write file failed"));
return Status;
}
ZwClose(myfile);
Irp->IoStatus.Status=Status;
Irp->IoStatus.Information=ulWriteLength;
IoCompleteRequest(Irp,IO_NO_INCREMENT);
KdPrint(("leave myWdm Write file"));
return Status;
}
#pragma code_seg("PAGE")
NTSTATUS MyWdmCreate(PDEVICE_OBJECT DeviceObject,PIRP Irp)
{
KdPrint(("enter My Wdm Create!"));
Irp->IoStatus.Status=STATUS_SUCCESS;
Irp->IoStatus.Information=0;
IoCompleteRequest(Irp,IO_NO_INCREMENT);
KdPrint(("Leave My Wdm Create!"));
return STATUS_SUCCESS;
}
#pragma code_seg("PAGE")
NTSTATUS MyWdmDeviceControl(PDEVICE_OBJECT DeviceObject,PIRP Irp)
{
NTSTATUS Status;
Status=STATUS_SUCCESS;
KdPrint(("enter my wdmDeviceIoControl"));
PIO_STACK_LOCATION stack=IoGetCurrentIrpStackLocation(Irp);
//ULONG buffer_in=stack->Parameters.DeviceIoControl.InputBufferLength; //得到输入缓冲区长度
//ULONG buffer_out=stack->Parameters.DeviceIoControl.OutputBufferLength; //得到输出缓冲区长度
ULONG code=stack->Parameters.DeviceIoControl.IoControlCode;
ULONG info=0;
switch(code)
{
case IOCTL_TEST1:
KdPrint(("device io control success !"));
break;
default:
break;
}
Irp->IoStatus.Status=Status;
Irp->IoStatus.Information=0;
IoCompleteRequest(Irp,IO_NO_INCREMENT);
KdPrint(("leave my wdmDeviceIoContrl"));
return Status;
}
#pragma code_seg("PAGE")
NTSTATUS MyWdmDeviceClose(PDEVICE_OBJECT DeviceObject,PIRP Irp)
{
KdPrint(("enter MyWdmDeviceClose"));
NTSTATUS Status;
Status=STATUS_SUCCESS;
Irp->IoStatus.Status=Status;
Irp->IoStatus.Information=0;
IoCompleteRequest(Irp,IO_NO_INCREMENT);
KdPrint(("leave MyWdmDeviceClose"));
return Status;
}
#pragma code_seg("PAGE")
NTSTATUS MyWdmDispatch(PDEVICE_OBJECT DeviceObject,PIRP Irp)
{
KdPrint(("Enter my_wdm_diapatch_function"));
NTSTATUS Status=NULL;
PIO_STACK_LOCATION irpsp=IoGetCurrentIrpStackLocation(Irp);
switch (irpsp->MajorFunction)
{
case IRP_MJ_CREATE:
Status=MyWdmCreate(DeviceObject,Irp);
break;
case IRP_MJ_WRITE:
Status=MyWdmWrite(DeviceObject,Irp);
break;
case IRP_MJ_READ:
Status=MyWdmRead(DeviceObject,Irp);
break;
case IRP_MJ_DEVICE_CONTROL:
Status=MyWdmDeviceControl(DeviceObject,Irp);
break;
case IRP_MJ_CLOSE:
Status=MyWdmDeviceClose(DeviceObject,Irp);
default:
Irp->IoStatus.Status=STATUS_SUCCESS;
Irp->IoStatus.Information=0L;
IoCompleteRequest(Irp,IO_NO_INCREMENT);
}
KdPrint(("leave my wdm dispatch"));
return Status;
}
#pragma code_seg("PAGE")
void MyWdmUnload(PDRIVER_OBJECT pDriverObject) //负责删除创建的设备对象
{
PDEVICE_OBJECT pNextObj;
KdPrint(("enter Driver unload"));
pNextObj=pDriverObject->DeviceObject;
while(pNextObj!=NULL)
{
PMY_DEVICE_EXTENSION pDevExt=(PMY_DEVICE_EXTENSION)pNextObj->DeviceExtension;
UNICODE_STRING pLinkName=pDevExt->UserSymbolicName;
IoDeleteSymbolicLink(&pLinkName);
pNextObj=pNextObj->NextDevice;
IoDeleteDevice(pDevExt->pDevbj);
}
}
void CuserMyWdmMfcDlg::OnBnClickedButton1()
{
hDevice=CreateFile(L"\\\\DosDevives\\MyLegacyDriver",GENERIC_READ|GENERIC_WRITE,0,NULL,
OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL);//异步方式打开设备要加上 | FILE_FLAG_OVERLAPPED
if(hDevice==INVALID_HANDLE_VALUE)
{
MessageBox(L"打开失败 ",L"txt",MB_OK);
LPVOID lpMsgBuf;
int error = GetLastError();
FormatMessage(
FORMAT_MESSAGE_ALLOCATE_BUFFER |
FORMAT_MESSAGE_FROM_SYSTEM |
FORMAT_MESSAGE_IGNORE_INSERTS,
NULL,
error,
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), /* Default language */
(LPTSTR) &lpMsgBuf,
0,
NULL);
/* Display the string. */
::MessageBox( NULL, (LPCTSTR)lpMsgBuf, L"Error", MB_OK | MB_ICONERROR );
return ;
}
MessageBox(L"Open Device success",L"box!",MB_OK);
return ;
}
|
能力值:
( LV2,RANK:10 )
|
-
-
6 楼
我发现 是不是不应该在 GetLasterrorcode前调用 messagebox
|
能力值:
( LV2,RANK:10 )
|
-
-
7 楼
果然- -
这次的错误是找不到网络路径
|
能力值:
( LV2,RANK:10 )
|
-
-
8 楼
把符号连接改成了\\??\\ 开头的
错误变成了 系统找不到指定文件
|
能力值:
( LV11,RANK:190 )
|
-
-
9 楼
UNC路径需要以"\\\\.\\"或"\\\\?\\"打开
|
能力值:
( LV2,RANK:10 )
|
-
-
10 楼
符号链接 改成 \\??\\MyLegacyDriver
打开时CreateFile里使用 \\\\.\\MyLegacyDriver
还是找不到指定设备
明明符号连接已经创建成功了
|
能力值:
( LV11,RANK:190 )
|
-
-
11 楼
如果你系统是支持符号链接用户相关性的,需要把符号链接改成 L"\\DosDevices\\Global\\MyLegacyDriver"
|
能力值:
( LV2,RANK:10 )
|
-
-
12 楼
恩??是创建时 还是打开时??
我试了下
创建符号链接时用 "\\??\\MyLegacyDriver "
打开时用 L"\\DosDevices\\Global\\MyLegacyDriver"
不行啊……
然后又试了
创建符号链接时用 "\\??\\MyLegacyDriver
打开时用 L"\\\\DosDevices\\Global\\MyLegacyDriver"
还是不行 然后又试了各种各样的组合 结果都是 系统找不到指定文件
我用winobj 看到创建的符号链接 在\ 目录下 的 Global?? 目录 里
我该用什么样的格式打开
|
能力值:
( LV2,RANK:10 )
|
-
-
13 楼
UNICODE_STRING SymLinkName;
if(IoIsWdmVersionAvailable(1,0x10))
{
RtlInitUnicodeString(&SymLinkName,L"\\DosDevices\\Global\\MyLegacyDriver");
KdPrint(("\\DosDevices\\Global\\MyLegacyDriver"));
}
else
{
RtlInitUnicodeString(&SymLinkName,L"\\DosDevices\\MyLegacyDriver");
KdPrint(("\\DosDevices\\MyLegacyDriver"));
}
pDevExt->UserSymbolicName=SymLinkName;
Status=IoCreateSymbolicLink(&SymLinkName,&DevName);
DebugView里显示是 \\DosDevices\\Global\\MyLegacyDriver
就是说确实是用户相关
然后我在用户模式下用 L"\\\\.\\MyLegacyDriver"打不开啊 错误是找不到指定文件 因为winobj显示符号链接在 Global目录里
然后又尝试 L"\\\\.\\Global??\\MyLegacyDriver" 还是打不开 错误是找不到指定路径 然后又尝试 L"\\\\.\\Global\\MyLegacyDriver" 还是打不开 错误是找不到指定文件 吐血
用winobj 都看到符号链接了………………就在 \ 目录下的 Global?? 目录里
到底该如何打开它
|
能力值:
( LV11,RANK:190 )
|
-
-
16 楼
额,是没多写,我看错了,不过可以试试,把pDevObj->Flags &= ~DO_DEVICE_INITIALIZING;加入SearchForLegacyDrivers
|
能力值:
( LV2,RANK:10 )
|
-
-
17 楼
|