source: trunk/dll/eas.c@ 1804

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

Support critical EAs

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 39.5 KB
RevLine 
[123]1
2/***********************************************************************
3
4 $Id: eas.c 1804 2015-05-04 01:31:59Z stevenhl $
5
[347]6 Display/edit EAs
7
[123]8 Copyright (c) 1993-98 M. Kimes
[1804]9 Copyright (c) 2004, 2014 Steven H. Levine
[123]10
[193]11 01 Aug 04 SHL Rework lstrip/rstrip usage
12 06 Jun 05 SHL Indent -i2
[207]13 06 Jun 05 SHL Rework DisplayEAsProc for VAC3.65 compat
14 06 Jun 05 SHL Drop unused variables
[347]15 17 Jul 06 SHL Use Runtime_Error
[574]16 22 Mar 07 GKY Use QWL_USER
[725]17 05 Jul 07 SHL GetFileEAs: avoid heap corruption
[730]18 15 Jul 07 GKY Allow subject edit of up to 256 chars
[755]19 03 Aug 07 GKY Remove surrious error message
[775]20 06 Aug 07 GKY Increase Subject EA to 1024
[795]21 20 Aug 07 GKY Move #pragma alloc_text to end for OpenWatcom compat
[827]22 01 Sep 07 GKY Use xDosSetPathInfo to fix case where FS3 buffer crosses 64k boundry
[985]23 29 Feb 08 GKY Use xfree where appropriate
[1395]24 07 Feb 09 GKY Allow user to turn off alert and/or error beeps in settings notebook.
[1480]25 12 Jul 09 GKY Add xDosQueryAppType and xDosAlloc... to allow FM/2 to load in high memory
[1498]26 17 JAN 10 GKY Changes to get working with Watcom 1.9 Beta (1/16/10). Mostly cast CHAR CONSTANT * as CHAR *.
[1546]27 23 Oct 10 GKY Added button to allow opening of a new file's eas from the EA dialog.
[1627]28 26 Aug 11 GKY Add a low mem version of xDosAlloc* wrappers; move error checking into all the
[1804]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
[123]32
33***********************************************************************/
34
[907]35#include <stdlib.h>
36#include <stdio.h>
37#include <string.h>
38#include <ctype.h>
39
[2]40#define INCL_WIN
41#define INCL_DOS
42#define INCL_DOSERRORS
[841]43#define INCL_LONGLONG
[2]44
[1179]45#include "fm3dll.h"
[1222]46#include "fm3dll2.h" // #define's for UM_*, control id's, etc.
[1207]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
[2]52#include "fm3dlg.h"
53#include "fm3str.h"
54#include "mle.h"
[1157]55#include "errutil.h" // Dos_Error...
56#include "strutil.h" // GetPString
57#include "defview.h" // QuickView
[1179]58#include "subj.h" // Subject
59#include "wrappers.h" // xDosSetPathInfo
[1157]60#include "eas.h"
[1179]61#include "strips.h" // bstrip
62#include "valid.h" // IsFile
63#include "misc.h" // PaintRecessedWindow
[1039]64#include "fortify.h"
[1546]65#include "getnames.h" // insert_filename
66#include "pathutil.h" // ForwardslashToBackslash
[2]67
68#pragma data_seg(DATA1)
[347]69
70static PSZ pszSrcFile = __FILE__;
71
[1804]72static PVOID SaveEA(CHAR *filename, HOLDFEA *current, CHAR *newdata,
[1157]73 BOOL silentfail);
[2]74
[193]75typedef struct
76{
[2]77 CHAR *name;
[193]78 INT type;
79}
80RESERVEDEAS;
[2]81
[193]82typedef struct
83{
84 CHAR *filename;
[2]85 HOLDFEA *head;
[193]86}
87ADDEA;
[2]88
[193]89HOLDFEA *CheckEA(HOLDFEA * head, CHAR * eaname)
90{
[1673]91 // return pointer to ea named eaname if found in linked list
[2]92
93 register HOLDFEA *info = NULL;
94
[551]95 if (eaname && *eaname) {
[2]96 info = head;
[551]97 while (info) {
98 if (!strcmp(info->name, eaname))
[1804]99 return info;
[551]100 info = info->next;
[2]101 }
102 }
103 return info;
104}
105
[193]106MRESULT EXPENTRY AddEAProc(HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2)
107{
108 ADDEA *add;
109 HOLDFEA *head;
110 CHAR *filename;
[551]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 };
[2]126
[551]127 switch (msg) {
[193]128 case WM_INITDLG:
[551]129 if (!mp2) {
[193]130 WinDismissDlg(hwnd, 0);
[2]131 break;
[193]132 }
[574]133 WinSetWindowPtr(hwnd, QWL_USER, (PVOID) mp2);
[193]134 WinSendDlgItemMsg(hwnd, EAC_NAME, EM_SETTEXTLIMIT,
[1804]135 MPFROM2SHORT(1024, 0), MPVOID);
[193]136 WinCheckButton(hwnd, EAC_ASCII, TRUE);
137 break;
[2]138
[193]139 case WM_PAINT:
140 PostMsg(hwnd, UM_PAINT, MPVOID, MPVOID);
141 break;
[2]142
[193]143 case UM_PAINT:
[551]144 PaintRecessedWindow(WinWindowFromID(hwnd, EAC_TEXT), (HPS) 0, FALSE,
[1804]145 FALSE);
[193]146 return 0;
[2]147
[193]148 case WM_CONTROL:
149 return 0;
[2]150
[193]151 case WM_COMMAND:
[551]152 switch (SHORT1FROMMP(mp1)) {
[193]153 case DID_OK:
154 add = INSTDATA(hwnd);
[551]155 head = add->head;
156 filename = add->filename;
[193]157 {
[1804]158 CHAR s[1025];
159 INT x;
160 USHORT type = EAT_ASCII;
[2]161
[1804]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;
[2]206
[1804]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 }
[193]241 }
242 break;
[2]243
[193]244 case DID_CANCEL:
245 WinDismissDlg(hwnd, 0);
246 break;
[2]247
[193]248 case IDM_HELP:
249 if (hwndHelp)
[1804]250 WinSendMsg(hwndHelp, HM_DISPLAY_HELP,
251 MPFROM2SHORT(HELP_ADDEA, 0), MPFROMSHORT(HM_RESOURCEID));
[193]252 break;
253 }
254 return 0;
[2]255 }
[193]256 return WinDefDlgProc(hwnd, msg, mp1, mp2);
[2]257}
258
[193]259static VOID HexDumpEA(HWND hwnd, HOLDFEA * info)
260{
261 if (info)
[551]262 HexDump(WinWindowFromID(hwnd, EA_HEXDUMP), info->value, info->cbValue);
[2]263}
264
[193]265VOID HexDump(HWND hwnd, CHAR * value, ULONG cbValue)
266{
[1673]267 // display a hexdump of a binary 'string' in listbox hwnd
[2]268
[193]269 CHAR s[132];
270 register CHAR *p, *pp, *a;
271 register ULONG x = 0, y, z;
[2]272
[193]273 WinSendMsg(hwnd, LM_DELETEALL, MPVOID, MPVOID);
[551]274 if (cbValue) {
[2]275 pp = p = value;
[551]276 while (x < cbValue) {
[2]277 y = x;
[193]278 sprintf(s, "%04lx ", x);
[2]279 a = s + 6;
[551]280 do {
[1804]281 sprintf(a, "%02x ", (UCHAR)*p);
282 a += 3;
283 p++;
284 x++;
[2]285 }
[193]286 while (x < cbValue && (x % 16));
[551]287 if (x % 16) {
[1804]288 z = x;
289 while (z % 16) {
290 *a++ = ' ';
291 *a++ = ' ';
292 *a++ = ' ';
293 z++;
294 }
[193]295 }
[2]296 *a++ = ' ';
297 p = pp;
[551]298 do {
[1804]299 if (*p)
300 *a++ = *p++;
301 else {
302 *a++ = '.';
303 p++;
304 }
305 *a = 0;
306 y++;
[193]307 }
308 while (y < x);
309 if ((SHORT) WinSendMsg(hwnd, LM_INSERTITEM, MPFROM2SHORT(LIT_END, 0),
[1804]310 MPFROMP(s)) < 0)
311 break;
[2]312 pp = p;
313 }
314 }
315}
316
[193]317typedef struct
318{
319 USHORT size;
320 USHORT flags;
321 HOLDFEA *head, *current;
322 CHAR **list;
323 CHAR filename[CCHMAXPATH];
324}
325EAPROCDATA;
[2]326
[193]327MRESULT EXPENTRY DisplayEAsProc(HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2)
328{
329 EAPROCDATA *eap;
330 HOLDFEA *info;
[1804]331 CHAR str[81];
332
[193]333 static HPOINTER hptrIcon = (HPOINTER) 0;
[2]334
[193]335 if (msg != WM_INITDLG)
[574]336 eap = (EAPROCDATA *) WinQueryWindowPtr(hwnd, QWL_USER);
[2]337
[551]338 switch (msg) {
[193]339 case WM_INITDLG:
[551]340 if (!mp2) {
[193]341 WinDismissDlg(hwnd, 0);
342 break;
343 }
[564]344 eap = xmallocz(sizeof(EAPROCDATA), pszSrcFile, __LINE__);
[551]345 if (!eap) {
[193]346 WinDismissDlg(hwnd, 0);
347 break;
348 }
349 hptrIcon = WinLoadPointer(HWND_DESKTOP, FM3ModHandle, EA_FRAME);
350 WinDefDlgProc(hwnd, WM_SETICON, MPFROMLONG(hptrIcon), MPVOID);
[551]351 eap->size = sizeof(EAPROCDATA);
352 eap->list = (CHAR **) mp2;
[574]353 WinSetWindowPtr(hwnd, QWL_USER, (PVOID) eap);
[193]354 WinSendDlgItemMsg(hwnd,
[1804]355 EA_ENTRY, EM_SETTEXTLIMIT, MPFROM2SHORT(40, 0), MPVOID);
[770]356 MLEsetlimit(WinWindowFromID(hwnd, EA_MLE), 32767);
[551]357 MLEsetformat(WinWindowFromID(hwnd, EA_MLE), MLFIE_NOTRANS);
[193]358 {
359 INT x;
360 SHORT sSelect;
361 CHAR s[CCHMAXPATH];
[2]362
[551]363 for (x = 0; eap->list[x]; x++) {
[1804]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));
[193]371 }
372 sSelect = (SHORT) WinSendDlgItemMsg(hwnd,
[1804]373 EA_NAMES,
374 LM_QUERYITEMCOUNT, MPVOID, MPVOID);
[193]375 if (sSelect > 0)
[1804]376 WinSendDlgItemMsg(hwnd,
377 EA_NAMES,
378 LM_SELECTITEM,
379 MPFROM2SHORT(0, 0), MPFROMSHORT(TRUE));
[193]380 else
[1804]381 WinDismissDlg(hwnd, 0);
[193]382 }
383 break;
[2]384
[193]385 case UM_SETDIR:
[551]386 if (*eap->filename) {
387 if (eap->head)
[1804]388 Free_FEAList(eap->head);
[551]389 eap->head = GetFileEAs(eap->filename, FALSE, FALSE);
390 if (!isalpha(*eap->filename) ||
[1804]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);
[2]395 }
[551]396 else {
[1804]397 WinEnableWindow(WinWindowFromID(hwnd, EA_CHANGE), TRUE);
398 WinEnableWindow(WinWindowFromID(hwnd, EA_ADD), TRUE);
399 WinEnableWindow(WinWindowFromID(hwnd, EA_DELETE), TRUE);
[2]400 }
[193]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);
[551]415 eap->current = NULL;
416 if (eap->head) {
[193]417 WinSetDlgItemText(hwnd, EA_TEXT, NullStr);
[551]418 info = eap->head;
419 while (info) {
[1804]420 WinSendDlgItemMsg(hwnd, EA_LISTBOX, LM_INSERTITEM,
421 MPFROM2SHORT(LIT_END, 0), MPFROMP(info->name));
422 info = info->next;
[2]423 }
[193]424 WinSendDlgItemMsg(hwnd, EA_LISTBOX, LM_SELECTITEM,
[1804]425 MPFROM2SHORT(0, 0), MPFROM2SHORT(TRUE, 0));
[193]426 }
427 else
[1804]428 WinSetDlgItemText(hwnd, EA_TEXT, (CHAR *)GetPString(IDS_EANOEAS));
[193]429 return 0;
[2]430
[193]431 case WM_PAINT:
432 PostMsg(hwnd, UM_PAINT, MPVOID, MPVOID);
433 break;
[2]434
[193]435 case UM_PAINT:
436 PaintRecessedWindow(WinWindowFromID(hwnd, EA_HELP), (HPS) 0, FALSE, TRUE);
[551]437 PaintRecessedWindow(WinWindowFromID(hwnd, EA_TEXT), (HPS) 0, FALSE,
[1804]438 FALSE);
[193]439 return 0;
[2]440
[193]441 case WM_CONTROL:
[551]442 switch (SHORT1FROMMP(mp1)) {
[193]443 case EA_NAMES:
[551]444 switch (SHORT2FROMMP(mp1)) {
[193]445 case LN_SETFOCUS:
[1804]446 WinSetDlgItemText(hwnd, EA_HELP, (CHAR *)GetPString(IDS_EAFILENAMESHELPTEXT));
447 break;
[193]448 case LN_KILLFOCUS:
[1804]449 WinSetDlgItemText(hwnd, EA_HELP, NullStr);
450 break;
[193]451 case LN_ENTER:
452 case LN_SELECT:
[1804]453 {
454 CHAR s[1025];
455 SHORT sSelect;
[193]456
[1804]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;
[2]475 }
476 break;
477
[193]478 case EA_LISTBOX:
[551]479 switch (SHORT2FROMMP(mp1)) {
[193]480 case LN_SETFOCUS:
[1804]481 WinSetDlgItemText(hwnd, EA_HELP, (CHAR *)GetPString(IDS_EATYPESHELPTEXT));
482 break;
[193]483 case LN_KILLFOCUS:
[1804]484 WinSetDlgItemText(hwnd, EA_HELP, NullStr);
485 break;
[193]486 case LN_SELECT:
[1804]487 {
488 CHAR s[1024];
489 SHORT sSelect;
[2]490
[1804]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) {
[2]515
[1804]516 USHORT len, num, type;
517 CHAR *data;
518 CHAR last = '\n';
519 const CHAR *linefeed = "\n";
520 BOOL alltext;
521 IPT pos = 0;
[2]522
[1804]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
[2]748
[1804]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;
[193]763 }
764 break;
[2]765
[193]766 case EA_ENTRY:
[551]767 switch (SHORT2FROMMP(mp1)) {
[193]768 case EN_SETFOCUS:
[1804]769 WinSetDlgItemText(hwnd, EA_HELP, (CHAR *)GetPString(IDS_EADATAHELPTEXT));
770 break;
[193]771 case EN_KILLFOCUS:
[1804]772 WinSetDlgItemText(hwnd, EA_HELP, NullStr);
773 break;
[193]774 case EN_CHANGE:
[1804]775 WinEnableWindow(WinWindowFromID(hwnd, EA_CHANGE), TRUE);
776 break;
[193]777 }
778 break;
[2]779
[193]780 case EA_HEXDUMP:
[551]781 switch (SHORT2FROMMP(mp1)) {
[193]782 case LN_SETFOCUS:
[1804]783 WinSetDlgItemText(hwnd, EA_HELP, (CHAR *)GetPString(IDS_EADATAHELPTEXT));
784 break;
[193]785 case LN_KILLFOCUS:
[1804]786 WinSetDlgItemText(hwnd, EA_HELP, NullStr);
787 break;
[193]788 }
789 break;
[2]790
[193]791 case EA_MLE:
[551]792 switch (SHORT2FROMMP(mp1)) {
[193]793 case MLN_SETFOCUS:
[1804]794 WinSetDlgItemText(hwnd, EA_HELP, (CHAR *)GetPString(IDS_EADATAHELPTEXT));
795 break;
[193]796 case MLN_KILLFOCUS:
[1804]797 WinSetDlgItemText(hwnd, EA_HELP, NullStr);
798 break;
[193]799 case MLN_CHANGE:
[1804]800 WinEnableWindow(WinWindowFromID(hwnd, EA_CHANGE), TRUE);
801 break;
[193]802 }
803 break;
804 }
805 return 0;
[2]806
[193]807 case WM_COMMAND:
[551]808 switch (SHORT1FROMMP(mp1)) {
[1546]809 case EA_OPENFILE:
810 {
[1804]811 CHAR filename[CCHMAXPATH];
812 CHAR *p;
813 CHAR **list = NULL;
[1546]814
[1804]815 if (*eap->filename)
816 strcpy(filename, eap->filename);
817 WinDismissDlg(hwnd, 1);
818 ForwardslashToBackslash(filename);
[1546]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__);
[1804]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;
[1546]845 }
[193]846 case EA_ADD:
847 {
[1804]848 ADDEA add;
[2]849
[1804]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 }
[2]858 }
[193]859 break;
860 case EA_CHANGE:
[551]861 if (!eap->current)
[1804]862 WinShowWindow(WinWindowFromID(hwnd, EA_CHANGE), FALSE);
[551]863 else {
[2]864
[1804]865 CHAR *s;
866 USHORT control;
[2]867
[1804]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;
[2]896
[1804]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 }
[193]929 }
930 break;
[2]931
[193]932 case EA_DELETE:
[551]933 if (eap->head && eap->current) {
[2]934
[1804]935 EAOP2 eaop;
936 PFEA2LIST pfealist;
937 GEA2LIST gealist;
938 APIRET rc;
939 SHORT sSelect;
[2]940
[1804]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 }
[193]1003 }
[551]1004 if (!eap->head)
[1804]1005 WinSetDlgItemText(hwnd, EA_TEXT, (CHAR *)GetPString(IDS_EANOEAS));
[193]1006 break;
[2]1007
[193]1008 case IDM_HELP:
1009 if (hwndHelp)
[1804]1010 WinSendMsg(hwndHelp, HM_DISPLAY_HELP,
1011 MPFROM2SHORT(HELP_EAS, 0), MPFROMSHORT(HM_RESOURCEID));
[193]1012 break;
[2]1013
[193]1014 case DID_OK:
1015 WinDismissDlg(hwnd, 1);
1016 break;
[2]1017
[193]1018 case DID_CANCEL:
1019 WinDismissDlg(hwnd, 0);
1020 break;
1021 }
1022 return 0;
[2]1023
[193]1024 case WM_CLOSE:
1025 break;
[2]1026
[193]1027 case WM_DESTROY:
[551]1028 if (eap) {
1029 if (eap->head)
[1804]1030 Free_FEAList(eap->head);
[1547]1031 xfree(mp2, pszSrcFile, __LINE__);
[1039]1032 free(eap);
[193]1033 if (hptrIcon)
[1804]1034 WinDestroyPointer(hptrIcon);
[193]1035 hptrIcon = (HPOINTER) 0;
1036 }
1037 break;
[1157]1038 } // switch
[193]1039 return WinDefDlgProc(hwnd, msg, mp1, mp2);
[2]1040}
1041
[1804]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)
[193]1055{
[2]1056 PFEA2LIST pfealist = NULL;
[193]1057 EAOP2 eaop;
1058 APIRET rc;
1059 ULONG ealen;
1060 USHORT len, *num, *plen;
[1804]1061 CHAR *p, *peaval;
[2]1062
[1804]1063 DbgMsg(pszSrcFile, __LINE__, "SaveEA: entered for %s", filename);
1064
[193]1065 if (!filename || !current)
[1804]1066 return (PVOID)pfealist; // FIXME to complain
1067
[2]1068 len = strlen(newdata);
[725]1069 ealen = sizeof(FEA2LIST) + 24 + (ULONG) current->cbName + 1 +
[1804]1070 (ULONG)len + 4;
1071 // Do type specific adjustments to EA length
1072 switch (*(USHORT *)current->value) {
[193]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++;
[551]1081 while (*p) {
[193]1082 if (*p == '\n' && *(p + 1))
[1804]1083 ealen += sizeof(USHORT);
[193]1084 p++;
1085 }
1086 break;
1087 case EAT_MVMT:
1088 ealen += sizeof(USHORT) * 5;
1089 p = newdata;
1090 while (*p == '\n')
1091 p++;
[551]1092 while (*p) {
[193]1093 if (*p == '\n' && *(p + 1))
[1804]1094 ealen += (sizeof(USHORT) * 2);
[193]1095 p++;
1096 }
1097 break;
1098 default:
[1804]1099 // FIXME to complain
[193]1100 return (PVOID) pfealist;
[1804]1101 } // switch EAT_...
[193]1102
[1804]1103 if (!xDosAllocMem((PPVOID)&pfealist, ealen, pszSrcFile, __LINE__)) {
1104 // Build FEA2LIST
[193]1105 memset(pfealist, 0, ealen);
[725]1106 pfealist->list[0].oNextEntryOffset = 0;
[1804]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
[193]1109
[551]1110 pfealist->list[0].cbName = current->cbName;
1111 memcpy(pfealist->list[0].szName, current->name,
[1804]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) {
[2]1117 case EAT_EA:
1118 case EAT_ASCII:
[1804]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;
[2]1125 break;
1126 case EAT_MVST:
[1804]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;
[193]1132 *num = 0;
[1804]1133 peaval += sizeof(USHORT);
1134 *(USHORT *)peaval = (USHORT)EAT_ASCII;
1135 peaval += sizeof(USHORT);
1136 plen = (USHORT *)peaval;
[193]1137 *plen = 0;
[1804]1138 peaval += sizeof(USHORT);
[2]1139 p = newdata;
[193]1140 while (*p == '\n')
[1804]1141 p++;
[551]1142 while (*p) {
[1804]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 }
[2]1156 }
1157 break;
[1804]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......................
[2]1169 * 000030 0A 00 4B 65 79 20 70 68 72 61 73 65 Key phrase
[1804]1170 */
1171 case EAT_MVMT:
1172 *(USHORT *)peaval = (USHORT)EAT_MVMT;
1173 peaval += sizeof(USHORT);
1174 *(USHORT *)peaval = *(USHORT *)(current->value + sizeof(USHORT));
[193]1175 peaval += sizeof(USHORT);
[1804]1176 num = (USHORT *)peaval;
1177 *num = 0;
1178 peaval += sizeof(USHORT);
1179 *(USHORT *)peaval = (USHORT)EAT_ASCII;
[193]1180 peaval += sizeof(USHORT);
[1804]1181 plen = (USHORT *)peaval;
[2]1182 *plen = 0;
[193]1183 peaval += sizeof(USHORT);
[1804]1184 p = newdata;
[551]1185 while (*p == '\n')
[1804]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;
[2]1201 peaval += sizeof(USHORT);
1202 }
[1804]1203 }
1204 break;
1205 } // switch EAT_...
1206
[2]1207 pfealist->list[0].cbValue = peaval - (pfealist->list[0].szName + pfealist->list[0].cbName + 1);
[725]1208 eaop.fpGEA2List = (PGEA2LIST)0;
1209 eaop.fpFEA2List = pfealist;
[1804]1210 eaop.oError = 0;
[2]1211 pfealist->cbList = 13 + (ULONG) pfealist->list[0].cbName +
[1804]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 }
[827]1229#else
[1804]1230 // Rewrite EA
1231 rc = xDosSetPathInfo(filename, FIL_QUERYEASIZE,
[551]1232 &eaop, sizeof(eaop), DSPI_WRTTHRU);
[2]1233#endif
1234 if (rc) {
1235 DosFreeMem(pfealist);
[551]1236 pfealist = NULL;
[347]1237 }
[1804]1238 if (rc && !silentfail) {
1239 if (rc == ERROR_ACCESS_DENIED || rc == ERROR_SHARING_VIOLATION) {
1240 saymsg(MB_ENTER,
1241 HWND_DESKTOP,
[347]1242 GetPString(IDS_OOPSTEXT),
1243 GetPString(IDS_CANTWRITEEATEXT), current->name, filename);
[1804]1244 }
1245 else {
1246 Dos_Error(MB_ENTER,
1247 rc,
1248 HWND_DESKTOP,
1249 pszSrcFile,
1250 __LINE__,
[347]1251 GetPString(IDS_ERRORWRITEEATEXT),
[2]1252 current->name, filename, eaop.oError);
1253 }
[1804]1254 }
[2]1255 }
1256 return (PVOID)pfealist;
[193]1257}
1258
[1673]1259HOLDFEA *GetFileEAs(CHAR * filename, BOOL ishandle, BOOL silentfail)
[2]1260{
[193]1261 // load eas from disk into HOLDFEA linked list
[847]1262
[193]1263 HOLDFEA *head = NULL, *info, *last = NULL;
1264 FILESTATUS4 fsa4;
1265 HFILE handle;
[2]1266 ULONG action;
[193]1267 APIRET rc;
[2]1268
[844]1269 if (!filename)
[1804]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 |
[193]1275 OPEN_SHARE_DENYREADWRITE |
1276 OPEN_ACCESS_READWRITE, (PEAOP2)0)) {
[847]1277 if (ishandle)
[1804]1278 handle = *(HFILE *) filename;
1279 if (!DosQueryFileInfo(handle, FIL_QUERYEASIZE, (PVOID)&fsa4,
[725]1280 (ULONG) sizeof(fsa4)) &&
[193]1281 fsa4.cbList > 4)
1282 {
[2]1283 PDENA2 pdena;
1284 EAOP2 eaop;
[193]1285 PGEA2LIST pgealist;
[1157]1286 PFEA2LIST pfealist;
[1804]1287 PGEA2 pgea;
[2]1288 ULONG ulEntry = 1; // Ordinal of EA to return
[551]1289 ULONG ulCount = 1; // # of EAs to return per call
1290
[1804]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);
[2]1362 DosPostEventSem(CompactSem);
[193]1363 } // if malloc OK
[2]1364 }
1365 if (!ishandle)
[551]1366 DosClose(handle);
[1804]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,
[725]1373 (ULONG)sizeof(fsa4)) &&
[193]1374 fsa4.cbList > 4)
1375 {
[2]1376 PDENA2 pdena;
1377 EAOP2 eaop;
[193]1378 PGEA2LIST pgealist;
[725]1379 PFEA2LIST pfealist;
[2]1380 PGEA2 pgea;
[551]1381 ULONG ulEntry = 1, ulCount = 1;
1382
[1804]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
[2]1473 } // if DosQueryPathInfo OK
1474 } // if need DosQueryPathInfo
1475 return head;
[193]1476}
1477
[1673]1478VOID Free_FEAList(HOLDFEA * pFEA)
[2]1479{
1480 // free a linked list of HOLDFEAs
1481
[551]1482 register HOLDFEA *next;
[1673]1483
[551]1484 while (pFEA) {
[1009]1485 // Free linked list
[1039]1486 next = pFEA->next;
[2]1487 xfree(pFEA->pfea, pszSrcFile, __LINE__);
1488 free(pFEA);
1489 pFEA = next;
1490 }
[795]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.