Ошибка GetFileSizeEx для сопоставления файлов

#c #windows #shared-memory

#c #Windows #разделяемая память

Вопрос:

У меня возникли проблемы с созданием именованной общей памяти и проверкой ее размера. Функция GetFileSizeEx завершается с ошибкой, когда я вызываю ее в функции, подобной этой. Есть идеи, как это отладить?

 void test_getsize(const char* lpName, int size){

    HANDLE handle = CreateFileMapping(
                     INVALID_HANDLE_VALUE,    // use paging file
                     NULL,                    // default security
                     PAGE_READWRITE,          // read/write access
                     0,                       // maximum object size (high-order DWORD)
                     size,                // maximum object size (low-order DWORD)
                     lpName);                 // name of mapping object

    if (handle== NULL || handle== INVALID_HANDLE_VALUE){
        last_error = get_error_from_errorno();
        *error_return =1;
    }


    LARGE_INTEGER new_size;

    err = GetFileSizeEx(handle, amp;new_size);

    if (err==0){ printf("err ");} else {printf("pass ");}
    printf("size=%lun", (unsigned long)new_size.QuadPart);
}
  

Комментарии:

1. И каков результат этого кода?

2. Вы не используете файл, не можете получить размер несуществующего файла.

3. Я немного (много?) поздно, но почему вы не используете MapViewOfFile / VirtualQuery ?

Ответ №1:

Дескриптор, которому вы передаете GetFileSizeEx , должен быть дескриптором файла. Вы передаете ему дескриптор сопоставления файлов, что является совершенно другим делом, поэтому оно не будет работать.

Поскольку, по-видимому, вам нужен размер сопоставления файлов (называемый объектом раздела), и я не думаю, что Win32 API предоставляет эту функцию, вам нужно будет использовать собственный вызываемый Windows API NtQuerySection . Вот идея о том, как это может работать (я не пробовал):

 typedef enum _SECTION_INFORMATION_CLASS
{
    SectionBasicInformation,
    SectionImageInformation
} SECTION_INFORMATION_CLASS;

typedef struct _SECTION_BASIC_INFORMATION {
  PVOID         Base;
  ULONG         Attributes;
  LARGE_INTEGER Size;
} SECTION_BASIC_INFORMATION;

typedef DWORD (WINAPI* NTQUERYSECTION)
    (HANDLE, SECTION_INFORMATION_CLASS, PVOID, ULONG, PULONG);
NTQUERYSECTION NtQuerySection =
    (NTQUERYSECTION)GetProcAddress(LoadLibrary("ntdll.dll"), "NtQuerySection");

SECTION_BASIC_INFORMATION SectionInfo = { 0 };
NTSTATUS = NtQuerySection(handle, SectionBasicInformation, amp;SectionInfo,
    sizeof(SectionInfo), 0);
  

Комментарии:

1. Спасибо за ответ. С тех пор я обнаружил, что возвращаемый ДЕСКРИПТОР является объектом раздела. как мне запросить размер объекта section? Я читал о «ZwQuerySection», но, похоже, это только в Windows NT.

2. @sean: Вы не вызываете Zw* функции из пользовательского режима. Используйте NtQuerySection функцию, как я изложил в своем обновленном ответе.

3. Поскольку NtQuerySection является недокументированным API, нет гарантии, что он будет там или будет работать так же в будущей версии Windows. Почему бы просто не запомнить размер, используемый для создания объекта section?

4. Я не могу вспомнить размер, потому что дескриптор, отображенный в памяти, был создан в другом процессе.

5. У меня все еще возникают проблемы с NtQuerySection. Он возвращает статус 0xC0000004 (STATUS_INFO_LENGTH_MISMATCH). The specified information record length does not match the length that is required for the specified information class. Но я не видел никаких заголовков, которые отображали бы структуру SECTION_BASIC_INFORMATION как какую-либо другую. у кого-нибудь есть рабочий пример NtQuerySection?