Example #1
0
/**
 * Create a filedisk PDO filled with the given disk parameters.
 *
 * @v MediaType                 The media type for the filedisk.
 * @ret WV_SP_FILEDISK_T        Points to the new filedisk, or NULL.
 *
 * Returns NULL if the PDO cannot be created.
 */
WV_SP_FILEDISK_T STDCALL WvFilediskCreatePdo(
    IN WVL_E_DISK_MEDIA_TYPE MediaType
  ) {
    NTSTATUS status;
    WV_SP_FILEDISK_T filedisk;
    PDEVICE_OBJECT pdo;
  
    DBG("Creating filedisk PDO...\n");

    /* Create the disk PDO. */
    status = WvlDiskCreatePdo(
        WvDriverObj,
        sizeof *filedisk,
        MediaType,
        &pdo
      );
    if (!NT_SUCCESS(status)) {
        WvlError("WvlDiskCreatePdo", status);
        goto err_pdo;
      }

    /* Initialize. */
    filedisk = pdo->DeviceExtension;
    RtlZeroMemory(filedisk, sizeof *filedisk);
    WvlDiskInit(filedisk->disk);
    WvDevInit(filedisk->Dev);
    filedisk->Dev->Ops.Free = WvFilediskFree_;
    filedisk->Dev->ext = filedisk->disk;
    filedisk->disk->disk_ops.Io = WvFilediskIo_;
    filedisk->disk->disk_ops.UnitNum = WvFilediskUnitNum_;
    filedisk->disk->disk_ops.PnpQueryId = WvFilediskPnpQueryId_;
    filedisk->disk->disk_ops.PnpQueryDevText = WvDiskPnpQueryDevText;
    filedisk->disk->ext = filedisk;
    filedisk->disk->DriverObj = WvDriverObj;
    filedisk->disk->DenyPageFile = TRUE;
    InitializeListHead(filedisk->Irps);
    KeInitializeSpinLock(filedisk->IrpsLock);

    /* Start the thread. */
    filedisk->Thread->Main.Func = WvFilediskThread_;
    status = WvlThreadStart(filedisk->Thread);
    if (!NT_SUCCESS(status)) {
        DBG("Couldn't create thread!\n");
        goto err_thread;
      }

    /* Set associations for the PDO, device, disk. */
    WvDevForDevObj(pdo, filedisk->Dev);
    WvDevSetIrpHandler(pdo, WvFilediskIrpDispatch);
    filedisk->Dev->Self = pdo;

    /* Some device parameters. */
    pdo->Flags |= DO_DIRECT_IO;         /* FIXME? */
    pdo->Flags |= DO_POWER_INRUSH;      /* FIXME? */

    DBG("New PDO: %p\n", pdo);
    return filedisk;

    WvlThreadSendStopAndWait(filedisk->Thread);
    err_thread:

    IoDeleteDevice(pdo);
    err_pdo:

    return NULL;
  }
Example #2
0
/* 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;
  }