Как узнать размер открытого объекта сопоставления имен файлов? [Дубликат]

Это звучит как хорошая задача описания технологии W3C XPath . Легко выразить такие запросы, как «вернуть все href атрибуты в тегах img, которые вложены в elements». Не являясь баффом PHP, я не могу сказать вам, в какой форме XPath может быть доступен. Если вы можете вызвать внешнюю программу для обработки HTML-файла, вы сможете использовать версию командной строки XPath. Для быстрого ввода см. http://en.wikipedia.org/wiki/XPath .

0
задан igal k 18 January 2016 в 18:17
поделиться

2 ответа

Насколько я знаю, нет способа получить размер существующего сопоставления файлов или отображения сопоставления файлов. Вы должны отслеживать эту информацию самостоятельно.

MSDN заявляет, что VirtualQueryEx способен делать такую ​​вещь.

Нет, все VirtualQueryEx может определить число страниц, зарезервированных для представления. Это означает, что результат всегда округляется до размера страницы. Кроме того, нет явной гарантии, что MapViewOfFile зарезервирует только минимальное количество страниц, необходимых для сопоставления файла. Например, он может выбрать округление до гранулярности распределения.

4
ответ дан Harry Johnston 24 August 2018 в 22:16
поделиться

Это действительно возможно, но Microsoft почему-то не документировала его. API NtQuerySection существовал с ранних версий Windows NT и до сих пор работает в Windows 10.

Итак, вот как вы это делаете (очевидно, на свой риск полагаться на недокументированный API ядра):

HANDLE hFileMapping = ::OpenFileMapping(FILE_MAP_READ | FILE_MAP_WRITE, FALSE, strSharedMemName);
_ASSERT(hFileMapping);

ULONGLONG uicbSharedMemSize = 0;

//Get the handle returned by the CreateFileMapping function
//Assuming the same process here...
HANDLE hDupH;
if((::DuplicateHandle(
    ::GetCurrentProcess(), hFileMapping, 
    ::GetCurrentProcess(), &hDupH,
    DUPLICATE_CLOSE_SOURCE | DUPLICATE_SAME_ACCESS, FALSE, 0)))
{
    hFileMapping = hDupH;

    enum SECTION_INFORMATION_CLASS{
        SectionBasicInformation,
        SectionImageInformation
    };

    typedef struct _SECTION_BASIC_INFORMATION {
      ULONG                   Unknown;
      ULONG                   SectionAttributes;
      LARGE_INTEGER           SectionSize;
    } SECTION_BASIC_INFORMATION, *PSECTION_BASIC_INFORMATION;

    static NTSTATUS
    (NTAPI
    *pfnNtQuerySection)(
      IN HANDLE               SectionHandle,
      IN SECTION_INFORMATION_CLASS InformationClass,
      OUT PVOID               InformationBuffer,
      IN ULONG                InformationBufferSize,
      OUT PULONG              ResultLength OPTIONAL ) = NULL;

    if(!pfnNtQuerySection)
        (FARPROC&)pfnNtQuerySection = ::GetProcAddress(::GetModuleHandle(L"ntdll.dll"), "NtQuerySection");

    if(pfnNtQuerySection)
    {
        SECTION_BASIC_INFORMATION sbi = {0};
        ULONG ucbRead = 0;
        NTSTATUS stat = pfnNtQuerySection(hFileMapping, SectionBasicInformation, &sbi, sizeof(sbi), &ucbRead);
        if(stat >= 0)
        {
            //The size returned will be rounded up to the page size (i.e. 4K in most cases)
            uicbSharedMemSize = sbi.SectionSize.QuadPart;
        }
    }
}

в первую очередь правильное определение для SECTION_BASIC_INFORMATION:

typedef struct _SECTION_BASIC_INFORMATION
{
    PVOID BaseAddress;
    ULONG AllocationAttributes;
    LARGE_INTEGER MaximumSize;
} SECTION_BASIC_INFORMATION, *PSECTION_BASIC_INFORMATION;

, поэтому старое определение (с DWORD первым членом - было неправильным и не будет работать для 64-битный код).

в секунду для вызова NtQuerySection дескриптор раздела должен иметь доступ SECTION_QUERY, в противном случае будет STATUS_ACCESS_DENIED - поэтому строка:

OpenFileMapping(FILE_MAP_READ | FILE_MAP_WRITE, FALSE, strSharedMemName);

неверна , должен быть

OpenFileMapping(SECTION_QUERY|FILE_MAP_READ|FILE_MAP_WRITE, FALSE, strSharedMemName);

или любым доступом, в том числе SECTION_QUERY

отметить, что если использовать OpenFileMapping и установить dwDesiredAccess точно на SECTION_QUERY, OpenFileMapping по неизвестной причине измените его на SECTION_MAP_READ - это следующая строка кода внутри этого api. if (dwDesiredAccess == SECTION_QUERY) dwDesiredAccess = SECTION_MAP_READ;, поэтому необходимо добавить некоторый доступ к SECTION_QUERY. конечно, мы можем использовать SECTION_QUERY точно с ZwOpenSection

next - для какого вызова DuplicateHandle?!? это абсолютно бессмысленно в вызове контекста задачи. мы получили управление секцией через OpenFileMappingW или ZwOpenSection.

и, наконец, для чего GetModuleHandle + GetProcAddress для ZwQuerySection? как нам интересно называть OpenFileMappingW без GetModuleHandle + GetProcAddress, например? как GetProcAddress звонит? так же мы можем вызвать ZwQuerySection - просто ссылку с ntdll.dll через ntdll.lib , которые существуют в каждой папке wdk lib. поэтому окончательный код должен быть:

if (HANDLE hMap = OpenFileMappingW(SECTION_QUERY|SECTION_MAP_READ, FALSE, name))
{
    SECTION_BASIC_INFORMATION sbi;
    if (0 <= ZwQuerySection(hMap, SectionBasicInformation, &sbi, sizeof(sbi), 0))
    {
        DbgPrint("section size = %I64x\n", sbi.Size.QuadPart);
    }
    CloseHandle(hMap);
}

или

HANDLE hMap;
if (0 <= ZwOpenSection(&hMap, SECTION_QUERY, &oa))
{
    SECTION_BASIC_INFORMATION sbi;
    if (0 <= ZwQuerySection(hMap, SectionBasicInformation, &sbi, sizeof(sbi), 0))
    {
        DbgPrint("section size = %I64x\n", sbi.Size.QuadPart);
    }
    CloseHandle(hMap);
}
1
ответ дан RbMm 24 August 2018 в 22:16
поделиться
Другие вопросы по тегам:

Похожие вопросы: