"NUL" device is missing

C

Chuck Chopp

In my build of WinXPe that I have running under VMware Workstation v4.5.1, I
have an application that is failing due to the "NUL" device not being
present. The application depends on the "NUL" device to be present so that
it can count the # of bytes of output that are produced by one of the
fprintf() functions w/o actually having any output produced. The "NUL"
device is present on WinXP Home, WinXP Pro and WinXP Tablet PC, as well as
in all versions of WinNT v4.0, Win2K and Win2K3.

What component would I need to add to my WinXPe build in the Target Designer
in order to get the "NUL" device included in my build?


TIA,

Chuck
--
Chuck Chopp

ChuckChopp (at) rtfmcsi (dot) com http://www.rtfmcsi.com

RTFM Consulting Services Inc. 864 801 2795 voice & voicemail
103 Autumn Hill Road 864 801 2774 fax
Greer, SC 29651

Do not send me unsolicited commercial email.
 
K

KM

Chuck,

The "Session Manager (Windows subsystem)" is the component responsible for
registring NUL device (and other DOS devices). You have likely got it in
your image already.
You will also need "Null Device Driver" (the component visilibity is 200 so
make sure you've got proper settings for TD min.visibility level).

KM
 
C

Chuck Chopp

KM said:
Chuck,

The "Session Manager (Windows subsystem)" is the component responsible for
registring NUL device (and other DOS devices). You have likely got it in
your image already.
You will also need "Null Device Driver" (the component visilibity is 200 so
make sure you've got proper settings for TD min.visibility level).

KM


Thanks, that appears to have done the trick. It was the visibility level
that through me off.


I suppose I could eliminate my need for the NUL device if I could find a
different way to achieve what I'm doing with the printf() functions.
Basically, I'm using fopen() to open up a channel to the NULL device and
then I'm using fprintf() to write a formatted string out to it. This
results in fprintf() returning the # of bytes written. I then allocate that
amount of memory plus one additional byte [NULL terminator] and use it as
the buffer for a sprintf() call. If I could get the # of bytes to be
written out by the *printf() function w/o using the NULL device I'd be a
happy camper.


TIA,

Chuck
--
Chuck Chopp

ChuckChopp (at) rtfmcsi (dot) com http://www.rtfmcsi.com

RTFM Consulting Services Inc. 864 801 2795 voice & voicemail
103 Autumn Hill Road 864 801 2774 fax
Greer, SC 29651

Do not send me unsolicited commercial email.
 
K

KM

Chuck,
I suppose I could eliminate my need for the NUL device if I could find a
different way to achieve what I'm doing with the printf() functions.
Basically, I'm using fopen() to open up a channel to the NULL device and
then I'm using fprintf() to write a formatted string out to it. This
results in fprintf() returning the # of bytes written. I then allocate that
amount of memory plus one additional byte [NULL terminator] and use it as
the buffer for a sprintf() call. If I could get the # of bytes to be
written out by the *printf() function w/o using the NULL device I'd be a happy camper.

If you want to stick with CRT (specifically to xxxprintf), you basically need a version of the sprintf that does not require you to
allocate a big output buffer. I'd say it is an old know CRT issue.

If you don't need floating point conversions, you can use Win32 APIs like FormatMessage that will allocate the buffer for you.

Or you can implement your own safe version of sprintf (not using NUL even though I think it is not a bad way to do so). For example,
you can switch to _snprintf and iterate the process of allocating/reallocating the buffer on necessary size.

Here is an example for you: http://www.flipcode.com/cgi-bin/msg.cgi?showThread=COTD-SafeSprintf&forum=cotd&id=-1

KM
 
C

Chuck Chopp

KM said:
If you want to stick with CRT (specifically to xxxprintf), you basically need a version of the sprintf that does not require you to
allocate a big output buffer. I'd say it is an old know CRT issue.

If you don't need floating point conversions, you can use Win32 APIs like FormatMessage that will allocate the buffer for you.

Or you can implement your own safe version of sprintf (not using NUL even though I think it is not a bad way to do so). For example,
you can switch to _snprintf and iterate the process of allocating/reallocating the buffer on necessary size.

Here is an example for you: http://www.flipcode.com/cgi-bin/msg.cgi?showThread=COTD-SafeSprintf&forum=cotd&id=-1

Yes, I'd prefer to stay with standard CRT functions to keep this solution as
portable as possible. I need full support for all of the format specifiers
used in the *printf() functions, so the Win32 API functions won't work for me.

I'll probably stick with using the NUL device right now. I may end up
taking the time later to implement my own format parser that calculates the
required # of bytes of storage required to hold the formatted string, but I
don't have time to do it right now.


--
Chuck Chopp

ChuckChopp (at) rtfmcsi (dot) com http://www.rtfmcsi.com

RTFM Consulting Services Inc. 864 801 2795 voice & voicemail
103 Autumn Hill Road 864 801 2774 fax
Greer, SC 29651

Do not send me unsolicited commercial email.
 
K

KM

Chuck,

I'll probably stick with using the NUL device right now. I may end up
taking the time later to implement my own format parser that calculates the
required # of bytes of storage required to hold the formatted string, but I
don't have time to do it right now.

What VC version you are building against?
The reason I am asking is that the issue has been fixed in C standard of 99
year. Only VC 2003 has peaked up the fix.
The fix was to pass NULL to _snprintf to count the number of characters
required for a specified formating string. Basically, you can make a call
like: _snprintf(NULL,0,"%...",...) and it will return you the number.

You can easy track this down exploring CRT source of VC. In VC 6.0
(sprintf.h, output.c, stdio.h) you may see that the string formating routine
subcalls do not check for NULL. In VC 2003 CRT, they do (output.c, write_xxx
functions called from _output). This may be a cure for you. Also, there is
another useful wrapper (don't know if it is ANSI compatible) -
_scprintf(char* format,...) - this will return the same number of characters
you need.

Hope this helps,
KM
 
C

Chuck Chopp

KM said:
What VC version you are building against?
The reason I am asking is that the issue has been fixed in C standard of 99
year. Only VC 2003 has peaked up the fix.
The fix was to pass NULL to _snprintf to count the number of characters
required for a specified formating string. Basically, you can make a call
like: _snprintf(NULL,0,"%...",...) and it will return you the number.

You can easy track this down exploring CRT source of VC. In VC 6.0
(sprintf.h, output.c, stdio.h) you may see that the string formating routine
subcalls do not check for NULL. In VC 2003 CRT, they do (output.c, write_xxx
functions called from _output). This may be a cure for you. Also, there is
another useful wrapper (don't know if it is ANSI compatible) -
_scprintf(char* format,...) - this will return the same number of characters
you need.

I'm stuck using Visual C/C++ v6.0 right now w/o the option to move on up to
the Studio 2003 compiler. However, I will keep this in mind for future use.
I spent quite a bit of time last night reviewing the source code for the
CRT and had reached the point where everything comes down to a call to the
_output() function that does all of the dirty work. If it is one of the
string printf() types of functions, then a dummy _iob [a.k.a. "FILE"
structure] is worked up where it lookes like a valid file handle but really
points to the string buffer. I can see the counted vs. uncounted versions
set a member in the structure to limit define the output buffer size.
Still, it is the _output() function that does all of the work and I haven't
gone through and reviewe the source code for _output to see if it tests
properly for NULL. I think that in VC6 it doesnn't as I've had errors occur
when passing in a NULL pointer to sprintf(). I'll look at it all in more
detail today.

It is encouraging to hear than an updated ANSI C standard does finally
address this problem, though. I've got VS2003 .NET on hand and I will
review the CRT source code from it, too, to see what the differences in the
implementation look like. Perhaps I can cook up my own flavor of _output()
to use with VC6 in my own code to back-port that functionality and thus
remove the dependency on the NUL device.


--
Chuck Chopp

ChuckChopp (at) rtfmcsi (dot) com http://www.rtfmcsi.com

RTFM Consulting Services Inc. 864 801 2795 voice & voicemail
103 Autumn Hill Road 864 801 2774 fax
Greer, SC 29651

Do not send me unsolicited commercial email.
 
K

KM

Chuck,
I'm stuck using Visual C/C++ v6.0 right now w/o the option to move on up to
the Studio 2003 compiler. However, I will keep this in mind for future use.
I spent quite a bit of time last night reviewing the source code for the
CRT and had reached the point where everything comes down to a call to the
_output() function that does all of the dirty work. If it is one of the
string printf() types of functions, then a dummy _iob [a.k.a. "FILE"
structure] is worked up where it lookes like a valid file handle but really
points to the string buffer. I can see the counted vs. uncounted versions
set a member in the structure to limit define the output buffer size.
Still, it is the _output() function that does all of the work and I haven't
gone through and reviewe the source code for _output to see if it tests
properly for NULL. I think that in VC6 it doesnn't as I've had errors
occur

It does not. The _output will call to funtions like write_string,
write_char, etc. to output strings/character/etc. to the stream.
In VC 6.0 the write_xxxx funcitons do not check if stream->base
(stream->ptr) is NULL.
VC 2003 does it.
when passing in a NULL pointer to sprintf(). I'll look at it all in more
detail today.

It is encouraging to hear than an updated ANSI C standard does finally
address this problem, though. I've got VS2003 .NET on hand and I will
review the CRT source code from it, too, to see what the differences in the
implementation look like. Perhaps I can cook up my own flavor of _output()
to use with VC6 in my own code to back-port that functionality and thus
remove the dependency on the NUL device.

KM
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top