[fpc-pascal] Syserrormessage, parameter data type
Jürgen Hestermann
juergen.hestermann at gmx.de
Sat Oct 4 16:40:59 CEST 2014
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?
More information about the fpc-pascal
mailing list