对发送Irp删除文件的学习笔记zz
在网上逛游的时候,看到了http://blog.csdn.net/beijixing2003/archive/2008/06/11/2535069.aspx这篇文章。于是对发送Irp删除文件进行了一翻学习。然后把代码重写了一下。上面链接的blog,把很多细节写的已经很详细了。所以学习起来还是很轻松的。
把自己重写的代码贴一下:
#include
<
ntddk.h
>
#define AYA_DEVICE L"\\Device\\DFBSI"
#define AYA_LINK L"\\DosDevices\\DFBSI"
HANDLE NTAPI AYA_OpenFile( IN PWCHAR szFileName )
{
NTSTATUS ns = STATUS_SUCCESS;
UNICODE_STRING FileName;
OBJECT_ATTRIBUTES oa;
HANDLE hFile;
IO_STATUS_BLOCK IoStatus;
if ( KeGetCurrentIrql() > PASSIVE_LEVEL )
{
KdPrint(( " Irql Error " ));
return NULL;
}
RtlInitUnicodeString( & FileName ,szFileName );
InitializeObjectAttributes( & oa , & FileName ,OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE ,\
NULL ,NULL);
ns = IoCreateFile( & hFile ,FILE_READ_ATTRIBUTES , & oa , & IoStatus , 0 ,FILE_ATTRIBUTE_NORMAL ,\
FILE_SHARE_DELETE ,FILE_OPEN , 0 ,NULL , 0 ,CreateFileTypeNone ,\
NULL ,IO_NO_PARAMETER_CHECKING );
if ( ! NT_SUCCESS( ns ) )
{
ZwClose( hFile );
KdPrint(( " IoCreateFile Error " ));
return NULL;
}
return hFile;
}
NTSTATUS
IoSetFileCompletion(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp,
IN PVOID Context
)
{
Irp -> UserIosb -> Status = Irp -> IoStatus.Status;
Irp -> UserIosb -> Information = Irp -> IoStatus.Information;
KeSetEvent( Irp -> UserEvent ,IO_NO_INCREMENT ,FALSE );
IoFreeIrp( Irp );
return STATUS_MORE_PROCESSING_REQUIRED;
}
NTSTATUS NTAPI StripFileAttributes( IN HANDLE hFile )
{
NTSTATUS ns = STATUS_SUCCESS;
PFILE_OBJECT pFileObject;
PDEVICE_OBJECT pDeviceObject;
PIRP pIrp;
KEVENT kFsEvent;
FILE_BASIC_INFORMATION FileInformation;
IO_STATUS_BLOCK IoStatus;
PIO_STACK_LOCATION pIrpSt;
ns = ObReferenceObjectByHandle( hFile ,DELETE , * IoFileObjectType ,KernelMode ,\
(PVOID * ) & pFileObject ,NULL );
if ( ! NT_SUCCESS( ns ) )
{
ObReferenceObject( pFileObject );
KdPrint(( " StripFileAttributes ObReferenceObjectByHandle Error " ));
return ns;
}
pDeviceObject = IoGetRelatedDeviceObject( pFileObject );
pIrp = IoAllocateIrp( pDeviceObject -> StackSize ,TRUE );
if ( pIrp == NULL )
{
ObReferenceObject( pFileObject );
KdPrint(( " StripFileAttributes IoAllocateIrp Error " ));
return STATUS_UNSUCCESSFUL;
}
KeInitializeEvent( & kFsEvent ,SynchronizationEvent ,FALSE );
RtlZeroMemory( & FileInformation , sizeof ( FILE_BASIC_INFORMATION ) );
FileInformation.FileAttributes = FILE_ATTRIBUTE_NORMAL;
pIrp -> AssociatedIrp.SystemBuffer = & FileInformation;
pIrp -> UserEvent = & kFsEvent;
pIrp -> UserIosb = & IoStatus;
pIrp -> Tail.Overlay.Thread = PsGetCurrentThread();
pIrp -> Tail.Overlay.OriginalFileObject = pFileObject;
pIrp -> RequestorMode = KernelMode;
pIrpSt = IoGetNextIrpStackLocation( pIrp );
pIrpSt -> MajorFunction = IRP_MJ_SET_INFORMATION;
pIrpSt -> DeviceObject = pDeviceObject;
pIrpSt -> FileObject = pFileObject;
pIrpSt -> Parameters.SetFile.Length = sizeof ( FILE_BASIC_INFORMATION );
pIrpSt -> Parameters.SetFile.FileObject = pFileObject;
pIrpSt -> Parameters.SetFile.FileInformationClass
= FileBasicInformation;
IoSetCompletionRoutine( pIrp ,IoSetFileCompletion ,NULL ,TRUE ,TRUE ,TRUE );
IoCallDriver( pDeviceObject ,pIrp );
KeWaitForSingleObject( & kFsEvent ,Executive ,KernelMode ,TRUE ,NULL );
ObReferenceObject( pFileObject );
return STATUS_SUCCESS;
}
NTSTATUS NTAPI DeleteFileBySendIrp( IN HANDLE hFile )
{
NTSTATUS ns = STATUS_SUCCESS;
PFILE_OBJECT pFileObject;
PDEVICE_OBJECT pDeviceObject;
PIRP pIrp;
KEVENT kFsEvent;
FILE_DISPOSITION_INFORMATION FileInformation;
IO_STATUS_BLOCK IoStatus;
PIO_STACK_LOCATION pIrpSt;
PSECTION_OBJECT_POINTERS pSectionObjectPointer;
ns = ObReferenceObjectByHandle( hFile ,DELETE , * IoFileObjectType ,KernelMode ,\
(PVOID * ) & pFileObject ,NULL );
if ( ! NT_SUCCESS( ns ) )
{
ObReferenceObject( pFileObject );
KdPrint(( " DeleteFileBySendIrp ObReferenceObjectByHandle Error " ));
return ns;
}
pDeviceObject = IoGetRelatedDeviceObject( pFileObject );
pIrp = IoAllocateIrp( pDeviceObject -> StackSize ,TRUE );
if ( pIrp == NULL )
{
ObReferenceObject( pFileObject );
KdPrint(( " DeleteFileBySendIrp IoAllocateIrp Error " ));
return STATUS_UNSUCCESSFUL;
}
KeInitializeEvent( & kFsEvent ,SynchronizationEvent ,FALSE );
FileInformation.DeleteFile = TRUE;
pIrp -> AssociatedIrp.SystemBuffer = & FileInformation;
pIrp -> UserEvent = & kFsEvent;
pIrp -> UserIosb = & IoStatus;
pIrp -> Tail.Overlay.Thread = PsGetCurrentThread();
pIrp -> Tail.Overlay.OriginalFileObject = pFileObject;
pIrp -> RequestorMode = KernelMode;
pIrpSt = IoGetNextIrpStackLocation( pIrp );
pIrpSt -> MajorFunction = IRP_MJ_SET_INFORMATION;
pIrpSt -> DeviceObject = pDeviceObject;
pIrpSt -> FileObject = pFileObject;
pIrpSt -> Parameters.SetFile.Length = sizeof ( FILE_DISPOSITION_INFORMATION );
pIrpSt -> Parameters.SetFile.FileObject = pFileObject;
pIrpSt -> Parameters.SetFile.FileInformationClass
= FileDispositionInformation;
IoSetCompletionRoutine( pIrp ,IoSetFileCompletion ,NULL ,TRUE ,TRUE ,TRUE );
pSectionObjectPointer = pFileObject -> SectionObjectPointer;
pSectionObjectPointer -> DataSectionObject = 0 ;
pSectionObjectPointer -> ImageSectionObject = 0 ;
IoCallDriver( pDeviceObject ,pIrp );
KeWaitForSingleObject( & kFsEvent ,Executive ,KernelMode ,TRUE ,NULL );
ObReferenceObject( pFileObject );
KdPrint(( " OK " ));
return STATUS_SUCCESS;
}
NTSTATUS NTAPI ForceDeleteFiles( PWCHAR szFileName )
{
HANDLE hFile;
NTSTATUS ns = STATUS_SUCCESS;
hFile = AYA_OpenFile( szFileName );
ns = StripFileAttributes( hFile );
if ( ! NT_SUCCESS( ns ) )
{
ZwClose( hFile );
KdPrint(( " ForceDeleteFiles StripFileAttributes Error " ));
return ns;
}
ns = DeleteFileBySendIrp( hFile );
if ( ! NT_SUCCESS( ns ) )
{
ZwClose( hFile );
KdPrint(( " ForceDeleteFiles DeleteFileBySendIrp Error " ));
return ns;
}
ZwClose( hFile );
return ns;
}
void AYA_Unload( IN PDRIVER_OBJECT pDriverObj )
{
UNICODE_STRING Temp;
RtlInitUnicodeString( & Temp ,AYA_LINK );
IoDeleteSymbolicLink( & Temp );
IoDeleteDevice( pDriverObj -> DeviceObject );
}
NTSTATUS AYA_Dispatch( IN PDEVICE_OBJECT pDeviceObj ,IN PIRP pIrp )
{
NTSTATUS ns = STATUS_SUCCESS;
PIO_STACK_LOCATION stIrp;
stIrp = IoGetCurrentIrpStackLocation( pIrp );
switch ( stIrp -> MajorFunction )
{
case IRP_MJ_CREATE:
break ;
case IRP_MJ_CLOSE:
break ;
case IRP_MJ_DEVICE_CONTROL:
break ;
default :
pIrp -> IoStatus.Status = STATUS_INVALID_PARAMETER;
break ;
}
ns = pIrp -> IoStatus.Status;
IoCompleteRequest( pIrp ,IO_NO_INCREMENT );
return ns;
}
NTSTATUS DriverEntry( IN PDRIVER_OBJECT pDriverObj ,IN PUNICODE_STRING RegistryPath )
{
NTSTATUS ns = STATUS_SUCCESS;
UNICODE_STRING AYA;
UNICODE_STRING AYAL;
PDEVICE_OBJECT pDevice;
WCHAR szFileName[] = L " \\??\\C:\\2.txt " ;
RtlInitUnicodeString( & AYA ,AYA_DEVICE );
ns = IoCreateDevice( pDriverObj , 0 , & AYA ,FILE_DEVICE_UNKNOWN , 0 ,FALSE , & pDevice );
RtlInitUnicodeString( & AYAL ,AYA_LINK );
ns = IoCreateSymbolicLink( & AYAL , & AYA );
pDriverObj -> MajorFunction[IRP_MJ_CREATE] =
pDriverObj -> MajorFunction[IRP_MJ_CLOSE] =
pDriverObj -> MajorFunction[IRP_MJ_DEVICE_CONTROL] = AYA_Dispatch;
pDriverObj -> DriverUnload = AYA_Unload;
ForceDeleteFiles( szFileName );
return ns;
}
#define AYA_DEVICE L"\\Device\\DFBSI"
#define AYA_LINK L"\\DosDevices\\DFBSI"
HANDLE NTAPI AYA_OpenFile( IN PWCHAR szFileName )
{
NTSTATUS ns = STATUS_SUCCESS;
UNICODE_STRING FileName;
OBJECT_ATTRIBUTES oa;
HANDLE hFile;
IO_STATUS_BLOCK IoStatus;
if ( KeGetCurrentIrql() > PASSIVE_LEVEL )
{
KdPrint(( " Irql Error " ));
return NULL;
}
RtlInitUnicodeString( & FileName ,szFileName );
InitializeObjectAttributes( & oa , & FileName ,OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE ,\
NULL ,NULL);
ns = IoCreateFile( & hFile ,FILE_READ_ATTRIBUTES , & oa , & IoStatus , 0 ,FILE_ATTRIBUTE_NORMAL ,\
FILE_SHARE_DELETE ,FILE_OPEN , 0 ,NULL , 0 ,CreateFileTypeNone ,\
NULL ,IO_NO_PARAMETER_CHECKING );
if ( ! NT_SUCCESS( ns ) )
{
ZwClose( hFile );
KdPrint(( " IoCreateFile Error " ));
return NULL;
}
return hFile;
}
NTSTATUS
IoSetFileCompletion(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp,
IN PVOID Context
)
{
Irp -> UserIosb -> Status = Irp -> IoStatus.Status;
Irp -> UserIosb -> Information = Irp -> IoStatus.Information;
KeSetEvent( Irp -> UserEvent ,IO_NO_INCREMENT ,FALSE );
IoFreeIrp( Irp );
return STATUS_MORE_PROCESSING_REQUIRED;
}
NTSTATUS NTAPI StripFileAttributes( IN HANDLE hFile )
{
NTSTATUS ns = STATUS_SUCCESS;
PFILE_OBJECT pFileObject;
PDEVICE_OBJECT pDeviceObject;
PIRP pIrp;
KEVENT kFsEvent;
FILE_BASIC_INFORMATION FileInformation;
IO_STATUS_BLOCK IoStatus;
PIO_STACK_LOCATION pIrpSt;
ns = ObReferenceObjectByHandle( hFile ,DELETE , * IoFileObjectType ,KernelMode ,\
(PVOID * ) & pFileObject ,NULL );
if ( ! NT_SUCCESS( ns ) )
{
ObReferenceObject( pFileObject );
KdPrint(( " StripFileAttributes ObReferenceObjectByHandle Error " ));
return ns;
}
pDeviceObject = IoGetRelatedDeviceObject( pFileObject );
pIrp = IoAllocateIrp( pDeviceObject -> StackSize ,TRUE );
if ( pIrp == NULL )
{
ObReferenceObject( pFileObject );
KdPrint(( " StripFileAttributes IoAllocateIrp Error " ));
return STATUS_UNSUCCESSFUL;
}
KeInitializeEvent( & kFsEvent ,SynchronizationEvent ,FALSE );
RtlZeroMemory( & FileInformation , sizeof ( FILE_BASIC_INFORMATION ) );
FileInformation.FileAttributes = FILE_ATTRIBUTE_NORMAL;
pIrp -> AssociatedIrp.SystemBuffer = & FileInformation;
pIrp -> UserEvent = & kFsEvent;
pIrp -> UserIosb = & IoStatus;
pIrp -> Tail.Overlay.Thread = PsGetCurrentThread();
pIrp -> Tail.Overlay.OriginalFileObject = pFileObject;
pIrp -> RequestorMode = KernelMode;
pIrpSt = IoGetNextIrpStackLocation( pIrp );
pIrpSt -> MajorFunction = IRP_MJ_SET_INFORMATION;
pIrpSt -> DeviceObject = pDeviceObject;
pIrpSt -> FileObject = pFileObject;
pIrpSt -> Parameters.SetFile.Length = sizeof ( FILE_BASIC_INFORMATION );
pIrpSt -> Parameters.SetFile.FileObject = pFileObject;
pIrpSt -> Parameters.SetFile.FileInformationClass
= FileBasicInformation;
IoSetCompletionRoutine( pIrp ,IoSetFileCompletion ,NULL ,TRUE ,TRUE ,TRUE );
IoCallDriver( pDeviceObject ,pIrp );
KeWaitForSingleObject( & kFsEvent ,Executive ,KernelMode ,TRUE ,NULL );
ObReferenceObject( pFileObject );
return STATUS_SUCCESS;
}
NTSTATUS NTAPI DeleteFileBySendIrp( IN HANDLE hFile )
{
NTSTATUS ns = STATUS_SUCCESS;
PFILE_OBJECT pFileObject;
PDEVICE_OBJECT pDeviceObject;
PIRP pIrp;
KEVENT kFsEvent;
FILE_DISPOSITION_INFORMATION FileInformation;
IO_STATUS_BLOCK IoStatus;
PIO_STACK_LOCATION pIrpSt;
PSECTION_OBJECT_POINTERS pSectionObjectPointer;
ns = ObReferenceObjectByHandle( hFile ,DELETE , * IoFileObjectType ,KernelMode ,\
(PVOID * ) & pFileObject ,NULL );
if ( ! NT_SUCCESS( ns ) )
{
ObReferenceObject( pFileObject );
KdPrint(( " DeleteFileBySendIrp ObReferenceObjectByHandle Error " ));
return ns;
}
pDeviceObject = IoGetRelatedDeviceObject( pFileObject );
pIrp = IoAllocateIrp( pDeviceObject -> StackSize ,TRUE );
if ( pIrp == NULL )
{
ObReferenceObject( pFileObject );
KdPrint(( " DeleteFileBySendIrp IoAllocateIrp Error " ));
return STATUS_UNSUCCESSFUL;
}
KeInitializeEvent( & kFsEvent ,SynchronizationEvent ,FALSE );
FileInformation.DeleteFile = TRUE;
pIrp -> AssociatedIrp.SystemBuffer = & FileInformation;
pIrp -> UserEvent = & kFsEvent;
pIrp -> UserIosb = & IoStatus;
pIrp -> Tail.Overlay.Thread = PsGetCurrentThread();
pIrp -> Tail.Overlay.OriginalFileObject = pFileObject;
pIrp -> RequestorMode = KernelMode;
pIrpSt = IoGetNextIrpStackLocation( pIrp );
pIrpSt -> MajorFunction = IRP_MJ_SET_INFORMATION;
pIrpSt -> DeviceObject = pDeviceObject;
pIrpSt -> FileObject = pFileObject;
pIrpSt -> Parameters.SetFile.Length = sizeof ( FILE_DISPOSITION_INFORMATION );
pIrpSt -> Parameters.SetFile.FileObject = pFileObject;
pIrpSt -> Parameters.SetFile.FileInformationClass
= FileDispositionInformation;
IoSetCompletionRoutine( pIrp ,IoSetFileCompletion ,NULL ,TRUE ,TRUE ,TRUE );
pSectionObjectPointer = pFileObject -> SectionObjectPointer;
pSectionObjectPointer -> DataSectionObject = 0 ;
pSectionObjectPointer -> ImageSectionObject = 0 ;
IoCallDriver( pDeviceObject ,pIrp );
KeWaitForSingleObject( & kFsEvent ,Executive ,KernelMode ,TRUE ,NULL );
ObReferenceObject( pFileObject );
KdPrint(( " OK " ));
return STATUS_SUCCESS;
}
NTSTATUS NTAPI ForceDeleteFiles( PWCHAR szFileName )
{
HANDLE hFile;
NTSTATUS ns = STATUS_SUCCESS;
hFile = AYA_OpenFile( szFileName );
ns = StripFileAttributes( hFile );
if ( ! NT_SUCCESS( ns ) )
{
ZwClose( hFile );
KdPrint(( " ForceDeleteFiles StripFileAttributes Error " ));
return ns;
}
ns = DeleteFileBySendIrp( hFile );
if ( ! NT_SUCCESS( ns ) )
{
ZwClose( hFile );
KdPrint(( " ForceDeleteFiles DeleteFileBySendIrp Error " ));
return ns;
}
ZwClose( hFile );
return ns;
}
void AYA_Unload( IN PDRIVER_OBJECT pDriverObj )
{
UNICODE_STRING Temp;
RtlInitUnicodeString( & Temp ,AYA_LINK );
IoDeleteSymbolicLink( & Temp );
IoDeleteDevice( pDriverObj -> DeviceObject );
}
NTSTATUS AYA_Dispatch( IN PDEVICE_OBJECT pDeviceObj ,IN PIRP pIrp )
{
NTSTATUS ns = STATUS_SUCCESS;
PIO_STACK_LOCATION stIrp;
stIrp = IoGetCurrentIrpStackLocation( pIrp );
switch ( stIrp -> MajorFunction )
{
case IRP_MJ_CREATE:
break ;
case IRP_MJ_CLOSE:
break ;
case IRP_MJ_DEVICE_CONTROL:
break ;
default :
pIrp -> IoStatus.Status = STATUS_INVALID_PARAMETER;
break ;
}
ns = pIrp -> IoStatus.Status;
IoCompleteRequest( pIrp ,IO_NO_INCREMENT );
return ns;
}
NTSTATUS DriverEntry( IN PDRIVER_OBJECT pDriverObj ,IN PUNICODE_STRING RegistryPath )
{
NTSTATUS ns = STATUS_SUCCESS;
UNICODE_STRING AYA;
UNICODE_STRING AYAL;
PDEVICE_OBJECT pDevice;
WCHAR szFileName[] = L " \\??\\C:\\2.txt " ;
RtlInitUnicodeString( & AYA ,AYA_DEVICE );
ns = IoCreateDevice( pDriverObj , 0 , & AYA ,FILE_DEVICE_UNKNOWN , 0 ,FALSE , & pDevice );
RtlInitUnicodeString( & AYAL ,AYA_LINK );
ns = IoCreateSymbolicLink( & AYAL , & AYA );
pDriverObj -> MajorFunction[IRP_MJ_CREATE] =
pDriverObj -> MajorFunction[IRP_MJ_CLOSE] =
pDriverObj -> MajorFunction[IRP_MJ_DEVICE_CONTROL] = AYA_Dispatch;
pDriverObj -> DriverUnload = AYA_Unload;
ForceDeleteFiles( szFileName );
return ns;
}