Tuesday, August 01, 2006

SystemParametersInfo: buffer size in unicode characters or bytes?

The SystemParametersInfo function in Windows CE can be tricky, even deadly, when it comes to passing in buffers for SPI_GETOEMINFO or SPI_GETPLATFORMTYPE.  Each of these uiAction values fill a given buffer with a string.  The uiParam argument takes the size of that buffer.  The catch is, for SPI_GETOEMINFO, uiParam takes a size of buffer in bytes and for SPI_GETPLATFORMTYPE uiParam takes the size of the buffer in count of unicode characters.



The documentation on SPI_GETOEMINFO is not precise on which type of buffer size is requested, and if you pass the wrong one to SPI_GETPLATFORMTYPE, you could find yourself in a buffer overrun situation.  Be careful.  The code below is safe:



#include "stdafx.h"

#define _countof(x) (sizeof(x) / sizeof(x[0]))

int _tmain(int argc, _TCHAR* argv[])
{
/**********************
* Get OEM information
**********************/

WCHAR wszOemInfo[50];
UINT cbOemInfo = sizeof(wszOemInfo);

if (SystemParametersInfoW(SPI_GETOEMINFO, cbOemInfo, wszOemInfo, 0))
MessageBoxW(NULL, wszOemInfo, L"OEMINFO", MB_OK);
else if (GetLastError() == ERROR_INSUFFICIENT_BUFFER)
MessageBoxW(NULL, L"Insufficient buffer", L"OEMINFO", MB_OK);
else
MessageBoxW(NULL, L"Some other error.", L"OEMINFO", MB_OK);


/**********************
* Get platform type
**********************/

WCHAR wszPlatformType[50];
UINT cchPlatformType = _countof(wszPlatformType);
if (SystemParametersInfoW(SPI_GETPLATFORMTYPE, cchPlatformType, wszPlatformType, 0))
MessageBoxW(NULL, wszPlatformType, L"Platform type", MB_OK);
else if (GetLastError() == ERROR_INSUFFICIENT_BUFFER)
MessageBoxW(NULL, L"Insufficient buffer", L"Platform type", MB_OK);
else
MessageBoxW(NULL, L"Some other error.", L"Platform type", MB_OK);

return 0;
}