- 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:
Alex Ionescu 2005-08-05 06:56:17 +00:00
parent 4a4e5adc99
commit 53aa4eb206

View file

@ -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 */