source: trunk/dll/eas.c@ 1817

Last change on this file since 1817 was 1817, checked in by Steven Levine, 10 years ago

testing trac viewer

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 39.5 KB
Line 
1
2/***********************************************************************
3
4 $Id: eas.c 1817 2015-06-24 03:24:01Z stevenhl $
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 DbgMsg(pszSrcFile, __LINE__, "SaveEA: entered for %s", filename);
1064
1065 if (!filename || !current)
1066 return (PVOID)pfealist; // FIXME to complain
1067
1068 len = strlen(newdata);
1069 ealen = sizeof(FEA2LIST) + 24 + (ULONG) current->cbName + 1 +
1070 (ULONG)len + 4;
1071 // Do type specific adjustments to EA length
1072 switch (*(USHORT *)current->value) {
1073 case EAT_EA:
1074 case EAT_ASCII:
1075 break;
1076 case EAT_MVST:
1077 ealen += sizeof(USHORT) * 5;
1078 p = newdata;
1079 while (*p == '\n')
1080 p++;
1081 while (*p) {
1082 if (*p == '\n' && *(p + 1))
1083 ealen += sizeof(USHORT);
1084 p++;
1085 }
1086 break;
1087 case EAT_MVMT:
1088 ealen += sizeof(USHORT) * 5;
1089 p = newdata;
1090 while (*p == '\n')
1091 p++;
1092 while (*p) {
1093 if (*p == '\n' && *(p + 1))
1094 ealen += (sizeof(USHORT) * 2);
1095 p++;
1096 }
1097 break;
1098 default:
1099 // FIXME to complain
1100 return (PVOID) pfealist;
1101 } // switch EAT_...
1102
1103 if (!xDosAllocMem((PPVOID)&pfealist, ealen, pszSrcFile, __LINE__)) {
1104 // Build FEA2LIST
1105 memset(pfealist, 0, ealen);
1106 pfealist->list[0].oNextEntryOffset = 0;
1107 // pfealist->list[0].fEA = 0; // Always write non-critical EAs
1108 pfealist->list[0].fEA = current->fEA; // Retain critical EA flags 2014-02-10 SHL
1109
1110 pfealist->list[0].cbName = current->cbName;
1111 memcpy(pfealist->list[0].szName, current->name,
1112 pfealist->list[0].cbName + 1);
1113 peaval = pfealist->list[0].szName + pfealist->list[0].cbName + 1;
1114
1115 // Build new EA value
1116 switch (*(USHORT *)current->value) {
1117 case EAT_EA:
1118 case EAT_ASCII:
1119 *(USHORT *)peaval = *(USHORT *)current->value;
1120 peaval += sizeof(USHORT);
1121 *(USHORT *)peaval = (USHORT)len;
1122 peaval += sizeof(USHORT);
1123 memcpy(peaval, newdata, len);
1124 peaval += len;
1125 break;
1126 case EAT_MVST:
1127 *(USHORT *)peaval = (USHORT)EAT_MVST;
1128 peaval += sizeof(USHORT);
1129 *(USHORT *)peaval = *(USHORT *)(current->value + sizeof(USHORT));
1130 peaval += sizeof(USHORT);
1131 num = (USHORT *)peaval;
1132 *num = 0;
1133 peaval += sizeof(USHORT);
1134 *(USHORT *)peaval = (USHORT)EAT_ASCII;
1135 peaval += sizeof(USHORT);
1136 plen = (USHORT *)peaval;
1137 *plen = 0;
1138 peaval += sizeof(USHORT);
1139 p = newdata;
1140 while (*p == '\n')
1141 p++;
1142 while (*p) {
1143 while (*p) {
1144 if (*p == '\n')
1145 p++;
1146 *peaval++ = *p++;
1147 (*plen)++;
1148 }
1149 if (*p || *plen)
1150 (*num)++;
1151 if (*p) {
1152 plen = (USHORT *)peaval;
1153 *plen = 0;
1154 peaval += sizeof(USHORT);
1155 }
1156 }
1157 break;
1158
1159 /**
1160 * cbList nextoffset fea cb cbval name.......
1161 * 000000 3C 00 00 00 00 00 00 00 6F 0B 24 00 2E 4B 45 59 < o
1162$ .KEY
1163 * .................... eat code num eat
1164 * 000010 50 48 52 41 53 45 53 00 DF FF 00 00 02 00 FD FF PHRASES ßÿ ýÿ
1165 * len.. phrase1............................ eat
1166 * 000020 0C 00 4B 65 79 20 70 68 72 61 73 65 20 31 FD FF
1167 Key phrase 1ýÿ
1168 * len.. phrase2......................
1169 * 000030 0A 00 4B 65 79 20 70 68 72 61 73 65 Key phrase
1170 */
1171 case EAT_MVMT:
1172 *(USHORT *)peaval = (USHORT)EAT_MVMT;
1173 peaval += sizeof(USHORT);
1174 *(USHORT *)peaval = *(USHORT *)(current->value + sizeof(USHORT));
1175 peaval += sizeof(USHORT);
1176 num = (USHORT *)peaval;
1177 *num = 0;
1178 peaval += sizeof(USHORT);
1179 *(USHORT *)peaval = (USHORT)EAT_ASCII;
1180 peaval += sizeof(USHORT);
1181 plen = (USHORT *)peaval;
1182 *plen = 0;
1183 peaval += sizeof(USHORT);
1184 p = newdata;
1185 while (*p == '\n')
1186 p++;
1187 while (*p) {
1188 while (*p) {
1189 if (*p == '\n')
1190 p++;
1191 *peaval++ = *p++;
1192 (*plen)++;
1193 }
1194 if (*p || *plen)
1195 (*num)++;
1196 if (*p) {
1197 *(USHORT *)peaval = (USHORT)EAT_ASCII;
1198 peaval += sizeof(USHORT);
1199 plen = (USHORT *)peaval;
1200 *plen = 0;
1201 peaval += sizeof(USHORT);
1202 }
1203 }
1204 break;
1205 } // switch EAT_...
1206
1207 pfealist->list[0].cbValue = peaval - (pfealist->list[0].szName + pfealist->list[0].cbName + 1);
1208 eaop.fpGEA2List = (PGEA2LIST)0;
1209 eaop.fpFEA2List = pfealist;
1210 eaop.oError = 0;
1211 pfealist->cbList = 13 + (ULONG) pfealist->list[0].cbName +
1212 (ULONG)pfealist->list[0].cbValue;
1213
1214#if 1
1215 // Rewrite iff modified
1216 if (current->pfea->cbValue == pfealist->list[0].cbValue &&
1217 memcmp(current->pfea->szName + current->pfea->cbName + 1,
1218 pfealist->list[0].szName + pfealist->list[0].cbName + 1,
1219 current->pfea->cbValue) == 0)
1220 {
1221 DbgMsg(pszSrcFile, __LINE__, "SaveEA: %s unchanged", current->pfea->szName);
1222 rc = 0; // Suppress rewrite
1223 }
1224 else {
1225 rc = xDosSetPathInfo(filename, FIL_QUERYEASIZE,
1226 &eaop, sizeof(eaop), DSPI_WRTTHRU);
1227 DbgMsg(pszSrcFile, __LINE__, "SaveEA: %s updated", current->pfea->szName);
1228 }
1229#else
1230 // Rewrite EA
1231 rc = xDosSetPathInfo(filename, FIL_QUERYEASIZE,
1232 &eaop, sizeof(eaop), DSPI_WRTTHRU);
1233#endif
1234 if (rc) {
1235 DosFreeMem(pfealist);
1236 pfealist = NULL;
1237 }
1238 if (rc && !silentfail) {
1239 if (rc == ERROR_ACCESS_DENIED || rc == ERROR_SHARING_VIOLATION) {
1240 saymsg(MB_ENTER,
1241 HWND_DESKTOP,
1242 GetPString(IDS_OOPSTEXT),
1243 GetPString(IDS_CANTWRITEEATEXT), current->name, filename);
1244 }
1245 else {
1246 Dos_Error(MB_ENTER,
1247 rc,
1248 HWND_DESKTOP,
1249 pszSrcFile,
1250 __LINE__,
1251 GetPString(IDS_ERRORWRITEEATEXT),
1252 current->name, filename, eaop.oError);
1253 }
1254 }
1255 }
1256 return (PVOID)pfealist;
1257}
1258
1259HOLDFEA *GetFileEAs(CHAR * filename, BOOL ishandle, BOOL silentfail)
1260{
1261 // load eas from disk into HOLDFEA linked list
1262
1263 HOLDFEA *head = NULL, *info, *last = NULL;
1264 FILESTATUS4 fsa4;
1265 HFILE handle;
1266 ULONG action;
1267 APIRET rc;
1268
1269 if (!filename)
1270 return head;
1271 if (ishandle || !DosOpen(filename, &handle, &action, 0, 0,
1272 OPEN_ACTION_FAIL_IF_NEW |
1273 OPEN_ACTION_OPEN_IF_EXISTS,
1274 OPEN_FLAGS_NOINHERIT |
1275 OPEN_SHARE_DENYREADWRITE |
1276 OPEN_ACCESS_READWRITE, (PEAOP2)0)) {
1277 if (ishandle)
1278 handle = *(HFILE *) filename;
1279 if (!DosQueryFileInfo(handle, FIL_QUERYEASIZE, (PVOID)&fsa4,
1280 (ULONG) sizeof(fsa4)) &&
1281 fsa4.cbList > 4)
1282 {
1283 PDENA2 pdena;
1284 EAOP2 eaop;
1285 PGEA2LIST pgealist;
1286 PFEA2LIST pfealist;
1287 PGEA2 pgea;
1288 ULONG ulEntry = 1; // Ordinal of EA to return
1289 ULONG ulCount = 1; // # of EAs to return per call
1290
1291 pdena = xmalloc(65536 + 1024, pszSrcFile, __LINE__);
1292 if (pdena) {
1293 while (!DosEnumAttribute(ENUMEA_REFTYPE_FHANDLE,
1294 &handle,
1295 ulEntry,
1296 (PVOID)pdena,
1297 (ULONG)65536,
1298 &ulCount,
1299 ENUMEA_LEVEL_NO_VALUE) &&
1300 ulCount)
1301 {
1302 // 64 is for header and spare - FIXME to allocate smarter
1303 pgealist = xmalloc(64 + pdena->cbName, pszSrcFile, __LINE__);
1304 if (pgealist) {
1305 pgealist->cbList = 64 + pdena->cbName;
1306 pgea = pgealist->list;
1307 pgea->oNextEntryOffset = 0;
1308 pgea->cbName = pdena->cbName;
1309 memcpy(pgea->szName, pdena->szName, pdena->cbName + 1);
1310 pfealist = xmallocz(64 + pdena->cbName + pdena->cbValue,
1311 pszSrcFile, __LINE__);
1312 if (pfealist) {
1313 pfealist->cbList = 64 + pdena->cbName + pdena->cbValue;
1314 eaop.fpGEA2List = pgealist;
1315 eaop.fpFEA2List = pfealist;
1316 eaop.oError = 0;
1317 rc = DosQueryFileInfo(handle,
1318 FIL_QUERYEASFROMLIST,
1319 (PVOID)&eaop,
1320 (ULONG)sizeof(EAOP2));
1321 if (rc) {
1322 if (!silentfail) {
1323 Dos_Error(MB_ENTER,
1324 rc,
1325 HWND_DESKTOP,
1326 pszSrcFile,
1327 __LINE__,
1328 GetPString(IDS_ERRORREADEATEXT), pdena->szName);
1329 }
1330 }
1331 else {
1332 info = xmalloc(sizeof(HOLDFEA), pszSrcFile, __LINE__);
1333 if (info) {
1334 // 05 Jul 07 SHL was one short
1335 info->pfea = xmalloc(eaop.fpFEA2List->cbList - sizeof(ULONG) + 1,
1336 pszSrcFile, __LINE__);
1337 memcpy(info->pfea, eaop.fpFEA2List->list,
1338 eaop.fpFEA2List->cbList - sizeof(ULONG));
1339 // Copy for hold
1340 info->name = info->pfea->szName;
1341 info->cbName = info->pfea->cbName;
1342 info->fEA = info->pfea->fEA; // 2014-02-10 SHL
1343 info->cbValue = info->pfea->cbValue;
1344 info->value = info->pfea->szName + info->pfea->cbName + 1;
1345 info->value[info->cbValue] = 0;
1346 info->next = NULL;
1347 // Add to list
1348 if (!head)
1349 head = info;
1350 else
1351 last->next = info;
1352 last = info;
1353 } // if malloc OK
1354 } // if query from list OK
1355 free(pfealist);
1356 } // if malloc OK
1357 free(pgealist);
1358 } // if malloc OK
1359 ulEntry += ulCount;
1360 } // while have EAs
1361 free(pdena);
1362 DosPostEventSem(CompactSem);
1363 } // if malloc OK
1364 }
1365 if (!ishandle)
1366 DosClose(handle);
1367 }
1368 else {
1369 // File probably in use - try to get EAs without opening file
1370 if (!DosQueryPathInfo(filename,
1371 FIL_QUERYEASIZE,
1372 (PVOID)&fsa4,
1373 (ULONG)sizeof(fsa4)) &&
1374 fsa4.cbList > 4)
1375 {
1376 PDENA2 pdena;
1377 EAOP2 eaop;
1378 PGEA2LIST pgealist;
1379 PFEA2LIST pfealist;
1380 PGEA2 pgea;
1381 ULONG ulEntry = 1, ulCount = 1;
1382
1383 pdena = xmalloc(65536 + 1024, pszSrcFile, __LINE__);
1384 if (pdena) {
1385 while (!DosEnumAttribute(ENUMEA_REFTYPE_PATH,
1386 filename,
1387 ulEntry,
1388 (PVOID)pdena,
1389 (ULONG)65536,
1390 &ulCount,
1391 ENUMEA_LEVEL_NO_VALUE) &&
1392 ulCount)
1393 {
1394 // Got some EAs
1395 pgealist = xmalloc(64 + pdena->cbName, pszSrcFile, __LINE__);
1396 if (pgealist) {
1397 pgealist->cbList = 64 + pdena->cbName;
1398 pgea = pgealist->list;
1399 pgea->oNextEntryOffset = 0;
1400 pgea->cbName = pdena->cbName;
1401 memcpy(pgea->szName, pdena->szName, pdena->cbName + 1);
1402 pfealist =
1403 xmallocz(64 + pdena->cbName + pdena->cbValue, pszSrcFile,
1404 __LINE__);
1405 if (pfealist) {
1406 pfealist->cbList = 64 + pdena->cbName + pdena->cbValue;
1407 eaop.fpGEA2List = pgealist;
1408 eaop.fpFEA2List = pfealist;
1409 eaop.oError = 0;
1410 rc = DosQueryPathInfo(filename,
1411 FIL_QUERYEASFROMLIST,
1412 (PVOID)&eaop,
1413 (ULONG)sizeof(EAOP2));
1414 if (!rc) {
1415 // Got one
1416 info = xmalloc(sizeof(HOLDFEA), pszSrcFile, __LINE__);
1417 if (info) {
1418 // 29 Nov 07 GKY One short (EA search crash)
1419 info->pfea = xmalloc(eaop.fpFEA2List->cbList - sizeof(ULONG) + 1,
1420 pszSrcFile, __LINE__);
1421 memcpy(info->pfea, eaop.fpFEA2List->list,
1422 eaop.fpFEA2List->cbList - sizeof(ULONG));
1423 info->name = info->pfea->szName;
1424 info->cbName = info->pfea->cbName;
1425 info->fEA = info->pfea->fEA; // 2014-02-10 SHL
1426 info->cbValue = info->pfea->cbValue;
1427 info->value = info->pfea->szName + info->pfea->cbName + 1;
1428 info->value[info->cbValue] = 0;
1429 info->next = NULL;
1430 // Add to list
1431 if (!head)
1432 head = info;
1433 else
1434 last->next = info;
1435 last = info;
1436 }
1437 else
1438 free(pfealist);
1439 }
1440 else {
1441 free(pfealist);
1442 if (!silentfail) {
1443 if (rc == ERROR_ACCESS_DENIED
1444 || rc == ERROR_SHARING_VIOLATION) {
1445 rc =
1446 saymsg(MB_ENTER | MB_CANCEL, HWND_DESKTOP,
1447 GetPString(IDS_OOPSTEXT),
1448 GetPString(IDS_CANTREADEATEXT), filename,
1449 pdena->szName);
1450 if (rc == MBID_CANCEL) {
1451 free(pgealist);
1452 break;
1453 }
1454 }
1455 else {
1456 Dos_Error(MB_ENTER,
1457 rc,
1458 HWND_DESKTOP,
1459 pszSrcFile,
1460 __LINE__,
1461 GetPString(IDS_ERRORREADEATEXT), pdena->szName);
1462 }
1463 }
1464 } // if DosQeryPathInfo
1465 } // if malloc OK
1466 free(pgealist);
1467 } // if malloc OK
1468 ulEntry += ulCount;
1469 } // while have EAs
1470 free(pdena);
1471 DosPostEventSem(CompactSem);
1472 } // if malloc OK
1473 } // if DosQueryPathInfo OK
1474 } // if need DosQueryPathInfo
1475 return head;
1476}
1477
1478VOID Free_FEAList(HOLDFEA * pFEA)
1479{
1480 // free a linked list of HOLDFEAs
1481
1482 register HOLDFEA *next;
1483
1484 while (pFEA) {
1485 // Free linked list
1486 next = pFEA->next;
1487 xfree(pFEA->pfea, pszSrcFile, __LINE__);
1488 free(pFEA);
1489 pFEA = next;
1490 }
1491 DosPostEventSem(CompactSem);
1492}
1493
1494#pragma alloc_text(EAS,DisplayEAsProc,SaveEA,HexDumpEA,CheckEA,AddEAProc)
1495#pragma alloc_text(EAS1,HexDump,GetFileEAs,Free_FEAList)
1496
Note: See TracBrowser for help on using the repository browser.