mirror of
https://github.com/reactos/reactos.git
synced 2025-02-22 08:25:03 +00:00
- Protect semaphore release with SEH, since it can cause an exception
- Correct object type initializer - Correct incorrect PreviousMode checks - Correct MaximumCount and ReleaseCount checks since they can't be negative either - Harmonize formatting svn path=/trunk/; revision=17059
This commit is contained in:
parent
4a4e5adc99
commit
53aa4eb206
1 changed files with 85 additions and 83 deletions
|
@ -2,9 +2,9 @@
|
|||
* COPYRIGHT: See COPYING in the top level directory
|
||||
* PROJECT: ReactOS kernel
|
||||
* FILE: ntoskrnl/ex/sem.c
|
||||
* PURPOSE: Synchronization primitives
|
||||
* PURPOSE: Semaphore Implementation
|
||||
*
|
||||
* PROGRAMMERS: Alex Ionescu (alex@relsoft.net)- Reformatting, bug fixes.
|
||||
* PROGRAMMERS: Alex Ionescu (alex@relsoft.net)
|
||||
* David Welch (welch@mcmail.com)
|
||||
*/
|
||||
|
||||
|
@ -18,14 +18,16 @@
|
|||
|
||||
POBJECT_TYPE ExSemaphoreObjectType;
|
||||
|
||||
static GENERIC_MAPPING ExSemaphoreMapping = {
|
||||
static GENERIC_MAPPING ExSemaphoreMapping =
|
||||
{
|
||||
STANDARD_RIGHTS_READ | SEMAPHORE_QUERY_STATE,
|
||||
STANDARD_RIGHTS_WRITE | SEMAPHORE_MODIFY_STATE,
|
||||
STANDARD_RIGHTS_EXECUTE | SYNCHRONIZE | SEMAPHORE_QUERY_STATE,
|
||||
SEMAPHORE_ALL_ACCESS};
|
||||
|
||||
static const INFORMATION_CLASS_INFO ExSemaphoreInfoClass[] = {
|
||||
SEMAPHORE_ALL_ACCESS
|
||||
};
|
||||
|
||||
static const INFORMATION_CLASS_INFO ExSemaphoreInfoClass[] =
|
||||
{
|
||||
/* SemaphoreBasicInformation */
|
||||
ICI_SQ_SAME( sizeof(SEMAPHORE_BASIC_INFORMATION), sizeof(ULONG), ICIF_QUERY ),
|
||||
};
|
||||
|
@ -47,8 +49,8 @@ ExpInitializeSemaphoreImplementation(VOID)
|
|||
ObjectTypeInitializer.DefaultNonPagedPoolCharge = sizeof(KSEMAPHORE);
|
||||
ObjectTypeInitializer.GenericMapping = ExSemaphoreMapping;
|
||||
ObjectTypeInitializer.PoolType = NonPagedPool;
|
||||
ObjectTypeInitializer.InvalidAttributes = OBJ_OPENLINK;
|
||||
ObjectTypeInitializer.ValidAccessMask = SEMAPHORE_ALL_ACCESS;
|
||||
ObjectTypeInitializer.UseDefaultObject = TRUE;
|
||||
ObpCreateTypeObject(&ObjectTypeInitializer, &Name, &ExSemaphoreObjectType);
|
||||
}
|
||||
|
||||
|
@ -67,29 +69,29 @@ NtCreateSemaphore(OUT PHANDLE SemaphoreHandle,
|
|||
HANDLE hSemaphore;
|
||||
KPROCESSOR_MODE PreviousMode = ExGetPreviousMode();
|
||||
NTSTATUS Status = STATUS_SUCCESS;
|
||||
|
||||
PAGED_CODE();
|
||||
|
||||
/* Check Output Safety */
|
||||
if(PreviousMode != KernelMode) {
|
||||
|
||||
_SEH_TRY {
|
||||
|
||||
if(PreviousMode != KernelMode)
|
||||
{
|
||||
_SEH_TRY
|
||||
{
|
||||
ProbeForWrite(SemaphoreHandle,
|
||||
sizeof(HANDLE),
|
||||
sizeof(ULONG));
|
||||
} _SEH_EXCEPT(_SEH_ExSystemExceptionFilter) {
|
||||
|
||||
}
|
||||
_SEH_EXCEPT(_SEH_ExSystemExceptionFilter)
|
||||
{
|
||||
Status = _SEH_GetExceptionCode();
|
||||
|
||||
} _SEH_END;
|
||||
}
|
||||
_SEH_END;
|
||||
|
||||
if(!NT_SUCCESS(Status)) return Status;
|
||||
}
|
||||
|
||||
/* Make sure the counts make sense */
|
||||
if (!MaximumCount || InitialCount < 0 || InitialCount > MaximumCount) {
|
||||
|
||||
if (MaximumCount <= 0 || InitialCount < 0 || InitialCount > MaximumCount)
|
||||
{
|
||||
DPRINT("Invalid Count Data!\n");
|
||||
return STATUS_INVALID_PARAMETER;
|
||||
}
|
||||
|
@ -106,8 +108,8 @@ NtCreateSemaphore(OUT PHANDLE SemaphoreHandle,
|
|||
(PVOID*)&Semaphore);
|
||||
|
||||
/* Check for Success */
|
||||
if (NT_SUCCESS(Status)) {
|
||||
|
||||
if (NT_SUCCESS(Status))
|
||||
{
|
||||
/* Initialize it */
|
||||
KeInitializeSemaphore(Semaphore,
|
||||
InitialCount,
|
||||
|
@ -123,17 +125,17 @@ NtCreateSemaphore(OUT PHANDLE SemaphoreHandle,
|
|||
ObDereferenceObject(Semaphore);
|
||||
|
||||
/* Check for success and return handle */
|
||||
if(NT_SUCCESS(Status)) {
|
||||
|
||||
_SEH_TRY {
|
||||
|
||||
if(NT_SUCCESS(Status))
|
||||
{
|
||||
_SEH_TRY
|
||||
{
|
||||
*SemaphoreHandle = hSemaphore;
|
||||
|
||||
} _SEH_EXCEPT(_SEH_ExSystemExceptionFilter) {
|
||||
|
||||
}
|
||||
_SEH_EXCEPT(_SEH_ExSystemExceptionFilter)
|
||||
{
|
||||
Status = _SEH_GetExceptionCode();
|
||||
|
||||
} _SEH_END;
|
||||
}
|
||||
_SEH_END;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -153,22 +155,22 @@ NtOpenSemaphore(OUT PHANDLE SemaphoreHandle,
|
|||
HANDLE hSemaphore;
|
||||
KPROCESSOR_MODE PreviousMode = ExGetPreviousMode();
|
||||
NTSTATUS Status = STATUS_SUCCESS;
|
||||
|
||||
PAGED_CODE();
|
||||
|
||||
/* Check Output Safety */
|
||||
if(PreviousMode == UserMode) {
|
||||
|
||||
_SEH_TRY {
|
||||
|
||||
if(PreviousMode != KernelMode)
|
||||
{
|
||||
_SEH_TRY
|
||||
{
|
||||
ProbeForWrite(SemaphoreHandle,
|
||||
sizeof(HANDLE),
|
||||
sizeof(ULONG));
|
||||
} _SEH_EXCEPT(_SEH_ExSystemExceptionFilter) {
|
||||
|
||||
}
|
||||
_SEH_EXCEPT(_SEH_ExSystemExceptionFilter)
|
||||
{
|
||||
Status = _SEH_GetExceptionCode();
|
||||
|
||||
} _SEH_END;
|
||||
}
|
||||
_SEH_END;
|
||||
|
||||
if(!NT_SUCCESS(Status)) return Status;
|
||||
}
|
||||
|
@ -183,16 +185,15 @@ NtOpenSemaphore(OUT PHANDLE SemaphoreHandle,
|
|||
&hSemaphore);
|
||||
|
||||
/* Check for success and return handle */
|
||||
if(NT_SUCCESS(Status)) {
|
||||
|
||||
_SEH_TRY {
|
||||
|
||||
if(NT_SUCCESS(Status))
|
||||
{
|
||||
_SEH_TRY
|
||||
{
|
||||
*SemaphoreHandle = hSemaphore;
|
||||
|
||||
} _SEH_EXCEPT(_SEH_ExSystemExceptionFilter) {
|
||||
|
||||
}
|
||||
_SEH_EXCEPT(_SEH_ExSystemExceptionFilter)
|
||||
{
|
||||
Status = _SEH_GetExceptionCode();
|
||||
|
||||
} _SEH_END;
|
||||
}
|
||||
|
||||
|
@ -225,8 +226,8 @@ NtQuerySemaphore(IN HANDLE SemaphoreHandle,
|
|||
ReturnLength,
|
||||
PreviousMode,
|
||||
&Status);
|
||||
if(!NT_SUCCESS(Status)) {
|
||||
|
||||
if(!NT_SUCCESS(Status))
|
||||
{
|
||||
/* Invalid buffers */
|
||||
DPRINT("NtQuerySemaphore() failed, Status: 0x%x\n", Status);
|
||||
return Status;
|
||||
|
@ -241,10 +242,10 @@ NtQuerySemaphore(IN HANDLE SemaphoreHandle,
|
|||
NULL);
|
||||
|
||||
/* Check for success */
|
||||
if(NT_SUCCESS(Status)) {
|
||||
|
||||
_SEH_TRY {
|
||||
|
||||
if(NT_SUCCESS(Status))
|
||||
{
|
||||
_SEH_TRY
|
||||
{
|
||||
PSEMAPHORE_BASIC_INFORMATION BasicInfo = (PSEMAPHORE_BASIC_INFORMATION)SemaphoreInformation;
|
||||
|
||||
/* Return the basic information */
|
||||
|
@ -254,10 +255,10 @@ NtQuerySemaphore(IN HANDLE SemaphoreHandle,
|
|||
/* Return length */
|
||||
if(ReturnLength) *ReturnLength = sizeof(SEMAPHORE_BASIC_INFORMATION);
|
||||
|
||||
} _SEH_EXCEPT(_SEH_ExSystemExceptionFilter) {
|
||||
|
||||
}
|
||||
_SEH_EXCEPT(_SEH_ExSystemExceptionFilter)
|
||||
{
|
||||
Status = _SEH_GetExceptionCode();
|
||||
|
||||
} _SEH_END;
|
||||
|
||||
/* Dereference the Object */
|
||||
|
@ -284,25 +285,26 @@ NtReleaseSemaphore(IN HANDLE SemaphoreHandle,
|
|||
PAGED_CODE();
|
||||
|
||||
/* Check buffer validity */
|
||||
if(PreviousCount != NULL && PreviousMode == UserMode) {
|
||||
|
||||
_SEH_TRY {
|
||||
|
||||
if(PreviousCount && PreviousMode != KernelMode)
|
||||
{
|
||||
_SEH_TRY
|
||||
{
|
||||
ProbeForWrite(PreviousCount,
|
||||
sizeof(LONG),
|
||||
sizeof(ULONG));
|
||||
} _SEH_EXCEPT(_SEH_ExSystemExceptionFilter) {
|
||||
|
||||
}
|
||||
_SEH_EXCEPT(_SEH_ExSystemExceptionFilter)
|
||||
{
|
||||
Status = _SEH_GetExceptionCode();
|
||||
|
||||
} _SEH_END;
|
||||
}
|
||||
_SEH_END;
|
||||
|
||||
if(!NT_SUCCESS(Status)) return Status;
|
||||
}
|
||||
|
||||
/* Make sure count makes sense */
|
||||
if (!ReleaseCount) {
|
||||
|
||||
if (ReleaseCount <= 0)
|
||||
{
|
||||
DPRINT("Invalid Release Count\n");
|
||||
return STATUS_INVALID_PARAMETER;
|
||||
}
|
||||
|
@ -316,28 +318,28 @@ NtReleaseSemaphore(IN HANDLE SemaphoreHandle,
|
|||
NULL);
|
||||
|
||||
/* Check for success */
|
||||
if (NT_SUCCESS(Status)) {
|
||||
|
||||
if (NT_SUCCESS(Status))
|
||||
{
|
||||
/* Release the semaphore */
|
||||
LONG PrevCount = KeReleaseSemaphore(Semaphore,
|
||||
IO_NO_INCREMENT,
|
||||
ReleaseCount,
|
||||
FALSE);
|
||||
ObDereferenceObject(Semaphore);
|
||||
|
||||
/* Return it */
|
||||
if(PreviousCount) {
|
||||
|
||||
_SEH_TRY {
|
||||
_SEH_TRY
|
||||
{
|
||||
LONG PrevCount = KeReleaseSemaphore(Semaphore,
|
||||
IO_NO_INCREMENT,
|
||||
ReleaseCount,
|
||||
FALSE);
|
||||
ObDereferenceObject(Semaphore);
|
||||
|
||||
/* Return the old count if requested */
|
||||
if(PreviousCount)
|
||||
{
|
||||
*PreviousCount = PrevCount;
|
||||
|
||||
} _SEH_EXCEPT(_SEH_ExSystemExceptionFilter) {
|
||||
|
||||
Status = _SEH_GetExceptionCode();
|
||||
|
||||
} _SEH_END;
|
||||
}
|
||||
}
|
||||
_SEH_EXCEPT(_SEH_ExSystemExceptionFilter)
|
||||
{
|
||||
Status = _SEH_GetExceptionCode();
|
||||
}
|
||||
_SEH_END;
|
||||
}
|
||||
|
||||
/* Return Status */
|
||||
|
|
Loading…
Reference in a new issue