Author: ion
Date: Wed May 24 06:48:51 2006
New Revision: 22001
URL:
http://svn.reactos.ru/svn/reactos?rev=22001&view=rev
Log:
- Thomas Weidenmueller (w3seek(a)reactos.org)
- Use SEH in Atom functions
- Only use result length if the caller gave one, in NtQuerySecurityObject.
Modified:
trunk/reactos/ntoskrnl/ex/atom.c
trunk/reactos/ntoskrnl/ob/security.c
Modified: trunk/reactos/ntoskrnl/ex/atom.c
URL:
http://svn.reactos.ru/svn/reactos/trunk/reactos/ntoskrnl/ex/atom.c?rev=2200…
==============================================================================
--- trunk/reactos/ntoskrnl/ex/atom.c (original)
+++ trunk/reactos/ntoskrnl/ex/atom.c Wed May 24 06:48:51 2006
@@ -284,83 +284,115 @@
PRTL_ATOM_TABLE AtomTable = ExpGetGlobalAtomTable();
PATOM_BASIC_INFORMATION BasicInformation = AtomInformation;
PATOM_TABLE_INFORMATION TableInformation = AtomInformation;
- NTSTATUS Status;
- ULONG Flags, UsageCount, NameLength;
+ NTSTATUS Status = STATUS_SUCCESS;
+ ULONG Flags, UsageCount, NameLength, RequiredLength = 0;
+ KPROCESSOR_MODE PreviousMode;
+
+ PAGED_CODE();
/* Check for valid table */
if (AtomTable == NULL) return STATUS_ACCESS_DENIED;
- /* FIXME: SEH! */
-
- /* Choose class */
- switch (AtomInformationClass)
- {
- /* Caller requested info about an atom */
- case AtomBasicInformation:
-
- /* Size check */
- *ReturnLength = FIELD_OFFSET(ATOM_BASIC_INFORMATION, Name);
- if (*ReturnLength > AtomInformationLength)
- {
- /* Fail */
- DPRINT1("Buffer too small\n");
- return STATUS_INFO_LENGTH_MISMATCH;
- }
-
- /* Prepare query */
- UsageCount = 0;
- NameLength = AtomInformationLength - *ReturnLength;
- BasicInformation->Name[0] = UNICODE_NULL;
-
- /* Query the data */
- Status = RtlQueryAtomInAtomTable(AtomTable,
- Atom,
- &UsageCount,
- &Flags,
- BasicInformation->Name,
- &NameLength);
- if (NT_SUCCESS(Status))
- {
- /* Return data */
- BasicInformation->UsageCount = (USHORT)UsageCount;
- BasicInformation->Flags = (USHORT)Flags;
- BasicInformation->NameLength = (USHORT)NameLength;
- *ReturnLength += NameLength + sizeof(WCHAR);
- }
- break;
-
- /* Caller requested info about an Atom Table */
- case AtomTableInformation:
-
- /* Size check */
- *ReturnLength = FIELD_OFFSET(ATOM_TABLE_INFORMATION, Atoms);
- if (*ReturnLength > AtomInformationLength)
- {
- /* Fail */
- DPRINT1("Buffer too small\n");
- return STATUS_INFO_LENGTH_MISMATCH;
- }
-
- /* Query the data */
- Status = RtlQueryAtomListInAtomTable(AtomTable,
- (AtomInformationLength - *ReturnLength)
/
- sizeof(RTL_ATOM),
-
&TableInformation->NumberOfAtoms,
- TableInformation->Atoms);
- if (NT_SUCCESS(Status))
- {
- /* Update the return length */
- *ReturnLength += TableInformation->NumberOfAtoms *
- sizeof(RTL_ATOM);
- }
- break;
-
- /* Caller was on crack */
- default:
-
- /* Unrecognized class */
- Status = STATUS_INVALID_INFO_CLASS;
- }
+ PreviousMode = ExGetPreviousMode();
+
+ _SEH_TRY
+ {
+ /* Probe the parameters */
+ if (PreviousMode != KernelMode)
+ {
+ ProbeForWrite(AtomInformation,
+ AtomInformationLength,
+ sizeof(ULONG));
+
+ if (ReturnLength != NULL)
+ {
+ ProbeForWriteUlong(ReturnLength);
+ }
+ }
+
+ /* Choose class */
+ switch (AtomInformationClass)
+ {
+ /* Caller requested info about an atom */
+ case AtomBasicInformation:
+
+ /* Size check */
+ RequiredLength = FIELD_OFFSET(ATOM_BASIC_INFORMATION, Name);
+ if (RequiredLength > AtomInformationLength)
+ {
+ /* Fail */
+ DPRINT1("Buffer too small\n");
+ Status = STATUS_INFO_LENGTH_MISMATCH;
+ _SEH_LEAVE;
+ }
+
+ /* Prepare query */
+ UsageCount = 0;
+ NameLength = AtomInformationLength - RequiredLength;
+ BasicInformation->Name[0] = UNICODE_NULL;
+
+ /* Query the data */
+ Status = RtlQueryAtomInAtomTable(AtomTable,
+ Atom,
+ &UsageCount,
+ &Flags,
+ BasicInformation->Name,
+ &NameLength);
+ if (NT_SUCCESS(Status))
+ {
+ /* Return data */
+ BasicInformation->UsageCount = (USHORT)UsageCount;
+ BasicInformation->Flags = (USHORT)Flags;
+ BasicInformation->NameLength = (USHORT)NameLength;
+ RequiredLength += NameLength + sizeof(WCHAR);
+ }
+ break;
+
+ /* Caller requested info about an Atom Table */
+ case AtomTableInformation:
+
+ /* Size check */
+ RequiredLength = FIELD_OFFSET(ATOM_TABLE_INFORMATION, Atoms);
+ if (RequiredLength > AtomInformationLength)
+ {
+ /* Fail */
+ DPRINT1("Buffer too small\n");
+ Status = STATUS_INFO_LENGTH_MISMATCH;
+ _SEH_LEAVE;
+ }
+
+ /* Query the data */
+ Status = RtlQueryAtomListInAtomTable(AtomTable,
+ (AtomInformationLength -
RequiredLength) /
+ sizeof(RTL_ATOM),
+
&TableInformation->NumberOfAtoms,
+ TableInformation->Atoms);
+ if (NT_SUCCESS(Status))
+ {
+ /* Update the return length */
+ RequiredLength += TableInformation->NumberOfAtoms *
sizeof(RTL_ATOM);
+ }
+ break;
+
+ /* Caller was on crack */
+ default:
+
+ /* Unrecognized class */
+ Status = STATUS_INVALID_INFO_CLASS;
+ break;
+ }
+
+ /* Return the required size */
+ if (ReturnLength != NULL)
+ {
+ *ReturnLength = RequiredLength;
+ }
+ }
+ _SEH_EXCEPT(_SEH_ExSystemExceptionFilter)
+ {
+ Status = _SEH_GetExceptionCode();
+ }
+ _SEH_END;
/* Return to caller */
return Status;
Modified: trunk/reactos/ntoskrnl/ob/security.c
URL:
http://svn.reactos.ru/svn/reactos/trunk/reactos/ntoskrnl/ob/security.c?rev=…
==============================================================================
--- trunk/reactos/ntoskrnl/ob/security.c (original)
+++ trunk/reactos/ntoskrnl/ob/security.c Wed May 24 06:48:51 2006
@@ -240,7 +240,10 @@
_SEH_TRY
{
ProbeForWrite(SecurityDescriptor, Length, sizeof(ULONG));
+ if (ResultLength != NULL)
+ {
ProbeForWriteUlong(ResultLength);
+ }
}
_SEH_HANDLE
{
@@ -280,15 +283,18 @@
ObDereferenceObject(Object);
/* return the required length */
+ if (ResultLength != NULL)
+ {
_SEH_TRY
{
*ResultLength = Length;
}
- _SEH_HANDLE
+ _SEH_EXCEPT(_SEH_ExSystemExceptionFilter)
{
Status = _SEH_GetExceptionCode();
}
_SEH_END;
+ }
}
return Status;