/** * Add a child node to the AoE bus. * * @v AoeDisk Points to the child AoE disk to add. * @ret TRUE for success, FALSE for failure. */ BOOLEAN STDCALL AoeBusAddDev( IN OUT AOE_SP_DISK AoeDisk ) { DBG("Entry\n"); if (!AoeBusMain.Fdo || !AoeDisk) { DBG("No bus or no device!\n"); return FALSE; } WvlBusInitNode(AoeDisk->BusNode, AoeDisk->Pdo); /* Associate the parent bus. */ AoeDisk->disk->ParentBus = AoeBusMain.Fdo; AoeDisk->Pdo->Flags &= ~DO_DEVICE_INITIALIZING; /* Add the new PDO device to the bus' list of children. */ WvlBusAddNode(&AoeBusMain, AoeDisk->BusNode); DBG("Exit\n"); return TRUE; }
/** 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; }
/* Produce a dummy PDO node on the main bus. Internal */ static NTSTATUS STDCALL WvDummyAdd_( IN WV_SP_DUMMY_IDS DummyIds, IN PDEVICE_OBJECT * Pdo ) { NTSTATUS status; PDEVICE_OBJECT pdo = NULL; WV_SP_DEV_T dev; WV_SP_DUMMY_IDS new_dummy_ids; status = IoCreateDevice( WvDriverObj, sizeof (WV_S_DEV_EXT), NULL, DummyIds->DevType, DummyIds->DevCharacteristics, FALSE, &pdo ); if (!NT_SUCCESS(status) || !pdo) { DBG("Couldn't create dummy device.\n"); status = STATUS_INSUFFICIENT_RESOURCES; goto err_create_pdo; } dev = wv_malloc(sizeof *dev); if (!dev) { DBG("Couldn't allocate dummy device.\n"); status = STATUS_INSUFFICIENT_RESOURCES; goto err_dev; } new_dummy_ids = wv_malloc(DummyIds->Len); if (!new_dummy_ids) { DBG("Couldn't allocate dummy IDs.\n"); status = STATUS_INSUFFICIENT_RESOURCES; goto err_dummy_ids; } /* Copy the IDs' offsets and lengths. */ RtlCopyMemory(new_dummy_ids, DummyIds, DummyIds->Len); /* Ok! */ WvDevInit(dev); dev->ext = new_dummy_ids; /* TODO: Implement a dummy free. Leaking. */ dev->Self = pdo; /* Optionally fill the caller's PDO pointer. */ if (Pdo) *Pdo = pdo; WvDevForDevObj(pdo, dev); WvDevSetIrpHandler(pdo, WvDummyIrpDispatch); WvlBusInitNode(&dev->BusNode, pdo); /* Associate the parent bus. */ dev->Parent = WvBus.Fdo; /* Add the new PDO device to the bus' list of children. */ WvlBusAddNode(&WvBus, &dev->BusNode); pdo->Flags &= ~DO_DEVICE_INITIALIZING; return STATUS_SUCCESS; wv_free(new_dummy_ids); err_dummy_ids: wv_free(dev); err_dev: IoDeleteDevice(pdo); err_create_pdo: return status; }