- Thomas Weidenmueller (w3seek@reactos.org)

- Use SEH in Atom functions
  - Only use result length if the caller gave one, in NtQuerySecurityObject.

svn path=/trunk/; revision=22001
This commit is contained in:
Alex Ionescu 2006-05-24 02:48:51 +00:00
parent 8a80070849
commit ee3fddd2d7
2 changed files with 99 additions and 61 deletions

View file

@ -284,13 +284,31 @@ NtQueryInformationAtom(RTL_ATOM Atom,
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! */
PreviousMode = ExGetPreviousMode();
_SEH_TRY
{
/* Probe the parameters */
if (PreviousMode != KernelMode)
{
ProbeForWrite(AtomInformation,
AtomInformationLength,
sizeof(ULONG));
if (ReturnLength != NULL)
{
ProbeForWriteUlong(ReturnLength);
}
}
/* Choose class */
switch (AtomInformationClass)
@ -299,17 +317,18 @@ NtQueryInformationAtom(RTL_ATOM Atom,
case AtomBasicInformation:
/* Size check */
*ReturnLength = FIELD_OFFSET(ATOM_BASIC_INFORMATION, Name);
if (*ReturnLength > AtomInformationLength)
RequiredLength = FIELD_OFFSET(ATOM_BASIC_INFORMATION, Name);
if (RequiredLength > AtomInformationLength)
{
/* Fail */
DPRINT1("Buffer too small\n");
return STATUS_INFO_LENGTH_MISMATCH;
Status = STATUS_INFO_LENGTH_MISMATCH;
_SEH_LEAVE;
}
/* Prepare query */
UsageCount = 0;
NameLength = AtomInformationLength - *ReturnLength;
NameLength = AtomInformationLength - RequiredLength;
BasicInformation->Name[0] = UNICODE_NULL;
/* Query the data */
@ -325,7 +344,7 @@ NtQueryInformationAtom(RTL_ATOM Atom,
BasicInformation->UsageCount = (USHORT)UsageCount;
BasicInformation->Flags = (USHORT)Flags;
BasicInformation->NameLength = (USHORT)NameLength;
*ReturnLength += NameLength + sizeof(WCHAR);
RequiredLength += NameLength + sizeof(WCHAR);
}
break;
@ -333,25 +352,25 @@ NtQueryInformationAtom(RTL_ATOM Atom,
case AtomTableInformation:
/* Size check */
*ReturnLength = FIELD_OFFSET(ATOM_TABLE_INFORMATION, Atoms);
if (*ReturnLength > AtomInformationLength)
RequiredLength = FIELD_OFFSET(ATOM_TABLE_INFORMATION, Atoms);
if (RequiredLength > AtomInformationLength)
{
/* Fail */
DPRINT1("Buffer too small\n");
return STATUS_INFO_LENGTH_MISMATCH;
Status = STATUS_INFO_LENGTH_MISMATCH;
_SEH_LEAVE;
}
/* Query the data */
Status = RtlQueryAtomListInAtomTable(AtomTable,
(AtomInformationLength - *ReturnLength) /
(AtomInformationLength - RequiredLength) /
sizeof(RTL_ATOM),
&TableInformation->NumberOfAtoms,
TableInformation->Atoms);
if (NT_SUCCESS(Status))
{
/* Update the return length */
*ReturnLength += TableInformation->NumberOfAtoms *
sizeof(RTL_ATOM);
RequiredLength += TableInformation->NumberOfAtoms * sizeof(RTL_ATOM);
}
break;
@ -360,8 +379,21 @@ NtQueryInformationAtom(RTL_ATOM Atom,
/* 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;
}

View file

@ -240,8 +240,11 @@ NtQuerySecurityObject(IN HANDLE Handle,
_SEH_TRY
{
ProbeForWrite(SecurityDescriptor, Length, sizeof(ULONG));
if (ResultLength != NULL)
{
ProbeForWriteUlong(ResultLength);
}
}
_SEH_HANDLE
{
Status = _SEH_GetExceptionCode();
@ -280,16 +283,19 @@ NtQuerySecurityObject(IN HANDLE Handle,
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;
}