Не удалось включить ntifs.h в проект win32 - PullRequest
4 голосов
/ 03 июня 2010

Я пытался использовать функцию под названием NTCreateFile. Когда я скомпилировал, он дал мне ошибку, говоря Msgstr "Идентификатор _NTCreateFile не найден". Я включил заголовок winternl.h. Итак, затем я попытался использовать ZwCreatFile, в соответствии с MSDN я включил ntifs.h, но я не могу включить этот заголовок. Там написано "не удалось открыть / найти каталог". Я использую V @ 2008. В чем проблема? Я что-то упустил?

EDIT1:

typedef NTSTATUS (*fp_CreatFile)(
    OUT PHANDLE FileHandle,
    IN ACCESS_MASK DesiredAccess,
    IN POBJECT_ATTRIBUTES ObjectAttributes,
    OUT PIO_STATUS_BLOCK IoStatusBlock,
    IN PLARGE_INTEGER AllocationSize OPTIONAL,
    IN ULONG FileAttributes,
    IN ULONG ShareAccess,
    IN ULONG CreateDisposition,
    IN ULONG CreateOptions,
    IN PVOID EaBuffer OPTIONAL,
    IN ULONG EaLength
    );
OBJECT_ATTRIBUTES myAttributes;

int _tmain(int argc, _TCHAR* argv[])
{
    fp_CreatFile myFunction;
    HMODULE module = LoadLibrary(L"ntdll.dll");
    if(NULL != module)
    {
        myFunction = (fp_CreatFile)GetProcAddress(module,"NtCreateFile");
    }

    UNICODE_STRING string;
    IO_STATUS_BLOCK fileStatus;
    string.Length = 56;
    string.Buffer = L"C:\\user\\kiddo\\Desktop\\7zFM.exe";
    string.MaximumLength = 56;

    HANDLE fileHandle;
    myAttributes.ObjectName = &string;
    myAttributes.Length = sizeof(OBJECT_ATTRIBUTES);
    long mystatus = myFunction(&fileHandle,FILE_GENERIC_READ,&myAttributes ,&fileStatus,NULL,FILE_ATTRIBUTE_NORMAL,FILE_SHARE_READ,
        NULL,NULL,NULL,NULL);
    return 0;
}

Когда он пытается вызвать это, он выдает следующую ошибку в окне сообщения. ОШИБКА: Ошибка проверки времени выполнения # 0 - значение ESP не было должным образом сохранено при вызове функции. Обычно это является результатом вызова функции, объявленной с одним соглашением о вызовах с указателем функции, объявленным с другим соглашением о вызовах.

Ответы [ 4 ]

4 голосов
/ 03 июня 2010

Если вы читаете документацию MSDN , первый абзац гласит:

Примечание. Перед использованием этой функции пожалуйста, прочитайте Вызов внутренних API .

Что говорит о том, что: (я выделил важные части)

Файл заголовка Winternl.h предоставляет прототипы внутренних API-интерфейсов Windows. Нет связанной библиотеки импорта, поэтому разработчики должны использовать время выполнения динамическое связывание для вызова функций описано в этом заголовочном файле.

Функции и структуры в Winternl.h являются внутренними операционная система и может быть изменена от одного выпуска Windows до затем, и, возможно, даже между сервисные пакеты для каждого выпуска. к поддерживать совместимость вашего приложение, вы должны использовать эквивалентные публичные функции вместо. Дополнительная информация доступна в заголовочный файл Winternl.h и документация для каждой функции.

Если вы используете эти функции, вы можете доступ к ним через динамический динамический связывание с использованием LoadLibrary и GetProcAddress . Это дает ваш код возможность ответить изящно если функция была изменена или удален из операционной системы. Изменения подписи, однако, не могут быть прощупывается.

Таким образом, вам придется загрузить функции, которые вы хотите использовать, из NtDll.dll, прежде чем сможете их использовать.

Вот пример не проверенного примера кода:

typedef NTSTATUS (__stdcall *NtCreateFile)(
    OUT PHANDLE FileHandle,
    IN ACCESS_MASK DesiredAccess,
    IN POBJECT_ATTRIBUTES ObjectAttributes,
    OUT PIO_STATUS_BLOCK IoStatusBlock,
    IN PLARGE_INTEGER AllocationSize OPTIONAL,
    IN ULONG FileAttributes,
    IN ULONG ShareAccess,
    IN ULONG CreateDisposition,
    IN ULONG CreateOptions,
    IN PVOID EaBuffer OPTIONAL,
    IN ULONG EaLength
    );

NtCreateFile _NtCreateFile = (NtCreateFile)GetProcAddress(GetModuleHandle("ntdll.dll"),"NtCreateFile");

// You can now use the function
_NtCreateFile(/* params */);

// Don't forget the release the resources
1 голос
/ 03 июня 2010

Несколько возможностей:

  • Вы говорите, что сообщение об ошибке «Идентификатор _NTCreateFile не найден». Имя API - NtCreateFile() (обратите внимание на строчную букву 't'). Возможно, вы просто используете неправильное имя.

  • ntifs.h и соответствующие библиотеки ссылок включены в комплект драйверов Windows (WDK), который можно загрузить здесь: http://www.microsoft.com/whdc/devtools/wdk/wdkpkg.mspx. Вы сможете использовать WDK, чтобы делать то, что вы хотите немного более прямо, чем при использовании динамического связывания. но тогда вам, как правило, придется купить целую новую систему сборки или выяснить, как интегрировать заголовки и библиотеки в текущую сборку.

  • Вы можете использовать метод динамического связывания , описанный ereOn .

1 голос
/ 03 июня 2010

Как ясно указано в сообщении об ошибке, вы неправильно указали соглашение о вызовах, вы сбросили NTAPI. Должно быть:

typedef NTSTATUS (__stdcall * fp_CreatFile)(
  // etc..
);

Правильная инициализация myAttributes обычно важна. Я не вижу, чтобы вы делали что-либо, что могло бы оправдать вызов недокументированной нативной функции API. Придерживайтесь CreateFile () как можно дольше.

1 голос
/ 03 июня 2010

ZwCreateFile является частью Windows Driver Kit, а не Windows SDK. Вам нужно будет установить комплект драйверов. Некоторые макросы и типы, используемые NTCreateFile, также требуют заголовков WDK. Это четко указано в документации по MSDN.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...