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

semphore.c File Reference

#include "exp.h"

Go to the source code of this file.

Functions

BOOLEAN ExpSemaphoreInitialization ()
NTSTATUS NtCreateSemaphore (IN PHANDLE SemaphoreHandle, IN ACCESS_MASK DesiredAccess, IN POBJECT_ATTRIBUTES ObjectAttributes OPTIONAL, IN LONG InitialCount, IN LONG MaximumCount)
NTSTATUS NtOpenSemaphore (OUT PHANDLE SemaphoreHandle, IN ACCESS_MASK DesiredAccess, IN POBJECT_ATTRIBUTES ObjectAttributes)
NTSTATUS NtQuerySemaphore (IN HANDLE SemaphoreHandle, IN SEMAPHORE_INFORMATION_CLASS SemaphoreInformationClass, OUT PVOID SemaphoreInformation, IN ULONG SemaphoreInformationLength, OUT PULONG ReturnLength OPTIONAL)
NTSTATUS NtReleaseSemaphore (IN HANDLE SemaphoreHandle, IN LONG ReleaseCount, OUT PLONG PreviousCount OPTIONAL)

Variables

ULONG ExpSemaphoreBoost = SEMAPHORE_INCREMENT
POBJECT_TYPE ExSemaphoreObjectType
GENERIC_MAPPING ExpSemaphoreMapping


Function Documentation

BOOLEAN ExpSemaphoreInitialization  ) 
 

Definition at line 64 of file semphore.c.

References ExpSemaphoreMapping, ExSemaphoreObjectType, L, NonPagedPool, NT_SUCCESS, NTSTATUS(), NULL, ObCreateObjectType(), RtlInitUnicodeString(), and Status.

00069 : 00070 00071 This function creates the semaphore object type descriptor at system 00072 initialization and stores the address of the object type descriptor 00073 in local static storage. 00074 00075 Arguments: 00076 00077 None. 00078 00079 Return Value: 00080 00081 A value of TRUE is returned if the semaphore object type descriptor is 00082 successfully created. Otherwise a value of FALSE is returned. 00083 00084 --*/ 00085 00086 { 00087 00088 OBJECT_TYPE_INITIALIZER ObjectTypeInitializer; 00089 NTSTATUS Status; 00090 UNICODE_STRING TypeName; 00091 00092 // 00093 // Initialize string descriptor. 00094 // 00095 00096 RtlInitUnicodeString(&TypeName, L"Semaphore"); 00097 00098 // 00099 // Create semaphore object type descriptor. 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 // If the semaphore object type descriptor was successfully created, then 00116 // return a value of TRUE. Otherwise return a value of FALSE. 00117 // 00118 00119 return (BOOLEAN)(NT_SUCCESS(Status)); 00120 }

NTSTATUS NtCreateSemaphore IN PHANDLE  SemaphoreHandle,
IN ACCESS_MASK  DesiredAccess,
IN POBJECT_ATTRIBUTES ObjectAttributes  OPTIONAL,
IN LONG  InitialCount,
IN LONG  MaximumCount
 

Definition at line 123 of file semphore.c.

References ExSemaphoreObjectType, ExSystemExceptionFilter(), Handle, KeInitializeSemaphore(), KernelMode, KPROCESSOR_MODE, NT_SUCCESS, NTSTATUS(), NULL, ObCreateObject(), ObInsertObject(), ObjectAttributes, ProbeForWriteHandle, and Status.

Referenced by RtlInitializeResource().

00133 : 00134 00135 This function creates a semaphore object, sets its initial count to the 00136 specified value, sets its maximum count to the specified value, and opens 00137 a handle to the object with the specified desired access. 00138 00139 Arguments: 00140 00141 SemaphoreHandle - Supplies a pointer to a variable that will receive the 00142 semaphore object handle. 00143 00144 DesiredAccess - Supplies the desired types of access for the semaphore 00145 object. 00146 00147 ObjectAttributes - Supplies a pointer to an object attributes structure. 00148 00149 InitialCount - Supplies the initial count of the semaphore object. 00150 00151 MaximumCount - Supplies the maximum count of the semaphore object. 00152 00153 Return Value: 00154 00155 TBS 00156 00157 --*/ 00158 00159 { 00160 00161 HANDLE Handle; 00162 KPROCESSOR_MODE PreviousMode; 00163 PVOID Semaphore; 00164 NTSTATUS Status; 00165 00166 // 00167 // Establish an exception handler, probe the output handle address, and 00168 // attempt to create a semaphore object. If the probe fails, then return 00169 // the exception code as the service status. Otherwise return the status 00170 // value returned by the object insertion routine. 00171 // 00172 00173 try { 00174 00175 // 00176 // Get previous processor mode and probe output handle address if 00177 // necessary. 00178 // 00179 00180 PreviousMode = KeGetPreviousMode(); 00181 if (PreviousMode != KernelMode) { 00182 ProbeForWriteHandle(SemaphoreHandle); 00183 } 00184 00185 // 00186 // Check argument validity. 00187 // 00188 00189 if ((MaximumCount <= 0) || (InitialCount < 0) || 00190 (InitialCount > MaximumCount)) { 00191 return STATUS_INVALID_PARAMETER; 00192 } 00193 00194 // 00195 // Allocate semaphore object. 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 // If the semaphore object was successfully allocated, then initialize 00210 // the semaphore object and attempt to insert the semaphore object in 00211 // the current process' handle table. 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 // If the semaphore object was successfully inserted in the current 00228 // process' handle table, then attempt to write the semaphore handle 00229 // value. If the write attempt fails, then do not report an error. 00230 // When the caller attempts to access the handle value, an access 00231 // violation will occur. 00232 // 00233 00234 if (NT_SUCCESS(Status)) { 00235 try { 00236 *SemaphoreHandle = Handle; 00237 } except(ExSystemExceptionFilter()) { 00238 } 00239 } 00240 } 00241 00242 // 00243 // If an exception occurs during the probe of the output handle address, 00244 // then always handle the exception and return the exception code as the 00245 // status value. 00246 // 00247 00248 } except(ExSystemExceptionFilter()) { 00249 return GetExceptionCode(); 00250 } 00251 00252 // 00253 // Return service status. 00254 // 00255 00256 return Status; 00257 }

NTSTATUS NtOpenSemaphore OUT PHANDLE  SemaphoreHandle,
IN ACCESS_MASK  DesiredAccess,
IN POBJECT_ATTRIBUTES  ObjectAttributes
 

Definition at line 260 of file semphore.c.

References ExSemaphoreObjectType, ExSystemExceptionFilter(), Handle, KernelMode, KPROCESSOR_MODE, NT_SUCCESS, NTSTATUS(), NULL, ObjectAttributes, ObOpenObjectByName(), ProbeForWriteHandle, and Status.

00268 : 00269 00270 This function opens a handle to a semaphore object with the specified 00271 desired access. 00272 00273 Arguments: 00274 00275 SemaphoreHandle - Supplies a pointer to a variable that will receive the 00276 semaphore object handle. 00277 00278 DesiredAccess - Supplies the desired types of access for the semaphore 00279 object. 00280 00281 ObjectAttributes - Supplies a pointer to an object attributes structure. 00282 00283 Return Value: 00284 00285 TBS 00286 00287 --*/ 00288 00289 { 00290 00291 HANDLE Handle; 00292 KPROCESSOR_MODE PreviousMode; 00293 NTSTATUS Status; 00294 00295 00296 // 00297 // Establish an exception handler, probe the output handle address, and 00298 // attempt to open a semaphore object. If the probe fails, then return 00299 // the exception code as the service status. Otherwise return the status 00300 // value returned by the object open routine. 00301 // 00302 00303 try { 00304 00305 // 00306 // Get previous processor mode and probe output handle address if 00307 // necessary. 00308 // 00309 00310 PreviousMode = KeGetPreviousMode(); 00311 if (PreviousMode != KernelMode) { 00312 ProbeForWriteHandle(SemaphoreHandle); 00313 } 00314 00315 // 00316 // Open handle to the semaphore object with the specified desired access. 00317 // 00318 00319 Status = ObOpenObjectByName(ObjectAttributes, 00320 ExSemaphoreObjectType, 00321 PreviousMode, 00322 NULL, 00323 DesiredAccess, 00324 NULL, 00325 &Handle); 00326 00327 // 00328 // If the open was successful, then attempt to write the semaphore 00329 // object handle value. If the write attempt fails, then do not report 00330 // an error. When the caller attempts to access the handle value, an 00331 // access violation will occur. 00332 // 00333 00334 if (NT_SUCCESS(Status)) { 00335 try { 00336 *SemaphoreHandle = Handle; 00337 } except(ExSystemExceptionFilter()) { 00338 } 00339 } 00340 00341 // 00342 // If an exception occurs during the probe of the output handle address, 00343 // then always handle the exception and return the exception code as the 00344 // status value. 00345 // 00346 00347 } except(ExSystemExceptionFilter()) { 00348 return GetExceptionCode(); 00349 } 00350 00351 00352 // 00353 // Return service status. 00354 // 00355 00356 return Status; 00357 }

NTSTATUS NtQuerySemaphore IN HANDLE  SemaphoreHandle,
IN SEMAPHORE_INFORMATION_CLASS  SemaphoreInformationClass,
OUT PVOID  SemaphoreInformation,
IN ULONG  SemaphoreInformationLength,
OUT PULONG ReturnLength  OPTIONAL
 

Definition at line 360 of file semphore.c.

References Count, ExSemaphoreObjectType, ExSystemExceptionFilter(), KeReadStateSemaphore(), KernelMode, KPROCESSOR_MODE, NT_SUCCESS, NTSTATUS(), NULL, ObDereferenceObject, ObReferenceObjectByHandle(), ProbeForWrite(), ProbeForWriteUlong, and Status.

00370 : 00371 00372 This function queries the state of a semaphore object and returns the 00373 requested information in the specified record structure. 00374 00375 Arguments: 00376 00377 SemaphoreHandle - Supplies a handle to a semaphore object. 00378 00379 SemaphoreInformationClass - Supplies the class of information being 00380 requested. 00381 00382 SemaphoreInformation - Supplies a pointer to a record that is to receive 00383 the requested information. 00384 00385 SemaphoreInformationLength - Supplies the length of the record that is 00386 to receive the requested information. 00387 00388 ReturnLength - Supplies an optional pointer to a variable that will 00389 receive the actual length of the information that is returned. 00390 00391 Return Value: 00392 00393 TBS 00394 00395 --*/ 00396 00397 { 00398 00399 PVOID Semaphore; 00400 LONG Count; 00401 LONG Maximum; 00402 KPROCESSOR_MODE PreviousMode; 00403 NTSTATUS Status; 00404 00405 // 00406 // Establish an exception handler, probe the output arguments, reference 00407 // the semaphore object, and return the specified information. If the probe 00408 // fails, then return the exception code as the service status. Otherwise 00409 // return the status value returned by the reference object by handle 00410 // routine. 00411 // 00412 00413 try { 00414 00415 // 00416 // Get previous processor mode and probe output arguments if necessary. 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 // Check argument validity. 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 // Reference semaphore object by handle. 00443 // 00444 00445 Status = ObReferenceObjectByHandle(SemaphoreHandle, 00446 SEMAPHORE_QUERY_STATE, 00447 ExSemaphoreObjectType, 00448 PreviousMode, 00449 &Semaphore, 00450 NULL); 00451 00452 // 00453 // If the reference was successful, then read the current state and 00454 // maximum count of the semaphore object, dereference semaphore object, 00455 // fill in the information structure, and return the length of the 00456 // information structure if specified. If the write of the semaphore 00457 // information or the return length fails, then do not report an error. 00458 // When the caller accesses the information structure or length an 00459 // access violation will occur. 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 // If an exception occurs during the probe of the output arguments, then 00478 // always handle the exception and return the exception code as the status 00479 // value. 00480 // 00481 00482 } except(ExSystemExceptionFilter()) { 00483 return GetExceptionCode(); 00484 } 00485 00486 // 00487 // Return service status. 00488 // 00489 00490 return Status; 00491 }

NTSTATUS NtReleaseSemaphore IN HANDLE  SemaphoreHandle,
IN LONG  ReleaseCount,
OUT PLONG PreviousCount  OPTIONAL
 

Definition at line 494 of file semphore.c.

References Count, ExpSemaphoreBoost, ExSemaphoreObjectType, ExSystemExceptionFilter(), FALSE, KeReleaseSemaphore(), KernelMode, KPROCESSOR_MODE, NT_SUCCESS, NTSTATUS(), NULL, ObDereferenceObject, ObReferenceObjectByHandle(), ProbeForWriteLong, and Status.

Referenced by RtlConvertExclusiveToShared(), and RtlReleaseResource().

00502 : 00503 00504 This function releases a semaphore object by adding the specified release 00505 count to the current value. 00506 00507 Arguments: 00508 00509 Semaphore - Supplies a handle to a semaphore object. 00510 00511 ReleaseCount - Supplies the release count that is to be added to the 00512 current semaphore count. 00513 00514 PreviousCount - Supplies an optional pointer to a variable that will 00515 receive the previous semaphore count. 00516 00517 Return Value: 00518 00519 TBS 00520 00521 --*/ 00522 00523 { 00524 00525 LONG Count; 00526 PVOID Semaphore; 00527 KPROCESSOR_MODE PreviousMode; 00528 NTSTATUS Status; 00529 00530 // 00531 // Establish an exception handler, probe the previous count address if 00532 // specified, reference the semaphore object, and release the semaphore 00533 // object. If the probe fails, then return the exception code as the 00534 // service status. Otherwise return the status value returned by the 00535 // reference object by handle routine. 00536 // 00537 00538 try { 00539 00540 // 00541 // Get previous processor mode and probe previous count address 00542 // if necessary. 00543 // 00544 00545 PreviousMode = KeGetPreviousMode(); 00546 if ((PreviousMode != KernelMode) && (ARGUMENT_PRESENT(PreviousCount))) { 00547 ProbeForWriteLong(PreviousCount); 00548 } 00549 00550 // 00551 // Check argument validity. 00552 // 00553 00554 if (ReleaseCount <= 0) { 00555 return STATUS_INVALID_PARAMETER; 00556 } 00557 00558 // 00559 // Reference semaphore object by handle. 00560 // 00561 00562 Status = ObReferenceObjectByHandle(SemaphoreHandle, 00563 SEMAPHORE_MODIFY_STATE, 00564 ExSemaphoreObjectType, 00565 PreviousMode, 00566 &Semaphore, 00567 NULL); 00568 00569 // 00570 // If the reference was successful, then release the semaphore object. 00571 // If an exception occurs because the maximum count of the semaphore 00572 // has been exceeded, then dereference the semaphore object and return 00573 // the exception code as the service status. Otherwise write the previous 00574 // count value if specified. If the write of the previous count fails, 00575 // then do not report an error. When the caller attempts to access the 00576 // previous count value, an access violation will occur. 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 // If an exception occurs during the probe of the previous count, then 00601 // always handle the exception and return the exception code as the status 00602 // value. 00603 // 00604 00605 } except(ExSystemExceptionFilter()) { 00606 return GetExceptionCode(); 00607 } 00608 00609 // 00610 // Return service status. 00611 // 00612 00613 return Status; 00614 } }


Variable Documentation

ULONG ExpSemaphoreBoost = SEMAPHORE_INCREMENT
 

Definition at line 32 of file semphore.c.

Referenced by NtReleaseSemaphore().

GENERIC_MAPPING ExpSemaphoreMapping
 

Initial value:

{ STANDARD_RIGHTS_READ | SEMAPHORE_QUERY_STATE, STANDARD_RIGHTS_WRITE | SEMAPHORE_MODIFY_STATE, STANDARD_RIGHTS_EXECUTE | SYNCHRONIZE, SEMAPHORE_ALL_ACCESS }

Definition at line 45 of file semphore.c.

Referenced by ExpSemaphoreInitialization().

POBJECT_TYPE ExSemaphoreObjectType
 

Definition at line 38 of file semphore.c.

Referenced by ExpSemaphoreInitialization(), NtCreateSemaphore(), NtOpenSemaphore(), NtQuerySemaphore(), NtReleaseSemaphore(), and NtSignalAndWaitForSingleObject().


Generated on Sat May 15 19:45:35 2004 for test by doxygen 1.3.7