wcsstr in kernel ?

I agree. This is not comparing pointers; wcsstr compares the strings the
pointers point to, character by character, and returns a pointer to the
character position in the second string where the first string appears.
So, for example, I might want to see if the file has the extension .txt.
So I might use wcsstr(L".txt", filename->Buffer). Now how could this
fail?

***********
Experienced programmers can stop reading here. This is elementary
programming stuff you could do in your sleep.
***********

Well, if I paeed in as the first argument as the Buffer member of a
UNICODE_STRING, it would not be guaranteed to be NUL-terminated, so wcsstr
will happily keep comparing characters. Suppose the UNICODE_STRING.Buffer
has the contents “.txt$” and the filename->Buffer is “myfile.txt%¥?”
Oops.

So, you say, you know that by using the literal, the first argument is
NUL-terminated. So it should work. And indeed it does, if the input is
“myfile.txt”. Even if it is “myfile.txt%¥?”, because it stops when it
finds “.txt” and you don’t overrun the length of the second string

So what happers if the string is “myfile.zip$&:?#%” and the next character
position is the first two bytes of a nonexistent page? Oops. BSOD.

What happens if the garbage I showed is not “$&:?#%” but “$&.txt”?

What if the user passes down “.TXT”?

What if the full path is given, and the string is
"\C\myprivatefiles\my.txtfuiles\oldfiles.zip?

So, you say, I can solve this by putting a NUL at the end of each string.
How are you going to do this? Unless you *know* there is space in the
buffer, you can’t do it. And even if you know there is space in the
buffer by detecting that MaximumLength>Length, you cannot be guaranteed
this will work for every possible input string. Most of the time, you can
expect that Length==MaximumLength (and remember this is a byte count, not
a character count). Bottom line: the CRT string manipulation functions
are, for all practical purposes, mostly useless.

We don’t have a spec on what is going on; we do have a silly assumption
that the input is 8-bit characters that are NUL-terminated, and the buffer
lentgh does not seem to be considered here. I am guessing in the absence
of useful description that this string is sent via DeviceIoControl, which
means the only sane way to do it is to provide both Unicode and 8-bit
versions, e.g.

#define IOCTL_MY_REQUESTA CTL_CODE(…stuff…)
#define IOCTL_MY_REQUESTW CTL_CODE(…slightly different stuff…)
#ifdef UNICODE
#define IOCTL_MY_REQUEST IOCTL_MY_REQUESTW
#else
#define IOCTL_MY_REQUEST IOCTL_MY_REQUESTA
#endif

and that, or some equally functional variant, is really the only
acceptable way to pass a string in. The conversion, 8-bit-to-Unicode, is
only performed for the -A variant. It cannot assume the string is
NUL-terminated. The result, a UNICODE_STRING, is derived from both
requests, and a pointer to that UNICODE_STRING is passed in to the
comparison routine, which must *NOT* be wcsstr. If there is no
equivalent Rtl function that works on UNICODE_STRINGs, then you have to
write one that works correctly.

*sigh*

Us: “You shouldn’t point a gun at your feet!”
You: “I know but it’s ok now, because I’m wearing flip-flops!”
Us: “Uhm… okie dokie.”

On Wed, May 29, 2013 at 5:06 AM, wrote:
>> The solution was really easy actually, instead of comparing the Buffer
>> member (which is PWSTR type), i was comparing the pointer directly so
>> that works
>>
>> if(wcsstr(procName->Buffer, proc.Buffer))
>> DbgPrint(“YOUPI !!”);
>>
>> procName is a PUNICODE_STRING which is the current process, and proc is
>> a UNICODE_STRING ( a proc name given from userland)
>>
>> —
>> NTDEV is sponsored by OSR
>>
>> OSR is HIRING!! See http://www.osr.com/careers
>>
>> For our schedule of WDF, WDM, debugging and other seminars visit:
>> http://www.osr.com/seminars
>>
>> To unsubscribe, visit the List Server section of OSR Online at
>> http://www.osronline.com/page.cfm?name=ListServer
>
> —
> NTDEV is sponsored by OSR
>
> OSR is HIRING!! See http://www.osr.com/careers
>
> For our schedule of WDF, WDM, debugging and other seminars visit:
> http://www.osr.com/seminars
>
> To unsubscribe, visit the List Server section of OSR Online at
> http://www.osronline.com/page.cfm?name=ListServer
>

>>strings if there are null terminated, if they are not, i add the null

> byte

It is very good that MS have disabled SSDT hooking. Providing such a
powerful tool for the developers which this experience and this amount
of professional common sense is just plain irresponsible :slight_smile:

I presume the :slight_smile: refers to how happy you are that Microsoft blocked SSDT
hooking (finally!) because the proper response to the experience/common
sense qualifications should be :frowning:
joe

> Thanks for all the nice comments !

It’s my first try writing a kernel driver, i’m just learning…

Well, i’ll explain a bit more what i’m trying to do.

I’m trying to write a tool like Process Monitor, which I’ll put some hooks
into the SSDT to monitor some functions.

The hooks work well, but it monitors every processes, and I want to
monitor functions calls only in a process name given by a ring3
application.

In order to do that, I use a function getCurrentProcName() which will
return the current process name (using a call to
ZwQueryInformationProcess()).

I received the process name which we want to monitor from userland in
dealing with IRP Write :

NTSTATUS IO_Write(PDEVICE_OBJECT DeviceObject, PIRP Irp)
{
NTSTATUS ntStatus = STATUS_SUCCESS;
PIO_STACK_LOCATION pIoStackIrp = NULL;

pIoStackIrp = IoGetCurrentIrpStackLocation(Irp);
if(pIoStackIrp)
{
pWriteDataBuffer = (PCHAR)Irp->AssociatedIrp.SystemBuffer;
if(pWriteDataBuffer)
{
// we check that the received string terminate with a null byte
if(pWriteDataBuffer[pIoStackIrp->Parameters.Write.Length] != 0)
pWriteDataBuffer[pIoStackIrp->Parameters.Write.Length] = 0;
****
Do you know ANYTHING about programming? This is simply a naïve (and
dangerous) non-solution to a problem. Using WriteFile is also insane; you
should be using DeviceIoControl. But what you have written here is a
Denial-of-Service (DoS) attack. And if you don’t understand why this is
true, you should not be programming in the kernel. Or in app space.
*****
DbgPrint(“Buffer received from userland : %s”, pWriteDataBuffer);
}
}
}

It works just fine, I received the correct string given from my app in
userland.
pWriteDataBuffer is a global PCHAR variable.
****
You really are totally clueless. Why in the name of all sanity would you
(a) assume the data is 8-bit characters and (b) use a global variable?

And it does ***NOT*** work “just fine”. The correct statement is “in the
one test I ran, it gave the illusion of working”. And I repeat my above
advice: if you don’t understand why 8-bit characters (only) makes no
sense, why a global PCHAR makes no sense, why adding the NUL character
makes no sense, and even if your PCHAR is NUL-terminated, why the
UNICODE_STRING you convert it to is most certainly NOT guaranteed to be
NUL-terminated, and synchronization issues (you use this global variable
without checking its validity), you should not be programming in the
kernel.

Oh, yes, what does the PCHAR point to? And what are you doing about
freeing resources that you have consumed?
joe
*****

My problem is that I want to print out the parameters of the functions
I’ve hooked only when they are called from the process given from
userland.

****
Someone who writes code that looks like what you have been showing us
should not be hooking SSDT entries.
****

So I need to compare the process name given from my function
GetCurrentProcName() which returns an UNICODE_STRING with the process name
given from userland (which is a PCHAR)

the GetCurrentProcName returns an unicode_string like :
“\Device\HarddiskVolume1\WINDOWS\system32\winlogon.exe”

and the process name from userland : “winlogon.exe”

So I need something like strstr(), I mean a function that will be able to
search a string into another one. Both strings are from different types,
so my idea was to convert the unicode_string to a PCHAR or the PCHAR to a
unicode_string and use strstr() or a similar function.

I hope you’ll understand it’s my first time dealing with kernel code, i’m
just trying to learn.

Thanks


NTDEV is sponsored by OSR

OSR is HIRING!! See http://www.osr.com/careers

For our schedule of WDF, WDM, debugging and other seminars visit:
http://www.osr.com/seminars

To unsubscribe, visit the List Server section of OSR Online at
http://www.osronline.com/page.cfm?name=ListServer

On Tue, May 28, 2013 at 6:41 PM, wrote:

> It shouldn’t even compile, because a const wchar_t is incompatible with
> PUNICODE_STRING. Now, assume that by some magic, the assignment takes
> place. Then it is pointing to some random place in memory, into which
> there will be an attempt to write the two USHORTs and the Buffer value.
> But string literals are normally placed in a write-protected segment, so
> the attempt to write into that space should take an access fault. Assume
> it has not been placed in write-protected memory, then it is pointing to a
> one-byte location in memory (the NUL character of a zero-length char
> literal). In Win32, it will write 8 bytes into that one-byte space; in
> Win64 it would write 12 byes into that one-byte space
>

a) it compiles at W2 with a warning.

b) that’s a lot of assumes. Actually it is quite possible the string
storage is not write protected, so the assignment will not toss an
exception.

In fact a user mode “release” version (not debug) of this crappy code both
compiles and runs.

#include “targetver.h”
#include <windows.h>
#include <ntsecapi.h>
#include <stdio.h>
#include <tchar.h>

int _tmain(int argc, _TCHAR* argv)
{
PUNICODE_STRING usProc = “”;
usProc->Length = 4;
usProc->MaximumLength = 6;

printf(“But really it works: %wZ\n”, usProc);

return 0;
}

Try it. Has to be compiled as “C” code. W2.

Mark Roddy</tchar.h></stdio.h></ntsecapi.h></windows.h>

I can’t try it (VS doesn’t run on my iPad), but here’s a couple variants
that should produce some interesting results:

PUNICODE_STRING s = “”;
s->Length = 4;
s->Buffer[s-\>Length] = 0;

or

PUNICODE_STRING s = “ABC”;

s->Length = 3;
if(s->Buffer[s-\>Length] != 0)
s->Buffer[s-\>Length] = 0;

The printf works by accident, because there is no typing done. Note that
it probably works correctly only for the empty string, and that, too, is
entirely by accident. It will probably fail catastrophically when %wZ
tries to print out an 8-bit string that actually has real characters. It
is amazing how many accidents have to happen to make even your simple “bad
example” give the illusion of working.

/W2 can be translated as “I love juggling bowling balls while standing on
thin ice”. Running a program that can’t pass /W2 without warnings
translates as “I like practicing dribbling bowling balls on thin ice”.

The warning should not be ignored.

Personally, I prefer to compie at /W4 and use the option “treat warnings
as errors”; someday Microsoft may finally fix ntddk.h so it doesn’t
generate warnings even if you don’t use a lot of #pragma warning
directives.

One of the advantages of using C++ in its “better C” mode is how uptight
it gets about type-checking.

By the way, my claim is erroneous, because it is not a const wchar_t, but
a const char *.

Also, I forgot to point out to the OP that UNICODE_STRING values for
Length and MaximumLength are /byte/ counts, not /character/ counts, so the
subscripting in the above example is wrong; it should be subscripted as
[s-\>length / sizeof(WCHAR)]. Which makes the code slightly less
erroneous, but not correct.

Using the WriteFile buffer length as a subscript on a Unicode string will,
of course, always be wrong. Assuming the input is 8-bit characters marks
the programmer as not having a good grasp of modern programming practice.
The correct solution would have been to use DeviceIoControl with both
8-bit and Unicode variants.

Using the length as a character subscript increases the chances that the
NUL assignment will clobber the header of the next storage block.
joe

On Tue, May 28, 2013 at 6:41 PM, wrote:
>
>> It shouldn’t even compile, because a const wchar_t is incompatible with
>> PUNICODE_STRING. Now, assume that by some magic, the assignment takes
>> place. Then it is pointing to some random place in memory, into which
>> there will be an attempt to write the two USHORTs and the Buffer value.
>> But string literals are normally placed in a write-protected segment, so
>> the attempt to write into that space should take an access fault.
>> Assume
>> it has not been placed in write-protected memory, then it is pointing to
>> a
>> one-byte location in memory (the NUL character of a zero-length char
>> literal). In Win32, it will write 8 bytes into that one-byte space; in
>> Win64 it would write 12 byes into that one-byte space
>>
>
> a) it compiles at W2 with a warning.
>
> b) that’s a lot of assumes. Actually it is quite possible the string
> storage is not write protected, so the assignment will not toss an
> exception.
>
> In fact a user mode “release” version (not debug) of this crappy code both
> compiles and runs.
>
>
>
> #include “targetver.h”
> #include <windows.h>
> #include <ntsecapi.h>
> #include <stdio.h>
> #include <tchar.h>
>
>
> int _tmain(int argc, _TCHAR* argv)
> {
> PUNICODE_STRING usProc = “”;
> usProc->Length = 4;
> usProc->MaximumLength = 6;
>
> printf(“But really it works: %wZ\n”, usProc);
>
> return 0;
> }
>
> Try it. Has to be compiled as “C” code. W2.
>
>
> Mark Roddy
>
> —
> NTDEV is sponsored by OSR
>
> OSR is HIRING!! See http://www.osr.com/careers
>
> For our schedule of WDF, WDM, debugging and other seminars visit:
> http://www.osr.com/seminars
>
> To unsubscribe, visit the List Server section of OSR Online at
> http://www.osronline.com/page.cfm?name=ListServer</tchar.h></stdio.h></ntsecapi.h></windows.h>

The point was that his crappy code actually compiled and ran. I completely
agree about C++ - I just refuse to compile anything in C mode if there is
an alternative, and always compile at the highest warning level with
warnings as errors. The fact that crappy code scribbling on static data
runs in the kernel is “interesting”.

Mark Roddy

On Thu, May 30, 2013 at 1:39 AM, wrote:

> I can’t try it (VS doesn’t run on my iPad), but here’s a couple variants
> that should produce some interesting results:
>
> PUNICODE_STRING s = “”;
> s->Length = 4;
> s->Buffer[s-&gt;Length] = 0;
>
> or
>
> PUNICODE_STRING s = “ABC”;
>
> s->Length = 3;
> if(s->Buffer[s-&gt;Length] != 0)
> s->Buffer[s-&gt;Length] = 0;
>
> The printf works by accident, because there is no typing done. Note that
> it probably works correctly only for the empty string, and that, too, is
> entirely by accident. It will probably fail catastrophically when %wZ
> tries to print out an 8-bit string that actually has real characters. It
> is amazing how many accidents have to happen to make even your simple “bad
> example” give the illusion of working.
>
> /W2 can be translated as “I love juggling bowling balls while standing on
> thin ice”. Running a program that can’t pass /W2 without warnings
> translates as “I like practicing dribbling bowling balls on thin ice”.
>
> The warning should not be ignored.
>
> Personally, I prefer to compie at /W4 and use the option “treat warnings
> as errors”; someday Microsoft may finally fix ntddk.h so it doesn’t
> generate warnings even if you don’t use a lot of #pragma warning
> directives.
>
> One of the advantages of using C++ in its “better C” mode is how uptight
> it gets about type-checking.
>
> By the way, my claim is erroneous, because it is not a const wchar_t, but
> a const char .
>
> Also, I forgot to point out to the OP that UNICODE_STRING values for
> Length and MaximumLength are /byte/ counts, not /character/ counts, so the
> subscripting in the above example is wrong; it should be subscripted as
> [s-&gt;length / sizeof(WCHAR)]. Which makes the code slightly less
> erroneous, but not correct.
>
> Using the WriteFile buffer length as a subscript on a Unicode string will,
> of course, always be wrong. Assuming the input is 8-bit characters marks
> the programmer as not having a good grasp of modern programming practice.
> The correct solution would have been to use DeviceIoControl with both
> 8-bit and Unicode variants.
>
> Using the length as a character subscript increases the chances that the
> NUL assignment will clobber the header of the next storage block.
> joe
>
> > On Tue, May 28, 2013 at 6:41 PM, wrote:
> >
> >> It shouldn’t even compile, because a const wchar_t is incompatible with
> >> PUNICODE_STRING. Now, assume that by some magic, the assignment takes
> >> place. Then it is pointing to some random place in memory, into which
> >> there will be an attempt to write the two USHORTs and the Buffer value.
> >> But string literals are normally placed in a write-protected segment, so
> >> the attempt to write into that space should take an access fault.
> >> Assume
> >> it has not been placed in write-protected memory, then it is pointing to
> >> a
> >> one-byte location in memory (the NUL character of a zero-length char
> >> literal). In Win32, it will write 8 bytes into that one-byte space; in
> >> Win64 it would write 12 byes into that one-byte space
> >>
> >
> > a) it compiles at W2 with a warning.
> >
> > b) that’s a lot of assumes. Actually it is quite possible the string
> > storage is not write protected, so the assignment will not toss an
> > exception.
> >
> > In fact a user mode “release” version (not debug) of this crappy code
> both
> > compiles and runs.
> >
> >
> >
> > #include “targetver.h”
> > #include <windows.h>
> > #include <ntsecapi.h>
> > #include <stdio.h>
> > #include <tchar.h>
> >
> >
> > int _tmain(int argc, _TCHAR
argv)
> > {
> > PUNICODE_STRING usProc = “”;
> > usProc->Length = 4;
> > usProc->MaximumLength = 6;
> >
> > printf(“But really it works: %wZ\n”, usProc);
> >
> > return 0;
> > }
> >
> > Try it. Has to be compiled as “C” code. W2.
> >
> >
> > Mark Roddy
> >
> > —
> > NTDEV is sponsored by OSR
> >
> > OSR is HIRING!! See http://www.osr.com/careers
> >
> > For our schedule of WDF, WDM, debugging and other seminars visit:
> > http://www.osr.com/seminars
> >
> > To unsubscribe, visit the List Server section of OSR Online at
> > http://www.osronline.com/page.cfm?name=ListServer
>
>
>
> —
> NTDEV is sponsored by OSR
>
> OSR is HIRING!! See http://www.osr.com/careers
>
> For our schedule of WDF, WDM, debugging and other seminars visit:
> http://www.osr.com/seminars
>
> To unsubscribe, visit the List Server section of OSR Online at
> http://www.osronline.com/page.cfm?name=ListServer
></tchar.h></stdio.h></ntsecapi.h></windows.h>

> The point was that his crappy code actually compiled and ran. I completely

agree about C++ - I just refuse to compile anything in C mode if there is
an alternative, and always compile at the highest warning level with
warnings as errors. The fact that crappy code scribbling on static data
runs in the kernel is “interesting”.

Mark Roddy

Which is a wonderful example for some of the students I am tutoring. They
have learned that “It doesn’t have to be correct as long as it runs well
enough to satisfy my professor”. I have tried to point out to them that,
literally, I have fired people for code much better than theirs but had
far more serious bugs. Your example is great for proving my point.
joe

On Thu, May 30, 2013 at 1:39 AM, wrote:
>
>> I can’t try it (VS doesn’t run on my iPad), but here’s a couple variants
>> that should produce some interesting results:
>>
>> PUNICODE_STRING s = “”;
>> s->Length = 4;
>> s->Buffer[s-&gt;Length] = 0;
>>
>> or
>>
>> PUNICODE_STRING s = “ABC”;
>>
>> s->Length = 3;
>> if(s->Buffer[s-&gt;Length] != 0)
>> s->Buffer[s-&gt;Length] = 0;
>>
>> The printf works by accident, because there is no typing done. Note
>> that
>> it probably works correctly only for the empty string, and that, too, is
>> entirely by accident. It will probably fail catastrophically when %wZ
>> tries to print out an 8-bit string that actually has real characters.
>> It
>> is amazing how many accidents have to happen to make even your simple
>> “bad
>> example” give the illusion of working.
>>
>> /W2 can be translated as “I love juggling bowling balls while standing
>> on
>> thin ice”. Running a program that can’t pass /W2 without warnings
>> translates as “I like practicing dribbling bowling balls on thin ice”.
>>
>> The warning should not be ignored.
>>
>> Personally, I prefer to compie at /W4 and use the option “treat warnings
>> as errors”; someday Microsoft may finally fix ntddk.h so it doesn’t
>> generate warnings even if you don’t use a lot of #pragma warning
>> directives.
>>
>> One of the advantages of using C++ in its “better C” mode is how uptight
>> it gets about type-checking.
>>
>> By the way, my claim is erroneous, because it is not a const wchar_t,
>> but
>> a const char .
>>
>> Also, I forgot to point out to the OP that UNICODE_STRING values for
>> Length and MaximumLength are /byte/ counts, not /character/ counts, so
>> the
>> subscripting in the above example is wrong; it should be subscripted as
>> [s-&gt;length / sizeof(WCHAR)]. Which makes the code slightly less
>> erroneous, but not correct.
>>
>> Using the WriteFile buffer length as a subscript on a Unicode string
>> will,
>> of course, always be wrong. Assuming the input is 8-bit characters
>> marks
>> the programmer as not having a good grasp of modern programming
>> practice.
>> The correct solution would have been to use DeviceIoControl with both
>> 8-bit and Unicode variants.
>>
>> Using the length as a character subscript increases the chances that the
>> NUL assignment will clobber the header of the next storage block.
>> joe
>>
>> > On Tue, May 28, 2013 at 6:41 PM, wrote:
>> >
>> >> It shouldn’t even compile, because a const wchar_t is incompatible
>> with
>> >> PUNICODE_STRING. Now, assume that by some magic, the assignment
>> takes
>> >> place. Then it is pointing to some random place in memory, into
>> which
>> >> there will be an attempt to write the two USHORTs and the Buffer
>> value.
>> >> But string literals are normally placed in a write-protected segment,
>> so
>> >> the attempt to write into that space should take an access fault.
>> >> Assume
>> >> it has not been placed in write-protected memory, then it is pointing
>> to
>> >> a
>> >> one-byte location in memory (the NUL character of a zero-length char
>> >> literal). In Win32, it will write 8 bytes into that one-byte space;
>> in
>> >> Win64 it would write 12 byes into that one-byte space
>> >>
>> >
>> > a) it compiles at W2 with a warning.
>> >
>> > b) that’s a lot of assumes. Actually it is quite possible the string
>> > storage is not write protected, so the assignment will not toss an
>> > exception.
>> >
>> > In fact a user mode “release” version (not debug) of this crappy code
>> both
>> > compiles and runs.
>> >
>> >
>> >
>> > #include “targetver.h”
>> > #include <windows.h>
>> > #include <ntsecapi.h>
>> > #include <stdio.h>
>> > #include <tchar.h>
>> >
>> >
>> > int _tmain(int argc, _TCHAR
argv)
>> > {
>> > PUNICODE_STRING usProc = “”;
>> > usProc->Length = 4;
>> > usProc->MaximumLength = 6;
>> >
>> > printf(“But really it works: %wZ\n”, usProc);
>> >
>> > return 0;
>> > }
>> >
>> > Try it. Has to be compiled as “C” code. W2.
>> >
>> >
>> > Mark Roddy
>> >
>> > —
>> > NTDEV is sponsored by OSR
>> >
>> > OSR is HIRING!! See http://www.osr.com/careers
>> >
>> > For our schedule of WDF, WDM, debugging and other seminars visit:
>> > http://www.osr.com/seminars
>> >
>> > To unsubscribe, visit the List Server section of OSR Online at
>> > http://www.osronline.com/page.cfm?name=ListServer
>>
>>
>>
>> —
>> NTDEV is sponsored by OSR
>>
>> OSR is HIRING!! See http://www.osr.com/careers
>>
>> For our schedule of WDF, WDM, debugging and other seminars visit:
>> http://www.osr.com/seminars
>>
>> To unsubscribe, visit the List Server section of OSR Online at
>> http://www.osronline.com/page.cfm?name=ListServer
>>
>
> —
> NTDEV is sponsored by OSR
>
> OSR is HIRING!! See http://www.osr.com/careers
>
> For our schedule of WDF, WDM, debugging and other seminars visit:
> http://www.osr.com/seminars
>
> To unsubscribe, visit the List Server section of OSR Online at
> http://www.osronline.com/page.cfm?name=ListServer</tchar.h></stdio.h></ntsecapi.h></windows.h>

I don’t disagree with what you are saying. I will add something more,
which I find a lot more interesting:

[Warning: generalizations follow]

We (collectively) don’t demand more from our compilers - which can and
should do a much better job at static analysis; we (collectively) are
averse at using static analysis tools like Lint and Polyspace which
can help detect such issues early; and, finally, when we
(collectively) try to get such tools we encounter a lot of resistance
from the people who approve purchase order but have a hard time
justifying an expense when they see little or no immediate value in
expensive software that won’t immediately and tangibly contribute to
the bottom line.

I used to wonder if other engineering disciplines have similar issues.
But something tells they don’t. Something tells me that an
aeronautical engineer demands that his design tools complain if he
tries to fit a square peg in a round hold. Something tells me that an
electrical engineer won’t have any qualms about using tools to verify
his design early and often. And something tells me that an accountant
wouldn’t question a structural engineer who asks to purchase an
expensive physics package to model the behavior of the bridge the firm
is designing.

On Thu, May 30, 2013 at 6:45 AM, Mark Roddy wrote:
> The point was that his crappy code actually compiled and ran. I completely
> agree about C++ - I just refuse to compile anything in C mode if there is an
> alternative, and always compile at the highest warning level with warnings
> as errors. The fact that crappy code scribbling on static data runs in the
> kernel is “interesting”.
>
>
> Mark Roddy
>
>
> On Thu, May 30, 2013 at 1:39 AM, wrote:
>>
>> I can’t try it (VS doesn’t run on my iPad), but here’s a couple variants
>> that should produce some interesting results:
>>
>> PUNICODE_STRING s = “”;
>> s->Length = 4;
>> s->Buffer[s-&gt;Length] = 0;
>>
>> or
>>
>> PUNICODE_STRING s = “ABC”;
>>
>> s->Length = 3;
>> if(s->Buffer[s-&gt;Length] != 0)
>> s->Buffer[s-&gt;Length] = 0;
>>
>> The printf works by accident, because there is no typing done. Note that
>> it probably works correctly only for the empty string, and that, too, is
>> entirely by accident. It will probably fail catastrophically when %wZ
>> tries to print out an 8-bit string that actually has real characters. It
>> is amazing how many accidents have to happen to make even your simple “bad
>> example” give the illusion of working.
>>
>> /W2 can be translated as “I love juggling bowling balls while standing on
>> thin ice”. Running a program that can’t pass /W2 without warnings
>> translates as “I like practicing dribbling bowling balls on thin ice”.
>>
>> The warning should not be ignored.
>>
>> Personally, I prefer to compie at /W4 and use the option “treat warnings
>> as errors”; someday Microsoft may finally fix ntddk.h so it doesn’t
>> generate warnings even if you don’t use a lot of #pragma warning
>> directives.
>>
>> One of the advantages of using C++ in its “better C” mode is how uptight
>> it gets about type-checking.
>>
>> By the way, my claim is erroneous, because it is not a const wchar_t, but
>> a const char .
>>
>> Also, I forgot to point out to the OP that UNICODE_STRING values for
>> Length and MaximumLength are /byte/ counts, not /character/ counts, so the
>> subscripting in the above example is wrong; it should be subscripted as
>> [s-&gt;length / sizeof(WCHAR)]. Which makes the code slightly less
>> erroneous, but not correct.
>>
>> Using the WriteFile buffer length as a subscript on a Unicode string will,
>> of course, always be wrong. Assuming the input is 8-bit characters marks
>> the programmer as not having a good grasp of modern programming practice.
>> The correct solution would have been to use DeviceIoControl with both
>> 8-bit and Unicode variants.
>>
>> Using the length as a character subscript increases the chances that the
>> NUL assignment will clobber the header of the next storage block.
>> joe
>>
>> > On Tue, May 28, 2013 at 6:41 PM, wrote:
>> >
>> >> It shouldn’t even compile, because a const wchar_t is incompatible with
>> >> PUNICODE_STRING. Now, assume that by some magic, the assignment takes
>> >> place. Then it is pointing to some random place in memory, into which
>> >> there will be an attempt to write the two USHORTs and the Buffer value.
>> >> But string literals are normally placed in a write-protected segment,
>> >> so
>> >> the attempt to write into that space should take an access fault.
>> >> Assume
>> >> it has not been placed in write-protected memory, then it is pointing
>> >> to
>> >> a
>> >> one-byte location in memory (the NUL character of a zero-length char
>> >> literal). In Win32, it will write 8 bytes into that one-byte space; in
>> >> Win64 it would write 12 byes into that one-byte space
>> >>
>> >
>> > a) it compiles at W2 with a warning.
>> >
>> > b) that’s a lot of assumes. Actually it is quite possible the string
>> > storage is not write protected, so the assignment will not toss an
>> > exception.
>> >
>> > In fact a user mode “release” version (not debug) of this crappy code
>> > both
>> > compiles and runs.
>> >
>> >
>> >
>> > #include “targetver.h”
>> > #include <windows.h>
>> > #include <ntsecapi.h>
>> > #include <stdio.h>
>> > #include <tchar.h>
>> >
>> >
>> > int _tmain(int argc, _TCHAR
argv)
>> > {
>> > PUNICODE_STRING usProc = “”;
>> > usProc->Length = 4;
>> > usProc->MaximumLength = 6;
>> >
>> > printf(“But really it works: %wZ\n”, usProc);
>> >
>> > return 0;
>> > }
>> >
>> > Try it. Has to be compiled as “C” code. W2.
>> >
>> >
>> > Mark Roddy
>> >
>> > —
>> > NTDEV is sponsored by OSR
>> >
>> > OSR is HIRING!! See http://www.osr.com/careers
>> >
>> > For our schedule of WDF, WDM, debugging and other seminars visit:
>> > http://www.osr.com/seminars
>> >
>> > To unsubscribe, visit the List Server section of OSR Online at
>> > http://www.osronline.com/page.cfm?name=ListServer
>>
>>
>>
>> —
>> NTDEV is sponsored by OSR
>>
>> OSR is HIRING!! See http://www.osr.com/careers
>>
>> For our schedule of WDF, WDM, debugging and other seminars visit:
>> http://www.osr.com/seminars
>>
>> To unsubscribe, visit the List Server section of OSR Online at
>> http://www.osronline.com/page.cfm?name=ListServer
>
>
> — NTDEV is sponsored by OSR OSR is HIRING!! See http://www.osr.com/careers
> For our schedule of WDF, WDM, debugging and other seminars visit:
> http://www.osr.com/seminars To unsubscribe, visit the List Server section of
> OSR Online at http://www.osronline.com/page.cfm?name=ListServer</tchar.h></stdio.h></ntsecapi.h></windows.h>

While C++ is going to complain more, the OP has reduced his warning
level. It does not matter whether it is C or C++ you can turn off the
complaints. Personally, I feel it is better to turn up the warning
level on C and not use “C++ as a better C”. If you want to use C++ for
specific features, then make the decision on those features, but there
is no checking the Microsoft C++ gives you that you cannot get with
Microsoft C and the correct settings.

Don Burn
Windows Filesystem and Driver Consulting
Website: http://www.windrvr.com
Blog: http://msmvps.com/blogs/WinDrvr

“Mark Roddy” wrote in message news:xxxxx@ntdev:

> The point was that his crappy code actually compiled and ran. I completely
> agree about C++ - I just refuse to compile anything in C mode if there is
> an alternative, and always compile at the highest warning level with
> warnings as errors. The fact that crappy code scribbling on static data
> runs in the kernel is “interesting”.
>
>
> Mark Roddy
>
>
> On Thu, May 30, 2013 at 1:39 AM, wrote:
>
> > I can’t try it (VS doesn’t run on my iPad), but here’s a couple variants
> > that should produce some interesting results:
> >
> > PUNICODE_STRING s = “”;
> > s->Length = 4;
> > s->Buffer[s-&gt;Length] = 0;
> >
> > or
> >
> > PUNICODE_STRING s = “ABC”;
> >
> > s->Length = 3;
> > if(s->Buffer[s-&gt;Length] != 0)
> > s->Buffer[s-&gt;Length] = 0;
> >
> > The printf works by accident, because there is no typing done. Note that
> > it probably works correctly only for the empty string, and that, too, is
> > entirely by accident. It will probably fail catastrophically when %wZ
> > tries to print out an 8-bit string that actually has real characters. It
> > is amazing how many accidents have to happen to make even your simple “bad
> > example” give the illusion of working.
> >
> > /W2 can be translated as “I love juggling bowling balls while standing on
> > thin ice”. Running a program that can’t pass /W2 without warnings
> > translates as “I like practicing dribbling bowling balls on thin ice”.
> >
> > The warning should not be ignored.
> >
> > Personally, I prefer to compie at /W4 and use the option “treat warnings
> > as errors”; someday Microsoft may finally fix ntddk.h so it doesn’t
> > generate warnings even if you don’t use a lot of #pragma warning
> > directives.
> >
> > One of the advantages of using C++ in its “better C” mode is how uptight
> > it gets about type-checking.
> >
> > By the way, my claim is erroneous, because it is not a const wchar_t, but
> > a const char .
> >
> > Also, I forgot to point out to the OP that UNICODE_STRING values for
> > Length and MaximumLength are /byte/ counts, not /character/ counts, so the
> > subscripting in the above example is wrong; it should be subscripted as
> > [s-&gt;length / sizeof(WCHAR)]. Which makes the code slightly less
> > erroneous, but not correct.
> >
> > Using the WriteFile buffer length as a subscript on a Unicode string will,
> > of course, always be wrong. Assuming the input is 8-bit characters marks
> > the programmer as not having a good grasp of modern programming practice.
> > The correct solution would have been to use DeviceIoControl with both
> > 8-bit and Unicode variants.
> >
> > Using the length as a character subscript increases the chances that the
> > NUL assignment will clobber the header of the next storage block.
> > joe
> >
> > > On Tue, May 28, 2013 at 6:41 PM, wrote:
> > >
> > >> It shouldn’t even compile, because a const wchar_t is incompatible with
> > >> PUNICODE_STRING. Now, assume that by some magic, the assignment takes
> > >> place. Then it is pointing to some random place in memory, into which
> > >> there will be an attempt to write the two USHORTs and the Buffer value.
> > >> But string literals are normally placed in a write-protected segment, so
> > >> the attempt to write into that space should take an access fault.
> > >> Assume
> > >> it has not been placed in write-protected memory, then it is pointing to
> > >> a
> > >> one-byte location in memory (the NUL character of a zero-length char
> > >> literal). In Win32, it will write 8 bytes into that one-byte space; in
> > >> Win64 it would write 12 byes into that one-byte space
> > >>
> > >
> > > a) it compiles at W2 with a warning.
> > >
> > > b) that’s a lot of assumes. Actually it is quite possible the string
> > > storage is not write protected, so the assignment will not toss an
> > > exception.
> > >
> > > In fact a user mode “release” version (not debug) of this crappy code
> > both
> > > compiles and runs.
> > >
> > >
> > >
> > > #include “targetver.h”
> > > #include <windows.h>
> > > #include <ntsecapi.h>
> > > #include <stdio.h>
> > > #include <tchar.h>
> > >
> > >
> > > int _tmain(int argc, _TCHAR
argv)
> > > {
> > > PUNICODE_STRING usProc = “”;
> > > usProc->Length = 4;
> > > usProc->MaximumLength = 6;
> > >
> > > printf(“But really it works: %wZ\n”, usProc);
> > >
> > > return 0;
> > > }
> > >
> > > Try it. Has to be compiled as “C” code. W2.
> > >
> > >
> > > Mark Roddy
> > >
> > > —
> > > NTDEV is sponsored by OSR
> > >
> > > OSR is HIRING!! See http://www.osr.com/careers
> > >
> > > For our schedule of WDF, WDM, debugging and other seminars visit:
> > > http://www.osr.com/seminars
> > >
> > > To unsubscribe, visit the List Server section of OSR Online at
> > > http://www.osronline.com/page.cfm?name=ListServer
> >
> >
> >
> > —
> > NTDEV is sponsored by OSR
> >
> > OSR is HIRING!! See http://www.osr.com/careers
> >
> > For our schedule of WDF, WDM, debugging and other seminars visit:
> > http://www.osr.com/seminars
> >
> > To unsubscribe, visit the List Server section of OSR Online at
> > http://www.osronline.com/page.cfm?name=ListServer
> ></tchar.h></stdio.h></ntsecapi.h></windows.h>

No actually C++ will not allow the assignment without a cast. Of course the
k0d3r will just put the cast in to make it compile…

Mark Roddy

On Thu, May 30, 2013 at 1:55 PM, Don Burn wrote:

> While C++ is going to complain more, the OP has reduced his warning level.
> It does not matter whether it is C or C++ you can turn off the complaints.
> Personally, I feel it is better to turn up the warning level on C and not
> use “C++ as a better C”. If you want to use C++ for specific features,
> then make the decision on those features, but there is no checking the
> Microsoft C++ gives you that you cannot get with Microsoft C and the
> correct settings.
>
>
>
> Don Burn
> Windows Filesystem and Driver Consulting
> Website: http://www.windrvr.com
> Blog: http://msmvps.com/blogs/**WinDrvr http:
>
>
>
>
> “Mark Roddy” wrote in message news:xxxxx@ntdev:
>
>
> The point was that his crappy code actually compiled and ran. I completely
>> agree about C++ - I just refuse to compile anything in C mode if there is
>> an alternative, and always compile at the highest warning level with
>> warnings as errors. The fact that crappy code scribbling on static data
>> runs in the kernel is “interesting”.
>>
>>
>> Mark Roddy
>>
>>
>> On Thu, May 30, 2013 at 1:39 AM, wrote:
>>
>> > I can’t try it (VS doesn’t run on my iPad), but here’s a couple variants
>> > that should produce some interesting results:
>> >
>> > PUNICODE_STRING s = “”;
>> > s->Length = 4;
>> > s->Buffer[s-&gt;Length] = 0;
>> >
>> > or
>> >
>> > PUNICODE_STRING s = “ABC”;
>> >
>> > s->Length = 3;
>> > if(s->Buffer[s-&gt;Length] != 0)
>> > s->Buffer[s-&gt;Length] = 0;
>> >
>> > The printf works by accident, because there is no typing done. Note
>> that
>> > it probably works correctly only for the empty string, and that, too, is
>> > entirely by accident. It will probably fail catastrophically when %wZ
>> > tries to print out an 8-bit string that actually has real characters.
>> It
>> > is amazing how many accidents have to happen to make even your simple
>> “bad
>> > example” give the illusion of working.
>> >
>> > /W2 can be translated as “I love juggling bowling balls while standing
>> on
>> > thin ice”. Running a program that can’t pass /W2 without warnings
>> > translates as “I like practicing dribbling bowling balls on thin ice”.
>> >
>> > The warning should not be ignored.
>> >
>> > Personally, I prefer to compie at /W4 and use the option “treat warnings
>> > as errors”; someday Microsoft may finally fix ntddk.h so it doesn’t
>> > generate warnings even if you don’t use a lot of #pragma warning
>> > directives.
>> >
>> > One of the advantages of using C++ in its “better C” mode is how uptight
>> > it gets about type-checking.
>> >
>> > By the way, my claim is erroneous, because it is not a const wchar_t,
>> but
>> > a const char .
>> >
>> > Also, I forgot to point out to the OP that UNICODE_STRING values for
>> > Length and MaximumLength are /byte/ counts, not /character/ counts, so
>> the
>> > subscripting in the above example is wrong; it should be subscripted as
>> > [s-&gt;length / sizeof(WCHAR)]. Which makes the code slightly less
>> > erroneous, but not correct.
>> >
>> > Using the WriteFile buffer length as a subscript on a Unicode string
>> will,
>> > of course, always be wrong. Assuming the input is 8-bit characters
>> marks
>> > the programmer as not having a good grasp of modern programming
>> practice.
>> > The correct solution would have been to use DeviceIoControl with both
>> > 8-bit and Unicode variants.
>> >
>> > Using the length as a character subscript increases the chances that the
>> > NUL assignment will clobber the header of the next storage block.
>> > joe
>> >
>> > > On Tue, May 28, 2013 at 6:41 PM, wrote:
>> > >
>> > >> It shouldn’t even compile, because a const wchar_t is incompatible
>> with
>> > >> PUNICODE_STRING. Now, assume that by some magic, the assignment
>> takes
>> > >> place. Then it is pointing to some random place in memory, into
>> which
>> > >> there will be an attempt to write the two USHORTs and the Buffer
>> value.
>> > >> But string literals are normally placed in a write-protected
>> segment, so
>> > >> the attempt to write into that space should take an access fault.
>> > >> Assume
>> > >> it has not been placed in write-protected memory, then it is
>> pointing to
>> > >> a
>> > >> one-byte location in memory (the NUL character of a zero-length char
>> > >> literal). In Win32, it will write 8 bytes into that one-byte space;
>> in
>> > >> Win64 it would write 12 byes into that one-byte space
>> > >>
>> > >
>> > > a) it compiles at W2 with a warning.
>> > >
>> > > b) that’s a lot of assumes. Actually it is quite possible the string
>> > > storage is not write protected, so the assignment will not toss an
>> > > exception.
>> > >
>> > > In fact a user mode “release” version (not debug) of this crappy code
>> > both
>> > > compiles and runs.
>> > >
>> > >
>> > >
>> > > #include “targetver.h”
>> > > #include <windows.h>
>> > > #include <ntsecapi.h>
>> > > #include <stdio.h>
>> > > #include <tchar.h>
>> > >
>> > >
>> > > int _tmain(int argc, _TCHAR
argv)
>> > > {
>> > > PUNICODE_STRING usProc = “”;
>> > > usProc->Length = 4;
>> > > usProc->MaximumLength = 6;
>> > >
>> > > printf(“But really it works: %wZ\n”, usProc);
>> > >
>> > > return 0;
>> > > }
>> > >
>> > > Try it. Has to be compiled as “C” code. W2.
>> > >
>> > >
>> > > Mark Roddy
>> > >
>> > > —
>> > > NTDEV is sponsored by OSR
>> > >
>> > > OSR is HIRING!! See http://www.osr.com/careers
>> > >
>> > > For our schedule of WDF, WDM, debugging and other seminars visit:
>> > > http://www.osr.com/seminars
>> > >
>> > > To unsubscribe, visit the List Server section of OSR Online at
>> > > http://www.osronline.com/page.**cfm?name=ListServerhttp:
>> >
>> >
>> >
>> > —
>> > NTDEV is sponsored by OSR
>> >
>> > OSR is HIRING!! See http://www.osr.com/careers
>> >
>> > For our schedule of WDF, WDM, debugging and other seminars visit:
>> > http://www.osr.com/seminars
>> >
>> > To unsubscribe, visit the List Server section of OSR Online at
>> > http://www.osronline.com/page. cfm?name=ListServerhttp:
>> >
>>
>
>
> —
> NTDEV is sponsored by OSR
>
> OSR is HIRING!! See http://www.osr.com/careers
>
> For our schedule of WDF, WDM, debugging and other seminars visit:
> http://www.osr.com/seminars
>
> To unsubscribe, visit the List Server section of OSR Online at
> http://www.osronline.com/page.
cfm?name=ListServerhttp:
></http:></http:></http:></tchar.h></stdio.h></ntsecapi.h></windows.h></http:>

Mark,

I haven’t checked it for a few years, but at one point that error
was could be disabled in Microsoft C++.

Don Burn
Windows Filesystem and Driver Consulting
Website: http://www.windrvr.com
Blog: http://msmvps.com/blogs/WinDrvr

“Mark Roddy” wrote in message news:xxxxx@ntdev:

> No actually C++ will not allow the assignment without a cast. Of course the
> k0d3r will just put the cast in to make it compile…
>
> Mark Roddy
>
>
> On Thu, May 30, 2013 at 1:55 PM, Don Burn wrote:
>
> > While C++ is going to complain more, the OP has reduced his warning level.
> > It does not matter whether it is C or C++ you can turn off the complaints.
> > Personally, I feel it is better to turn up the warning level on C and not
> > use “C++ as a better C”. If you want to use C++ for specific features,
> > then make the decision on those features, but there is no checking the
> > Microsoft C++ gives you that you cannot get with Microsoft C and the
> > correct settings.
> >
> >
> >
> > Don Burn
> > Windows Filesystem and Driver Consulting
> > Website: http://www.windrvr.com
> > Blog: http://msmvps.com/blogs/**WinDrvr http:
> >
> >
> >
> >
> > “Mark Roddy” wrote in message news:xxxxx@ntdev:
> >
> >
> > The point was that his crappy code actually compiled and ran. I completely
> >> agree about C++ - I just refuse to compile anything in C mode if there is
> >> an alternative, and always compile at the highest warning level with
> >> warnings as errors. The fact that crappy code scribbling on static data
> >> runs in the kernel is “interesting”.
> >>
> >>
> >> Mark Roddy
> >>
> >>
> >> On Thu, May 30, 2013 at 1:39 AM, wrote:
> >>
> >> > I can’t try it (VS doesn’t run on my iPad), but here’s a couple variants
> >> > that should produce some interesting results:
> >> >
> >> > PUNICODE_STRING s = “”;
> >> > s->Length = 4;
> >> > s->Buffer[s-&gt;Length] = 0;
> >> >
> >> > or
> >> >
> >> > PUNICODE_STRING s = “ABC”;
> >> >
> >> > s->Length = 3;
> >> > if(s->Buffer[s-&gt;Length] != 0)
> >> > s->Buffer[s-&gt;Length] = 0;
> >> >
> >> > The printf works by accident, because there is no typing done. Note
> >> that
> >> > it probably works correctly only for the empty string, and that, too, is
> >> > entirely by accident. It will probably fail catastrophically when %wZ
> >> > tries to print out an 8-bit string that actually has real characters.
> >> It
> >> > is amazing how many accidents have to happen to make even your simple
> >> “bad
> >> > example” give the illusion of working.
> >> >
> >> > /W2 can be translated as “I love juggling bowling balls while standing
> >> on
> >> > thin ice”. Running a program that can’t pass /W2 without warnings
> >> > translates as “I like practicing dribbling bowling balls on thin ice”.
> >> >
> >> > The warning should not be ignored.
> >> >
> >> > Personally, I prefer to compie at /W4 and use the option “treat warnings
> >> > as errors”; someday Microsoft may finally fix ntddk.h so it doesn’t
> >> > generate warnings even if you don’t use a lot of #pragma warning
> >> > directives.
> >> >
> >> > One of the advantages of using C++ in its “better C” mode is how uptight
> >> > it gets about type-checking.
> >> >
> >> > By the way, my claim is erroneous, because it is not a const wchar_t,
> >> but
> >> > a const char .
> >> >
> >> > Also, I forgot to point out to the OP that UNICODE_STRING values for
> >> > Length and MaximumLength are /byte/ counts, not /character/ counts, so
> >> the
> >> > subscripting in the above example is wrong; it should be subscripted as
> >> > [s-&gt;length / sizeof(WCHAR)]. Which makes the code slightly less
> >> > erroneous, but not correct.
> >> >
> >> > Using the WriteFile buffer length as a subscript on a Unicode string
> >> will,
> >> > of course, always be wrong. Assuming the input is 8-bit characters
> >> marks
> >> > the programmer as not having a good grasp of modern programming
> >> practice.
> >> > The correct solution would have been to use DeviceIoControl with both
> >> > 8-bit and Unicode variants.
> >> >
> >> > Using the length as a character subscript increases the chances that the
> >> > NUL assignment will clobber the header of the next storage block.
> >> > joe
> >> >
> >> > > On Tue, May 28, 2013 at 6:41 PM, wrote:
> >> > >
> >> > >> It shouldn’t even compile, because a const wchar_t is incompatible
> >> with
> >> > >> PUNICODE_STRING. Now, assume that by some magic, the assignment
> >> takes
> >> > >> place. Then it is pointing to some random place in memory, into
> >> which
> >> > >> there will be an attempt to write the two USHORTs and the Buffer
> >> value.
> >> > >> But string literals are normally placed in a write-protected
> >> segment, so
> >> > >> the attempt to write into that space should take an access fault.
> >> > >> Assume
> >> > >> it has not been placed in write-protected memory, then it is
> >> pointing to
> >> > >> a
> >> > >> one-byte location in memory (the NUL character of a zero-length char
> >> > >> literal). In Win32, it will write 8 bytes into that one-byte space;
> >> in
> >> > >> Win64 it would write 12 byes into that one-byte space
> >> > >>
> >> > >
> >> > > a) it compiles at W2 with a warning.
> >> > >
> >> > > b) that’s a lot of assumes. Actually it is quite possible the string
> >> > > storage is not write protected, so the assignment will not toss an
> >> > > exception.
> >> > >
> >> > > In fact a user mode “release” version (not debug) of this crappy code
> >> > both
> >> > > compiles and runs.
> >> > >
> >> > >
> >> > >
> >> > > #include “targetver.h”
> >> > > #include <windows.h>
> >> > > #include <ntsecapi.h>
> >> > > #include <stdio.h>
> >> > > #include <tchar.h>
> >> > >
> >> > >
> >> > > int _tmain(int argc, _TCHAR
argv)
> >> > > {
> >> > > PUNICODE_STRING usProc = “”;
> >> > > usProc->Length = 4;
> >> > > usProc->MaximumLength = 6;
> >> > >
> >> > > printf(“But really it works: %wZ\n”, usProc);
> >> > >
> >> > > return 0;
> >> > > }
> >> > >
> >> > > Try it. Has to be compiled as “C” code. W2.
> >> > >
> >> > >
> >> > > Mark Roddy
> >> > >
> >> > > —
> >> > > NTDEV is sponsored by OSR
> >> > >
> >> > > OSR is HIRING!! See http://www.osr.com/careers
> >> > >
> >> > > For our schedule of WDF, WDM, debugging and other seminars visit:
> >> > > http://www.osr.com/seminars
> >> > >
> >> > > To unsubscribe, visit the List Server section of OSR Online at
> >> > > http://www.osronline.com/page.**cfm?name=ListServerhttp:
> >> >
> >> >
> >> >
> >> > —
> >> > NTDEV is sponsored by OSR
> >> >
> >> > OSR is HIRING!! See http://www.osr.com/careers
> >> >
> >> > For our schedule of WDF, WDM, debugging and other seminars visit:
> >> > http://www.osr.com/seminars
> >> >
> >> > To unsubscribe, visit the List Server section of OSR Online at
> >> > http://www.osronline.com/page. cfm?name=ListServerhttp:
> >> >
> >>
> >
> >
> > —
> > NTDEV is sponsored by OSR
> >
> > OSR is HIRING!! See http://www.osr.com/careers
> >
> > For our schedule of WDF, WDM, debugging and other seminars visit:
> > http://www.osr.com/seminars
> >
> > To unsubscribe, visit the List Server section of OSR Online at
> > http://www.osronline.com/page.
cfm?name=ListServerhttp:
> ></http:></http:></http:></tchar.h></stdio.h></ntsecapi.h></windows.h></http:>

I have some wonderful examples of function pointers which were cast to
eliminate the warnings. Wonderful things happen like having a __stdcall
function with two arguments be called as if it were __cdecl with three
arguments. To use the analogy mentioned elswhere in this thread, it
allows you to insert a square peg in a round hole, by dressing it in round
peg clothing. AFAIK, the only place where function pointers actually
need to be cast is after GetProcAddress (which is, I think, the only API
call that accepts only 8-bit character pointers.
joe

No actually C++ will not allow the assignment without a cast. Of course
the
k0d3r will just put the cast in to make it compile…

Mark Roddy

On Thu, May 30, 2013 at 1:55 PM, Don Burn wrote:
>
>> While C++ is going to complain more, the OP has reduced his warning
>> level.
>> It does not matter whether it is C or C++ you can turn off the
>> complaints.
>> Personally, I feel it is better to turn up the warning level on C and
>> not
>> use “C++ as a better C”. If you want to use C++ for specific features,
>> then make the decision on those features, but there is no checking the
>> Microsoft C++ gives you that you cannot get with Microsoft C and the
>> correct settings.
>>
>>
>>
>> Don Burn
>> Windows Filesystem and Driver Consulting
>> Website: http://www.windrvr.com
>> Blog: http://msmvps.com/blogs/**WinDrvr
>> http:
>>
>>
>>
>>
>> “Mark Roddy” wrote in message news:xxxxx@ntdev:
>>
>>
>> The point was that his crappy code actually compiled and ran. I
>> completely
>>> agree about C++ - I just refuse to compile anything in C mode if there
>>> is
>>> an alternative, and always compile at the highest warning level with
>>> warnings as errors. The fact that crappy code scribbling on static data
>>> runs in the kernel is “interesting”.
>>>
>>>
>>> Mark Roddy
>>>
>>>
>>> On Thu, May 30, 2013 at 1:39 AM, wrote:
>>>
>>> > I can’t try it (VS doesn’t run on my iPad), but here’s a couple
>>> variants
>>> > that should produce some interesting results:
>>> >
>>> > PUNICODE_STRING s = “”;
>>> > s->Length = 4;
>>> > s->Buffer[s-&gt;Length] = 0;
>>> >
>>> > or
>>> >
>>> > PUNICODE_STRING s = “ABC”;
>>> >
>>> > s->Length = 3;
>>> > if(s->Buffer[s-&gt;Length] != 0)
>>> > s->Buffer[s-&gt;Length] = 0;
>>> >
>>> > The printf works by accident, because there is no typing done. Note
>>> that
>>> > it probably works correctly only for the empty string, and that, too,
>>> is
>>> > entirely by accident. It will probably fail catastrophically when
>>> %wZ
>>> > tries to print out an 8-bit string that actually has real characters.
>>> It
>>> > is amazing how many accidents have to happen to make even your simple
>>> “bad
>>> > example” give the illusion of working.
>>> >
>>> > /W2 can be translated as “I love juggling bowling balls while
>>> standing
>>> on
>>> > thin ice”. Running a program that can’t pass /W2 without warnings
>>> > translates as “I like practicing dribbling bowling balls on thin
>>> ice”.
>>> >
>>> > The warning should not be ignored.
>>> >
>>> > Personally, I prefer to compie at /W4 and use the option “treat
>>> warnings
>>> > as errors”; someday Microsoft may finally fix ntddk.h so it doesn’t
>>> > generate warnings even if you don’t use a lot of #pragma warning
>>> > directives.
>>> >
>>> > One of the advantages of using C++ in its “better C” mode is how
>>> uptight
>>> > it gets about type-checking.
>>> >
>>> > By the way, my claim is erroneous, because it is not a const wchar_t,
>>> but
>>> > a const char .
>>> >
>>> > Also, I forgot to point out to the OP that UNICODE_STRING values for
>>> > Length and MaximumLength are /byte/ counts, not /character/ counts,
>>> so
>>> the
>>> > subscripting in the above example is wrong; it should be subscripted
>>> as
>>> > [s-&gt;length / sizeof(WCHAR)]. Which makes the code slightly less
>>> > erroneous, but not correct.
>>> >
>>> > Using the WriteFile buffer length as a subscript on a Unicode string
>>> will,
>>> > of course, always be wrong. Assuming the input is 8-bit characters
>>> marks
>>> > the programmer as not having a good grasp of modern programming
>>> practice.
>>> > The correct solution would have been to use DeviceIoControl with both
>>> > 8-bit and Unicode variants.
>>> >
>>> > Using the length as a character subscript increases the chances that
>>> the
>>> > NUL assignment will clobber the header of the next storage block.
>>> > joe
>>> >
>>> > > On Tue, May 28, 2013 at 6:41 PM, wrote:
>>> > >
>>> > >> It shouldn’t even compile, because a const wchar_t is incompatible
>>> with
>>> > >> PUNICODE_STRING. Now, assume that by some magic, the assignment
>>> takes
>>> > >> place. Then it is pointing to some random place in memory, into
>>> which
>>> > >> there will be an attempt to write the two USHORTs and the Buffer
>>> value.
>>> > >> But string literals are normally placed in a write-protected
>>> segment, so
>>> > >> the attempt to write into that space should take an access fault.
>>> > >> Assume
>>> > >> it has not been placed in write-protected memory, then it is
>>> pointing to
>>> > >> a
>>> > >> one-byte location in memory (the NUL character of a zero-length
>>> char
>>> > >> literal). In Win32, it will write 8 bytes into that one-byte
>>> space;
>>> in
>>> > >> Win64 it would write 12 byes into that one-byte space
>>> > >>
>>> > >
>>> > > a) it compiles at W2 with a warning.
>>> > >
>>> > > b) that’s a lot of assumes. Actually it is quite possible the
>>> string
>>> > > storage is not write protected, so the assignment will not toss an
>>> > > exception.
>>> > >
>>> > > In fact a user mode “release” version (not debug) of this crappy
>>> code
>>> > both
>>> > > compiles and runs.
>>> > >
>>> > >
>>> > >
>>> > > #include “targetver.h”
>>> > > #include <windows.h>
>>> > > #include <ntsecapi.h>
>>> > > #include <stdio.h>
>>> > > #include <tchar.h>
>>> > >
>>> > >
>>> > > int _tmain(int argc, _TCHAR
argv)
>>> > > {
>>> > > PUNICODE_STRING usProc = “”;
>>> > > usProc->Length = 4;
>>> > > usProc->MaximumLength = 6;
>>> > >
>>> > > printf(“But really it works: %wZ\n”, usProc);
>>> > >
>>> > > return 0;
>>> > > }
>>> > >
>>> > > Try it. Has to be compiled as “C” code. W2.
>>> > >
>>> > >
>>> > > Mark Roddy
>>> > >
>>> > > —
>>> > > NTDEV is sponsored by OSR
>>> > >
>>> > > OSR is HIRING!! See http://www.osr.com/careers
>>> > >
>>> > > For our schedule of WDF, WDM, debugging and other seminars visit:
>>> > > http://www.osr.com/seminars
>>> > >
>>> > > To unsubscribe, visit the List Server section of OSR Online at
>>> > > http://www.osronline.com/page.**cfm?name=ListServerhttp:
>>> >
>>> >
>>> >
>>> > —
>>> > NTDEV is sponsored by OSR
>>> >
>>> > OSR is HIRING!! See http://www.osr.com/careers
>>> >
>>> > For our schedule of WDF, WDM, debugging and other seminars visit:
>>> > http://www.osr.com/seminars
>>> >
>>> > To unsubscribe, visit the List Server section of OSR Online at
>>> > http://www.osronline.com/page. cfm?name=ListServerhttp:
>>> >
>>>
>>
>>
>> —
>> NTDEV is sponsored by OSR
>>
>> OSR is HIRING!! See http://www.osr.com/careers
>>
>> For our schedule of WDF, WDM, debugging and other seminars visit:
>> http://www.osr.com/seminars
>>
>> To unsubscribe, visit the List Server section of OSR Online at
>> http://www.osronline.com/page.
cfm?name=ListServerhttp:
>>
>
> —
> NTDEV is sponsored by OSR
>
> OSR is HIRING!! See http://www.osr.com/careers
>
> For our schedule of WDF, WDM, debugging and other seminars visit:
> http://www.osr.com/seminars
>
> To unsubscribe, visit the List Server section of OSR Online at
> http://www.osronline.com/page.cfm?name=ListServer</http:></http:></http:></tchar.h></stdio.h></ntsecapi.h></windows.h></http:>

[quote]
We (collectively) don’t demand more from our compilers - which can and
should do a much better job at static analysis; we (collectively) are
averse at using static analysis tools like Lint and Polyspace which
can help detect such issues early;

True, we (software developers collectively) tend to be an odd bunch, I think.

Note that with Code Analysis (PreFAST) built directly into the WDK in VS 2012, and Static Driver Verifier also fully integrated (and run asynchronously)… you DO get a pretty decent set of tools for “free.” Also, turning on /W4 will get you all SORTS of interesting stuff.

Of course, if a dev’s going to turn down the warning level and not use the tools… not much we can do there.

Peter
OSR