Changeset 123
- Timestamp:
- Dec 14, 2001, 11:41:33 PM (24 years ago)
- Location:
- trunk
- Files:
-
- 19 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/include/helpers/apps.h
r113 r123 76 76 // V0.9.16 (2001-10-06) 77 77 78 #define PROG_WIN32 990 // added V0.9.16 (2001-12-08) [umoeller] 79 78 80 APIRET appQueryAppType(const char *pcszExecutable, 79 81 PULONG pulDosAppType, -
trunk/include/helpers/dosh.h
r121 r123 57 57 PVOID doshMalloc(ULONG cb, 58 58 APIRET *parc); 59 60 APIRET doshAllocArray(ULONG c, 61 ULONG cbArrayItem, 62 PBYTE *ppv, 63 PULONG pcbAllocated); 59 64 60 65 PVOID doshAllocSharedMem(ULONG ulSize, … … 353 358 LONG lOffset, 354 359 ULONG ulMethod, 355 ULONGcb,360 PULONG pcb, 356 361 PBYTE pbData); 357 362 … … 464 469 ********************************************************************/ 465 470 471 #pragma pack(1) 472 466 473 /* 467 474 *@@ DOSEXEHEADER: … … 473 480 */ 474 481 475 #pragma pack(1)476 482 typedef struct _DOSEXEHEADER 477 483 { … … 532 538 ULONG ulChecksum; // 08: MS: reserved, OS/2: checksum 533 539 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 */ 534 558 USHORT usAutoDataSegNo; // 0e: auto-data seg no. 535 559 USHORT usInitlHeapSize; // 10: initl. heap size … … 581 605 ULONG ulModuleVersion; // 0c: module version 582 606 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 */ 583 619 ULONG ulPageCount; // 14: no. of pages in module 584 620 ULONG ulEIPRelObj; // 18: object to which EIP is relative … … 680 716 } PEHEADER, *PPEHEADER; 681 717 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 682 782 #pragma pack() 683 684 /*685 *@@ FSYSMODULE:686 *687 *@@added V0.9.9 (2001-03-11) [lafaix]688 */689 690 typedef struct _FSYSMODULE691 {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 _FSYSFUNCTION702 {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 _FSYSRESOURCE715 {716 ULONG ulID; // resource ID717 ULONG ulType; // resource type718 ULONG ulSize; // resource size in bytes719 ULONG ulFlag; // resource flags720 } FSYSRESOURCE, *PFSYSRESOURCE;721 783 722 784 // object/segment flags (in NE and LX) … … 822 884 // module info substring (if IBM BLDLEVEL format) 823 885 886 #ifndef __STRIP_DOWN_EXECUTABLE__ // for mini stubs in warpin, to reduce code size 824 887 // if pszInfo is extended DESCRIPTION field, the following 825 888 // are set as well: … … 833 896 pszFixpak; 834 897 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 835 905 } EXECUTABLE, *PEXECUTABLE; 836 906 … … 838 908 PEXECUTABLE* ppExec); 839 909 840 APIRET doshExecClose(PEXECUTABLE pExec);841 842 910 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; 843 922 844 923 APIRET doshExecQueryImportedModules(PEXECUTABLE pExec, … … 848 927 APIRET doshExecFreeImportedModules(PFSYSMODULE paModules); 849 928 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 850 942 APIRET doshExecQueryExportedFunctions(PEXECUTABLE pExec, 851 943 PFSYSFUNCTION *ppaFunctions, … … 854 946 APIRET doshExecFreeExportedFunctions(PFSYSFUNCTION paFunctions); 855 947 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 856 963 APIRET doshExecQueryResources(PEXECUTABLE pExec, 857 964 PFSYSRESOURCE *ppaResources, … … 859 966 860 967 APIRET doshExecFreeResources(PFSYSRESOURCE paResources); 968 969 APIRET doshLoadLXMaps(PEXECUTABLE pExec); 970 971 VOID doshFreeLXMaps(PEXECUTABLE pExec); 972 973 APIRET doshExecClose(PEXECUTABLE *ppExec); 861 974 862 975 APIRET doshSearchPath(PCSZ pcszPath, -
trunk/include/helpers/memdebug.h
r113 r123 80 80 typedef struct _HEAPITEM 81 81 { 82 struct _HEAPITEM *pNext; // next item in linked list or NULL if last82 // struct _HEAPITEM *pNext; // next item in linked list or NULL if last 83 83 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 86 95 unsigned long ulSize; // requested size (without magic head and tail) 87 96 … … 97 106 } HEAPITEM, *PHEAPITEM; 98 107 99 extern PHEAPITEM G_pHeapItemsRoot; 108 extern TREE *G_pHeapItemsRoot; 109 extern LONG G_cHeapItems; 100 110 extern ULONG G_ulItemsReleased; 101 111 extern ULONG G_ulBytesReleased; -
trunk/include/helpers/standards.h
r113 r123 63 63 64 64 /* 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 /* 65 86 *@@ ARRAYITEMCOUNT: 66 87 * helpful macro to count the count of items -
trunk/include/helpers/stringh.h
r122 r123 32 32 #define STRINGH_HEADER_INCLUDED 33 33 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 35 45 36 46 PSZ XWPENTRY strhcpy(PSZ string1, const char *string2); -
trunk/include/helpers/threads.h
r115 r123 60 60 HAB hab; // for PM threads 61 61 HMQ hmq; // for PM threads 62 BOOL fExitComplete;62 HEV hevExitComplete; // posted when thread exits V0.9.16 (2001-12-08) [umoeller] 63 63 64 64 // data to be maintained by application -
trunk/src/helpers/apps.c
r122 r123 513 513 * -- PROG_WINDOWABLEVIO 514 514 * 515 * -- PROG_DEFAULT 516 * 515 517 *@@added V0.9.9 (2001-03-07) [umoeller] 516 518 *@@changed V0.9.12 (2001-05-27) [umoeller]: moved from winh.c to apps.c 517 519 *@@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 518 521 */ 519 522 520 523 APIRET appQueryAppType(const char *pcszExecutable, 521 522 524 PULONG pulDosAppType, 525 PULONG pulWinAppType) 523 526 { 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 536 560 // 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 539 563 // 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 (?!?) 545 572 ) 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; 553 600 554 601 return (arc); … … 608 655 case PROG_WIN_GAME: return "PROG_WIN_GAME"; 609 656 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"; 610 660 } 611 661 -
trunk/src/helpers/cnrh.c
r106 r123 1865 1865 1866 1866 memset(&drgImage, 0, sizeof(drgImage)); 1867 pdrgInfo = DrgAllocDraginfo(1); // one item only 1868 if (pdrgInfo )1867 1868 if (pdrgInfo = DrgAllocDraginfo(1)) // one item only 1869 1869 { 1870 1870 DRAGITEM drgItem; -
trunk/src/helpers/comctl.c
r122 r123 510 510 511 511 case WM_MENUEND: 512 {513 512 if ((HWND)mp2 == pmbd->hwndMenu) // V0.9.14 (2001-07-31) [umoeller] 514 513 { … … 548 547 pmbd->hwndMenu = NULLHANDLE; 549 548 } // end if ((HWND)mp1 == pmbd->pmbd->hwndMenu) // V0.9.14 (2001-07-31) [umoeller] 550 break; }549 break; 551 550 552 551 /* … … 569 568 570 569 case WM_DESTROY: 571 mrc = (*(pmbd->pfnwpButtonOriginal))(hwndButton, msg, mp1, mp2);570 mrc = pmbd->pfnwpButtonOriginal(hwndButton, msg, mp1, mp2); 572 571 free(pmbd); 573 572 break; 574 573 575 574 default: 576 mrc = (*(pmbd->pfnwpButtonOriginal))(hwndButton, msg, mp1, mp2);575 mrc = pmbd->pfnwpButtonOriginal(hwndButton, msg, mp1, mp2); 577 576 } 578 577 … … 617 616 { 618 617 BOOL brc = FALSE; 619 PMENUBUTTONDATA pmbd = (PMENUBUTTONDATA)malloc(sizeof(MENUBUTTONDATA));620 if (pmbd )618 PMENUBUTTONDATA pmbd; 619 if (pmbd = (PMENUBUTTONDATA)malloc(sizeof(MENUBUTTONDATA))) 621 620 { 622 621 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)) 626 624 { 627 625 pmbd->hmodMenu = hmodMenu; … … 730 728 731 729 case WM_TIMER: 732 {733 730 pa->usAniCurrent++; 734 731 if (pa->usAniCurrent >= pa->usAniCount) … … 739 736 (MPARAM)pa->ahptrAniIcons[pa->usAniCurrent], 740 737 (MPARAM)NULL); 741 break; }738 break; 742 739 743 740 /* … … 793 790 // create a suitable bitmap w/ the size of the 794 791 // 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 ) 798 798 { 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) 801 818 { 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) 821 821 { 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))) 869 863 870 864 // in any case, clean up now … … 877 871 // enforce WM_PAINT 878 872 WinInvalidateRect(hwndStatic, NULL, FALSE); 879 880 break; }873 } 874 break; 881 875 882 876 /* … … 940 934 941 935 WinEndPaint(hps); 942 break; } 936 } 937 break; 943 938 944 939 /* … … 948 943 949 944 case WM_DESTROY: 950 {951 945 // undo subclassing in case more WM_TIMERs come in 952 946 WinSubclassWindow(hwndStatic, OldStaticProc); … … 962 956 963 957 mrc = OldStaticProc(hwndStatic, msg, mp1, mp2); 964 break; }958 break; 965 959 966 960 default: … … 1117 1111 BOOL fStartAnimation) // TRUE: start animation now 1118 1112 { 1119 PANIMATIONDATA paNew = ctlPrepareStaticIcon(hwndStatic, usAnimCount);1120 if (paNew )1113 PANIMATIONDATA paNew; 1114 if (paNew = ctlPrepareStaticIcon(hwndStatic, usAnimCount)) 1121 1115 { 1122 1116 paNew->ulDelay = ulDelay; … … 1132 1126 if (fStartAnimation) 1133 1127 { 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); 1137 1133 } 1138 1134 } … … 1150 1146 { 1151 1147 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 1160 1160 return (brc); 1161 1161 } … … 1345 1345 // check flags: 1346 1346 // 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) 1348 1348 ) 1349 1349 { … … 1367 1367 1368 1368 flReturned = (ULONG)WinSendMsg(hwndOwner, 1369 WM_CONTROL,1370 MPFROM2SHORT(WinQueryWindowUShort(hwndEdit,1371 QWS_ID),1372 EN_HOTKEY), // new notification code1373 (MPARAM)&hkn);1369 WM_CONTROL, 1370 MPFROM2SHORT(WinQueryWindowUShort(hwndEdit, 1371 QWS_ID), 1372 EN_HOTKEY), // new notification code 1373 (MPARAM)&hkn); 1374 1374 if (flReturned & HEFL_SETTEXT) 1375 1375 WinSetWindowText(hwndEdit, hkn.szDescription); … … 1383 1383 WinSetWindowText(hwndEdit, ""); 1384 1384 1385 1386 1385 mrc = (MPARAM)TRUE; // WM_CHAR processed flag; 1387 1386 } 1388 break; } 1387 } 1388 break; 1389 1389 1390 1390 default: -
trunk/src/helpers/configsys.c
r117 r123 91 91 } 92 92 93 arc = doshLoadTextFile(pcszFile, 94 ppszContents); 95 96 if (arc == NO_ERROR) 93 if (!(arc = doshLoadTextFile(pcszFile, 94 ppszContents))) 97 95 { 98 96 // convert all \r\n to \n … … 316 314 ULONG cbCopyTo) // out: sizeof(*pszCopyTo) 317 315 { 318 PSZ p = csysFindKey(pcszSearchIn, pcszKey, NULL, NULL),316 PSZ p, 319 317 prc = NULL; 320 318 321 if (p )319 if (p = csysFindKey(pcszSearchIn, pcszKey, NULL, NULL)) 322 320 { 323 321 prc = p + strlen(pcszKey); … … 326 324 // copy to pszCopyTo 327 325 ULONG cb; 328 PSZ pEOL = strhFindEOL(prc, &cb);329 if (pEOL )326 PSZ pEOL; 327 if (pEOL = strhFindEOL(prc, &cb)) 330 328 { 331 329 if (cb > cbCopyTo) … … 370 368 { 371 369 BOOL fIsAllUpperCase = FALSE; 372 PSZ pKey = csysFindKey(*ppszBuf, 373 pcszKey, 374 NULL, 375 &fIsAllUpperCase), 370 PSZ pKey, 376 371 pReturn = NULL; 377 if (pKey) 372 if (pKey = csysFindKey(*ppszBuf, 373 pcszKey, 374 NULL, 375 &fIsAllUpperCase)) 378 376 { 379 377 // key found in file: … … 381 379 382 380 // replace existing parameter 383 PSZ pOldParam = pKey + strlen(pcszKey);384 // pOldParam now has the old parameter, which we385 // will overwrite now; pOldParam points into *ppszBuf386 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 389 387 ULONG ulOldParamOfs = pOldParam - *ppszBuf; 390 388 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)) 395 391 { 392 // pEOL now has first end-of-line after the parameter 393 396 394 // char count to replace 397 395 ULONG ulToReplace = pEOL - pOldParam; … … 477 475 BOOL fIsAllUpperCase = FALSE; 478 476 PSZ pStartOfLine = NULL; 479 PSZ pKey = csysFindKey(pszSearchIn, 480 pszKey, 481 &pStartOfLine, 482 &fIsAllUpperCase); 477 PSZ pKey; 483 478 BOOL brc = FALSE; 484 479 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; 491 489 // go to first character after EOL 492 490 while ( (*pEOL) … … 604 602 605 603 // 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, '=')) 608 606 { 609 607 // yes: separate in two strings … … 751 749 // Manip.pszSearchString has the search string 752 750 // 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)) 756 754 { 757 755 // search string found: … … 777 775 // Manip.pszSearchString has the search string 778 776 // 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)) 781 780 { 782 781 // search string found: -
trunk/src/helpers/datetime.c
r108 r123 230 230 * returns TRUE if yr is a leap year. 231 231 * 232 * ( c) Ray Gardner. Public domain.232 * (W) Ray Gardner. Public domain. 233 233 */ 234 234 … … 260 260 * you then get 63. 261 261 * 262 * ( c) Ray Gardner. Public domain.262 * (W) Ray Gardner. Public domain. 263 263 */ 264 264 … … 272 272 * converts a year to the no. of days passed. 273 273 * 274 * ( c) Ray Gardner. Public domain.274 * (W) Ray Gardner. Public domain. 275 275 */ 276 276 … … 288 288 * the given date. 289 289 * 290 * ( c) Ray Gardner. Public domain.290 * (W) Ray Gardner. Public domain. 291 291 */ 292 292 … … 308 308 * 309 309 * 310 * ( c) Ray Gardner. Public domain.310 * (W) Ray Gardner. Public domain. 311 311 */ 312 312 … … 343 343 ULONG year) // in: year (e.g. 1999) 344 344 { 345 BOOL brc = FALSE;346 345 if (day > 0) 347 346 { … … 356 355 case 12 : 357 356 if (day <= 31) 358 brc = TRUE;357 return (TRUE); 359 358 break; 360 359 … … 364 363 case 11 : 365 364 if (day <= 30) 366 brc = TRUE;365 return (TRUE); 367 366 break; 368 367 369 368 case 2 : 370 369 if (day < 29) 371 brc = TRUE;370 return (TRUE); 372 371 else 373 372 if (day == 29) 374 373 if (dtIsLeapYear(year)) 375 return 1;374 return (TRUE); 376 375 } 377 376 } 378 return (brc); 379 } 380 377 378 return (FALSE); 379 } 380 -
trunk/src/helpers/dialog.c
r122 r123 678 678 cy = pcp->cy; 679 679 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) 718 725 } 719 726 -
trunk/src/helpers/dosh.c
r122 r123 127 127 ULONG ulAction; 128 128 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))) 134 134 { 135 135 SHIFTSTATE ShiftState; 136 136 ULONG cbDataLen = sizeof(ShiftState); 137 137 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))) 142 141 brc = ((ShiftState.fsState & 3) != 0); 143 142 … … 308 307 309 308 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 327 APIRET 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; 310 340 } 311 341 … … 1333 1363 * has no dot in it). 1334 1364 * 1365 * In the pathological case of a dot in the path 1366 * but not in the filename itself, this correctly 1367 * returns NULL. 1368 * 1335 1369 *@@added V0.9.6 (2000-10-16) [umoeller] 1336 1370 *@@changed V0.9.7 (2000-12-10) [umoeller]: fixed "F:filename.ext" case … … 1344 1378 { 1345 1379 // find filename 1346 PCSZ p2 = strrchr(pcszFilename + 2, '\\'), 1347 // works on "C:\blah" or "\\unc\blah" 1380 PCSZ p2, 1348 1381 pStartOfName = NULL, 1349 1382 pExtension = NULL; 1350 1383 1351 if (p2) 1384 if (p2 = strrchr(pcszFilename + 2, '\\')) 1385 // works on "C:\blah" or "\\unc\blah" 1352 1386 pStartOfName = p2 + 1; 1353 1387 else … … 1365 1399 1366 1400 // find last dot in filename 1367 pExtension = strrchr(pStartOfName, '.'); 1368 if (pExtension) 1401 if (pExtension = strrchr(pStartOfName, '.')) 1369 1402 pReturn = (PSZ)pExtension + 1; 1370 1403 } … … 1418 1451 // Each data field following fsqBuffer.szName begins 1419 1452 // 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)) 1424 1456 brc = TRUE; 1425 1457 } … … 1438 1470 */ 1439 1471 1440 APIRET doshQueryFileSize(HFILE hFile, 1441 PULONG pulSize) 1472 APIRET doshQueryFileSize(HFILE hFile, // in: file handle 1473 PULONG pulSize) // out: file size (ptr can be NULL) 1442 1474 { 1443 1475 APIRET arc; 1444 1476 FILESTATUS3 fs3; 1445 1477 if (!(arc = DosQueryFileInfo(hFile, FIL_STANDARD, &fs3, sizeof(fs3)))) 1446 *pulSize = fs3.cbFile; 1478 if (pulSize) 1479 *pulSize = fs3.cbFile; 1447 1480 return (arc); 1448 1481 } … … 1453 1486 * or 0 if the file could not be 1454 1487 * found. 1488 * 1455 1489 * Use doshQueryFileSize instead to query the 1456 1490 * size if you have a HFILE. 1457 1491 * 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 * 1458 1500 *@@changed V0.9.16 (2001-10-19) [umoeller]: now returning APIRET 1459 1501 */ 1460 1502 1461 APIRET doshQueryPathSize(PCSZ pcszFile, 1462 PULONG pulSize) 1503 APIRET doshQueryPathSize(PCSZ pcszFile, // in: filename 1504 PULONG pulSize) // out: file size (ptr can be NULL) 1463 1505 { 1464 1506 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 1468 1518 return (arc); 1469 1519 } … … 1488 1538 * returned. 1489 1539 * 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 * 1490 1547 *@@added V0.9.0 [umoeller] 1491 1548 */ 1492 1549 1493 1550 APIRET doshQueryPathAttr(const char* pcszFile, // in: file or directory name 1494 PULONG pulAttr) // out: attributes 1551 PULONG pulAttr) // out: attributes (ptr can be NULL) 1495 1552 { 1496 1553 FILESTATUS3 fs3; 1497 APIRET arc = DosQueryPathInfo((PSZ)pcszFile, 1554 APIRET arc; 1555 1556 if (!(arc = DosQueryPathInfo((PSZ)pcszFile, 1498 1557 FIL_STANDARD, 1499 1558 &fs3, 1500 sizeof(fs3)); 1501 if (arc == NO_ERROR) 1559 sizeof(fs3)))) 1502 1560 { 1503 1561 if (pulAttr) … … 1532 1590 ULONG ulAttr) // in: new attributes 1533 1591 { 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, 1536 1604 FIL_STANDARD, 1537 1605 &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); 1550 1614 } 1551 1615 … … 1640 1704 LONG lOffset, // in: offset to write at (depends on ulMethod) 1641 1705 ULONG ulMethod, // in: one of FILE_BEGIN, FILE_CURRENT, FILE_END 1642 ULONG cb, // in: bytes to write1706 PULONG pcb, // in: bytes to read, out: bytes read 1643 1707 PBYTE pbData) // out: read buffer (must be cb bytes) 1644 1708 { 1645 1709 APIRET arc; 1710 ULONG cb = *pcb; 1646 1711 ULONG ulDummy; 1712 1713 *pcb = 0; 1714 1647 1715 if (!(arc = DosSetFilePtr(hf, 1648 1716 lOffset, 1649 1717 ulMethod, 1650 1718 &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 } 1655 1726 1656 1727 return (arc); … … 1663 1734 * 1664 1735 * 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: 1680 1755 * 1681 1756 * -- If XOPEN_BINARY is set, no conversion is performed … … 1687 1762 * *ppFile receives a new XFILE structure describing 1688 1763 * 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 1689 1779 * 1690 1780 *@@added V0.9.16 (2001-10-19) [umoeller] … … 1699 1789 APIRET arc = NO_ERROR; 1700 1790 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) 1740 1804 { 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)) 1756 1834 { 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); 1767 1874 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; 1776 1876 } 1777 1778 if (arc)1779 doshClose(&pFile);1780 1877 else 1781 *ppFile = pFile;1878 arc = ERROR_NOT_ENOUGH_MEMORY; 1782 1879 } 1783 1880 else 1784 arc = ERROR_NOT_ENOUGH_MEMORY; 1785 } 1786 else 1787 arc = ERROR_INVALID_PARAMETER; 1881 arc = ERROR_INVALID_PARAMETER; 1882 } 1788 1883 1789 1884 return (arc); … … 2199 2294 if (!pcszTemp) 2200 2295 { 2201 pcszTemp = getenv("TEMP"); 2202 if (!pcszTemp) 2296 if (!(pcszTemp = getenv("TEMP"))) 2203 2297 pcszTemp = getenv("TMP"); 2204 2298 } … … 2385 2479 *@@ doshQueryDirExist: 2386 2480 * returns TRUE if the given directory 2387 * exists .2481 * exists and really is a directory. 2388 2482 */ 2389 2483 … … 2391 2485 { 2392 2486 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)))) 2398 2493 // file found: 2399 2494 return ((fs3.attrFile & FILE_DIRECTORY) != 0); … … 2641 2736 { 2642 2737 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))) 2648 2744 { 2649 2745 ULONG ul; … … 2652 2748 ul++) 2653 2749 { 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: 2664 2755 break; 2665 2756 } 2757 2758 if (arc) 2759 // V0.9.16 (2001-12-08) [umoeller] 2760 DosFreeModule(*phmod); 2666 2761 } 2667 2762 -
trunk/src/helpers/dosh2.c
r110 r123 426 426 *@@changed V0.9.10 (2001-04-08) [umoeller]: now setting ppExec only if NO_ERROR is returned 427 427 *@@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 428 430 */ 429 431 … … 440 442 return (ERROR_INVALID_PARAMETER); 441 443 442 pExec = (PEXECUTABLE)malloc(sizeof(EXECUTABLE)); 443 if (!(pExec)) 444 if (!(pExec = (PEXECUTABLE)malloc(sizeof(EXECUTABLE)))) 444 445 return (ERROR_NOT_ENOUGH_MEMORY); 445 446 … … 458 459 | OPEN_FLAGS_SEQUENTIAL 459 460 | OPEN_FLAGS_NOINHERIT 460 | OPEN_SHARE_DENYNONE 461 // | OPEN_SHARE_DENYNONE 462 | OPEN_SHARE_DENYWRITE // changed V0.9.16 (2001-12-08) [umoeller] 461 463 | OPEN_ACCESS_READONLY, // read-only mode 462 464 NULL))) // no EAs … … 464 466 // file opened successfully: 465 467 466 ULONG ulLocal = 0;467 468 468 // read old DOS EXE header 469 pExec->pDosExeHeader = (PDOSEXEHEADER)malloc(sizeof(DOSEXEHEADER)); 470 if (!(pExec->pDosExeHeader)) 469 if (!(pExec->pDosExeHeader = (PDOSEXEHEADER)malloc(sizeof(DOSEXEHEADER)))) 471 470 arc = ERROR_NOT_ENOUGH_MEMORY; 472 471 else 473 472 { 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))) 485 479 { 486 480 ULONG ulNewHeaderOfs = 0; // V0.9.12 (2001-05-03) [umoeller] … … 530 524 // V0.9.12 (2001-05-03) [umoeller] 531 525 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))) 543 534 { 544 535 PBYTE pbCheckOS = NULL; 545 536 546 537 // reset file ptr 547 DosSetFilePtr(hFile,538 /* DosSetFilePtr(hFile, 548 539 ulNewHeaderOfs, 549 540 FILE_BEGIN, 550 541 &ulLocal); 551 552 if (memcmp(achNewHeaderType, "NE", 2) == 0) 542 */ 543 544 if (!memcmp(achNewHeaderType, "NE", 2)) 553 545 { 554 546 // New Executable: 555 547 pExec->ulExeFormat = EXEFORMAT_NE; 556 548 // 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 559 573 arc = ERROR_NOT_ENOUGH_MEMORY; 560 else561 // read in NE header562 if (!(arc = DosRead(hFile,563 pExec->pNEHeader,564 sizeof(NEHEADER),565 &(pExec->cbNEHeader))))566 if (pExec->cbNEHeader == sizeof(NEHEADER))567 pbCheckOS = &(pExec->pNEHeader->bTargetOS);568 574 } 569 575 else if ( (memcmp(achNewHeaderType, "LX", 2) == 0) … … 575 581 pExec->ulExeFormat = EXEFORMAT_LX; 576 582 // 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 579 607 arc = ERROR_NOT_ENOUGH_MEMORY; 580 else581 // read in LX header582 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));588 608 } 589 609 else if (memcmp(achNewHeaderType, "PE", 2) == 0) … … 597 617 // V0.9.10 (2001-04-08) [lafaix] 598 618 // 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))) 603 625 { 604 626 // 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)) 609 628 { 610 629 // copy standard PE header … … 615 634 // read in optional PE header 616 635 if (!(arc = DosRead(hFile, 617 & (pExec->pPEHeader->usReserved3),636 &pExec->pPEHeader->usReserved3, 618 637 PEHeader.usHeaderSize, 619 & (pExec->cbPEHeader))))638 &pExec->cbPEHeader))) 620 639 pExec->cbPEHeader += 24; 621 640 } 641 else 642 arc = ERROR_NOT_ENOUGH_MEMORY; 622 643 } 623 644 } … … 661 682 if (arc != NO_ERROR) 662 683 // error: clean up 663 doshExecClose( pExec);684 doshExecClose(&pExec); 664 685 else 665 686 *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 by674 * 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 else706 arc = ERROR_INVALID_PARAMETER;707 687 708 688 return (arc); … … 789 769 { 790 770 // 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)) 793 772 { 794 773 memcpy(pExec->pszBuildDateTime, … … 1862 1841 { 1863 1842 // 32-bit OS/2 executable: 1864 cResources = pExec->pLXHeader->ulResTblCnt; 1865 1866 if (cResources) 1843 if (cResources = pExec->pLXHeader->ulResTblCnt) 1867 1844 { 1868 1845 #pragma pack(1) // V0.9.9 (2001-04-02) [umoeller] 1869 struct rsrc32 / * Resource Table Entry */1846 struct rsrc32 // Resource Table Entry 1870 1847 { 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 1876 1853 } rs; 1877 1854 1878 struct o32_obj / * Flat .EXE object table entry */1855 struct o32_obj // Flat .EXE object table entry 1879 1856 { 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 1886 1863 } ot; 1887 1864 #pragma pack() // V0.9.9 (2001-04-03) [umoeller] … … 1890 1867 ULONG ulDummy; 1891 1868 int i; 1869 ULONG ulCurOfs; 1892 1870 1893 1871 paResources = (PFSYSRESOURCE)malloc(cb); … … 1956 1934 #pragma pack(1) // V0.9.9 (2001-04-02) [umoeller] 1957 1935 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 1959 1937 { 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 1964 1942 } ns; 1965 1943 #pragma pack() … … 2183 2161 free(paResources); 2184 2162 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 2206 APIRET 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 2286 VOID 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 2307 APIRET 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); 2185 2364 } 2186 2365 -
trunk/src/helpers/memdebug.c
r93 r123 32 32 * is executed, the system might be in a global memory 33 33 * 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. 35 36 * 36 37 * These debug functions have been added with V0.9.3 … … 38 39 * 39 40 * 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. 40 44 * 41 45 * -- A PM heap debugging window which shows the status … … 49 53 * 50 54 * 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. 52 57 * 53 58 * If you don't want those replaced, add … … 55 60 * before including memdebug.h. 56 61 * 62 * To avoid calling a debug function for a single call, 63 * place the malloc call (or whatever) in brackets. 64 * 57 65 * That's all. XWorkplace's setup.h does this automatically 58 66 * if XWorkplace is compiled with debug code. … … 60 68 * A couple of WARNINGS: 61 69 * 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. 71 76 * 72 77 * 2) The replacement functions in this file allocate … … 76 81 * memory overwrites. Two magic strings are allocated, 77 82 * one before the actual buffer, and one behind it. 83 * The pointer returned is _not_ identical to the one 84 * that was internally allocated. 78 85 * 79 86 * As a result, YOU MUST NOT confuse the replacement … … 119 126 #include <setjmp.h> 120 127 128 #include "helpers\tree.h" 129 121 130 #define DONT_REPLACE_MALLOC // never do debug memory for this 122 131 #define MEMDEBUG_PRIVATE … … 125 134 #ifdef __XWPMEMDEBUG__ 126 135 136 #include "helpers\dosh.h" 127 137 #include "helpers\except.h" 138 128 139 #include "helpers\memdebug.h" // included by setup.h already 129 140 #include "helpers\stringh.h" … … 146 157 #define MEMBLOCKMAGIC_TAIL "\250\210&%/dfjsk%#,dlhf\223" 147 158 148 HMTX G_hmtxMallocList = NULLHANDLE;149 150 extern PHEAPITEMG_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;159 HMTX G_hmtxMallocList = NULLHANDLE; 160 161 extern TREE *G_pHeapItemsRoot = NULL; 162 extern LONG G_cHeapItems = 0; 163 164 PFNCBMEMDLOG G_pMemdLogFunc = NULL; 165 166 extern ULONG G_ulItemsReleased = 0; 167 extern ULONG G_ulBytesReleased = 0; 157 168 158 169 /* ****************************************************************** … … 175 186 BOOL memdLock(VOID) 176 187 { 177 APIRET arc = NO_ERROR;178 if (G_hmtxMallocList == NULLHANDLE)188 if (!G_hmtxMallocList) 189 { 179 190 // 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 } 184 200 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); 189 205 } 190 206 … … 199 215 { 200 216 DosReleaseMutexSem(G_hmtxMallocList); 217 } 218 219 /* 220 *@@ LogError: 221 * 222 *@@added V0.9.16 (2001-12-08) [umoeller] 223 */ 224 225 VOID 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 246 PHEAPITEM 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 259 VOID 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 289 VOID 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 } 201 324 } 202 325 … … 217 340 * 218 341 *@@added V0.9.3 (2000-04-11) [umoeller] 342 *@@changed V0.9.16 (2001-12-08) [umoeller]: reworked to use trees now, much faster 219 343 */ 220 344 … … 228 352 if (stSize == 0) 229 353 // 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()) 231 360 { 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))) 267 370 { 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)); 294 390 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)) 297 406 { 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); 311 413 } 312 414 } 415 416 memdUnlock(); 313 417 } 314 315 memdUnlock();316 }317 418 318 419 return (prc); … … 361 462 * 362 463 *@@added V0.9.3 (2000-04-10) [umoeller] 464 *@@changed V0.9.16 (2001-12-08) [umoeller]: reworked to use trees now, much faster 363 465 */ 364 466 … … 368 470 const char *pcszFunction) 369 471 { 370 BOOL fFound = FALSE;371 472 if (memdLock()) 372 473 { 373 // PLISTNODE pNode = lstQueryFirstNode(&G_llHeapItems); 374 PHEAPITEM pHeapItem = G_pHeapItemsRoot; 474 PHEAPITEM pHeapItem; 375 475 376 476 // search the list with the pointer which was 377 477 // 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)) 382 480 { 383 if (pHeapItem->pAfterMagic == p) 481 // the same address may be allocated and freed 482 // several times, so check 483 if (!pHeapItem->fFreed) 384 484 { 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); 435 515 } 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); 436 523 437 524 memdUnlock(); 438 525 } 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 }452 526 } 453 527 … … 459 533 *@@added V0.9.6 (2000-11-12) [umoeller] 460 534 *@@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 461 536 */ 462 537 … … 468 543 { 469 544 void *prc = NULL; 470 BOOL fFound = FALSE;471 545 472 546 if (!p) … … 477 551 if (memdLock()) 478 552 { 479 PHEAPITEM pHeapItem = G_pHeapItemsRoot;480 481 553 // search the list with the pointer which was 482 554 // 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)) 487 558 { 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)) 493 625 { 494 // found:495 PVOID pObjNew = 0;496 ULONG ulError = 0;497 ULONG cbCopy = 0;498 PTIB ptib;499 PPIB ppib;500 501 // check magic string502 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)) 514 646 { 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); 533 653 } 534 654 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) 586 656 } 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); 587 663 588 664 memdUnlock(); 589 665 } 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 }603 666 604 667 return (prc); … … 624 687 if (memdLock()) 625 688 { 626 PHEAPITEM pHeapItem = G_pHeapItemsRoot, 627 pPrevious = NULL; 689 /* PHEAPITEM pHeapItem = treeFirst(G_pHeapItemsRoot); 628 690 629 691 while (pHeapItem) 630 692 { 631 693 // store next first, because we can change the "next" pointer 632 PHEAPITEM pNext = pHeapItem->pNext; // can be NULL694 PHEAPITEM pNext = treeNext(pHeapItem); 633 695 634 696 if (pHeapItem->fFreed) … … 658 720 pHeapItem = pNext; 659 721 } 660 722 */ 661 723 G_ulItemsReleased += ulItemsReleased; 662 724 G_ulBytesReleased += ulBytesReleased; -
trunk/src/helpers/memdebug_win.c
r91 r123 47 47 #include <setjmp.h> 48 48 49 #include "helpers\tree.h" 50 49 51 #define DONT_REPLACE_MALLOC // never do debug memory for this 50 52 #define MEMDEBUG_PRIVATE … … 56 58 #include "helpers\except.h" 57 59 // #include "helpers\memdebug.h" // included by setup.h already 60 #include "helpers\nls.h" 58 61 #include "helpers\stringh.h" 59 62 #include "helpers\winh.h" … … 278 281 { 279 282 // count heap items 280 ULONG ulHeapItemsCount1 = 0;283 // ULONG ulHeapItemsCount1 = 0; 281 284 PMEMRECORD pMemRecordFirst; 282 285 283 if (memdLock()) 286 ULONG cHeapItems = 0; 287 BOOL fLocked = FALSE; 288 289 TRY_LOUD(excpt1) 284 290 { 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()) 296 292 { 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)) 299 308 { 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); 302 387 } 303 else304 {305 (*pulAllocatedItems)++;306 (*pulAllocatedBytes) += pHeapItem->ulSize;307 }308 309 (*pulTotalBytes) += pHeapItem->ulSize;310 311 pHeapItem = pHeapItem->pNext;312 388 } 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) 320 393 { 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); 390 400 } 391 401 } END_CATCH(); 402 403 if (fLocked) 392 404 memdUnlock(); 393 }394 405 } 395 406 … … 625 636 " Total memory logs freed: %s items = %s bytes\n" 626 637 "Total memory logs freed and discarded: %s items = %s bytes", 627 strhThousandsDouble(szTotalItems,638 nlsThousandsDouble(szTotalItems, 628 639 ulTotalItems, 629 640 '.'), 630 strhThousandsDouble(szTotalBytes,641 nlsThousandsDouble(szTotalBytes, 631 642 ulTotalBytes, 632 643 '.'), 633 strhThousandsDouble(szAllocatedItems,644 nlsThousandsDouble(szAllocatedItems, 634 645 ulAllocatedItems, 635 646 '.'), 636 strhThousandsDouble(szAllocatedBytes,647 nlsThousandsDouble(szAllocatedBytes, 637 648 ulAllocatedBytes, 638 649 '.'), 639 strhThousandsDouble(szFreedItems,650 nlsThousandsDouble(szFreedItems, 640 651 ulFreedItems, 641 652 '.'), 642 strhThousandsDouble(szFreedBytes,653 nlsThousandsDouble(szFreedBytes, 643 654 ulFreedBytes, 644 655 '.'), 645 strhThousandsDouble(szReleasedItems,656 nlsThousandsDouble(szReleasedItems, 646 657 G_ulItemsReleased, 647 658 '.'), 648 strhThousandsDouble(szReleasedBytes,659 nlsThousandsDouble(szReleasedBytes, 649 660 G_ulBytesReleased, 650 661 '.')); -
trunk/src/helpers/stringh.c
r122 r123 42 42 43 43 #define INCL_WINSHELLDATA 44 #define INCL_DOSERRORS 44 45 #include <os2.h> 45 46 … … 68 69 */ 69 70 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 80 APIRET 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 70 118 /* 71 119 *@@ strhStore: … … 81 129 */ 82 130 83 VOIDstrhStore(PSZ *ppszTarget,84 PCSZ pcszSource,85 PULONG pulLength) // out: length of new string (ptr can be NULL)131 APIRET strhStore(PSZ *ppszTarget, 132 PCSZ pcszSource, 133 PULONG pulLength) // out: length of new string (ptr can be NULL) 86 134 { 87 135 ULONG ulLength = 0; … … 98 146 if (*ppszTarget = (PSZ)malloc(ulLength + 1)) 99 147 memcpy(*ppszTarget, pcszSource, ulLength + 1); 148 else 149 return (ERROR_NOT_ENOUGH_MEMORY); 100 150 } 101 151 else … … 105 155 if (pulLength) 106 156 *pulLength = ulLength; 157 158 return (NO_ERROR); 107 159 } 108 160 … … 127 179 128 180 /* 129 *@@ strhdup :181 *@@ strhdupDebug: 130 182 * memory debug version of strhdup. 131 183 * … … 133 185 */ 134 186 135 PSZ strhdupDebug(const char *p szSource,187 PSZ strhdupDebug(const char *pcszSource, 136 188 unsigned long *pulLength, 137 189 const char *pcszSourceFile, … … 147 199 { 148 200 if (pszReturn = (PSZ)memdMalloc(ulLength + 1, 149 pcszSourceFile, 201 pcszSourceFile, // fixed V0.9.16 (2001-12-08) [umoeller] 150 202 ulLine, 151 203 pcszFunction)) -
trunk/src/helpers/threads.c
r116 r123 40 40 // as unsigned char 41 41 42 #define INCL_WINMESSAGEMGR 42 43 #define INCL_DOSPROCESS 43 44 #define INCL_DOSSEMAPHORES … … 130 131 if (pti) 131 132 { 133 HEV hevExitComplete; 134 132 135 if (pti->flFlags & THRF_WAIT) 133 136 // "Wait" flag set: thrCreate is then … … 168 171 } 169 172 173 // copy event sem before freeing pti 174 hevExitComplete = pti->hevExitComplete; 175 170 176 // set exit flags 171 177 // V0.9.7 (2000-12-20) [umoeller] 172 pti->fExitComplete = TRUE;173 178 pti->tid = NULLHANDLE; 174 179 … … 180 185 if (pti->flFlags & THRF_TRANSIENT) 181 186 free(pti); 187 188 if (hevExitComplete) 189 // caller wants notification: 190 DosPostEventSem(hevExitComplete); 191 // V0.9.16 (2001-12-08) [umoeller] 182 192 } 183 193 … … 394 404 *@@added V0.9.5 (2000-08-26) [umoeller] 395 405 *@@changed V0.9.9 (2001-03-07) [umoeller]: added pcszThreadName 406 *@@changed V0.9.16 (2001-12-08) [umoeller]: fixed hang with thrWait 396 407 */ 397 408 … … 417 428 { 418 429 THREADINFO ti = {0}; 430 volatile unsigned long tidRunning = 0; 419 431 thrCreate(&ti, 420 432 pfn, 421 NULL,433 &tidRunning, 422 434 pcszThreadName, 423 435 THRF_PMMSGQUEUE, 424 436 ulData); 425 437 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 426 443 427 444 while (WinGetMsg(hab, … … 445 462 // otherwise THREADINFO is deleted from the stack 446 463 // 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); 448 468 449 469 WinDestroyWindow(hwndNotify); … … 481 501 PLISTNODE pNode; 482 502 *pcThreads = lstCountItems(&G_llThreadInfos); 483 _Pmpf((__FUNCTION__ ": got %d threads", *pcThreads));484 503 pArray = (PTHREADINFO)malloc(*pcThreads * sizeof(THREADINFO)); 485 504 pThis = pArray; … … 561 580 * the thread will actually terminate. 562 581 * 582 * Update V0.9.16: Do not use this with PM theads at 583 * all. DosWaitThread can hang the system then. 584 * 563 585 * Returns FALSE if the thread wasn't running or TRUE 564 586 * if it was and has terminated. … … 631 653 { 632 654 if (pti) 633 if (!(pti->fExitComplete)) 634 return (pti->tid); 655 return (pti->tid); 635 656 636 657 return (NULLHANDLE); -
trunk/src/helpers/timer.c
r93 r123 540 540 // window still valid: 541 541 // 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); */ 544 545 545 546 // moved this up V0.9.14 (2001-08-01) [umoeller] … … 547 548 548 549 // 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, 550 561 WM_TIMER, 551 562 (MPARAM)pTimer->usTimerID, 552 0); 563 0); */ 553 564 // V0.9.12 (2001-05-24) [umoeller] 554 565 // if the winproc chooses to start or
Note:
See TracChangeset
for help on using the changeset viewer.