Changeset 123


Ignore:
Timestamp:
Dec 14, 2001, 11:41:33 PM (24 years ago)
Author:
umoeller
Message:

Lots of changes for icons and refresh.

Location:
trunk
Files:
19 edited

Legend:

Unmodified
Added
Removed
  • trunk/include/helpers/apps.h

    r113 r123  
    7676                    // V0.9.16 (2001-10-06)
    7777
     78        #define PROG_WIN32              990     // added V0.9.16 (2001-12-08) [umoeller]
     79
    7880        APIRET appQueryAppType(const char *pcszExecutable,
    7981                                PULONG pulDosAppType,
  • trunk/include/helpers/dosh.h

    r121 r123  
    5757    PVOID doshMalloc(ULONG cb,
    5858                     APIRET *parc);
     59
     60    APIRET doshAllocArray(ULONG c,
     61                          ULONG cbArrayItem,
     62                          PBYTE *ppv,
     63                          PULONG pcbAllocated);
    5964
    6065    PVOID doshAllocSharedMem(ULONG ulSize,
     
    353358                      LONG lOffset,
    354359                      ULONG ulMethod,
    355                       ULONG cb,
     360                      PULONG pcb,
    356361                      PBYTE pbData);
    357362
     
    464469     ********************************************************************/
    465470
     471    #pragma pack(1)
     472
    466473    /*
    467474     *@@ DOSEXEHEADER:
     
    473480     */
    474481
    475     #pragma pack(1)
    476482    typedef struct _DOSEXEHEADER
    477483    {
     
    532538        ULONG     ulChecksum;           // 08: MS: reserved, OS/2: checksum
    533539        USHORT    usFlags;              // 0c: flags
     540                           /*
     541                              #define NENOTP          0x8000          // Not a process == library
     542                              #define NENOTMPSAFE     0x4000          // Process is not multi-processor safe
     543                              #define NEIERR          0x2000          // Errors in image
     544                              #define NEBOUND         0x0800          // Bound Family/API
     545                              #define NEAPPTYP        0x0700          // Application type mask
     546                              #define NENOTWINCOMPAT  0x0100          // Not compatible with P.M. Windowing
     547                              #define NEWINCOMPAT     0x0200          // Compatible with P.M. Windowing
     548                              #define NEWINAPI        0x0300          // Uses P.M. Windowing API
     549                              #define NEFLTP          0x0080          // Floating-point instructions
     550                              #define NEI386          0x0040          // 386 instructions
     551                              #define NEI286          0x0020          // 286 instructions
     552                              #define NEI086          0x0010          // 8086 instructions
     553                              #define NEPROT          0x0008          // Runs in protected mode only
     554                              #define NEPPLI          0x0004          // Per-Process Library Initialization
     555                              #define NEINST          0x0002          // Instance data
     556                              #define NESOLO          0x0001          // Solo data (single data)
     557                           */
    534558        USHORT    usAutoDataSegNo;      // 0e: auto-data seg no.
    535559        USHORT    usInitlHeapSize;      // 10: initl. heap size
     
    581605        ULONG     ulModuleVersion;      // 0c: module version
    582606        ULONG     ulFlags;              // 10: module flags
     607                          /* #define E32NOTP          0x8000L        // Library Module - used as NENOTP
     608                             #define E32NOLOAD        0x2000L        // Module not Loadable
     609                             #define E32PMAPI         0x0300L        // Uses PM Windowing API
     610                             #define E32PMW           0x0200L        // Compatible with PM Windowing
     611                             #define E32NOPMW         0x0100L        // Incompatible with PM Windowing
     612                             #define E32NOEXTFIX      0x0020L        // NO External Fixups in .EXE
     613                             #define E32NOINTFIX      0x0010L        // NO Internal Fixups in .EXE
     614                             #define E32SYSDLL        0x0008L        // System DLL, Internal Fixups discarded
     615                             #define E32LIBINIT       0x0004L        // Per-Process Library Initialization
     616                             #define E32LIBTERM       0x40000000L    // Per-Process Library Termination
     617                             #define E32APPMASK       0x0300L        // Application Type Mask
     618                          */
    583619        ULONG     ulPageCount;          // 14: no. of pages in module
    584620        ULONG     ulEIPRelObj;          // 18: object to which EIP is relative
     
    680716    } PEHEADER, *PPEHEADER;
    681717
     718    // additional LX structures
     719
     720    /*
     721     *@@ RESOURCETABLEENTRY:
     722     *     LX resource table entry.
     723     *
     724     *@@added V0.9.16 (2001-12-08) [umoeller]
     725     */
     726
     727    typedef struct _RESOURCETABLEENTRY     // rsrc32
     728    {
     729        unsigned short  type;   // Resource type
     730        unsigned short  name;   // Resource name
     731        unsigned long   cb;     // Resource size
     732        unsigned short  obj;    // Object number
     733        unsigned long   offset; // Offset within object
     734    } RESOURCETABLEENTRY;
     735
     736    /*
     737     *@@ OBJECTTABLEENTRY:
     738     *     LX object table entry.
     739     *
     740     *@@added V0.9.16 (2001-12-08) [umoeller]
     741     */
     742
     743    typedef struct _OBJECTTABLEENTRY       // o32_obj
     744    {
     745        unsigned long   o32_size;     // Object virtual size
     746        unsigned long   o32_base;     // Object base virtual address
     747        unsigned long   o32_flags;    // Attribute flags
     748        unsigned long   o32_pagemap;  // Object page map index
     749        unsigned long   o32_mapsize;  // Number of entries in object page map
     750        unsigned long   o32_reserved; // Reserved
     751    } OBJECTTABLEENTRY;
     752
     753    /*
     754     *@@ OBJECTPAGETABLEENTRY:
     755     *     LX object _page_ table entry, sometimes
     756     *     referred to as map entry.
     757     *
     758     *@@added V0.9.16 (2001-12-08) [umoeller]
     759     */
     760
     761    typedef struct _OBJECTPAGETABLEENTRY   // o32_map
     762    {
     763        unsigned long   o32_pagedataoffset;     // file offset of page
     764        unsigned short  o32_pagesize;           // # of real bytes of page data
     765        unsigned short  o32_pageflags;          // Per-Page attributes
     766    } OBJECTPAGETABLEENTRY;
     767
     768    /*
     769     *@@ LXITER:
     770     *      iteration Record format for 'EXEPACK'ed pages.
     771     *
     772     *@@added V0.9.16 (2001-12-08) [umoeller]
     773     */
     774
     775    typedef struct _LXITER
     776    {
     777        unsigned short LX_nIter;            // number of iterations
     778        unsigned short LX_nBytes;           // number of bytes
     779        unsigned char  LX_Iterdata;         // iterated data byte(s)
     780    } LXITER, *PLXITER;
     781
    682782    #pragma pack()
    683 
    684     /*
    685      *@@ FSYSMODULE:
    686      *
    687      *@@added V0.9.9 (2001-03-11) [lafaix]
    688      */
    689 
    690     typedef struct _FSYSMODULE
    691     {
    692         CHAR achModuleName[256];
    693     } FSYSMODULE, *PFSYSMODULE;
    694 
    695     /*
    696      *@@ FSYSFUNCTION:
    697      *
    698      *@@added V0.9.9 (2001-03-11) [lafaix]
    699      */
    700 
    701     typedef struct _FSYSFUNCTION
    702     {
    703         ULONG ulOrdinal;
    704         ULONG ulType;
    705         CHAR achFunctionName[256];
    706     } FSYSFUNCTION, *PFSYSFUNCTION;
    707 
    708     /*
    709      *@@ FSYSRESOURCE:
    710      *
    711      *@@added V0.9.7 (2000-12-18) [lafaix]
    712      */
    713 
    714     typedef struct _FSYSRESOURCE
    715     {
    716         ULONG ulID;                     // resource ID
    717         ULONG ulType;                   // resource type
    718         ULONG ulSize;                   // resource size in bytes
    719         ULONG ulFlag;                   // resource flags
    720     } FSYSRESOURCE, *PFSYSRESOURCE;
    721783
    722784    // object/segment flags (in NE and LX)
     
    822884                // module info substring (if IBM BLDLEVEL format)
    823885
     886#ifndef __STRIP_DOWN_EXECUTABLE__       // for mini stubs in warpin, to reduce code size
    824887        // if pszInfo is extended DESCRIPTION field, the following
    825888        // are set as well:
     
    833896                            pszFixpak;
    834897
     898        // the following fields are set after doshLoadLXMaps
     899        BOOL                    fLXMapsLoaded;      // TRUE after doshLoadLXMaps
     900        RESOURCETABLEENTRY      *pRsTbl;        // pLXHeader->ulResTblCnt
     901        OBJECTTABLEENTRY        *pObjTbl;       // pLXHeader->ulObjCount
     902        OBJECTPAGETABLEENTRY    *pObjPageTbl;   // pLXHeader->ulPageCount
     903
     904#endif
    835905    } EXECUTABLE, *PEXECUTABLE;
    836906
     
    838908                        PEXECUTABLE* ppExec);
    839909
    840     APIRET doshExecClose(PEXECUTABLE pExec);
    841 
    842910    APIRET doshExecQueryBldLevel(PEXECUTABLE pExec);
     911
     912    /*
     913     *@@ FSYSMODULE:
     914     *
     915     *@@added V0.9.9 (2001-03-11) [lafaix]
     916     */
     917
     918    typedef struct _FSYSMODULE
     919    {
     920        CHAR achModuleName[256];
     921    } FSYSMODULE, *PFSYSMODULE;
    843922
    844923    APIRET doshExecQueryImportedModules(PEXECUTABLE pExec,
     
    848927    APIRET doshExecFreeImportedModules(PFSYSMODULE paModules);
    849928
     929    /*
     930     *@@ FSYSFUNCTION:
     931     *
     932     *@@added V0.9.9 (2001-03-11) [lafaix]
     933     */
     934
     935    typedef struct _FSYSFUNCTION
     936    {
     937        ULONG ulOrdinal;
     938        ULONG ulType;
     939        CHAR achFunctionName[256];
     940    } FSYSFUNCTION, *PFSYSFUNCTION;
     941
    850942    APIRET doshExecQueryExportedFunctions(PEXECUTABLE pExec,
    851943                                          PFSYSFUNCTION *ppaFunctions,
     
    854946    APIRET doshExecFreeExportedFunctions(PFSYSFUNCTION paFunctions);
    855947
     948    /*
     949     *@@ FSYSRESOURCE:
     950     *
     951     *@@added V0.9.7 (2000-12-18) [lafaix]
     952     */
     953
     954    typedef struct _FSYSRESOURCE
     955    {
     956        ULONG ulID;                     // resource ID
     957        ULONG ulType;                   // resource type
     958        ULONG ulSize;                   // resource size in bytes
     959        ULONG ulFlag;                   // resource flags
     960
     961    } FSYSRESOURCE, *PFSYSRESOURCE;
     962
    856963    APIRET doshExecQueryResources(PEXECUTABLE pExec,
    857964                                  PFSYSRESOURCE *ppaResources,
     
    859966
    860967    APIRET doshExecFreeResources(PFSYSRESOURCE paResources);
     968
     969    APIRET doshLoadLXMaps(PEXECUTABLE pExec);
     970
     971    VOID doshFreeLXMaps(PEXECUTABLE pExec);
     972
     973    APIRET doshExecClose(PEXECUTABLE *ppExec);
    861974
    862975    APIRET doshSearchPath(PCSZ pcszPath,
  • trunk/include/helpers/memdebug.h

    r113 r123  
    8080        typedef struct _HEAPITEM
    8181        {
    82             struct _HEAPITEM    *pNext;     // next item in linked list or NULL if last
     82            // struct _HEAPITEM    *pNext;     // next item in linked list or NULL if last
    8383
    84             void                *pAfterMagic; // memory pointer returned by memdMalloc;
    85                                             // this points to after the magic string
     84            TREE                Tree;           // tree node for tree.* functions;
     85                                                // ulKey has the pointer that is returned
     86                                                // by memdMalloc and points to after the
     87                                                // magic string (in the buffer that was
     88                                                // really allocated). Using this as the
     89                                                // tree sort key allows us to do fast
     90                                                // searches in memdFree.
     91
     92            // void                *pAfterMagic; // memory pointer returned by memdMalloc;
     93                                              // this points to after the magic string
     94
    8695            unsigned long       ulSize;     // requested size (without magic head and tail)
    8796
     
    97106        } HEAPITEM, *PHEAPITEM;
    98107
    99         extern PHEAPITEM    G_pHeapItemsRoot;
     108        extern TREE         *G_pHeapItemsRoot;
     109        extern LONG         G_cHeapItems;
    100110        extern ULONG        G_ulItemsReleased;
    101111        extern ULONG        G_ulBytesReleased;
  • trunk/include/helpers/standards.h

    r113 r123  
    6363
    6464    /*
     65     *@@ FREE:
     66     *      wrapper around the typical free() sequence.
     67     *
     68     *      Usage:
     69     *
     70     +          FREE(p)
     71     *
     72     *      This expands to:
     73     *
     74     +          if (p)
     75     +          {
     76     +              free(p);
     77     +              p = NULL;
     78     +          }
     79     *
     80     *@@added V0.9.16 (2001-12-08) [umoeller]
     81     */
     82
     83    #define FREE(ptr) if ((ptr)) { free(ptr); ptr = NULL; }
     84
     85    /*
    6586     *@@ ARRAYITEMCOUNT:
    6687     *      helpful macro to count the count of items
  • trunk/include/helpers/stringh.h

    r122 r123  
    3232    #define STRINGH_HEADER_INCLUDED
    3333
    34     VOID XWPENTRY strhStore(PSZ *ppszTarget, PCSZ pcszSource, PULONG pulLength);
     34    #if defined(__DEBUG_MALLOC_ENABLED__) && !defined(DONT_REPLACE_STRINGH_MALLOC) // setup.h, helpers\memdebug.c
     35        APIRET XWPENTRY strhStoreDebug(PSZ *ppszTarget,
     36                                       PCSZ pcszSource,
     37                                       PULONG pulLength,
     38                                       const char *pcszSourceFile,
     39                                       unsigned long ulLine,
     40                                       const char *pcszFunction);
     41        #define strhStore(a, b, c) strhStoreDebug((a), (b), (c), __FILE__, __LINE__, __FUNCTION__)
     42    #else
     43        APIRET XWPENTRY strhStore(PSZ *ppszTarget, PCSZ pcszSource, PULONG pulLength);
     44    #endif
    3545
    3646    PSZ XWPENTRY strhcpy(PSZ string1, const char *string2);
  • trunk/include/helpers/threads.h

    r115 r123  
    6060        HAB     hab;            // for PM threads
    6161        HMQ     hmq;            // for PM threads
    62         BOOL    fExitComplete;
     62        HEV     hevExitComplete;    // posted when thread exits V0.9.16 (2001-12-08) [umoeller]
    6363
    6464        // data to be maintained by application
  • trunk/src/helpers/apps.c

    r122 r123  
    513513 *      --  PROG_WINDOWABLEVIO
    514514 *
     515 *      --  PROG_DEFAULT
     516 *
    515517 *@@added V0.9.9 (2001-03-07) [umoeller]
    516518 *@@changed V0.9.12 (2001-05-27) [umoeller]: moved from winh.c to apps.c
    517519 *@@changed V0.9.14 (2001-08-07) [pr]: use FAPPTYP_* constants
     520 *@@changed V0.9.16 (2001-12-08) [umoeller]: added checks for batch files, other optimizations
    518521 */
    519522
    520523APIRET appQueryAppType(const char *pcszExecutable,
    521                         PULONG pulDosAppType,
    522                         PULONG pulWinAppType)
     524                       PULONG pulDosAppType,
     525                       PULONG pulWinAppType)
    523526{
    524     APIRET arc = DosQueryAppType((PSZ)pcszExecutable, pulDosAppType);
    525     if (arc == NO_ERROR)
    526     {
    527         ULONG _ulDosAppType = *pulDosAppType;
    528 
    529         if (_ulDosAppType == 0)
    530             *pulWinAppType = PROG_FULLSCREEN;
    531         else if (_ulDosAppType & FAPPTYP_PHYSDRV)       // 0x40
    532             *pulWinAppType = PROG_PDD;
    533         else if (_ulDosAppType & FAPPTYP_VIRTDRV)       // 0x80)
    534             *pulWinAppType = PROG_VDD;
    535         else if ((_ulDosAppType & 0xF0) == FAPPTYP_DLL) // 0x10)
     527    APIRET arc;
     528
     529/*
     530   #define FAPPTYP_NOTSPEC         0x0000
     531   #define FAPPTYP_NOTWINDOWCOMPAT 0x0001
     532   #define FAPPTYP_WINDOWCOMPAT    0x0002
     533   #define FAPPTYP_WINDOWAPI       0x0003
     534   #define FAPPTYP_BOUND           0x0008
     535   #define FAPPTYP_DLL             0x0010
     536   #define FAPPTYP_DOS             0x0020
     537   #define FAPPTYP_PHYSDRV         0x0040  // physical device driver
     538   #define FAPPTYP_VIRTDRV         0x0080  // virtual device driver
     539   #define FAPPTYP_PROTDLL         0x0100  // 'protected memory' dll
     540   #define FAPPTYP_WINDOWSREAL     0x0200  // Windows real mode app
     541   #define FAPPTYP_WINDOWSPROT     0x0400  // Windows protect mode app
     542   #define FAPPTYP_WINDOWSPROT31   0x1000  // Windows 3.1 protect mode app
     543   #define FAPPTYP_32BIT           0x4000
     544*/
     545
     546    ULONG   ulWinAppType = PROG_DEFAULT;
     547
     548    if (!(arc = DosQueryAppType((PSZ)pcszExecutable, pulDosAppType)))
     549    {
     550        // clear the 32-bit flag
     551        // V0.9.16 (2001-12-08) [umoeller]
     552        ULONG ulDosAppType = (*pulDosAppType) & ~FAPPTYP_32BIT,
     553              ulLoAppType = ulDosAppType & 0xFFFF;
     554
     555        if (ulDosAppType & FAPPTYP_PHYSDRV)            // 0x40
     556            ulWinAppType = PROG_PDD;
     557        else if (ulDosAppType & FAPPTYP_VIRTDRV)       // 0x80
     558            ulWinAppType = PROG_VDD;
     559        else if ((ulDosAppType & 0xF0) == FAPPTYP_DLL) // 0x10
    536560            // DLL bit set
    537             *pulWinAppType = PROG_DLL;
    538         else if (_ulDosAppType & FAPPTYP_DOS)           // 0x20)
     561            ulWinAppType = PROG_DLL;
     562        else if (ulDosAppType & FAPPTYP_DOS)           // 0x20
    539563            // DOS bit set?
    540             *pulWinAppType = PROG_WINDOWEDVDM;
    541         else if ((_ulDosAppType & FAPPTYP_WINDOWAPI) == FAPPTYP_WINDOWAPI) // 0x0003) // "Window-API" == PM
    542             *pulWinAppType = PROG_PM;
    543         else if (   ((_ulDosAppType & 0xFFFF) == FAPPTYP_WINDOWSPROT31) // 0x1000) // windows program (?!?)
    544                  || ((_ulDosAppType & 0xFFFF) == FAPPTYP_WINDOWSPROT) // ) // windows program (?!?)
     564            ulWinAppType = PROG_WINDOWEDVDM;
     565        else if ((ulDosAppType & FAPPTYP_WINDOWAPI) == FAPPTYP_WINDOWAPI) // 0x0003)
     566            // "Window-API" == PM
     567            ulWinAppType = PROG_PM;
     568        else if (ulLoAppType == FAPPTYP_WINDOWSREAL)
     569            ulWinAppType = PROG_31_ENHSEAMLESSCOMMON;  // @@todo really?
     570        else if (   (ulLoAppType == FAPPTYP_WINDOWSPROT31) // 0x1000) // windows program (?!?)
     571                 || (ulLoAppType == FAPPTYP_WINDOWSPROT) // ) // windows program (?!?)
    545572                )
    546             *pulWinAppType = PROG_31_ENHSEAMLESSCOMMON;  // PROG_31_ENH;
    547             // *pulWinAppType = PROG_31_ENHSEAMLESSVDM;
    548         else if ((_ulDosAppType & FAPPTYP_WINDOWAPI /* 0x03 */ ) == FAPPTYP_WINDOWCOMPAT) // 0x02)
    549             *pulWinAppType = PROG_WINDOWABLEVIO;
    550         else if ((_ulDosAppType & FAPPTYP_WINDOWAPI /* 0x03 */ ) == FAPPTYP_NOTWINDOWCOMPAT) // 0x01)
    551             *pulWinAppType = PROG_FULLSCREEN;
    552     }
     573            ulWinAppType = PROG_31_ENHSEAMLESSCOMMON;  // PROG_31_ENH;
     574        else if ((ulDosAppType & FAPPTYP_WINDOWAPI /* 0x03 */ ) == FAPPTYP_WINDOWCOMPAT) // 0x02)
     575            ulWinAppType = PROG_WINDOWABLEVIO;
     576        else if ((ulDosAppType & FAPPTYP_WINDOWAPI /* 0x03 */ ) == FAPPTYP_NOTWINDOWCOMPAT) // 0x01)
     577            ulWinAppType = PROG_FULLSCREEN;
     578    }
     579
     580    if (ulWinAppType == PROG_DEFAULT)
     581    {
     582        // added checks for batch files V0.9.16 (2001-12-08) [umoeller]
     583        PCSZ pcszExt;
     584        if (pcszExt = doshGetExtension(pcszExecutable))
     585        {
     586            if (!stricmp(pcszExt, "BAT"))
     587            {
     588                ulWinAppType = PROG_WINDOWEDVDM;
     589                arc = NO_ERROR;
     590            }
     591            else if (!stricmp(pcszExt, "CMD"))
     592            {
     593                ulWinAppType = PROG_WINDOWABLEVIO;
     594                arc = NO_ERROR;
     595            }
     596        }
     597    }
     598
     599    *pulWinAppType = ulWinAppType;
    553600
    554601    return (arc);
     
    608655        case PROG_WIN_GAME: return "PROG_WIN_GAME";
    609656        case PROG_DOS_MODE: return "PROG_DOS_MODE";
     657
     658        // added this V0.9.16 (2001-12-08) [umoeller]
     659        case PROG_WIN32: return "PROG_WIN32";
    610660    }
    611661
  • trunk/src/helpers/cnrh.c

    r106 r123  
    18651865
    18661866    memset(&drgImage, 0, sizeof(drgImage));
    1867     pdrgInfo = DrgAllocDraginfo(1); // one item only
    1868     if (pdrgInfo)
     1867
     1868    if (pdrgInfo = DrgAllocDraginfo(1)) // one item only
    18691869    {
    18701870        DRAGITEM drgItem;
  • trunk/src/helpers/comctl.c

    r122 r123  
    510510
    511511        case WM_MENUEND:
    512         {
    513512            if ((HWND)mp2 == pmbd->hwndMenu) // V0.9.14 (2001-07-31) [umoeller]
    514513            {
     
    548547                pmbd->hwndMenu = NULLHANDLE;
    549548            } // end if ((HWND)mp1 == pmbd->pmbd->hwndMenu) // V0.9.14 (2001-07-31) [umoeller]
    550         break; }
     549        break;
    551550
    552551        /*
     
    569568
    570569        case WM_DESTROY:
    571             mrc = (*(pmbd->pfnwpButtonOriginal))(hwndButton, msg, mp1, mp2);
     570            mrc = pmbd->pfnwpButtonOriginal(hwndButton, msg, mp1, mp2);
    572571            free(pmbd);
    573572        break;
    574573
    575574        default:
    576             mrc = (*(pmbd->pfnwpButtonOriginal))(hwndButton, msg, mp1, mp2);
     575            mrc = pmbd->pfnwpButtonOriginal(hwndButton, msg, mp1, mp2);
    577576    }
    578577
     
    617616{
    618617    BOOL brc = FALSE;
    619     PMENUBUTTONDATA pmbd = (PMENUBUTTONDATA)malloc(sizeof(MENUBUTTONDATA));
    620     if (pmbd)
     618    PMENUBUTTONDATA pmbd;
     619    if (pmbd = (PMENUBUTTONDATA)malloc(sizeof(MENUBUTTONDATA)))
    621620    {
    622621        memset(pmbd, 0, sizeof(MENUBUTTONDATA));
    623         pmbd->pfnwpButtonOriginal = WinSubclassWindow(hwndButton,
    624                                                       ctl_fnwpSubclassedMenuButton);
    625         if (pmbd->pfnwpButtonOriginal)
     622        if (pmbd->pfnwpButtonOriginal = WinSubclassWindow(hwndButton,
     623                                                          ctl_fnwpSubclassedMenuButton))
    626624        {
    627625            pmbd->hmodMenu = hmodMenu;
     
    730728
    731729            case WM_TIMER:
    732             {
    733730                pa->usAniCurrent++;
    734731                if (pa->usAniCurrent >= pa->usAniCount)
     
    739736                           (MPARAM)pa->ahptrAniIcons[pa->usAniCurrent],
    740737                           (MPARAM)NULL);
    741             break; }
     738            break;
    742739
    743740            /*
     
    793790                    // create a suitable bitmap w/ the size of the
    794791                    // static control
    795                     if ((pa->hbm = gpihCreateBitmap(hpsMem,
    796                                                     szlPage.cx,
    797                                                     szlPage.cy)))
     792                    if (    ((pa->hbm = gpihCreateBitmap(hpsMem,
     793                                                         szlPage.cx,
     794                                                         szlPage.cy)))
     795                            // associate the bit map with the memory PS
     796                         && (GpiSetBitmap(hpsMem, pa->hbm) != HBM_ERROR)
     797                       )
    798798                    {
    799                         // associate the bit map with the memory PS
    800                         if (GpiSetBitmap(hpsMem, pa->hbm) != HBM_ERROR)
     799                        // fill the bitmap with the current static
     800                        // background color
     801                        POINTL ptl = {0, 0};
     802                        GpiMove(hpsMem, &ptl);
     803                        ptl.x = pa->rclIcon.xRight;
     804                        ptl.y = pa->rclIcon.yTop;
     805                        GpiSetColor(hpsMem,
     806                                    lBkgndColor);
     807                        GpiBox(hpsMem,
     808                               DRO_FILL, // interior only
     809                               &ptl,
     810                               0, 0);    // no corner rounding
     811
     812                        /*
     813                         * ANF_ICON:
     814                         *
     815                         */
     816
     817                        if (pa->ulFlags & ANF_ICON)
    801818                        {
    802                             // fill the bitmap with the current static
    803                             // background color
    804                             POINTL ptl = {0, 0};
    805                             GpiMove(hpsMem, &ptl);
    806                             ptl.x = pa->rclIcon.xRight;
    807                             ptl.y = pa->rclIcon.yTop;
    808                             GpiSetColor(hpsMem,
    809                                         lBkgndColor);
    810                             GpiBox(hpsMem,
    811                                    DRO_FILL, // interior only
    812                                    &ptl,
    813                                    0, 0);    // no corner rounding
    814 
    815                             /*
    816                              * ANF_ICON:
    817                              *
    818                              */
    819 
    820                             if (pa->ulFlags & ANF_ICON)
     819                            // store new icon in our own structure
     820                            if (pa->hptr = (HPOINTER)mp1)
    821821                            {
    822                                 // store new icon in our own structure
    823                                 pa->hptr = (HPOINTER)mp1;
    824 
    825                                 if (pa->hptr)
    826                                 {
    827                                     // center the icon in the bitmap
    828                                     // V0.9.16 (2001-10-15) [umoeller]
    829                                     POINTL ptlOfs;
    830                                     ptlOfs.x = (   (pa->rclIcon.xRight - pa->rclIcon.xLeft)
    831                                                  - pa->lIconSize
    832                                                ) / 2;
    833                                     ptlOfs.y = (   (pa->rclIcon.yTop - pa->rclIcon.yBottom)
    834                                                  - pa->lIconSize
    835                                                ) / 2;
    836 
    837                                     // paint icon into bitmap
    838                                     gpihIcon2Bitmap(hpsMem,
    839                                                     pa->hptr,
    840                                                     lBkgndColor,
    841                                                     &ptlOfs,
    842                                                     pa->lIconSize);
    843                                 }
    844 
    845                             } // end if (pa->ulFlags & ANF_ICON)
    846 
    847                             /*
    848                              * ANF_BITMAP:
    849                              *
    850                              */
    851 
    852                             else if (pa->ulFlags & ANF_BITMAP)
    853                             {
    854                                 // store passed bitmap
    855                                 HBITMAP     hbmSource = (HBITMAP)mp1;
    856 
    857                                 if (hbmSource)
    858                                     gpihStretchBitmap(hpsMem,       // target
    859                                                       hbmSource,    // source
    860                                                       NULL,     // use size of bitmap
    861                                                       &pa->rclIcon,
    862                                                       ((pa->ulFlags & ANF_PROPORTIONAL)
    863                                                             != 0));
    864 
    865                             } // end if (pa->ulFlags & ANF_BITMAP)
    866 
    867                         } // end if (GpiSetBitmap(...
    868                     } // if (pa->hbm = gpihCreateBitmap(hpsMem, &(pa->rclIcon)))
     822                                // center the icon in the bitmap
     823                                // V0.9.16 (2001-10-15) [umoeller]
     824                                POINTL ptlOfs;
     825                                ptlOfs.x = (   (pa->rclIcon.xRight - pa->rclIcon.xLeft)
     826                                             - pa->lIconSize
     827                                           ) / 2;
     828                                ptlOfs.y = (   (pa->rclIcon.yTop - pa->rclIcon.yBottom)
     829                                             - pa->lIconSize
     830                                           ) / 2;
     831
     832                                // paint icon into bitmap
     833                                gpihIcon2Bitmap(hpsMem,
     834                                                pa->hptr,
     835                                                lBkgndColor,
     836                                                &ptlOfs,
     837                                                pa->lIconSize);
     838                            }
     839
     840                        } // end if (pa->ulFlags & ANF_ICON)
     841
     842                        /*
     843                         * ANF_BITMAP:
     844                         *
     845                         */
     846
     847                        else if (pa->ulFlags & ANF_BITMAP)
     848                        {
     849                            // store passed bitmap
     850                            HBITMAP     hbmSource;
     851                            if (hbmSource = (HBITMAP)mp1)
     852                                gpihStretchBitmap(hpsMem,       // target
     853                                                  hbmSource,    // source
     854                                                  NULL,     // use size of bitmap
     855                                                  &pa->rclIcon,
     856                                                  ((pa->ulFlags & ANF_PROPORTIONAL)
     857                                                        != 0));
     858
     859                        } // end if (pa->ulFlags & ANF_BITMAP)
     860
     861                    } // end if (GpiSetBitmap(...
     862                      // && (pa->hbm = gpihCreateBitmap(hpsMem, &(pa->rclIcon)))
    869863
    870864                    // in any case, clean up now
     
    877871                // enforce WM_PAINT
    878872                WinInvalidateRect(hwndStatic, NULL, FALSE);
    879 
    880             break; }
     873            }
     874            break;
    881875
    882876            /*
     
    940934
    941935                WinEndPaint(hps);
    942             break; }
     936            }
     937            break;
    943938
    944939            /*
     
    948943
    949944            case WM_DESTROY:
    950             {
    951945                // undo subclassing in case more WM_TIMERs come in
    952946                WinSubclassWindow(hwndStatic, OldStaticProc);
     
    962956
    963957                mrc = OldStaticProc(hwndStatic, msg, mp1, mp2);
    964             break; }
     958            break;
    965959
    966960            default:
     
    11171111                         BOOL fStartAnimation)       // TRUE: start animation now
    11181112{
    1119     PANIMATIONDATA paNew = ctlPrepareStaticIcon(hwndStatic, usAnimCount);
    1120     if (paNew)
     1113    PANIMATIONDATA paNew;
     1114    if (paNew = ctlPrepareStaticIcon(hwndStatic, usAnimCount))
    11211115    {
    11221116        paNew->ulDelay = ulDelay;
     
    11321126        if (fStartAnimation)
    11331127        {
    1134             WinStartTimer(WinQueryAnchorBlock(hwndStatic), hwndStatic,
    1135                     1, ulDelay);
    1136             WinPostMsg(hwndStatic, WM_TIMER, NULL, NULL);
     1128            WinStartTimer(paNew->hab,
     1129                          hwndStatic,
     1130                          1,
     1131                          ulDelay);
     1132            WinPostMsg(hwndStatic, WM_TIMER, (MPARAM)1, NULL);
    11371133        }
    11381134    }
     
    11501146{
    11511147    BOOL brc = FALSE;
    1152     PANIMATIONDATA pa = (PANIMATIONDATA)WinQueryWindowULong(hwndStatic, QWL_USER);
    1153     if (pa)
    1154         if (WinStartTimer(WinQueryAnchorBlock(hwndStatic), hwndStatic,
    1155                         1, pa->ulDelay))
    1156         {
    1157             brc = TRUE;
    1158             WinPostMsg(hwndStatic, WM_TIMER, NULL, NULL);
    1159         }
     1148    PANIMATIONDATA pa;
     1149    if (    (pa = (PANIMATIONDATA)WinQueryWindowULong(hwndStatic, QWL_USER))
     1150         && (WinStartTimer(pa->hab,
     1151                           hwndStatic,
     1152                           1,
     1153                           pa->ulDelay))
     1154       )
     1155    {
     1156        brc = TRUE;
     1157        WinPostMsg(hwndStatic, WM_TIMER, (MPARAM)1, NULL);
     1158    }
     1159
    11601160    return (brc);
    11611161}
     
    13451345                    // check flags:
    13461346                    // filter out those ugly composite key (accents etc.)
    1347                &&  ((usFlags & (KC_DEADKEY | KC_COMPOSITE | KC_INVALIDCOMP)) == 0)
     1347                 && ((usFlags & (KC_DEADKEY | KC_COMPOSITE | KC_INVALIDCOMP)) == 0)
    13481348               )
    13491349            {
     
    13671367
    13681368                flReturned = (ULONG)WinSendMsg(hwndOwner,
    1369                                           WM_CONTROL,
    1370                                           MPFROM2SHORT(WinQueryWindowUShort(hwndEdit,
    1371                                                                             QWS_ID),
    1372                                                        EN_HOTKEY),  // new notification code
    1373                                           (MPARAM)&hkn);
     1369                                               WM_CONTROL,
     1370                                               MPFROM2SHORT(WinQueryWindowUShort(hwndEdit,
     1371                                                                                 QWS_ID),
     1372                                                            EN_HOTKEY),  // new notification code
     1373                                               (MPARAM)&hkn);
    13741374                if (flReturned & HEFL_SETTEXT)
    13751375                    WinSetWindowText(hwndEdit, hkn.szDescription);
     
    13831383                    WinSetWindowText(hwndEdit, "");
    13841384
    1385 
    13861385                mrc = (MPARAM)TRUE; // WM_CHAR processed flag;
    13871386            }
    1388         break; }
     1387        }
     1388        break;
    13891389
    13901390        default:
  • trunk/src/helpers/configsys.c

    r117 r123  
    9191    }
    9292
    93     arc = doshLoadTextFile(pcszFile,
    94                            ppszContents);
    95 
    96     if (arc == NO_ERROR)
     93    if (!(arc = doshLoadTextFile(pcszFile,
     94                                 ppszContents)))
    9795    {
    9896        // convert all \r\n to \n
     
    316314                     ULONG cbCopyTo)            // out: sizeof(*pszCopyTo)
    317315{
    318     PSZ     p = csysFindKey(pcszSearchIn, pcszKey, NULL, NULL),
     316    PSZ     p,
    319317            prc = NULL;
    320318
    321     if (p)
     319    if (p = csysFindKey(pcszSearchIn, pcszKey, NULL, NULL))
    322320    {
    323321        prc = p + strlen(pcszKey);
     
    326324            // copy to pszCopyTo
    327325            ULONG cb;
    328             PSZ pEOL = strhFindEOL(prc, &cb);
    329             if (pEOL)
     326            PSZ pEOL;
     327            if (pEOL = strhFindEOL(prc, &cb))
    330328            {
    331329                if (cb > cbCopyTo)
     
    370368{
    371369    BOOL    fIsAllUpperCase = FALSE;
    372     PSZ     pKey = csysFindKey(*ppszBuf,
    373                                pcszKey,
    374                                NULL,
    375                                &fIsAllUpperCase),
     370    PSZ     pKey,
    376371            pReturn = NULL;
    377     if (pKey)
     372    if (pKey = csysFindKey(*ppszBuf,
     373                           pcszKey,
     374                           NULL,
     375                           &fIsAllUpperCase))
    378376    {
    379377        // key found in file:
     
    381379
    382380        // replace existing parameter
    383         PSZ pOldParam = pKey + strlen(pcszKey);
    384         // pOldParam now has the old parameter, which we
    385         // will overwrite now; pOldParam points into *ppszBuf
    386 
    387         if (pOldParam)
    388         {
     381        PSZ pOldParam;
     382        if (pOldParam = pKey + strlen(pcszKey))
     383        {
     384            // pOldParam now has the old parameter, which we
     385            // will overwrite now; pOldParam points into *ppszBuf
     386
    389387            ULONG   ulOldParamOfs = pOldParam - *ppszBuf;
    390388
    391             PSZ pEOL = strhFindEOL(pOldParam, NULL);
    392             // pEOL now has first end-of-line after the parameter
    393 
    394             if (pEOL)
     389            PSZ pEOL;
     390            if (pEOL = strhFindEOL(pOldParam, NULL))
    395391            {
     392                // pEOL now has first end-of-line after the parameter
     393
    396394                // char count to replace
    397395                ULONG   ulToReplace = pEOL - pOldParam;
     
    477475    BOOL    fIsAllUpperCase = FALSE;
    478476    PSZ     pStartOfLine = NULL;
    479     PSZ     pKey = csysFindKey(pszSearchIn,
    480                                pszKey,
    481                                &pStartOfLine,
    482                                &fIsAllUpperCase);
     477    PSZ     pKey;
    483478    BOOL    brc = FALSE;
    484479
    485     if (pKey)
    486     {
    487         PSZ pEOL = strhFindEOL(pKey, NULL);
    488         // pEOL now has first end-of-line after the key
    489         if (pEOL)
    490         {
     480    if (pKey = csysFindKey(pszSearchIn,
     481                           pszKey,
     482                           &pStartOfLine,
     483                           &fIsAllUpperCase))
     484    {
     485        PSZ pEOL;
     486        if (pEOL = strhFindEOL(pKey, NULL))
     487        {
     488            // pEOL now has first end-of-line after the key;
    491489            // go to first character after EOL
    492490            while (    (*pEOL)
     
    604602
    605603    // First, check if the new-line string has a "=" char
    606     PSZ pSep = strchr(pManip->pszNewLine, '=');
    607     if (pSep)
     604    PSZ pSep;
     605    if (pSep = strchr(pManip->pszNewLine, '='))
    608606    {
    609607        // yes: separate in two strings
     
    751749                // Manip.pszSearchString has the search string
    752750                // before whose line we must insert
    753                 PSZ pFound = strhistr(*ppszContents,
    754                                       pManip->pszVerticalSearchString);
    755                 if (pFound)
     751                PSZ pFound;
     752                if (pFound = strhistr(*ppszContents,
     753                                      pManip->pszVerticalSearchString))
    756754                {
    757755                    // search string found:
     
    777775                // Manip.pszSearchString has the search string
    778776                // after whose line we must insert
    779                 PSZ pFound = strhistr(*ppszContents, pManip->pszVerticalSearchString);
    780                 if (pFound)
     777                PSZ pFound;
     778                if (pFound = strhistr(*ppszContents,
     779                                      pManip->pszVerticalSearchString))
    781780                {
    782781                    // search string found:
  • trunk/src/helpers/datetime.c

    r108 r123  
    230230 *      returns TRUE if yr is a leap year.
    231231 *
    232  *      (c) Ray Gardner. Public domain.
     232 *      (W) Ray Gardner. Public domain.
    233233 */
    234234
     
    260260 *      you then get 63.
    261261 *
    262  *      (c) Ray Gardner. Public domain.
     262 *      (W) Ray Gardner. Public domain.
    263263 */
    264264
     
    272272 *      converts a year to the no. of days passed.
    273273 *
    274  *      (c) Ray Gardner. Public domain.
     274 *      (W) Ray Gardner. Public domain.
    275275 */
    276276
     
    288288 *      the given date.
    289289 *
    290  *      (c) Ray Gardner. Public domain.
     290 *      (W) Ray Gardner. Public domain.
    291291 */
    292292
     
    308308 *
    309309 *
    310  *      (c) Ray Gardner. Public domain.
     310 *      (W) Ray Gardner. Public domain.
    311311 */
    312312
     
    343343                   ULONG year)    // in: year (e.g. 1999)
    344344{
    345     BOOL brc = FALSE;
    346345    if (day > 0)
    347346    {
     
    356355            case 12 :
    357356                if (day <= 31)
    358                     brc = TRUE;
     357                    return (TRUE);
    359358            break;
    360359
     
    364363            case 11 :
    365364                if (day <= 30)
    366                     brc = TRUE;
     365                    return (TRUE);
    367366            break;
    368367
    369368            case 2 :
    370369                if (day < 29)
    371                     brc = TRUE;
     370                    return (TRUE);
    372371                else
    373372                    if (day == 29)
    374373                        if (dtIsLeapYear(year))
    375                             return 1 ;
     374                            return (TRUE);
    376375        }
    377376    }
    378     return (brc);
    379 }
    380 
     377
     378    return (FALSE);
     379}
     380
  • trunk/src/helpers/dialog.c

    r122 r123  
    678678        cy = pcp->cy;
    679679
    680         // change the title if this is a static with SS_BITMAP;
    681         // we have used a HBITMAP in there!
    682         if (    ((ULONG)pControlDef->pcszClass == 0xffff0005L) // WC_STATIC:
    683              && (    ((flStyle & 0x0F) == SS_BITMAP)
    684                   || ((flStyle & 0x0F) == SS_ICON)
    685                 )
    686            )
    687         {
    688             // change style flag to not use SS_BITMAP nor SS_ICON;
    689             // control creation fails otherwise (stupid, stupid PM)
    690             flOld = flStyle;
    691             flStyle = ((flStyle & ~0x0F) | SS_FGNDFRAME);
    692             pcszTitle = "";
    693             lHandleSet = (LHANDLE)pControlDef->pcszText;
    694         }
    695         // hack the stupid drop-down combobox which doesn't
    696         // expand otherwise (the size of the drop-down is
    697         // the full size of the control... duh)
    698         else if (    ((ULONG)pControlDef->pcszClass == 0xffff0002L)
    699                   && (flStyle & (CBS_DROPDOWN | CBS_DROPDOWNLIST))
    700                 )
    701         {
    702             y -= 100;
    703             cy += 100;
    704         }
    705         // the stupid entry field resizes itself if it has
    706         // the ES_MARGIN style, so correlate that too... dammit
    707         // V0.9.16 (2001-12-08) [umoeller]
    708         else if (    ((ULONG)pControlDef->pcszClass == 0xffff0006L)
    709                   && (flStyle & ES_MARGIN)
    710                 )
    711         {
    712             LONG cxMargin = 3 * WinQuerySysValue(HWND_DESKTOP, SV_CXBORDER);
    713             LONG cyMargin = 3 * WinQuerySysValue(HWND_DESKTOP, SV_CYBORDER);
    714 
    715             x += cxMargin;
    716             y += cxMargin;
    717         }
     680        // now implement hacks for certain controls
     681        switch ((ULONG)pControlDef->pcszClass)
     682        {
     683            case 0xffff0005L: // WC_STATIC:
     684                // change the title if this is a static with SS_BITMAP;
     685                // we have used a HBITMAP in there!
     686                if (    (    ((flStyle & 0x0F) == SS_BITMAP)
     687                          || ((flStyle & 0x0F) == SS_ICON)
     688                        )
     689                   )
     690                {
     691                    // change style flag to not use SS_BITMAP nor SS_ICON;
     692                    // control creation fails otherwise (stupid, stupid PM)
     693                    flOld = flStyle;
     694                    flStyle = ((flStyle & ~0x0F) | SS_FGNDFRAME);
     695                    pcszTitle = "";
     696                    lHandleSet = (LHANDLE)pControlDef->pcszText;
     697                }
     698            break;
     699
     700            case 0xffff0002L:   // combobox
     701                // hack the stupid drop-down combobox which doesn't
     702                // expand otherwise (the size of the drop-down is
     703                // the full size of the control... duh)
     704                if (flStyle & (CBS_DROPDOWN | CBS_DROPDOWNLIST))
     705                {
     706                    y -= 100;
     707                    cy += 100;
     708                }
     709            break;
     710
     711            case 0xffff0006L:   // entry field
     712                // the stupid entry field resizes itself if it has
     713                // the ES_MARGIN style, so correlate that too... dammit
     714                // V0.9.16 (2001-12-08) [umoeller]
     715                if (flStyle & ES_MARGIN)
     716                {
     717                    LONG cxMargin = 3 * WinQuerySysValue(HWND_DESKTOP, SV_CXBORDER);
     718                    LONG cyMargin = 3 * WinQuerySysValue(HWND_DESKTOP, SV_CYBORDER);
     719
     720                    x += cxMargin;
     721                    y += cxMargin;
     722                }
     723            break;
     724        } // end switch ((ULONG)pControlDef->pcszClass)
    718725    }
    719726
  • trunk/src/helpers/dosh.c

    r122 r123  
    127127    ULONG           ulAction;
    128128
    129     arc = DosOpen("KBD$", &hfKbd, &ulAction, 0,
    130                   FILE_NORMAL, FILE_OPEN,
    131                   OPEN_ACCESS_READONLY | OPEN_SHARE_DENYWRITE,
    132                   (PEAOP2)NULL);
    133     if (arc == NO_ERROR)
     129    if (!(arc = DosOpen("KBD$", &hfKbd, &ulAction, 0,
     130                        FILE_NORMAL,
     131                        FILE_OPEN,
     132                        OPEN_ACCESS_READONLY | OPEN_SHARE_DENYWRITE,
     133                        (PEAOP2)NULL)))
    134134    {
    135135        SHIFTSTATE      ShiftState;
    136136        ULONG           cbDataLen = sizeof(ShiftState);
    137137
    138         arc = DosDevIOCtl(hfKbd, IOCTL_KEYBOARD, KBD_GETSHIFTSTATE,
    139                           NULL, 0, NULL,      // no parameters
    140                           &ShiftState, cbDataLen, &cbDataLen);
    141         if (arc == NO_ERROR)
     138        if (!(arc = DosDevIOCtl(hfKbd, IOCTL_KEYBOARD, KBD_GETSHIFTSTATE,
     139                                NULL, 0, NULL,      // no parameters
     140                                &ShiftState, cbDataLen, &cbDataLen)))
    142141            brc = ((ShiftState.fsState & 3) != 0);
    143142
     
    308307
    309308    return (pv);
     309}
     310
     311/*
     312 *@@ doshAllocArray:
     313 *      allocates c * cbArrayItem bytes.
     314 *      Similar to calloc(), but returns
     315 *      error codes:
     316 *
     317 *      --  NO_ERROR: *ppv and *pcbAllocated were set.
     318 *
     319 *      --  ERROR_NO_DATA: either c or cbArrayItem are
     320 *          zero.
     321 *
     322 *      --  ERROR_NOT_ENOUGH_MEMORY: malloc() failed.
     323 *
     324 *@@added V0.9.16 (2001-12-08) [umoeller]
     325 */
     326
     327APIRET doshAllocArray(ULONG c,              // in: array item count
     328                      ULONG cbArrayItem,    // in: size of one array item
     329                      PBYTE *ppv,           // out: memory ptr if NO_ERROR is returned
     330                      PULONG pcbAllocated)  // out: # of bytes allocated
     331{
     332    if (!c || !cbArrayItem)
     333        return ERROR_NO_DATA;
     334
     335    *pcbAllocated = c * cbArrayItem;
     336    if (!(*ppv = malloc(*pcbAllocated)))
     337        return ERROR_NOT_ENOUGH_MEMORY;
     338
     339    return NO_ERROR;
    310340}
    311341
     
    13331363 *      has no dot in it).
    13341364 *
     1365 *      In the pathological case of a dot in the path
     1366 *      but not in the filename itself, this correctly
     1367 *      returns NULL.
     1368 *
    13351369 *@@added V0.9.6 (2000-10-16) [umoeller]
    13361370 *@@changed V0.9.7 (2000-12-10) [umoeller]: fixed "F:filename.ext" case
     
    13441378    {
    13451379        // find filename
    1346         PCSZ    p2 = strrchr(pcszFilename + 2, '\\'),
    1347                             // works on "C:\blah" or "\\unc\blah"
     1380        PCSZ    p2,
    13481381                pStartOfName = NULL,
    13491382                pExtension = NULL;
    13501383
    1351         if (p2)
     1384        if (p2 = strrchr(pcszFilename + 2, '\\'))
     1385                            // works on "C:\blah" or "\\unc\blah"
    13521386            pStartOfName = p2 + 1;
    13531387        else
     
    13651399
    13661400        // find last dot in filename
    1367         pExtension = strrchr(pStartOfName, '.');
    1368         if (pExtension)
     1401        if (pExtension = strrchr(pStartOfName, '.'))
    13691402            pReturn = (PSZ)pExtension + 1;
    13701403    }
     
    14181451        // Each data field following fsqBuffer.szName begins
    14191452        // immediately after the previous item.
    1420         if (strncmp((PSZ)&(pfsqBuffer->szName) + pfsqBuffer->cbName + 1,
    1421                     "FAT",
    1422                     3)
    1423                == 0)
     1453        if (!strncmp((PSZ)&(pfsqBuffer->szName) + pfsqBuffer->cbName + 1,
     1454                     "FAT",
     1455                     3))
    14241456            brc = TRUE;
    14251457    }
     
    14381470 */
    14391471
    1440 APIRET doshQueryFileSize(HFILE hFile,
    1441                          PULONG pulSize)
     1472APIRET doshQueryFileSize(HFILE hFile,       // in: file handle
     1473                         PULONG pulSize)    // out: file size (ptr can be NULL)
    14421474{
    14431475    APIRET arc;
    14441476    FILESTATUS3 fs3;
    14451477    if (!(arc = DosQueryFileInfo(hFile, FIL_STANDARD, &fs3, sizeof(fs3))))
    1446         *pulSize = fs3.cbFile;
     1478        if (pulSize)
     1479            *pulSize = fs3.cbFile;
    14471480    return (arc);
    14481481}
     
    14531486 *      or 0 if the file could not be
    14541487 *      found.
     1488 *
    14551489 *      Use doshQueryFileSize instead to query the
    14561490 *      size if you have a HFILE.
    14571491 *
     1492 *      Otherwise this returns:
     1493 *
     1494 *      --  ERROR_FILE_NOT_FOUND
     1495 *      --  ERROR_PATH_NOT_FOUND
     1496 *      --  ERROR_SHARING_VIOLATION
     1497 *      --  ERROR_FILENAME_EXCED_RANGE
     1498 *      --  ERROR_INVALID_PARAMETER
     1499 *
    14581500 *@@changed V0.9.16 (2001-10-19) [umoeller]: now returning APIRET
    14591501 */
    14601502
    1461 APIRET doshQueryPathSize(PCSZ pcszFile,
    1462                          PULONG pulSize)
     1503APIRET doshQueryPathSize(PCSZ pcszFile,         // in: filename
     1504                         PULONG pulSize)        // out: file size (ptr can be NULL)
    14631505{
    14641506    APIRET arc;
    1465     FILESTATUS3 fs3;
    1466     if (!(arc = DosQueryPathInfo((PSZ)pcszFile, FIL_STANDARD, &fs3, sizeof(fs3))))
    1467         *pulSize = fs3.cbFile;
     1507
     1508    if (pcszFile)      // V0.9.16 (2001-12-08) [umoeller]
     1509    {
     1510        FILESTATUS3 fs3;
     1511        if (!(arc = DosQueryPathInfo((PSZ)pcszFile, FIL_STANDARD, &fs3, sizeof(fs3))))
     1512            if (pulSize)
     1513                *pulSize = fs3.cbFile;
     1514    }
     1515    else
     1516        arc = ERROR_INVALID_PARAMETER;
     1517
    14681518    return (arc);
    14691519}
     
    14881538 *      returned.
    14891539 *
     1540 *      Otherwise this returns:
     1541 *
     1542 *      --  ERROR_FILE_NOT_FOUND
     1543 *      --  ERROR_PATH_NOT_FOUND
     1544 *      --  ERROR_SHARING_VIOLATION
     1545 *      --  ERROR_FILENAME_EXCED_RANGE
     1546 *
    14901547 *@@added V0.9.0 [umoeller]
    14911548 */
    14921549
    14931550APIRET doshQueryPathAttr(const char* pcszFile,      // in: file or directory name
    1494                          PULONG pulAttr)            // out: attributes
     1551                         PULONG pulAttr)            // out: attributes (ptr can be NULL)
    14951552{
    14961553    FILESTATUS3 fs3;
    1497     APIRET arc = DosQueryPathInfo((PSZ)pcszFile,
     1554    APIRET arc;
     1555
     1556    if (!(arc = DosQueryPathInfo((PSZ)pcszFile,
    14981557                                  FIL_STANDARD,
    14991558                                  &fs3,
    1500                                   sizeof(fs3));
    1501     if (arc == NO_ERROR)
     1559                                  sizeof(fs3))))
    15021560    {
    15031561        if (pulAttr)
     
    15321590                       ULONG ulAttr)            // in: new attributes
    15331591{
    1534     FILESTATUS3 fs3;
    1535     APIRET rc = DosQueryPathInfo((PSZ)pcszFile,
     1592    APIRET arc;
     1593
     1594    if (pcszFile)
     1595    {
     1596        FILESTATUS3 fs3;
     1597        if (!(arc = DosQueryPathInfo((PSZ)pcszFile,
     1598                                      FIL_STANDARD,
     1599                                      &fs3,
     1600                                      sizeof(fs3))))
     1601        {
     1602            fs3.attrFile = ulAttr;
     1603            arc = DosSetPathInfo((PSZ)pcszFile,
    15361604                                 FIL_STANDARD,
    15371605                                 &fs3,
    1538                                  sizeof(fs3));
    1539 
    1540     if (rc == NO_ERROR)
    1541     {
    1542         fs3.attrFile = ulAttr;
    1543         rc = DosSetPathInfo((PSZ)pcszFile,
    1544                             FIL_STANDARD,
    1545                             &fs3,
    1546                             sizeof(fs3),
    1547                             DSPI_WRTTHRU);
    1548     }
    1549     return (rc);
     1606                                 sizeof(fs3),
     1607                                 DSPI_WRTTHRU);
     1608        }
     1609    }
     1610    else
     1611        arc = ERROR_INVALID_PARAMETER;
     1612
     1613    return (arc);
    15501614}
    15511615
     
    16401704                  LONG lOffset,    // in: offset to write at (depends on ulMethod)
    16411705                  ULONG ulMethod,  // in: one of FILE_BEGIN, FILE_CURRENT, FILE_END
    1642                   ULONG cb,        // in: bytes to write
     1706                  PULONG pcb,      // in: bytes to read, out: bytes read
    16431707                  PBYTE pbData)    // out: read buffer (must be cb bytes)
    16441708{
    16451709    APIRET arc;
     1710    ULONG cb = *pcb;
    16461711    ULONG ulDummy;
     1712
     1713    *pcb = 0;
     1714
    16471715    if (!(arc = DosSetFilePtr(hf,
    16481716                              lOffset,
    16491717                              ulMethod,
    16501718                              &ulDummy)))
    1651         arc = DosRead(hf,
    1652                       pbData,
    1653                       cb,
    1654                       &ulDummy);
     1719    {
     1720        if (!(arc = DosRead(hf,
     1721                            pbData,
     1722                            cb,
     1723                            &ulDummy)))
     1724            *pcb = ulDummy;     // bytes read
     1725    }
    16551726
    16561727    return (arc);
     
    16631734 *
    16641735 *      ulOpenMode determines the mode to open the
    1665  *      file in:
    1666  *
    1667  +      +-------------------------+------+-----------+-----------+
    1668  +      |                         |      |           |           |
    1669  +      |  ulOpenMode             | mode | if exists | if new    |
    1670  +      +-------------------------+------+-----------+-----------+
    1671  +      |  XOPEN_READ_EXISTING    | read | opens     | fails     |
    1672  +      +-------------------------+------+-----------+-----------+
    1673  +      |  XOPEN_READWRITE_APPEND | r/w  | opens,    | creates   |
    1674  +      |                         |      | appends   |           |
    1675  +      +-------------------------+------+-----------+-----------+
    1676  +      |  XOPEN_READWRITE_NEW    | r/w  | replaces  | creates   |
    1677  +      +-------------------------+------+-----------+-----------+
    1678  *
    1679  *      In addition, you can specify the XOPEN_BINARY flag:
     1736 *      file in (fptr specifies the position after
     1737 *      the open):
     1738 *
     1739 +      +-------------------------+------+------------+-----------+
     1740 +      |  ulOpenMode             | mode | if exists  | if new    |
     1741 +      +-------------------------+------+------------+-----------+
     1742 +      |  XOPEN_READ_EXISTING    | read | opens      | fails     |
     1743 +      |                         |      | fptr = 0   |           |
     1744 +      +-------------------------+------+------------+-----------+
     1745 +      |  XOPEN_READWRITE_APPEND | r/w  | opens,     | creates   |
     1746 +      |                         |      | appends    |           |
     1747 +      |                         |      | fptr = end | fptr = 0  |
     1748 +      +-------------------------+------+------------+-----------+
     1749 +      |  XOPEN_READWRITE_NEW    | r/w  | replaces   | creates   |
     1750 +      |                         |      | fptr = 0   | fptr = 0  |
     1751 +      +-------------------------+------+------------+-----------+
     1752 *
     1753 *      In addition, you can OR one of the above values with
     1754 *      the XOPEN_BINARY flag:
    16801755 *
    16811756 *      --  If XOPEN_BINARY is set, no conversion is performed
     
    16871762 *      *ppFile receives a new XFILE structure describing
    16881763 *      the open file, if NO_ERROR is returned.
     1764 *
     1765 *      The file pointer is then set to the beginning of the
     1766 *      file _unless_ XOPEN_READWRITE_APPEND was specified;
     1767 *      in that case only, the file pointer is set to the
     1768 *      end of the file so data can be appended (see above).
     1769 *
     1770 *      Otherwise this returns:
     1771 *
     1772 *      --  ERROR_FILE_NOT_FOUND
     1773 *      --  ERROR_PATH_NOT_FOUND
     1774 *      --  ERROR_SHARING_VIOLATION
     1775 *      --  ERROR_FILENAME_EXCED_RANGE
     1776 *
     1777 *      --  ERROR_NOT_ENOUGH_MEMORY
     1778 *      --  ERROR_INVALID_PARAMETER
    16891779 *
    16901780 *@@added V0.9.16 (2001-10-19) [umoeller]
     
    16991789    APIRET arc = NO_ERROR;
    17001790
    1701     ULONG   fsOpenFlags = 0,
    1702             fsOpenMode =    OPEN_FLAGS_FAIL_ON_ERROR
    1703                           | OPEN_FLAGS_NO_LOCALITY
    1704                           | OPEN_FLAGS_NOINHERIT;
    1705 
    1706     switch (flOpenMode & XOPEN_ACCESS_MASK)
    1707     {
    1708         case XOPEN_READ_EXISTING:
    1709             fsOpenFlags =   OPEN_ACTION_FAIL_IF_NEW
    1710                           | OPEN_ACTION_OPEN_IF_EXISTS;
    1711             fsOpenMode |=   OPEN_SHARE_DENYWRITE
    1712                           | OPEN_ACCESS_READONLY;
    1713             // _Pmpf((__FUNCTION__ ": opening XOPEN_READ_EXISTING"));
    1714         break;
    1715 
    1716         case XOPEN_READWRITE_APPEND:
    1717             fsOpenFlags =   OPEN_ACTION_CREATE_IF_NEW
    1718                           | OPEN_ACTION_OPEN_IF_EXISTS;
    1719             fsOpenMode |=   OPEN_SHARE_DENYREADWRITE
    1720                           | OPEN_ACCESS_READWRITE;
    1721             // _Pmpf((__FUNCTION__ ": opening XOPEN_READWRITE_APPEND"));
    1722         break;
    1723 
    1724         case XOPEN_READWRITE_NEW:
    1725             fsOpenFlags =   OPEN_ACTION_CREATE_IF_NEW
    1726                           | OPEN_ACTION_REPLACE_IF_EXISTS;
    1727             fsOpenMode |=   OPEN_SHARE_DENYREADWRITE
    1728                           | OPEN_ACCESS_READWRITE;
    1729             // _Pmpf((__FUNCTION__ ": opening XOPEN_READWRITE_NEW"));
    1730         break;
    1731 
    1732         default:
    1733             arc = ERROR_INVALID_PARAMETER;
    1734     }
    1735 
    1736     if ((!arc) && pcszFilename && fsOpenFlags && pcbFile && ppFile)
    1737     {
    1738         PXFILE pFile;
    1739         if (pFile = NEW(XFILE))
     1791    // run this first, because if the file doesn't
     1792    // exists, DosOpen only returns ERROR_OPEN_FAILED,
     1793    // which isn't that meaningful
     1794    // V0.9.16 (2001-12-08) [umoeller]
     1795    if (!(arc = doshQueryPathSize(pcszFilename,
     1796                                  pcbFile)))
     1797    {
     1798        ULONG   fsOpenFlags = 0,
     1799                fsOpenMode =    OPEN_FLAGS_FAIL_ON_ERROR
     1800                              | OPEN_FLAGS_NO_LOCALITY
     1801                              | OPEN_FLAGS_NOINHERIT;
     1802
     1803        switch (flOpenMode & XOPEN_ACCESS_MASK)
    17401804        {
    1741             ULONG ulAction;
    1742 
    1743             ZERO(pFile);
    1744 
    1745             // copy open flags
    1746             pFile->flOpenMode = flOpenMode;
    1747 
    1748             if (!(arc = DosOpen((PSZ)pcszFilename,
    1749                                 &pFile->hf,
    1750                                 &ulAction,
    1751                                 *pcbFile,
    1752                                 FILE_ARCHIVED,
    1753                                 fsOpenFlags,
    1754                                 fsOpenMode,
    1755                                 NULL)))       // EAs
     1805            case XOPEN_READ_EXISTING:
     1806                fsOpenFlags =   OPEN_ACTION_FAIL_IF_NEW
     1807                              | OPEN_ACTION_OPEN_IF_EXISTS;
     1808                fsOpenMode |=   OPEN_SHARE_DENYWRITE
     1809                              | OPEN_ACCESS_READONLY;
     1810                // _Pmpf((__FUNCTION__ ": opening XOPEN_READ_EXISTING"));
     1811            break;
     1812
     1813            case XOPEN_READWRITE_APPEND:
     1814                fsOpenFlags =   OPEN_ACTION_CREATE_IF_NEW
     1815                              | OPEN_ACTION_OPEN_IF_EXISTS;
     1816                fsOpenMode |=   OPEN_SHARE_DENYREADWRITE
     1817                              | OPEN_ACCESS_READWRITE;
     1818                // _Pmpf((__FUNCTION__ ": opening XOPEN_READWRITE_APPEND"));
     1819            break;
     1820
     1821            case XOPEN_READWRITE_NEW:
     1822                fsOpenFlags =   OPEN_ACTION_CREATE_IF_NEW
     1823                              | OPEN_ACTION_REPLACE_IF_EXISTS;
     1824                fsOpenMode |=   OPEN_SHARE_DENYREADWRITE
     1825                              | OPEN_ACCESS_READWRITE;
     1826                // _Pmpf((__FUNCTION__ ": opening XOPEN_READWRITE_NEW"));
     1827            break;
     1828        }
     1829
     1830        if ((!arc) && fsOpenFlags && pcbFile && ppFile)
     1831        {
     1832            PXFILE pFile;
     1833            if (pFile = NEW(XFILE))
    17561834            {
    1757                 // alright, got the file:
    1758 
    1759                 if (    (ulAction == FILE_EXISTED)
    1760                      && ((flOpenMode & XOPEN_ACCESS_MASK) == XOPEN_READWRITE_APPEND)
    1761                    )
    1762                     // get its size and set ptr to end for append
    1763                     arc = DosSetFilePtr(pFile->hf,
    1764                                         0,
    1765                                         FILE_END,
    1766                                         pcbFile);
     1835                ULONG ulAction;
     1836
     1837                ZERO(pFile);
     1838
     1839                // copy open flags
     1840                pFile->flOpenMode = flOpenMode;
     1841
     1842                if (!(arc = DosOpen((PSZ)pcszFilename,
     1843                                    &pFile->hf,
     1844                                    &ulAction,
     1845                                    *pcbFile,
     1846                                    FILE_ARCHIVED,
     1847                                    fsOpenFlags,
     1848                                    fsOpenMode,
     1849                                    NULL)))       // EAs
     1850                {
     1851                    // alright, got the file:
     1852
     1853                    if (    (ulAction == FILE_EXISTED)
     1854                         && ((flOpenMode & XOPEN_ACCESS_MASK) == XOPEN_READWRITE_APPEND)
     1855                       )
     1856                        // get its size and set ptr to end for append
     1857                        arc = DosSetFilePtr(pFile->hf,
     1858                                            0,
     1859                                            FILE_END,
     1860                                            pcbFile);
     1861                    else
     1862                        arc = doshQueryFileSize(pFile->hf,
     1863                                                pcbFile);
     1864                        // file ptr is at beginning
     1865
     1866                    // store file size
     1867                    pFile->cbInitial
     1868                    = pFile->cbCurrent
     1869                    = *pcbFile;
     1870                }
     1871
     1872                if (arc)
     1873                    doshClose(&pFile);
    17671874                else
    1768                     arc = doshQueryFileSize(pFile->hf,
    1769                                             pcbFile);
    1770                     // file ptr is at beginning
    1771 
    1772                 // store file size
    1773                 pFile->cbInitial
    1774                 = pFile->cbCurrent
    1775                 = *pcbFile;
     1875                    *ppFile = pFile;
    17761876            }
    1777 
    1778             if (arc)
    1779                 doshClose(&pFile);
    17801877            else
    1781                 *ppFile = pFile;
     1878                arc = ERROR_NOT_ENOUGH_MEMORY;
    17821879        }
    17831880        else
    1784             arc = ERROR_NOT_ENOUGH_MEMORY;
    1785     }
    1786     else
    1787         arc = ERROR_INVALID_PARAMETER;
     1881            arc = ERROR_INVALID_PARAMETER;
     1882    }
    17881883
    17891884    return (arc);
     
    21992294        if (!pcszTemp)
    22002295        {
    2201             pcszTemp = getenv("TEMP");
    2202             if (!pcszTemp)
     2296            if (!(pcszTemp = getenv("TEMP")))
    22032297                pcszTemp = getenv("TMP");
    22042298        }
     
    23852479 *@@ doshQueryDirExist:
    23862480 *      returns TRUE if the given directory
    2387  *      exists.
     2481 *      exists and really is a directory.
    23882482 */
    23892483
     
    23912485{
    23922486    FILESTATUS3 fs3;
    2393     APIRET arc = DosQueryPathInfo((PSZ)pcszDir,
    2394                                   FIL_STANDARD,
    2395                                   &fs3,
    2396                                   sizeof(fs3));
    2397     if (arc == NO_ERROR)
     2487    APIRET arc;
     2488
     2489    if (!(arc = DosQueryPathInfo((PSZ)pcszDir,
     2490                                 FIL_STANDARD,
     2491                                 &fs3,
     2492                                 sizeof(fs3))))
    23982493        // file found:
    23992494        return ((fs3.attrFile & FILE_DIRECTORY) != 0);
     
    26412736{
    26422737    CHAR    szName[CCHMAXPATH];
    2643     APIRET arc = DosLoadModule(szName,
    2644                                sizeof(szName),
    2645                                pszModuleName,
    2646                                phmod);
    2647     if (arc == NO_ERROR)
     2738    APIRET  arc;
     2739
     2740    if (!(arc = DosLoadModule(szName,
     2741                              sizeof(szName),
     2742                              pszModuleName,
     2743                              phmod)))
    26482744    {
    26492745        ULONG  ul;
     
    26522748             ul++)
    26532749        {
    2654             arc = DosQueryProcAddr(*phmod,
    2655                                    0,               // ordinal, ignored
    2656                                    (PSZ)paResolves[ul].pcszFunctionName,
    2657                                    paResolves[ul].ppFuncAddress);
    2658 
    2659             /* _Pmpf(("Resolved %s to 0x%lX, rc: %d",
    2660                     paResolves[ul].pcszFunctionName,
    2661                     *paResolves[ul].ppFuncAddress,
    2662                     arc)); */
    2663             if (arc != NO_ERROR)
     2750            if (arc = DosQueryProcAddr(*phmod,
     2751                                       0,               // ordinal, ignored
     2752                                       (PSZ)paResolves[ul].pcszFunctionName,
     2753                                       paResolves[ul].ppFuncAddress))
     2754                // error:
    26642755                break;
    26652756        }
     2757
     2758        if (arc)
     2759            // V0.9.16 (2001-12-08) [umoeller]
     2760            DosFreeModule(*phmod);
    26662761    }
    26672762
  • trunk/src/helpers/dosh2.c

    r110 r123  
    426426 *@@changed V0.9.10 (2001-04-08) [umoeller]: now setting ppExec only if NO_ERROR is returned
    427427 *@@changed V0.9.12 (2001-05-03) [umoeller]: added support for NOSTUB newstyle executables
     428 *@@changed V0.9.16 (2001-12-08) [umoeller]: now using OPEN_SHARE_DENYWRITE
     429 *@@changed V0.9.16 (2001-12-08) [umoeller]: fLibrary was never set, works for LX and NE now
    428430 */
    429431
     
    440442        return (ERROR_INVALID_PARAMETER);
    441443
    442     pExec = (PEXECUTABLE)malloc(sizeof(EXECUTABLE));
    443     if (!(pExec))
     444    if (!(pExec = (PEXECUTABLE)malloc(sizeof(EXECUTABLE))))
    444445        return (ERROR_NOT_ENOUGH_MEMORY);
    445446
     
    458459                           | OPEN_FLAGS_SEQUENTIAL
    459460                           | OPEN_FLAGS_NOINHERIT
    460                            | OPEN_SHARE_DENYNONE
     461                           // | OPEN_SHARE_DENYNONE
     462                           | OPEN_SHARE_DENYWRITE       // changed V0.9.16 (2001-12-08) [umoeller]
    461463                           | OPEN_ACCESS_READONLY,      // read-only mode
    462464                        NULL)))                         // no EAs
     
    464466        // file opened successfully:
    465467
    466         ULONG           ulLocal = 0;
    467 
    468468        // read old DOS EXE header
    469         pExec->pDosExeHeader = (PDOSEXEHEADER)malloc(sizeof(DOSEXEHEADER));
    470         if (!(pExec->pDosExeHeader))
     469        if (!(pExec->pDosExeHeader = (PDOSEXEHEADER)malloc(sizeof(DOSEXEHEADER))))
    471470            arc = ERROR_NOT_ENOUGH_MEMORY;
    472471        else
    473472        {
    474             ULONG   ulBytesRead = 0;
    475 
    476             if (    (!(arc = DosSetFilePtr(hFile,
    477                                            0L,
    478                                            FILE_BEGIN,
    479                                            &ulLocal)))      // out: new offset
    480                  && (!(arc = DosRead(hFile,
    481                                      pExec->pDosExeHeader,
    482                                      sizeof(DOSEXEHEADER),
    483                                      &(pExec->cbDosExeHeader))))
    484                )
     473            pExec->cbDosExeHeader = sizeof(DOSEXEHEADER);
     474            if (!(arc = doshReadAt(hFile,
     475                                   0,
     476                                   FILE_BEGIN,
     477                                   &pExec->cbDosExeHeader,      // in/out
     478                                   (PBYTE)pExec->pDosExeHeader)))
    485479            {
    486480                ULONG ulNewHeaderOfs = 0;       // V0.9.12 (2001-05-03) [umoeller]
     
    530524                    // V0.9.12 (2001-05-03) [umoeller]
    531525                    CHAR    achNewHeaderType[2] = "";
    532 
    533                     if (    (!(arc = DosSetFilePtr(hFile,
    534                                                    ulNewHeaderOfs,
    535                                                    FILE_BEGIN,
    536                                                    &ulLocal)))
    537                             // read two chars to find out header type
    538                          && (!(arc = DosRead(hFile,
    539                                              &achNewHeaderType,
    540                                              sizeof(achNewHeaderType),
    541                                              &ulBytesRead)))
    542                        )
     526                    ULONG   cbRead;
     527
     528                    cbRead = sizeof(achNewHeaderType);
     529                    if (!(arc = doshReadAt(hFile,
     530                                           ulNewHeaderOfs,
     531                                           FILE_BEGIN,
     532                                           &cbRead,
     533                                           achNewHeaderType)))
    543534                    {
    544535                        PBYTE   pbCheckOS = NULL;
    545536
    546537                        // reset file ptr
    547                         DosSetFilePtr(hFile,
     538                        /* DosSetFilePtr(hFile,
    548539                                      ulNewHeaderOfs,
    549540                                      FILE_BEGIN,
    550541                                      &ulLocal);
    551 
    552                         if (memcmp(achNewHeaderType, "NE", 2) == 0)
     542                           */
     543
     544                        if (!memcmp(achNewHeaderType, "NE", 2))
    553545                        {
    554546                            // New Executable:
    555547                            pExec->ulExeFormat = EXEFORMAT_NE;
    556548                            // allocate NE header
    557                             pExec->pNEHeader = (PNEHEADER)malloc(sizeof(NEHEADER));
    558                             if (!(pExec->pNEHeader))
     549                            if (pExec->pNEHeader = (PNEHEADER)malloc(sizeof(NEHEADER)))
     550                            {
     551                                // read in NE header
     552                                pExec->cbNEHeader = sizeof(NEHEADER);
     553                                if (!(arc = doshReadAt(hFile,
     554                                                       ulNewHeaderOfs,
     555                                                       FILE_BEGIN,
     556                                                       &pExec->cbNEHeader,
     557                                                       (PBYTE)pExec->pNEHeader)))
     558                                {
     559                                    if (pExec->cbNEHeader == sizeof(NEHEADER))
     560                                    {
     561                                        pbCheckOS = &pExec->pNEHeader->bTargetOS;
     562                                        // set library flag V0.9.16 (2001-12-08) [umoeller]
     563                                        if (pExec->pNEHeader->usFlags & 0x8000)
     564                                            // library:
     565                                            pExec->fLibrary = TRUE;
     566                                    }
     567                                    else
     568                                        // V0.9.16 (2001-12-08) [umoeller]
     569                                        arc = ERROR_INVALID_EXE_SIGNATURE;
     570                                }
     571                            }
     572                            else
    559573                                arc = ERROR_NOT_ENOUGH_MEMORY;
    560                             else
    561                                 // read in NE header
    562                                 if (!(arc = DosRead(hFile,
    563                                                     pExec->pNEHeader,
    564                                                     sizeof(NEHEADER),
    565                                                     &(pExec->cbNEHeader))))
    566                                     if (pExec->cbNEHeader == sizeof(NEHEADER))
    567                                         pbCheckOS = &(pExec->pNEHeader->bTargetOS);
    568574                        }
    569575                        else if (   (memcmp(achNewHeaderType, "LX", 2) == 0)
     
    575581                            pExec->ulExeFormat = EXEFORMAT_LX;
    576582                            // allocate LX header
    577                             pExec->pLXHeader = (PLXHEADER)malloc(sizeof(LXHEADER));
    578                             if (!(pExec->pLXHeader))
     583                            if (pExec->pLXHeader = (PLXHEADER)malloc(sizeof(LXHEADER)))
     584                            {
     585                                // read in LX header
     586                                pExec->cbLXHeader = sizeof(LXHEADER);
     587                                if (!(arc = doshReadAt(hFile,
     588                                                       ulNewHeaderOfs,
     589                                                       FILE_BEGIN,
     590                                                       &pExec->cbLXHeader,
     591                                                       (PBYTE)pExec->pLXHeader)))
     592                                {
     593                                    if (pExec->cbLXHeader == sizeof(LXHEADER))
     594                                    {
     595                                        pbCheckOS = (PBYTE)(&pExec->pLXHeader->usTargetOS);
     596                                        // set library flag V0.9.16 (2001-12-08) [umoeller]
     597                                        if (pExec->pLXHeader->ulFlags & 0x8000)
     598                                            // library:
     599                                            pExec->fLibrary = TRUE;
     600                                    }
     601                                    else
     602                                        // V0.9.16 (2001-12-08) [umoeller]
     603                                        arc = ERROR_INVALID_EXE_SIGNATURE;
     604                                }
     605                            }
     606                            else
    579607                                arc = ERROR_NOT_ENOUGH_MEMORY;
    580                             else
    581                                 // read in LX header
    582                                 if (!(arc = DosRead(hFile,
    583                                                     pExec->pLXHeader,
    584                                                     sizeof(LXHEADER),
    585                                                     &(pExec->cbLXHeader))))
    586                                     if (pExec->cbLXHeader == sizeof(LXHEADER))
    587                                         pbCheckOS = (PBYTE)(&(pExec->pLXHeader->usTargetOS));
    588608                        }
    589609                        else if (memcmp(achNewHeaderType, "PE", 2) == 0)
     
    597617                            // V0.9.10 (2001-04-08) [lafaix]
    598618                            // read in standard PE header
    599                             if (!(arc = DosRead(hFile,
    600                                                 &PEHeader,
    601                                                 24,
    602                                                 &ulBytesRead)))
     619                            cbRead = 24;
     620                            if (!(arc = doshReadAt(hFile,
     621                                                   ulNewHeaderOfs,
     622                                                   FILE_BEGIN,
     623                                                   &cbRead,
     624                                                   (PBYTE)&PEHeader)))
    603625                            {
    604626                                // allocate PE header
    605                                 pExec->pPEHeader = (PPEHEADER)malloc(24 + PEHeader.usHeaderSize);
    606                                 if (!(pExec->pPEHeader))
    607                                     arc = ERROR_NOT_ENOUGH_MEMORY;
    608                                 else
     627                                if (pExec->pPEHeader = (PPEHEADER)malloc(24 + PEHeader.usHeaderSize))
    609628                                {
    610629                                    // copy standard PE header
     
    615634                                    // read in optional PE header
    616635                                    if (!(arc = DosRead(hFile,
    617                                                         &(pExec->pPEHeader->usReserved3),
     636                                                        &pExec->pPEHeader->usReserved3,
    618637                                                        PEHeader.usHeaderSize,
    619                                                         &(pExec->cbPEHeader))))
     638                                                        &pExec->cbPEHeader)))
    620639                                        pExec->cbPEHeader += 24;
    621640                                }
     641                                else
     642                                    arc = ERROR_NOT_ENOUGH_MEMORY;
    622643                            }
    623644                        }
     
    661682    if (arc != NO_ERROR)
    662683        // error: clean up
    663         doshExecClose(pExec);
     684        doshExecClose(&pExec);
    664685    else
    665686        *ppExec = pExec;
    666 
    667     return (arc);
    668 }
    669 
    670 /*
    671  *@@ doshExecClose:
    672  *      this closes an executable opened with doshExecOpen.
    673  *      Always call this function if NO_ERROR was returned by
    674  *      doshExecOpen.
    675  *
    676  *@@added V0.9.0 [umoeller]
    677  */
    678 
    679 APIRET doshExecClose(PEXECUTABLE pExec)
    680 {
    681     APIRET arc = NO_ERROR;
    682     if (pExec)
    683     {
    684         if (pExec->pDosExeHeader)
    685             free(pExec->pDosExeHeader);
    686         if (pExec->pNEHeader)
    687             free(pExec->pNEHeader);
    688         if (pExec->pLXHeader)
    689             free(pExec->pLXHeader);
    690 
    691         if (pExec->pszDescription)
    692             free(pExec->pszDescription);
    693         if (pExec->pszVendor)
    694             free(pExec->pszVendor);
    695         if (pExec->pszVersion)
    696             free(pExec->pszVersion);
    697         if (pExec->pszInfo)
    698             free(pExec->pszInfo);
    699 
    700         if (pExec->hfExe)
    701             arc = DosClose(pExec->hfExe);
    702 
    703         free(pExec);
    704     }
    705     else
    706         arc = ERROR_INVALID_PARAMETER;
    707687
    708688    return (arc);
     
    789769                    {
    790770                        // date/time seems to be fixed 24 chars in length
    791                         pExec->pszBuildDateTime = (PSZ)malloc(25);
    792                         if (pExec->pszBuildDateTime)
     771                        if (pExec->pszBuildDateTime = (PSZ)malloc(25))
    793772                        {
    794773                            memcpy(pExec->pszBuildDateTime,
     
    18621841        {
    18631842            // 32-bit OS/2 executable:
    1864             cResources = pExec->pLXHeader->ulResTblCnt;
    1865 
    1866             if (cResources)
     1843            if (cResources = pExec->pLXHeader->ulResTblCnt)
    18671844            {
    18681845                #pragma pack(1)     // V0.9.9 (2001-04-02) [umoeller]
    1869                 struct rsrc32               /* Resource Table Entry */
     1846                struct rsrc32               // Resource Table Entry
    18701847                {
    1871                     unsigned short  type;   /* Resource type */
    1872                     unsigned short  name;   /* Resource name */
    1873                     unsigned long   cb;     /* Resource size */
    1874                     unsigned short  obj;    /* Object number */
    1875                     unsigned long   offset; /* Offset within object */
     1848                    unsigned short  type;   // Resource type
     1849                    unsigned short  name;   // Resource name
     1850                    unsigned long   cb;     // Resource size
     1851                    unsigned short  obj;    // Object number
     1852                    unsigned long   offset; // Offset within object
    18761853                } rs;
    18771854
    1878                 struct o32_obj                    /* Flat .EXE object table entry */
     1855                struct o32_obj                    // Flat .EXE object table entry
    18791856                {
    1880                     unsigned long   o32_size;     /* Object virtual size */
    1881                     unsigned long   o32_base;     /* Object base virtual address */
    1882                     unsigned long   o32_flags;    /* Attribute flags */
    1883                     unsigned long   o32_pagemap;  /* Object page map index */
    1884                     unsigned long   o32_mapsize;  /* Number of entries in object page map */
    1885                     unsigned long   o32_reserved; /* Reserved */
     1857                    unsigned long   o32_size;     // Object virtual size
     1858                    unsigned long   o32_base;     // Object base virtual address
     1859                    unsigned long   o32_flags;    // Attribute flags
     1860                    unsigned long   o32_pagemap;  // Object page map index
     1861                    unsigned long   o32_mapsize;  // Number of entries in object page map
     1862                    unsigned long   o32_reserved; // Reserved
    18861863                } ot;
    18871864                #pragma pack() // V0.9.9 (2001-04-03) [umoeller]
     
    18901867                ULONG ulDummy;
    18911868                int i;
     1869                ULONG ulCurOfs;
    18921870
    18931871                paResources = (PFSYSRESOURCE)malloc(cb);
     
    19561934                    #pragma pack(1)     // V0.9.9 (2001-04-02) [umoeller]
    19571935                    struct {unsigned short type; unsigned short name;} rti;
    1958                     struct new_seg                          /* New .EXE segment table entry */
     1936                    struct new_seg                          // New .EXE segment table entry
    19591937                    {
    1960                         unsigned short      ns_sector;      /* File sector of start of segment */
    1961                         unsigned short      ns_cbseg;       /* Number of bytes in file */
    1962                         unsigned short      ns_flags;       /* Attribute flags */
    1963                         unsigned short      ns_minalloc;    /* Minimum allocation in bytes */
     1938                        unsigned short      ns_sector;      // File sector of start of segment
     1939                        unsigned short      ns_cbseg;       // Number of bytes in file
     1940                        unsigned short      ns_flags;       // Attribute flags
     1941                        unsigned short      ns_minalloc;    // Minimum allocation in bytes
    19641942                    } ns;
    19651943                    #pragma pack()
     
    21832161    free(paResources);
    21842162    return (NO_ERROR);
     2163}
     2164
     2165/*
     2166 *@@ doshLoadLXMaps:
     2167 *      loads the three main LX maps into the given
     2168 *      EXECUTABLE structure.
     2169 *
     2170 *      This loads:
     2171 *
     2172 *      1)  the LX resource table;
     2173 *
     2174 *      2)  the LX object table;
     2175 *
     2176 *      3)  the LX object _page_ table (object map).
     2177 *
     2178 *      Note that this is not automatically called
     2179 *      by doshExecOpen to save time, since the LX
     2180 *      maps are not needed for all the other exe
     2181 *      functions.
     2182 *
     2183 *      This returns:
     2184 *
     2185 *      --  NO_ERROR: all three LX maps were loaded,
     2186 *          and pExec->fLXMapsLoaded was set to TRUE.
     2187 *
     2188 *      --  ERROR_INVALID_PARAMETER
     2189 *
     2190 *      --  ERROR_INVALID_EXE_SIGNATURE: pExec does
     2191 *          not specify an LX executable.
     2192 *
     2193 *      --  ERROR_NO_DATA: at least one of the structs
     2194 *          does not exist.
     2195 *
     2196 *      --  ERROR_NOT_ENOUGH_MEMORY
     2197 *
     2198 *      plus the error codes of doshReadAt.
     2199 *
     2200 *      Call doshFreeLXMaps to clean up explicitly, but
     2201 *      that func automatically gets called by doshExecClose.
     2202 *
     2203 *@@added V0.9.16 (2001-12-08) [umoeller]
     2204 */
     2205
     2206APIRET doshLoadLXMaps(PEXECUTABLE pExec)
     2207{
     2208    APIRET arc;
     2209
     2210    if (!pExec)
     2211        arc = ERROR_INVALID_PARAMETER;
     2212    else if (pExec->ulExeFormat != EXEFORMAT_LX)
     2213        arc = ERROR_INVALID_EXE_SIGNATURE;
     2214    else if (pExec->fLXMapsLoaded)
     2215        // already loaded:
     2216        arc = NO_ERROR;
     2217    else
     2218    {
     2219        PLXHEADER pLXHeader = pExec->pLXHeader;
     2220        ULONG ulNewHeaderOfs = 0;
     2221        ULONG cb;
     2222
     2223        if (pExec->pDosExeHeader)
     2224            // executable has DOS stub: V0.9.12 (2001-05-03) [umoeller]
     2225            ulNewHeaderOfs = pExec->pDosExeHeader->ulNewHeaderOfs;
     2226
     2227        // resource table
     2228        if (    (!(arc = doshAllocArray(pLXHeader->ulResTblCnt,
     2229                                        sizeof(RESOURCETABLEENTRY),
     2230                                        (PBYTE*)&pExec->pRsTbl,
     2231                                        &cb)))
     2232             && (!(arc = doshReadAt(pExec->hfExe,
     2233                                    pLXHeader->ulResTblOfs
     2234                                      + ulNewHeaderOfs,
     2235                                    FILE_BEGIN,
     2236                                    &cb,
     2237                                    (PBYTE)pExec->pRsTbl)))
     2238            )
     2239        {
     2240            // object table
     2241            if (    (!(arc = doshAllocArray(pLXHeader->ulObjCount,
     2242                                            sizeof(OBJECTTABLEENTRY),
     2243                                            (PBYTE*)&pExec->pObjTbl,
     2244                                            &cb)))
     2245                 && (!(arc = doshReadAt(pExec->hfExe,
     2246                                        pLXHeader->ulObjTblOfs
     2247                                          + ulNewHeaderOfs,
     2248                                        FILE_BEGIN,
     2249                                        &cb,
     2250                                        (PBYTE)pExec->pObjTbl)))
     2251               )
     2252            {
     2253                // object page table
     2254                if (    (!(arc = doshAllocArray(pLXHeader->ulPageCount,
     2255                                                sizeof(OBJECTPAGETABLEENTRY),
     2256                                                (PBYTE*)&pExec->pObjPageTbl,
     2257                                                &cb)))
     2258                     && (!(arc = doshReadAt(pExec->hfExe,
     2259                                            pLXHeader->ulObjPageTblOfs
     2260                                              + ulNewHeaderOfs,
     2261                                            FILE_BEGIN,
     2262                                            &cb,
     2263                                            (PBYTE)pExec->pObjPageTbl)))
     2264                   )
     2265                  ;
     2266            }
     2267        }
     2268
     2269        if (!arc)
     2270            pExec->fLXMapsLoaded = TRUE;
     2271        else
     2272            doshFreeLXMaps(pExec);
     2273    }
     2274
     2275    return (arc);
     2276}
     2277
     2278/*
     2279 *@@ doshFreeLXMaps:
     2280 *      frees only the LX maps allocated by doshLoadLXMaps.
     2281 *      This gets called automatically by doshExecClose.
     2282 *
     2283 *@@added V0.9.16 (2001-12-08) [umoeller]
     2284 */
     2285
     2286VOID doshFreeLXMaps(PEXECUTABLE pExec)
     2287{
     2288    FREE(pExec->pRsTbl);
     2289    FREE(pExec->pObjTbl);
     2290    FREE(pExec->pObjPageTbl);
     2291    pExec->fLXMapsLoaded = FALSE;
     2292}
     2293
     2294/*
     2295 *@@ doshExecClose:
     2296 *      this closes an executable opened with doshExecOpen.
     2297 *      Always call this function if NO_ERROR was returned by
     2298 *      doshExecOpen.
     2299 *
     2300 *      This automaticall calls doshFreeLXMaps.
     2301 *
     2302 *@@added V0.9.0 [umoeller]
     2303 *@@changed V0.9.16 (2001-12-08) [umoeller]: fixed memory leaks
     2304 *@@changed V0.9.16 (2001-12-08) [umoeller]: changed prototype to null the pExec ptr
     2305 */
     2306
     2307APIRET doshExecClose(PEXECUTABLE *ppExec)
     2308{
     2309    APIRET arc = NO_ERROR;
     2310    PEXECUTABLE pExec;
     2311    if (    (ppExec)
     2312         && (pExec = *ppExec)
     2313       )
     2314    {
     2315        char **papsz[] =
     2316            {
     2317                (char**)&pExec->pDosExeHeader,
     2318                (char**)&pExec->pNEHeader,
     2319                (char**)&pExec->pLXHeader,
     2320                (char**)&pExec->pPEHeader,
     2321
     2322                &pExec->pszDescription,
     2323                &pExec->pszVendor,
     2324                &pExec->pszVersion,
     2325                &pExec->pszInfo,
     2326
     2327                &pExec->pszBuildDateTime,
     2328                &pExec->pszBuildMachine,
     2329                &pExec->pszASD,
     2330                &pExec->pszLanguage,
     2331                &pExec->pszCountry,
     2332                &pExec->pszRevision,
     2333                &pExec->pszUnknown,
     2334                &pExec->pszFixpak
     2335            };
     2336        ULONG ul;
     2337
     2338        doshFreeLXMaps(pExec);
     2339
     2340        // fixed the memory leaks with the missing fields,
     2341        // turned this into a loop
     2342        for (ul = 0;
     2343             ul < sizeof(papsz) / sizeof(papsz[0]);
     2344             ul++)
     2345        {
     2346            PSZ pThis;
     2347            if (pThis = *papsz[ul])
     2348            {
     2349                free(pThis);
     2350                pThis = NULL;
     2351            }
     2352        }
     2353
     2354        if (pExec->hfExe)
     2355            arc = DosClose(pExec->hfExe);
     2356
     2357        free(pExec);
     2358        *ppExec = NULL;
     2359    }
     2360    else
     2361        arc = ERROR_INVALID_PARAMETER;
     2362
     2363    return (arc);
    21852364}
    21862365
  • trunk/src/helpers/memdebug.c

    r93 r123  
    3232 *         is executed, the system might be in a global memory
    3333 *         lock, so DON'T display a message box while in that
    34  *         function.
     34 *         function, and DO NOT call malloc() or other memory
     35 *         functions in there.
    3536 *
    3637 *         These debug functions have been added with V0.9.3
     
    3839 *
    3940 *         V0.9.6 added realloc() support and fixed a few bugs.
     41 *
     42 *         With V0.9.16, most of this was rewritten to be much
     43 *         faster. This no longer slows down the system enormously.
    4044 *
    4145 *      -- A PM heap debugging window which shows the status
     
    4953 *
    5054 *      2) Include memdebug.h AFTER those two. This will remap
    51  *         the malloc() etc. calls.
     55 *         the malloc() etc. calls to the debug functions in
     56 *         this file by defining macros for them.
    5257 *
    5358 *         If you don't want those replaced, add
     
    5560 *         before including memdebug.h.
    5661 *
     62 *         To avoid calling a debug function for a single call,
     63 *         place the malloc call (or whatever) in brackets.
     64 *
    5765 *      That's all. XWorkplace's setup.h does this automatically
    5866 *      if XWorkplace is compiled with debug code.
     
    6068 *      A couple of WARNINGS:
    6169 *
    62  *      1)  Memory debugging can greatly slow down the system
    63  *          after a while. When free() is invoked, the memory
    64  *          that was allocated is freed, but not the memory
    65  *          log entry (the HEAPITEM) to allow tracing what was
    66  *          freed. As a result, the linked list of memory items
    67  *          keeps growing longer, and free() becomes terribly
    68  *          slow after a while because it must traverse the
    69  *          entire list for each free() call. Use memdReleaseFreed
    70  *          from time to time.
     70 *      1)  When free() is invoked, the memory that was allocated
     71 *          is freed, but not the memory log entry (the HEAPITEM)
     72 *          to allow tracing what was freed. As a result, the tree
     73 *          of memory items keeps growing longer. Do not expect
     74 *          this to work forever, even though things have greatly
     75 *          improved with V0.9.16.
    7176 *
    7277 *      2)  The replacement functions in this file allocate
     
    7681 *          memory overwrites. Two magic strings are allocated,
    7782 *          one before the actual buffer, and one behind it.
     83 *          The pointer returned is _not_ identical to the one
     84 *          that was internally allocated.
    7885 *
    7986 *          As a result, YOU MUST NOT confuse the replacement
     
    119126#include <setjmp.h>
    120127
     128#include "helpers\tree.h"
     129
    121130#define DONT_REPLACE_MALLOC             // never do debug memory for this
    122131#define MEMDEBUG_PRIVATE
     
    125134#ifdef __XWPMEMDEBUG__
    126135
     136#include "helpers\dosh.h"
    127137#include "helpers\except.h"
     138
    128139#include "helpers\memdebug.h"        // included by setup.h already
    129140#include "helpers\stringh.h"
     
    146157#define MEMBLOCKMAGIC_TAIL     "\250\210&%/dfjsk%#,dlhf\223"
    147158
    148 HMTX            G_hmtxMallocList = NULLHANDLE;
    149 
    150 extern PHEAPITEM G_pHeapItemsRoot = NULL;
    151 PHEAPITEM       G_pHeapItemsLast = NULL;
    152 
    153 PFNCBMEMDLOG    G_pMemdLogFunc = NULL;
    154 
    155 extern ULONG    G_ulItemsReleased = 0;
    156 extern ULONG    G_ulBytesReleased = 0;
     159HMTX                G_hmtxMallocList = NULLHANDLE;
     160
     161extern TREE         *G_pHeapItemsRoot = NULL;
     162extern LONG         G_cHeapItems = 0;
     163
     164PFNCBMEMDLOG        G_pMemdLogFunc = NULL;
     165
     166extern ULONG        G_ulItemsReleased = 0;
     167extern ULONG        G_ulBytesReleased = 0;
    157168
    158169/* ******************************************************************
     
    175186BOOL memdLock(VOID)
    176187{
    177     APIRET arc = NO_ERROR;
    178     if (G_hmtxMallocList == NULLHANDLE)
     188    if (!G_hmtxMallocList)
     189    {
    179190        // first call:
    180         arc = DosCreateMutexSem(NULL,
    181                                 &G_hmtxMallocList,
    182                                 0,          // unshared
    183                                 TRUE);      // request now!
     191        if (!DosCreateMutexSem(NULL,
     192                               &G_hmtxMallocList,
     193                               0,          // unshared
     194                               TRUE))      // request now!
     195        {
     196            treeInit(&G_pHeapItemsRoot, &G_cHeapItems);
     197            return TRUE;
     198        }
     199    }
    184200    else
    185         arc = DosRequestMutexSem(G_hmtxMallocList,
    186                                  SEM_INDEFINITE_WAIT);
    187 
    188     return (arc == NO_ERROR);
     201        return (!DosRequestMutexSem(G_hmtxMallocList,
     202                                    SEM_INDEFINITE_WAIT));
     203
     204    return (FALSE);
    189205}
    190206
     
    199215{
    200216    DosReleaseMutexSem(G_hmtxMallocList);
     217}
     218
     219/*
     220 *@@ LogError:
     221 *
     222 *@@added V0.9.16 (2001-12-08) [umoeller]
     223 */
     224
     225VOID LogError(const char *pcszFormat,     // in: format string (like with printf)
     226              ...)                        // in: additional stuff (like with printf)
     227{
     228    if (G_pMemdLogFunc)
     229    {
     230        CHAR        szMsg[1000];
     231        va_list     args;
     232
     233        va_start(args, pcszFormat);
     234        vsprintf(szMsg, pcszFormat, args);
     235        va_end(args);
     236        G_pMemdLogFunc(szMsg);
     237    }
     238}
     239
     240/*
     241 *@@ FindHeapItem:
     242 *
     243 *@@added V0.9.16 (2001-12-08) [umoeller]
     244 */
     245
     246PHEAPITEM FindHeapItem(void *p)
     247{
     248    return ((PHEAPITEM)treeFind(G_pHeapItemsRoot,
     249                                (ULONG)p,
     250                                treeCompareKeys));
     251}
     252
     253/*
     254 *@@ FillHeapItem:
     255 *
     256 *@@added V0.9.16 (2001-12-08) [umoeller]
     257 */
     258
     259VOID FillHeapItem(PHEAPITEM pHeapItem,
     260                  void *prc,
     261                  size_t stSize,
     262                  const char *pcszSourceFile, // in: source file name
     263                  unsigned long ulLine,       // in: source line
     264                  const char *pcszFunction)   // in: function name
     265{
     266    pHeapItem->ulSize = stSize;
     267
     268    pHeapItem->pcszSourceFile = pcszSourceFile;
     269    pHeapItem->ulLine = ulLine;
     270    pHeapItem->pcszFunction = pcszFunction;
     271
     272    DosGetDateTime(&pHeapItem->dtAllocated);
     273
     274    pHeapItem->ulTID = doshMyTID();
     275
     276    pHeapItem->fFreed = FALSE;
     277
     278    // use the return pointer as the tree sort key
     279    // V0.9.16 (2001-12-08) [umoeller]
     280    pHeapItem->Tree.ulKey = (ULONG)prc;
     281}
     282
     283/*
     284 *@@ CheckMagics:
     285 *
     286 *@@added V0.9.16 (2001-12-08) [umoeller]
     287 */
     288
     289VOID CheckMagics(const char *pcszParentFunc,
     290                 PHEAPITEM pHeapItem,
     291                 PBYTE p,
     292                 const char *pcszSourceFile, // in: source file name
     293                 unsigned long ulLine,       // in: source line
     294                 const char *pcszFunction)   // in: function name
     295{
     296    void    *pBeforeMagic = ((PBYTE)p) - sizeof(MEMBLOCKMAGIC_HEAD);
     297    ULONG   ulError = 0;
     298
     299    // check magic string
     300    if (memcmp(pBeforeMagic,
     301               MEMBLOCKMAGIC_HEAD,
     302               sizeof(MEMBLOCKMAGIC_HEAD)))
     303        ulError = 1;
     304    else if (memcmp(((PBYTE)p) + pHeapItem->ulSize,
     305                    MEMBLOCKMAGIC_TAIL,
     306                    sizeof(MEMBLOCKMAGIC_TAIL)))
     307        ulError = 2;
     308
     309    if (ulError)
     310    {
     311        LogError("%s: Magic string %s memory block at 0x%lX has been overwritten.\n"
     312                 "This was detected by the free() call at %s (%s, line %d).\n"
     313                 "The block was allocated by %s (%s, line %d).",
     314                 pcszParentFunc,
     315                 (ulError == 1) ? "before" : "after",
     316                 p,
     317                 pcszFunction,
     318                     pcszSourceFile,
     319                     ulLine, // free
     320                 pHeapItem->pcszFunction,
     321                     pHeapItem->pcszSourceFile,
     322                     pHeapItem->ulLine);
     323    }
    201324}
    202325
     
    217340 *
    218341 *@@added V0.9.3 (2000-04-11) [umoeller]
     342 *@@changed V0.9.16 (2001-12-08) [umoeller]: reworked to use trees now, much faster
    219343 */
    220344
     
    228352    if (stSize == 0)
    229353        // malloc(0) called: report error
    230         if (G_pMemdLogFunc)
     354        LogError(__FUNCTION__ ": Function %s (%s, line %d) called malloc(0).",
     355                 pcszFunction,
     356                     pcszSourceFile,
     357                     ulLine);
     358    else
     359        if (memdLock())
    231360        {
    232             CHAR szMsg[1000];
    233             sprintf(szMsg,
    234                     "Function %s (%s, line %d) called malloc(0).",
    235                     pcszFunction,
    236                         pcszSourceFile,
    237                         ulLine);
    238             G_pMemdLogFunc(szMsg);
    239         }
    240 
    241     if (memdLock())
    242     {
    243         // call default malloc(), but with the additional
    244         // size of our MEMBLOCKMAGIC strings; we'll return
    245         // the first byte after the "front" string so we can
    246         // check for string overwrites
    247         void *pObj = malloc(stSize
    248                             + sizeof(MEMBLOCKMAGIC_HEAD)
    249                             + sizeof(MEMBLOCKMAGIC_TAIL));
    250         if (pObj)
    251         {
    252             PHEAPITEM   pHeapItem = (PHEAPITEM)malloc(sizeof(HEAPITEM));
    253 
    254             // store "front" magic string
    255             memcpy(pObj,
    256                    MEMBLOCKMAGIC_HEAD,
    257                    sizeof(MEMBLOCKMAGIC_HEAD));
    258             // return address: first byte after "front" magic string
    259             prc = ((PBYTE)pObj) + sizeof(MEMBLOCKMAGIC_HEAD);
    260             // store "tail" magic string to block which
    261             // will be returned plus the size which was requested
    262             memcpy(((PBYTE)prc) + stSize,
    263                    MEMBLOCKMAGIC_TAIL,
    264                    sizeof(MEMBLOCKMAGIC_TAIL));
    265 
    266             if (pHeapItem)
     361            // call default malloc(), but with the additional
     362            // size of our MEMBLOCKMAGIC strings; we'll return
     363            // the first byte after the "front" string so we can
     364            // check for string overwrites
     365            void *pObj;
     366
     367            if (pObj = malloc(   sizeof(MEMBLOCKMAGIC_HEAD)
     368                               + stSize
     369                               + sizeof(MEMBLOCKMAGIC_TAIL)))
    267370            {
    268                 PTIB        ptib;
    269                 PPIB        ppib;
    270 
    271                 pHeapItem->pNext = 0;
    272 
    273                 pHeapItem->pAfterMagic = prc;
    274                 pHeapItem->ulSize = stSize;
    275                 pHeapItem->pcszSourceFile = pcszSourceFile;
    276                 pHeapItem->ulLine = ulLine;
    277                 pHeapItem->pcszFunction = pcszFunction;
    278 
    279                 DosGetDateTime(&pHeapItem->dtAllocated);
    280 
    281                 pHeapItem->ulTID = 0;
    282 
    283                 if (DosGetInfoBlocks(&ptib, &ppib) == NO_ERROR)
    284                     if (ptib)
    285                         if (ptib->tib_ptib2)
    286                             pHeapItem->ulTID = ptib->tib_ptib2->tib2_ultid;
    287 
    288                 pHeapItem->fFreed = FALSE;
    289 
    290                 // append heap item to linked list
    291                 if (G_pHeapItemsRoot == NULL)
    292                     // first item:
    293                     G_pHeapItemsRoot = pHeapItem;
     371                PHEAPITEM pHeapItem;
     372                BOOL fInsert = TRUE;
     373
     374                // store "front" magic string
     375                memcpy(pObj,
     376                       MEMBLOCKMAGIC_HEAD,
     377                       sizeof(MEMBLOCKMAGIC_HEAD));
     378                // return address: first byte after "front" magic string
     379                prc = ((PBYTE)pObj) + sizeof(MEMBLOCKMAGIC_HEAD);
     380                // store "tail" magic string to block which
     381                // will be returned plus the size which was requested
     382                memcpy(((PBYTE)prc) + stSize,
     383                       MEMBLOCKMAGIC_TAIL,
     384                       sizeof(MEMBLOCKMAGIC_TAIL));
     385
     386                if (!(pHeapItem = FindHeapItem(prc)))
     387                    // not re-using old address:
     388                    // create a new heap item
     389                    pHeapItem = (PHEAPITEM)malloc(sizeof(HEAPITEM));
    294390                else
    295                     // we have items already:
    296                     if (G_pHeapItemsLast)
     391                    fInsert = FALSE;
     392
     393                FillHeapItem(pHeapItem,
     394                             prc,
     395                             stSize,
     396                             pcszSourceFile,
     397                             ulLine,
     398                             pcszFunction);
     399
     400                if (fInsert)
     401                    // append heap item to linked list
     402                    if (treeInsert(&G_pHeapItemsRoot,
     403                                   &G_cHeapItems,
     404                                   (TREE*)pHeapItem,
     405                                   treeCompareKeys))
    297406                    {
    298                         // last item cached:
    299                         G_pHeapItemsLast->pNext = pHeapItem;
    300                         G_pHeapItemsLast = pHeapItem;
    301                     }
    302                     else
    303                     {
    304                         // not cached: find end of list
    305                         PHEAPITEM phi = G_pHeapItemsRoot;
    306                         while (phi->pNext)
    307                             phi = phi->pNext;
    308 
    309                         phi->pNext = pHeapItem;
    310                         G_pHeapItemsLast = pHeapItem;
     407                        LogError(__FUNCTION__ ": treeInsert failed for memory block at 0x%lX.\n"
     408                                 "The block was allocated by %s (%s, line %d).",
     409                                 prc,
     410                                 pcszFunction,
     411                                     pcszSourceFile,
     412                                     ulLine);
    311413                    }
    312414            }
     415
     416            memdUnlock();
    313417        }
    314 
    315         memdUnlock();
    316     }
    317418
    318419    return (prc);
     
    361462 *
    362463 *@@added V0.9.3 (2000-04-10) [umoeller]
     464 *@@changed V0.9.16 (2001-12-08) [umoeller]: reworked to use trees now, much faster
    363465 */
    364466
     
    368470              const char *pcszFunction)
    369471{
    370     BOOL fFound = FALSE;
    371472    if (memdLock())
    372473    {
    373         // PLISTNODE   pNode = lstQueryFirstNode(&G_llHeapItems);
    374         PHEAPITEM pHeapItem = G_pHeapItemsRoot;
     474        PHEAPITEM pHeapItem;
    375475
    376476        // search the list with the pointer which was
    377477        // really returned by the original malloc(),
    378         // that is, the byte before the magic string
    379         void *pBeforeMagic = ((PBYTE)p) - sizeof(MEMBLOCKMAGIC_HEAD);
    380 
    381         while (pHeapItem)
     478        // that is, the byte after the magic string
     479        if (pHeapItem = FindHeapItem(p))
    382480        {
    383             if (pHeapItem->pAfterMagic == p)
     481            // the same address may be allocated and freed
     482            // several times, so check
     483            if (!pHeapItem->fFreed)
    384484            {
    385                 // the same address may be allocated and freed
    386                 // several times, so if this address has been
    387                 // freed, search on
    388                 if (!pHeapItem->fFreed)
    389                 {
    390                     // found:
    391                     ULONG   ulError = 0;
    392                     // check magic string
    393                     if (memcmp(pBeforeMagic,
    394                                MEMBLOCKMAGIC_HEAD,
    395                                sizeof(MEMBLOCKMAGIC_HEAD))
    396                             != 0)
    397                         ulError = 1;
    398                     else if (memcmp(((PBYTE)pHeapItem->pAfterMagic) + pHeapItem->ulSize,
    399                                     MEMBLOCKMAGIC_TAIL,
    400                                     sizeof(MEMBLOCKMAGIC_TAIL))
    401                             != 0)
    402                         ulError = 2;
    403 
    404                     if (ulError)
    405                     {
    406                         // magic block has been overwritten:
    407                         if (G_pMemdLogFunc)
    408                         {
    409                             CHAR szMsg[1000];
    410                             sprintf(szMsg,
    411                                     "Magic string %s memory block at 0x%lX has been overwritten.\n"
    412                                     "This was detected by the free() call at %s (%s, line %d).\n"
    413                                     "The block was allocated by %s (%s, line %d).",
    414                                     (ulError == 1) ? "before" : "after",
    415                                     p,
    416                                     pcszFunction,
    417                                         pcszSourceFile,
    418                                         ulLine, // free
    419                                     pHeapItem->pcszFunction,
    420                                         pHeapItem->pcszSourceFile,
    421                                         pHeapItem->ulLine);
    422                             G_pMemdLogFunc(szMsg);
    423                         }
    424                     }
    425 
    426                     free(pBeforeMagic);
    427                     pHeapItem->fFreed = TRUE;
    428 
    429                     fFound = TRUE;
    430                     break;
    431                 } // if (!pHeapItem->fFreed)
    432             }
    433 
    434             pHeapItem = pHeapItem->pNext;
     485                // found:
     486                void    *pBeforeMagic = ((PBYTE)p) - sizeof(MEMBLOCKMAGIC_HEAD);
     487
     488                CheckMagics(__FUNCTION__,
     489                            pHeapItem,
     490                            p,
     491                            pcszSourceFile,
     492                            ulLine,
     493                            pcszFunction);
     494
     495                // free the real memory item
     496                free(pBeforeMagic);
     497
     498                // mark the heap item as freed, but
     499                // keep it in the list
     500                pHeapItem->fFreed = TRUE;
     501
     502            } // if (!pHeapItem->fFreed)
     503            else
     504                // memory block has been freed twice:
     505                LogError(__FUNCTION__ ": Memory block at 0x%lX has been freed twice.\n"
     506                         "This was detected by the free() call at %s (%s, line %d).\n"
     507                         "The block was originally allocated by %s (%s, line %d).",
     508                         p,
     509                         pcszFunction,
     510                             pcszSourceFile,
     511                             ulLine, // free
     512                         pHeapItem->pcszFunction,
     513                             pHeapItem->pcszSourceFile,
     514                             pHeapItem->ulLine);
    435515        }
     516        else
     517            // not found:
     518            LogError(__FUNCTION__ ": free() called with invalid object 0x%lX from %s (%s, line %d).",
     519                     p,
     520                     pcszFunction,
     521                         pcszSourceFile,
     522                         ulLine);
    436523
    437524        memdUnlock();
    438525    }
    439 
    440     if (!fFound)
    441         if (G_pMemdLogFunc)
    442         {
    443             CHAR szMsg[1000];
    444             sprintf(szMsg,
    445                     "free() called with invalid object from %s (%s, line %d) for object 0x%lX.",
    446                     pcszFunction,
    447                         pcszSourceFile,
    448                         ulLine,
    449                     p);
    450             G_pMemdLogFunc(szMsg);
    451         }
    452526}
    453527
     
    459533 *@@added V0.9.6 (2000-11-12) [umoeller]
    460534 *@@changed V0.9.12 (2001-05-21) [umoeller]: this reported errors on realloc(0), which is a valid call, fixed
     535 *@@changed V0.9.16 (2001-12-08) [umoeller]: reworked to use trees now, much faster
    461536 */
    462537
     
    468543{
    469544    void *prc = NULL;
    470     BOOL fFound = FALSE;
    471545
    472546    if (!p)
     
    477551    if (memdLock())
    478552    {
    479         PHEAPITEM pHeapItem = G_pHeapItemsRoot;
    480 
    481553        // search the list with the pointer which was
    482554        // really returned by the original malloc(),
    483         // that is, the byte before the magic string
    484         void *pBeforeMagic = ((PBYTE)p) - sizeof(MEMBLOCKMAGIC_HEAD);
    485 
    486         while (pHeapItem)
     555        // that is, the byte after the magic string
     556        PHEAPITEM pHeapItem, pExisting;
     557        if (pHeapItem = FindHeapItem(p))
    487558        {
    488             if (pHeapItem->pAfterMagic == p)
    489                 // the same address may be allocated and freed
    490                 // several times, so if this address has been
    491                 // freed, search on
    492                 if (!pHeapItem->fFreed)
     559            // found:
     560            if (pHeapItem->fFreed)
     561            {
     562                LogError(__FUNCTION__ ": realloc() called with memory block at 0x%lX that was already freed.\n"
     563                         "This was detected by the realloc() call at %s (%s, line %d).\n"
     564                         "The block was originally allocated by %s (%s, line %d).",
     565                         p,
     566                         pcszFunction,
     567                             pcszSourceFile,
     568                             ulLine, // free
     569                         pHeapItem->pcszFunction,
     570                             pHeapItem->pcszSourceFile,
     571                             pHeapItem->ulLine);
     572            }
     573            else
     574            {
     575                // block is valid:
     576                void    *pBeforeMagic = ((PBYTE)p) - sizeof(MEMBLOCKMAGIC_HEAD);
     577                PVOID   pObjNew = 0;
     578                ULONG   ulError = 0;
     579                ULONG   cbCopy = 0;
     580
     581                CheckMagics(__FUNCTION__,
     582                            pHeapItem,
     583                            p,
     584                            pcszSourceFile,
     585                            ulLine,
     586                            pcszFunction);
     587
     588                // now reallocate!
     589                pObjNew = malloc(   sizeof(MEMBLOCKMAGIC_HEAD)
     590                                  + stSize   // new size
     591                                  + sizeof(MEMBLOCKMAGIC_TAIL));
     592
     593                // store "front" magic string
     594                memcpy(pObjNew,
     595                       MEMBLOCKMAGIC_HEAD,
     596                       sizeof(MEMBLOCKMAGIC_HEAD));
     597                // return address: first byte after "front" magic string
     598                prc = ((PBYTE)pObjNew) + sizeof(MEMBLOCKMAGIC_HEAD);
     599
     600                // bytes to copy: the smaller of the old and the new size
     601                cbCopy = pHeapItem->ulSize;
     602                if (stSize < pHeapItem->ulSize)
     603                    cbCopy = stSize;
     604
     605                // copy buffer from old memory object
     606                memcpy(prc,         // after "front" magic
     607                       p,
     608                       cbCopy);
     609
     610                // store "tail" magic string to block which
     611                // will be returned plus the size which was requested
     612                memcpy(((PBYTE)prc) + stSize,
     613                       MEMBLOCKMAGIC_TAIL,
     614                       sizeof(MEMBLOCKMAGIC_TAIL));
     615
     616                // free the old buffer
     617                free(pBeforeMagic);
     618
     619                // update the tree, since prc has changed
     620                treeDelete(&G_pHeapItemsRoot,
     621                           &G_cHeapItems,
     622                           (TREE*)pHeapItem);
     623                // append heap item to linked list
     624                if (pExisting = FindHeapItem(prc))
    493625                {
    494                     // found:
    495                     PVOID   pObjNew = 0;
    496                     ULONG   ulError = 0;
    497                     ULONG   cbCopy = 0;
    498                     PTIB    ptib;
    499                     PPIB    ppib;
    500 
    501                     // check magic string
    502                     if (memcmp(pBeforeMagic,
    503                                MEMBLOCKMAGIC_HEAD,
    504                                sizeof(MEMBLOCKMAGIC_HEAD))
    505                             != 0)
    506                         ulError = 1;
    507                     else if (memcmp(((PBYTE)pHeapItem->pAfterMagic) + pHeapItem->ulSize,
    508                                     MEMBLOCKMAGIC_TAIL,
    509                                     sizeof(MEMBLOCKMAGIC_TAIL))
    510                             != 0)
    511                         ulError = 2;
    512 
    513                     if (ulError)
     626                    // a different heap item exists for this address:
     627                    // delete this one and use that instead; there's
     628                    // no need to re-insert either
     629                    free(pHeapItem);
     630                    pHeapItem = pExisting;
     631                }
     632
     633                FillHeapItem(pHeapItem,
     634                             prc,
     635                             stSize,
     636                             pcszSourceFile,
     637                             ulLine,
     638                             pcszFunction);
     639
     640                // insert only if we didn't use an existing item
     641                if (!pExisting)
     642                    if (treeInsert(&G_pHeapItemsRoot,
     643                                   &G_cHeapItems,
     644                                   (TREE*)pHeapItem,
     645                                   treeCompareKeys))
    514646                    {
    515                         // magic block has been overwritten:
    516                         if (G_pMemdLogFunc)
    517                         {
    518                             CHAR szMsg[1000];
    519                             sprintf(szMsg,
    520                                     "Magic string %s memory block at 0x%lX has been overwritten.\n"
    521                                     "This was detected by the realloc() call at %s (%s, line %d).\n"
    522                                     "The block was allocated by %s (%s, line %d).",
    523                                     (ulError == 1) ? "before" : "after",
    524                                     p,
    525                                     pcszFunction,
    526                                         pcszSourceFile,
    527                                         ulLine, // free
    528                                     pHeapItem->pcszFunction,
    529                                         pHeapItem->pcszSourceFile,
    530                                         pHeapItem->ulLine);
    531                             G_pMemdLogFunc(szMsg);
    532                         }
     647                        LogError(__FUNCTION__ ": treeInsert failed for memory block at 0x%lX.\n"
     648                                 "The block was allocated by %s (%s, line %d).",
     649                                 prc,
     650                                 pcszFunction,
     651                                     pcszSourceFile,
     652                                     ulLine);
    533653                    }
    534654
    535                     // now reallocate!
    536                     pObjNew = malloc(stSize   // new size
    537                                      + sizeof(MEMBLOCKMAGIC_HEAD)
    538                                      + sizeof(MEMBLOCKMAGIC_TAIL));
    539 
    540                     // store "front" magic string
    541                     memcpy(pObjNew,
    542                            MEMBLOCKMAGIC_HEAD,
    543                            sizeof(MEMBLOCKMAGIC_HEAD));
    544                     // return address: first byte after "front" magic string
    545                     prc = ((PBYTE)pObjNew) + sizeof(MEMBLOCKMAGIC_HEAD);
    546 
    547                     // bytes to copy: the smaller of the old and the new size
    548                     cbCopy = pHeapItem->ulSize;
    549                     if (stSize < pHeapItem->ulSize)
    550                         cbCopy = stSize;
    551 
    552                     // copy buffer from old memory object
    553                     memcpy(prc,         // after "front" magic
    554                            pHeapItem->pAfterMagic,
    555                            cbCopy);
    556 
    557                     // store "tail" magic string to block which
    558                     // will be returned plus the size which was requested
    559                     memcpy(((PBYTE)prc) + stSize,
    560                            MEMBLOCKMAGIC_TAIL,
    561                            sizeof(MEMBLOCKMAGIC_TAIL));
    562 
    563                     // free the old buffer
    564                     free(pBeforeMagic);
    565 
    566                     // update the HEAPITEM
    567                     pHeapItem->pAfterMagic = prc;       // new pointer!
    568                     pHeapItem->ulSize = stSize;         // new size!
    569                     pHeapItem->pcszSourceFile = pcszSourceFile;
    570                     pHeapItem->ulLine = ulLine;
    571                     pHeapItem->pcszFunction = pcszFunction;
    572 
    573                     // update date, time, TID
    574                     DosGetDateTime(&pHeapItem->dtAllocated);
    575                     pHeapItem->ulTID = 0;
    576                     if (DosGetInfoBlocks(&ptib, &ppib) == NO_ERROR)
    577                         if (ptib)
    578                             if (ptib->tib_ptib2)
    579                                 pHeapItem->ulTID = ptib->tib_ptib2->tib2_ultid;
    580 
    581                     fFound = TRUE;
    582                     break;
    583                 } // if (!pHeapItem->fFreed)
    584 
    585             pHeapItem = pHeapItem->pNext;
     655            } // if (!pHeapItem->fFreed)
    586656        }
     657        else
     658            LogError(__FUNCTION__ ": realloc() called with invalid object from %s (%s, line %d) for object 0x%lX.",
     659                     pcszFunction,
     660                         pcszSourceFile,
     661                         ulLine,
     662                     p);
    587663
    588664        memdUnlock();
    589665    }
    590 
    591     if (!fFound)
    592         if (G_pMemdLogFunc)
    593         {
    594             CHAR szMsg[1000];
    595             sprintf(szMsg,
    596                     "realloc() called with invalid object from %s (%s, line %d) for object 0x%lX.",
    597                     pcszFunction,
    598                         pcszSourceFile,
    599                         ulLine,
    600                     p);
    601             G_pMemdLogFunc(szMsg);
    602         }
    603666
    604667    return (prc);
     
    624687    if (memdLock())
    625688    {
    626         PHEAPITEM pHeapItem = G_pHeapItemsRoot,
    627                   pPrevious = NULL;
     689        /* PHEAPITEM pHeapItem = treeFirst(G_pHeapItemsRoot);
    628690
    629691        while (pHeapItem)
    630692        {
    631693            // store next first, because we can change the "next" pointer
    632             PHEAPITEM   pNext = pHeapItem->pNext;       // can be NULL
     694            PHEAPITEM   pNext = treeNext(pHeapItem);
    633695
    634696            if (pHeapItem->fFreed)
     
    658720            pHeapItem = pNext;
    659721        }
    660 
     722        */
    661723        G_ulItemsReleased += ulItemsReleased;
    662724        G_ulBytesReleased += ulBytesReleased;
  • trunk/src/helpers/memdebug_win.c

    r91 r123  
    4747#include <setjmp.h>
    4848
     49#include "helpers\tree.h"
     50
    4951#define DONT_REPLACE_MALLOC             // never do debug memory for this
    5052#define MEMDEBUG_PRIVATE
     
    5658#include "helpers\except.h"
    5759// #include "helpers\memdebug.h"        // included by setup.h already
     60#include "helpers\nls.h"
    5861#include "helpers\stringh.h"
    5962#include "helpers\winh.h"
     
    278281{
    279282    // count heap items
    280     ULONG       ulHeapItemsCount1 = 0;
     283    // ULONG       ulHeapItemsCount1 = 0;
    281284    PMEMRECORD  pMemRecordFirst;
    282285
    283     if (memdLock())
     286    ULONG       cHeapItems = 0;
     287    BOOL        fLocked = FALSE;
     288
     289    TRY_LOUD(excpt1)
    284290    {
    285         PHEAPITEM pHeapItem = G_pHeapItemsRoot;
    286 
    287         *pulTotalItems = 0;
    288         *pulAllocatedItems = 0;
    289         *pulFreedItems = 0;
    290 
    291         *pulTotalBytes = 0;
    292         *pulAllocatedBytes = 0;
    293         *pulFreedBytes = 0;
    294 
    295         while (pHeapItem)
     291        if (fLocked = memdLock())
    296292        {
    297             ulHeapItemsCount1++;
    298             if (pHeapItem->fFreed)
     293            PHEAPITEM pHeapItem = (PHEAPITEM)treeFirst(G_pHeapItemsRoot);
     294
     295            *pulTotalItems = 0;
     296            *pulAllocatedItems = 0;
     297            *pulFreedItems = 0;
     298
     299            *pulTotalBytes = 0;
     300            *pulAllocatedBytes = 0;
     301            *pulFreedBytes = 0;
     302
     303            *pulTotalItems = G_cHeapItems;
     304
     305            if (pMemRecordFirst = (PMEMRECORD)cnrhAllocRecords(hwndCnr,
     306                                                               sizeof(MEMRECORD),
     307                                                               G_cHeapItems))
    299308            {
    300                 (*pulFreedItems)++;
    301                 (*pulFreedBytes) += pHeapItem->ulSize;
     309                PMEMRECORD  pMemRecordThis = pMemRecordFirst;
     310                pHeapItem = (PHEAPITEM)treeFirst(G_pHeapItemsRoot);
     311
     312                while ((pMemRecordThis) && (pHeapItem))
     313                {
     314                    if (pHeapItem->fFreed)
     315                    {
     316                        (*pulFreedItems)++;
     317                        (*pulFreedBytes) += pHeapItem->ulSize;
     318                    }
     319                    else
     320                    {
     321                        (*pulAllocatedItems)++;
     322                        (*pulAllocatedBytes) += pHeapItem->ulSize;
     323                    }
     324
     325                    (*pulTotalBytes) += pHeapItem->ulSize;
     326
     327                    pMemRecordThis->ulIndex = cHeapItems++;
     328
     329                    cnrhDateTimeDos2Win(&pHeapItem->dtAllocated,
     330                                        &pMemRecordThis->cdateAllocated,
     331                                        &pMemRecordThis->ctimeAllocated);
     332
     333                    if (pHeapItem->fFreed)
     334                        pMemRecordThis->pszFreed = "yes";
     335
     336                    pMemRecordThis->ulTID = pHeapItem->ulTID;
     337
     338                    strhcpy(pMemRecordThis->szSource, pHeapItem->pcszSourceFile);
     339                    pMemRecordThis->pszSource = pMemRecordThis->szSource;
     340
     341                    pMemRecordThis->ulLine = pHeapItem->ulLine;
     342
     343                    strhcpy(pMemRecordThis->szFunction, pHeapItem->pcszFunction);
     344                    pMemRecordThis->pszFunction = pMemRecordThis->szFunction;
     345
     346                    pMemRecordThis->ulAddress = pHeapItem->Tree.ulKey;
     347
     348                    sprintf(pMemRecordThis->szAddress,
     349                            "0x%lX",
     350                            pHeapItem->Tree.ulKey);
     351                    pMemRecordThis->pszAddress = pMemRecordThis->szAddress;
     352
     353                    pMemRecordThis->ulSize = pHeapItem->ulSize;
     354
     355
     356                    /* switch (pMemRecordThis->useflag)
     357                    {
     358                        case _USEDENTRY: pMemRecordThis->pszUseFlag = "Used"; break;
     359                        case _FREEENTRY: pMemRecordThis->pszUseFlag = "Freed"; break;
     360                    }
     361
     362                    switch (pMemRecordThis->status)
     363                    {
     364                        case _HEAPBADBEGIN: pMemRecordThis->pszStatus = "heap bad begin"; break;
     365                        case _HEAPBADNODE: pMemRecordThis->pszStatus = "heap bad node"; break;
     366                        case _HEAPEMPTY: pMemRecordThis->pszStatus = "heap empty"; break;
     367                        case _HEAPOK: pMemRecordThis->pszStatus = "OK"; break;
     368                    }
     369
     370                    sprintf(pMemRecordThis->szAddress, "0x%lX", pMemRecordThis->pObject);
     371                    strhcpy(pMemRecordThis->szSource,
     372                            (pMemRecordThis->filename)
     373                                ? pMemRecordThis->filename
     374                                : "?"); */
     375
     376                    pMemRecordThis = (PMEMRECORD)pMemRecordThis->recc.preccNextRecord;
     377                    pHeapItem = (PHEAPITEM)treeNext((TREE*)pHeapItem);
     378                }
     379
     380                cnrhInsertRecords(hwndCnr,
     381                                  NULL,         // parent
     382                                  (PRECORDCORE)pMemRecordFirst,
     383                                  TRUE,
     384                                  NULL,
     385                                  CRA_RECORDREADONLY,
     386                                  cHeapItems);
    302387            }
    303             else
    304             {
    305                 (*pulAllocatedItems)++;
    306                 (*pulAllocatedBytes) += pHeapItem->ulSize;
    307             }
    308 
    309             (*pulTotalBytes) += pHeapItem->ulSize;
    310 
    311             pHeapItem = pHeapItem->pNext;
    312388        }
    313 
    314         *pulTotalItems = ulHeapItemsCount1;
    315 
    316         pMemRecordFirst = (PMEMRECORD)cnrhAllocRecords(hwndCnr,
    317                                                        sizeof(MEMRECORD),
    318                                                        ulHeapItemsCount1);
    319         if (pMemRecordFirst)
     389    }
     390    CATCH(excpt1)
     391    {
     392        if (G_pMemdLogFunc)
    320393        {
    321             ULONG       ulHeapItemsCount2 = 0;
    322             PMEMRECORD  pMemRecordThis = pMemRecordFirst;
    323             pHeapItem = G_pHeapItemsRoot;
    324             // PLISTNODE   pMemNode = lstQueryFirstNode(&G_llHeapItems);
    325 
    326             while ((pMemRecordThis) && (pHeapItem))
    327             {
    328                 // PHEAPITEM pHeapItem = (PHEAPITEM)pMemNode->pItemData;
    329 
    330                 pMemRecordThis->ulIndex = ulHeapItemsCount2++;
    331 
    332                 cnrhDateTimeDos2Win(&pHeapItem->dtAllocated,
    333                                     &pMemRecordThis->cdateAllocated,
    334                                     &pMemRecordThis->ctimeAllocated);
    335 
    336                 if (pHeapItem->fFreed)
    337                     pMemRecordThis->pszFreed = "yes";
    338 
    339                 pMemRecordThis->ulTID = pHeapItem->ulTID;
    340 
    341                 strhcpy(pMemRecordThis->szSource, pHeapItem->pcszSourceFile);
    342                 pMemRecordThis->pszSource = pMemRecordThis->szSource;
    343 
    344                 pMemRecordThis->ulLine = pHeapItem->ulLine;
    345 
    346                 strhcpy(pMemRecordThis->szFunction, pHeapItem->pcszFunction);
    347                 pMemRecordThis->pszFunction = pMemRecordThis->szFunction;
    348 
    349                 pMemRecordThis->ulAddress = (ULONG)pHeapItem->pAfterMagic;
    350 
    351                 sprintf(pMemRecordThis->szAddress,
    352                         "0x%lX",
    353                         pHeapItem->pAfterMagic);
    354                 pMemRecordThis->pszAddress = pMemRecordThis->szAddress;
    355 
    356                 pMemRecordThis->ulSize = pHeapItem->ulSize;
    357 
    358 
    359                 /* switch (pMemRecordThis->useflag)
    360                 {
    361                     case _USEDENTRY: pMemRecordThis->pszUseFlag = "Used"; break;
    362                     case _FREEENTRY: pMemRecordThis->pszUseFlag = "Freed"; break;
    363                 }
    364 
    365                 switch (pMemRecordThis->status)
    366                 {
    367                     case _HEAPBADBEGIN: pMemRecordThis->pszStatus = "heap bad begin"; break;
    368                     case _HEAPBADNODE: pMemRecordThis->pszStatus = "heap bad node"; break;
    369                     case _HEAPEMPTY: pMemRecordThis->pszStatus = "heap empty"; break;
    370                     case _HEAPOK: pMemRecordThis->pszStatus = "OK"; break;
    371                 }
    372 
    373                 sprintf(pMemRecordThis->szAddress, "0x%lX", pMemRecordThis->pObject);
    374                 strhcpy(pMemRecordThis->szSource,
    375                         (pMemRecordThis->filename)
    376                             ? pMemRecordThis->filename
    377                             : "?"); */
    378 
    379                 pMemRecordThis = (PMEMRECORD)pMemRecordThis->recc.preccNextRecord;
    380                 pHeapItem = pHeapItem->pNext;
    381             }
    382 
    383             cnrhInsertRecords(hwndCnr,
    384                               NULL,         // parent
    385                               (PRECORDCORE)pMemRecordFirst,
    386                               TRUE,
    387                               NULL,
    388                               CRA_RECORDREADONLY,
    389                               ulHeapItemsCount2);
     394            CHAR        szMsg[1000];
     395            sprintf(szMsg,
     396                    "Crash occured at object #%d out of %d",
     397                    cHeapItems,
     398                    G_cHeapItems);
     399            G_pMemdLogFunc(szMsg);
    390400        }
    391 
     401    } END_CATCH();
     402
     403    if (fLocked)
    392404        memdUnlock();
    393     }
    394405}
    395406
     
    625636                                "    Total memory logs freed: %s items = %s bytes\n"
    626637                                "Total memory logs freed and discarded: %s items = %s bytes",
    627                                 strhThousandsDouble(szTotalItems,
     638                                nlsThousandsDouble(szTotalItems,
    628639                                                    ulTotalItems,
    629640                                                    '.'),
    630                                 strhThousandsDouble(szTotalBytes,
     641                                nlsThousandsDouble(szTotalBytes,
    631642                                                    ulTotalBytes,
    632643                                                    '.'),
    633                                 strhThousandsDouble(szAllocatedItems,
     644                                nlsThousandsDouble(szAllocatedItems,
    634645                                                    ulAllocatedItems,
    635646                                                    '.'),
    636                                 strhThousandsDouble(szAllocatedBytes,
     647                                nlsThousandsDouble(szAllocatedBytes,
    637648                                                    ulAllocatedBytes,
    638649                                                    '.'),
    639                                 strhThousandsDouble(szFreedItems,
     650                                nlsThousandsDouble(szFreedItems,
    640651                                                    ulFreedItems,
    641652                                                    '.'),
    642                                 strhThousandsDouble(szFreedBytes,
     653                                nlsThousandsDouble(szFreedBytes,
    643654                                                    ulFreedBytes,
    644655                                                    '.'),
    645                                 strhThousandsDouble(szReleasedItems,
     656                                nlsThousandsDouble(szReleasedItems,
    646657                                                    G_ulItemsReleased,
    647658                                                    '.'),
    648                                 strhThousandsDouble(szReleasedBytes,
     659                                nlsThousandsDouble(szReleasedBytes,
    649660                                                    G_ulBytesReleased,
    650661                                                    '.'));
  • trunk/src/helpers/stringh.c

    r122 r123  
    4242
    4343#define INCL_WINSHELLDATA
     44#define INCL_DOSERRORS
    4445#include <os2.h>
    4546
     
    6869 */
    6970
     71#ifdef __DEBUG_MALLOC_ENABLED__
     72
     73/*
     74 *@@ strhStoreDebug:
     75 *      memory debug version of strhStore.
     76 *
     77 *@@added V0.9.16 (2001-12-08) [umoeller]
     78 */
     79
     80APIRET strhStoreDebug(PSZ *ppszTarget,
     81                      PCSZ pcszSource,
     82                      PULONG pulLength,        // out: length of new string (ptr can be NULL)
     83                      const char *pcszSourceFile,
     84                      unsigned long ulLine,
     85                      const char *pcszFunction)
     86{
     87    ULONG ulLength = 0;
     88
     89    if (ppszTarget)
     90    {
     91        if (*ppszTarget)
     92            free(*ppszTarget);
     93
     94        if (    (pcszSource)
     95             && (ulLength = strlen(pcszSource))
     96           )
     97        {
     98            if (*ppszTarget = (PSZ)memdMalloc(ulLength + 1,
     99                                              pcszSourceFile,
     100                                              ulLine,
     101                                              pcszFunction))
     102                memcpy(*ppszTarget, pcszSource, ulLength + 1);
     103            else
     104                return (ERROR_NOT_ENOUGH_MEMORY);
     105        }
     106        else
     107            *ppszTarget = NULL;
     108    }
     109
     110    if (pulLength)
     111        *pulLength = ulLength;
     112
     113    return (NO_ERROR);
     114}
     115
     116#endif
     117
    70118/*
    71119 *@@ strhStore:
     
    81129 */
    82130
    83 VOID strhStore(PSZ *ppszTarget,
    84                PCSZ pcszSource,
    85                PULONG pulLength)        // out: length of new string (ptr can be NULL)
     131APIRET strhStore(PSZ *ppszTarget,
     132                 PCSZ pcszSource,
     133                 PULONG pulLength)        // out: length of new string (ptr can be NULL)
    86134{
    87135    ULONG ulLength = 0;
     
    98146            if (*ppszTarget = (PSZ)malloc(ulLength + 1))
    99147                memcpy(*ppszTarget, pcszSource, ulLength + 1);
     148            else
     149                return (ERROR_NOT_ENOUGH_MEMORY);
    100150        }
    101151        else
     
    105155    if (pulLength)
    106156        *pulLength = ulLength;
     157
     158    return (NO_ERROR);
    107159}
    108160
     
    127179
    128180/*
    129  *@@ strhdup:
     181 *@@ strhdupDebug:
    130182 *      memory debug version of strhdup.
    131183 *
     
    133185 */
    134186
    135 PSZ strhdupDebug(const char *pszSource,
     187PSZ strhdupDebug(const char *pcszSource,
    136188                 unsigned long *pulLength,
    137189                 const char *pcszSourceFile,
     
    147199    {
    148200        if (pszReturn = (PSZ)memdMalloc(ulLength + 1,
    149                                         pcszSourceFile,
     201                                        pcszSourceFile,     // fixed V0.9.16 (2001-12-08) [umoeller]
    150202                                        ulLine,
    151203                                        pcszFunction))
  • trunk/src/helpers/threads.c

    r116 r123  
    4040    // as unsigned char
    4141
     42#define INCL_WINMESSAGEMGR
    4243#define INCL_DOSPROCESS
    4344#define INCL_DOSSEMAPHORES
     
    130131    if (pti)
    131132    {
     133        HEV hevExitComplete;
     134
    132135        if (pti->flFlags & THRF_WAIT)
    133136            // "Wait" flag set: thrCreate is then
     
    168171        }
    169172
     173        // copy event sem before freeing pti
     174        hevExitComplete = pti->hevExitComplete;
     175
    170176        // set exit flags
    171177        // V0.9.7 (2000-12-20) [umoeller]
    172         pti->fExitComplete = TRUE;
    173178        pti->tid = NULLHANDLE;
    174179
     
    180185        if (pti->flFlags & THRF_TRANSIENT)
    181186            free(pti);
     187
     188        if (hevExitComplete)
     189            // caller wants notification:
     190            DosPostEventSem(hevExitComplete);
     191                    // V0.9.16 (2001-12-08) [umoeller]
    182192    }
    183193
     
    394404 *@@added V0.9.5 (2000-08-26) [umoeller]
    395405 *@@changed V0.9.9 (2001-03-07) [umoeller]: added pcszThreadName
     406 *@@changed V0.9.16 (2001-12-08) [umoeller]: fixed hang with thrWait
    396407 */
    397408
     
    417428    {
    418429        THREADINFO  ti = {0};
     430        volatile unsigned long tidRunning = 0;
    419431        thrCreate(&ti,
    420432                  pfn,
    421                   NULL,
     433                  &tidRunning,
    422434                  pcszThreadName,
    423435                  THRF_PMMSGQUEUE,
    424436                  ulData);
    425437        ti.hwndNotify = hwndNotify;
     438        // create event sem to wait on V0.9.16 (2001-12-08) [umoeller]
     439        DosCreateEventSem(NULL,
     440                          &ti.hevExitComplete,
     441                          0,
     442                          FALSE);       // not posted
    426443
    427444        while (WinGetMsg(hab,
     
    445462        // otherwise THREADINFO is deleted from the stack
    446463        // before the thread exits... will crash!
    447         thrWait(&ti);
     464        // thrWait(&ti);
     465        // now using event sem V0.9.16 (2001-12-08) [umoeller]
     466        WinWaitEventSem(ti.hevExitComplete, 5000);
     467        DosCloseEventSem(ti.hevExitComplete);
    448468
    449469        WinDestroyWindow(hwndNotify);
     
    481501        PLISTNODE pNode;
    482502        *pcThreads = lstCountItems(&G_llThreadInfos);
    483         _Pmpf((__FUNCTION__ ": got %d threads", *pcThreads));
    484503        pArray = (PTHREADINFO)malloc(*pcThreads * sizeof(THREADINFO));
    485504        pThis = pArray;
     
    561580 *      the thread will actually terminate.
    562581 *
     582 *      Update V0.9.16: Do not use this with PM theads at
     583 *      all. DosWaitThread can hang the system then.
     584 *
    563585 *      Returns FALSE if the thread wasn't running or TRUE
    564586 *      if it was and has terminated.
     
    631653{
    632654    if (pti)
    633         if (!(pti->fExitComplete))
    634             return (pti->tid);
     655        return (pti->tid);
    635656
    636657    return (NULLHANDLE);
  • trunk/src/helpers/timer.c

    r93 r123  
    540540                                // window still valid:
    541541                                // get the window's window proc
    542                                 PFNWP pfnwp = (PFNWP)WinQueryWindowPtr(pTimer->hwndTarget,
    543                                                                        QWP_PFNWP);
     542                                QMSG qmsg;
     543                                /* PFNWP pfnwp = (PFNWP)WinQueryWindowPtr(pTimer->hwndTarget,
     544                                                                       QWP_PFNWP); */
    544545
    545546                                // moved this up V0.9.14 (2001-08-01) [umoeller]
     
    547548
    548549                                // call the window proc DIRECTLY
    549                                 pfnwp(pTimer->hwndTarget,
     550                                qmsg.hwnd = pTimer->hwndTarget;
     551                                qmsg.msg = WM_TIMER;
     552                                qmsg.mp1 = (MPARAM)pTimer->usTimerID;
     553                                qmsg.mp2 = (MPARAM)0;
     554                                qmsg.time = 0;
     555                                qmsg.ptl.x = 0;
     556                                qmsg.ptl.y = 0;
     557                                qmsg.reserved = 0;
     558                                WinDispatchMsg(pSet->hab,
     559                                               &qmsg);
     560                                /* pfnwp(pTimer->hwndTarget,
    550561                                      WM_TIMER,
    551562                                      (MPARAM)pTimer->usTimerID,
    552                                       0);
     563                                      0); */
    553564                                    // V0.9.12 (2001-05-24) [umoeller]
    554565                                    // if the winproc chooses to start or
Note: See TracChangeset for help on using the changeset viewer.