能力值:
( LV12,RANK:760 )
|
-
-
2 楼
根据传说是这么处理的~~
//////////////////////////////////////////////////////////////////////////
//
// ConvertDeviceName
//
// 将形如 "\\Device\\HarddiskVolumeX\\xxxx的内核文件路径
// 转化为 DOS文件路径(c:\\xxxx\\xxx....)
//
//////////////////////////////////////////////////////////////////////////
NTSTATUS ConvertDeviceName(LPCWSTR FileName , LPCWSTR OutFileName)
{
HANDLE FileHandle ;
OBJECT_ATTRIBUTES oba;
IO_STATUS_BLOCK iosb ;
UNICODE_STRING uniname;
NTSTATUS stat ;
PFILE_OBJECT FileObject ;
RtlInitUnicodeString(&uniname , FileName);
InitializeObjectAttributes(&oba , &uniname , OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE , 0 , 0 );
stat = IoCreateFile(&FileHandle ,
FILE_READ_ATTRIBUTES ,
&oba,
&iosb ,
0,
FILE_ATTRIBUTE_NORMAL ,
FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE ,
FILE_OPEN,
FILE_NON_DIRECTORY_FILE | FILE_SYNCHRONOUS_IO_NONALERT ,
0 ,
0,
CreateFileTypeNone ,
0,
IO_NO_PARAMETER_CHECKING
);
if (!NT_SUCCESS(stat))
{
return stat ;
}
stat = ObReferenceObjectByHandle(FileHandle ,
GENERIC_READ ,
*IoFileObjectType ,
KernelMode ,
&FileObject ,
NULL);
if (!NT_SUCCESS(stat) ||
!FileObject ||
!FileObject->FileName.Length ||
!FileObject->FileName.Buffer)
{
ZwClose(FileHandle);
return STATUS_INVALID_PARAMETER ;
}
//开始获取DosName
{
UNICODE_STRING VolumeName ;
UNICODE_STRING FanalName ;
BOOL WillFreeVolumeName = TRUE ;
VolumeName.Buffer = NULL ;
VolumeName.Length = 0 ;
VolumeName.MaximumLength = 0 ;
stat = RtlVolumeDeviceToDosName(FileObject->DeviceObject , &VolumeName);
if (!NT_SUCCESS(stat))
{
RtlInitUnicodeString(&VolumeName , L"\\" );
WillFreeVolumeName = FALSE ;
}
if (FileObject->FileName.Length + VolumeName.Length >= 0x800 * 2)
{
ObDereferenceObject(FileObject);
ZwClose(FileHandle);
if (WillFreeVolumeName && MmIsAddressValid(VolumeName.Buffer))
{
ExFreePool(VolumeName.Buffer);
}
return STATUS_INVALID_PARAMETER ;
}
RtlZeroMemory((PVOID)OutFileName , 0x800 * 2);
RtlInitUnicodeString(&FanalName , OutFileName);
FanalName.MaximumLength = 0x800 * 2 ;
//byte
if (!NT_SUCCESS(RtlAppendUnicodeStringToString(&FanalName , &VolumeName)))
{
ObDereferenceObject(FileObject);
ZwClose(FileHandle);
if (WillFreeVolumeName && MmIsAddressValid(VolumeName.Buffer))
{
ExFreePool(VolumeName.Buffer);
}
return STATUS_INVALID_PARAMETER ;
}
if (!NT_SUCCESS(RtlAppendUnicodeStringToString(&FanalName , &FileObject->FileName)))
{
ObDereferenceObject(FileObject);
ZwClose(FileHandle);
if (WillFreeVolumeName && MmIsAddressValid(VolumeName.Buffer))
{
ExFreePool(VolumeName.Buffer);
}
return STATUS_INVALID_PARAMETER ;
}
ObDereferenceObject(FileObject);
ZwClose(FileHandle);
if (WillFreeVolumeName && MmIsAddressValid(VolumeName.Buffer))
{
ExFreePool(VolumeName.Buffer);
}
return STATUS_SUCCESS ;
}
}
|
能力值:
( LV13,RANK:260 )
|
-
-
3 楼
感觉你既然是动态挂载新盘符的时候出现 系统挂起,
也就是说你的挂载盘符是手动的时候,这个时候还不如设置 context 上下文,也就是扩展device 这样在create 取出对应的盘符 就可以.....
上面的那两个盘符 IoVolumeDeviceToDosName RtlVolumeDeviceToDosName 动态挂载盘符,都有可能 出现问题,如果是 之前已挂载的可能不会出问题... 一家之言....个人想法....
|
能力值:
( LV2,RANK:10 )
|
-
-
4 楼
感谢v神~~~
意思是在IRP_MJ_CREATE传递到下层之前,先自己打开一遍这个文件然后用IoVolumeDeviceToDosName 查盘符吗?
嗯,如果是这样就要处理IRP重入问题。。可以根据那个flag pass掉吧。。
不过,还是用RtlVolumeDeviceToDosName /IoVolumeDeviceToDosName 这个函数的话,虽然和之前调用的时机是不同了(一个打开文件前,一个打开文件后),但不知道还会不会触发系统挂起的问题?
我这个问题老外说要用MountPointManager??
http://www.osronline.com/showThread.cfm?link=23125
关于IoVolumeDeviceToDosName系统挂起的问题-
http://www.osronline.com/showThread.CFM?link=96556
|
能力值:
( LV2,RANK:10 )
|
-
-
5 楼
在插入u盘得时候。调用这函数就会出问题。。
意思是加载驱动的时候先记录已经挂载的卷标到context的表里,然后在新挂卷标的时候update这个表?
|
能力值:
( LV13,RANK:260 )
|
-
-
6 楼
如果你用 的是minifilter的话,直接开辟context 上下文,设置 name 即可
如果你用sfilter 模型 那就放在扩展 对象里 就可
在create 里 无论是前处理 还是后处理,就不存在重入的问题...直接取出 使用
|
能力值:
( LV2,RANK:10 )
|
-
-
7 楼
用的是sfilter模型
是不是在SfFsNotification里面获取这个新MOUNT的卷标的盘符?
|
能力值:
( LV13,RANK:260 )
|
-
-
8 楼
做一下不就全知道了....
做比知道更重要 哈哈
|
能力值:
( LV2,RANK:10 )
|
-
-
9 楼
恩。正在做。。。。希望一切顺利
|
|
|