|
|
/*++
Copyright (c) 1989 Microsoft Corporation
Module Name:
querysec.c
Abstract:
This module contains the routines which implement the NtQuerySection service.
Author:
Lou Perazzoli (loup) 22-May-1989 Landy Wang (landyw) 02-Jun-1997
Revision History:
--*/
#include "mi.h"
#ifdef ALLOC_PRAGMA
#pragma alloc_text(PAGE,NtQuerySection)
#endif
NTSTATUS NtQuerySection( IN HANDLE SectionHandle, IN SECTION_INFORMATION_CLASS SectionInformationClass, OUT PVOID SectionInformation, IN SIZE_T SectionInformationLength, OUT PSIZE_T ReturnLength OPTIONAL )
/*++
Routine Description:
This function provides the capability to determine the base address, size, granted access, and allocation of an opened section object.
Arguments:
SectionHandle - Supplies an open handle to a section object.
SectionInformationClass - The section information class about which to retrieve information.
SectionInformation - A pointer to a buffer that receives the specified information. The format and content of the buffer depend on the specified section class.
SectionInformation Format by Information Class:
SectionBasicInformation - Data type is PSECTION_BASIC_INFORMATION.
SECTION_BASIC_INFORMATION Structure
PVOID BaseAddress - The base virtual address of the section if the section is based.
LARGE_INTEGER MaximumSize - The maximum size of the section in bytes.
ULONG AllocationAttributes - The allocation attributes flags.
AllocationAttributes Flags
SEC_BASED - The section is a based section.
SEC_FILE - The section is backed by a data file.
SEC_RESERVE - All pages of the section were initially set to the reserved state.
SEC_COMMIT - All pages of the section were initially to the committed state.
SEC_IMAGE - The section was mapped as an executable image file.
SECTION_IMAGE_INFORMATION
SectionInformationLength - Specifies the length in bytes of the section information buffer.
ReturnLength - An optional pointer which, if specified, receives the number of bytes placed in the section information buffer.
Return Value:
NTSTATUS.
--*/
{ NTSTATUS Status; PSECTION Section; KPROCESSOR_MODE PreviousMode;
PAGED_CODE();
//
// Get previous processor mode and probe output argument if necessary.
//
PreviousMode = KeGetPreviousMode(); if (PreviousMode != KernelMode) {
//
// Check arguments.
//
try {
ProbeForWrite(SectionInformation, SectionInformationLength, sizeof(ULONG));
if (ARGUMENT_PRESENT (ReturnLength)) { ProbeForWriteUlong_ptr (ReturnLength); }
} except (EXCEPTION_EXECUTE_HANDLER) {
//
// If an exception occurs during the probe or capture
// of the initial values, then handle the exception and
// return the exception code as the status value.
//
return GetExceptionCode(); } }
//
// Check argument validity.
//
if ((SectionInformationClass != SectionBasicInformation) && (SectionInformationClass != SectionImageInformation)) { return STATUS_INVALID_INFO_CLASS; }
if (SectionInformationClass == SectionBasicInformation) { if (SectionInformationLength < (ULONG)sizeof(SECTION_BASIC_INFORMATION)) { return STATUS_INFO_LENGTH_MISMATCH; } } else { if (SectionInformationLength < (ULONG)sizeof(SECTION_IMAGE_INFORMATION)) { return STATUS_INFO_LENGTH_MISMATCH; } }
//
// Reference section object by handle for READ access, get the information
// from the section object, dereference the section
// object, fill in information structure, optionally return the length of
// the information structure, and return service status.
//
Status = ObReferenceObjectByHandle (SectionHandle, SECTION_QUERY, MmSectionObjectType, PreviousMode, (PVOID *)&Section, NULL);
if (NT_SUCCESS(Status)) {
try {
if (SectionInformationClass == SectionBasicInformation) { ((PSECTION_BASIC_INFORMATION)SectionInformation)->BaseAddress = (PVOID)Section->Address.StartingVpn;
((PSECTION_BASIC_INFORMATION)SectionInformation)->MaximumSize = Section->SizeOfSection;
((PSECTION_BASIC_INFORMATION)SectionInformation)->AllocationAttributes = 0;
if (Section->u.Flags.Image) { ((PSECTION_BASIC_INFORMATION)SectionInformation)->AllocationAttributes = SEC_IMAGE; } if (Section->u.Flags.Based) { ((PSECTION_BASIC_INFORMATION)SectionInformation)->AllocationAttributes |= SEC_BASED; } if (Section->u.Flags.File) { ((PSECTION_BASIC_INFORMATION)SectionInformation)->AllocationAttributes |= SEC_FILE; } if (Section->u.Flags.NoCache) { ((PSECTION_BASIC_INFORMATION)SectionInformation)->AllocationAttributes |= SEC_NOCACHE; } if (Section->u.Flags.Reserve) { ((PSECTION_BASIC_INFORMATION)SectionInformation)->AllocationAttributes |= SEC_RESERVE; } if (Section->u.Flags.Commit) { ((PSECTION_BASIC_INFORMATION)SectionInformation)->AllocationAttributes |= SEC_COMMIT; } if (Section->Segment->ControlArea->u.Flags.GlobalMemory) { ((PSECTION_BASIC_INFORMATION)SectionInformation)->AllocationAttributes |= SEC_GLOBAL; }
if (ARGUMENT_PRESENT(ReturnLength)) { *ReturnLength = sizeof(SECTION_BASIC_INFORMATION); } } else {
if (Section->u.Flags.Image == 0) { Status = STATUS_SECTION_NOT_IMAGE; } else { *((PSECTION_IMAGE_INFORMATION)SectionInformation) = *Section->Segment->u2.ImageInformation; if (ARGUMENT_PRESENT(ReturnLength)) { *ReturnLength = sizeof(SECTION_IMAGE_INFORMATION); } } }
} except (EXCEPTION_EXECUTE_HANDLER) { Status = GetExceptionCode (); }
ObDereferenceObject ((PVOID)Section); } return Status; }
|