Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Ntoskrnl exported functions

212 views
Skip to first unread message

John Buller

unread,
Jun 22, 2000, 3:00:00 AM6/22/00
to
Trying to build a printer driver for Windows NT 4.0

Ntoskrnl exports something called DbgPrint, according to depends.exe.
A prototype of DbgPrint exists in ntddk.h. In a brute-force approach,
I copied the prototype into my (printer driver) source file, inserted
a call to DbgPrint, and ran build. The linker can't find DbgPrint and
gives the usual "unresolved external symbol" error.

I tried the same thing with atoi, also exported by ntoskrnl.
I included stdlib.h for the prototype. The linker can't resolve that
either.

Is it possible that BUILD is not automatically trying to link to
ntoskrnl?
Build.log for the build contains the line
D:\DDK\lib\i386\checked\libcntpr.lib
as part of the link so I guess that's OK. What am I overlooking?

John Buller

James Antognini

unread,
Jun 22, 2000, 3:00:00 AM6/22/00
to
The linker should import ntoskrnl.lib. I've no idea from what you've said why it
isn't. You can force this via your sources file, eg,

TARGETLIBS=$(DDK_LIB_PATH)\ntoskrnl.lib

Note that the symbol is for Win2000. If you're targeting NT, it's a different
one. Look at other sources files in the DDK for an idea.

--
James Antognini
IBM Watson Research

John Buller

unread,
Jun 22, 2000, 3:00:00 AM6/22/00
to
I *did* spend a lot of time trying various things before I posted the first message.
Now it seems that the linker resolves atoi, but still can't resolve DbgPrint. I
don't think I changed anything. Thanks for telling me how to force the link. I think
I'll try that.

John

Rich Testardi

unread,
Jun 22, 2000, 3:00:00 AM6/22/00
to
Hi,

> Ntoskrnl exports something called DbgPrint, according to depends.exe.
> A prototype of DbgPrint exists in ntddk.h. In a brute-force approach,
> I copied the prototype into my (printer driver) source file, inserted
> a call to DbgPrint, and ran build. The linker can't find DbgPrint and
> gives the usual "unresolved external symbol" error.

How was the symbol decorated in the error message? I assume you're
using the NTDDK build environment... Which of these did it look like?

_cdecl: error LNK2001: unresolved external symbol _DbgPrint
_stdcall: error LNK2001: unresolved external symbol _DbgPrint@4
_fastcall: error LNK2001: unresolved external symbol @DbgPrint@4

If you got anything but the first one, your prototype or calling
conventions are declared wrong -- you *should* always get _cdecl for any
prototype for a varargs function, but for your atoi case, you could get
anything...

You can see the calling convention expected by the ntoskrnl.lib from

link -dump -exports ntoskrnl.lib | grep -E "atoi|DbgPrint"
_atoi
_DbgPrint

Both are _cdecl. The default calling convention for the NTDDK is
_stdcall -- that's what you get if you don't specify anything in your
prototype.

To get something else, you need a prototype like:

ULONG
_cdecl
DbgPrint(
PCH Format,
...
);

_CRTIMP int __cdecl atoi(const char *);

I'd use your source browser to determine *exactly* which prototype you're
using -- you might be getting an unexpected header file somewhere...
atoi is not in ntddk.h, so I assume you're using stdlib.h from the DDK.

You need to be especially careful with this stuff whenever you hand craft
(or copy) your own prototypes, which it sounds like you're doing...

If you want more on calling conventions, see:

www.microsoft.com/MSJ/0698/BUGSLAYER0698.HTM

Or if you can find it, check out Q100832.

Good luck.

Rich

Rich Testardi, #include <disclaimer.h>, EMC Corporation
Phone: +1-970-203-0937, E-mail: rtes...@emc.com
Street: http://home.interserv.com/~rtestard/address.htm
My webpage: http://home.interserv.com/~rtestard/
My dog's webpage: http://www.dogchow.com/pages/tc/
What better way to honor the giver than to love, cherish,
and enjoy the gift? What greater gift than life?

John Buller

unread,
Jun 22, 2000, 3:00:00 AM6/22/00
to
Rich,

Thanks for this information. The linker uses the symbol _DbgPrint. I
appreciate knowing about link -dump -exports, etc. I forced the link with
ntoskrnl in the manner suggested by James Antognini and now it works. The
sources file I copied from (Microsoft examples) didn't do this explicitly. I
know it sounds like I'm being reckless, just copying a prototype into my
source code - in fact it was exactly the one you suggested - but I'm only at
the point of trying to get *anything* to compile and link. Actually i've
just finished that and now I have to get it to work with windbg. Thanks
again.

John

James Antognini

unread,
Jun 22, 2000, 3:00:00 AM6/22/00
to
Are you using build to do the compilation and linking? Build should figure these
things out. In a command window, make your current directory the one where you
have your sources file (I'm assuming there's only one such directory involved;
build can handle more than one, but the procedure is a little different in the
latter case), and do:

build -cefM

(You can omit the 'M' if your machine isn't an MP. You'll get multithreading on
an MP.)

Maxim S. Shatskih

unread,
Jun 23, 2000, 3:00:00 AM6/23/00
to
> Trying to build a printer driver for Windows NT 4.0
>
> Ntoskrnl exports something called DbgPrint, according to depends.exe.

IIRC the GDI drivers are not allowed to call NTOSKRNL exports - only WIN32K
ones.
They use the different loader with different import resolution method.

Max

John Buller

unread,
Jun 23, 2000, 3:00:00 AM6/23/00
to
James,

I see that "build -cef" is recommended in the Microsoft documentation. I read the
docs on
those options and tried them. The build seems to work the same as the unadorned
"build" I
was using, but I'll use -cef now.

I solved at least part of the mystery. In my Sources file I set
TARGETTYPE=GDI_DRIVER since
that's what I'm trying for. I notice that the $(NTMAKEENV)\makefile.def contains
the
following:
...
!ELSEIF "$(TARGETTYPE)" == "DRIVER"
TARGETEXT=sys
TARGETLIB=$(SDK_LIB_PATH)\ntoskrnl.lib $(SDK_LIB_PATH)\hal.lib
...
!ELSEIF "$(TARGETTYPE)" == "GDI_DRIVER"
TARGETEXT=dll
TARGETLIB=$(SDK_LIB_PATH)\win32k.lib
!ENDIF # TARGETTYPE
...
So if I set my TARGETTYPE to "DRIVER" then I'll get an automatic link to ntoskrnl,
but the
result will be called "TextDrv1.sys" rather than "TextDrv1.dll". I think I can live
with
forcing the link explicitly.

The part of the mystery I haven't solved: When I look at the link info in build.log
I see
H:\DDK\lib\i386\checked\int64.lib
H:\DDK\lib\i386\checked\win32k.lib
H:\DDK\lib\i386\checked\pslib.lib
H:\DDK\lib\i386\checked\libcntpr.lib
H:\DDK\lib\i386\checked\ntoskrnl.lib
(These are arguments to the linker specified in a temporary file). The last three
come from
my Sources file, and win32k.lib is inserted by the GDI_DRIVER case in Makefile.def,
but
where does the int64.lib come from? Makefile.def does not contain the string
"int64".

Anyway the main question is cleared up to my satisfaction. I thought you or someone
else
might be interested in these details. Thanks again.

John

James Antognini

unread,
Jun 23, 2000, 3:00:00 AM6/23/00
to
I assume that int64.lib is provided by build itself. I've noticed that build
does things for (or "to") you, depending on the extension type (eg, .sys versus
.dll). For example, if you say in sources that you're building a dll, that build
will force ntdll.lib before ntoskrnl.lib. That's bad news if one intends to load
the executable into kernel space (eg, by ZwSetSystemInformation), because
ntdll.dll isn't loaded there and the attempt to load the dll will fail (I got
0xC000007A, STATUS_PROCEDURE_NOT_FOUND). I could get around the use of ntdll.lib
by manually editing the input to the linker and so ensuring that ntoskrnl.lib
came first, but I didn't find a way to get build to do that "automatically" if I
was creating a dll: build thinks it knows best (see my entry in this newsgroup
on 22 April 2000, under "Re: DLL Kernal-mode Driver for NT").

Using build should automatically ensure ntoskrnl.lib is used at link time, so it
ought not to be necessary to have that library in your sources.

Klaus Peter Gerlicher

unread,
Jun 29, 2000, 3:00:00 AM6/29/00
to
Oh boy, when writing GDI type drivers you cannot use anything NTOSKRNL
exports. Printer and Video driver can use EngDebugPrint() instead which is
actually just a wrapper for DbgPrint but exported by Win32k.sys.

Regards,

Klaus P. Gerlicher
S3/Professional Graphics

"John Buller" <jbu...@ica.net> wrote in message
news:3952191E...@ica.net...


> Trying to build a printer driver for Windows NT 4.0
>
> Ntoskrnl exports something called DbgPrint, according to depends.exe.

> A prototype of DbgPrint exists in ntddk.h. In a brute-force approach,
> I copied the prototype into my (printer driver) source file, inserted
> a call to DbgPrint, and ran build. The linker can't find DbgPrint and
> gives the usual "unresolved external symbol" error.
>

0 new messages