test: eventpr.c Source File

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

# eventpr.c

Go to the documentation of this file.

    00001 /*++
    00002
    00003 Copyright (c) 1989  Microsoft Corporation
    00004
    00005 Module Name:
    00006
    00007     eventpr.c
    00008
    00009 Abstract:
    00010
    00011     This module implements the executive event pair object.  Functions
    00012     are provided to create, open, waitlow, waithi, setlow, sethi,
    00013     sethiwaitlo, setlowaithi.
    00014
    00015 Author:
    00016
    00017     Mark Lucovsky (markl) 18-Oct-1990
    00018
    00019 Environment:
    00020
    00021     Kernel mode only.
    00022
    00023 Revision History:
    00024
    00025 --*/
    00026
    00027 #include "exp.h"
    00028
    00029 //
    00030 // Define performance counters.
    00031 //
    00032
    00033 ULONG EvPrSetHigh = 0;
    00034 ULONG EvPrSetLow = 0;
    00035
    00036 //
    00037 // Address of event pair object type descriptor.
    00038 //
    00039
    00040 POBJECT_TYPE ExEventPairObjectType;
    00041
    00042 //
    00043 // Structure that describes the mapping of generic access rights to object
    00044 // specific access rights for event pair objects.
    00045 //
    00046
    00047 GENERIC_MAPPING ExpEventPairMapping = {
    00048     STANDARD_RIGHTS_READ |
    00049         SYNCHRONIZE,
    00050     STANDARD_RIGHTS_WRITE |
    00051         SYNCHRONIZE,
    00052     STANDARD_RIGHTS_EXECUTE |
    00053         SYNCHRONIZE,
    00054     EVENT_PAIR_ALL_ACCESS
    00055 };
    00056
    00057 #ifdef ALLOC_PRAGMA
    00058 #pragma alloc_text(INIT, ExpEventPairInitialization)
    00059 #pragma alloc_text(PAGE, NtCreateEventPair)
    00060 #pragma alloc_text(PAGE, NtOpenEventPair)
    00061 #pragma alloc_text(PAGE, NtWaitLowEventPair)
    00062 #pragma alloc_text(PAGE, NtWaitHighEventPair)
    00063 #pragma alloc_text(PAGE, NtSetLowWaitHighEventPair)
    00064 #pragma alloc_text(PAGE, NtSetHighWaitLowEventPair)
    00065 #pragma alloc_text(PAGE, NtSetHighEventPair)
    00066 #pragma alloc_text(PAGE, NtSetLowEventPair)
    00067 #endif
    00068
    00069 BOOLEAN
    00070 ExpEventPairInitialization (
    00071     )
    00072
    00073 /*++
    00074
    00075 Routine Description:
    00076
    00077     This function creates the event pair object type descriptor at system
    00078     initialization and stores the address of the object type descriptor
    00079     in global storage.
    00080
    00081 Arguments:
    00082
    00083     None.
    00084
    00085 Return Value:
    00086
    00087     A value of TRUE is returned if the event pair object type descriptor is
    00088     successfully initialized. Otherwise a value of FALSE is returned.
    00089
    00090 --*/
    00091
    00092 {
    00093
    00094     OBJECT_TYPE_INITIALIZER ObjectTypeInitializer;
    00095     ULONG Offset = 0;
    00096     NTSTATUS Status;
    00097     UNICODE_STRING TypeName;
    00098
    00099     //
    00100     // Initialize string descriptor.
    00101     //
    00102
    00103     RtlInitUnicodeString(&TypeName, L"EventPair");
    00104
    00105     //
    00106     // Create event object type descriptor.
    00107     //
    00108
    00109     RtlZeroMemory(&ObjectTypeInitializer, sizeof(ObjectTypeInitializer));
    00110     ObjectTypeInitializer.Length = sizeof(ObjectTypeInitializer);
    00111     ObjectTypeInitializer.InvalidAttributes = OBJ_OPENLINK;
    00112     ObjectTypeInitializer.GenericMapping = ExpEventPairMapping;
    00113     ObjectTypeInitializer.PoolType = NonPagedPool;
    00114     ObjectTypeInitializer.DefaultNonPagedPoolCharge = sizeof(EEVENT_PAIR);
    00115     ObjectTypeInitializer.ValidAccessMask = EVENT_PAIR_ALL_ACCESS;
    00116     ObjectTypeInitializer.UseDefaultObject = TRUE;
    00117     Status = ObCreateObjectType(&TypeName,
    00118                                 &ObjectTypeInitializer,
    00119                                 (PSECURITY_DESCRIPTOR)NULL,
    00120                                 &ExEventPairObjectType);
    00121
    00122     //
    00123     // If the event pair object type descriptor was successfully created, then
    00124     // return a value of TRUE. Otherwise return a value of FALSE.
    00125     //
    00126
    00127     return (BOOLEAN)(NT_SUCCESS(Status));
    00128 }
    00129
    00130 NTSTATUS
    00131 NtCreateEventPair (
    00132     OUT PHANDLE EventPairHandle,
    00133     IN ACCESS_MASK DesiredAccess,
    00134     IN POBJECT_ATTRIBUTES ObjectAttributes OPTIONAL
    00135     )
    00136
    00137 /*++
    00138
    00139 Routine Description:
    00140
    00141     This function creates an event pair object, sets it initial state,
    00142     and opens a handle to the object with the specified desired access.
    00143
    00144 Arguments:
    00145
    00146     EventPairHandle - Supplies a pointer to a variable that will receive the
    00147         event pair object handle.
    00148
    00149     DesiredAccess - Supplies the desired types of access for the event
    00150         pair object.
    00151
    00152     ObjectAttributes - Supplies a pointer to an object attributes
    00153         structure.
    00154
    00155 Return Value:
    00156
    00157     TBS
    00158
    00159 --*/
    00160
    00161 {
    00162
    00163     PEEVENT_PAIR EventPair;
    00164     HANDLE Handle;
    00165     KPROCESSOR_MODE PreviousMode;
    00166     NTSTATUS Status;
    00167
    00168     //
    00169     // Establish an exception handler, probe the output handle address, and
    00170     // attempt to create an event object. If the probe fails, then return the
    00171     // exception code as the service status. Otherwise return the status value
    00172     // returned by the object insertion routine.
    00173     //
    00174
    00175     try {
    00176
    00177         //
    00178         // Get previous processor mode and probe output handle address if
    00179         // necessary.
    00180         //
    00181
    00182         PreviousMode = KeGetPreviousMode();
    00183         if (PreviousMode != KernelMode) {
    00184             ProbeForWriteHandle(EventPairHandle);
    00185         }
    00186
    00187         //
    00188         // Allocate event object.
    00189         //
    00190
    00191         Status = ObCreateObject(PreviousMode,
    00192                                 ExEventPairObjectType,
    00193                                 ObjectAttributes,
    00194                                 PreviousMode,
    00195                                 NULL,
    00196                                 sizeof(EEVENT_PAIR),
    00197                                 0,
    00198                                 0,
    00199                                 (PVOID *)&EventPair);
    00200
    00201         //
    00202         // If the event pair object was successfully allocated, then
    00203         // initialize the event pair object and attempt to insert the
    00204         // event pair object in the current process' handle table.
    00205         //
    00206
    00207         if (NT_SUCCESS(Status)) {
    00208             KeInitializeEventPair(&EventPair->KernelEventPair);
    00209             Status = ObInsertObject((PVOID)EventPair,
    00210                                     NULL,
    00211                                     DesiredAccess,
    00212                                     0,
    00213                                     (PVOID *)NULL,
    00214                                     &Handle);
    00215
    00216             //
    00217             // If the event pair object was successfully inserted in the
    00218             // current process' handle table, then attempt to write the
    00219             // event pair object handle value.  If the write attempt
    00220             // fails, then do not report an error.  When the caller
    00221             // attempts to access the handle value, an access violation
    00222             // will occur.
    00223
    00224             if (NT_SUCCESS(Status)) {
    00225                 try {
    00226                     *EventPairHandle = Handle;
    00227
    00228                 } except(ExSystemExceptionFilter()) {
    00229                 }
    00230             }
    00231         }
    00232
    00233         //
    00234         // If an exception occurs during the probe of the output handle address,
    00235         // then always handle the exception and return the exception code as the
    00236         // status value.
    00237         //
    00238
    00239     } except (ExSystemExceptionFilter()) {
    00240         return GetExceptionCode();
    00241     }
    00242
    00243     //
    00244     // Return service status.
    00245     //
    00246
    00247     return Status;
    00248 }
    00249
    00250 NTSTATUS
    00251 NtOpenEventPair(
    00252     OUT PHANDLE EventPairHandle,
    00253     IN ACCESS_MASK DesiredAccess,
    00254     IN POBJECT_ATTRIBUTES ObjectAttributes
    00255     )
    00256
    00257 /*++
    00258
    00259 Routine Description:
    00260
    00261     This function opens a handle to an event pair object with the specified
    00262     desired access.
    00263
    00264 Arguments:
    00265
    00266     EventPairHandle - Supplies a pointer to a variable that will receive
    00267         the event pair object handle.
    00268
    00269     DesiredAccess - Supplies the desired types of access for the event
    00270         pair object.
    00271
    00272     ObjectAttributes - Supplies a pointer to an object attributes structure.
    00273
    00274 Return Value:
    00275
    00276     TBS
    00277
    00278 --*/
    00279
    00280 {
    00281
    00282     HANDLE Handle;
    00283     KPROCESSOR_MODE PreviousMode;
    00284     NTSTATUS Status;
    00285
    00286     //
    00287     // Establish an exception handler, probe the output handle address, and
    00288     // attempt to open the event object. If the probe fails, then return the
    00289     // exception code as the service status. Otherwise return the status value
    00290     // returned by the object open routine.
    00291     //
    00292
    00293     try {
    00294
    00295         //
    00296         // Get previous processor mode and probe output handle address
    00297         // if necessary.
    00298         //
    00299
    00300         PreviousMode = KeGetPreviousMode();
    00301         if (PreviousMode != KernelMode) {
    00302             ProbeForWriteHandle(EventPairHandle);
    00303         }
    00304
    00305         //
    00306         // Open handle to the event pair object with the specified
    00307         // desired access.
    00308         //
    00309
    00310         Status = ObOpenObjectByName(ObjectAttributes,
    00311                                     ExEventPairObjectType,
    00312                                     PreviousMode,
    00313                                     NULL,
    00314                                     DesiredAccess,
    00315                                     NULL,
    00316                                     &Handle);
    00317
    00318
    00319         //
    00320         // If the open was successful, then attempt to write the event
    00321         // pair object handle value.  If the write attempt fails, then do
    00322         // not report an error.  When the caller attempts to access the
    00323         // handle value, an access violation will occur.
    00324         //
    00325
    00326         if (NT_SUCCESS(Status)) {
    00327             try {
    00328                 *EventPairHandle = Handle;
    00329
    00330             } except(ExSystemExceptionFilter()) {
    00331             }
    00332         }
    00333
    00334         //
    00335         // If an exception occurs during the probe of the output event handle,
    00336         // then always handle the exception and return the exception code as the
    00337         // status value.
    00338         //
    00339
    00340     } except (ExSystemExceptionFilter()) {
    00341         return GetExceptionCode();
    00342     }
    00343
    00344     //
    00345     // Return service status.
    00346     //
    00347
    00348     return Status;
    00349 }
    00350
    00351 NTSTATUS
    00352 NtWaitLowEventPair(
    00353     IN HANDLE EventPairHandle
    00354     )
    00355
    00356 /*++
    00357
    00358 Routine Description:
    00359
    00360     This function waits on the low event of an event pair object.
    00361
    00362 Arguments:
    00363
    00364     EventPairHandle - Supplies a handle to an event pair object.
    00365
    00366 Return Value:
    00367
    00368     TBS
    00369
    00370 --*/
    00371
    00372 {
    00373
    00374     PEEVENT_PAIR EventPair;
    00375     KPROCESSOR_MODE PreviousMode;
    00376     NTSTATUS Status;
    00377
    00378     //
    00379     // Reference event pair object by handle.
    00380     //
    00381
    00382     PreviousMode = KeGetPreviousMode();
    00383     Status = ObReferenceObjectByHandle(EventPairHandle,
    00384                                        SYNCHRONIZE,
    00385                                        ExEventPairObjectType,
    00386                                        PreviousMode,
    00387                                        (PVOID *)&EventPair,
    00388                                        NULL);
    00389
    00390     //
    00391     // If the reference was successful, then wait on the Low event
    00392     // of the event pair.
    00393     //
    00394
    00395     if (NT_SUCCESS(Status)) {
    00396         Status = KeWaitForLowEventPair(&EventPair->KernelEventPair,
    00397                                        PreviousMode,
    00398                                        FALSE,
    00399                                        NULL);
    00400
    00401         ObDereferenceObject(EventPair);
    00402     }
    00403
    00404     //
    00405     // Return service status.
    00406     //
    00407
    00408     return Status;
    00409 }
    00410
    00411 NTSTATUS
    00412 NtWaitHighEventPair(
    00413     IN HANDLE EventPairHandle
    00414     )
    00415
    00416 /*++
    00417
    00418 Routine Description:
    00419
    00420     This function waits on the high event of an event pair object.
    00421
    00422 Arguments:
    00423
    00424     EventPairHandle - Supplies a handle to an event pair object.
    00425
    00426 Return Value:
    00427
    00428     TBS
    00429
    00430 --*/
    00431
    00432 {
    00433
    00434     PEEVENT_PAIR EventPair;
    00435     KPROCESSOR_MODE PreviousMode;
    00436     NTSTATUS Status;
    00437
    00438     //
    00439     // Reference event pair object by handle.
    00440     //
    00441
    00442     PreviousMode = KeGetPreviousMode();
    00443     Status = ObReferenceObjectByHandle(EventPairHandle,
    00444                                        SYNCHRONIZE,
    00445                                        ExEventPairObjectType,
    00446                                        PreviousMode,
    00447                                        (PVOID *)&EventPair,
    00448                                        NULL);
    00449
    00450     //
    00451     // If the reference was successful, then wait on the Low event
    00452     // of the event pair.
    00453     //
    00454
    00455     if (NT_SUCCESS(Status)) {
    00456         Status = KeWaitForHighEventPair(&EventPair->KernelEventPair,
    00457                                         PreviousMode,
    00458                                         FALSE,
    00459                                         NULL);
    00460
    00461         ObDereferenceObject(EventPair);
    00462     }
    00463
    00464     //
    00465     // Return service status.
    00466     //
    00467
    00468     return Status;
    00469 }
    00470
    00471 NTSTATUS
    00472 NtSetLowWaitHighEventPair(
    00473     IN HANDLE EventPairHandle
    00474     )
    00475
    00476 /*++
    00477
    00478 Routine Description:
    00479
    00480     This function sets the low event of an event pair and then
    00481     waits on the high event of an event pair object.
    00482
    00483 Arguments:
    00484
    00485     EventPairHandle - Supplies a handle to an event pair object.
    00486
    00487 Return Value:
    00488
    00489     TBS
    00490
    00491 --*/
    00492
    00493 {
    00494
    00495     PEEVENT_PAIR EventPair;
    00496     KPROCESSOR_MODE PreviousMode;
    00497     NTSTATUS Status;
    00498
    00499     //
    00500     // Reference event pair object by handle.
    00501     //
    00502
    00503     PreviousMode = KeGetPreviousMode();
    00504     Status = ObReferenceObjectByHandle(EventPairHandle,
    00505                                        SYNCHRONIZE,
    00506                                        ExEventPairObjectType,
    00507                                        PreviousMode,
    00508                                        (PVOID *)&EventPair,
    00509                                        NULL);
    00510
    00511     //
    00512     // If the reference was successful, then wait on the Low event
    00513     // of the event pair.
    00514     //
    00515
    00516     if (NT_SUCCESS(Status)) {
    00517         EvPrSetLow++;
    00518         Status = KeSetLowWaitHighEventPair(&EventPair->KernelEventPair,
    00519                                            PreviousMode);
    00520
    00521         ObDereferenceObject(EventPair);
    00522     }
    00523
    00524     //
    00525     // Return service status.
    00526     //
    00527
    00528     return Status;
    00529 }
    00530
    00531 NTSTATUS
    00532 NtSetHighWaitLowEventPair(
    00533     IN HANDLE EventPairHandle
    00534     )
    00535
    00536 /*++
    00537
    00538 Routine Description:
    00539
    00540     This function sets the high event of an event pair and then
    00541     waits on the low event of an event pair object.
    00542
    00543 Arguments:
    00544
    00545     EventPairHandle - Supplies a handle to an event pair object.
    00546
    00547 Return Value:
    00548
    00549     TBS
    00550
    00551 --*/
    00552
    00553 {
    00554
    00555     PEEVENT_PAIR EventPair;
    00556     KPROCESSOR_MODE PreviousMode;
    00557     NTSTATUS Status;
    00558
    00559     //
    00560     // Reference event pair object by handle.
    00561     //
    00562
    00563     PreviousMode = KeGetPreviousMode();
    00564     Status = ObReferenceObjectByHandle(EventPairHandle,
    00565                                        SYNCHRONIZE,
    00566                                        ExEventPairObjectType,
    00567                                        PreviousMode,
    00568                                        (PVOID *)&EventPair,
    00569                                        NULL);
    00570
    00571     //
    00572     // If the reference was successful, then wait on the Low event
    00573     // of the event pair.
    00574     //
    00575
    00576     if (NT_SUCCESS(Status)) {
    00577         EvPrSetHigh++;
    00578         Status = KeSetHighWaitLowEventPair(&EventPair->KernelEventPair,
    00579                                            PreviousMode);
    00580
    00581         ObDereferenceObject(EventPair);
    00582     }
    00583
    00584     //
    00585     // Return service status.
    00586     //
    00587
    00588     return Status;
    00589 }
    00590
    00591 NTSTATUS
    00592 NtSetLowEventPair(
    00593     IN HANDLE EventPairHandle
    00594     )
    00595
    00596 /*++
    00597
    00598 Routine Description:
    00599
    00600     This function sets the low event of an event pair object.
    00601
    00602 Arguments:
    00603
    00604     EventPairHandle - Supplies a handle to an event pair object.
    00605
    00606 Return Value:
    00607
    00608     TBS
    00609
    00610 --*/
    00611
    00612 {
    00613
    00614     PEEVENT_PAIR EventPair;
    00615     KPROCESSOR_MODE PreviousMode;
    00616     NTSTATUS Status;
    00617
    00618     //
    00619     // Reference event pair object by handle.
    00620     //
    00621
    00622     PreviousMode = KeGetPreviousMode();
    00623     Status = ObReferenceObjectByHandle(EventPairHandle,
    00624                                        SYNCHRONIZE,
    00625                                        ExEventPairObjectType,
    00626                                        PreviousMode,
    00627                                        (PVOID *)&EventPair,
    00628                                        NULL);
    00629
    00630     //
    00631     // If the reference was successful, then wait on the Low event
    00632     // of the event pair.
    00633     //
    00634
    00635     if (NT_SUCCESS(Status)) {
    00636         EvPrSetLow++;
    00637         KeSetLowEventPair(&EventPair->KernelEventPair,
    00638                           EVENT_PAIR_INCREMENT,FALSE);
    00639
    00640         ObDereferenceObject(EventPair);
    00641     }
    00642
    00643     //
    00644     // Return service status.
    00645     //
    00646
    00647     return Status;
    00648 }
    00649
    00650 NTSTATUS
    00651 NtSetHighEventPair(
    00652     IN HANDLE EventPairHandle
    00653     )
    00654
    00655 /*++
    00656
    00657 Routine Description:
    00658
    00659     This function sets the high event of an event pair object.
    00660
    00661 Arguments:
    00662
    00663     EventPairHandle - Supplies a handle to an event pair object.
    00664
    00665 Return Value:
    00666
    00667     TBS
    00668
    00669 --*/
    00670
    00671 {
    00672
    00673     PEEVENT_PAIR EventPair;
    00674     KPROCESSOR_MODE PreviousMode;
    00675     NTSTATUS Status;
    00676
    00677     //
    00678     // Reference event pair object by handle.
    00679     //
    00680
    00681     PreviousMode = KeGetPreviousMode();
    00682     Status = ObReferenceObjectByHandle(EventPairHandle,
    00683                                        SYNCHRONIZE,
    00684                                        ExEventPairObjectType,
    00685                                        PreviousMode,
    00686                                        (PVOID *)&EventPair,
    00687                                        NULL);
    00688
    00689     //
    00690     // If the reference was successful, then wait on the Low event
    00691     // of the event pair.
    00692     //
    00693
    00694     if (NT_SUCCESS(Status)) {
    00695         EvPrSetHigh++;
    00696         KeSetHighEventPair(&EventPair->KernelEventPair,
    00697                            EVENT_PAIR_INCREMENT,FALSE);
    00698
    00699         ObDereferenceObject(EventPair);
    00700     }
    00701
    00702     //
    00703     // Return service status.
    00704     //
    00705
    00706     return Status;
    00707 }