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