/* 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; }
/** 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; }