GetCursorInfo() crashing on Windows NT 4 Service Pack 6.

Louis Solomon / SteelBytes
24/Feb/04

after a lot of investigation, this appears to be MS's fault (shock horror)
here's a workaround I wrote (in a minimal test harness):

#define STRICT
#define VC_EXTRALEAN
#define WIN32_LEAN_AND_MEAN
#include 
#pragma check_stack(off)
#pragma runtime_checks( "", off )
#pragma comment (linker, "/ENTRY:\"Entry_Point\"")
#undef RtlZeroMemory
extern "C" NTSYSAPI VOID NTAPI RtlZeroMemory (VOID UNALIGNED *Destination,SIZE_T Length);

__declspec(naked) static BOOL __stdcall Safe_GetCursorInfo(CURSORINFO *pci)
{
	_asm {
		push ebp // preseve the callers ebp
		mov ebp,esp // stash esp in ebp (ebp should not be destroyed by any func)
		push [esp+8] // push [pci]
		call dword ptr [GetCursorInfo] // call GetCursorInfo (whom trashes esp on nt4sp6)
		mov esp,ebp // get correct esp from our stash
		pop ebp // restore the callers ebp
		ret 4 // return with stdcall pop of params
	}
}

void WINAPI Entry_Point(void)
{
	CURSORINFO pci;
	ZeroMemory(&pci,sizeof(pci));
	pci.cbSize = sizeof(pci);
	char s[1024];
	if (Safe_GetCursorInfo(&pci))
	{
		wsprintf(s,
			"GetCursorInfo returned:\r\n"
			"\tcbSize: %i\r\n"
			"\tflags: %08x\r\n"
			"\thCursor: %08x\r\n"
			"\tptScreenPos: %i,%i",
			pci.cbSize,pci.flags,pci.hCursor,pci.ptScreenPos.x,pci.ptScreenPos.y);
	}
	else
	{
		DWORD error = GetLastError();
		LPVOID lpMsgBuf;
		FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER|FORMAT_MESSAGE_FROM_SYSTEM|FORMAT_MESSAGE_IGNORE_INSERTS,
			NULL,error,MAKELANGID(LANG_NEUTRAL,SUBLANG_DEFAULT),(LPTSTR)&lpMsgBuf,0,NULL);
		wsprintf(s,"GetCursorInfo failed\r\nGetLastError: %i %s",error,lpMsgBuf);
		LocalFree(lpMsgBuf);
	}
	MessageBox(NULL,s,"GetCursorInfo_Test",0);
	ExitProcess(0);
}