[Compuware Corporation] [Compuware NuMega home page] [NuMega Lab] [teal] [DriverStudio] [Image][Image] · Home [Image] [Driver Products] Using WDM Callback Objects · DriverStudio Suppose you have a kernel mode driver that wants to provide notification · DriverBundle of an event to other drivers, but the driver has no way of knowing which · Previews other drivers in the system might be interested in being notified. In · Compatibility other words, the driver would like to broadcast a message to whichever [Downloads] · drivers are ready to receive it. For example, suppose a driver wants to Wizards inform related drivers that it has modified some registry setting, but · Utilities the driver doesn't know which of those related drivers are currently · NT source running. examples · VxD source WDM provides a little known mechanism for implementing exactly this kind examples of communication between drivers. The mechanism uses a system entity · WDM source somewhat ambiguously named a callback object. A callback object is examples essentially a named object associated with a list of function addresses. [Resources] · A driver can notify the callback, which causes the system to call each of the functions on the callback's function list. Other drivers can add or Technical papers remove function addresses from the callback's function list. · Useful links · Technical tips To create a callback object, a driver calls ExCreateCallback: [Support] · Support · Knowledge base NTSTATUS · Problem ExCreateCallback( submission OUT PCALLBACK_OBJECT *CallbackObject, · Product IN POBJECT_ATTRIBUTES ObjectAttributes, registration IN BOOLEAN Create, · Release notes IN BOOLEAN AllowMultipleCallbacks [Shop NuMega] · ); Buy it! · Price list The system uses the name in the object attributes structure to create a · How to buy named callback object. There is a branch of the object directory named · Sales offices "Callback," and this is where callback objects are normally created. The calling driver must specify the full object path when initializing the object attributes. A successful call to ExCreateCallback sets [Y2K Compliance] *CallbackObject to a pointer to a system callback object that the driver can later use to notify the callback. [More information] This same service is used by other drivers that want to be called when the object is notified. Such drivers set parameter Create to FALSE. To register a function to be called when the callback is notified, a driver calls ExRegisterCallback, whose prototype is as follows: PVOID ExRegisterCallback( IN PCALLBACK_OBJECT CallbackObject, IN PCALLBACK_FUNCTION CallbackFunction, IN PVOID CallbackContext ); For this call, CallbackObject is the object pointer obtained from an earlier call to ExCreateCallback, and CallbackFunction is the address of the function to be called when the callback is notified. The callback function must have the following prototype: VOID CallbackFunction ( IN PVOID CallbackContext, IN PVOID Argument1, IN PVOID Argument2 ); To notify the callback, i.e. to cause all registered callback functions to be called, a driver calls ExNotifyCallback: VOID ExNotifyCallback( IN PCALLBACK_OBJECT CallbackObject, IN PVOID Argument1, IN PVOID Argument2 ); To remove a function from the list of functions to be called when a callback is notified, a driver calls ExUnregisterCallback. This parameter to this function is the value returned from the call to ExRegisterCallback. You can view the callback objects that exist on your system (Windows 98 or Windows 2000) using a tool like Winobj, or by using the objdir command in SoftICE. You will probably see these three callbacks, which are created by the system: SetSystemTime, SuspendHibernateSystem, and SetSystemInformation. Any driver can register a function to be called when the system notifies these callback objects. For example, if you wanted to get notification of whenever the system time was changed, you would add this code to your driver: At global scope: PVOID gUnregisterToken=0; VOID MySetTimeFunction(PVOID ctx, PVOID arg1, PVOID arg2) { DbgPrint("The set time function was called\n"); } During initialization: NTSTATUS status; OBJECT_ATTRIBUTES Oa; UNICODE_STRING CallbackName; PCALLBACK_OBJECT pSetTimeCallback; RtlInitUnicodeString(&CallbackName,L"\\Callback\\SetSystemTime"); InitializeObjectAttributes( &Oa, &CallbackName, OBJ_CASE_INSENSITIVE, NULL, NULL ); status = ExCreateCallback(&pSetTimeCallback, &Oa, FALSE, FALSE); if ( NT_SUCCESS(status) && pSetTimeCallback ) { gUnregisterToken = ExRegisterCallback( pSetTimeCallback, MySetTimeFunction, NULL); } In your unload or remove routine: if ( gUnregisterToken ) ExUnregisterCallback(gUnregisterToken); Two final notes about callbacks: * Compuware's DriverWorks class library will provide a class that wraps up callback functionality in an easy to use C++ class. * The callback services exist on NT 4.0, but are stubbed out. DriverCentral · DriverStudio · Free downloads · Resources · Support and Services · Shop NuMega Compuware NuMega · Tel: +1 603 578-8400 · Updated: 9 August 1999 · Problems? Contact our webmaster.