Main Page | Class Hierarchy | Class List | File List | Class Members | File Members

callback.c File Reference

#include "exp.h"

Go to the source code of this file.

Classes

struct  _CALLBACK_OBJECT
struct  _CALLBACK_REGISTRATION

Defines

#define CALLBACK_MODIFY_STATE   0x0001
#define CALLBACK_ALL_ACCESS

Typedefs

typedef _CALLBACK_OBJECT CALLBACK_OBJECT
typedef _CALLBACK_OBJECTPCALLBACK_OBJECT
typedef _CALLBACK_REGISTRATION CALLBACK_REGISTRATION
typedef _CALLBACK_REGISTRATIONPCALLBACK_REGISTRATION

Functions

VOID ExpDeleteCallback (IN PCALLBACK_OBJECT CallbackObject)
BOOLEAN ExpInitializeCallbacks ()
NTSTATUS ExCreateCallback (OUT PCALLBACK_OBJECT *CallbackObject, IN POBJECT_ATTRIBUTES ObjectAttributes, IN BOOLEAN Create, IN BOOLEAN AllowMultipleCallbacks)
PVOID ExRegisterCallback (IN PCALLBACK_OBJECT CallbackObject, IN PCALLBACK_FUNCTION CallbackFunction, IN PVOID CallbackContext)
VOID ExUnregisterCallback (IN PVOID CbRegistration)
VOID ExNotifyCallback (IN PCALLBACK_OBJECT CallbackObject, IN PVOID Argument1, IN PVOID Argument2)

Variables

POBJECT_TYPE ExCallbackObjectType
KEVENT ExpCallbackEvent
GENERIC_MAPPING ExpCallbackMapping


Define Documentation

#define CALLBACK_ALL_ACCESS
 

Value:

(STANDARD_RIGHTS_REQUIRED|SYNCHRONIZE|\ CALLBACK_MODIFY_STATE )

Definition at line 35 of file ex/callback.c.

Referenced by ExpInitializeCallbacks().

#define CALLBACK_MODIFY_STATE   0x0001
 

Definition at line 33 of file ex/callback.c.


Typedef Documentation

typedef struct _CALLBACK_OBJECT CALLBACK_OBJECT
 

typedef struct _CALLBACK_REGISTRATION CALLBACK_REGISTRATION
 

typedef struct _CALLBACK_OBJECT * PCALLBACK_OBJECT
 

Referenced by ExCreateCallback(), and ExUnregisterCallback().

typedef struct _CALLBACK_REGISTRATION * PCALLBACK_REGISTRATION
 

Referenced by ExNotifyCallback(), ExRegisterCallback(), and ExUnregisterCallback().


Function Documentation

NTSTATUS ExCreateCallback OUT PCALLBACK_OBJECT CallbackObject,
IN POBJECT_ATTRIBUTES  ObjectAttributes,
IN BOOLEAN  Create,
IN BOOLEAN  AllowMultipleCallbacks
 

Definition at line 222 of file ex/callback.c.

References Create(), ExCallbackObjectType, Handle, KeInitializeSpinLock(), KernelMode, NT_SUCCESS, NTSTATUS(), NULL, ObCreateObject(), ObInsertObject(), ObjectAttributes, ObOpenObjectByName(), ObReferenceObjectByHandle(), PAGED_CODE, PCALLBACK_OBJECT, and Status.

Referenced by ExpInitializeCallbacks().

00231 : 00232 00233 This function opens a callback object with the specified callback 00234 object. If the callback object does not exist or it is a NULL then 00235 a callback object will be created if create is TRUE. If a callbackobject 00236 is created it will only support mulitiple registered callbacks if 00237 AllowMulitipleCallbacks is TRUE. 00238 00239 Arguments: 00240 00241 CallbackObject - Supplies a pointer to a variable that will receive the 00242 Callback object. 00243 00244 CallbackName - Supplies a pointer to a object name that will receive the 00245 00246 Create - Supplies a flag which indicates whether a callback object will 00247 be created or not . 00248 00249 AllowMultipleCallbacks - Supplies a flag which indicates only support 00250 mulitiple registered callbacks. 00251 00252 Return Value: 00253 00254 Returns STATUS_SUCESS unless fali... 00255 00256 --*/ 00257 00258 { 00259 PCALLBACK_OBJECT cbObject; 00260 NTSTATUS Status; 00261 HANDLE Handle; 00262 00263 PAGED_CODE(); 00264 00265 // 00266 // If named callback, open handle to it 00267 // 00268 00269 if (ObjectAttributes->ObjectName) { 00270 Status = ObOpenObjectByName(ObjectAttributes, 00271 ExCallbackObjectType, 00272 KernelMode, 00273 NULL, 00274 0, // DesiredAccess, 00275 NULL, 00276 &Handle); 00277 } else { 00278 Status = STATUS_UNSUCCESSFUL; 00279 } 00280 00281 // 00282 // If not opened, check if callback should be created 00283 // 00284 00285 if(!NT_SUCCESS(Status) && Create ) { 00286 Status = ObCreateObject(KernelMode, 00287 ExCallbackObjectType, 00288 ObjectAttributes, 00289 KernelMode, 00290 NULL, 00291 sizeof(CALLBACK_OBJECT), 00292 0, 00293 0, 00294 (PVOID *)&cbObject ); 00295 00296 if(NT_SUCCESS(Status)){ 00297 00298 // 00299 // Fill in structure signature 00300 // 00301 00302 cbObject->Signature = 'llaC'; 00303 00304 // 00305 // It will support multiple registered callbacks if 00306 // AllowMultipleCallbacks is TRUE. 00307 // 00308 00309 cbObject->AllowMultipleCallbacks = AllowMultipleCallbacks; 00310 00311 // 00312 // Initialize CallbackObject queue. 00313 // 00314 00315 InitializeListHead( &cbObject->RegisteredCallbacks ); 00316 00317 // 00318 // Initialize spinlock 00319 // 00320 00321 KeInitializeSpinLock (&cbObject->Lock); 00322 00323 00324 // 00325 // Put the object in the root directory 00326 // 00327 00328 Status = ObInsertObject ( 00329 cbObject, 00330 NULL, 00331 FILE_READ_DATA, 00332 0, 00333 NULL, 00334 &Handle ); 00335 00336 } 00337 00338 } 00339 00340 if(NT_SUCCESS(Status)){ 00341 00342 // 00343 // Add one to callback object reference count 00344 // 00345 00346 Status = ObReferenceObjectByHandle ( 00347 Handle, 00348 0, // DesiredAccess 00349 ExCallbackObjectType, 00350 KernelMode, 00351 &cbObject, 00352 NULL 00353 ); 00354 00355 ZwClose (Handle); 00356 } 00357 00358 // 00359 // If SUCEESS , returns a referenced pointer to the CallbackObject. 00360 // 00361 00362 if (NT_SUCCESS(Status)) { 00363 *CallbackObject = cbObject; 00364 } 00365 00366 return Status; 00367 }

VOID ExNotifyCallback IN PCALLBACK_OBJECT  CallbackObject,
IN PVOID  Argument1,
IN PVOID  Argument2
 

Definition at line 563 of file ex/callback.c.

References _CALLBACK_REGISTRATION::Busy, _CALLBACK_REGISTRATION::CallbackContext, _CALLBACK_REGISTRATION::CallbackFunction, DISPATCH_LEVEL, ExpCallbackEvent, FALSE, KeAcquireSpinLock, KeReleaseSpinLock(), KeSetEvent(), NULL, PCALLBACK_REGISTRATION, and _CALLBACK_REGISTRATION::UnregisterWaiting.

00571 : 00572 00573 This function notifies all registered callbacks . 00574 00575 Arguments: 00576 00577 CallbackObject - supplies a pointer to the callback object should be 00578 notified. 00579 00580 SystemArgument1 - supplies a pointer will be passed to callback function. 00581 00582 SystemArgument2 - supplies a pointer will be passed to callback function. 00583 00584 Return Value: 00585 00586 None. 00587 00588 --*/ 00589 00590 { 00591 PLIST_ENTRY Link; 00592 PCALLBACK_REGISTRATION CallbackRegistration; 00593 KIRQL OldIrql; 00594 00595 if (CallbackObject == NULL) { 00596 return ; 00597 } 00598 00599 // 00600 // Synchronize with callback object 00601 // 00602 00603 KeAcquireSpinLock (&CallbackObject->Lock, &OldIrql); 00604 00605 // 00606 // call registered callbacks at callers IRQL level 00607 // ( done if FIFO order of registration ) 00608 // 00609 00610 if (OldIrql == DISPATCH_LEVEL) { 00611 00612 // 00613 // OldIrql is DISPATCH_LEVEL, just invoke all callbacks without 00614 // releasing the lock 00615 // 00616 00617 for (Link = CallbackObject->RegisteredCallbacks.Flink; 00618 Link != &CallbackObject->RegisteredCallbacks; 00619 Link = Link->Flink) { 00620 00621 // 00622 // Get current registration to notify 00623 // 00624 00625 CallbackRegistration = CONTAINING_RECORD (Link, 00626 CALLBACK_REGISTRATION, 00627 Link); 00628 00629 // 00630 // Notify reigstration 00631 // 00632 00633 CallbackRegistration->CallbackFunction( 00634 CallbackRegistration->CallbackContext, 00635 Argument1, 00636 Argument2 00637 ); 00638 00639 } // next registration 00640 00641 } else { 00642 00643 // 00644 // OldIrql is < DISPATCH_LEVEL, the code being called may be pagable 00645 // and the callback object spinlock needs to be released around 00646 // each registration callback. 00647 // 00648 00649 for (Link = CallbackObject->RegisteredCallbacks.Flink; 00650 Link != &CallbackObject->RegisteredCallbacks; 00651 Link = Link->Flink ) { 00652 00653 // 00654 // Get current registration to notify 00655 // 00656 00657 CallbackRegistration = CONTAINING_RECORD (Link, 00658 CALLBACK_REGISTRATION, 00659 Link); 00660 00661 // 00662 // If registration is being removed, don't bothing calling it 00663 // 00664 00665 if (!CallbackRegistration->UnregisterWaiting) { 00666 00667 // 00668 // Set registration busy 00669 // 00670 00671 CallbackRegistration->Busy += 1; 00672 00673 // 00674 // Release SpinLock and notify this callback 00675 // 00676 00677 KeReleaseSpinLock (&CallbackObject->Lock, OldIrql); 00678 00679 CallbackRegistration->CallbackFunction( 00680 CallbackRegistration->CallbackContext, 00681 Argument1, 00682 Argument2 00683 ); 00684 00685 // 00686 // Synchronize with CallbackObject 00687 // 00688 00689 KeAcquireSpinLock (&CallbackObject->Lock, &OldIrql); 00690 00691 // 00692 // Remove our busy count 00693 // 00694 00695 CallbackRegistration->Busy -= 1; 00696 00697 // 00698 // If the registriation removal is pending, kick global 00699 // event let unregister conitnue 00700 // 00701 00702 if (CallbackRegistration->UnregisterWaiting && 00703 CallbackRegistration->Busy == 0) { 00704 KeSetEvent (&ExpCallbackEvent, 0, FALSE); 00705 } 00706 } 00707 } 00708 } 00709 00710 00711 // 00712 // Release callback 00713 // 00714 00715 KeReleaseSpinLock (&CallbackObject->Lock, OldIrql); 00716 } }

VOID ExpDeleteCallback IN PCALLBACK_OBJECT  CallbackObject  ) 
 

Definition at line 370 of file ex/callback.c.

References ASSERT.

Referenced by ExpInitializeCallbacks().

00373 { 00374 ASSERT (IsListEmpty(&CallbackObject->RegisteredCallbacks)); 00375 }

BOOLEAN ExpInitializeCallbacks  ) 
 

Definition at line 101 of file ex/callback.c.

References CALLBACK_ALL_ACCESS, EXP_INITIALIZE_GLOBAL_CALLBACKS::CallBackObject, ExCallbackObjectType, ExCreateCallback(), ExpCallbackEvent, ExpCallbackMapping, ExpDeleteCallback(), ExpInitializeCallback, ExpWstrCallback, FALSE, KeInitializeEvent, L, NonPagedPool, NT_SUCCESS, NtClose(), NtCreateDirectoryObject(), NTSTATUS(), NULL, ObCreateObjectType(), OBJECT_TYPE_INITIALIZER, ObjectAttributes, RtlInitUnicodeString(), SePublicDefaultSd, Status, and TRUE.

00106 : 00107 00108 This function creates the callback object type descriptor at system 00109 initialization and stores the address of the object type descriptor 00110 in local static storage. 00111 00112 Arguments: 00113 00114 None. 00115 00116 Return Value: 00117 00118 A value of TRUE is returned if the timer object type descriptor is 00119 successfully initialized. Otherwise a value of FALSE is returned. 00120 00121 --*/ 00122 00123 { 00124 OBJECT_TYPE_INITIALIZER ObjectTypeInitializer; 00125 OBJECT_ATTRIBUTES ObjectAttributes; 00126 NTSTATUS Status; 00127 UNICODE_STRING unicodeString; 00128 ULONG i; 00129 HANDLE handle; 00130 00131 // 00132 // Initialize string descriptor. 00133 // 00134 00135 RtlInitUnicodeString(&unicodeString, L"Callback"); 00136 00137 // 00138 // Create timer object type descriptor. 00139 // 00140 00141 RtlZeroMemory(&ObjectTypeInitializer, sizeof(ObjectTypeInitializer)); 00142 ObjectTypeInitializer.Length = sizeof(ObjectTypeInitializer); 00143 ObjectTypeInitializer.InvalidAttributes = OBJ_OPENLINK; 00144 ObjectTypeInitializer.GenericMapping = ExpCallbackMapping; 00145 ObjectTypeInitializer.DeleteProcedure = ExpDeleteCallback; 00146 ObjectTypeInitializer.PoolType = NonPagedPool; 00147 ObjectTypeInitializer.ValidAccessMask = CALLBACK_ALL_ACCESS; 00148 Status = ObCreateObjectType(&unicodeString, 00149 &ObjectTypeInitializer, 00150 (PSECURITY_DESCRIPTOR)NULL, 00151 &ExCallbackObjectType); 00152 00153 if (!NT_SUCCESS(Status)) { 00154 return FALSE; 00155 } 00156 00157 RtlInitUnicodeString( &unicodeString, ExpWstrCallback ); 00158 InitializeObjectAttributes( 00159 &ObjectAttributes, 00160 &unicodeString, 00161 OBJ_CASE_INSENSITIVE | OBJ_PERMANENT, 00162 NULL, 00163 SePublicDefaultSd 00164 ); 00165 00166 Status = NtCreateDirectoryObject( 00167 &handle, 00168 DIRECTORY_ALL_ACCESS, 00169 &ObjectAttributes 00170 ); 00171 00172 if (!NT_SUCCESS(Status)) { 00173 return FALSE; 00174 } 00175 00176 NtClose (handle); 00177 00178 // 00179 // Initialize event to wait on for Unregisters which occur while 00180 // notifications are in progress 00181 // 00182 00183 KeInitializeEvent (&ExpCallbackEvent, NotificationEvent, 0); 00184 00185 // 00186 // Initialize NT global callbacks 00187 // 00188 00189 for (i=0; ExpInitializeCallback[i].CallBackObject; i++) { 00190 00191 // 00192 // Create named calledback 00193 // 00194 00195 RtlInitUnicodeString(&unicodeString, ExpInitializeCallback[i].CallbackName); 00196 00197 00198 InitializeObjectAttributes( 00199 &ObjectAttributes, 00200 &unicodeString, 00201 OBJ_PERMANENT | OBJ_CASE_INSENSITIVE, 00202 NULL, 00203 NULL 00204 ); 00205 00206 Status = ExCreateCallback ( 00207 ExpInitializeCallback[i].CallBackObject, 00208 &ObjectAttributes, 00209 TRUE, 00210 TRUE 00211 ); 00212 00213 if (!NT_SUCCESS(Status)) { 00214 return FALSE; 00215 } 00216 } 00217 00218 return TRUE; 00219 }

PVOID ExRegisterCallback IN PCALLBACK_OBJECT  CallbackObject,
IN PCALLBACK_FUNCTION  CallbackFunction,
IN PVOID  CallbackContext
 

Definition at line 378 of file ex/callback.c.

References ASSERT, _CALLBACK_REGISTRATION::Busy, _CALLBACK_REGISTRATION::CallbackContext, _CALLBACK_REGISTRATION::CallbackFunction, _CALLBACK_REGISTRATION::CallbackObject, DISPATCH_LEVEL, ExAllocatePoolWithTag, ExFreePool(), FALSE, KeAcquireSpinLock, KeReleaseSpinLock(), _CALLBACK_REGISTRATION::Link, NonPagedPool, NTSTATUS(), NULL, ObDereferenceObject, ObReferenceObject, PCALLBACK_FUNCTION, PCALLBACK_REGISTRATION, Status, TRUE, and _CALLBACK_REGISTRATION::UnregisterWaiting.

00386 : 00387 00388 This routine allows a caller to register that it would like to have its 00389 callback Function invoked when the callback notification call occurs. 00390 00391 Arguments: 00392 00393 CallbackObject - Supplies a pointer to a CallbackObject. 00394 00395 CallbackFunction - Supplies a pointer to a function which is to 00396 be executed when the Callback notification occures. 00397 00398 CallbackContext - Supplies a pointer to an arbitrary data structure 00399 that will be passed to the function specified by the CallbackFunction 00400 parameter. 00401 00402 Return Value: 00403 00404 Returns handle to callback registration. 00405 00406 --*/ 00407 { 00408 PCALLBACK_REGISTRATION CallbackRegistration; 00409 BOOLEAN Inserted; 00410 KIRQL OldIrql; 00411 NTSTATUS Status; 00412 00413 ASSERT (CallbackFunction); 00414 ASSERT (KeGetCurrentIrql() < DISPATCH_LEVEL); 00415 00416 // 00417 // Add reference to object 00418 // 00419 00420 ObReferenceObject (CallbackObject); 00421 00422 // 00423 // Begin by attempting to allocate storage for the CallbackRegistration. 00424 // one cannot be allocated, return the error status. 00425 // 00426 00427 CallbackRegistration = ExAllocatePoolWithTag( 00428 NonPagedPool, 00429 sizeof( CALLBACK_REGISTRATION ), 00430 'eRBC' 00431 ); 00432 00433 00434 if( !CallbackRegistration ) { 00435 ObDereferenceObject (CallbackObject); 00436 return NULL; 00437 } 00438 00439 00440 // 00441 // Initialize the callback packet 00442 // 00443 00444 CallbackRegistration->CallbackObject = CallbackObject; 00445 CallbackRegistration->CallbackFunction = CallbackFunction; 00446 CallbackRegistration->CallbackContext = CallbackContext; 00447 CallbackRegistration->Busy = 0; 00448 CallbackRegistration->UnregisterWaiting = FALSE; 00449 00450 00451 Inserted = FALSE; 00452 KeAcquireSpinLock (&CallbackObject->Lock, &OldIrql); 00453 00454 if( CallbackObject->AllowMultipleCallbacks || 00455 IsListEmpty( &CallbackObject->RegisteredCallbacks ) ) { 00456 00457 // 00458 // add CallbackRegistration to tail 00459 // 00460 00461 00462 Inserted = TRUE; 00463 InsertTailList( &CallbackObject->RegisteredCallbacks, 00464 &CallbackRegistration->Link ) 00465 } 00466 00467 KeReleaseSpinLock (&CallbackObject->Lock, OldIrql); 00468 00469 if (!Inserted) { 00470 ExFreePool (CallbackRegistration); 00471 CallbackRegistration = NULL; 00472 } 00473 00474 return (PVOID) CallbackRegistration; 00475 }

VOID ExUnregisterCallback IN PVOID  CbRegistration  ) 
 

Definition at line 479 of file ex/callback.c.

References ASSERT, _CALLBACK_REGISTRATION::Busy, _CALLBACK_REGISTRATION::CallbackObject, DISPATCH_LEVEL, Executive, ExFreePool(), ExpCallbackEvent, FALSE, KeAcquireSpinLock, KeClearEvent, KeReleaseSpinLock(), KernelMode, KeWaitForSingleObject(), _CALLBACK_REGISTRATION::Link, _CALLBACK_OBJECT::Lock, NULL, ObDereferenceObject, PCALLBACK_OBJECT, PCALLBACK_REGISTRATION, TRUE, and _CALLBACK_REGISTRATION::UnregisterWaiting.

00485 : 00486 00487 This function removes the callback registration for the callbacks 00488 from the list of callback object . 00489 00490 Arguments: 00491 00492 CallbackRegistration - Pointer to device object for the file system. 00493 00494 Return Value: 00495 00496 None. 00497 00498 --*/ 00499 00500 { 00501 PCALLBACK_REGISTRATION CallbackRegistration; 00502 PCALLBACK_OBJECT CallbackObject; 00503 KIRQL OldIrql; 00504 00505 ASSERT (KeGetCurrentIrql() < DISPATCH_LEVEL); 00506 00507 CallbackRegistration = (PCALLBACK_REGISTRATION) CbRegistration; 00508 CallbackObject = CallbackRegistration->CallbackObject; 00509 00510 KeAcquireSpinLock (&CallbackObject->Lock, &OldIrql); 00511 00512 // 00513 // Wait for registration 00514 // 00515 00516 while (CallbackRegistration->Busy) { 00517 00518 // 00519 // Set waiting flag, then wait. (not performance critical - use 00520 // single global event to wait for any and all unregister waits) 00521 // 00522 00523 CallbackRegistration->UnregisterWaiting = TRUE; 00524 KeClearEvent (&ExpCallbackEvent); 00525 KeReleaseSpinLock (&CallbackObject->Lock, OldIrql); 00526 00527 KeWaitForSingleObject ( 00528 &ExpCallbackEvent, 00529 Executive, 00530 KernelMode, 00531 FALSE, 00532 NULL 00533 ); 00534 00535 // 00536 // Synchronize with callback object and recheck registration busy 00537 // 00538 00539 KeAcquireSpinLock (&CallbackObject->Lock, &OldIrql); 00540 } 00541 00542 // 00543 // Registration not busy, remove it from the callback object 00544 // 00545 00546 RemoveEntryList (&CallbackRegistration->Link); 00547 KeReleaseSpinLock (&CallbackObject->Lock, OldIrql); 00548 00549 // 00550 // Free memory used for CallbackRegistration 00551 // 00552 00553 ExFreePool (CallbackRegistration); 00554 00555 // 00556 // Remove reference count on CallbackObject 00557 // 00558 00559 ObDereferenceObject (CallbackObject); 00560 }


Variable Documentation

POBJECT_TYPE ExCallbackObjectType
 

Definition at line 43 of file ex/callback.c.

Referenced by ExCreateCallback(), and ExpInitializeCallbacks().

KEVENT ExpCallbackEvent
 

Definition at line 49 of file ex/callback.c.

Referenced by ExNotifyCallback(), ExpInitializeCallbacks(), and ExUnregisterCallback().

GENERIC_MAPPING ExpCallbackMapping
 

Initial value:

{ STANDARD_RIGHTS_READ , STANDARD_RIGHTS_WRITE | CALLBACK_MODIFY_STATE, STANDARD_RIGHTS_EXECUTE | SYNCHRONIZE, CALLBACK_ALL_ACCESS }

Definition at line 56 of file ex/callback.c.

Referenced by ExpInitializeCallbacks().


Generated on Sat May 15 19:43:02 2004 for test by doxygen 1.3.7