Kernel Api to Extract the Number From the unicode string.

hi
After Googling 4 hours of time did’t succeed in finding this so i am
posting this Query here.

i have a unicode string in driver sources like “COM4” and i want to
extract the Number “4” from the unicode string and coping/assinging that
number to a ULONG type variable.

i have tried using RtlUnicodeStringTointeger but did’t worked for me, might
be becuase of my string is in different format as that of
RtlUnicodeStringTointeger will work.

Is there any Kernel Api which will do my work. or else do i need to write
any some part of code to extract the numbers from the unicode string.

Please do provide the inputs to solve this.

thanks in advances.

There is no direct API to parse the string the way you have described. You are looking for something like sscanf(source, “COM%u”, &result) and that sort of function is not there. You can roll your own.

OTOH, if the data that you are trying to parse originated from user mode (via IOCTL), then you can also send the parsed data.

Also consider that many of the Rtl*Unicode*() functions [and Rtl*() functions operating on UNICODE_STRING] have an IRQL requirement of PASSIVE_LEVEL, so take that into consideration while using them in your solution.

Thank you Anand For ur reply.

this string i am getting from the Registry and i have achieved this from the this post “https://www.osronline.com/showthread.cfm?link=127630

i am also doing the same think in my driver’s AddDevice Routine. any how thank u for suggestions. i will take ur suggestions while implementing.

*num = *(USHORT*)(mystring->buffer+3);

Oh, and dont forget to substract the ascii code for zero.

Of course that assumes there are no more than 10 serial ports in a system.
I’ve supplied a driver for a board with 8 ports, which was used in multiples
in a Windows system.

The OP needs to think about using RtlPrefixUnicodeString to test if the
first three letters are “COM” and then use
RtlUnicodeStringToInteger after having adjusted the UNICODE_STRING structure
by adding 3 to the pointer, and removing 6 (3 *sizeof(WCHAR)) from length
and maximumlength.

Don Burn
Windows Driver Consulting
Website: http://www.windrvr.com

-----Original Message-----
From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com] On Behalf Of xxxxx@hotmail.com
Sent: Friday, March 03, 2017 9:39 AM
To: Windows System Software Devs Interest List
Subject: RE:[ntdev] Kernel Api to Extract the Number From the unicode
string.

Oh, and dont forget to substract the ascii code for zero.


NTDEV is sponsored by OSR

Visit the list online at:
http:

MONTHLY seminars on crash dump analysis, WDF, Windows internals and software
drivers!
Details at http:

To unsubscribe, visit the List Server section of OSR Online at
http:</http:></http:></http:>

The OP asked about COM4, no assumptions at all.

i have used the below code to extract a number from the unicode string and assinged to ULONG variable.
us.Length = us.MaximumLength = (USHORT)pvp->DataLength - 6;
us.Buffer = (PWSTR)(pvp->Data + 6);
RtlUnicodeStringToInteger( &us, 10, PortNr );

this logic is working fine for me even if i have more then 10 serial ports in my system.i have tested with more then 10 serial ports and the COM ports numbers are COM15,COM16… etc. its working fine for me.
@Don Burn: i am not getting what Your saying can u please elaborate more. is it there any problem in using above logic for extracting number from the unicode string if my system have more then 10 serial port devices.

@johnbasha shiak: Mr. Burn’s comment was in response to:

*num = *(USHORT*)(mystring->buffer+3);
Oh, and dont forget to substract the ascii code for zero.

NOT in response to using RtlUnicodeStringToInteger.

Peter
OSR
@OSRDrivers

If you use a NULL terminated string than us.MaximumLength and us.Length should not match.

MaximumLength is the size in bytes of the memory buffer used to store the string while Length is the size of the string in bytes (without the terminating NULL). So the buffer should be large enough to hold the string plus the NULL terminating character and so MaximumLength should equal at least Length + 2 for NULL terminated strings.

So you should do the following:

us.Length -= 6;
us.MaximumLength -= 6;
us.Buffer += 3;

Of course it is assumed that the string has at least a length of 6.

And depending on where the UNICODE_STRING came from remember to wind back the buffer pointer after you have extracted the numeric part or it.

Or just be safe an clone the UNICODE_STRING structure for the operation.

Don Burn
Windows Driver Consulting
Website: http://www.windrvr.com

-----Original Message-----
From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com] On Behalf Of xxxxx@hotmail.com
Sent: Wednesday, March 08, 2017 10:17 AM
To: Windows System Software Devs Interest List
Subject: RE:[ntdev] Kernel Api to Extract the Number From the unicode
string.

And depending on where the UNICODE_STRING came from remember to wind back
the buffer pointer after you have extracted the numeric part or it.


NTDEV is sponsored by OSR

Visit the list online at:
http:

MONTHLY seminars on crash dump analysis, WDF, Windows internals and software
drivers!
Details at http:

To unsubscribe, visit the List Server section of OSR Online at
http:</http:></http:></http:>

xxxxx@gmail.com wrote:

If you use a NULL terminated string than us.MaximumLength and us.Length should not match.

Since he is constructing a new UNICODE_STRING to wrap an existing buffer
specifically for the purpose of calling RtlUnicodeStringToInteger, this
comment does not apply. Indeed, it’s quite likely that
RtlUnicodeStringToInteger never even looks at the MaximumLength value.

MaximumLength is the size in bytes of the memory buffer used to store the string while Length is the size of the string in bytes (without the terminating NULL). So the buffer should be large enough to hold the string plus the NULL terminating character and so MaximumLength should equal at least Length + 2 for NULL terminated strings.

Zero termination is just not as important in kernel work as it is in
user mode. The only time you need to worry about a zero terminator in a
UNICODE_STRING is if you plan to pass the string to the standard library
routines that expect a wchar_t *. If you’re sticking with
UNICODE_STRING APIs, then the zero terminator is not an issue.


Tim Roberts, xxxxx@probo.com
Providenza & Boekelheide, Inc.

DataLength is most probably the member of the KEY_VALUE_FULL_INFORMATION or KEY_VALUE_PARTIAL_INFORMATION structure indicating the size of the data that was read from the registry. With a REG_SZ value, you have a NULL terminated string.

You *must* not assume the string returned from a REG_SZ query is null terminated. It is up to the writer of the value to null terminate and include the null in the number of bytes written

Bent from my phone


From: xxxxx@lists.osr.com on behalf of xxxxx@gmail.com
Sent: Wednesday, March 8, 2017 3:32:37 PM
To: Windows System Software Devs Interest List
Subject: RE:[ntdev] Kernel Api to Extract the Number From the unicode string.

DataLength is most probably the member of the KEY_VALUE_FULL_INFORMATION or KEY_VALUE_PARTIAL_INFORMATION structure indicating the size of the data that was read from the registry. With a REG_SZ value, you have a NULL terminated string.


NTDEV is sponsored by OSR

Visit the list online at: http:

MONTHLY seminars on crash dump analysis, WDF, Windows internals and software drivers!
Details at http:

To unsubscribe, visit the List Server section of OSR Online at http:</http:></http:></http:>

Yes, thank you Doron. I remember of registry cleaning apps searching for and deleting non-NULL terminated REG_SZ values.

So driver writers must check the last character.

> So driver writers must check the last character.

And especially - application writers and libraries writers.

(by the way… has requiring null terminator been fixed in WDF?)

– pa

xxxxx@gmail.com wrote:

DataLength is most probably the member of the KEY_VALUE_FULL_INFORMATION or KEY_VALUE_PARTIAL_INFORMATION structure indicating the size of the data that was read from the registry. With a REG_SZ value, you have a NULL terminated string.

But that’s totally irrelevant here. You have to understand the use
case. In this case, we simply do not care that the registry buffer
contained another two bytes. I am creating a UNICODE_STRING structure
to describe the string, not the buffer, because that’s what the consumer
of this information cares about.

If I’m using a UNICODE_STRING to describe a chunk of memory that I need
to free later, or if it is a UNICODE_STRING that I’ll need to modify or
extend, then it’s critical to have the MaximumLength describe the
buffer, not the contents. That’s just not the case in this example.


Tim Roberts, xxxxx@probo.com
Providenza & Boekelheide, Inc.

What specific WDF issue are you referring to?

-----Original Message-----
From: xxxxx@lists.osr.com [mailto:xxxxx@lists.osr.com] On Behalf Of xxxxx@fastmail.fm
Sent: Thursday, March 9, 2017 9:41 AM
To: Windows System Software Devs Interest List
Subject: RE:[ntdev] Kernel Api to Extract the Number From the unicode string.

> So driver writers must check the last character.

And especially - application writers and libraries writers.

(by the way… has requiring null terminator been fixed in WDF?)

– pa


NTDEV is sponsored by OSR

Visit the list online at: http:

MONTHLY seminars on crash dump analysis, WDF, Windows internals and software drivers!
Details at http:

To unsubscribe, visit the List Server section of OSR Online at http:</http:></http:></http:>

> What specific WDF issue are you referring to?

If you remember, some time ago there was an issue with registering COM ports and the strings with COM port names were not 0 terminated. I’ve looked on github and indeed the registry-reading code for REG_SZ (or MULTI_SZ?) demanded that values in registry are null terminated. IIRC it was not trivial to make a compact fix because the checking code was in a separate module/file from code tjhat allocates memory and reads. I have not dared then to propose to always allocate 2 bytes more for all registry reads…

– pa