VirtualBox

Changeset 11922 in vbox for trunk/src


Ignore:
Timestamp:
Sep 1, 2008 2:33:41 PM (16 years ago)
Author:
vboxsync
Message:

Windows additions: IRP creation must work in any thread context.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Additions/common/VBoxGuestLib/SysHlp.cpp

    r11606 r11922  
    227227}
    228228
     229#ifdef RT_OS_WINDOWS
     230static NTSTATUS vbglDriverIOCtlCompletion (IN PDEVICE_OBJECT DeviceObject,
     231                                           IN PIRP Irp,
     232                                           IN PVOID Context)
     233{
     234    Log(("VBGL completion %x\n", Irp));
     235
     236    KEVENT *pEvent = (KEVENT *)Context;
     237    KeSetEvent (pEvent, IO_NO_INCREMENT, FALSE);
     238
     239    return STATUS_MORE_PROCESSING_REQUIRED;
     240}
     241#endif
     242
    229243int vbglDriverIOCtl (VBGLDRIVER *pDriver, uint32_t u32Function, void *pvData, uint32_t cbData)
    230244{
     
    232246
    233247#ifdef RT_OS_WINDOWS
    234     IO_STATUS_BLOCK ioStatusBlock;
    235 
    236248    KEVENT Event;
     249
    237250    KeInitializeEvent (&Event, NotificationEvent, FALSE);
    238251
    239     PIRP irp = IoBuildDeviceIoControlRequest (u32Function,
    240                                               pDriver->pDeviceObject,
    241                                               pvData,
    242                                               cbData,
    243                                               pvData,
    244                                               cbData,
    245                                               FALSE, /* external */
    246                                               &Event,
    247                                               &ioStatusBlock);
     252    /* Have to use the IoAllocateIRP method because this code is generic and
     253     * must work in any thread context.
     254     * The IoBuildDeviceIoControlRequest, which was used here, does not work
     255     * when APCs are disabled, for example.
     256     */
     257    PIRP irp = IoAllocateIrp (pDriver->pDeviceObject->StackSize, FALSE);
     258
     259    Log(("vbglDriverIOCtl: irp %p, IRQL = %d\n", irp, KeGetCurrentIrql()));
     260
    248261    if (irp == NULL)
    249262    {
    250         Log(("vbglDriverIOCtl: IoBuildDeviceIoControlRequest failed!\n"));
     263        Log(("vbglDriverIOCtl: IRP allocation failed!\n"));
    251264        return VERR_NO_MEMORY;
    252265    }
    253266
     267    /*
     268     * Setup the IRP_MJ_DEVICE_CONTROL IRP.
     269     */
     270
     271    PIO_STACK_LOCATION nextStack = IoGetNextIrpStackLocation (irp);
     272
     273    nextStack->MajorFunction = IRP_MJ_DEVICE_CONTROL;
     274    nextStack->MinorFunction = 0;
     275    nextStack->DeviceObject = pDriver->pDeviceObject;
     276    nextStack->Parameters.DeviceIoControl.OutputBufferLength = cbData;
     277    nextStack->Parameters.DeviceIoControl.InputBufferLength = cbData;
     278    nextStack->Parameters.DeviceIoControl.IoControlCode = u32Function;
     279    nextStack->Parameters.DeviceIoControl.Type3InputBuffer = pvData;
     280
     281    irp->AssociatedIrp.SystemBuffer = pvData; /* Output buffer. */
     282    irp->MdlAddress = NULL;   
     283
     284    /* A completion routine is required to signal the Event. */
     285    IoSetCompletionRoutine (irp, vbglDriverIOCtlCompletion, &Event, TRUE, TRUE, TRUE);
     286
    254287    NTSTATUS rc = IoCallDriver (pDriver->pDeviceObject, irp);
    255288
    256     if (rc == STATUS_PENDING)
    257     {
    258         Log(("vbglDriverIOCtl: STATUS_PENDING\n"));
    259         rc = KeWaitForSingleObject(&Event,
    260                                    Executive,
    261                                    KernelMode,
    262                                    FALSE,
    263                                    NULL);
    264 
    265         rc = ioStatusBlock.Status;
    266     }
    267 
    268     if (!NT_SUCCESS(rc))
    269         Log(("vbglDriverIOCtl: IoCallDriver failed with ntstatus=%x\n", rc));
     289    if (NT_SUCCESS (rc))
     290    {
     291        /* Wait the event to be signalled by the completion routine. */
     292        KeWaitForSingleObject (&Event,
     293                               Executive,
     294                               KernelMode,
     295                               FALSE,
     296                               NULL);
     297
     298        rc = irp->IoStatus.Status;
     299
     300        Log(("vbglDriverIOCtl: wait completed IRQL = %d\n", KeGetCurrentIrql()));
     301    }
     302
     303    IoFreeIrp (irp);
     304
     305    if (rc != STATUS_SUCCESS)
     306        Log(("vbglDriverIOCtl: ntstatus=%x\n", rc));
    270307
    271308    return NT_SUCCESS(rc)? VINF_SUCCESS: VERR_VBGL_IOCTL_FAILED;
Note: See TracChangeset for help on using the changeset viewer.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette