Re: Strange behaviour getting Device ID (calling KernelIoControl)
- From: voidcoder <voidcoder@xxxxxxxxx>
- Date: Thu, 22 Feb 2007 10:22:18 +0100
> - I can't understand why voidcoder said to use directly outBytes (is
> documented somewhere)?
It is a standard way to handle I/O calls on all Windows
platforms including CE. If you get the ERROR_INSUFFICIENT_BUFFER
error, the actual out size is returned through the "pOutSize"
parameter (unless the developer didn't follow the well known
standards when handling I/O requests ...).
Well, if you want to read yourself, here is it:
....
If an IOCTL caller passes in otherwise correct parameters with a buffer
that is too small (as determined by examining nOutSize), we will fail with
ERROR_INSUFFICIENT_BUFFER and return *pOutSize = minimum buffer size necessary
for success.
....
KernelIoControl
http://msdn2.microsoft.com/en-us/aa909165.aspx
Rob wrote:
I found that line of code in another example, but I think the problem is not in that line because:.
- in the real device I get 96 from that instruction (using also the code in http://groups.google.it/group/microsoft.public.pocketpc.developer/browse_thread/thread/bef6d7eb63e69684/e7606ac2036ad22f?lnk=st&q=KernelIoControl*delete&rnum=1&hl=it#e7606ac2036ad22f , I get 96 in di.dwSize member)
If, instead of calling that instruction, I call directly tempBufferSize = 96, I get the same bug (on emulator I get the same result, with obviously different buffer size).
- I can't understand exactly when u say "It looks like you think that the required size is coming back in the data member, not in the data size member ".
AFAIK, from the first call to KernelIoControl, if the buffer is insufficient, in the buffer is returned the real buffer size.
This is better seen from the other code linked above, where a DEVICE_ID structure is used: it gets the size from dwSize member.
DEVICE_ID is defined as
typedef struct _DEVICE_ID {
DWORD dwSize;
DWORD dwPresetIDOffset;
DWORD dwPresetIDBytes;
DWORD dwPlatformIDOffset;
DWORD dwPlatformIDBytes;
} DEVICE_ID, *PDEVICE_ID;
so using the first 4 bytes of the returned buffer should be analogous to reading dwSize member, isn't it?
(in my real code I really don't use the instruction *((UINT*) &tempBuffer[0]); , I use an analogous one that reads the first 4 bytes of the buffer).
- I can't understand why voidcoder said to use directly outBytes (is documented somewhere)? In my first call to KernelIoControl, if it works as voidcoder said, I should expect 96, while I really get 0, so I can't use it!
"<ctacke/>" <ctacke[@]opennetcf[dot]com> wrote in message news:Om0YhKhVHHA.496@xxxxxxxxxxxxxxxxxxxxxxxWhat on earth is this line all about?
tempBufferSize = *((UINT*) &tempBuffer[0]);
That's very likely the problem. It looks like you think that the required size is coming back in the data member, not in the data size member (plus that's a lot of indirection and dereferencing even if that were actually the case).
--
Chris Tacke - Embedded MVP
OpenNETCF Consulting
Managed Code in the Embedded World
www.opennetcf.com
--
"Rob" <r@xxxxx> wrote in message news:uBHlmGhVHHA.4844@xxxxxxxxxxxxxxxxxxxxxxxHi all,
I get a strange behaviour when I call KernelIoControl in order to get the DeviceID.
I report a partial code in order to show the instructions used (I removed uninfluential code).
I know that there are other working implementations (such as http://groups.google.it/group/microsoft.public.pocketpc.developer/browse_thread/thread/bef6d7eb63e69684/e7606ac2036ad22f?lnk=st&q=KernelIoControl*delete&rnum=1&hl=it#e7606ac2036ad22f), but I'd like to understand the problem in my code.
The problem happens if I call 2 times the GetDeviceID function consecutively:
- the first time, GetDeviceID behaves correctly: KernelIoControl is called 2 times, the first with the insufficient buffer;
- the second call to GetDeviceID reports a bug: the first time KernelIoControl returns TRUE, even if the buffer has insufficient size (and GetLastError returns 0).
The most strange thing is that the second GetDeviceID call behaves correctly if I remove the last "delete[] tempBuffer;" instruction: why I have this bug?
Am I missing something, or written something incorrectly? If I remove the last " delete[] tempBuffer;" I have a memory leak, isn't it?
I get this bug both on emulators and real device.
I altro tried to test it with Entrek Codesnitch utility, but I got an even stranger situation: under that tool, also the first call to GetDeviceID get TRUE even in the first KernelIoControl call, with the insufficient buffer.
This is the code:
---------------------------------------------------------------------------------------
#include <WINIOCTL.H>
#define IOCTL_HAL_GET_DEVICEID CTL_CODE(FILE_DEVICE_HAL, 21, METHOD_BUFFERED, FILE_ANY_ACCESS)
extern "C" __declspec(dllimport)
BOOL KernelIoControl(
DWORD dwIoControlCode,
LPVOID lpInBuf,
DWORD nInBufSize,
LPVOID lpOutBuf,
DWORD nOutBufSize,
LPDWORD lpBytesReturned);
void GetDeviceID()
{
DWORD outBytes = 0;
DWORD err;
DWORD tempBufferSize = 20;
BYTE *tempBuffer;
BOOL bRes;
tempBuffer = new BYTE[tempBufferSize];
while (true)
{
bRes = ::KernelIoControl(
IOCTL_HAL_GET_DEVICEID,
0,
0,
tempBuffer,
tempBufferSize,
&outBytes);
if (bRes) break;
err = GetLastError ();
if (ERROR_INSUFFICIENT_BUFFER == err)
{
tempBufferSize = *((UINT*) &tempBuffer[0]);
delete[] tempBuffer;
tempBuffer = new BYTE[tempBufferSize];
}
}
delete[] tempBuffer;
}
---------------------------------------------------------------------------------------
I know there are other implemen
- Follow-Ups:
- References:
- Prev by Date: Re: Strange behaviour getting Device ID (calling KernelIoControl)
- Next by Date: Re: Strange behaviour getting Device ID (calling KernelIoControl)
- Previous by thread: Re: Strange behaviour getting Device ID (calling KernelIoControl)
- Next by thread: Re: Strange behaviour getting Device ID (calling KernelIoControl)
- Index(es):
Relevant Pages
|