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

📄 rawfs.c

📁 ReactOS是一些高手根据Windows XP的内核编写出的类XP。内核实现机理和API函数调用几乎相同。甚至可以兼容XP的程序。喜欢研究系统内核的人可以看一看。
💻 C
📖 第 1 页 / 共 3 页
字号:
            RtlExtendedIntegerMultiply(DiskGeometry.Cylinders,
                                       DiskGeometry.TracksPerCylinder *
                                       DiskGeometry.SectorsPerTrack);
    }

    /* Set available units */
    Buffer->AvailableAllocationUnits = Buffer->TotalAllocationUnits;

    /* Return length and success */
    *Length -= sizeof(FILE_FS_SIZE_INFORMATION);
    return STATUS_SUCCESS;
}

NTSTATUS
NTAPI
RawQueryFsDeviceInfo(IN PVCB Vcb,
                     IN PFILE_FS_DEVICE_INFORMATION Buffer,
                     IN OUT PULONG Length)
{
    PAGED_CODE();

    /* Validate buffer */
    if (*Length < sizeof(FILE_FS_DEVICE_INFORMATION))
    {
        /* Fail */
        return STATUS_BUFFER_OVERFLOW;
    }

    /* Clear buffer and write information */
    RtlZeroMemory(Buffer, sizeof(FILE_FS_DEVICE_INFORMATION));
    Buffer->DeviceType = FILE_DEVICE_DISK;
    Buffer->Characteristics = Vcb->TargetDeviceObject->Characteristics;

    /* Return length and success */
    *Length -= sizeof(FILE_FS_DEVICE_INFORMATION);
    return STATUS_SUCCESS;
}

NTSTATUS
NTAPI
RawQueryFsAttributeInfo(IN PVCB Vcb,
                        IN PFILE_FS_ATTRIBUTE_INFORMATION Buffer,
                        IN OUT PULONG Length)
{
    const WCHAR szRawFSName[] = L"RAW";
    ULONG ReturnLength;
    PAGED_CODE();

    /* Check if the buffer is large enough for our name ("RAW") */
    ReturnLength = FIELD_OFFSET(FILE_FS_ATTRIBUTE_INFORMATION,
                                FileSystemName[sizeof(szRawFSName) / sizeof(szRawFSName[0])]);
    if (*Length < ReturnLength) return STATUS_BUFFER_OVERFLOW;

    /* Output the data */
    Buffer->FileSystemAttributes = 0;
    Buffer->MaximumComponentNameLength = 0;
    Buffer->FileSystemNameLength = 6;
    RtlCopyMemory(&Buffer->FileSystemName[0], szRawFSName, sizeof(szRawFSName));

    /* Return length and success */
    *Length -= ReturnLength;
    return STATUS_SUCCESS;
}

NTSTATUS
NTAPI
RawQueryVolumeInformation(IN PVCB Vcb,
                          IN PIRP Irp,
                          IN PIO_STACK_LOCATION IoStackLocation)
{
    NTSTATUS Status;
    ULONG Length;
    PVOID Buffer;
    PAGED_CODE();

    /* Get IRP Data */
    Length = IoStackLocation->Parameters.QueryVolume.Length;
    Buffer = Irp->AssociatedIrp.SystemBuffer;

    /* Check the kind of request */
    switch (IoStackLocation->Parameters.QueryVolume.FsInformationClass)
    {
        /* Volume information request */
        case FileFsVolumeInformation:

            Status = RawQueryFsVolumeInfo(Vcb, Buffer, &Length);
            break;

        /* File system size invormation */
        case FileFsSizeInformation:

            Status = RawQueryFsSizeInfo(Vcb, Buffer, &Length);
            break;

        /* Device information */
        case FileFsDeviceInformation:

            Status = RawQueryFsDeviceInfo(Vcb, Buffer, &Length);
            break;

        /* Attribute information */
        case FileFsAttributeInformation:

            Status = RawQueryFsAttributeInfo(Vcb, Buffer, &Length);
            break;

        /* Invalid request */
        default:

            /* Fail it */
            Status = STATUS_INVALID_PARAMETER;
            break;
    }

    /* Set status and complete the request */
    Irp->IoStatus.Information = IoStackLocation->
                                Parameters.QueryVolume.Length - Length;
    Irp->IoStatus.Status = Status;
    IoCompleteRequest(Irp, IO_DISK_INCREMENT);
    return Status;
}

NTSTATUS
NTAPI
RawCleanup(IN PVCB Vcb,
           IN PIRP Irp,
           IN PIO_STACK_LOCATION IoStackLocation)
{
    NTSTATUS Status;
    PAGED_CODE();

    /* Make sure we can clean up */
    Status = KeWaitForSingleObject(&Vcb->Mutex,
                                   Executive,
                                   KernelMode,
                                   FALSE,
                                   NULL);
    ASSERT(NT_SUCCESS(Status));

    /* Remove shared access and complete the request */
    IoRemoveShareAccess(IoStackLocation->FileObject, &Vcb->ShareAccess);
    KeReleaseMutex(&Vcb->Mutex, FALSE);
    Irp->IoStatus.Status = STATUS_SUCCESS;
    IoCompleteRequest(Irp, IO_DISK_INCREMENT);
    return STATUS_SUCCESS;
}

NTSTATUS
NTAPI
RawDispatch(IN PVOLUME_DEVICE_OBJECT DeviceObject,
            IN PIRP Irp)
{
    NTSTATUS Status = STATUS_INVALID_DEVICE_REQUEST;
    PIO_STACK_LOCATION IoStackLocation;
    PVCB Vcb;
    PAGED_CODE();

    /* Get the stack location */
    IoStackLocation = IoGetCurrentIrpStackLocation(Irp);

    /* Differentiate between Volume DO and FS DO */
    if ((((PDEVICE_OBJECT)DeviceObject)->Size == sizeof(DEVICE_OBJECT)) &&
        !((IoStackLocation->MajorFunction == IRP_MJ_FILE_SYSTEM_CONTROL) &&
          (IoStackLocation->MinorFunction == IRP_MN_MOUNT_VOLUME)))
    {
        /* This is an FS DO. Stub out the common calls */
        if ((IoStackLocation->MajorFunction == IRP_MJ_CREATE) ||
            (IoStackLocation->MajorFunction == IRP_MJ_CLEANUP) ||
            (IoStackLocation->MajorFunction == IRP_MJ_CLOSE))
        {
            /* Return success for them */
            Status = STATUS_SUCCESS;
        }
        else
        {
            /* Anything else, we don't support */
            Status = STATUS_INVALID_DEVICE_REQUEST;
        }

        /* Complete the request */
        Irp->IoStatus.Status = Status;
        IoCompleteRequest(Irp, IO_DISK_INCREMENT);
        return Status;
    }

    /* Otherwise, get our VCB and start handling the IRP */
    FsRtlEnterFileSystem();
    Vcb = &DeviceObject->Vcb;

    /* Check what kind of IRP this is */
    switch (IoStackLocation->MajorFunction)
    {
        /* Cleanup request */
        case IRP_MJ_CLEANUP:

            Status = RawCleanup(Vcb, Irp, IoStackLocation);
            break;

        /* Close request */
        case IRP_MJ_CLOSE:

            Status = RawClose(Vcb, Irp, IoStackLocation);
            break;

        /* Create request */
        case IRP_MJ_CREATE:

            Status = RawCreate(Vcb, Irp, IoStackLocation);
            break;

        /* FSCTL request */
        case IRP_MJ_FILE_SYSTEM_CONTROL:

            Status = RawFileSystemControl(Vcb, Irp, IoStackLocation);
            break;

        /* R/W or IOCTL request */
        case IRP_MJ_READ:
        case IRP_MJ_WRITE:
        case IRP_MJ_DEVICE_CONTROL:

            Status = RawReadWriteDeviceControl(Vcb, Irp, IoStackLocation);
            break;

        /* Information query request */
        case IRP_MJ_QUERY_INFORMATION:

            Status = RawQueryInformation(Vcb, Irp, IoStackLocation);
            break;

        /* Information set request */
        case IRP_MJ_SET_INFORMATION:

            Status = RawSetInformation(Vcb, Irp, IoStackLocation);
            break;

        /* Volume information request */
        case IRP_MJ_QUERY_VOLUME_INFORMATION:

            Status = RawQueryVolumeInformation(Vcb, Irp, IoStackLocation);
            break;

        /* Unexpected request */
        default:

            /* Anything else is pretty bad */
            KeBugCheck(FILE_SYSTEM);
    }

    /* Return the status */
    FsRtlExitFileSystem();
    return Status;
}

NTSTATUS
NTAPI
RawShutdown(IN PDEVICE_OBJECT DeviceObject,
            IN PIRP Irp)
{
    /* Unregister file systems */
#if 0 // FIXME: This freezes ROS at shutdown. PnP Problem?
    IoUnregisterFileSystem(RawDiskDeviceObject);
    IoUnregisterFileSystem(RawCdromDeviceObject);
    IoUnregisterFileSystem(RawTapeDeviceObject);

    /* Delete the devices */
    IoDeleteDevice(RawDiskDeviceObject);
    IoDeleteDevice(RawCdromDeviceObject);
    IoDeleteDevice(RawTapeDeviceObject);
#endif

    /* Complete the request */
    Irp->IoStatus.Status = STATUS_SUCCESS;
    IoCompleteRequest(Irp, IO_DISK_INCREMENT);
    return STATUS_SUCCESS;
}

VOID
NTAPI
RawUnload(IN PDRIVER_OBJECT DriverObject)
{
#if 0 // FIXME: DriverUnload is never called
    /* Dereference device objects */
    ObDereferenceObject(RawDiskDeviceObject);
    ObDereferenceObject(RawCdromDeviceObject);
    ObDereferenceObject(RawTapeDeviceObject);
#endif
}

NTSTATUS
NTAPI
RawFsDriverEntry(IN PDRIVER_OBJECT DriverObject,
                 IN PUNICODE_STRING RegistryPath)
{
    UNICODE_STRING DeviceName;
    NTSTATUS Status;

    /* Create the raw disk device */
    RtlInitUnicodeString(&DeviceName, L"\\Device\\RawDisk");
    Status = IoCreateDevice(DriverObject,
                            0,
                            NULL,
                            FILE_DEVICE_DISK_FILE_SYSTEM,
                            0,
                            FALSE,
                            &RawDiskDeviceObject);
    if (!NT_SUCCESS(Status)) return Status;

    /* Create the raw CDROM device */
    RtlInitUnicodeString(&DeviceName, L"\\Device\\RawCdRom");
    Status = IoCreateDevice(DriverObject,
                            0,
                            NULL,
                            FILE_DEVICE_CD_ROM_FILE_SYSTEM,
                            0,
                            FALSE,
                            &RawCdromDeviceObject);
    if (!NT_SUCCESS(Status)) return Status;

    /* Create the raw tape device */
    RtlInitUnicodeString(&DeviceName, L"\\Device\\RawTape");
    Status = IoCreateDevice(DriverObject,
                            0,
                            NULL,
                            FILE_DEVICE_TAPE_FILE_SYSTEM,
                            0,
                            FALSE,
                            &RawTapeDeviceObject);
    if (!NT_SUCCESS(Status)) return Status;

    /* Set Direct I/O for all devices */
    RawDiskDeviceObject->Flags |= DO_DIRECT_IO;
    RawCdromDeviceObject->Flags |= DO_DIRECT_IO;
    RawTapeDeviceObject->Flags |= DO_DIRECT_IO;

    /* Set generic stubs */
    DriverObject->MajorFunction[IRP_MJ_CREATE] =
    DriverObject->MajorFunction[IRP_MJ_CLEANUP] =
    DriverObject->MajorFunction[IRP_MJ_CLOSE] =
    DriverObject->MajorFunction[IRP_MJ_READ] =
    DriverObject->MajorFunction[IRP_MJ_WRITE] =
    DriverObject->MajorFunction[IRP_MJ_QUERY_INFORMATION] =
    DriverObject->MajorFunction[IRP_MJ_SET_INFORMATION] =
    DriverObject->MajorFunction[IRP_MJ_QUERY_VOLUME_INFORMATION] =
    DriverObject->MajorFunction[IRP_MJ_CLEANUP] =
    DriverObject->MajorFunction[IRP_MJ_FILE_SYSTEM_CONTROL] =
    DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = (PDRIVER_DISPATCH)RawDispatch;

    /* Shutdown and unload */
    DriverObject->MajorFunction[IRP_MJ_SHUTDOWN] = RawShutdown;
    DriverObject->DriverUnload = RawUnload;

    /* Register the file systems */
    IoRegisterFileSystem(RawDiskDeviceObject);
    IoRegisterFileSystem(RawCdromDeviceObject);
    IoRegisterFileSystem(RawTapeDeviceObject);

#if 0 // FIXME: DriverUnload is never called
    /* Reference device objects */
    ObReferenceObject(RawDiskDeviceObject);
    ObReferenceObject(RawCdromDeviceObject);
    ObReferenceObject(RawTapeDeviceObject);
#endif
    return STATUS_SUCCESS;
}

/* EOF */

⌨️ 快捷键说明

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