00001 
00002 
00003 
00004 
00005 
00006 
00007 
00008 
00009 
00010 
00011 
00012 
00013 
00014 
00015 
00016 
00017 
00018 
00019 
00020 
00021 
00022 
00023 
00024 
00025 
00026 
#include "exp.h"
00027 
00028 
00029 
00030 
00031 
00032 ULONG 
ExpSemaphoreBoost = 
SEMAPHORE_INCREMENT;
00033 
00034 
00035 
00036 
00037 
00038 POBJECT_TYPE ExSemaphoreObjectType;
00039 
00040 
00041 
00042 
00043 
00044 
00045 GENERIC_MAPPING 
ExpSemaphoreMapping = {
00046     STANDARD_RIGHTS_READ |
00047         SEMAPHORE_QUERY_STATE,
00048     STANDARD_RIGHTS_WRITE |
00049         SEMAPHORE_MODIFY_STATE,
00050     STANDARD_RIGHTS_EXECUTE |
00051         SYNCHRONIZE,
00052     SEMAPHORE_ALL_ACCESS
00053 };
00054 
00055 
#ifdef ALLOC_PRAGMA
00056 
#pragma alloc_text(INIT, ExpSemaphoreInitialization)
00057 
#pragma alloc_text(PAGE, NtCreateSemaphore)
00058 
#pragma alloc_text(PAGE, NtOpenSemaphore)
00059 
#pragma alloc_text(PAGE, NtQuerySemaphore)
00060 
#pragma alloc_text(PAGE, NtReleaseSemaphore)
00061 
#endif
00062 
00063 BOOLEAN
00064 ExpSemaphoreInitialization (
00065     )
00066 
00067 
00068 
00069 
00070 
00071 
00072 
00073 
00074 
00075 
00076 
00077 
00078 
00079 
00080 
00081 
00082 
00083 
00084 
00085 
00086 {
00087 
00088     
OBJECT_TYPE_INITIALIZER ObjectTypeInitializer;
00089     
NTSTATUS Status;
00090     UNICODE_STRING TypeName;
00091 
00092     
00093     
00094     
00095 
00096     
RtlInitUnicodeString(&TypeName, 
L"Semaphore");
00097 
00098     
00099     
00100     
00101 
00102     RtlZeroMemory(&ObjectTypeInitializer, 
sizeof(ObjectTypeInitializer));
00103     ObjectTypeInitializer.Length = 
sizeof(ObjectTypeInitializer);
00104     ObjectTypeInitializer.InvalidAttributes = OBJ_OPENLINK;
00105     ObjectTypeInitializer.GenericMapping = 
ExpSemaphoreMapping;
00106     ObjectTypeInitializer.PoolType = 
NonPagedPool;
00107     ObjectTypeInitializer.DefaultNonPagedPoolCharge = 
sizeof(
KSEMAPHORE);
00108     ObjectTypeInitializer.ValidAccessMask = SEMAPHORE_ALL_ACCESS;
00109     
Status = 
ObCreateObjectType(&TypeName,
00110                                 &ObjectTypeInitializer,
00111                                 (PSECURITY_DESCRIPTOR)
NULL,
00112                                 &
ExSemaphoreObjectType);
00113 
00114     
00115     
00116     
00117     
00118 
00119     
return (BOOLEAN)(
NT_SUCCESS(
Status));
00120 }
00121 
00122 
NTSTATUS
00123 NtCreateSemaphore (
00124     IN PHANDLE SemaphoreHandle,
00125     IN ACCESS_MASK DesiredAccess,
00126     IN POBJECT_ATTRIBUTES ObjectAttributes OPTIONAL,
00127     IN LONG InitialCount,
00128     IN LONG MaximumCount
00129     )
00130 
00131 
00132 
00133 
00134 
00135 
00136 
00137 
00138 
00139 
00140 
00141 
00142 
00143 
00144 
00145 
00146 
00147 
00148 
00149 
00150 
00151 
00152 
00153 
00154 
00155 
00156 
00157 
00158 
00159 {
00160 
00161     HANDLE 
Handle;
00162     
KPROCESSOR_MODE PreviousMode;
00163     PVOID Semaphore;
00164     
NTSTATUS Status;
00165 
00166     
00167     
00168     
00169     
00170     
00171     
00172 
00173     
try {
00174 
00175         
00176         
00177         
00178         
00179 
00180         PreviousMode = KeGetPreviousMode();
00181         
if (PreviousMode != 
KernelMode) {
00182             
ProbeForWriteHandle(SemaphoreHandle);
00183         }
00184 
00185         
00186         
00187         
00188 
00189         
if ((MaximumCount <= 0) || (InitialCount < 0) ||
00190            (InitialCount > MaximumCount)) {
00191             
return STATUS_INVALID_PARAMETER;
00192         }
00193 
00194         
00195         
00196         
00197 
00198         
Status = 
ObCreateObject(PreviousMode,
00199                                 
ExSemaphoreObjectType,
00200                                 
ObjectAttributes,
00201                                 PreviousMode,
00202                                 
NULL,
00203                                 
sizeof(
KSEMAPHORE),
00204                                 0,
00205                                 0,
00206                                 (PVOID *)&Semaphore);
00207 
00208         
00209         
00210         
00211         
00212         
00213 
00214         
if (
NT_SUCCESS(
Status)) {
00215             
KeInitializeSemaphore((
PKSEMAPHORE)Semaphore,
00216                                   InitialCount,
00217                                   MaximumCount);
00218 
00219             
Status = 
ObInsertObject(Semaphore,
00220                                     
NULL,
00221                                     DesiredAccess,
00222                                     0,
00223                                     (PVOID *)
NULL,
00224                                     &
Handle);
00225 
00226             
00227             
00228             
00229             
00230             
00231             
00232             
00233 
00234             
if (
NT_SUCCESS(
Status)) {
00235                 
try {
00236                     *SemaphoreHandle = 
Handle;
00237                 } except(
ExSystemExceptionFilter()) {
00238                 }
00239             }
00240         }
00241 
00242     
00243     
00244     
00245     
00246     
00247 
00248     } except(
ExSystemExceptionFilter()) {
00249         
return GetExceptionCode();
00250     }
00251 
00252     
00253     
00254     
00255 
00256     
return Status;
00257 }
00258 
00259 
NTSTATUS
00260 NtOpenSemaphore (
00261     OUT PHANDLE SemaphoreHandle,
00262     IN ACCESS_MASK DesiredAccess,
00263     IN POBJECT_ATTRIBUTES ObjectAttributes
00264     )
00265 
00266 
00267 
00268 
00269 
00270 
00271 
00272 
00273 
00274 
00275 
00276 
00277 
00278 
00279 
00280 
00281 
00282 
00283 
00284 
00285 
00286 
00287 
00288 
00289 {
00290 
00291     HANDLE 
Handle;
00292     
KPROCESSOR_MODE PreviousMode;
00293     
NTSTATUS Status;
00294 
00295 
00296     
00297     
00298     
00299     
00300     
00301     
00302 
00303     
try {
00304 
00305         
00306         
00307         
00308         
00309 
00310         PreviousMode = KeGetPreviousMode();
00311         
if (PreviousMode != 
KernelMode) {
00312             
ProbeForWriteHandle(SemaphoreHandle);
00313         }
00314 
00315         
00316         
00317         
00318 
00319         
Status = 
ObOpenObjectByName(
ObjectAttributes,
00320                                     
ExSemaphoreObjectType,
00321                                     PreviousMode,
00322                                     
NULL,
00323                                     DesiredAccess,
00324                                     
NULL,
00325                                     &
Handle);
00326 
00327         
00328         
00329         
00330         
00331         
00332         
00333 
00334         
if (
NT_SUCCESS(
Status)) {
00335             
try {
00336                 *SemaphoreHandle = 
Handle;
00337             } except(
ExSystemExceptionFilter()) {
00338             }
00339         }
00340 
00341     
00342     
00343     
00344     
00345     
00346 
00347     } except(
ExSystemExceptionFilter()) {
00348         
return GetExceptionCode();
00349     }
00350 
00351 
00352     
00353     
00354     
00355 
00356     
return Status;
00357 }
00358 
00359 
NTSTATUS
00360 NtQuerySemaphore (
00361     IN HANDLE SemaphoreHandle,
00362     IN SEMAPHORE_INFORMATION_CLASS SemaphoreInformationClass,
00363     OUT PVOID SemaphoreInformation,
00364     IN ULONG SemaphoreInformationLength,
00365     OUT PULONG ReturnLength OPTIONAL
00366     )
00367 
00368 
00369 
00370 
00371 
00372 
00373 
00374 
00375 
00376 
00377 
00378 
00379 
00380 
00381 
00382 
00383 
00384 
00385 
00386 
00387 
00388 
00389 
00390 
00391 
00392 
00393 
00394 
00395 
00396 
00397 {
00398 
00399     PVOID Semaphore;
00400     LONG 
Count;
00401     LONG Maximum;
00402     
KPROCESSOR_MODE PreviousMode;
00403     
NTSTATUS Status;
00404 
00405     
00406     
00407     
00408     
00409     
00410     
00411     
00412 
00413     
try {
00414 
00415         
00416         
00417         
00418 
00419         PreviousMode = KeGetPreviousMode();
00420         
if (PreviousMode != 
KernelMode) {
00421             
ProbeForWrite(SemaphoreInformation,
00422                           
sizeof(SEMAPHORE_BASIC_INFORMATION),
00423                           
sizeof(ULONG));
00424 
00425             
if (ARGUMENT_PRESENT(ReturnLength)) {
00426                 
ProbeForWriteUlong(ReturnLength);
00427             }
00428         }
00429 
00430         
00431         
00432         
00433 
00434         
if (SemaphoreInformationClass != SemaphoreBasicInformation) {
00435             
return STATUS_INVALID_INFO_CLASS;
00436         }
00437         
if (SemaphoreInformationLength != 
sizeof(SEMAPHORE_BASIC_INFORMATION)) {
00438             
return STATUS_INFO_LENGTH_MISMATCH;
00439         }
00440 
00441         
00442         
00443         
00444 
00445         
Status = 
ObReferenceObjectByHandle(SemaphoreHandle,
00446                                            SEMAPHORE_QUERY_STATE,
00447                                            
ExSemaphoreObjectType,
00448                                            PreviousMode,
00449                                            &Semaphore,
00450                                            
NULL);
00451 
00452         
00453         
00454         
00455         
00456         
00457         
00458         
00459         
00460         
00461 
00462         
if (
NT_SUCCESS(
Status)) {
00463             
Count = 
KeReadStateSemaphore((
PKSEMAPHORE)Semaphore);
00464             Maximum = ((
PKSEMAPHORE)Semaphore)->Limit;
00465             
ObDereferenceObject(Semaphore);
00466             
try {
00467                 ((PSEMAPHORE_BASIC_INFORMATION)SemaphoreInformation)->CurrentCount = 
Count;
00468                 ((PSEMAPHORE_BASIC_INFORMATION)SemaphoreInformation)->MaximumCount = Maximum;
00469                 
if (ARGUMENT_PRESENT(ReturnLength)) {
00470                     *ReturnLength = 
sizeof(SEMAPHORE_BASIC_INFORMATION);
00471                 }
00472             } except(
ExSystemExceptionFilter()) {
00473             }
00474         }
00475 
00476     
00477     
00478     
00479     
00480     
00481 
00482     } except(
ExSystemExceptionFilter()) {
00483         
return GetExceptionCode();
00484     }
00485 
00486     
00487     
00488     
00489 
00490     
return Status;
00491 }
00492 
00493 
NTSTATUS
00494 NtReleaseSemaphore (
00495     IN HANDLE SemaphoreHandle,
00496     IN LONG ReleaseCount,
00497     OUT PLONG PreviousCount OPTIONAL
00498     )
00499 
00500 
00501 
00502 
00503 
00504 
00505 
00506 
00507 
00508 
00509 
00510 
00511 
00512 
00513 
00514 
00515 
00516 
00517 
00518 
00519 
00520 
00521 
00522 
00523 {
00524 
00525     LONG 
Count;
00526     PVOID Semaphore;
00527     
KPROCESSOR_MODE PreviousMode;
00528     
NTSTATUS Status;
00529 
00530     
00531     
00532     
00533     
00534     
00535     
00536     
00537 
00538     
try {
00539 
00540         
00541         
00542         
00543         
00544 
00545         PreviousMode = KeGetPreviousMode();
00546         
if ((PreviousMode != 
KernelMode) && (ARGUMENT_PRESENT(PreviousCount))) {
00547             
ProbeForWriteLong(PreviousCount);
00548         }
00549 
00550         
00551         
00552         
00553 
00554         
if (ReleaseCount <= 0) {
00555             
return STATUS_INVALID_PARAMETER;
00556         }
00557 
00558         
00559         
00560         
00561 
00562         
Status = 
ObReferenceObjectByHandle(SemaphoreHandle,
00563                                            SEMAPHORE_MODIFY_STATE,
00564                                            
ExSemaphoreObjectType,
00565                                            PreviousMode,
00566                                            &Semaphore,
00567                                            
NULL);
00568 
00569         
00570         
00571         
00572         
00573         
00574         
00575         
00576         
00577         
00578 
00579         
if (
NT_SUCCESS(
Status)) {
00580             
try {
00581                 
Count = 
KeReleaseSemaphore((
PKSEMAPHORE)Semaphore,
00582                                            
ExpSemaphoreBoost,
00583                                            ReleaseCount,
00584                                            
FALSE);
00585 
00586                 
ObDereferenceObject(Semaphore);
00587                 
if (ARGUMENT_PRESENT(PreviousCount)) {
00588                     
try {
00589                         *PreviousCount = 
Count;
00590                     } except(
ExSystemExceptionFilter()) {
00591                     }
00592                 }
00593             } except(
ExSystemExceptionFilter()) {
00594                 
ObDereferenceObject(Semaphore);
00595                 
return GetExceptionCode();
00596             }
00597         }
00598 
00599     
00600     
00601     
00602     
00603     
00604 
00605     } except(
ExSystemExceptionFilter()) {
00606         
return GetExceptionCode();
00607     }
00608 
00609     
00610     
00611     
00612 
00613     
return Status;
00614 }