[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