/**
 * Create (i.e. Open) file entry point.
 *
 * @param   pDevObj     Device object.
 * @param   pIrp        Request packet.
 */
NTSTATUS _stdcall VBoxDrvNtCreate(PDEVICE_OBJECT pDevObj, PIRP pIrp)
{
    Log(("VBoxDrvNtCreate: RequestorMode=%d\n", pIrp->RequestorMode));
    const bool          fUnrestricted = pDevObj == g_pDevObjSys;
    PIO_STACK_LOCATION  pStack = IoGetCurrentIrpStackLocation(pIrp);
    PFILE_OBJECT        pFileObj = pStack->FileObject;
    PSUPDRVDEVEXT       pDevExt = SUPDRVNT_GET_DEVEXT(pDevObj);

    /*
     * We are not remotely similar to a directory...
     * (But this is possible.)
     */
    if (pStack->Parameters.Create.Options & FILE_DIRECTORY_FILE)
    {
        pIrp->IoStatus.Status       = STATUS_NOT_A_DIRECTORY;
        pIrp->IoStatus.Information  = 0;
        IoCompleteRequest(pIrp, IO_NO_INCREMENT);
        return STATUS_NOT_A_DIRECTORY;
    }

    /*
     * Don't create a session for kernel clients, they'll close the handle
     * immediately and work with the file object via
     * VBoxDrvNtInternalDeviceControl.  The first request will there be one
     * to create a session.
     */
    NTSTATUS rcNt;
    if (pIrp->RequestorMode == KernelMode)
        rcNt = STATUS_SUCCESS;
    else
    {
        /*
         * Call common code for the rest.
         */
        pFileObj->FsContext = NULL;
        PSUPDRVSESSION pSession;
        int rc = supdrvCreateSession(pDevExt, true /*fUser*/, fUnrestricted, &pSession);
        if (!rc)
            pFileObj->FsContext = pSession;
        rcNt = pIrp->IoStatus.Status = VBoxDrvNtErr2NtStatus(rc);
    }

    pIrp->IoStatus.Information  = 0;
    IoCompleteRequest(pIrp, IO_NO_INCREMENT);

    return rcNt;
}
示例#2
0
RT_C_DECLS_END


/**
 * Driver entry point.
 *
 * @returns appropriate status code.
 * @param   pDrvObj     Pointer to driver object.
 * @param   pRegPath    Registry base path.
 */
ULONG _stdcall DriverEntry(PDRIVER_OBJECT pDrvObj, PUNICODE_STRING pRegPath)
{
    NTSTATUS    rc;

    /*
     * Create device.
     * (That means creating a device object and a symbolic link so the DOS
     * subsystems (OS/2, win32, ++) can access the device.)
     */
    UNICODE_STRING  DevName;
    RtlInitUnicodeString(&DevName, DEVICE_NAME_NT);
    PDEVICE_OBJECT  pDevObj;
    rc = IoCreateDevice(pDrvObj, sizeof(SUPDRVDEVEXT), &DevName, FILE_DEVICE_UNKNOWN, 0, FALSE, &pDevObj);
    if (NT_SUCCESS(rc))
    {
        UNICODE_STRING DosName;
        RtlInitUnicodeString(&DosName, DEVICE_NAME_DOS);
        rc = IoCreateSymbolicLink(&DosName, &DevName);
        if (NT_SUCCESS(rc))
        {
            int vrc = RTR0Init(0);
            if (RT_SUCCESS(vrc))
            {
                Log(("VBoxDrv::DriverEntry\n"));

                /*
                 * Initialize the device extension.
                 */
                PSUPDRVDEVEXT pDevExt = (PSUPDRVDEVEXT)pDevObj->DeviceExtension;
                memset(pDevExt, 0, sizeof(*pDevExt));

                vrc = supdrvInitDevExt(pDevExt, sizeof(SUPDRVSESSION));
                if (!vrc)
                {
                    /*
                     * Setup the driver entry points in pDrvObj.
                     */
                    pDrvObj->DriverUnload                                   = VBoxDrvNtUnload;
                    pDrvObj->MajorFunction[IRP_MJ_CREATE]                   = VBoxDrvNtCreate;
                    pDrvObj->MajorFunction[IRP_MJ_CLEANUP]                  = VBoxDrvNtCleanup;
                    pDrvObj->MajorFunction[IRP_MJ_CLOSE]                    = VBoxDrvNtClose;
                    pDrvObj->MajorFunction[IRP_MJ_DEVICE_CONTROL]           = VBoxDrvNtDeviceControl;
                    pDrvObj->MajorFunction[IRP_MJ_INTERNAL_DEVICE_CONTROL]  = VBoxDrvNtInternalDeviceControl;
                    pDrvObj->MajorFunction[IRP_MJ_READ]                     = VBoxDrvNtNotSupportedStub;
                    pDrvObj->MajorFunction[IRP_MJ_WRITE]                    = VBoxDrvNtNotSupportedStub;

                    /* more? */

                    /* Register ourselves for power state changes. */
                    UNICODE_STRING      CallbackName;
                    OBJECT_ATTRIBUTES   Attr;

                    RtlInitUnicodeString(&CallbackName, L"\\Callback\\PowerState");
                    InitializeObjectAttributes(&Attr, &CallbackName, OBJ_CASE_INSENSITIVE, NULL, NULL);

                    rc = ExCreateCallback(&pDevExt->pObjPowerCallback, &Attr, TRUE, TRUE);
                    if (rc == STATUS_SUCCESS)
                        pDevExt->hPowerCallback = ExRegisterCallback(pDevExt->pObjPowerCallback, VBoxPowerDispatchCallback, pDevObj);

                    Log(("VBoxDrv::DriverEntry returning STATUS_SUCCESS\n"));
                    return STATUS_SUCCESS;
                }

                Log(("supdrvInitDevExit failed with vrc=%d!\n", vrc));
                rc = VBoxDrvNtErr2NtStatus(vrc);

                IoDeleteSymbolicLink(&DosName);
                RTR0Term();
            }
            else
            {
                Log(("RTR0Init failed with vrc=%d!\n", vrc));
                rc = VBoxDrvNtErr2NtStatus(vrc);
            }
        }
        else
            Log(("IoCreateSymbolicLink failed with rc=%#x!\n", rc));

        IoDeleteDevice(pDevObj);
    }
    else
        Log(("IoCreateDevice failed with rc=%#x!\n", rc));

    if (NT_SUCCESS(rc))
        rc = STATUS_INVALID_PARAMETER;
    Log(("VBoxDrv::DriverEntry returning %#x\n", rc));
    return rc;
}
/**
 * Driver entry point.
 *
 * @returns appropriate status code.
 * @param   pDrvObj     Pointer to driver object.
 * @param   pRegPath    Registry base path.
 */
ULONG _stdcall DriverEntry(PDRIVER_OBJECT pDrvObj, PUNICODE_STRING pRegPath)
{
    /*
     * Create device.
     * (That means creating a device object and a symbolic link so the DOS
     * subsystems (OS/2, win32, ++) can access the device.)
     */
    NTSTATUS rcNt = vboxdrvNtCreateDevices(pDrvObj);
    if (NT_SUCCESS(rcNt))
    {
        int vrc = RTR0Init(0);
        if (RT_SUCCESS(vrc))
        {
            Log(("VBoxDrv::DriverEntry\n"));

            /*
             * Initialize the device extension.
             */
            PSUPDRVDEVEXT pDevExt = (PSUPDRVDEVEXT)g_pDevObjSys->DeviceExtension;
            memset(pDevExt, 0, sizeof(*pDevExt));

            vrc = supdrvInitDevExt(pDevExt, sizeof(SUPDRVSESSION));
            if (!vrc)
            {
                /*
                 * Setup the driver entry points in pDrvObj.
                 */
                pDrvObj->DriverUnload                                   = VBoxDrvNtUnload;
                pDrvObj->MajorFunction[IRP_MJ_CREATE]                   = VBoxDrvNtCreate;
                pDrvObj->MajorFunction[IRP_MJ_CLEANUP]                  = VBoxDrvNtCleanup;
                pDrvObj->MajorFunction[IRP_MJ_CLOSE]                    = VBoxDrvNtClose;
                pDrvObj->MajorFunction[IRP_MJ_DEVICE_CONTROL]           = VBoxDrvNtDeviceControl;
                pDrvObj->MajorFunction[IRP_MJ_INTERNAL_DEVICE_CONTROL]  = VBoxDrvNtInternalDeviceControl;
                pDrvObj->MajorFunction[IRP_MJ_READ]                     = VBoxDrvNtNotSupportedStub;
                pDrvObj->MajorFunction[IRP_MJ_WRITE]                    = VBoxDrvNtNotSupportedStub;

                /* more? */

                /* Register ourselves for power state changes. */
                UNICODE_STRING      CallbackName;
                OBJECT_ATTRIBUTES   Attr;

                RtlInitUnicodeString(&CallbackName, L"\\Callback\\PowerState");
                InitializeObjectAttributes(&Attr, &CallbackName, OBJ_CASE_INSENSITIVE, NULL, NULL);

                rcNt = ExCreateCallback(&pDevExt->pObjPowerCallback, &Attr, TRUE, TRUE);
                if (rcNt == STATUS_SUCCESS)
                    pDevExt->hPowerCallback = ExRegisterCallback(pDevExt->pObjPowerCallback, VBoxPowerDispatchCallback,
                                                                 g_pDevObjSys);

                Log(("VBoxDrv::DriverEntry returning STATUS_SUCCESS\n"));
                return STATUS_SUCCESS;
            }

            Log(("supdrvInitDevExit failed with vrc=%d!\n", vrc));
            rcNt = VBoxDrvNtErr2NtStatus(vrc);

            RTR0Term();
        }
        else
        {
            Log(("RTR0Init failed with vrc=%d!\n", vrc));
            rcNt = VBoxDrvNtErr2NtStatus(vrc);
        }

        vboxdrvNtDestroyDevices();
    }
    if (NT_SUCCESS(rcNt))
        rcNt = STATUS_INVALID_PARAMETER;
    return rcNt;
}