In my programs I use this code quite often:
SysErrorMessage(GetLastError);But recently my program had a range check
error which let me have a look at the definiton
of the 2 functions GetLastError and SysErrorMessage. GetLastError is from the WinAPI:
----------------------------------------------------------- function GetLastError:DWORD; external 'kernel32' name 'GetLastError'; -----------------------------------------------------------
and SysErrorMessage is from SysUtils:
-----------------------------------------------------------
function SysErrorMessage(ErrorCode: Integer): String;
const MaxMsgSize = Format_Message_Max_Width_Mask;
var MsgBuffer: pChar;
begin
GetMem(MsgBuffer, MaxMsgSize);
FillChar(MsgBuffer^, MaxMsgSize, #0);
FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM,
nil,
ErrorCode, <----- 3rd Parameter
MakeLangId(LANG_NEUTRAL, SUBLANG_DEFAULT),
MsgBuffer, { This function allocs the memory }
MaxMsgSize, { Maximum message size }
nil);
SysErrorMessage := StrPas(MsgBuffer);
FreeMem(MsgBuffer, MaxMsgSize);
end;
-----------------------------------------------------------GetLastError yields a DWORD but SysErrorMessage expects an INTEGER. Why? This raises a range check for all error codes >2^31.
A closer look at SysErrorMessage shows that the ERRORCODE will not be used in this routine but only handed over to FormatMessageA which expects a DWORD!
-----------------------------------------------------------
function FormatMessageA(dwFlags:DWORD;
lpSource:LPCVOID;
dwMessageId:DWORD; <----- 3rd Parameter
dwLanguageId:DWORD;
lpBuffer:LPSTR;
nSize:DWORD;
Arguments:va_list):DWORD; external 'kernel32' name 'FormatMessageA';
-----------------------------------------------------------So if GetLastError gives a DWORD and FormatMessageA expects a DWORD shouldn't SysErrorMessage use a DWORD too?
