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
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
> 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?
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
build -cefM
(You can omit the 'M' if your machine isn't an MP. You'll get multithreading on
an MP.)
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
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
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.
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.
>