Kernel Mode is Stringing Me Along

So far, my experience with strings in kernel mode is very weird. Here’s what I want to do:

WCHAR stringA = L".doc";
WCHAR *stringB = (get this from a function call of some sort);

if (stricmp(stringA, stringB) == 0)
do_something_marginally_intersting();

Here is how I am able to do this in my driver;

PUNICODE_STRING puString = NULL;
puString = ExAllocatePoolWithTag(NonPagedPool, sizeof(UNICODE_STRING), TAGNAME);
RtlInitUnicodeString(puString, L".doc");
if (RtlCompareUnicodeString(puString, AnotherUnicodeString, TRUE) == 0)
do_something_that_might_or_not_blue_screen_my_system();

ExFreePoolWithTag(puString, TAGNAME);

What we have here is an explosion of code to do the simplest thing. I’m using *the* RTL library, but it seems to suck for what you might think is simple stuff.

Is there a better way or am I stuck converting every single little string I want to use into a UNICODE_STRING?

Thanks!

The kernel uses UNICODE_STRINGs; get used to it. Everyone finds it
painful at first.

But, there is a “safe string API” that you should probably look into

  • it’s a replacement for str*() in the kernel, and it has much more
    well-defined and carefully defined semantics. Look at <ntstrsafe.h>
    and RtlStringCch* and RtlStringCb* for more.

    -Steve

    On Nov 3, 2006, at 1:51 PM, xxxxx@hotmail.com wrote:

    > So far, my experience with strings in kernel mode is very weird.
    > Here’s what I want to do:
    >
    > WCHAR stringA = L".doc";
    > WCHAR *stringB = (get this from a function call of some sort);
    >
    > if (stricmp(stringA, stringB) == 0)
    > do_something_marginally_intersting();
    >
    > Here is how I am able to do this in my driver;
    >
    > PUNICODE_STRING puString = NULL;
    > puString = ExAllocatePoolWithTag(NonPagedPool, sizeof
    > (UNICODE_STRING), TAGNAME);
    > RtlInitUnicodeString(puString, L".doc");
    > if (RtlCompareUnicodeString(puString, AnotherUnicodeString, TRUE)
    > == 0)
    > do_something_that_might_or_not_blue_screen_my_system();
    >
    > ExFreePoolWithTag(puString, TAGNAME);
    >
    > What we have here is an explosion of code to do the simplest
    > thing. I’m using the RTL library, but it seems to suck for what
    > you might think is simple stuff.
    >
    > Is there a better way or am I stuck converting every single little
    > string I want to use into a UNICODE_STRING?
    >
    > Thanks!
    >
    >
    >
    > —
    > Questions? First check the IFS FAQ at https://www.osronline.com/
    > article.cfm?id=17
    >
    > You are currently subscribed to ntfsd as:
    > xxxxx@positivenetworks.net
    > To unsubscribe send a blank email to xxxxx@lists.osr.com</ntstrsafe.h>

If you want to use UNICODE_STRING (recommended), try:

UNICODE_STRING uString = RTL_CONSTANT_STRING( L".doc" );

if (RtlCompareUnicodeString(&uString, AnotherUnicodeString, TRUE) == 0)
do_something_that_might_or_not_blue_screen_my_system();

You can use wcsxxx routines (like _wcsicmp) if you know absolutely for
certain without a doubt that the strings are all null-terminated.

Ken

-----Original Message-----
From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com] On Behalf Of xxxxx@hotmail.com
Sent: Friday, November 03, 2006 2:52 PM
To: Windows File Systems Devs Interest List
Subject: [ntfsd] Kernel Mode is Stringing Me Along

So far, my experience with strings in kernel mode is very weird. Here’s
what I want to do:

WCHAR stringA = L".doc";
WCHAR *stringB = (get this from a function call of some sort);

if (stricmp(stringA, stringB) == 0)
do_something_marginally_intersting();

Here is how I am able to do this in my driver;

PUNICODE_STRING puString = NULL;
puString = ExAllocatePoolWithTag(NonPagedPool, sizeof(UNICODE_STRING),
TAGNAME);
RtlInitUnicodeString(puString, L".doc");
if (RtlCompareUnicodeString(puString, AnotherUnicodeString, TRUE) == 0)
do_something_that_might_or_not_blue_screen_my_system();

ExFreePoolWithTag(puString, TAGNAME);

What we have here is an explosion of code to do the simplest thing. I’m
using *the* RTL library, but it seems to suck for what you might think is
simple stuff.

Is there a better way or am I stuck converting every single little string I
want to use into a UNICODE_STRING?

Thanks!


Questions? First check the IFS FAQ at
https://www.osronline.com/article.cfm?id=17

You are currently subscribed to ntfsd as: xxxxx@comcast.net
To unsubscribe send a blank email to xxxxx@lists.osr.com

The call RtlInitUnicodeString() simply points the unicode.buffer value AT
the string you pass in. Hence there is no need to perform the allocation you
are doing. Do this:

UNICODE_STRING uniString;

RtlInitUnicodeString(&uniString, L".doc");

if (RtlCompareUnicodeString( &uniString, AnotherUnicodeString, TRUE) == 0)
do_something_that_might_or_not_blue_screen_my_system();

Pete

Kernel Drivers
Windows Filesystem and Device Driver Consulting
www.KernelDrivers.com
(303)546-0300

-----Original Message-----
From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com] On Behalf Of xxxxx@hotmail.com
Sent: Friday, November 03, 2006 12:52 PM
To: Windows File Systems Devs Interest List
Subject: [ntfsd] Kernel Mode is Stringing Me Along

So far, my experience with strings in kernel mode is very weird. Here’s
what I want to do:

WCHAR stringA = L".doc";
WCHAR *stringB = (get this from a function call of some sort);

if (stricmp(stringA, stringB) == 0)
do_something_marginally_intersting();

Here is how I am able to do this in my driver;

PUNICODE_STRING puString = NULL;
puString = ExAllocatePoolWithTag(NonPagedPool, sizeof(UNICODE_STRING),
TAGNAME);
RtlInitUnicodeString(puString, L".doc");
if (RtlCompareUnicodeString(puString, AnotherUnicodeString, TRUE) == 0)
do_something_that_might_or_not_blue_screen_my_system();

ExFreePoolWithTag(puString, TAGNAME);

What we have here is an explosion of code to do the simplest thing. I’m
using *the* RTL library, but it seems to suck for what you might think is
simple stuff.

Is there a better way or am I stuck converting every single little string I
want to use into a UNICODE_STRING?

Thanks!


Questions? First check the IFS FAQ at
https://www.osronline.com/article.cfm?id=17

You are currently subscribed to ntfsd as: xxxxx@kerneldrivers.com
To unsubscribe send a blank email to xxxxx@lists.osr.com

Thanks all. Peter, that makes a lot of sense.

> Is there a better way or am I stuck converting every single little string I
want to

use into a UNICODE_STRING?

Nearly all strings in the kernel are UNICODE_STRING, and this is correct - the
old-style C runtime functions working with zero-terminated strings are
vulnerable in terms of security if the string is too long.

So, “string with length” is used in Windows kernel instead of “zero-terminated
string”.

Maxim Shatskih, Windows DDK MVP
StorageCraft Corporation
xxxxx@storagecraft.com
http://www.storagecraft.com