News:

Download Pelles C here: http://www.pellesc.se

Main Menu

Recent posts

#11
Feature requests / Enhanced editor suggestion #2
Last post by PhilG57 - February 15, 2026, 02:16:00 PM
A user selectable (on or off) editor feature to display the status of variables.  Ideally the feature would show whether a variable is local, global, static, described in this file or another file, etc. 

This capability would make it easier locating variables in large multi-file projects and might even help to reduce the number of variables described or defined.  I do love your editor's 'find in files' feature though. 
#12
Feature requests / Enhanced editor suggestion
Last post by PhilG57 - February 14, 2026, 05:58:31 PM
I often mess around with existing code written years ago, often for systems other than Windows.  It would be helpful to me if the editor would show which #ifdef/#else/#endif paths were active.  This might be done by highlighting, or not, the appropriate code sections.  Sometime I run into multiple, nested #ifdef's and sorting it all out is a big pain.  Thanks.
#13
General discussions / Re: Retrieving information fro...
Last post by TimoVJL - February 13, 2026, 05:39:49 PM
An adaptation to Matt Pietrek's code for library files.
Yes, an very old code and you can fix it.
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>

extern TCHAR *szAppName;

extern void WriteOut(HWND hWnd, TCHAR *szText);
DWORD ConvertBigEndian(DWORD bigEndian);
BOOL IsRegularLibSymbol(PSTR pszSymbolName);

//=============================================================================
// Other miscellaneous variables and macros
//=============================================================================
// MakePtr is a macro that allows you to easily add to values (including
// pointers) together without dealing with C's pointer arithmetic.  It
// essentially treats the last two parameters as DWORDs.  The first
// parameter is used to typecast the result to the appropriate pointer type.
#define MakePtr( cast, ptr, addValue ) (cast)( (DWORD_PTR)(ptr) + (DWORD_PTR)(addValue))

//=============================================================================
// Start of program code
//=============================================================================

int ProcessFileLibExp(HWND hWnd, PBYTE pMappedFileBase, int iOpt)
{
    TCHAR szTmp[260];

    //if (0 != strncmp((PCHAR)pMappedFileBase, IMAGE_ARCHIVE_START, IMAGE_ARCHIVE_START_SIZE))
    if (0 != memcmp((PCHAR)pMappedFileBase, IMAGE_ARCHIVE_START, IMAGE_ARCHIVE_START_SIZE))
    {
        //wsprintf(szTmp, TEXT("Not a valid COFF LIB file\n"));
        //WriteOut(hWnd, szTmp);
        MessageBox(NULL, TEXT("Not a valid COFF LIB file\n"), szAppName, MB_OK);
        return 4;
    }
    //WriteOut(hWnd, TEXT("test"));
    // Point to the first archive member.  This entry contains the LIB symbols,
    // and immediately follows the archive start string ("!<arch>\n")
    PIMAGE_ARCHIVE_MEMBER_HEADER pMbrHdr;
    pMbrHdr = MakePtr(PIMAGE_ARCHIVE_MEMBER_HEADER, pMappedFileBase, IMAGE_ARCHIVE_START_SIZE);
    // First DWORD after this member header is a symbol count
    PDWORD pcbSymbols = (PDWORD) (pMbrHdr + 1);    // Pointer math!
    // Following the symbol count is an array of offsets to archive members
    // (essentially, embedded .OBJ files)
    PDWORD pMemberOffsets = pcbSymbols + 1;    // Pointer math!
    // Second header MS libs
    PIMAGE_ARCHIVE_MEMBER_HEADER pMbrHdr2;
    DWORD dwOfs = strtol((char*)pMbrHdr->Size, NULL, 10) + IMAGE_SIZEOF_ARCHIVE_MEMBER_HDR;
    pMbrHdr2 = MakePtr(PIMAGE_ARCHIVE_MEMBER_HEADER, pMbrHdr, dwOfs);
    int iHdr;
    DWORD cSymbols;
    PSTR pszSymbolName, pszSymbolName2 = 0;
    PDWORD pMemberOffsets2 = 0;
    PWORD pIndices = 0;
    if (*(BYTE*)pMbrHdr2 == '/') {     // second header found ?
        iHdr = 2;
        // First DWORD after this member header is a member count of Offset table
       
        PDWORD pcbSMembers2 = (PDWORD) (pMbrHdr2 + 1);    // Pointer math!
        // After that there is symbol count of Index table
        PDWORD pcbSymbols2 = (PDWORD) (pMbrHdr2 + 1) + *pcbSMembers2 + 1;
        cSymbols = *pcbSymbols2;    // use second header symbol count
        pMemberOffsets2 = pcbSMembers2 + 1;    // Pointer math!
        pIndices = MakePtr(PWORD, pMemberOffsets2, *pcbSMembers2 * sizeof(DWORD) + sizeof(DWORD));

        // Following the array of member offsets is an array of offsets to symbol
        // names.
        pszSymbolName2 = MakePtr(PSTR, pcbSymbols2, cSymbols * sizeof(WORD) + sizeof(DWORD));
        pszSymbolName = pszSymbolName2;
    } else {
        iHdr = 1;    // no second header
        // First DWORD after this member header is a symbol count
        //PDWORD pcbSymbols = (PDWORD) (pMbrHdr + 1);    // Pointer math!
        // The symbol count is stored in big endian format, so adjust as
        // appropriate for the target architecture
        cSymbols = ConvertBigEndian(*pcbSymbols);

        // Following the symbol count is an array of offsets to archive members
        // (essentially, embedded .OBJ files)
        pMemberOffsets = pcbSymbols + 1;    // Pointer math!

        // Following the array of member offsets is an array of offsets to symbol
        // names.
        pszSymbolName = MakePtr(PSTR, pMemberOffsets, 4 * cSymbols);
    }
    // Find module name first
    BOOL bImports = 0;
    for (unsigned i = 0; i < cSymbols; i++)
    {
        //if (LibSymbolType(pszSymbolName) == 2) {
        if (0 == memcmp(pszSymbolName, "__IMPORT_DESCRIPTOR_", 20)) {
            bImports = 1;
            wsprintf(szTmp, TEXT("LIBRARY %hs\n"), pszSymbolName+20);
            WriteOut(hWnd, szTmp);
            break;
        }

        if (0 == memcmp(pszSymbolName, "__head_lib32_lib", 16)
            || 0 == memcmp(pszSymbolName, "__head_lib64_lib", 16)
            || 0 == memcmp(pszSymbolName, "__head_lib", 10)) {
            bImports = 1;
            if (*(pszSymbolName+10) != '3' && *(pszSymbolName+10) != '6')
                wsprintf(szTmp, TEXT("LIBRARY %hs"), pszSymbolName+10);
            else wsprintf(szTmp, TEXT("LIBRARY %hs"), pszSymbolName+16);
            int nLen = lstrlen(szTmp);
            szTmp[nLen-2] = 10;
            szTmp[nLen-1] = 0;
            WriteOut(hWnd, szTmp);
            break;
        }

        pMemberOffsets++;    // only for first header
        pszSymbolName += strlen(pszSymbolName) + 1;
    }
    if (!bImports) return 1;    // no export for def file, just give up
    //wsprintf(szTmp, "LIBRARY %s\nEXPORTS\n", pTmp);
    wsprintf(szTmp, TEXT("EXPORTS\n"));
    WriteOut(hWnd, szTmp);

    if (iHdr == 1) {
        // Following the symbol count is an array of offsets to archive members
        // (essentially, embedded .OBJ files)
        pMemberOffsets = pcbSymbols + 1;    // Pointer math!
        // Following the array of member offsets is an array of offsets to symbol
        // names.
        pszSymbolName = MakePtr(PSTR, pMemberOffsets, 4 * cSymbols);
    } else
        pszSymbolName = pszSymbolName2;
    // Loop through every symbol in the second archive member
    //     
    for (unsigned i = 0; i < cSymbols; i++)
    {
        // Call DisplayLibInfoForSymbol, which figures out what kind of symbol
        // it is.  The "IsRegularLibSymbol" filters out symbols that are
        // internal to the linking process
        //printf(TEXT("%04X %hs\n"), offset, pszSymbolName);
        //if (LibSymbolType(pszSymbolName) == 1) {
        if (0 == memcmp(pszSymbolName, "__imp_", 6)) {
            if (iOpt == 1 || iOpt > 4)
                wsprintf(szTmp, TEXT("%hs\n"), pszSymbolName + 6);
            else if (iOpt == 2)
                wsprintf(szTmp, TEXT("\"%hs\"\n"), pszSymbolName + 6);
            else if (iOpt == 3) {
                TCHAR szFunc[260];
                wsprintf(szFunc, TEXT("%hs"), pszSymbolName + 6);
                int iPos = wsprintf(szTmp, TEXT("%s\n"), szFunc);
                for (int iC = iPos; iC > 0; iC--) {
                    if (szTmp[iC] == '@') {
                        szTmp[iC] = 0;
                        iPos = iC;
                        wsprintf(&szTmp[iC], TEXT(" = %s\n"), szFunc);
                        break;
                    }
                }
            }
            else if (iOpt == 4) {
                DWORD offset = pMemberOffsets2[pIndices[i]-1];    // base 1 -> 0
                IMPORT_OBJECT_HEADER *pImpObjHdr = MakePtr(IMPORT_OBJECT_HEADER *, pMappedFileBase, offset + sizeof(IMAGE_ARCHIVE_MEMBER_HEADER));
                wsprintf(szTmp, TEXT("%hs @%d\n"), pszSymbolName + 6, pImpObjHdr->Hint);
            }
            WriteOut(hWnd, szTmp);
        }

        // Advanced to the next name.
        // symbol names are sequential null-terminated strings
        pMemberOffsets++;    // only for first header
        pszSymbolName += strlen(pszSymbolName) + 1;
    }

    return 0;
}

//=============================================================================
// Converts from big endian to little endian numbers.
//=============================================================================
DWORD ConvertBigEndian(DWORD bigEndian)
{
    DWORD temp = 0;

    temp |= bigEndian >> 24;
    temp |= ((bigEndian & 0x00FF0000) >> 8);
    temp |= ((bigEndian & 0x0000FF00) << 8);
    temp |= ((bigEndian & 0x000000FF) << 24);

    return temp;
}
#14
General discussions / Re: Retrieving information fro...
Last post by Vortex - February 11, 2026, 07:05:41 PM
Hi Timo,

Thanks for the heads up. A better approach :

E:\PellesC\Lib\Win>\PellesC\bin\podump.exe /SYMBOLS htmlhelp.lib

Dump of htmlhelp.lib

File type: LIB

SYMBOL TABLE
0000 00000001 ABS    notype      static       | @feat.00
     compatible with /safeseh
0001 00000000 SECT1  notype      static       | .bss
     length of section   11, #relocations    0, #linenumbers    0
0003 00000000 SECT2  notype      static       | .text
     length of section  187, #relocations   1E, #linenumbers    0
0005 00000000 UNDEF  notype      external     | __imp__RegQueryValueExW@24
0006 00000000 UNDEF  notype      external     | __imp__RegOpenKeyExW@20
0007 00000000 UNDEF  notype      external     | __imp__RegCloseKey@4
0008 00000000 UNDEF  notype      external     | __imp__LoadLibraryW@4
0009 00000000 UNDEF  notype      external     | __imp__GetProcAddress@8
000A 00000000 SECT3  notype      static       | .rdata
     length of section   A4, #relocations    0, #linenumbers    0
000C 00000090 SECT2  notype ()   external     | _HtmlHelpA@16
000D 00000110 SECT2  notype ()   external     | _HtmlHelpW@16
000E 00000000 SECT1  notype      static       | _g_hmodHHCtrl
000F 00000000 SECT2  notype ()   static       | _LoadHHCtrl@0
0010 0000002C SECT3  notype      static       | @1030
0011 0000002A SECT3  notype      static       | @1034
0012 00000014 SECT3  notype      static       | @1040
0013 00000004 SECT1  notype      static       | @1066
0014 00000008 SECT1  notype      static       | @1069
0015 0000000A SECT3  notype      static       | @1078
0016 0000000C SECT1  notype      static       | @1118
0017 00000010 SECT1  notype      static       | @1121
0018 00000000 SECT3  notype      static       | @1130

SUMMARY
      11 .bss
      A4 .rdata
     187 .text
#15
General discussions / Re: Retrieving information fro...
Last post by TimoVJL - February 10, 2026, 10:06:40 PM
Not actually a bug, as it is a static library.
About Htmlhelp.lib

EDIT: use pope.exe to see linker members / symbols
#16
General discussions / Retrieving information from ht...
Last post by Vortex - February 10, 2026, 09:11:39 PM
Hello,

Podump does not display the functions exported by htmlhelp.lib :
\PellesC\bin\podump.exe /EXPORTS \PellesC\lib\win\htmlhelp.lib
Dump of \PellesC\lib\win\htmlhelp.lib

File type: LIB

SUMMARY
      11 .bss
      A4 .rdata
    187 .text

\PellesC\bin\polib.exe /MAKEDEF:htmlhelp.def /MACHINE:x86 \PellesC\lib\win\htmlhelp.lib
The size of htmlhelp.def is 0 byte.

Same issues with the 64-bit version of htmlhelp.lib
#17
User contributions / Re: Import libraries for the U...
Last post by TimoVJL - February 10, 2026, 08:58:21 PM
Nice, no need additional MS tools

EDIT:
If someone don't need Pelles C crt and don't need commanline
#pragma nodefaultlib
void __cdecl mainCRTStartup(void)
{
void __cdecl exit(int status);
int __cdecl main(void);
exit(main());
}
#18
User contributions / Re: Import libraries for the U...
Last post by Vortex - February 10, 2026, 07:52:59 PM
Hi Timo,

Here is my report. Run the two MakeLibs.bat files to create the import libraries for both of the 32-bit and 64-bit architectures :

set p=E:\PellesC\bin
.
.
%p%\Polib.exe /MACHINE:x86 /OUT:ucrt.lib api-ms-win-crt-conio-l1-1-0.lib api-ms-win-crt-convert-l1-1-0.lib api-ms-win-crt-environment-l1-1-0.lib api-ms-win-crt-filesystem-l1-1-0.lib api-ms-win-crt-heap-l1-1-0.lib api-ms-win-crt-locale-l1-1-0.lib api-ms-win-crt-math-l1-1-0.lib api-ms-win-crt-multibyte-l1-1-0.lib api-ms-win-crt-process-l1-1-0.lib api-ms-win-crt-runtime-l1-1-0.lib api-ms-win-crt-stdio-l1-1-0.lib api-ms-win-crt-string-l1-1-0.lib api-ms-win-crt-time-l1-1-0.lib api-ms-win-crt-utility-l1-1-0.lib

Polib reports some warning messages bot they are not harmful :

POLIB: warning: No symbols added from 'api-ms-win-crt-convert-l1-1-0.dll'; thismember will never be seen by the linker.
POLIB: warning: No symbols added from 'api-ms-win-crt-environment-l1-1-0.dll'; this member will never be seen by the linker.
POLIB: warning: No symbols added from 'api-ms-win-crt-filesystem-l1-1-0.dll'; this member will never be seen by the linker.
POLIB: warning: No symbols added from 'api-ms-win-crt-heap-l1-1-0.dll'; this member will never be seen by the linker.
.
.
.
POLIB: warning: No symbols added from 'api-ms-win-crt-string-l1-1-0.dll'; this member will never be seen by the linker.
POLIB: warning: No symbols added from 'api-ms-win-crt-time-l1-1-0.dll'; this member will never be seen by the linker.
POLIB: warning: No symbols added from 'api-ms-win-crt-utility-l1-1-0.dll'; thismember will never be seen by the linker.

Simple example built with Pelles C :

\PellesC\bin\podump.exe /IMPORTS Test.exe

Dump of Test.exe

File type: EXE

        Imported symbols

        api-ms-win-crt-stdio-l1-1-0.dll

          406128 import address table
          406064 import name table
              0 time date stamp (Thu Jan  1 03:00:00 1970)
              0 index of first forwarder reference

        hint  name
          0  __acrt_iob_func
          0  __stdio_common_vfprintf

        api-ms-win-crt-string-l1-1-0.dll

          406134 import address table
          406070 import name table
              0 time date stamp (Thu Jan  1 03:00:00 1970)
              0 index of first forwarder reference

        hint  name
          0  _strupr

        api-ms-win-crt-filesystem-l1-1-0.dll

          40613C import address table
          406078 import name table
              0 time date stamp (Thu Jan  1 03:00:00 1970)
              0 index of first forwarder reference

        hint  name
          0  _getdrives
#19
Downloads / PellesC Version 13.00
Last post by Christian - February 10, 2026, 11:36:57 AM
PellesC Version 13.00

May 21, 2025

For 64-bit Windows 7/8/10 host, targeting 32-bit or 64-bit Windows Vista/7/8/10.
#20
User contributions / Re: Import libraries for the U...
Last post by Vortex - February 09, 2026, 12:30:20 PM
Hi Timo,

I will try it with the latest release of Polink.