News:

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

Main Menu

Recent posts

#11
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;
}
#12
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
#13
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
#14
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
#15
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());
}
#16
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
#17
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.
#18
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.
#19
Tips & tricks / Re: Silly test for msvcrt and ...
Last post by TimoVJL - February 09, 2026, 11:18:26 AM
That silly test used only ucrtbase.dll, as those Api Stub forwanders mostly point to it.
Making ucrt.lib is more demanding, as have to collect those (stupid) forwanders are mostly used for versioning, and with no code.
#20
User contributions / Re: Import libraries for the U...
Last post by TimoVJL - February 09, 2026, 11:12:01 AM
Is it possible to build that ucrt.lib with polib.exe too ?