source: trunk/dll/makelist.c

Last change on this file was 1916, checked in by Gregg Young, 3 days ago

Fix easize so that EAs larger than 32767 show their actual size instead of 32767

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 8.3 KB
RevLine 
[51]1
2/***********************************************************************
3
4 $Id: makelist.c 1916 2025-11-01 18:30:47Z gyoung $
5
6 Make file lists
7
8 Copyright (c) 1993-98 M. Kimes
[907]9 Copyright (c) 2003, 2008 Steven H.Levine
[51]10
[361]11 12 Feb 03 SHL AddToFileList: standardize EA math
12 22 Jul 06 SHL Use Runtime_Error
13 22 Jul 06 SHL AddToList optimize
[603]14 06 Apr 07 GKY Work around PM DragInfo and DrgFreeDISH limits
[793]15 20 Aug 07 GKY Move #pragma alloc_text to end for OpenWatcom compat
[985]16 29 Feb 08 GKY Use xfree where appropriate
[1077]17 17 Jul 08 SHL Add SetListOwner for Fortify support
[1570]18 12 Jun 11 GKY Added IdleIfNeeded to the freelist loop to improve system
19 responsiveness when freeing lists with large numbers of items
[51]20
21***********************************************************************/
[361]22
[907]23#include <stdlib.h>
24#include <string.h>
25
[2]26#define INCL_DOS
27#define INCL_WIN
[841]28#define INCL_LONGLONG
[2]29
[1210]30#include "fm3dll.h" // 05 Jan 08 SHL fixme to be gone
[361]31#include "fm3str.h"
[907]32#include "makelist.h"
33#include "errutil.h" // Dos_Error...
34#include "strutil.h" // GetPString
35#include "dircnrs.h"
[1185]36#include "misc.h" // CurrentRecord
[1210]37#include "newview.h" // Data declarations
[1185]38#include "wrappers.h" // xfree
[1009]39#include "fortify.h" // 06 May 08 SHL
[1570]40#include "tmrsvcs.h" // ITIMER_DESC
[1916]41#include "eas.h" // GetLargeEASize
[1009]42
[361]43static PSZ pszSrcFile = __FILE__;
44
[907]45VOID SortList(LISTINFO *li)
[361]46{
[1673]47 // bubble-sort entries by size, descending
[2]48
[907]49 UINT x;
[2]50 CHAR *s;
51 ULONG l;
[551]52 BOOL swapped;
[2]53
[551]54 if (li && li->list && li->list[0] && li->cbFile) {
[2]55 do {
56 swapped = FALSE;
[551]57 for (x = 0; li->list[x] && li->list[x + 1]; x++) {
58 if (li->cbFile[x] < li->cbFile[x + 1]) {
59 s = li->list[x];
60 li->list[x] = li->list[x + 1];
61 li->list[x + 1] = s;
62 l = li->cbFile[x];
63 li->cbFile[x] = li->cbFile[x + 1];
64 li->cbFile[x + 1] = l;
65 if (li->ulitemID) {
66 l = li->ulitemID[x];
67 li->ulitemID[x] = li->ulitemID[x + 1];
68 li->ulitemID[x + 1] = l;
69 }
70 swapped = TRUE;
71 }
[2]72 }
[551]73 } while (swapped);
[2]74 }
75}
76
[907]77VOID FreeListInfo(LISTINFO *li)
[361]78{
[551]79 if (li) {
[1009]80 xfree(li->ulitemID, pszSrcFile, __LINE__);
81 xfree(li->cbFile, pszSrcFile, __LINE__);
[551]82 if (li->list)
[2]83 FreeList(li->list);
[1039]84 free(li);
[2]85 }
86}
87
[907]88VOID FreeList(CHAR **list)
[361]89{
[907]90 UINT x;
[1570]91 ITIMER_DESC itdSleep = { 0 };
92
[551]93 if (list) {
[1570]94 InitITimer(&itdSleep, 500);
[551]95 for (x = 0; list[x]; x++) {
[2]96#ifdef __DEBUG_ALLOC__
[551]97 _heap_check();
[2]98#endif
99 free(list[x]);
[1570]100 if (!IdleIfNeeded(&itdSleep, 30)) {
101 for (x = x + 1; list[x]; x++) {
102 free(list[x]);
103 }
104 break;
105 }
[2]106 }
107#ifdef __DEBUG_ALLOC__
[551]108 _heap_check();
[2]109#endif
[1039]110 free(list);
[1570]111 priority_normal();
112 DosPostEventSem(CompactSem);
[2]113 }
114}
115
[907]116INT AddToFileList(CHAR *string, FILEFINDBUF4L *ffb4, FILELIST ***list,
117 UINT *pnumfiles, UINT *pnumalloced)
[51]118{
[361]119 FILELIST *pfl;
[551]120
[361]121 if (string && ffb4) {
[772]122 // Ensure room for NULL entry
[907]123 if (((*pnumfiles) + 3) > *pnumalloced) {
[361]124 FILELIST **pflArray;
[551]125
[361]126 // Use plain realloc for speed
[772]127 // 06 Aug 07 SHL fixme to know why + 6
[1063]128# ifdef FORTIFY
129 Fortify_EnterScope();
130# endif
[907]131 pflArray = realloc(*list, (*pnumalloced + 6) * sizeof(FILELIST *));
[361]132 if (!pflArray) {
[551]133 Runtime_Error(pszSrcFile, __LINE__, GetPString(IDS_OUTOFMEMORY));
134 return 1;
[361]135 }
[907]136 (*pnumalloced) += 6;
[361]137 *list = pflArray;
[2]138 }
[361]139 // Use plain malloc for speed
140 pfl = malloc(sizeof(FILELIST) + strlen(string));
141 if (!pfl) {
[551]142 Runtime_Error(pszSrcFile, __LINE__, GetPString(IDS_OUTOFMEMORY));
[2]143 return 2;
[361]144 }
145 pfl->attrFile = ffb4->attrFile;
146 pfl->date = ffb4->fdateLastWrite;
147 pfl->time = ffb4->ftimeLastWrite;
148 pfl->ladate = ffb4->fdateLastAccess;
149 pfl->latime = ffb4->ftimeLastAccess;
150 pfl->crdate = ffb4->fdateCreation;
151 pfl->crtime = ffb4->ftimeCreation;
152 pfl->cbFile = ffb4->cbFile;
[1916]153 //Need to account for snapshot file but since cbList is a ulong and will always be even the fact they can exceed
154 //65535 doesn't matter. 31 Oct 25 GKY
155 pfl->easize = ffb4->cbList == 65535 ? GetLargeEASize(ffb4->achName) : CBLIST_TO_EASIZE(ffb4->cbList);
[551]156 strcpy(pfl->fname, string);
[907]157 (*list)[*pnumfiles] = pfl;
158 (*pnumfiles)++;
[772]159 // Ensure list always ends with two NULL entries
160 // 06 Aug 07 SHL fixme to know why
[907]161 (*list)[*pnumfiles] = NULL;
162 (*list)[(*pnumfiles) + 1] = NULL;
[2]163#ifdef __DEBUG_ALLOC__
164 _heap_check();
165#endif
166 }
167 return 0;
168}
169
[773]170/**
171 * Add string to string list
172 * Enlarges as needed
173 * Ensures 2 NULL end markers exist
174 */
175
[907]176INT AddToList(CHAR *string, CHAR ***list, UINT *pnumfiles, UINT *pnumalloced)
[361]177{
178 CHAR **ppsz;
179 PSZ psz;
[2]180
[361]181 if (string) {
[907]182 if (((*pnumfiles) + 3) > *pnumalloced) {
[361]183 // Use plain realloc for speed
[1063]184# ifdef FORTIFY
185 Fortify_EnterScope();
186# endif
[907]187 ppsz = realloc(*list, (*pnumalloced + 6) * sizeof(CHAR *));
[361]188 if (!ppsz) {
[551]189 Runtime_Error(pszSrcFile, __LINE__, "realloc");
190 return 1;
[361]191 }
[907]192 (*pnumalloced) += 6;
[361]193 *list = ppsz;
[2]194 }
[361]195 // Use plain malloc for speed
196 psz = malloc(strlen(string) + 1);
197 if (!psz) {
[551]198 Runtime_Error(pszSrcFile, __LINE__, GetPString(IDS_OUTOFMEMORY));
[2]199 return 2;
[361]200 }
[907]201 (*list)[*pnumfiles] = psz;
202 strcpy((*list)[*pnumfiles], string); // Add entry
203 (*pnumfiles)++;
204 (*list)[*pnumfiles] = NULL; // Add end marker
205 (*list)[(*pnumfiles) + 1] = NULL; // Add 2nd end marker - fixme to know why?
[2]206#ifdef __DEBUG_ALLOC__
207 _heap_check();
208#endif
209 }
210 return 0;
211}
212
[551]213CHAR **BuildList(HWND hwndCnr)
[361]214{
[2]215 PCNRITEM pci;
[551]216 CHAR **list = NULL, **test;
[907]217 UINT numfiles = 0, numalloc = 0;
218 INT error = 0, attribute = CRA_CURSORED;
[2]219
[551]220 pci = (PCNRITEM) CurrentRecord(hwndCnr);
221 if (pci && (INT) pci != -1 && !(pci->flags & RECFLAGS_ENV)) {
222 if (pci->rc.flRecordAttr & CRA_SELECTED) {
[2]223 attribute = CRA_SELECTED;
[551]224 pci = WinSendMsg(hwndCnr, CM_QUERYRECORDEMPHASIS, MPFROMLONG(CMA_FIRST),
225 MPFROMSHORT(attribute));
[2]226 }
227 }
[551]228 while (pci && (INT) pci != -1 && !error) {
[361]229 if (!(pci->rc.flRecordAttr & CRA_FILTERED))
[730]230 error = AddToList(pci->pszFileName, &list, &numfiles, &numalloc);
[551]231 pci = WinSendMsg(hwndCnr, CM_QUERYRECORDEMPHASIS, MPFROMP(pci),
232 MPFROMSHORT(attribute));
[2]233 }
[361]234 if (numalloc > numfiles + 1) {
235 // Use plain realloc for speed
[1029]236
[1063]237# ifdef FORTIFY
238 Fortify_EnterScope();
239# endif
[551]240 test = realloc(list, sizeof(CHAR *) * (numfiles + 1));
[361]241 if (!test)
[551]242 Runtime_Error(pszSrcFile, __LINE__, GetPString(IDS_OUTOFMEMORY));
[361]243 else
[2]244 list = test;
[773]245 } // while
[2]246 return list;
247}
248
[551]249CHAR **BuildArcList(HWND hwndCnr)
[361]250{
[2]251 PARCITEM pai;
[551]252 CHAR **list = NULL;
[907]253 UINT numfiles = 0, numalloc = 0;
254 INT error = 0, attribute = CRA_CURSORED;
[2]255
[551]256 pai = (PARCITEM) CurrentRecord(hwndCnr);
257 if (pai && (INT) pai != -1) {
258 if (pai->rc.flRecordAttr & CRA_SELECTED) {
[2]259 attribute = CRA_SELECTED;
[551]260 pai = WinSendMsg(hwndCnr, CM_QUERYRECORDEMPHASIS, MPFROMLONG(CMA_FIRST),
261 MPFROMSHORT(attribute));
[2]262 }
263 }
[551]264 while (pai && (INT) pai != -1 && !error) {
265 if (!(pai->rc.flRecordAttr & CRA_FILTERED))
[730]266 error = AddToList(pai->pszFileName, &list, &numfiles, &numalloc);
[551]267 pai = WinSendMsg(hwndCnr, CM_QUERYRECORDEMPHASIS, MPFROMP(pai),
268 MPFROMSHORT(attribute));
[2]269 }
270 return list;
271}
272
[907]273CHAR **RemoveFromList(CHAR **list, CHAR *item)
[361]274{
[907]275 UINT x, y;
[2]276
[551]277 if (list && list[0] && item) {
278 for (x = 0; list[x]; x++) {
279 if (item == list[x]) {
[1077]280 free(list[x]);
[551]281 list[x] = NULL;
282 for (y = x;; y++) {
283 if (y != x && !list[y])
284 break;
285 list[y] = list[y + 1];
286 }
287 if (!list[0]) {
288 FreeList(list);
289 list = NULL;
290 }
[1063]291# ifdef FORTIFY
[1077]292 Fortify_LeaveScope();
[1063]293# endif
[551]294 break;
[2]295 }
296 }
297 }
298 return list;
299}
300
[907]301CHAR **CombineLists(CHAR **prime, CHAR **add)
[361]302{
[907]303 UINT x;
304 UINT numalloc, numfiles = 0;
[2]305
[551]306 if (add && add[0]) {
307 if (prime) {
308 for (x = 0; prime[x]; x++)
309 numfiles++;
[2]310 }
311 numalloc = numfiles;
[551]312 for (x = 0; add[x]; x++) {
313 if (*add[x])
314 AddToList(add[x], &prime, &numfiles, &numalloc);
[2]315 }
316 FreeList(add);
317 }
318 return prime;
319}
[793]320
[1077]321#ifdef FORTIFY
322
323VOID SetListOwner(LISTINFO *li)
324{
325 if (li) {
326 CHAR **list = li->list;
327 if (list) {
328 UINT x;
329 for (x = 0; list[x]; x++)
[1078]330 Fortify_BecomeOwner(list[x]);
[1077]331 }
[1078]332 Fortify_BecomeOwner(li);
[1077]333 }
334}
335
336#endif // FORTIFY
337
[793]338#pragma alloc_text(MAKELIST,AddToList,AddToFileList,BuildList,FreeListInfo,FreeList)
339#pragma alloc_text(MAKELIST,SortList,BuildArcList,RemoveFromList,CombineLists)
[1077]340#ifdef FORTIFY
341#pragma alloc_text(MAKELIST,SetListOwner)
342#endif // FORTIFY
Note: See TracBrowser for help on using the repository browser.