- 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,83 +284,115 @@ NtQueryInformationAtom(RTL_ATOM Atom,
PRTL_ATOM_TABLE AtomTable = ExpGetGlobalAtomTable(); PRTL_ATOM_TABLE AtomTable = ExpGetGlobalAtomTable();
PATOM_BASIC_INFORMATION BasicInformation = AtomInformation; PATOM_BASIC_INFORMATION BasicInformation = AtomInformation;
PATOM_TABLE_INFORMATION TableInformation = AtomInformation; PATOM_TABLE_INFORMATION TableInformation = AtomInformation;
NTSTATUS Status; NTSTATUS Status = STATUS_SUCCESS;
ULONG Flags, UsageCount, NameLength; ULONG Flags, UsageCount, NameLength, RequiredLength = 0;
KPROCESSOR_MODE PreviousMode;
PAGED_CODE();
/* Check for valid table */ /* Check for valid table */
if (AtomTable == NULL) return STATUS_ACCESS_DENIED; if (AtomTable == NULL) return STATUS_ACCESS_DENIED;
/* FIXME: SEH! */ PreviousMode = ExGetPreviousMode();
/* Choose class */ _SEH_TRY
switch (AtomInformationClass)
{ {
/* Caller requested info about an atom */ /* Probe the parameters */
case AtomBasicInformation: if (PreviousMode != KernelMode)
{
ProbeForWrite(AtomInformation,
AtomInformationLength,
sizeof(ULONG));
/* Size check */ if (ReturnLength != NULL)
*ReturnLength = FIELD_OFFSET(ATOM_BASIC_INFORMATION, Name);
if (*ReturnLength > AtomInformationLength)
{ {
/* Fail */ ProbeForWriteUlong(ReturnLength);
DPRINT1("Buffer too small\n");
return STATUS_INFO_LENGTH_MISMATCH;
} }
}
/* Prepare query */ /* Choose class */
UsageCount = 0; switch (AtomInformationClass)
NameLength = AtomInformationLength - *ReturnLength; {
BasicInformation->Name[0] = UNICODE_NULL; /* Caller requested info about an atom */
case AtomBasicInformation:
/* Query the data */ /* Size check */
Status = RtlQueryAtomInAtomTable(AtomTable, RequiredLength = FIELD_OFFSET(ATOM_BASIC_INFORMATION, Name);
Atom, if (RequiredLength > AtomInformationLength)
&UsageCount, {
&Flags, /* Fail */
BasicInformation->Name, DPRINT1("Buffer too small\n");
&NameLength); Status = STATUS_INFO_LENGTH_MISMATCH;
if (NT_SUCCESS(Status)) _SEH_LEAVE;
{ }
/* 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 */ /* Prepare query */
case AtomTableInformation: UsageCount = 0;
NameLength = AtomInformationLength - RequiredLength;
BasicInformation->Name[0] = UNICODE_NULL;
/* Size check */ /* Query the data */
*ReturnLength = FIELD_OFFSET(ATOM_TABLE_INFORMATION, Atoms); Status = RtlQueryAtomInAtomTable(AtomTable,
if (*ReturnLength > AtomInformationLength) Atom,
{ &UsageCount,
/* Fail */ &Flags,
DPRINT1("Buffer too small\n"); BasicInformation->Name,
return STATUS_INFO_LENGTH_MISMATCH; &NameLength);
} if (NT_SUCCESS(Status))
{
/* Return data */
BasicInformation->UsageCount = (USHORT)UsageCount;
BasicInformation->Flags = (USHORT)Flags;
BasicInformation->NameLength = (USHORT)NameLength;
RequiredLength += NameLength + sizeof(WCHAR);
}
break;
/* Query the data */ /* Caller requested info about an Atom Table */
Status = RtlQueryAtomListInAtomTable(AtomTable, case AtomTableInformation:
(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 */ /* Size check */
default: RequiredLength = FIELD_OFFSET(ATOM_TABLE_INFORMATION, Atoms);
if (RequiredLength > AtomInformationLength)
{
/* Fail */
DPRINT1("Buffer too small\n");
Status = STATUS_INFO_LENGTH_MISMATCH;
_SEH_LEAVE;
}
/* Unrecognized class */ /* Query the data */
Status = STATUS_INVALID_INFO_CLASS; 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 to caller */
return Status; return Status;

View file

@ -240,8 +240,11 @@ NtQuerySecurityObject(IN HANDLE Handle,
_SEH_TRY _SEH_TRY
{ {
ProbeForWrite(SecurityDescriptor, Length, sizeof(ULONG)); ProbeForWrite(SecurityDescriptor, Length, sizeof(ULONG));
if (ResultLength != NULL)
{
ProbeForWriteUlong(ResultLength); ProbeForWriteUlong(ResultLength);
} }
}
_SEH_HANDLE _SEH_HANDLE
{ {
Status = _SEH_GetExceptionCode(); Status = _SEH_GetExceptionCode();
@ -280,16 +283,19 @@ NtQuerySecurityObject(IN HANDLE Handle,
ObDereferenceObject(Object); ObDereferenceObject(Object);
/* return the required length */ /* return the required length */
if (ResultLength != NULL)
{
_SEH_TRY _SEH_TRY
{ {
*ResultLength = Length; *ResultLength = Length;
} }
_SEH_HANDLE _SEH_EXCEPT(_SEH_ExSystemExceptionFilter)
{ {
Status = _SEH_GetExceptionCode(); Status = _SEH_GetExceptionCode();
} }
_SEH_END; _SEH_END;
} }
}
return Status; return Status;
} }