mirror of
https://github.com/reactos/reactos.git
synced 2025-08-05 08:53:02 +00:00
- 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:
parent
8a80070849
commit
ee3fddd2d7
2 changed files with 99 additions and 61 deletions
|
@ -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;
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue