Exemplo n.º 1
0
/* Attach a file as a disk, based on an IRP. */
NTSTATUS STDCALL WvFilediskAttach(IN PIRP irp) {
    PCHAR buf = irp->AssociatedIrp.SystemBuffer;
    WV_SP_MOUNT_DISK params = (WV_SP_MOUNT_DISK) buf;
    WVL_E_DISK_MEDIA_TYPE media_type;
    UINT32 sector_size;
    WV_SP_FILEDISK_T filedisk;
    NTSTATUS status;
    ANSI_STRING ansi_path;

    switch (params->type) {
        case 'f':
          media_type = WvlDiskMediaTypeFloppy;
          sector_size = 512;
          break;

        case 'c':
          media_type = WvlDiskMediaTypeOptical;
          sector_size = 2048;
          break;

        default:
          media_type = WvlDiskMediaTypeHard;
          sector_size = 512;
          break;
      }
    DBG("Media type: %d\n", media_type);

    /* Create the filedisk PDO. */
    filedisk = WvFilediskCreatePdo(media_type);
    if (filedisk == NULL) {
        DBG("Could not create file-backed disk!\n");
        status = STATUS_INSUFFICIENT_RESOURCES;
        goto err_pdo;
      }

    /* Set filedisk parameters. */
    filedisk->disk->Media = media_type;
    filedisk->disk->SectorSize = sector_size;
    filedisk->disk->Cylinders = params->cylinders;
    filedisk->disk->Heads = params->heads;
    filedisk->disk->Sectors = params->sectors;

    /* Populate the file path into a counted ANSI string. */
    RtlInitAnsiString(&ansi_path, buf + sizeof *params);

    /* Attempt to open the file from within the filedisk's thread. */
    status = WvFilediskOpen_(filedisk, &ansi_path);
    if (!NT_SUCCESS(status))
      goto err_file_open;

    /* Add the filedisk to the bus. */
    filedisk->disk->ParentBus = WvBus.Fdo;
    if (!WvBusAddDev(filedisk->Dev)) {
        status = STATUS_UNSUCCESSFUL;
        goto err_add_child;
      }

    return STATUS_SUCCESS;

    WvBusRemoveDev(filedisk->Dev);
    err_add_child:

    /* Any open file handle will be closed upon thread exit. */
    err_file_open:

    WvFilediskFree_(filedisk->Dev);
    err_pdo:

    return status;
  }
Exemplo n.º 2
0
/** Create a GRUB4DOS sector-mapped disk and sets its parent bus */
DEVICE_OBJECT * WvFilediskCreateG4dDisk(
    SP_WV_G4D_DRIVE_MAPPING slot,
    DEVICE_OBJECT * bus_dev_obj,
    WVL_E_DISK_MEDIA_TYPE media_type,
    UINT32 sector_size
  ) {
    WV_SP_FILEDISK_T filedisk_ptr;
    #ifdef TODO_RESTORE_FILE_MAPPED_G4D_DISKS
    /* Matches disks to files. */
    WV_S_FILEDISK_GRUB4DOS_DRIVE_FILE_SET sets[8] = {0};
    #endif

    /*
     * Create the threaded, file-backed disk.  Hook the
     * read/write routine so we can access the backing disk
     * late(r) during the boot process.
     */
    filedisk_ptr = WvFilediskCreatePdo(media_type);
    if (!filedisk_ptr) {
        DBG("Could not create GRUB4DOS sector-mapped disk!\n");
        return NULL;
      }
    DBG("Sector-mapped disk is type: %d\n", media_type);

    /* Other parameters we know. */
    filedisk_ptr->disk->Media = media_type;
    filedisk_ptr->disk->SectorSize = sector_size;

    #ifdef TODO_RESTORE_FILE_MAPPED_G4D_DISKS
    /* Find an associated filename, if one exists. */
    {   int j = 8;

        while (j--) {
            if (
                (sets[j].int13_drive_num == slot->SourceDrive) &&
                (sets[j].filepath != NULL)
              )
              WvFilediskHotSwap(filedisk_ptr, sets[j].filepath);
          }
      } /* j scope. */
    #endif

    /* Note the offset of the disk image from the backing disk's start. */
    filedisk_ptr->offset.QuadPart =
      slot->SectorStart * (slot->DestODD ? 2048 : 512);
    /*
     * Size and geometry.  Please note that since we require a .VHD
     * footer, we exclude this from the LBA disk size by truncating
     * a 512-byte sector for HDD images, or a 2048-byte sector for .ISO.
     */
    {   ULONGLONG total_size =
          slot->SectorCount * (slot->DestODD ? 2048 : 512);

        filedisk_ptr->disk->LBADiskSize =
          (total_size - filedisk_ptr->disk->SectorSize) /
          filedisk_ptr->disk->SectorSize;
      } /* total_size scope. */
    filedisk_ptr->disk->Heads = slot->MaxHead + 1;
    filedisk_ptr->disk->Sectors = slot->DestMaxSector;
    filedisk_ptr->disk->Cylinders = (
        filedisk_ptr->disk->LBADiskSize /
        (filedisk_ptr->disk->Heads * filedisk_ptr->disk->Sectors)
      );
    /*
     * Set a filedisk "hash" and mark the drive as a boot-drive.
     * The "hash" is 'G4DX', where X is the GRUB4DOS INT 13h
     * drive number.  Note that mutiple G4D INT 13h chains will
     * cause a "hash" collision!  Too bad for now.
     */
    filedisk_ptr->hash = 'G4DX';
    ((PUCHAR) &filedisk_ptr->hash)[0] = slot->SourceDrive;
    filedisk_ptr->Dev->Boot = TRUE;
    if (!WvFilediskG4dFindBackingDisk(filedisk_ptr)) {
        WvDevFree(filedisk_ptr->Dev);
        return NULL;
      }

    /* Add the filedisk to the bus. */
    filedisk_ptr->disk->ParentBus = bus_dev_obj;
    WvlBusInitNode(&filedisk_ptr->Dev->BusNode, filedisk_ptr->Dev->Self);
    filedisk_ptr->Dev->BusNode.Linked = TRUE;
    filedisk_ptr->Dev->Self->Flags &= ~DO_DEVICE_INITIALIZING;

    return filedisk_ptr->Dev->Self;
  }