source: trunk/dll/eas.c

Last change on this file was 1877, checked in by Gregg Young, 10 years ago

Remove debug code

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 39.4 KB
Line 
1
2/***********************************************************************
3
4 $Id: eas.c 1877 2015-10-11 21:43:27Z gyoung $
5
6 Display/edit EAs
7
8 Copyright (c) 1993-98 M. Kimes
9 Copyright (c) 2004, 2014 Steven H. Levine
10
11 01 Aug 04 SHL Rework lstrip/rstrip usage
12 06 Jun 05 SHL Indent -i2
13 06 Jun 05 SHL Rework DisplayEAsProc for VAC3.65 compat
14 06 Jun 05 SHL Drop unused variables
15 17 Jul 06 SHL Use Runtime_Error
16 22 Mar 07 GKY Use QWL_USER
17 05 Jul 07 SHL GetFileEAs: avoid heap corruption
18 15 Jul 07 GKY Allow subject edit of up to 256 chars
19 03 Aug 07 GKY Remove surrious error message
20 06 Aug 07 GKY Increase Subject EA to 1024
21 20 Aug 07 GKY Move #pragma alloc_text to end for OpenWatcom compat
22 01 Sep 07 GKY Use xDosSetPathInfo to fix case where FS3 buffer crosses 64k boundry
23 29 Feb 08 GKY Use xfree where appropriate
24 07 Feb 09 GKY Allow user to turn off alert and/or error beeps in settings notebook.
25 12 Jul 09 GKY Add xDosQueryAppType and xDosAlloc... to allow FM/2 to load in high memory
26 17 JAN 10 GKY Changes to get working with Watcom 1.9 Beta (1/16/10). Mostly cast CHAR CONSTANT * as CHAR *.
27 23 Oct 10 GKY Added button to allow opening of a new file's eas from the EA dialog.
28 26 Aug 11 GKY Add a low mem version of xDosAlloc* wrappers; move error checking into all the
29 xDosAlloc* wrappers.
30 10 Feb 14 SHL DisplayEAsProc: Indicate if EA is critical, avoid rewrites if no change
31 10 Feb 14 SHL SaveEA: Avoid rewrites if no change
32
33***********************************************************************/
34
35#include <stdlib.h>
36#include <stdio.h>
37#include <string.h>
38#include <ctype.h>
39
40#define INCL_WIN
41#define INCL_DOS
42#define INCL_DOSERRORS
43#define INCL_LONGLONG
44
45#include "fm3dll.h"
46#include "fm3dll2.h" // #define's for UM_*, control id's, etc.
47#include "notebook.h" // Data declaration(s)
48#include "info.h" // Data declaration(s)
49#include "init.h" // Data declaration(s)
50#include "mainwnd.h" // Data declaration(s)
51#include "newview.h" // Data declarations
52#include "fm3dlg.h"
53#include "fm3str.h"
54#include "mle.h"
55#include "errutil.h" // Dos_Error...
56#include "strutil.h" // GetPString
57#include "defview.h" // QuickView
58#include "subj.h" // Subject
59#include "wrappers.h" // xDosSetPathInfo
60#include "eas.h"
61#include "strips.h" // bstrip
62#include "valid.h" // IsFile
63#include "misc.h" // PaintRecessedWindow
64#include "fortify.h"
65#include "getnames.h" // insert_filename
66#include "pathutil.h" // ForwardslashToBackslash
67
68#pragma data_seg(DATA1)
69
70static PSZ pszSrcFile = __FILE__;
71
72static PVOID SaveEA(CHAR *filename, HOLDFEA *current, CHAR *newdata,
73 BOOL silentfail);
74
75typedef struct
76{
77 CHAR *name;
78 INT type;
79}
80RESERVEDEAS;
81
82typedef struct
83{
84 CHAR *filename;
85 HOLDFEA *head;
86}
87ADDEA;
88
89HOLDFEA *CheckEA(HOLDFEA * head, CHAR * eaname)
90{
91 // return pointer to ea named eaname if found in linked list
92
93 register HOLDFEA *info = NULL;
94
95 if (eaname && *eaname) {
96 info = head;
97 while (info) {
98 if (!strcmp(info->name, eaname))
99 return info;
100 info = info->next;
101 }
102 }
103 return info;
104}
105
106MRESULT EXPENTRY AddEAProc(HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2)
107{
108 ADDEA *add;
109 HOLDFEA *head;
110 CHAR *filename;
111 static CHAR *forbidden[] = { ".ASSOCTABLE",
112 ".CLASSINFO",
113 ".ICON",
114 ".CODEPAGE",
115 ""
116 };
117 static RESERVEDEAS restypes[] = { ".TYPE", EAT_MVMT,
118 ".SUBJECT", EAT_ASCII,
119 ".COMMENTS", EAT_MVMT,
120 ".KEYPHRASES", EAT_MVMT,
121 ".HISTORY", EAT_MVMT,
122 ".LONGNAME", EAT_ASCII,
123 ".VERSION", EAT_ASCII,
124 "", 0
125 };
126
127 switch (msg) {
128 case WM_INITDLG:
129 if (!mp2) {
130 WinDismissDlg(hwnd, 0);
131 break;
132 }
133 WinSetWindowPtr(hwnd, QWL_USER, (PVOID) mp2);
134 WinSendDlgItemMsg(hwnd, EAC_NAME, EM_SETTEXTLIMIT,
135 MPFROM2SHORT(1024, 0), MPVOID);
136 WinCheckButton(hwnd, EAC_ASCII, TRUE);
137 break;
138
139 case WM_PAINT:
140 PostMsg(hwnd, UM_PAINT, MPVOID, MPVOID);
141 break;
142
143 case UM_PAINT:
144 PaintRecessedWindow(WinWindowFromID(hwnd, EAC_TEXT), (HPS) 0, FALSE,
145 FALSE);
146 return 0;
147
148 case WM_CONTROL:
149 return 0;
150
151 case WM_COMMAND:
152 switch (SHORT1FROMMP(mp1)) {
153 case DID_OK:
154 add = INSTDATA(hwnd);
155 head = add->head;
156 filename = add->filename;
157 {
158 CHAR s[1025];
159 INT x;
160 USHORT type = EAT_ASCII;
161
162 *s = 0;
163 WinQueryDlgItemText(hwnd, EAC_NAME, 1024, s);
164 bstrip(s);
165 if (!*s)
166 WinDismissDlg(hwnd, 0);
167 else {
168 if (CheckEA(head, s)) {
169 if (!fAlertBeepOff)
170 DosBeep(50, 100);
171 WinSetDlgItemText(hwnd, EAC_TEXT,
172 (CHAR *)GetPString(IDS_EANAMEEXISTSTEXT));
173 break;
174 }
175 for (x = 0; *forbidden[x]; x++) {
176 if (!strcmp(forbidden[x], s)) {
177 if (!fAlertBeepOff)
178 DosBeep(50, 100);
179 WinSetDlgItemText(hwnd, EAC_TEXT,
180 (CHAR *)GetPString(IDS_EANAMERESERVEDTEXT));
181 return 0;
182 }
183 }
184 if (WinQueryButtonCheckstate(hwnd, EAC_MVST))
185 type = EAT_MVST;
186 else if (WinQueryButtonCheckstate(hwnd, EAC_MVMT))
187 type = EAT_MVMT;
188 for (x = 0; *restypes[x].name; x++) {
189 if (!strcmp(restypes[x].name, s)) {
190 if (type != restypes[x].type) {
191 if (!fAlertBeepOff)
192 DosBeep(50, 100);
193 WinSetDlgItemText(hwnd, EAC_TEXT,
194 (CHAR *)GetPString(IDS_EAWRONGTYPETEXT));
195 return 0;
196 }
197 break;
198 }
199 }
200 // if we get here, create dummy ea
201 {
202 PFEA2LIST pfealist = NULL;
203 EAOP2 eaop;
204 ULONG ealen;
205 CHAR *eaval;
206
207 ealen = sizeof(FEA2LIST) + strlen(s) + 64;
208 if (!xDosAllocMem((PPVOID) & pfealist, ealen + 1, pszSrcFile, __LINE__)) {
209 memset(pfealist, 0, ealen + 1);
210 pfealist->cbList = ealen;
211 pfealist->list[0].oNextEntryOffset = 0;
212 pfealist->list[0].fEA = 0;
213 pfealist->list[0].cbName = strlen(s);
214 strcpy(pfealist->list[0].szName, s);
215 eaval = pfealist->list[0].szName + strlen(s) + 1;
216 *(USHORT *)eaval = (USHORT)type;
217 eaval += sizeof(USHORT);
218 if (type == EAT_MVST || type == EAT_MVMT) {
219 *(USHORT *)eaval = (USHORT) 0; // codepage
220 eaval += sizeof(USHORT);
221 *(USHORT *)eaval = (USHORT)1; // number
222 eaval += sizeof(USHORT);
223 *(USHORT *)eaval = (USHORT)EAT_ASCII; // type
224 eaval += sizeof(USHORT);
225 }
226 *(USHORT *)eaval = (USHORT)4;
227 eaval += sizeof(USHORT);
228 memcpy(eaval, GetPString(IDS_FAKETEXT), 4);
229 pfealist->list[0].cbValue = 4 + (sizeof(USHORT) * 2) +
230 ((type == EAT_MVST ||
231 type == EAT_MVMT) ? sizeof(USHORT) * 3 : 0);
232 eaop.fpGEA2List = (PGEA2LIST) 0;
233 eaop.fpFEA2List = pfealist;
234 eaop.oError = 0;
235 xDosSetPathInfo(filename, FIL_QUERYEASIZE,
236 &eaop, sizeof(eaop), DSPI_WRTTHRU);
237 WinDismissDlg(hwnd, 1);
238 }
239 }
240 }
241 }
242 break;
243
244 case DID_CANCEL:
245 WinDismissDlg(hwnd, 0);
246 break;
247
248 case IDM_HELP:
249 if (hwndHelp)
250 WinSendMsg(hwndHelp, HM_DISPLAY_HELP,
251 MPFROM2SHORT(HELP_ADDEA, 0), MPFROMSHORT(HM_RESOURCEID));
252 break;
253 }
254 return 0;
255 }
256 return WinDefDlgProc(hwnd, msg, mp1, mp2);
257}
258
259static VOID HexDumpEA(HWND hwnd, HOLDFEA * info)
260{
261 if (info)
262 HexDump(WinWindowFromID(hwnd, EA_HEXDUMP), info->value, info->cbValue);
263}
264
265VOID HexDump(HWND hwnd, CHAR * value, ULONG cbValue)
266{
267 // display a hexdump of a binary 'string' in listbox hwnd
268
269 CHAR s[132];
270 register CHAR *p, *pp, *a;
271 register ULONG x = 0, y, z;
272
273 WinSendMsg(hwnd, LM_DELETEALL, MPVOID, MPVOID);
274 if (cbValue) {
275 pp = p = value;
276 while (x < cbValue) {
277 y = x;
278 sprintf(s, "%04lx ", x);
279 a = s + 6;
280 do {
281 sprintf(a, "%02x ", (UCHAR)*p);
282 a += 3;
283 p++;
284 x++;
285 }
286 while (x < cbValue && (x % 16));
287 if (x % 16) {
288 z = x;
289 while (z % 16) {
290 *a++ = ' ';
291 *a++ = ' ';
292 *a++ = ' ';
293 z++;
294 }
295 }
296 *a++ = ' ';
297 p = pp;
298 do {
299 if (*p)
300 *a++ = *p++;
301 else {
302 *a++ = '.';
303 p++;
304 }
305 *a = 0;
306 y++;
307 }
308 while (y < x);
309 if ((SHORT) WinSendMsg(hwnd, LM_INSERTITEM, MPFROM2SHORT(LIT_END, 0),
310 MPFROMP(s)) < 0)
311 break;
312 pp = p;
313 }
314 }
315}
316
317typedef struct
318{
319 USHORT size;
320 USHORT flags;
321 HOLDFEA *head, *current;
322 CHAR **list;
323 CHAR filename[CCHMAXPATH];
324}
325EAPROCDATA;
326
327MRESULT EXPENTRY DisplayEAsProc(HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2)
328{
329 EAPROCDATA *eap;
330 HOLDFEA *info;
331 CHAR str[81];
332
333 static HPOINTER hptrIcon = (HPOINTER) 0;
334
335 if (msg != WM_INITDLG)
336 eap = (EAPROCDATA *) WinQueryWindowPtr(hwnd, QWL_USER);
337
338 switch (msg) {
339 case WM_INITDLG:
340 if (!mp2) {
341 WinDismissDlg(hwnd, 0);
342 break;
343 }
344 eap = xmallocz(sizeof(EAPROCDATA), pszSrcFile, __LINE__);
345 if (!eap) {
346 WinDismissDlg(hwnd, 0);
347 break;
348 }
349 hptrIcon = WinLoadPointer(HWND_DESKTOP, FM3ModHandle, EA_FRAME);
350 WinDefDlgProc(hwnd, WM_SETICON, MPFROMLONG(hptrIcon), MPVOID);
351 eap->size = sizeof(EAPROCDATA);
352 eap->list = (CHAR **) mp2;
353 WinSetWindowPtr(hwnd, QWL_USER, (PVOID) eap);
354 WinSendDlgItemMsg(hwnd,
355 EA_ENTRY, EM_SETTEXTLIMIT, MPFROM2SHORT(40, 0), MPVOID);
356 MLEsetlimit(WinWindowFromID(hwnd, EA_MLE), 32767);
357 MLEsetformat(WinWindowFromID(hwnd, EA_MLE), MLFIE_NOTRANS);
358 {
359 INT x;
360 SHORT sSelect;
361 CHAR s[CCHMAXPATH];
362
363 for (x = 0; eap->list[x]; x++) {
364 if (DosQueryPathInfo(eap->list[x], FIL_QUERYFULLNAME, s, sizeof(s)))
365 strcpy(s, eap->list[x]);
366 if (IsFile(s) != -1)
367 WinSendDlgItemMsg(hwnd,
368 EA_NAMES,
369 LM_INSERTITEM,
370 MPFROM2SHORT(LIT_SORTASCENDING, 0), MPFROMP(s));
371 }
372 sSelect = (SHORT) WinSendDlgItemMsg(hwnd,
373 EA_NAMES,
374 LM_QUERYITEMCOUNT, MPVOID, MPVOID);
375 if (sSelect > 0)
376 WinSendDlgItemMsg(hwnd,
377 EA_NAMES,
378 LM_SELECTITEM,
379 MPFROM2SHORT(0, 0), MPFROMSHORT(TRUE));
380 else
381 WinDismissDlg(hwnd, 0);
382 }
383 break;
384
385 case UM_SETDIR:
386 if (*eap->filename) {
387 if (eap->head)
388 Free_FEAList(eap->head);
389 eap->head = GetFileEAs(eap->filename, FALSE, FALSE);
390 if (!isalpha(*eap->filename) ||
391 (driveflags[toupper(*eap->filename) - 'A'] & DRIVE_NOTWRITEABLE)) {
392 WinEnableWindow(WinWindowFromID(hwnd, EA_CHANGE), FALSE);
393 WinEnableWindow(WinWindowFromID(hwnd, EA_ADD), FALSE);
394 WinEnableWindow(WinWindowFromID(hwnd, EA_DELETE), FALSE);
395 }
396 else {
397 WinEnableWindow(WinWindowFromID(hwnd, EA_CHANGE), TRUE);
398 WinEnableWindow(WinWindowFromID(hwnd, EA_ADD), TRUE);
399 WinEnableWindow(WinWindowFromID(hwnd, EA_DELETE), TRUE);
400 }
401 WinSendMsg(hwnd, UM_SETUP, MPVOID, MPVOID);
402 }
403 break;
404
405 case UM_SETUP:
406 WinSendDlgItemMsg(hwnd, EA_LISTBOX, LM_DELETEALL, MPVOID, MPVOID);
407 WinShowWindow(WinWindowFromID(hwnd, EA_ENTRY), FALSE);
408 WinSetDlgItemText(hwnd, EA_ENTRY, NullStr);
409 WinShowWindow(WinWindowFromID(hwnd, EA_MLE), FALSE);
410 MLEclearall(WinWindowFromID(hwnd, EA_MLE));
411 WinShowWindow(WinWindowFromID(hwnd, EA_HEXDUMP), FALSE);
412 WinSendDlgItemMsg(hwnd, EA_HEXDUMP, LM_DELETEALL, MPVOID, MPVOID);
413 WinShowWindow(WinWindowFromID(hwnd, EA_CHANGE), FALSE);
414 WinShowWindow(WinWindowFromID(hwnd, EA_DELETE), FALSE);
415 eap->current = NULL;
416 if (eap->head) {
417 WinSetDlgItemText(hwnd, EA_TEXT, NullStr);
418 info = eap->head;
419 while (info) {
420 WinSendDlgItemMsg(hwnd, EA_LISTBOX, LM_INSERTITEM,
421 MPFROM2SHORT(LIT_END, 0), MPFROMP(info->name));
422 info = info->next;
423 }
424 WinSendDlgItemMsg(hwnd, EA_LISTBOX, LM_SELECTITEM,
425 MPFROM2SHORT(0, 0), MPFROM2SHORT(TRUE, 0));
426 }
427 else
428 WinSetDlgItemText(hwnd, EA_TEXT, (CHAR *)GetPString(IDS_EANOEAS));
429 return 0;
430
431 case WM_PAINT:
432 PostMsg(hwnd, UM_PAINT, MPVOID, MPVOID);
433 break;
434
435 case UM_PAINT:
436 PaintRecessedWindow(WinWindowFromID(hwnd, EA_HELP), (HPS) 0, FALSE, TRUE);
437 PaintRecessedWindow(WinWindowFromID(hwnd, EA_TEXT), (HPS) 0, FALSE,
438 FALSE);
439 return 0;
440
441 case WM_CONTROL:
442 switch (SHORT1FROMMP(mp1)) {
443 case EA_NAMES:
444 switch (SHORT2FROMMP(mp1)) {
445 case LN_SETFOCUS:
446 WinSetDlgItemText(hwnd, EA_HELP, (CHAR *)GetPString(IDS_EAFILENAMESHELPTEXT));
447 break;
448 case LN_KILLFOCUS:
449 WinSetDlgItemText(hwnd, EA_HELP, NullStr);
450 break;
451 case LN_ENTER:
452 case LN_SELECT:
453 {
454 CHAR s[1025];
455 SHORT sSelect;
456
457 sSelect = (SHORT) WinSendDlgItemMsg(hwnd, EA_NAMES,
458 LM_QUERYSELECTION,
459 MPFROM2SHORT(LIT_FIRST, 0),
460 MPVOID);
461 if (sSelect >= 0) {
462 *s = 0;
463 WinSendDlgItemMsg(hwnd, EA_NAMES, LM_QUERYITEMTEXT,
464 MPFROM2SHORT(sSelect, 1024), MPFROMP(s));
465 if (*s) {
466 strcpy(eap->filename, s);
467 if (SHORT2FROMMP(mp1) == LN_SELECT)
468 WinSendMsg(hwnd, UM_SETDIR, MPVOID, MPVOID);
469 else
470 QuickView(hwnd, eap->filename);
471 }
472 }
473 }
474 break;
475 }
476 break;
477
478 case EA_LISTBOX:
479 switch (SHORT2FROMMP(mp1)) {
480 case LN_SETFOCUS:
481 WinSetDlgItemText(hwnd, EA_HELP, (CHAR *)GetPString(IDS_EATYPESHELPTEXT));
482 break;
483 case LN_KILLFOCUS:
484 WinSetDlgItemText(hwnd, EA_HELP, NullStr);
485 break;
486 case LN_SELECT:
487 {
488 CHAR s[1024];
489 SHORT sSelect;
490
491 eap->current = NULL;
492 if (eap->head) {
493 WinSetDlgItemText(hwnd, EA_TEXT, NullStr);
494 WinShowWindow(WinWindowFromID(hwnd, EA_ENTRY), FALSE);
495 WinSetDlgItemText(hwnd, EA_ENTRY, NullStr);
496 MLEclearall(WinWindowFromID(hwnd, EA_MLE));
497 WinShowWindow(WinWindowFromID(hwnd, EA_MLE), FALSE);
498 WinShowWindow(WinWindowFromID(hwnd,EA_CHANGE), FALSE);
499 WinShowWindow(WinWindowFromID(hwnd, EA_DELETE), FALSE);
500 WinShowWindow(WinWindowFromID(hwnd, EA_HEXDUMP), FALSE);
501 WinSendDlgItemMsg(hwnd, EA_HEXDUMP, LM_DELETEALL, MPVOID, MPVOID);
502 *s = 0;
503 sSelect = (USHORT)WinSendDlgItemMsg(hwnd,
504 EA_LISTBOX,
505 LM_QUERYSELECTION,
506 MPFROMSHORT(LIT_FIRST),
507 MPVOID);
508 if (sSelect >= 0) {
509 WinSendDlgItemMsg(hwnd,
510 EA_LISTBOX,
511 LM_QUERYITEMTEXT,
512 MPFROM2SHORT(sSelect, 1024),
513 MPFROMP(s));
514 if (*s) {
515
516 USHORT len, num, type;
517 CHAR *data;
518 CHAR last = '\n';
519 const CHAR *linefeed = "\n";
520 BOOL alltext;
521 IPT pos = 0;
522
523 // Find selected EA and refresh details display
524 info = eap->head;
525 while (info) {
526 if (!strcmp(s, info->name)) {
527 // Found it
528 eap->current = info;
529 WinShowWindow(WinWindowFromID(hwnd, EA_DELETE), TRUE);
530 switch (*(USHORT *)info->value) {
531 case EAT_EA:
532 case EAT_ASCII:
533 if (!strcmp(info->name, SUBJECT))
534 WinSendDlgItemMsg(hwnd, EA_ENTRY,
535 EM_SETTEXTLIMIT,
536 MPFROM2SHORT(1024, 0), MPVOID);
537 else
538 WinSendDlgItemMsg(hwnd, EA_ENTRY,
539 EM_SETTEXTLIMIT,
540 MPFROM2SHORT(1024, 0), MPVOID);
541 WinSetDlgItemText(hwnd, EA_ENTRY,
542 info->value + (sizeof(USHORT) * 2));
543 WinShowWindow(WinWindowFromID(hwnd, EA_ENTRY), TRUE);
544 WinEnableWindow(WinWindowFromID(hwnd, EA_CHANGE),
545 FALSE);
546 WinShowWindow(WinWindowFromID(hwnd, EA_CHANGE), TRUE); // Allow edits
547 sprintf(str,
548 GetPString(IDS_DATAANDBYTESTEXT),
549 *(USHORT *)info->value == EAT_ASCII ?
550 GetPString(IDS_TEXTTEXT) :
551 GetPString(IDS_EAREFTEXT),
552 info->cbValue);
553 WinSetDlgItemText(hwnd, EA_TEXT, str);
554 break;
555 case EAT_MVST:
556 MLEclearall(WinWindowFromID(hwnd, EA_MLE));
557 num = *(USHORT *)(info->value + (sizeof(USHORT) * 2));
558 type = *(USHORT *)(info->value + (sizeof(USHORT) * 3));
559 if (type == EAT_ASCII) {
560 data = info->value + (sizeof(USHORT) * 4);
561 len = *(USHORT *)data;
562 data += sizeof(USHORT);
563 while ((data - info->value) + len <= info->cbValue) {
564 if (last != '\n') {
565 WinSendDlgItemMsg(hwnd,
566 EA_MLE,
567 MLM_SETIMPORTEXPORT,
568 MPFROMP(linefeed),
569 MPFROMLONG(1));
570 WinSendDlgItemMsg(hwnd,
571 EA_MLE,
572 MLM_IMPORT,
573 MPFROMP(&pos), MPFROMLONG(1));
574 }
575 WinSendDlgItemMsg(hwnd,
576 EA_MLE,
577 MLM_SETIMPORTEXPORT,
578 MPFROMP(data),
579 MPFROMLONG((ULONG) len));
580 WinSendDlgItemMsg(hwnd,
581 EA_MLE,
582 MLM_IMPORT,
583 MPFROMP(&pos),
584 MPFROMLONG((ULONG) len));
585 data += len;
586 last = *(data - 1);
587 if (data - info->value >= info->cbValue)
588 break;
589 len = *(USHORT *)data;
590 data += sizeof(USHORT);
591 }
592 WinShowWindow(WinWindowFromID(hwnd, EA_MLE), TRUE);
593 // Do not know how to edit
594 WinEnableWindow(WinWindowFromID(hwnd, EA_CHANGE),
595 FALSE);
596 WinShowWindow(WinWindowFromID(hwnd, EA_CHANGE), TRUE);
597 }
598 else {
599 WinShowWindow(WinWindowFromID(hwnd, EA_MLE), FALSE);
600 HexDumpEA(hwnd, info);
601 WinShowWindow(WinWindowFromID(hwnd, EA_HEXDUMP),
602 TRUE);
603 }
604 sprintf(str,
605 GetPString(IDS_MVSTTEXT),
606 num,
607 num == 1 ?
608 GetPString(IDS_YTEXT) :
609 GetPString(IDS_IESTEXT),
610 info->cbValue);
611 WinSetDlgItemText(hwnd, EA_TEXT, str);
612 break;
613 case EAT_MVMT:
614 MLEclearall(WinWindowFromID(hwnd, EA_MLE));
615 num = *(USHORT *)(info->value + (sizeof(USHORT) * 2));
616 data = info->value + (sizeof(USHORT) * 3);
617 type = *(USHORT *)data;
618 data += sizeof(USHORT);
619 len = *(USHORT *)data;
620 data += sizeof(USHORT);
621 alltext = TRUE;
622 while ((data - info->value) - len <= info->cbValue) {
623 if (type != EAT_ASCII) {
624 alltext = FALSE;
625 break;
626 }
627 data += len;
628 if (data - info->value >= info->cbValue)
629 break;
630 type = *(USHORT *)data;
631 data += sizeof(USHORT);
632 len = *(USHORT *)data;
633 data += sizeof(USHORT);
634 }
635 if (alltext) {
636 data = info->value + (sizeof(USHORT) * 3);
637 type = *(USHORT *)data;
638 data += sizeof(USHORT);
639 len = *(USHORT *)data;
640 data += sizeof(USHORT);
641 while ((data - info->value) - len <= info->cbValue) {
642 if (last != '\n') {
643 WinSendDlgItemMsg(hwnd,
644 EA_MLE,
645 MLM_SETIMPORTEXPORT,
646 MPFROMP(linefeed),
647 MPFROMLONG(1));
648 WinSendDlgItemMsg(hwnd,
649 EA_MLE,
650 MLM_IMPORT,
651 MPFROMP(&pos), MPFROMLONG(1));
652 }
653 WinSendDlgItemMsg(hwnd,
654 EA_MLE,
655 MLM_SETIMPORTEXPORT,
656 MPFROMP(data),
657 MPFROMLONG((ULONG) len));
658 WinSendDlgItemMsg(hwnd,
659 EA_MLE,
660 MLM_IMPORT,
661 MPFROMP(&pos),
662 MPFROMLONG((ULONG) len));
663 data += len;
664 last = *(data - 1);
665 if (data - info->value >= info->cbValue)
666 break;
667 type = *(USHORT *)data;
668 data += sizeof(USHORT);
669 len = *(USHORT *)data;
670 data += sizeof(USHORT);
671 }
672 }
673 if (alltext) {
674 WinShowWindow(WinWindowFromID(hwnd, EA_MLE), TRUE);
675 WinEnableWindow(WinWindowFromID(hwnd,
676 EA_CHANGE), FALSE);
677 WinShowWindow(WinWindowFromID(hwnd, EA_CHANGE), TRUE);
678 }
679 else {
680 WinShowWindow(WinWindowFromID(hwnd, EA_MLE), FALSE);
681 HexDumpEA(hwnd, info);
682 WinShowWindow(WinWindowFromID(hwnd, EA_HEXDUMP),
683 TRUE);
684 }
685 sprintf(str,
686 GetPString(IDS_MVMTTEXT),
687 num,
688 num == 1 ?
689 GetPString(IDS_YTEXT) :
690 GetPString(IDS_IESTEXT),
691 info->cbValue,
692 alltext ?
693 GetPString(IDS_ALLTEXTTEXT) :
694 GetPString(IDS_MIXEDTYPESTEXT));
695 WinSetDlgItemText(hwnd, EA_TEXT, str);
696 break;
697 default:
698 HexDumpEA(hwnd, info);
699 WinShowWindow(WinWindowFromID(hwnd, EA_HEXDUMP), TRUE);
700 switch (*(USHORT *)info->value) {
701 case EAT_BINARY:
702 sprintf(str,
703 GetPString(IDS_BINARYBYTESTEXT),
704 info->fEA ? GetPString(IDS_CRITICALEA) : "",
705 info->cbValue);
706 WinSetDlgItemText(hwnd, EA_TEXT, str);
707 break;
708 case EAT_BITMAP:
709 sprintf(str,
710 GetPString(IDS_BITMAPBYTESTEXT),
711 info->cbValue);
712 WinSetDlgItemText(hwnd, EA_TEXT, str);
713 break;
714 case EAT_METAFILE:
715 sprintf(str,
716 GetPString(IDS_METAFILEBYTESTEXT),
717 info->cbValue);
718 WinSetDlgItemText(hwnd, EA_TEXT, str);
719 break;
720 case EAT_ICON:
721 sprintf(str,
722 GetPString(IDS_ICONBYTESTEXT),
723 info->cbValue);
724 WinSetDlgItemText(hwnd, EA_TEXT, str);
725 break;
726 case EAT_ASN1:
727 sprintf(str,
728 GetPString(IDS_ASN1BYTESTEXT),
729 info->cbValue);
730 WinSetDlgItemText(hwnd, EA_TEXT, str);
731 break;
732 default:
733 sprintf(str,
734 GetPString(IDS_UNKNOWNBYTESTEXT),
735 *(USHORT *)info->value,
736 info->cbValue);
737 WinSetDlgItemText(hwnd, EA_TEXT, str);
738 break;
739 }
740 break;
741 } // switch EAT_...
742 } // if matched
743 info = info->next;
744 } // while
745 } // if have name
746 } // if have select
747 } // if have non-empty list
748
749 if (!isalpha(*eap->filename) ||
750 (driveflags[toupper(*eap->filename) - 'A'] &
751 DRIVE_NOTWRITEABLE)) {
752 WinEnableWindow(WinWindowFromID(hwnd, EA_CHANGE), FALSE);
753 WinEnableWindow(WinWindowFromID(hwnd, EA_ADD), FALSE);
754 WinEnableWindow(WinWindowFromID(hwnd, EA_DELETE), FALSE);
755 }
756 else {
757 WinEnableWindow(WinWindowFromID(hwnd, EA_CHANGE), TRUE);
758 WinEnableWindow(WinWindowFromID(hwnd, EA_ADD), TRUE);
759 WinEnableWindow(WinWindowFromID(hwnd, EA_DELETE), TRUE);
760 }
761 }
762 break;
763 }
764 break;
765
766 case EA_ENTRY:
767 switch (SHORT2FROMMP(mp1)) {
768 case EN_SETFOCUS:
769 WinSetDlgItemText(hwnd, EA_HELP, (CHAR *)GetPString(IDS_EADATAHELPTEXT));
770 break;
771 case EN_KILLFOCUS:
772 WinSetDlgItemText(hwnd, EA_HELP, NullStr);
773 break;
774 case EN_CHANGE:
775 WinEnableWindow(WinWindowFromID(hwnd, EA_CHANGE), TRUE);
776 break;
777 }
778 break;
779
780 case EA_HEXDUMP:
781 switch (SHORT2FROMMP(mp1)) {
782 case LN_SETFOCUS:
783 WinSetDlgItemText(hwnd, EA_HELP, (CHAR *)GetPString(IDS_EADATAHELPTEXT));
784 break;
785 case LN_KILLFOCUS:
786 WinSetDlgItemText(hwnd, EA_HELP, NullStr);
787 break;
788 }
789 break;
790
791 case EA_MLE:
792 switch (SHORT2FROMMP(mp1)) {
793 case MLN_SETFOCUS:
794 WinSetDlgItemText(hwnd, EA_HELP, (CHAR *)GetPString(IDS_EADATAHELPTEXT));
795 break;
796 case MLN_KILLFOCUS:
797 WinSetDlgItemText(hwnd, EA_HELP, NullStr);
798 break;
799 case MLN_CHANGE:
800 WinEnableWindow(WinWindowFromID(hwnd, EA_CHANGE), TRUE);
801 break;
802 }
803 break;
804 }
805 return 0;
806
807 case WM_COMMAND:
808 switch (SHORT1FROMMP(mp1)) {
809 case EA_OPENFILE:
810 {
811 CHAR filename[CCHMAXPATH];
812 CHAR *p;
813 CHAR **list = NULL;
814
815 if (*eap->filename)
816 strcpy(filename, eap->filename);
817 WinDismissDlg(hwnd, 1);
818 ForwardslashToBackslash(filename);
819 p = strrchr(filename, '\\');
820 if (p) {
821 p++;
822 *p = 0;
823 }
824 else
825 *filename = 0;
826 strcat(filename, "*");
827 list = xmalloc(sizeof(CHAR *) * 2, pszSrcFile, __LINE__);
828
829 if (list) {
830 if (insert_filename(HWND_DESKTOP,filename,TRUE,FALSE) &&
831 *filename && *filename != '*') {
832 list[0] = filename;
833 list[1] = NULL;
834 WinDlgBox(HWND_DESKTOP,
835 HWND_DESKTOP,
836 DisplayEAsProc,
837 FM3ModHandle,
838 EA_FRAME,
839 (PVOID)list);
840 }
841 else
842 free(list);
843 }
844 break;
845 }
846 case EA_ADD:
847 {
848 ADDEA add;
849
850 add.filename = eap->filename;
851 add.head = eap->head;
852 if (WinDlgBox(HWND_DESKTOP, hwnd, AddEAProc, FM3ModHandle,
853 EAC_FRAME, &add)) {
854 Free_FEAList(eap->head);
855 eap->head = GetFileEAs(eap->filename, FALSE, FALSE);
856 WinSendMsg(hwnd, UM_SETUP, MPVOID, MPVOID);
857 }
858 }
859 break;
860 case EA_CHANGE:
861 if (!eap->current)
862 WinShowWindow(WinWindowFromID(hwnd, EA_CHANGE), FALSE);
863 else {
864
865 CHAR *s;
866 USHORT control;
867
868 if (!eap->head || !*eap->filename)
869 Runtime_Error(pszSrcFile, __LINE__, NULL);
870 else {
871 switch (*(USHORT *)eap->current->value) {
872 case EAT_EA:
873 case EAT_ASCII:
874 control = EA_ENTRY;
875 break;
876 case EAT_MVMT:
877 control = EA_MLE;
878 break;
879 case EAT_MVST:
880 control = EA_MLE;
881 break;
882 default:
883 Runtime_Error(pszSrcFile, __LINE__, "unexpected type");
884 WinShowWindow(WinWindowFromID(hwnd, EA_CHANGE), FALSE);
885 control = 0;
886 }
887 if (control) {
888 s = xmalloc(32768, pszSrcFile, __LINE__);
889 if (s) {
890 *s = 0;
891 WinQueryDlgItemText(hwnd, control, 32767, (PCH) s);
892 if (!*s)
893 Runtime_Error(pszSrcFile, __LINE__, NULL);
894 else {
895 PFEA2LIST pfealist;
896
897 // FIXME to only rewrite if modified
898 pfealist = SaveEA(eap->filename, eap->current, s, FALSE);
899 if (!pfealist)
900 Runtime_Error(pszSrcFile, __LINE__, "SaveEA");
901 else {
902 // EA rewritten - update listbox
903 PFEA2 pfea = xmalloc(pfealist->cbList, pszSrcFile, __LINE__);
904 if (pfea) {
905 memcpy(pfea,
906 pfealist->list,
907 pfealist->cbList - sizeof(ULONG));
908 free(eap->current->pfea); // Stale
909 // Refresh current
910 eap->current->pfea = pfea;
911 eap->current->name = eap->current->pfea->szName;
912 eap->current->cbName = eap->current->pfea->cbName;
913 eap->current->fEA = eap->current->pfea->fEA;
914 eap->current->cbValue = eap->current->pfea->cbValue;
915 eap->current->value = eap->current->pfea->szName +
916 eap->current->pfea->cbName + 1;
917 eap->current->value[eap->current->cbValue] = 0;
918 // Refresh display
919 PostMsg(hwnd, WM_CONTROL,
920 MPFROM2SHORT(EA_LISTBOX, LN_SELECT), MPVOID);
921 }
922 DosFreeMem(pfealist);
923 }
924 }
925 free(s);
926 }
927 }
928 }
929 }
930 break;
931
932 case EA_DELETE:
933 if (eap->head && eap->current) {
934
935 EAOP2 eaop;
936 PFEA2LIST pfealist;
937 GEA2LIST gealist;
938 APIRET rc;
939 SHORT sSelect;
940
941 pfealist =
942 xmallocz(sizeof(FEA2LIST) + eap->current->cbName + 1, pszSrcFile,
943 __LINE__);
944 if (pfealist) {
945 pfealist->cbList = sizeof(FEA2LIST) + eap->current->cbName + 1;
946 pfealist->list[0].cbName = eap->current->cbName;
947 strcpy(pfealist->list[0].szName, eap->current->name);
948 pfealist->list[0].cbValue = 0;
949 memset(&gealist, 0, sizeof(GEA2LIST));
950 gealist.cbList = sizeof(GEA2LIST);
951 eaop.fpGEA2List = &gealist;
952 eaop.fpFEA2List = pfealist;
953 eaop.oError = 0;
954 rc = xDosSetPathInfo(eap->filename, FIL_QUERYEASIZE,
955 &eaop, sizeof(eaop), DSPI_WRTTHRU);
956 free(pfealist);
957 if (rc)
958 Dos_Error(MB_CANCEL, rc, hwnd, pszSrcFile, __LINE__,
959 "xDosSetPathInfo");
960 else {
961 sSelect = 0;
962 if (eap->current == eap->head) {
963 eap->head = eap->head->next;
964 free(eap->current->pfea);
965 free(eap->current);
966 eap->current = NULL;
967 }
968 else {
969 info = eap->head;
970 while (info) {
971 if (info->next == eap->current) {
972 sSelect++;
973 info->next = eap->current->next;
974 free(eap->current->pfea);
975 free(eap->current);
976 eap->current = NULL;
977 break;
978 }
979 sSelect++;
980 info = info->next;
981 }
982 }
983 WinSendDlgItemMsg(hwnd, EA_LISTBOX, LM_DELETEITEM,
984 MPFROM2SHORT(sSelect, 0), MPVOID);
985 WinShowWindow(WinWindowFromID(hwnd, EA_ENTRY), FALSE);
986 WinShowWindow(WinWindowFromID(hwnd, EA_MLE), FALSE);
987 WinShowWindow(WinWindowFromID(hwnd, EA_CHANGE), FALSE);
988 WinShowWindow(WinWindowFromID(hwnd, EA_DELETE), FALSE);
989 WinShowWindow(WinWindowFromID(hwnd, EA_HEXDUMP), FALSE);
990 WinSetDlgItemText(hwnd, EA_ENTRY, NullStr);
991 MLEclearall(WinWindowFromID(hwnd, EA_MLE));
992 WinSendDlgItemMsg(hwnd, EA_HEXDUMP, LM_DELETEALL, MPVOID, MPVOID);
993 if (sSelect && (SHORT) WinSendDlgItemMsg(hwnd, EA_LISTBOX,
994 LM_QUERYITEMCOUNT,
995 MPVOID, MPVOID) <=
996 sSelect)
997 sSelect--;
998 WinSendDlgItemMsg(hwnd, EA_LISTBOX, LM_SELECTITEM,
999 MPFROM2SHORT(sSelect, 0),
1000 MPFROM2SHORT(TRUE, 0));
1001 }
1002 }
1003 }
1004 if (!eap->head)
1005 WinSetDlgItemText(hwnd, EA_TEXT, (CHAR *)GetPString(IDS_EANOEAS));
1006 break;
1007
1008 case IDM_HELP:
1009 if (hwndHelp)
1010 WinSendMsg(hwndHelp, HM_DISPLAY_HELP,
1011 MPFROM2SHORT(HELP_EAS, 0), MPFROMSHORT(HM_RESOURCEID));
1012 break;
1013
1014 case DID_OK:
1015 WinDismissDlg(hwnd, 1);
1016 break;
1017
1018 case DID_CANCEL:
1019 WinDismissDlg(hwnd, 0);
1020 break;
1021 }
1022 return 0;
1023
1024 case WM_CLOSE:
1025 break;
1026
1027 case WM_DESTROY:
1028 if (eap) {
1029 if (eap->head)
1030 Free_FEAList(eap->head);
1031 xfree(mp2, pszSrcFile, __LINE__);
1032 free(eap);
1033 if (hptrIcon)
1034 WinDestroyPointer(hptrIcon);
1035 hptrIcon = (HPOINTER) 0;
1036 }
1037 break;
1038 } // switch
1039 return WinDefDlgProc(hwnd, msg, mp1, mp2);
1040}
1041
1042/**
1043 * Update one file EA
1044 * @param filename is file to be updated
1045 * @param current is discriptor for current EA value
1046 * @param newdata is text string to be converted to EA value
1047 * @param silentfail suppresses error message boxes if set
1048 * @returns point to FEA2LIST for updated EA or NULL if error
1049 */
1050
1051PVOID SaveEA(CHAR *filename,
1052 HOLDFEA *current,
1053 CHAR *newdata,
1054 BOOL silentfail)
1055{
1056 PFEA2LIST pfealist = NULL;
1057 EAOP2 eaop;
1058 APIRET rc;
1059 ULONG ealen;
1060 USHORT len, *num, *plen;
1061 CHAR *p, *peaval;
1062
1063 if (!filename || !current)
1064 return (PVOID)pfealist; // FIXME to complain
1065
1066 len = strlen(newdata);
1067 ealen = sizeof(FEA2LIST) + 24 + (ULONG) current->cbName + 1 +
1068 (ULONG)len + 4;
1069 // Do type specific adjustments to EA length
1070 switch (*(USHORT *)current->value) {
1071 case EAT_EA:
1072 case EAT_ASCII:
1073 break;
1074 case EAT_MVST:
1075 ealen += sizeof(USHORT) * 5;
1076 p = newdata;
1077 while (*p == '\n')
1078 p++;
1079 while (*p) {
1080 if (*p == '\n' && *(p + 1))
1081 ealen += sizeof(USHORT);
1082 p++;
1083 }
1084 break;
1085 case EAT_MVMT:
1086 ealen += sizeof(USHORT) * 5;
1087 p = newdata;
1088 while (*p == '\n')
1089 p++;
1090 while (*p) {
1091 if (*p == '\n' && *(p + 1))
1092 ealen += (sizeof(USHORT) * 2);
1093 p++;
1094 }
1095 break;
1096 default:
1097 // FIXME to complain
1098 return (PVOID) pfealist;
1099 } // switch EAT_...
1100
1101 if (!xDosAllocMem((PPVOID)&pfealist, ealen, pszSrcFile, __LINE__)) {
1102 // Build FEA2LIST
1103 memset(pfealist, 0, ealen);
1104 pfealist->list[0].oNextEntryOffset = 0;
1105 // pfealist->list[0].fEA = 0; // Always write non-critical EAs
1106 pfealist->list[0].fEA = current->fEA; // Retain critical EA flags 2014-02-10 SHL
1107
1108 pfealist->list[0].cbName = current->cbName;
1109 memcpy(pfealist->list[0].szName, current->name,
1110 pfealist->list[0].cbName + 1);
1111 peaval = pfealist->list[0].szName + pfealist->list[0].cbName + 1;
1112
1113 // Build new EA value
1114 switch (*(USHORT *)current->value) {
1115 case EAT_EA:
1116 case EAT_ASCII:
1117 *(USHORT *)peaval = *(USHORT *)current->value;
1118 peaval += sizeof(USHORT);
1119 *(USHORT *)peaval = (USHORT)len;
1120 peaval += sizeof(USHORT);
1121 memcpy(peaval, newdata, len);
1122 peaval += len;
1123 break;
1124 case EAT_MVST:
1125 *(USHORT *)peaval = (USHORT)EAT_MVST;
1126 peaval += sizeof(USHORT);
1127 *(USHORT *)peaval = *(USHORT *)(current->value + sizeof(USHORT));
1128 peaval += sizeof(USHORT);
1129 num = (USHORT *)peaval;
1130 *num = 0;
1131 peaval += sizeof(USHORT);
1132 *(USHORT *)peaval = (USHORT)EAT_ASCII;
1133 peaval += sizeof(USHORT);
1134 plen = (USHORT *)peaval;
1135 *plen = 0;
1136 peaval += sizeof(USHORT);
1137 p = newdata;
1138 while (*p == '\n')
1139 p++;
1140 while (*p) {
1141 while (*p) {
1142 if (*p == '\n')
1143 p++;
1144 *peaval++ = *p++;
1145 (*plen)++;
1146 }
1147 if (*p || *plen)
1148 (*num)++;
1149 if (*p) {
1150 plen = (USHORT *)peaval;
1151 *plen = 0;
1152 peaval += sizeof(USHORT);
1153 }
1154 }
1155 break;
1156
1157 /**
1158 * cbList nextoffset fea cb cbval name.......
1159 * 000000 3C 00 00 00 00 00 00 00 6F 0B 24 00 2E 4B 45 59 < o
1160$ .KEY
1161 * .................... eat code num eat
1162 * 000010 50 48 52 41 53 45 53 00 DF FF 00 00 02 00 FD FF PHRASES ßÿ ýÿ
1163 * len.. phrase1............................ eat
1164 * 000020 0C 00 4B 65 79 20 70 68 72 61 73 65 20 31 FD FF
1165 Key phrase 1ýÿ
1166 * len.. phrase2......................
1167 * 000030 0A 00 4B 65 79 20 70 68 72 61 73 65 Key phrase
1168 */
1169 case EAT_MVMT:
1170 *(USHORT *)peaval = (USHORT)EAT_MVMT;
1171 peaval += sizeof(USHORT);
1172 *(USHORT *)peaval = *(USHORT *)(current->value + sizeof(USHORT));
1173 peaval += sizeof(USHORT);
1174 num = (USHORT *)peaval;
1175 *num = 0;
1176 peaval += sizeof(USHORT);
1177 *(USHORT *)peaval = (USHORT)EAT_ASCII;
1178 peaval += sizeof(USHORT);
1179 plen = (USHORT *)peaval;
1180 *plen = 0;
1181 peaval += sizeof(USHORT);
1182 p = newdata;
1183 while (*p == '\n')
1184 p++;
1185 while (*p) {
1186 while (*p) {
1187 if (*p == '\n')
1188 p++;
1189 *peaval++ = *p++;
1190 (*plen)++;
1191 }
1192 if (*p || *plen)
1193 (*num)++;
1194 if (*p) {
1195 *(USHORT *)peaval = (USHORT)EAT_ASCII;
1196 peaval += sizeof(USHORT);
1197 plen = (USHORT *)peaval;
1198 *plen = 0;
1199 peaval += sizeof(USHORT);
1200 }
1201 }
1202 break;
1203 } // switch EAT_...
1204
1205 pfealist->list[0].cbValue = peaval - (pfealist->list[0].szName + pfealist->list[0].cbName + 1);
1206 eaop.fpGEA2List = (PGEA2LIST)0;
1207 eaop.fpFEA2List = pfealist;
1208 eaop.oError = 0;
1209 pfealist->cbList = 13 + (ULONG) pfealist->list[0].cbName +
1210 (ULONG)pfealist->list[0].cbValue;
1211
1212#if 1
1213 // Rewrite iff modified
1214 if (current->pfea->cbValue == pfealist->list[0].cbValue &&
1215 memcmp(current->pfea->szName + current->pfea->cbName + 1,
1216 pfealist->list[0].szName + pfealist->list[0].cbName + 1,
1217 current->pfea->cbValue) == 0) {
1218 //DbgMsg(pszSrcFile, __LINE__, "SaveEA: %s unchanged", current->pfea->szName);
1219 rc = 0; // Suppress rewrite
1220 }
1221 else {
1222 rc = xDosSetPathInfo(filename, FIL_QUERYEASIZE,
1223 &eaop, sizeof(eaop), DSPI_WRTTHRU);
1224 //DbgMsg(pszSrcFile, __LINE__, "SaveEA: %s updated", current->pfea->szName);
1225 }
1226#else
1227 // Rewrite EA
1228 rc = xDosSetPathInfo(filename, FIL_QUERYEASIZE,
1229 &eaop, sizeof(eaop), DSPI_WRTTHRU);
1230#endif
1231 if (rc) {
1232 DosFreeMem(pfealist);
1233 pfealist = NULL;
1234 }
1235 if (rc && !silentfail) {
1236 if (rc == ERROR_ACCESS_DENIED || rc == ERROR_SHARING_VIOLATION) {
1237 saymsg(MB_ENTER,
1238 HWND_DESKTOP,
1239 GetPString(IDS_OOPSTEXT),
1240 GetPString(IDS_CANTWRITEEATEXT), current->name, filename);
1241 }
1242 else {
1243 Dos_Error(MB_ENTER,
1244 rc,
1245 HWND_DESKTOP,
1246 pszSrcFile,
1247 __LINE__,
1248 GetPString(IDS_ERRORWRITEEATEXT),
1249 current->name, filename, eaop.oError);
1250 }
1251 }
1252 }
1253 return (PVOID)pfealist;
1254}
1255
1256HOLDFEA *GetFileEAs(CHAR * filename, BOOL ishandle, BOOL silentfail)
1257{
1258 // load eas from disk into HOLDFEA linked list
1259
1260 HOLDFEA *head = NULL, *info, *last = NULL;
1261 FILESTATUS4 fsa4;
1262 HFILE handle;
1263 ULONG action;
1264 APIRET rc;
1265
1266 if (!filename)
1267 return head;
1268 if (ishandle || !DosOpen(filename, &handle, &action, 0, 0,
1269 OPEN_ACTION_FAIL_IF_NEW |
1270 OPEN_ACTION_OPEN_IF_EXISTS,
1271 OPEN_FLAGS_NOINHERIT |
1272 OPEN_SHARE_DENYREADWRITE |
1273 OPEN_ACCESS_READWRITE, (PEAOP2)0)) {
1274 if (ishandle)
1275 handle = *(HFILE *) filename;
1276 if (!DosQueryFileInfo(handle, FIL_QUERYEASIZE, (PVOID)&fsa4,
1277 (ULONG) sizeof(fsa4)) &&
1278 fsa4.cbList > 4)
1279 {
1280 PDENA2 pdena;
1281 EAOP2 eaop;
1282 PGEA2LIST pgealist;
1283 PFEA2LIST pfealist;
1284 PGEA2 pgea;
1285 ULONG ulEntry = 1; // Ordinal of EA to return
1286 ULONG ulCount = 1; // # of EAs to return per call
1287
1288 pdena = xmalloc(65536 + 1024, pszSrcFile, __LINE__);
1289 if (pdena) {
1290 while (!DosEnumAttribute(ENUMEA_REFTYPE_FHANDLE,
1291 &handle,
1292 ulEntry,
1293 (PVOID)pdena,
1294 (ULONG)65536,
1295 &ulCount,
1296 ENUMEA_LEVEL_NO_VALUE) &&
1297 ulCount)
1298 {
1299 // 64 is for header and spare - FIXME to allocate smarter
1300 pgealist = xmalloc(64 + pdena->cbName, pszSrcFile, __LINE__);
1301 if (pgealist) {
1302 pgealist->cbList = 64 + pdena->cbName;
1303 pgea = pgealist->list;
1304 pgea->oNextEntryOffset = 0;
1305 pgea->cbName = pdena->cbName;
1306 memcpy(pgea->szName, pdena->szName, pdena->cbName + 1);
1307 pfealist = xmallocz(64 + pdena->cbName + pdena->cbValue,
1308 pszSrcFile, __LINE__);
1309 if (pfealist) {
1310 pfealist->cbList = 64 + pdena->cbName + pdena->cbValue;
1311 eaop.fpGEA2List = pgealist;
1312 eaop.fpFEA2List = pfealist;
1313 eaop.oError = 0;
1314 rc = DosQueryFileInfo(handle,
1315 FIL_QUERYEASFROMLIST,
1316 (PVOID)&eaop,
1317 (ULONG)sizeof(EAOP2));
1318 if (rc) {
1319 if (!silentfail) {
1320 Dos_Error(MB_ENTER,
1321 rc,
1322 HWND_DESKTOP,
1323 pszSrcFile,
1324 __LINE__,
1325 GetPString(IDS_ERRORREADEATEXT), pdena->szName);
1326 }
1327 }
1328 else {
1329 info = xmalloc(sizeof(HOLDFEA), pszSrcFile, __LINE__);
1330 if (info) {
1331 // 05 Jul 07 SHL was one short
1332 info->pfea = xmalloc(eaop.fpFEA2List->cbList - sizeof(ULONG) + 1,
1333 pszSrcFile, __LINE__);
1334 memcpy(info->pfea, eaop.fpFEA2List->list,
1335 eaop.fpFEA2List->cbList - sizeof(ULONG));
1336 // Copy for hold
1337 info->name = info->pfea->szName;
1338 info->cbName = info->pfea->cbName;
1339 info->fEA = info->pfea->fEA; // 2014-02-10 SHL
1340 info->cbValue = info->pfea->cbValue;
1341 info->value = info->pfea->szName + info->pfea->cbName + 1;
1342 info->value[info->cbValue] = 0;
1343 info->next = NULL;
1344 // Add to list
1345 if (!head)
1346 head = info;
1347 else
1348 last->next = info;
1349 last = info;
1350 } // if malloc OK
1351 } // if query from list OK
1352 free(pfealist);
1353 } // if malloc OK
1354 free(pgealist);
1355 } // if malloc OK
1356 ulEntry += ulCount;
1357 } // while have EAs
1358 free(pdena);
1359 DosPostEventSem(CompactSem);
1360 } // if malloc OK
1361 }
1362 if (!ishandle)
1363 DosClose(handle);
1364 }
1365 else {
1366 // File probably in use - try to get EAs without opening file
1367 if (!DosQueryPathInfo(filename,
1368 FIL_QUERYEASIZE,
1369 (PVOID)&fsa4,
1370 (ULONG)sizeof(fsa4)) &&
1371 fsa4.cbList > 4)
1372 {
1373 PDENA2 pdena;
1374 EAOP2 eaop;
1375 PGEA2LIST pgealist;
1376 PFEA2LIST pfealist;
1377 PGEA2 pgea;
1378 ULONG ulEntry = 1, ulCount = 1;
1379
1380 pdena = xmalloc(65536 + 1024, pszSrcFile, __LINE__);
1381 if (pdena) {
1382 while (!DosEnumAttribute(ENUMEA_REFTYPE_PATH,
1383 filename,
1384 ulEntry,
1385 (PVOID)pdena,
1386 (ULONG)65536,
1387 &ulCount,
1388 ENUMEA_LEVEL_NO_VALUE) &&
1389 ulCount)
1390 {
1391 // Got some EAs
1392 pgealist = xmalloc(64 + pdena->cbName, pszSrcFile, __LINE__);
1393 if (pgealist) {
1394 pgealist->cbList = 64 + pdena->cbName;
1395 pgea = pgealist->list;
1396 pgea->oNextEntryOffset = 0;
1397 pgea->cbName = pdena->cbName;
1398 memcpy(pgea->szName, pdena->szName, pdena->cbName + 1);
1399 pfealist =
1400 xmallocz(64 + pdena->cbName + pdena->cbValue, pszSrcFile,
1401 __LINE__);
1402 if (pfealist) {
1403 pfealist->cbList = 64 + pdena->cbName + pdena->cbValue;
1404 eaop.fpGEA2List = pgealist;
1405 eaop.fpFEA2List = pfealist;
1406 eaop.oError = 0;
1407 rc = DosQueryPathInfo(filename,
1408 FIL_QUERYEASFROMLIST,
1409 (PVOID)&eaop,
1410 (ULONG)sizeof(EAOP2));
1411 if (!rc) {
1412 // Got one
1413 info = xmalloc(sizeof(HOLDFEA), pszSrcFile, __LINE__);
1414 if (info) {
1415 // 29 Nov 07 GKY One short (EA search crash)
1416 info->pfea = xmalloc(eaop.fpFEA2List->cbList - sizeof(ULONG) + 1,
1417 pszSrcFile, __LINE__);
1418 memcpy(info->pfea, eaop.fpFEA2List->list,
1419 eaop.fpFEA2List->cbList - sizeof(ULONG));
1420 info->name = info->pfea->szName;
1421 info->cbName = info->pfea->cbName;
1422 info->fEA = info->pfea->fEA; // 2014-02-10 SHL
1423 info->cbValue = info->pfea->cbValue;
1424 info->value = info->pfea->szName + info->pfea->cbName + 1;
1425 info->value[info->cbValue] = 0;
1426 info->next = NULL;
1427 // Add to list
1428 if (!head)
1429 head = info;
1430 else
1431 last->next = info;
1432 last = info;
1433 }
1434 else
1435 free(pfealist);
1436 }
1437 else {
1438 free(pfealist);
1439 if (!silentfail) {
1440 if (rc == ERROR_ACCESS_DENIED
1441 || rc == ERROR_SHARING_VIOLATION) {
1442 rc =
1443 saymsg(MB_ENTER | MB_CANCEL, HWND_DESKTOP,
1444 GetPString(IDS_OOPSTEXT),
1445 GetPString(IDS_CANTREADEATEXT), filename,
1446 pdena->szName);
1447 if (rc == MBID_CANCEL) {
1448 free(pgealist);
1449 break;
1450 }
1451 }
1452 else {
1453 Dos_Error(MB_ENTER,
1454 rc,
1455 HWND_DESKTOP,
1456 pszSrcFile,
1457 __LINE__,
1458 GetPString(IDS_ERRORREADEATEXT), pdena->szName);
1459 }
1460 }
1461 } // if DosQeryPathInfo
1462 } // if malloc OK
1463 free(pgealist);
1464 } // if malloc OK
1465 ulEntry += ulCount;
1466 } // while have EAs
1467 free(pdena);
1468 DosPostEventSem(CompactSem);
1469 } // if malloc OK
1470 } // if DosQueryPathInfo OK
1471 } // if need DosQueryPathInfo
1472 return head;
1473}
1474
1475VOID Free_FEAList(HOLDFEA * pFEA)
1476{
1477 // free a linked list of HOLDFEAs
1478
1479 register HOLDFEA *next;
1480
1481 while (pFEA) {
1482 // Free linked list
1483 next = pFEA->next;
1484 xfree(pFEA->pfea, pszSrcFile, __LINE__);
1485 free(pFEA);
1486 pFEA = next;
1487 }
1488 DosPostEventSem(CompactSem);
1489}
1490
1491#pragma alloc_text(EAS,DisplayEAsProc,SaveEA,HexDumpEA,CheckEA,AddEAProc)
1492#pragma alloc_text(EAS1,HexDump,GetFileEAs,Free_FEAList)
1493
Note: See TracBrowser for help on using the repository browser.