IoGetDevicePropertyData() bug checks with 0xF7

“However, as a standard pattern with NT APIs, if the API returns
STATUS_BUFFER_TOO_SMALL it’s typically fine to pass a length of zero and a
NULL buffer pointer to retrieve the size to allocate (what else would you
pass?).”

Unless the function is coded with a bug and will puke if you pass the NULL buffer, and good luck getting Microsoft to fix that, and even bigger luck with having to support systems without that quickfix installed. For example, ever tried to use StorPortNotify/LinkUp/LinkDown? Bang!

>For example, ever tried to use StorPortNotify/LinkUp/LinkDown? Bang!

Or pass a file object to ObQueryNameString on Win2K <= SP2, which would tell
you that the buffer was too small but fail to update the length to indicate
how big the buffer should be :slight_smile: If only we could all just count on the
latest and greatest being installed (but what fun would that be, really?).

-scott


Scott Noone
Consulting Associate and Chief System Problem Analyst
OSR Open Systems Resources, Inc.
http://www.osronline.com

wrote in message news:xxxxx@ntdev…

“However, as a standard pattern with NT APIs, if the API returns
STATUS_BUFFER_TOO_SMALL it’s typically fine to pass a length of zero and a
NULL buffer pointer to retrieve the size to allocate (what else would you
pass?).”

Unless the function is coded with a bug and will puke if you pass the NULL
buffer, and good luck getting Microsoft to fix that, and even bigger luck
with having to support systems without that quickfix installed. For example,
ever tried to use StorPortNotify/LinkUp/LinkDown? Bang!

This came up in my work just today. I was trying to figure out what a
Prefast warning was telling me and I read, carefully, the declaration of
ZwQueryValueKey. It explicitly says that NULL is allowed when Length is 0
and that the result will always be a failure status:

IRQL_requires_max(PASSIVE_LEVEL)
When(Length == 0, Post_satisfies(return < 0))
When(Length > 0, Post_satisfies(return <= 0))
NTSYSAPI
NTSTATUS
NTAPI
ZwQueryValueKey(
In HANDLE KeyHandle,
In PUNICODE_STRING ValueName,
In KEY_VALUE_INFORMATION_CLASS KeyValueInformationClass,
Out_writes_bytes_opt(Length) PVOID KeyValueInformation,
In ULONG Length,
Out PULONG ResultLength
);

Many interfaces follow this pattern.

Jake Oshins
Windows Kernel Team

This message implies no warranties and confers no rights.


“Scott Noone” wrote in message news:xxxxx@ntdev…

However, I read the docs and nowhere do they say the pointer is allowed to
be NULL.

The WDK docs can be incomplete or misleading. It’s in cases like this that
it would be exceptionally helpful to have a clear example of how to call the
API. I’m always amazed whenever I have to call a Win32 API and there’s a
nice, clean example of how to use the API in a useful way.

However, as a standard pattern with NT APIs, if the API returns
STATUS_BUFFER_TOO_SMALL it’s typically fine to pass a length of zero and a
NULL buffer pointer to retrieve the size to allocate (what else would you
pass?). Note that this is distinct from APIs that return
STATUS_BUFFER_OVERFLOW, which usually requires that you pass in some fixed
length buffer to determine the actual buffer length that you need to
allocate. In this particular case, a well placed breakpoint during boot will
show that the in box drivers call this API with a length of zero and a NULL
pointer to retrieve the size required.

-scott


Scott Noone
Consulting Associate and Chief System Problem Analyst
OSR Open Systems Resources, Inc.
http://www.osronline.com

wrote in message news:xxxxx@ntdev…

I find that quite often people feel *compelled* to create variables to
hold constant values, because the parameters say DWORD so they have to
have a DWORD variable. Uusually, this variable is declared at the head of
the function, and serves no purpose other than to hold the 0 value.

If this code fragment is incomplete, the OP should do a better job of
posting code fragments! Given what I see here, which is all I can believe
exists, the use of variables seems entirely gratuitous.

However, I read the docs and nowhere do they say the pointer is allowed to
be NULL.
joe

xxxxx@flounder.com wrote:
>> :frowning: No luck. Same bug check Tim
>> …
>> PVOID pDevicePropertyData = NULL;
>> DEVPROPKEY propertyKey = DEVPKEY_Device_Numa_Node;
>> ULONG bufferLength = 0;
>> DEVPROPTYPE devicePropertydataType;
>>
>>
>> status = IoGetDevicePropertyData(
>> FdoData->UnderlyingPDO, // PhysicalDeviceObject
>> &propertyKey,
>> LOCALE_NEUTRAL,
>> 0,
>> bufferLength,
>> pDevicePropertyData,
>> &returnedLength,
>> &devicePropertydataType
>> );
> Note that you are calling it with a buffer length of 0 and a NULL
> pointer.
> I did not see in the MSDN where this is a valid combination. Presumably
> it should be expected to return the correct value in &returnLength, but
> the docs are silent on this. And if you want to pass in 0,NULL, then
> the
> correct thing to do is pass in the values 0, NULL; you don’t need to use
> variables to hold these values!

Of course, Joe knows that there is absolutely no difference between
those. The function will see two zeros. It doesn’t care whether they
are constants or variables passed by value.

We’re not seeing all of the code here. I would not be surprised if this
were in “while” loop, where the first iteration passes these zeros, and
when the call completes, it shoves numbers in those variables and loops
again.


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


NTDEV is sponsored by OSR

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

This pattern is so common at the API level, I once found an API that did
it, even though the docs did not say so. They do now (I submitted a bug
report on it).

However, expecting kernel behavior to mimic user-mode behavior seems
risky. Which is why I was questioning the use of the NULL pointer.
joe

“However, as a standard pattern with NT APIs, if the API returns
STATUS_BUFFER_TOO_SMALL it’s typically fine to pass a length of zero and a
NULL buffer pointer to retrieve the size to allocate (what else would you
pass?).”

Unless the function is coded with a bug and will puke if you pass the NULL
buffer, and good luck getting Microsoft to fix that, and even bigger luck
with having to support systems without that quickfix installed. For
example, ever tried to use StorPortNotify/LinkUp/LinkDown? Bang!


NTDEV is sponsored by OSR

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