⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 重入问题创建shadow device object.txt

📁 文件系统驱动开发的文档资料(IFS DDK)
💻 TXT
📖 第 1 页 / 共 2 页
字号:
版主,你好像误解了那个人提出的问题.不光是要将IRP发送到特定的FSD栈里的某一层.而是要在我自己的Filter中Create 文件,而又不重入我的Filter,“老外”的做法是起一个“标志性”的名字,然后在Filter中区分那些文件是我的Filiter要打开的,那些是一般程序要打开的,但是么,这实在不明智。有一种好方法,就是自己建立IRP请求,然后下传。其中用到了一些构建自己的IRP,以及FileObject的方法。 
下面是创建避免重入的关键代码,用该代码可以直接构建并下传打开文件的IRP。不过,这只是测试版的代码,如果哪位大侠发现这里的Bug,希望与我联系(li-gen@x263.net),谢谢。另外感谢Smith, Joel 的指导。 

NTSTATUS FsSimpleOpen(PUNICODE_STRING pstrName, ACCESS_MASK DesiredAccess, PDEVICE_OBJECT pVolume, PDEVICE_OBJECT pRealDevice, PFILE_OBJECT pParent, PFILE_OBJECT *ppFile) 

{ 
PIRP pIrp = NULL; 
PIO_STACK_LOCATION pStack; 
KEVENT event; 
IO_STATUS_BLOCK stat; 
NTSTATUS ntRet; 
PFILE_OBJECT pFile = NULL; 
OBJECT_ATTRIBUTES oa; 
ACCESS_STATE AccessState; 
HANDLE hFile = NULL; 
IO_SECURITY_CONTEXT ctx; 
ULONG *pAuxData = ExAllocatePool(NonPagedPool, 1024); 

if (pAuxData == NULL) 
{ 
ntRet = STATUS_INSUFFICIENT_RESOURCES; 
CLEANUP(); 
} 

ASSERT(pVolume != NULL); 
ASSERT(pRealDevice != NULL); 
ASSERT(ppFile != NULL); 
ASSERT(pstrName != NULL); 

memset(pAuxData, 0, 1024); 

//initialize an event and an IRP to send to the fsd 
KeInitializeEvent(&event, SynchronizationEvent, FALSE); 
pIrp = IoAllocateIrp(pVolume->StackSize, FALSE); 
IF_OUTOFMEMORY_CLEANUP(pIrp, &ntRet); 

InitializeObjectAttributes(&oa, 
NULL, 
OBJ_CASE_INSENSITIVE, 
NULL, 
NULL); 

//create a file object for the irp 
ntRet = ObCreateObject(KernelMode, 
*IoFileObjectType, 
&oa, 
KernelMode, 
0, 
sizeof(FILE_OBJECT), 
0, 
0, 
&pFile); 

IF_FAIL_CLEANUP(ntRet); 

//initialize the file object 
RtlZeroMemory(pFile, sizeof(FILE_OBJECT)); 
pFile->Type = IO_TYPE_FILE; 
pFile->Size = sizeof(FILE_OBJECT); 
pFile->DeviceObject = pRealDevice; 
pFile->Flags = FO_SYNCHRONOUS_IO; 
pFile->RelatedFileObject = pParent; 

//initialize embedded synch objects 
KeInitializeEvent(&pFile->Lock, SynchronizationEvent, FALSE); 
KeInitializeEvent(&pFile->Event, NotificationEvent, FALSE); 

//copy the file name into the buffer 
pFile->FileName.Buffer = ExAllocatePool(NonPagedPool, pstrName->MaximumLength); 
if (pFile->FileName.Buffer == NULL) 
{ 
ntRet = STATUS_INSUFFICIENT_RESOURCES; 
CLEANUP(); 
} 

pFile->FileName.MaximumLength = pstrName->MaximumLength; 
pFile->FileName.Length = pstrName->Length; 
RtlCopyMemory(pFile->FileName.Buffer, pstrName->Buffer, pstrName->Length); 

//setup the irp 
pIrp->UserEvent = &event; 
pIrp->UserIosb = &stat; 
pIrp->Tail.Overlay.Thread = KeGetCurrentThread(); 
pIrp->Tail.Overlay.OriginalFileObject = pFile; 
pIrp->RequestorMode = KernelMode; 
pIrp->Flags |= (IRP_CREATE_OPERATION | IRP_SYNCHRONOUS_API); 
pIrp->MdlAddress = NULL; 
pIrp->PendingReturned = FALSE; 
pIrp->Cancel = FALSE; 
pIrp->CancelRoutine = NULL; 
pIrp->Tail.Overlay.AuxiliaryBuffer = NULL; 

//Set up the I/O stack location. 
pStack = IoGetNextIrpStackLocation(pIrp); 
pStack->MajorFunction = IRP_MJ_CREATE; 
pStack->DeviceObject = pVolume; 
pStack->FileObject = pFile; 

//create an access state for the sd 
ntRet = SeCreateAccessState(&AccessState, pAuxData, DesiredAccess, IoGetFileObjectGenericMapping()); 
IF_FAIL_CLEANUP(ntRet); 

//fill out the create\'s security context 
ctx.AccessState = &AccessState; 
ctx.DesiredAccess = DesiredAccess; 
ctx.SecurityQos = NULL; 
ctx.FullCreateOptions = 0; 

//fill out the the create parameter 
pStack->Parameters.Create.SecurityContext = &ctx; 
pStack->Parameters.Create.Options = FILE_OPEN << 24; 
pStack->Parameters.Create.FileAttributes = FILE_ATTRIBUTE_NORMAL; 
pStack->Parameters.Create.ShareAccess = FILE_SHARE_READ | FILE_SHARE_WRITE; 
pStack->Parameters.Create.EaLength = 0; 

//set the completion routine (that will free the irp) 
IoSetCompletionRoutine(pIrp, FsDefaultComplete, 0, TRUE, TRUE, TRUE); 

//Send it to the FSD 
ntRet = IoCallDriver(pVolume, pIrp); 
pIrp = NULL; 

if (ntRet == STATUS_PENDING) 
{ 
//wait for the io to complete 
KeWaitForSingleObject(&event, Executive, KernelMode, TRUE, 0); 
ntRet = stat.Status; 
} 

CLEANUP: 

SAFE_FREE_POOL(pAuxData); 

if (!NT_SUCCESS(ntRet)) 
{ 
if (pIrp != NULL) 
{ 
IoFreeIrp(pIrp); 
} 
if (pFile) 
{ 
SAFE_FREE_POOL(pFile->FileName.Buffer); 
pFile->DeviceObject = NULL; 
ObDereferenceObject(pFile); 
} 
} 
else 
{ 
FsReferenceDeviceAndVpb(pFile); 

//set the out param 
*ppFile = pFile; 
} 
return ntRet; 
} 

VOID FsReferenceDeviceAndVpb(PFILE_OBJECT pFile) 
{ 
NTSTATUS ntRet; 

ASSERT(pFile->Vpb != NULL ? pFile->DeviceObject->Vpb != NULL : 
pFile->DeviceObject->Vpb == NULL); 

//Increment RealDevice\'s reference count. 
InterlockedIncrement(&pFile->DeviceObject->ReferenceCount); 

//Increment Vpb\'s reference count, if one exists. 
if (pFile->Vpb) 
{ 
ASSERT((pFile->Vpb->Flags & VPB_MOUNTED) && !(pFile->Vpb->Flags & VPB_LOCKED)); 
InterlockedIncrement(&pFile->Vpb->ReferenceCount); 
} 
} 


我可不想要钱。我还是学生嘛,但是么,我觉得有技术就因该提供。 
希望 版主 多提意见。但是如果有哪位未经我同意,把本程序投稿到相管杂志或是本站的资料文章区,来骗取个人利益,我一定饶不了他。

=====================================


BOOLEAN 
HookDrive( 
IN PDRIVER_OBJECT DriverObject, 
IN WCHAR DriveLetter 
) 
{ 
IO_STATUS_BLOCK IoStatus; 
HANDLE FileHandle; 
OBJECT_ATTRIBUTES ObjectAttributes; 
PDEVICE_OBJECT FileSysDevice; 
PDEVICE_OBJECT DeviceObject; 
PDEVICE_OBJECT ShadowDeviceObject; 
UNICODE_STRING ShadowDeviceName; 
WCHAR ShadowDeviceNameBuffer[] = L"\\Device\\FDFilterShadowA"; 
UNICODE_STRING FileName; 
WCHAR FileNameBuffer[] = L"\\DosDevices\\A:\\"; 
NTSTATUS Status; 
PFILE_OBJECT FileObject; 
PDEVICE_EXTENSION Pdx; 
PDEVICE_EXTENSION ShadowPdx; 

// 
// Replace the drive letter 
// 
FileNameBuffer[12] = DriveLetter; 
ShadowDeviceNameBuffer[22] = DriveLetter; 

// 
// We have to figure out what device to hook - first open the volume's 
// root directory 
// 
RtlInitUnicodeString(&FileName, FileNameBuffer); 
InitializeObjectAttributes(&ObjectAttributes, &FileName, OBJ_CASE_INSENSITIVE, NULL, NULL); 
Status = ZwCreateFile(&FileHandle, SYNCHRONIZE | FILE_ANY_ACCESS, 
&ObjectAttributes, &IoStatus, NULL, 0, 
FILE_SHARE_READ | FILE_SHARE_WRITE, 
FILE_OPEN, FILE_SYNCHRONOUS_IO_NONALERT | FILE_DIRECTORY_FILE, 
NULL, 0); 
if (!NT_SUCCESS(Status)) 
{ 
KdPrint(("fdfilter.sys: Could not open drive: %x\n", Status)); 
return FALSE; 
} 

KdPrint(("fdfilter.sys: opened the root directory!!! handle: %x\n", FileHandle)); 

// 
// Got the file handle, so now look-up the file-object it refers to 
// 
Status = ObReferenceObjectByHandle(FileHandle, FILE_READ_DATA, NULL, KernelMode, &FileObject, NULL); 
if (!NT_SUCCESS(Status)) 
{ 
KdPrint(("fdfilter.sys: Could not get fileobject from handle\n")); 
ZwClose(FileHandle); 
return FALSE; 
} 

// 
// Next, find out what device is associated with the file object by getting its related 
// device object 
// 
FileSysDevice = IoGetRelatedDeviceObject(FileObject); 
if (!FileSysDevice) 
{ 
KdPrint(("fdfilter.sys: Could not get related device object\n")); 
ObDereferenceObject(FileObject); 
ZwClose(FileHandle); 
return FALSE; 
} 

// 
// Create a shadow device object 
// 
RtlInitUnicodeString(&ShadowDeviceName, ShadowDeviceNameBuffer); 
Status = IoCreateDevice(DriverObject, 
sizeof(DEVICE_EXTENSION), 
&ShadowDeviceName, 
FileSysDevice->DeviceType, 
0, 
FALSE, 
&ShadowDeviceObject); 
if (!NT_SUCCESS(Status)) 
{ 
KdPrint(("fdfilter.sys: failed to create associated device\n")); 
ObDereferenceObject(FileObject); 
ZwClose(FileHandle); 
return FALSE; 
} 
ShadowDeviceObject->StackSize = FileSysDevice->StackSize; 

// 
// The file system's device hasn't been hooked already, so make a hooking device 
// object that will be attached to it. 
// 
Status = IoCreateDevice(DriverObject, 
sizeof(DEVICE_EXTENSION), 
NULL, 
FileSysDevice->DeviceType, 
0, 
FALSE, 
&DeviceObject); 
if (!NT_SUCCESS(Status)) 
{ 
KdPrint(("fdfilter.sys: failed to create associated device\n")); 
ObDereferenceObject(FileObject); 
ZwClose(FileHandle); 
IoDeleteDevice(ShadowDeviceObject); 
return FALSE; 
} 

// 
// Setup the device extensions. The drive letter and file system object are stored 
// in the extension. 
// 
ShadowPdx = ShadowDeviceObject->DeviceExtension; 
ShadowPdx->Type = SHADOW; 
ShadowPdx->FsDeviceObject = NULL; 
ShadowPdx->AttachToDeviceObject = NULL; 
ShadowPdx->BuddyDeviceObject = DeviceObject; 

Pdx = DeviceObject->DeviceExtension; 

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -