NTSTATUS NotifyCallbackObject(PWSTR pszCallbackName, PVOID pParam) { NTSTATUS status = STATUS_UNSUCCESSFUL; OBJECT_ATTRIBUTES cboa = { 0, }; UNICODE_STRING usCbName; PCALLBACK_OBJECT pCallbackObj; if (pszCallbackName == NULL) { return STATUS_INVALID_PARAMETER; } RtlInitUnicodeString(&usCbName, pszCallbackName); InitializeObjectAttributes(&cboa, &usCbName, OBJ_CASE_INSENSITIVE, 0, 0); status = ExCreateCallback(&pCallbackObj, &cboa, FALSE, TRUE); if (NT_SUCCESS(status)) { ExNotifyCallback(pCallbackObj, pParam, NULL); ObDereferenceObject(pCallbackObj); } else drbdlock_print_log("Failed to open callback object for %ws, status : 0x%x\n", pszCallbackName, status); return status; }
NTSTATUS RegisterPowerStateChangeCallback(_Inout_ DEVICE_EXTENSION* pDeviceExtension) { #if DBG DbgPrintEx(DPFLTR_IHVNETWORK_ID, DPFLTR_INFO_LEVEL, " ---> RegisterPowerStateChangeCallback()\n"); #endif /// DBG NT_ASSERT(pDeviceExtension); NTSTATUS status = STATUS_SUCCESS; OBJECT_ATTRIBUTES objectAttributes = {0}; UNICODE_STRING unicodeString = {0}; RtlInitUnicodeString(&unicodeString, L"\\Callback\\PowerState"); InitializeObjectAttributes(&objectAttributes, &unicodeString, OBJ_CASE_INSENSITIVE, 0, 0); status = ExCreateCallback(&(pDeviceExtension->pCallbackObject), &objectAttributes, FALSE, /// Do not create as the system should already have done this TRUE); /// Allow multiple callbacks if(status != STATUS_SUCCESS) { DbgPrintEx(DPFLTR_IHVNETWORK_ID, DPFLTR_ERROR_LEVEL, " !!!! RegisterPowerStateChangeCallback : ExCreateCallback() [status: %#x]\n", status); HLPR_BAIL; } pDeviceExtension->pRegistration = ExRegisterCallback(pDeviceExtension->pCallbackObject, PowerStateCallback, pDeviceExtension); HLPR_BAIL_LABEL: #if DBG DbgPrintEx(DPFLTR_IHVNETWORK_ID, DPFLTR_INFO_LEVEL, " <--- RegisterPowerStateChangeCallback() [status: %#x]\n", status); #endif /// DBG return status; }
// Registers power callback _Use_decl_annotations_ NTSTATUS PowerCallbackInitialization() { PAGED_CODE(); UNICODE_STRING name = RTL_CONSTANT_STRING(L"\\Callback\\PowerState"); OBJECT_ATTRIBUTES oa = RTL_CONSTANT_OBJECT_ATTRIBUTES(&name, OBJ_CASE_INSENSITIVE); auto status = ExCreateCallback(&g_pcp_callback_object, &oa, FALSE, TRUE); if (!NT_SUCCESS(status)) { return status; } g_pcp_registration = ExRegisterCallback( g_pcp_callback_object, PowerCallbackpCallbackRoutine, nullptr); if (!g_pcp_registration) { ObDereferenceObject(g_pcp_callback_object); g_pcp_callback_object = nullptr; return STATUS_UNSUCCESSFUL; } return status; }
NTSTATUS register_power_callback(PDEV_EXT ext) { OBJECT_ATTRIBUTES obj; UNICODE_STRING name; NTSTATUS status; RtlInitUnicodeString(&name, L"\\Callback\\PowerState"); InitializeObjectAttributes(&obj, &name, OBJ_CASE_INSENSITIVE, NULL, NULL); status = ExCreateCallback(&ext->CbObject, &obj, FALSE, TRUE); if (!NT_SUCCESS(status)) return status; ext->CbRegistration = ExRegisterCallback(ext->CbObject, power_callback, ext); if (!ext->CbRegistration) { ObDereferenceObject(ext->CbObject); return STATUS_UNSUCCESSFUL; } return STATUS_SUCCESS; }
NTSTATUS drbdlockStartupCallback( VOID ) /*++ Routine Description: Initializes callback object to be notified. Arguments: None. Return Value: NtStatus values. --*/ { NTSTATUS status = STATUS_UNSUCCESSFUL; OBJECT_ATTRIBUTES oa = { 0, }; UNICODE_STRING usCallbackName; RtlInitUnicodeString(&usCallbackName, DRBDLOCK_CALLBACK_NAME); InitializeObjectAttributes(&oa, &usCallbackName, OBJ_CASE_INSENSITIVE | OBJ_PERMANENT, 0, 0); status = ExCreateCallback(&g_pCallbackObj, &oa, TRUE, TRUE); if (!NT_SUCCESS(status)) { drbdlock_print_log("ExCreateCallback failed, status : 0x%x\n", status); return status; } g_pCallbackReg = ExRegisterCallback(g_pCallbackObj, drbdlockCallbackFunc, NULL); return status; }
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; }
BOOLEAN ndisprotRegisterExCallBack() { OBJECT_ATTRIBUTES ObjectAttr; UNICODE_STRING CallBackObjectName; NTSTATUS Status; BOOLEAN bResult = TRUE; DEBUGP(DL_LOUD, ("--> ndisprotRegisterExCallBack\n")); PAGED_CODE(); do { RtlInitUnicodeString(&CallBackObjectName, NDISPROT_CALLBACK_NAME); InitializeObjectAttributes(&ObjectAttr, &CallBackObjectName, OBJ_CASE_INSENSITIVE | OBJ_PERMANENT, NULL, NULL); Status = ExCreateCallback(&CallbackObject, &ObjectAttr, TRUE, TRUE); if (!NT_SUCCESS(Status)) { DEBUGP(DL_ERROR, ("RegisterExCallBack: failed to create callback %lx\n", Status)); bResult = FALSE; break; } CallbackRegisterationHandle = ExRegisterCallback(CallbackObject, ndisprotCallback, (PVOID)NULL); if (CallbackRegisterationHandle == NULL) { DEBUGP(DL_ERROR,("RegisterExCallBack: failed to register a Callback routine%lx\n", Status)); bResult = FALSE; break; } ExNotifyCallback(CallbackObject, (PVOID)CALLBACK_SOURCE_NDISPROT, (PVOID)NULL); }while(FALSE); if(!bResult) { if (CallbackRegisterationHandle) { ExUnregisterCallback(CallbackRegisterationHandle); CallbackRegisterationHandle = NULL; } if (CallbackObject) { ObDereferenceObject(CallbackObject); CallbackObject = NULL; } } DEBUGP(DL_LOUD, ("<-- ndisprotRegisterExCallBack\n")); return bResult; }
BOOLEAN ExpInitializeCallbacks ( ) /*++ Routine Description: This function creates the callback object type descriptor at system initialization and stores the address of the object type descriptor in local static storage. Arguments: None. Return Value: A value of TRUE is returned if the timer object type descriptor is successfully initialized. Otherwise a value of FALSE is returned. --*/ { #ifdef _PNP_POWER_ OBJECT_TYPE_INITIALIZER ObjectTypeInitializer; OBJECT_ATTRIBUTES ObjectAttributes; NTSTATUS Status; UNICODE_STRING unicodeString; ULONG i; HANDLE handle; // // Initialize string descriptor. // RtlInitUnicodeString(&unicodeString, L"Callback"); // // Create timer object type descriptor. // RtlZeroMemory(&ObjectTypeInitializer, sizeof(ObjectTypeInitializer)); ObjectTypeInitializer.Length = sizeof(ObjectTypeInitializer); ObjectTypeInitializer.InvalidAttributes = OBJ_OPENLINK; ObjectTypeInitializer.GenericMapping = ExpCallbackMapping; ObjectTypeInitializer.DeleteProcedure = ExpDeleteCallback; ObjectTypeInitializer.PoolType = NonPagedPool; ObjectTypeInitializer.ValidAccessMask = CALLBACK_ALL_ACCESS; Status = ObCreateObjectType(&unicodeString, &ObjectTypeInitializer, (PSECURITY_DESCRIPTOR)NULL, &ExCallbackObjectType); if (!NT_SUCCESS(Status)) { return FALSE; } RtlInitUnicodeString( &unicodeString, ExpWstrCallback ); InitializeObjectAttributes( &ObjectAttributes, &unicodeString, OBJ_CASE_INSENSITIVE | OBJ_PERMANENT, NULL, SePublicDefaultSd ); Status = NtCreateDirectoryObject( &handle, DIRECTORY_ALL_ACCESS, &ObjectAttributes ); if (!NT_SUCCESS(Status)) { return FALSE; } NtClose (handle); // // Initialize event to wait on for Unregisters which occur while // notifications are in progress // KeInitializeEvent (&ExpCallbackEvent, NotificationEvent, 0); // // Initialize NT global callbacks // for (i=0; ExpInitializeCallback[i].CallBackObject; i++) { // // Create named calledback // RtlInitUnicodeString(&unicodeString, ExpInitializeCallback[i].CallbackName); InitializeObjectAttributes( &ObjectAttributes, &unicodeString, OBJ_PERMANENT | OBJ_CASE_INSENSITIVE, NULL, NULL ); Status = ExCreateCallback ( ExpInitializeCallback[i].CallBackObject, &ObjectAttributes, TRUE, TRUE ); if (!NT_SUCCESS(Status)) { return FALSE; } } #endif return TRUE; }
/** * 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; }
/*++ * @name ExpInitializeCallbacks * * Creates the Callback Object as a valid Object Type in the Kernel. * Internal function, subject to further review * * @return TRUE if the Callback Object Type was successfully created. * * @remarks None * *--*/ BOOLEAN INIT_FUNCTION NTAPI ExpInitializeCallbacks(VOID) { OBJECT_ATTRIBUTES ObjectAttributes; NTSTATUS Status; UNICODE_STRING DirName = RTL_CONSTANT_STRING(L"\\Callback"); UNICODE_STRING CallbackName; UNICODE_STRING Name; OBJECT_TYPE_INITIALIZER ObjectTypeInitializer; HANDLE DirectoryHandle; ULONG i; /* Setup lightweight callback lock */ ExpCallBackFlush.Value = 0; /* Initialize the Callback Object type */ RtlZeroMemory(&ObjectTypeInitializer, sizeof(ObjectTypeInitializer)); RtlInitUnicodeString(&Name, L"Callback"); ObjectTypeInitializer.Length = sizeof(ObjectTypeInitializer); ObjectTypeInitializer.InvalidAttributes = OBJ_OPENLINK; ObjectTypeInitializer.GenericMapping = ExpCallbackMapping; ObjectTypeInitializer.PoolType = NonPagedPool; ObjectTypeInitializer.DeleteProcedure = ExpDeleteCallback; ObjectTypeInitializer.ValidAccessMask = CALLBACK_ALL_ACCESS; Status = ObCreateObjectType(&Name, &ObjectTypeInitializer, NULL, &ExCallbackObjectType); if (!NT_SUCCESS(Status)) return FALSE; /* Initialize the Object */ InitializeObjectAttributes(&ObjectAttributes, &DirName, OBJ_CASE_INSENSITIVE | OBJ_PERMANENT, NULL, SePublicDefaultSd); /* Create the Object Directory */ Status = NtCreateDirectoryObject(&DirectoryHandle, DIRECTORY_ALL_ACCESS, &ObjectAttributes); if (!NT_SUCCESS(Status)) return FALSE; /* Close Handle... */ NtClose(DirectoryHandle); /* Initialize Event used when unregistering */ KeInitializeEvent(&ExpCallbackEvent, NotificationEvent, 0); /* Default NT Kernel Callbacks. */ for (i = 0; ExpInitializeCallback[i].CallbackObject; i++) { /* Create the name from the structure */ RtlInitUnicodeString(&CallbackName, ExpInitializeCallback[i].Name); /* Initialize the Object Attributes Structure */ InitializeObjectAttributes(&ObjectAttributes, &CallbackName, OBJ_PERMANENT | OBJ_CASE_INSENSITIVE, NULL, NULL); /* Create the Callback Object */ Status = ExCreateCallback(ExpInitializeCallback[i].CallbackObject, &ObjectAttributes, TRUE, TRUE); if (!NT_SUCCESS(Status)) return FALSE; } /* Everything successful */ return TRUE; }
NTSTATUS NTAPI DriverEntry(IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING RegistryPath) { NTSTATUS Status; PDRIVER_EXTENSION DriverExtension; OBJECT_ATTRIBUTES ObjectAttributes; UNICODE_STRING CallbackName; /* Allocate registry path */ GlobalRegistryPath.MaximumLength = RegistryPath->Length + sizeof(UNICODE_NULL); GlobalRegistryPath.Length = RegistryPath->Length; GlobalRegistryPath.Buffer = ExAllocatePoolWithTag(PagedPool, GlobalRegistryPath.MaximumLength, 'MtaB'); if (!GlobalRegistryPath.Buffer) { /* Fail if we're out of memory this early */ if (CmBattDebug & CMBATT_GENERIC_WARNING) DbgPrint("CmBatt: Couldn't allocate pool for registry path."); return STATUS_INSUFFICIENT_RESOURCES; } /* Buffer allocated, copy the string */ RtlCopyUnicodeString(&GlobalRegistryPath, RegistryPath); if (CmBattDebug & CMBATT_GENERIC_INFO) DbgPrint("CmBatt DriverEntry - Obj (%08x) Path \"%ws\"\n", DriverObject, RegistryPath->Buffer); /* Setup the major dispatchers */ DriverObject->MajorFunction[IRP_MJ_CREATE] = CmBattOpenClose; DriverObject->MajorFunction[IRP_MJ_CLOSE] = CmBattOpenClose; DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = CmBattIoctl; DriverObject->MajorFunction[IRP_MJ_POWER] = CmBattPowerDispatch; DriverObject->MajorFunction[IRP_MJ_PNP] = CmBattPnpDispatch; DriverObject->MajorFunction[IRP_MJ_SYSTEM_CONTROL] = CmBattSystemControl; /* And the unload routine */ DriverObject->DriverUnload = CmBattUnload; /* And the add device routine */ DriverExtension = DriverObject->DriverExtension; DriverExtension->AddDevice = CmBattAddDevice; /* Create a power callback */ RtlInitUnicodeString(&CallbackName, L"\\Callback\\PowerState"); InitializeObjectAttributes(&ObjectAttributes, &CallbackName, OBJ_KERNEL_HANDLE, NULL, NULL); Status = ExCreateCallback(&CmBattPowerCallBackObject, &ObjectAttributes, 0, TRUE); if (!NT_SUCCESS(Status)) { /* No callback, fail */ CmBattPowerCallBackObject = 0; if (CmBattDebug & CMBATT_GENERIC_WARNING) DbgPrint("CmBattRegisterPowerCallBack: failed status=0x%08x\n", Status); } else { /* Register the power callback now */ CmBattPowerCallBackRegistration = ExRegisterCallback(CmBattPowerCallBackObject, (PVOID)CmBattPowerCallBack, DriverObject); if (CmBattPowerCallBackRegistration) { /* Last thing: setup our DPC and timer for battery wake */ KeInitializeDpc(&CmBattWakeDpcObject, (PVOID)CmBattWakeDpc, DriverObject); KeInitializeTimer(&CmBattWakeDpcTimerObject); } else { ObDereferenceObject(CmBattPowerCallBackObject); if (CmBattDebug & CMBATT_GENERIC_WARNING) DbgPrint("CmBattRegisterPowerCallBack: ExRegisterCallback failed.\n"); } /* All good */ Status = STATUS_SUCCESS; } /* Return failure or success */ return Status; }