neak47
驱动小牛
驱动小牛
  • 注册日期2009-05-25
  • 最后登录2016-01-09
  • 粉丝4
  • 关注0
  • 积分140分
  • 威望1221点
  • 贡献值1点
  • 好评度0点
  • 原创分0分
  • 专家分1分
阅读:3591回复:1

使用IRP进行文件操作

楼主#
更多 发布于:2009-09-04 11:00
#include "ntifs.h"
 
//
//  Define the structure used by this driver module. 
//
typedef struct _AUX_ACCESS_DATA {
    PPRIVILEGE_SET PrivilegesUsed;
    GENERIC_MAPPING GenericMapping;
    ACCESS_MASK AccessesToAudit;
    ULONG Reserve;                        //unknow...
} AUX_ACCESS_DATA, *PAUX_ACCESS_DATA;
//
//  Define the local routines used by this driver module. 
//
NTSTATUS
ObCreateObject (
    IN KPROCESSOR_MODE ProbeMode,
    IN POBJECT_TYPE ObjectType,
    IN POBJECT_ATTRIBUTES ObjectAttributes OPTIONAL,
    IN KPROCESSOR_MODE OwnershipMode,
    IN OUT PVOID ParseContext OPTIONAL,
    IN ULONG ObjectBodySize,
    IN ULONG PagedPoolCharge,
    IN ULONG NonPagedPoolCharge,
    OUT PVOID *Object
    );
NTSTATUS
SeCreateAccessState(
    IN PACCESS_STATE AccessState,
    IN PAUX_ACCESS_DATA AuxData,
    IN ACCESS_MASK DesiredAccess,
    IN PGENERIC_MAPPING GenericMapping OPTIONAL
    );
//
// IoCompletionRoutine
//
// This routine is used to handle I/O (read OR write) completion
//
// Inputs:
// DeviceObject - not used
// Irp - the I/O operation being completed
// Context - not used
//
// Outputs:
// None.
//
// Returns:
// STATUS_MORE_PROCESSING_REQUIRED
//
// Notes:
// The purpose of this routine is to do "cleanup" on I/O operations
// so we don't constantly throw away perfectly good MDLs as part of
// completion processing.
//
NTSTATUS
IoCompletionRoutine(
    IN PDEVICE_OBJECT DeviceObject,
    IN PIRP Irp,
    IN PVOID Context
    );
//
// IrpCreateFile
//
// This routine is used as NtCreateFile but first and third parameter.
//
// Inputs:
// DesiredAccess - Specifies an ACCESS_MASK value that determines
//                    the requested access to the object. 
// FilePath - Path of file to create,as L"C:\\Windows"(Unicode).
// AllocationSize - Pointer to a LARGE_INTEGER that contains the initial allocation
//                    size, in bytes, for a file that is created or overwritten.
// FileAttributes - Specifies one or more FILE_ATTRIBUTE_XXX flags, which represent
//                    the file attributes to set if you are creating or overwriting a file.
// ShareAccess - Type of share access.
// CreateDisposition - Specifies the action to perform if the file does or does not exist.
// CreateOptions - Specifies the options to apply when creating or opening the file. 
// EaBuffer - For device and intermediate drivers, this parameter must be a NULL pointer. 
// EaLength - For device and intermediate drivers, this parameter must be zero.
//
// Ouputs:
// FileObject - Pointer to a PFILE_OBJECT variable that
//                receives a PFILE_OBJECT to the file.
// IoStatusBlock - Pointer to an IO_STATUS_BLOCK structure that receives the final
//                completion status and information about the requested read operation. 
//
// Returns:
// The IRP send status.
//
// Notes:
// This is equivalent to NtCreateFile,but return FILE_OBJECT not HANDLE.
//
NTSTATUS
IrpCreateFile(
    OUT PFILE_OBJECT  *FileObject,
    IN ACCESS_MASK  DesiredAccess,
    IN PUNICODE_STRING  FilePath,
    OUT PIO_STATUS_BLOCK  IoStatusBlock,
    IN PLARGE_INTEGER  AllocationSize OPTIONAL,
    IN ULONG  FileAttributes,
    IN ULONG  ShareAccess,
    IN ULONG  CreateDisposition,
    IN ULONG  CreateOptions,
    IN PVOID  EaBuffer OPTIONAL,
    IN ULONG  EaLength
    );
//
// IrpClose
//
// This routine is used as ObDereferenceObject.
//
// Inputs:
// FileObject - Pointer to a PFILE_OBJECT variable that will close
//
// Ouputs:
// IoStatusBlock - Pointer to an IO_STATUS_BLOCK structure that receives the final
//                completion status and information about the requested read operation. 
//
// Returns:
// The IRP send status.
//
// Notes:
// This is equivalent to ObDereferenceObject
//
NTSTATUS
IrpClose(
    IN PFILE_OBJECT  FileObject
    );
//
// IrpQueryDirectoryFile
//
// This routine is used as NtQueryDirectoryFile.
//
// Inputs:
// FileObject - Pointer to a PFILE_OBJECT.
// Length - Size, in bytes, of the buffer pointed to by FileInformation. The caller
//            should set this parameter according to the given FileInformationClass. 
// FileInformationClass - Type of information to be returned about files in the directory. 
// FileName - Pointer to a caller-allocated Unicode string containing the name of a file
//            (or multiple files, if wildcards are used) within the directory specified by FileHandle.
//            This parameter is optional and can be NULL. 
//
// Ouputs:
// IoStatusBlock - Pointer to an IO_STATUS_BLOCK structure that receives the final
//                completion status and information about the requested read operation. 
// FileInformation - Pointer to a buffer that receives the desired
//                        information about the file. 
//
// Returns:
// The IRP send status.
//
// Notes:
// This is equivalent to NtQueryDirectoryFile, but no ApcRoutine.
//
NTSTATUS
IrpQueryDirectoryFile(
    IN PFILE_OBJECT  FileObject,
    OUT PIO_STATUS_BLOCK  IoStatusBlock,
    OUT PVOID  FileInformation,
    IN ULONG  Length,
    IN FILE_INFORMATION_CLASS  FileInformationClass,
    IN PUNICODE_STRING  FileName  OPTIONAL
    );
//
// IrpQueryInformationFile
//
// This routine is used as NtQueryInformationFile.
//
// Inputs:
// FileObject - Pointer to a PFILE_OBJECT.
// Length - Size, in bytes, of the buffer pointed to by FileInformation. The caller
//            should set this parameter according to the given FileInformationClass. 
// FileInformationClass - Type of information to be returned about files in the directory. 
//
// Ouputs:
// IoStatusBlock - Pointer to an IO_STATUS_BLOCK structure that receives the final
//                completion status and information about the requested read operation. 
// FileInformation - Pointer to a buffer that receives the desired
//                        information about the file. 
//
// Returns:
// The IRP send status.
//
// Notes:
// This is equivalent to NtQueryInformationFile.
//
NTSTATUS
IrpQueryInformationFile(
    IN PFILE_OBJECT  FileObject,
    OUT PIO_STATUS_BLOCK  IoStatusBlock,
    OUT PVOID  FileInformation,
    IN ULONG  Length,
    IN FILE_INFORMATION_CLASS  FileInformationClass
    );
//
// IrpSetInformationFile
//
// This routine is used as NtSetInformationFile.
//
// Inputs:
// FileObject - Pointer to a PFILE_OBJECT.
// FileInformation - Pointer to a buffer that contains the information to set for the file.  
// Length - Size, in bytes, of the buffer pointed to by FileInformation. The caller
//            should set this parameter according to the given FileInformationClass. 
// FileInformationClass - Type of information to be returned about files in the directory. 
// ReplaceIfExists - Set to TRUE to specify that if a file with the same name already exists,
//                    it should be replaced with the given file. Set to FALSE if the rename
//                    operation should fail if a file with the given name already exists. 
//
// Ouputs:
// IoStatusBlock - Pointer to an IO_STATUS_BLOCK structure that receives the final
//                completion status and information about the requested read operation. 
//
// Returns:
// The IRP send status.
//
// Notes:
// This is equivalent to NtSetInformationFile.
//
NTSTATUS
IrpSetInformationFile(
    IN PFILE_OBJECT  FileObject,
    OUT PIO_STATUS_BLOCK  IoStatusBlock,
    IN PVOID  FileInformation,
    IN ULONG  Length,
    IN FILE_INFORMATION_CLASS  FileInformationClass,
    IN BOOLEAN  ReplaceIfExists
    );
//
// IrpReadFile
//
// This routine is used as NtReadFile.
//
// Inputs:
// FileObject - Pointer to a PFILE_OBJECT.
// Buffer - Pointer to a caller-allocated buffer that receives the data read from the file.
// Length - The size, in bytes, of the buffer pointed to by Buffer. 
// ByteOffset - Pointer to a variable that specifies the starting byte offset
//                in the file where the read operation will begin. 
//
// Ouputs:
// IoStatusBlock - Pointer to an IO_STATUS_BLOCK structure that receives the final
//                completion status and information about the requested read operation. 
//
// Returns:
// The IRP send status.
//
// Notes:
// This is equivalent to NtReadFile, but no ApcRoutine.
//
NTSTATUS
IrpReadFile(
    IN PFILE_OBJECT  FileObject,
    OUT PIO_STATUS_BLOCK  IoStatusBlock,
    OUT PVOID  Buffer,
    IN ULONG  Length,
    IN PLARGE_INTEGER  ByteOffset  OPTIONAL
    );
//
// IrpReadFile
//
// This routine is used as NtReadFile.
//
// Inputs:
// FileObject - Pointer to a PFILE_OBJECT.
// Buffer - Pointer to a caller-allocated buffer that contains the data to write to the file. 
// Length - The size, in bytes, of the buffer pointed to by Buffer. 
// ByteOffset - Pointer to a variable that specifies the starting byte offset
//                in the file for beginning the write operation.
//
// Ouputs:
// IoStatusBlock - Pointer to an IO_STATUS_BLOCK structure that receives the final
//                completion status and information about the requested read operation. 
//
// Returns:
// The IRP send status.
//
// Notes:
// This is equivalent to NtReadFile, but no ApcRoutine.
//
NTSTATUS 
IrpWriteFile(
    IN PFILE_OBJECT  FileObject,
    OUT PIO_STATUS_BLOCK  IoStatusBlock,
    IN PVOID  Buffer,
    IN ULONG  Length,
    IN PLARGE_INTEGER  ByteOffset  OPTIONAL
    );
 
//
// Function start.
//
NTSTATUS
IoCompletionRoutine(
    IN PDEVICE_OBJECT DeviceObject,
    IN PIRP Irp,
    IN PVOID Context)
{
    *Irp->UserIosb = Irp->IoStatus;
    if (Irp->UserEvent)
        KeSetEvent(Irp->UserEvent, IO_NO_INCREMENT, 0);
    if (Irp->MdlAddress)
    {
        IoFreeMdl(Irp->MdlAddress);
        Irp->MdlAddress = NULL;
    }
    IoFreeIrp(Irp);
    return STATUS_MORE_PROCESSING_REQUIRED;
}
 
NTSTATUS
IrpCreateFile(
    OUT PFILE_OBJECT  *FileObject,
    IN ACCESS_MASK  DesiredAccess,
    IN PUNICODE_STRING  FilePath,
    OUT PIO_STATUS_BLOCK  IoStatusBlock,
    IN PLARGE_INTEGER  AllocationSize  OPTIONAL,
    IN ULONG  FileAttributes,
    IN ULONG  ShareAccess,
    IN ULONG  CreateDisposition,
    IN ULONG  CreateOptions,
    IN PVOID  EaBuffer  OPTIONAL,
    IN ULONG  EaLength)
{
    NTSTATUS ntStatus;
 
    HANDLE hFile;
    PFILE_OBJECT pFile, _FileObject;
    UNICODE_STRING UniDeviceNameString;
    OBJECT_ATTRIBUTES ObjectAttributes;
    PDEVICE_OBJECT DeviceObject, RealDevice;
 
    PIRP Irp;
    KEVENT kEvent;
    PIO_STACK_LOCATION IrpSp;
    ACCESS_STATE AccessState;
    AUX_ACCESS_DATA AuxData;
    IO_SECURITY_CONTEXT SecurityContext;
 
    if(FilePath->Length < 6)
        return STATUS_INVALID_PARAMETER;
 
    RtlInitUnicodeString( &UniDeviceNameString, L"\\DosDevices\\*:\\" );
    UniDeviceNameString.Buffer[12] = FilePath->Buffer[0];
    InitializeObjectAttributes(&ObjectAttributes, &UniDeviceNameString, OBJ_KERNEL_HANDLE, NULL, NULL);
 
    ntStatus = IoCreateFile(&hFile,
                            GENERIC_READ|SYNCHRONIZE,
                            &ObjectAttributes,
                            IoStatusBlock,
                            NULL,
                            FILE_ATTRIBUTE_NORMAL,
                            FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
                            FILE_OPEN,
                            FILE_SYNCHRONOUS_IO_NONALERT,
                            NULL,
                            0,
                            CreateFileTypeNone,
                            NULL,
                            IO_NO_PARAMETER_CHECKING);
    if(!NT_SUCCESS(ntStatus)) return ntStatus;
 
    ntStatus = ObReferenceObjectByHandle(hFile,
                                         FILE_READ_ACCESS, // ACCESS_MASK
                                         *IoFileObjectType,
                                         KernelMode,
                                         &pFile,
                                         0);
    NtClose(hFile);
    if(!NT_SUCCESS(ntStatus)) return ntStatus;
 
    DeviceObject = pFile->Vpb->DeviceObject;
    RealDevice = pFile->Vpb->RealDevice;
    ObDereferenceObject(pFile);
 
    InitializeObjectAttributes(&ObjectAttributes, NULL, OBJ_CASE_INSENSITIVE, 0, NULL);
 
    ntStatus = ObCreateObject(KernelMode,
                              *IoFileObjectType,
                              &ObjectAttributes,
                              KernelMode,
                              NULL,
                              sizeof(FILE_OBJECT),
                              0,
                              0,
                              &_FileObject);
    if (!NT_SUCCESS(ntStatus)) return ntStatus;
 
    Irp = IoAllocateIrp(DeviceObject->StackSize, FALSE);
    if(Irp == NULL)
    {
        ObDereferenceObject(_FileObject);
        return STATUS_INSUFFICIENT_RESOURCES;
    }
 
    KeInitializeEvent(&kEvent, SynchronizationEvent, FALSE);
 
    RtlZeroMemory(_FileObject, sizeof(FILE_OBJECT));
    _FileObject->Type = IO_TYPE_FILE;
    _FileObject->Size = sizeof(FILE_OBJECT);
    _FileObject->DeviceObject = RealDevice;
    _FileObject->Flags = FO_SYNCHRONOUS_IO;
    RtlInitUnicodeString( &_FileObject->FileName, &FilePath->Buffer[2]);
    KeInitializeEvent(&_FileObject->Lock, SynchronizationEvent, FALSE);
    KeInitializeEvent(&_FileObject->Event, NotificationEvent, FALSE);
 
    RtlZeroMemory(&AuxData, sizeof(AUX_ACCESS_DATA));
    ntStatus = SeCreateAccessState( &AccessState,
                                    &AuxData,
                                    DesiredAccess,
                                    IoGetFileObjectGenericMapping());
    if (!NT_SUCCESS(ntStatus))
    {
        IoFreeIrp(Irp);
        ObDereferenceObject(_FileObject);
        return ntStatus;
    }
    SecurityContext.SecurityQos = NULL;
    SecurityContext.AccessState = &AccessState;
    SecurityContext.DesiredAccess = DesiredAccess;
    SecurityContext.FullCreateOptions = 0;
 
    Irp->MdlAddress = NULL;
    Irp->AssociatedIrp.SystemBuffer = EaBuffer;
    Irp->Flags = IRP_CREATE_OPERATION|IRP_SYNCHRONOUS_API;
    Irp->RequestorMode = KernelMode;
    Irp->UserIosb = IoStatusBlock;
    Irp->UserEvent = &kEvent;
    Irp->PendingReturned = FALSE;
    Irp->Cancel = FALSE;
    Irp->CancelRoutine = NULL;
    Irp->Tail.Overlay.Thread = PsGetCurrentThread();
    Irp->Tail.Overlay.AuxiliaryBuffer = NULL;
    Irp->Tail.Overlay.OriginalFileObject = _FileObject;
 
    IrpSp = IoGetNextIrpStackLocation(Irp);
    IrpSp->MajorFunction = IRP_MJ_CREATE;
    IrpSp->DeviceObject = DeviceObject;
    IrpSp->FileObject = _FileObject;
    IrpSp->Parameters.Create.SecurityContext = &SecurityContext;
    IrpSp->Parameters.Create.Options = (CreateDisposition << 24) | CreateOptions;
    IrpSp->Parameters.Create.FileAttributes = (USHORT)FileAttributes;
    IrpSp->Parameters.Create.ShareAccess = (USHORT)ShareAccess;
    IrpSp->Parameters.Create.EaLength = EaLength;
 
    IoSetCompletionRoutine(Irp, IoCompletionRoutine, 0, TRUE, TRUE, TRUE);
    ntStatus = IoCallDriver(DeviceObject, Irp);
    if(ntStatus == STATUS_PENDING)
        KeWaitForSingleObject(&kEvent, Executive, KernelMode, TRUE, 0);
 
    ntStatus = IoStatusBlock->Status;
 
    if(!NT_SUCCESS(ntStatus))
     {
    _FileObject->DeviceObject =NULL;
        ObDereferenceObject(_FileObject);
    }
    else
    {
        InterlockedIncrement(&_FileObject->DeviceObject->ReferenceCount);
        if (_FileObject->Vpb)
            InterlockedIncrement(&_FileObject->Vpb->ReferenceCount);
        *FileObject = _FileObject;
    }
 
    return ntStatus;
}
 
NTSTATUS
IrpClose(
    IN PFILE_OBJECT  FileObject)
{
    NTSTATUS ntStatus;
    IO_STATUS_BLOCK  IoStatusBlock;
    PIRP Irp;
    KEVENT kEvent;
    PIO_STACK_LOCATION IrpSp;
    PDEVICE_OBJECT pBaseDeviceObject = FileObject->Vpb->DeviceObject;
 
    if (FileObject->Vpb == 0 || FileObject->Vpb->DeviceObject == NULL)
        return STATUS_UNSUCCESSFUL;
 
    Irp = IoAllocateIrp(FileObject->Vpb->DeviceObject->StackSize, FALSE);
    if(Irp == NULL) return STATUS_INSUFFICIENT_RESOURCES;
 
    KeInitializeEvent(&kEvent, SynchronizationEvent, FALSE);
 
    Irp->UserEvent = &kEvent;
    Irp->UserIosb = &IoStatusBlock;
    Irp->RequestorMode = KernelMode;
    Irp->Flags = IRP_CLOSE_OPERATION|IRP_SYNCHRONOUS_API;
    Irp->Tail.Overlay.Thread = PsGetCurrentThread();
    Irp->Tail.Overlay.OriginalFileObject = FileObject;
 
    IrpSp = IoGetNextIrpStackLocation(Irp);
    IrpSp->MajorFunction = IRP_MJ_CLEANUP;
    IrpSp->FileObject = FileObject;
 
    ntStatus = IoCallDriver(pBaseDeviceObject, Irp);
    if (ntStatus == STATUS_PENDING)
        KeWaitForSingleObject(&kEvent, Executive, KernelMode, FALSE, NULL);
 
    ntStatus = IoStatusBlock.Status;
    if(!NT_SUCCESS(ntStatus))
    {
        IoFreeIrp(Irp);
        return ntStatus;
    }
 
    KeClearEvent(&kEvent);
    IoReuseIrp(Irp , STATUS_SUCCESS);
 
    Irp->UserEvent = &kEvent;
    Irp->UserIosb = &IoStatusBlock;
    Irp->Tail.Overlay.OriginalFileObject = FileObject;
    Irp->Tail.Overlay.Thread = PsGetCurrentThread();
    Irp->AssociatedIrp.SystemBuffer = (PVOID)NULL;
    Irp->Flags = IRP_CLOSE_OPERATION|IRP_SYNCHRONOUS_API;
 
    IrpSp = IoGetNextIrpStackLocation(Irp);
    IrpSp->MajorFunction = IRP_MJ_CLOSE;
    IrpSp->FileObject = FileObject;
 
    if (FileObject->Vpb && !(FileObject->Flags & FO_DIRECT_DEVICE_OPEN))
    {
        InterlockedDecrement(&FileObject->Vpb->ReferenceCount);
        FileObject->Flags |= FO_FILE_OPEN_CANCELLED;
    }
 
    ntStatus = IoCallDriver(pBaseDeviceObject, Irp);
    if (ntStatus == STATUS_PENDING)
        KeWaitForSingleObject(&kEvent, Executive, KernelMode, FALSE, NULL);
 
    IoFreeIrp(Irp);
 
    ntStatus = IoStatusBlock.Status;
    return ntStatus;
}
 
NTSTATUS
IrpQueryDirectoryFile(
    IN PFILE_OBJECT  FileObject,
    OUT PIO_STATUS_BLOCK  IoStatusBlock,
    OUT PVOID  FileInformation,
    IN ULONG  Length,
    IN FILE_INFORMATION_CLASS  FileInformationClass,
    IN PUNICODE_STRING  FileName  OPTIONAL)
{
    NTSTATUS ntStatus;
    PIRP Irp;
    KEVENT kEvent;
    PIO_STACK_LOCATION IrpSp;
 
    if (FileObject->Vpb == 0 || FileObject->Vpb->DeviceObject == NULL)
        return STATUS_UNSUCCESSFUL;
 
    Irp = IoAllocateIrp(FileObject->Vpb->DeviceObject->StackSize, FALSE);
    if(Irp == NULL) return STATUS_INSUFFICIENT_RESOURCES;
 
    KeInitializeEvent(&kEvent, SynchronizationEvent, FALSE);
 
    RtlZeroMemory(FileInformation, Length);
    Irp->UserEvent = &kEvent;
    Irp->UserIosb = IoStatusBlock;
    Irp->UserBuffer = FileInformation;
    Irp->Tail.Overlay.Thread = PsGetCurrentThread();
    Irp->Tail.Overlay.OriginalFileObject = FileObject;
    Irp->Overlay.AsynchronousParameters.UserApcRoutine = (PIO_APC_ROUTINE)NULL;
 
    IrpSp = IoGetNextIrpStackLocation(Irp);
    IrpSp->MajorFunction = IRP_MJ_DIRECTORY_CONTROL;
    IrpSp->MinorFunction = IRP_MN_QUERY_DIRECTORY;
    IrpSp->FileObject = FileObject;
    IrpSp->Flags = SL_RESTART_SCAN;
    IrpSp->Parameters.QueryDirectory.Length = Length;
    IrpSp->Parameters.QueryDirectory.FileName = FileName;
    IrpSp->Parameters.QueryDirectory.FileInformationClass = FileInformationClass;
 
    IoSetCompletionRoutine(Irp, IoCompletionRoutine, 0, TRUE, TRUE, TRUE);
    ntStatus = IoCallDriver(FileObject->Vpb->DeviceObject, Irp);
    if (ntStatus == STATUS_PENDING)
        KeWaitForSingleObject(&kEvent, Executive, KernelMode, TRUE, 0);
 
    return IoStatusBlock->Status;
}
 
NTSTATUS
IrpQueryInformationFile(
    IN PFILE_OBJECT  FileObject,
    OUT PIO_STATUS_BLOCK  IoStatusBlock,
    OUT PVOID  FileInformation,
    IN ULONG  Length,
    IN FILE_INFORMATION_CLASS  FileInformationClass)
{
    NTSTATUS ntStatus;
    PIRP Irp;
    KEVENT kEvent;
    PIO_STACK_LOCATION IrpSp;
 
    if (FileObject->Vpb == 0 || FileObject->Vpb->DeviceObject == NULL)
        return STATUS_UNSUCCESSFUL;
 
    Irp = IoAllocateIrp(FileObject->Vpb->DeviceObject->StackSize, FALSE);
    if(Irp == NULL) return STATUS_INSUFFICIENT_RESOURCES;
 
    KeInitializeEvent(&kEvent, SynchronizationEvent, FALSE);
 
    RtlZeroMemory(FileInformation, Length);
    Irp->AssociatedIrp.SystemBuffer = FileInformation;
    Irp->UserEvent = &kEvent;
    Irp->UserIosb = IoStatusBlock;
    Irp->RequestorMode = KernelMode;
    Irp->Tail.Overlay.Thread = PsGetCurrentThread();
    Irp->Tail.Overlay.OriginalFileObject = FileObject;
 
    IrpSp = IoGetNextIrpStackLocation(Irp);
    IrpSp->MajorFunction = IRP_MJ_QUERY_INFORMATION;
    IrpSp->DeviceObject = FileObject->Vpb->DeviceObject;
    IrpSp->FileObject = FileObject;
    IrpSp->Parameters.QueryFile.Length = Length;
    IrpSp->Parameters.QueryFile.FileInformationClass = FileInformationClass;
 
    IoSetCompletionRoutine(Irp, IoCompletionRoutine, 0, TRUE, TRUE, TRUE);
    ntStatus = IoCallDriver(FileObject->Vpb->DeviceObject, Irp);
    if (ntStatus == STATUS_PENDING)
        KeWaitForSingleObject(&kEvent, Executive, KernelMode, TRUE, 0);
 
    return IoStatusBlock->Status;
}
 
NTSTATUS
IrpSetInformationFile(
    IN PFILE_OBJECT  FileObject,
    OUT PIO_STATUS_BLOCK  IoStatusBlock,
    IN PVOID  FileInformation,
    IN ULONG  Length,
    IN FILE_INFORMATION_CLASS  FileInformationClass,
    IN BOOLEAN  ReplaceIfExists)
{
    NTSTATUS ntStatus;
    PIRP Irp;
    KEVENT kEvent;
    PIO_STACK_LOCATION IrpSp;
 
    if (FileObject->Vpb == 0 || FileObject->Vpb->DeviceObject == NULL)
        return STATUS_UNSUCCESSFUL;
 
    Irp = IoAllocateIrp(FileObject->Vpb->DeviceObject->StackSize, FALSE);
    if(Irp == NULL) return STATUS_INSUFFICIENT_RESOURCES;
 
    KeInitializeEvent(&kEvent, SynchronizationEvent, FALSE);
 
    Irp->AssociatedIrp.SystemBuffer = FileInformation;
    Irp->UserEvent = &kEvent;
    Irp->UserIosb = IoStatusBlock;
    Irp->RequestorMode = KernelMode;
    Irp->Tail.Overlay.Thread = PsGetCurrentThread();
    Irp->Tail.Overlay.OriginalFileObject = FileObject;
 
    IrpSp = IoGetNextIrpStackLocation(Irp);
    IrpSp->MajorFunction = IRP_MJ_SET_INFORMATION;
    IrpSp->DeviceObject = FileObject->Vpb->DeviceObject;
    IrpSp->FileObject = FileObject;
    IrpSp->Parameters.SetFile.ReplaceIfExists = ReplaceIfExists;
    IrpSp->Parameters.SetFile.FileObject = FileObject;
    IrpSp->Parameters.SetFile.AdvanceOnly = FALSE;
    IrpSp->Parameters.SetFile.Length = Length;
    IrpSp->Parameters.SetFile.FileInformationClass = FileInformationClass;
 
    IoSetCompletionRoutine(Irp, IoCompletionRoutine, 0, TRUE, TRUE, TRUE);
    ntStatus = IoCallDriver(FileObject->Vpb->DeviceObject, Irp);
    if (ntStatus == STATUS_PENDING)
        KeWaitForSingleObject(&kEvent, Executive, KernelMode, TRUE, 0);
 
    return IoStatusBlock->Status;
}
 
NTSTATUS
IrpReadFile(
    IN PFILE_OBJECT  FileObject,
    OUT PIO_STATUS_BLOCK  IoStatusBlock,
    OUT PVOID  Buffer,
    IN ULONG  Length,
    IN PLARGE_INTEGER  ByteOffset  OPTIONAL)
{
    NTSTATUS ntStatus;
    PIRP Irp;
    KEVENT kEvent;
    PIO_STACK_LOCATION IrpSp;
 
    if (FileObject->Vpb == 0 || FileObject->Vpb->DeviceObject == NULL)
        return STATUS_UNSUCCESSFUL;
 
    if(ByteOffset == NULL)
    {
        if(!(FileObject->Flags & FO_SYNCHRONOUS_IO))
            return STATUS_INVALID_PARAMETER;
        ByteOffset = &FileObject->CurrentByteOffset;
    }
 
    Irp = IoAllocateIrp(FileObject->Vpb->DeviceObject->StackSize, FALSE);
    if(Irp == NULL) return STATUS_INSUFFICIENT_RESOURCES;
 
    RtlZeroMemory(Buffer, Length);
    if(FileObject->DeviceObject->Flags & DO_BUFFERED_IO)
    {
        Irp->AssociatedIrp.SystemBuffer = Buffer;
    }
    else if(FileObject->DeviceObject->Flags & DO_DIRECT_IO)
    {
        Irp->MdlAddress = IoAllocateMdl(Buffer, Length, 0, 0, 0);
        if (Irp->MdlAddress == NULL)
        {
            IoFreeIrp(Irp);
            return STATUS_INSUFFICIENT_RESOURCES;
        }
        MmBuildMdlForNonPagedPool(Irp->MdlAddress);
    }
    else
    {
        Irp->UserBuffer = Buffer;
    }
 
    KeInitializeEvent(&kEvent, SynchronizationEvent, FALSE);
 
    Irp->UserEvent = &kEvent;
    Irp->UserIosb = IoStatusBlock;
    Irp->RequestorMode = KernelMode;
    Irp->Flags = IRP_READ_OPERATION;
    Irp->Tail.Overlay.Thread = PsGetCurrentThread();
    Irp->Tail.Overlay.OriginalFileObject = FileObject;
 
    IrpSp = IoGetNextIrpStackLocation(Irp);
    IrpSp->MajorFunction = IRP_MJ_READ;
    IrpSp->MinorFunction = IRP_MN_NORMAL;
    IrpSp->DeviceObject = FileObject->Vpb->DeviceObject;
    IrpSp->FileObject = FileObject;
    IrpSp->Parameters.Read.Length = Length;
    IrpSp->Parameters.Read.ByteOffset = *ByteOffset;
 
    IoSetCompletionRoutine(Irp, IoCompletionRoutine, 0, TRUE, TRUE, TRUE);
    ntStatus = IoCallDriver(FileObject->Vpb->DeviceObject, Irp);
    if (ntStatus == STATUS_PENDING)
        KeWaitForSingleObject(&kEvent, Executive, KernelMode, TRUE, 0);
 
    return IoStatusBlock->Status;
}
 
NTSTATUS 
IrpWriteFile(
    IN PFILE_OBJECT  FileObject,
    OUT PIO_STATUS_BLOCK  IoStatusBlock,
    IN PVOID  Buffer,
    IN ULONG  Length,
    IN PLARGE_INTEGER  ByteOffset  OPTIONAL)
{
    NTSTATUS ntStatus;
    PIRP Irp;
    KEVENT kEvent;
    PIO_STACK_LOCATION IrpSp;
 
    if (FileObject->Vpb == 0 || FileObject->Vpb->DeviceObject == NULL)
        return STATUS_UNSUCCESSFUL;
 
    if (ByteOffset == NULL)
    {
        if (!(FileObject->Flags & FO_SYNCHRONOUS_IO))
            return STATUS_INVALID_PARAMETER;
        ByteOffset = &FileObject->CurrentByteOffset;
    }
 
    Irp = IoAllocateIrp(FileObject->Vpb->DeviceObject->StackSize, FALSE);
    if (Irp == NULL) return STATUS_INSUFFICIENT_RESOURCES;
 
    if(FileObject->DeviceObject->Flags & DO_BUFFERED_IO)
    {
        Irp->AssociatedIrp.SystemBuffer = Buffer;
    }
    else
    {
        Irp->MdlAddress = IoAllocateMdl(Buffer, Length, 0, 0, 0);
        if (Irp->MdlAddress == NULL)
        {
            IoFreeIrp(Irp);
            return STATUS_INSUFFICIENT_RESOURCES;
        }
        MmBuildMdlForNonPagedPool(Irp->MdlAddress);
    }
 
    KeInitializeEvent(&kEvent, SynchronizationEvent, FALSE);
 
    Irp->UserEvent = &kEvent;
    Irp->UserIosb = IoStatusBlock;
    Irp->RequestorMode = KernelMode;
    Irp->Flags = IRP_WRITE_OPERATION;
    Irp->Tail.Overlay.Thread = PsGetCurrentThread();
    Irp->Tail.Overlay.OriginalFileObject = FileObject;
 
    IrpSp = IoGetNextIrpStackLocation(Irp);
    IrpSp->MajorFunction = IRP_MJ_WRITE;
    IrpSp->MinorFunction = IRP_MN_NORMAL;
    IrpSp->DeviceObject = FileObject->Vpb->DeviceObject;
    IrpSp->FileObject = FileObject;
    IrpSp->Parameters.Write.Length = Length;
    IrpSp->Parameters.Write.ByteOffset = *ByteOffset;
 
    IoSetCompletionRoutine(Irp, IoCompletionRoutine, NULL, TRUE, TRUE, TRUE);
    ntStatus = IoCallDriver(FileObject->Vpb->DeviceObject, Irp);
 
    if (ntStatus == STATUS_PENDING)
        KeWaitForSingleObject(&kEvent, Executive, KernelMode, TRUE, NULL);
 
    return IoStatusBlock->Status;
}
znsoft
管理员
管理员
  • 注册日期2001-03-23
  • 最后登录2023-10-25
  • 粉丝300
  • 关注6
  • 积分910分
  • 威望14796点
  • 贡献值7点
  • 好评度2410点
  • 原创分5分
  • 专家分100分
  • 社区居民
  • 最爱沙发
  • 社区明星
沙发#
发布于:2009-09-04 13:17
感谢分享
http://www.zndev.com 免费源码交换网 ----------------------------- 软件创造价值,驱动提供力量! 淡泊以明志,宁静以致远。 ---------------------------------- 勤用搜索,多查资料,先搜再问。
游客

返回顶部