无法在win32项目中包含ntifs.h

时间:2010-06-03 10:12:38

标签: c winapi kernel

我尝试使用名为NTCreateFile的函数。当我编译它给我一个错误说 “找不到_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 个答案:

答案 0 :(得分:4)

如果您阅读MSDN documentation,则第一段说:

  

注意在使用此功能之前,   请阅读Calling Internal APIs

其中说:(我强调了重要部分)

  

Winternl.h头文件公开   内部Windows API的原型。   没有关联的导入库,   所以开发人员必须使用运行时   动态链接调用函数   在此头文件中描述。

     

中的功能和结构   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 :(得分:1)

ZwCreateFile是Windows驱动程序工具包的一部分,而不是Windows SDK。您需要安装驱动程序工具包。 NTCreateFile使用的某些宏和类型也需要WDK头。 MSDN上的文档中明确说明了这一点。

答案 2 :(得分:1)

正如错误消息所明确指出的那样,您的调用约定错误,您删除了NTAPI。它应该是:

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

正确初始化myAttributes通常很重要。我没有看到你做任何可以保证调用未记录的本机API函数。只要你愿意,坚持使用CreateFile()。

答案 3 :(得分:1)

几种可能性:

  • 您说错误消息是“找不到_NTCreateFile标识符”。 API的名称为NtCreateFile()(请注意小写的“t”)。您可能只是使用了错误的名称。

  • ntifs.h及相关链接库包含在Windows驱动程序工具包(WDK)中,可从此处下载:http://www.microsoft.com/whdc/devtools/wdk/wdkpkg.mspx。您应该能够使用WDK比使用动态链接更直接地执行您想要的操作。但是你通常需要购买一个全新的构建系统,或者弄清楚如何将头文件和库集成到你当前的构建中。

  • 您可以使用dynamic linking technique outlined by ereOn