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