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@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=22001... ============================================================================== --- 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=2... ============================================================================== --- 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;