#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?