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

📄 kfc.c

📁 操作系统引导的一些介绍,对学习引导的有很大的帮助与提高
💻 C
📖 第 1 页 / 共 2 页
字号:
//  This function retrieves the "standard" information for the underlying file system.
//
// Inputs:
//  FileObject - the file to retrieve information about
//
// Outputs:
//  StandardInformation - the buffer where the data should be stored
//  IoStatusBlock - information about what actually happened.
//
// Returns:
//  None.
//
// Notes:
//  This is equivalent to ZwQueryInformationFile, for FILE_STANDARD_INFORMATION
//

static VOID KfcGetFileStandardInformation(PFILE_OBJECT FileObject,
                                          PFILE_STANDARD_INFORMATION StandardInformation,
                                          PIO_STATUS_BLOCK IoStatusBlock)
{
    PIRP irp;
    PDEVICE_OBJECT fsdDevice = IoGetRelatedDeviceObject(FileObject);
    KEVENT event;
    PIO_STACK_LOCATION ioStackLocation;

    //
    // Start off on the right foot - zero the information block.
    //

    RtlZeroMemory(StandardInformation, sizeof(FILE_STANDARD_INFORMATION));

    //
    // Allocate an irp for this request.  This could also come from a 
    // private pool, for instance.
    //

    irp = IoAllocateIrp(fsdDevice->StackSize, FALSE);

    if (!irp) {
        //
        // Failure!
        //

        return;
    }

    irp->AssociatedIrp.SystemBuffer = StandardInformation;

    irp->UserEvent = &event;

    irp->UserIosb = IoStatusBlock;

    irp->Tail.Overlay.Thread = PsGetCurrentThread();

    irp->Tail.Overlay.OriginalFileObject = FileObject;

    irp->RequestorMode = KernelMode;

    //
    // Initialize the event
    //

    KeInitializeEvent(&event, SynchronizationEvent, FALSE);

    //
    // Set up the I/O stack location.
    //

    ioStackLocation = IoGetNextIrpStackLocation(irp);

    ioStackLocation->MajorFunction = IRP_MJ_QUERY_INFORMATION;

    ioStackLocation->DeviceObject = fsdDevice;

    ioStackLocation->FileObject = FileObject;

    ioStackLocation->Parameters.QueryFile.Length = sizeof(FILE_STANDARD_INFORMATION);
    
    ioStackLocation->Parameters.QueryFile.FileInformationClass = FileStandardInformation;

    //
    // Set the completion routine.
    //

    IoSetCompletionRoutine(irp, KfcIoCompletion, 0, TRUE, TRUE, TRUE);

    //
    // Send it to the FSD
    //

    (void) IoCallDriver(fsdDevice, irp);

    //
    // Wait for the I/O
    //

    KeWaitForSingleObject(&event, Executive, KernelMode, TRUE, 0);

    //
    // Done!
    //

    return;

}



//
// KfcIoCompletion
//
//  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.
//



static NTSTATUS KfcIoCompletion(PDEVICE_OBJECT DeviceObject,
                                PIRP Irp,
                                PVOID Context)
{
    //
    // Copy the status information back into the "user" IOSB.
    //
    
    *Irp->UserIosb = Irp->IoStatus;
    
    //
    // Set the user event - wakes up the mainline code doing this.
    //
    
    KeSetEvent(Irp->UserEvent, 0, FALSE);
    
    
    //
    // Free the IRP now that we are done with it.
    //
    
    IoFreeIrp(Irp);
    
    //
    // We return STATUS_MORE_PROCESSING_REQUIRED because this "magic" return value
    // tells the I/O Manager that additional processing will be done by this driver
    // to the IRP - in fact, it might (as it is in this case) already BE done - and
    // the IRP cannot be completed.
    //
    
    return STATUS_MORE_PROCESSING_REQUIRED;
}

static VOID KfcRead(PFILE_OBJECT FileObject,
                    PLARGE_INTEGER Offset,
                    ULONG Length,
                    PMDL Mdl,
                    PIO_STATUS_BLOCK IoStatusBlock)
{
    PIRP irp;
    KEVENT event;
    PIO_STACK_LOCATION ioStackLocation;
    PDEVICE_OBJECT fsdDevice = IoGetRelatedDeviceObject(FileObject);
    
    //
    // Set up the event we'll use.
    //
    
    KeInitializeEvent(&event, SynchronizationEvent, FALSE);
    
    
    //
    // Allocate and build the IRP we'll be sending to the FSD.
    //
    
    irp = IoAllocateIrp(fsdDevice->StackSize, FALSE);
    
    if (!irp) {
        
        //
        // Allocation failed, presumably due to memory allocation failure.
        //
        
        IoStatusBlock->Status = STATUS_INSUFFICIENT_RESOURCES;

        IoStatusBlock->Information = 0;
        
    }
    
    irp->MdlAddress = Mdl;
    
    irp->UserEvent = &event;
    
    irp->UserIosb = IoStatusBlock;
    
    irp->Tail.Overlay.Thread = PsGetCurrentThread();
    
    irp->Tail.Overlay.OriginalFileObject= FileObject;
    
    irp->RequestorMode = KernelMode;
    
    
    //
    // Indicate that this is a READ operation.
    //
    
    irp->Flags = IRP_READ_OPERATION;
    
    
    //
    // Set up the next I/O stack location.  These are the parameters
    // that will be passed to the underlying driver.
    //
    
    ioStackLocation = IoGetNextIrpStackLocation(irp);
    
    ioStackLocation->MajorFunction = IRP_MJ_READ;
    
    ioStackLocation->MinorFunction = 0;
    
    ioStackLocation->DeviceObject = fsdDevice;
    
    ioStackLocation->FileObject = FileObject;
    
    
    //
    // We use a completion routine to keep the I/O Manager from doing
    // "cleanup" on our IRP - like freeing our MDL.
    //
    
    IoSetCompletionRoutine(irp, KfcIoCompletion, 0, TRUE, TRUE, TRUE);
    
    ioStackLocation->Parameters.Read.Length = Length;
    
    ioStackLocation->Parameters.Read.ByteOffset = *Offset;
    
    
    //
    // Send it on.  Ignore the return code.
    //
    
    (void) IoCallDriver(fsdDevice, irp);
    
    
    //
    // Wait for the I/O to complete.
    //
    
    KeWaitForSingleObject(&event, Executive, KernelMode, TRUE, 0);
    
    
    //
    // Done.  Return results are in the io status block.
    //
    
    return;
}

//
// KfcSetFileAllocation
//
//  This routine sets a file's ALLOCATION size to the specified value.
//  Note that this DOES NOT extend the file's EOF.
//
// Inputs:
//  FileObject - the file on which to set the allocation size
//  AllocationSize - the new allocation size
//
// Ouputs:
//  IoStatusBlock - the results of this operation
//
// Returns:
//  None.
//
// Notes:
//  None.


static VOID KfcSetFileAllocation(PFILE_OBJECT FileObject,
                                 PLARGE_INTEGER AllocationSize,
                                 PIO_STATUS_BLOCK IoStatusBlock)
{
    PIRP irp;
    PDEVICE_OBJECT fsdDevice = IoGetRelatedDeviceObject(FileObject);
    KEVENT event;
    PIO_STACK_LOCATION ioStackLocation;
    
    //
    // Allocate an irp for this request.  This could also come from a 
    // private pool, for instance.
    //
    
    irp = IoAllocateIrp(fsdDevice->StackSize, FALSE);
    
    if (!irp) {
        //
        // Failure!
        //
        
        return;
    }
    
    irp->AssociatedIrp.SystemBuffer = AllocationSize;
    
    irp->UserEvent = &event;
    
    irp->UserIosb = IoStatusBlock;
    
    irp->Tail.Overlay.Thread = PsGetCurrentThread();
    
    irp->Tail.Overlay.OriginalFileObject = FileObject;
    
    irp->RequestorMode = KernelMode;


    //
    // Initialize the event
    //

    KeInitializeEvent(&event, SynchronizationEvent, FALSE);


    //
    // Set up the I/O stack location.
    //

    ioStackLocation = IoGetNextIrpStackLocation(irp);

    ioStackLocation->MajorFunction = IRP_MJ_SET_INFORMATION;

    ioStackLocation->DeviceObject = fsdDevice;

    ioStackLocation->FileObject = FileObject;

    ioStackLocation->Parameters.SetFile.Length = sizeof(LARGE_INTEGER);

    ioStackLocation->Parameters.SetFile.FileInformationClass = FileAllocationInformation;

    ioStackLocation->Parameters.SetFile.FileObject = 0; // not used for allocation
    
    ioStackLocation->Parameters.SetFile.AdvanceOnly = FALSE;

    //
    // Set the completion routine.
    //

    IoSetCompletionRoutine(irp, KfcIoCompletion, 0, TRUE, TRUE, TRUE);

    //
    // Send it to the FSD
    //

    (void) IoCallDriver(fsdDevice, irp);

    //
    // Wait for the I/O
    //

    KeWaitForSingleObject(&event, Executive, KernelMode, TRUE, 0);

    //
    // Done!
    //

    return;
}




static VOID KfcWrite(PFILE_OBJECT FileObject,
                     PLARGE_INTEGER Offset,
                     ULONG Length,
                     PMDL Mdl,
                     PIO_STATUS_BLOCK IoStatusBlock)
{
    PIRP irp;
    KEVENT event;
    PIO_STACK_LOCATION ioStackLocation;
    PDEVICE_OBJECT fsdDevice = IoGetRelatedDeviceObject(FileObject);
    
    //
    // Set up the event we'll use.
    //
    
    KeInitializeEvent(&event, SynchronizationEvent, FALSE);
    
    
    //
    // Allocate and build the IRP we'll be sending to the FSD.
    //
    
    irp = IoAllocateIrp(fsdDevice->StackSize, FALSE);
    
    if (!irp) {
        
        //
        // Allocation failed, presumably due to memory allocation failure.
        //
        
        IoStatusBlock->Status = STATUS_INSUFFICIENT_RESOURCES;
        
        IoStatusBlock->Information = 0;
        
    }
    
    irp->MdlAddress = Mdl;
    
    irp->UserEvent = &event;
    
    irp->UserIosb = IoStatusBlock;
    
    irp->Tail.Overlay.Thread = PsGetCurrentThread();
    
    irp->Tail.Overlay.OriginalFileObject= FileObject;
    
    irp->RequestorMode = KernelMode;
    
    
    //
    // Indicate that this is a WRITE operation.
    //
    
    irp->Flags = IRP_WRITE_OPERATION;
    
    
    //
    // Set up the next I/O stack location.  These are the parameters
    // that will be passed to the underlying driver.
    //
    
    ioStackLocation = IoGetNextIrpStackLocation(irp);
    
    ioStackLocation->MajorFunction = IRP_MJ_WRITE;
    
    ioStackLocation->MinorFunction = 0;
    
    ioStackLocation->DeviceObject = fsdDevice;
    
    ioStackLocation->FileObject = FileObject;
    
    
    //
    // We use a completion routine to keep the I/O Manager from doing
    // "cleanup" on our IRP - like freeing our MDL.
    //
    
    IoSetCompletionRoutine(irp, KfcIoCompletion, 0, TRUE, TRUE, TRUE);
    
    ioStackLocation->Parameters.Write.Length = Length;
    
    ioStackLocation->Parameters.Write.ByteOffset = *Offset;
    
    
    //
    // Send it on.  Ignore the return code.
    //
    
    (void) IoCallDriver(fsdDevice, irp);
    
    
    //
    // Wait for the I/O to complete.
    //
    
    KeWaitForSingleObject(&event, Executive, KernelMode, TRUE, 0);
    
    
    //
    // Done.  Return results are in the io status block.
    //
    
    return;

}

⌨️ 快捷键说明

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