在网上逛游的时候,看到了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;
}