From the list of idiotic function signatures…

I stumbled on the function QueryWorkingSet today. It seems to be usable for solving a problem I have… What’s really amazing about this function is its totally braindead signature:

BOOL QueryWorkingSet(
  HANDLE hProcess,
  PVOID pv,
  DWORD cb
);

Please look beyond the weird Microsoft-isms with type names and the idiotic Hungarian notation. What does it do? Basically it takes a buffer (pv) of a certain length (cb) and tries to stuff some information in it. So, how big do we have to make the buffer? Who knows?

Microsoft seems to have a desire to force programmers to make 2 calls to each function that returns data in a buffer. Functions don’t take an int as the bufffer’s length, instead they take int *. The first call would pass in 0 as length (or rather a pointer to a variable that’s set to 0). The call would fail, but the value of the variable would be set to the required size of the buffer for a successful call.

So, back to QueryWorkingSet. How does one find out the required size of the buffer pv? The only way seems to be repeated calls with progressively larger buffers. Brilliant API Microsoft!

Share

4 Comments

  1. To get the needed size for QueryWorkingSet() try something like:

    DWORD dw, dwNeededSize; QueryWorkingSet(hProc, &dw, sizeof(DWORD)); dwNeededSize = (dw+1) * sizeof(DWORD_PTR); … QueryWorkingSet(hProc, some allocated buff, dwNeededSize);

    you will want to check for correct error codes etc (like ERROR_BAD_LENGTH) after the first call..

  2. What you are suggesting is that QueryWorkingSet() returns the size (well, actually a multiplier) in the “buffer” if the buffer size is too small.

    That is not consistent with the documentation of the function in MSDN. I’ll give it a shot and report on the results.

  3. Well, not exactly.

    Basically what the code does is passing a 4 byte PSAPI_WORKING_SET_INFORMATION structure to QueryWorkingSet(). The first 4 bytes of the structure is the NumberOfEntries member. If the buffer is 4 bytes or more but still too small he will still fill out the NumberOfEntries member. Once you have NumberOfEntries you can easily calculate the full size of the structure. (NumberOfEntries+1)*4 and you have the number of bytes the structure needs. This behaviour is not inconsistent with msdn’s documentation. But you’re right, they don’t document it at all. It’s a well know hack that’s been around at least since NT4. As with most hacks, the main drawback with it is that you don’t get to whine if they change this behaviour in future versions..

  4. Well, despite my being wrong initially I think you’ve just made my initial point anyway. Absolutely brilliant API. :-)

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>