2

I'm investigating the Windows Native API now, Nt*/Zw* methods. I downloaded the WDK, installed it and successfully compiled an application (x64, under Win 8.1 x64, VS2013). The only thing it does is a call to NtOpenFile().

To successfully compile/link it, I had to make the following changes to project properties (template Application For Drivers):

  • Add includes folder from WDK
  • Add Lib folder from WDK
  • Tell linker to use ntoskrnl.lib

Unexpectedly, upon running a debugger, I'm presented with error message "The program can't start because C:\Windows\SYSTEM32\werkernel.sys is missing from your computer. Try reinstalling the program to fix this problem." The werkernel.sys obviously exists in system32\drivers.

EDIT: To be clear, the mentioned error also occurs when launching the app by doubleclicking the icon.

This load happens before any of my code, I can't find anything anywhere in internet nor in project properties on the file in question. So, to summarize, I have the following questions so far:

  1. Why werkernel.sys is being loaded at all for my application?
  2. Why is it being loaded from System32?

I understand that it is possible to mklink werkernel.sys drivers\werkernel.sys, but it feels like I'm doing somethig terribly wrong.

Mike Makarov
  • 1,287
  • 8
  • 17
  • I'm using Visual Studio. I have another application (in C#) that uses NtQueryDirectoryInformationFile() — and there everything works fine, so I didn't expect any problems with C++ code. Actually I want to use NtOpenFile in that C# app, but I stuck with 0xc000000d response from NtCreateFile, so I decided to play around with it using WDK just to see what I'm doing wrong on managed side. – Mike Makarov Mar 19 '15 at 09:30
  • What is the /SUBSYSTEM option set to? (Project properties, under Linker, System, Subsystem.) Also, have you tried using [ntdll.lib as documented](https://msdn.microsoft.com/en-us/library/bb432381%28v=vs.85%29.aspx) rather than ntoskrnl.lib? – Harry Johnston Mar 19 '15 at 22:07
  • Yes, this worked. Thank you! As I wrote below, I was confused by general "proxy" page for NtCreateFile redirecting to ZwCreateFile. It seems that where Zw* docs say one must link ntoskrnl.lib, in fact for NT* functions one must link ntdll.lib. – Mike Makarov Mar 20 '15 at 22:59
  • I believe you would link to ntoskrnl.lib for a device driver, and presumably for a native executable as well, but it isn't intended for use by a Win32 application. – Harry Johnston Mar 21 '15 at 04:09

2 Answers2

2

Linking ntdll.lib rather than ntoskrnl.lib worked for me when I had a similar problem.

user3553031
  • 5,990
  • 1
  • 20
  • 40
  • Thanks, this helped. I was confused by general NtOpenFile page redirecting to [ZwOpenFile](https://msdn.microsoft.com/en-us/library/windows/hardware/ff567011(v=vs.85).aspx) which tells to link ntkrnl.lib – Mike Makarov Mar 20 '15 at 22:51
1

NtOpenFile is what Microsoft calls "internal API", it should not be used for productional software, neither should it be used for experimentation or be used at all, these functions are subject to change between each SP-release or major windows-version.

If you want to open files in user-mode (WDK and usermode? Does not compute ... unless you're actually writing for UMDF) you are advised to use OpenFile :
https://msdn.microsoft.com/en-us/library/windows/desktop/aa365430(v=vs.85).aspx
or in your driver :
https://msdn.microsoft.com/en-us/library/windows/hardware/ff567011(v=vs.85).aspx.

tl;dr : dont use these old functions, they arent meant to be used.

Microsoft statement on "internal" API : https://msdn.microsoft.com/en-us/library/bb432200(v=vs.85).aspx

specializt
  • 1,913
  • 15
  • 26
  • This is a pretty old page you're referring to BTW. Nt/Zw functions are perfectly documented now. And if you want to know the reason to use native functions in this particular case - consider 0.35 sec for 2 calls to NtQueryDirectoryInformationFile() vs 12 sec (yes, twelve seconds!) for FindFirst/FindNext/FindClose. For NtOpenFile() I just hope it'll make the app even faster :) – Mike Makarov Mar 20 '15 at 22:56
  • using internal APIs does not make your application faster - thats a hugely mislead conclusion. The reason that some internal functions SEEM to be faster is a rather uncomfortable truth : wrong usage of the public API. You will not be able to gain more than a few microseconds for each Nt/Zw-call compared to the standard equivalents, your example pretty much is proof for you using the API in a wrong way. WINAPI is _extremely_ hard to master, only very few actually know how to do it properly. Oh and you're using the word "native" incorrectly - there are no non-native functions in WINAPI. – specializt Mar 20 '15 at 23:05
  • Microsoft use the word "native" in at least two different ways. One of them is the way Mike is using it - to describe functions that are part of the kernel as opposed to being part of a subsystem (such as Win32) or applications that run directly under the kernel rather than within a subsystem. See, for example, [the /SUBSYSTEM option](https://msdn.microsoft.com/en-us/library/fcc1zstk.aspx). – Harry Johnston Mar 21 '15 at 04:08
  • thats actually somewhat interesting; yet it still is pretty error-prone and useless to call "Native" functions directly - if your app is running slow 99,9999999999999999999999999% of the time it is your own fault. The "Native" API will be removed once they're able to do so, hence all of your applications will not work anymore in the foreseeable future. – specializt Mar 21 '15 at 11:52
  • @Mike: in the particular case of enumerating a directory, you should probably investigate GetFileInformationByHandleEx. – Harry Johnston Mar 21 '15 at 21:06