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 }