source: trunk/dll/droplist.c@ 1567

Last change on this file since 1567 was 1498, checked in by Gregg Young, 16 years ago

Changes to get FM2 to compile with the latest watcom 1.9 beta (mostly type casts of CHAR CONSTANT * to CHAR *). Changes to get the environment settings working everywhere again (broken by the change that moved commands to the INI); Added an environment size variable (set to 2048 which was the largest I found hard coded). Still need to find everywhere the environment size is set and use this variable.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 13.5 KB
Line 
1/***********************************************************************
2
3 $Id: droplist.c 1498 2010-01-18 00:57:01Z gyoung $
4
5 Drop support
6
7 Copyright (c) 1993-98 M. Kimes
8 Copyright (c) 2003, 2010 Steven H.Levine
9
10 22 Nov 02 SHL Baseline
11 08 Feb 03 SHL DropHelp: calc EA size consistently
12 21 Jul 06 SHL Drop dup code
13 22 Jul 06 SHL Check more run time errors
14 06 Apr 07 GKY Work around PM DragInfo and DrgFreeDISH limits
15 06 Apr 07 GKY Add some error checking in drag/drop
16 19 Apr 07 SHL Use FreeDragInfoData
17 19 Apr 07 SHL Add more drag/drop error checking
18 21 Apr 07 SHL Add debug code to track down reason for PMERR_SOURCE_SAME_AS_TARGET
19 10 Jun 07 GKY Add CheckPmDrgLimit including IsFm2Window as part of work around PM drag limit
20 02 Aug 07 SHL Lock in DoFileDrop sanity checks
21 20 Aug 07 GKY Move #pragma alloc_text to end for OpenWatcom compat
22 08 Mar 09 GKY Additional strings move to PCSZs
23 17 JAN 10 GKY Changes to get working with Watcom 1.9 Beta (1/16/10). Mostly cast CHAR CONSTANT * as CHAR *.
24
25***********************************************************************/
26
27#include <string.h>
28
29#define INCL_DOS
30#define INCL_WIN
31#define INCL_LONGLONG
32
33#include "fm3dll.h"
34#include "avl.h" // Data declaration(s)
35#include "init.h" // Data declaration(s)
36#include "fm3str.h"
37#include "errutil.h" // Dos_Error...
38#include "strutil.h" // GetPString
39#include "droplist.h"
40#include "draglist.h" // FreeDragInfoData
41#include "misc.h" // IsFm2Window
42#include "wrappers.h" // xrealloc
43
44#include "fortify.h"
45
46static PSZ pszSrcFile = __FILE__;
47
48static ULONG GetDropCount(HWND hwnd, MPARAM mp1);
49static BOOL TwoDrgNames(PDRAGITEM pDItem, CHAR * buffer1, ULONG buflen1,
50 char *buffer2, ULONG buflen2);
51
52BOOL CheckPmDrgLimit(PDRAGINFO pDInfo)
53{
54 /*
55 * Checks for FM2 source window then checks window words
56 * for ulItemsToUnHilite and if it is not zero displays a
57 * message to the users that not all items are being dragged
58 * returns TRUE on success
59 */
60 if (!DrgAccessDraginfo(pDInfo)) {
61 Win_Error(HWND_DESKTOP, HWND_DESKTOP, pszSrcFile, __LINE__,
62 PCSZ_DRGACCESSDRAGINFO);
63 return FALSE;
64 }
65 else if (IsFm2Window(pDInfo->hwndSource, FALSE)) {
66 DIRCNRDATA *dcdsrc = INSTDATA(pDInfo->hwndSource);
67 if (dcdsrc->ulItemsToUnHilite) {
68 saymsg(MB_OK | MB_INFORMATION,
69 HWND_DESKTOP,
70 GetPString(IDS_ERRORTEXT),
71 GetPString(IDS_EXCEEDPMDRGLMT));
72 }
73 DrgFreeDraginfo(pDInfo);
74 }
75 return TRUE;
76}
77
78BOOL TwoDrgNames(PDRAGITEM pDItem, CHAR * buffer1, ULONG buflen1,
79 char *buffer2, ULONG buflen2)
80{
81 /*
82 * Gets archive name from directory field, file name from file field
83 * Returns FALSE on error, TRUE on success.
84 */
85
86 register ULONG len;
87 BOOL ret = FALSE;
88
89 if (pDItem && buffer2 && buflen2) { /* else error calling function */
90 if (buffer1 && buflen1) /* zero buffers */
91 *buffer1 = 0;
92 *buffer2 = 0;
93
94 if (buffer1 && buflen1) {
95 len = DrgQueryStrName(pDItem->hstrContainerName, buflen1, buffer1);
96 buffer1[len] = 0;
97 if (len) { /* be sure we get full pathname of arc file */
98
99 char szTemp[CCHMAXPATH + 2];
100
101 if (!DosQueryPathInfo(buffer1,
102 FIL_QUERYFULLNAME, szTemp, sizeof(szTemp))) {
103 strncpy(buffer1, szTemp, buflen1);
104 buffer1[buflen1 - 1] = 0;
105 }
106 }
107 { /* be sure that file/directory is accessible */
108 FILESTATUS3 fsa3;
109
110 DosError(FERR_DISABLEHARDERR);
111 if (DosQueryPathInfo(buffer1,
112 FIL_STANDARD,
113 &fsa3,
114 sizeof(fsa3)) ||
115 fsa3.attrFile & FILE_DIRECTORY) {
116 *buffer1 = 0;
117 return ret;
118 }
119 }
120 }
121
122 len = DrgQueryStrName(pDItem->hstrSourceName, buflen2, buffer2);
123 buffer2[len] = 0;
124 if (len)
125 ret = TRUE;
126 }
127 return ret;
128}
129
130BOOL FullDrgName(PDRAGITEM pDItem, CHAR * buffer, ULONG buflen)
131{
132 /*
133 * Gets full name of file from a dragged item.
134 * Returns FALSE on error, TRUE on success.
135 */
136
137 ULONG len, blen;
138 BOOL ret = FALSE;
139 APIRET rc;
140 FILESTATUS3 fsa3;
141
142 if (pDItem && buffer && buflen) { /* else error calling function */
143 *buffer = 0; /* zero buffer */
144
145 blen = DrgQueryStrName(pDItem->hstrContainerName, buflen, buffer);
146 if(!blen)
147 Win_Error(HWND_DESKTOP, HWND_DESKTOP, pszSrcFile, __LINE__,
148 "DrgQueryStrName");
149 else {
150 if (*(buffer + (blen - 1)) != '\\') {
151 *(buffer + blen) = '\\';
152 blen++;
153 }
154 }
155 buffer[blen] = 0;
156 len = DrgQueryStrName(pDItem->hstrSourceName,
157 buflen - blen, buffer + blen);
158 buffer[blen + len] = 0;
159 { /* be sure we get full pathname of file/directory */
160 char szTemp[CCHMAXPATH + 2];
161 rc = DosQueryPathInfo(buffer,
162 FIL_QUERYFULLNAME, szTemp, sizeof(szTemp));
163 if (!rc) {
164 strncpy(buffer, szTemp, buflen);
165 buffer[buflen - 1] = 0;
166 }
167 else
168 Dos_Error(MB_CANCEL, rc, HWND_DESKTOP, pszSrcFile, __LINE__,
169 PCSZ_DOSQUERYPATHINFO);
170 }
171
172 rc = DosQueryPathInfo(buffer, FIL_STANDARD, &fsa3, sizeof(fsa3));
173 if (!rc)
174 ret = TRUE;
175 else {
176 Dos_Error(MB_CANCEL, rc, HWND_DESKTOP, pszSrcFile, __LINE__,
177 PCSZ_DOSQUERYPATHINFO);
178 *buffer = 0;
179 }
180 }
181 return ret;
182}
183
184BOOL GetOneDrop(HWND hwnd, MPARAM mp1, MPARAM mp2, char *buffer, ULONG buflen)
185{
186 PDRAGITEM pDItem; /* DRAGITEM struct ptr */
187 PDRAGINFO pDInfo; /* DRAGINFO struct ptr */
188 ULONG numitems;
189 register ULONG curitem;
190 BOOL ret = FALSE;
191
192 if (buffer && buflen)
193 *buffer = 0; /* zero buffer field */
194
195 pDInfo = (PDRAGINFO) mp1; /* Get DRAGINFO pointer */
196 if (pDInfo) {
197 if (!DrgAccessDraginfo(pDInfo)) {
198 Win_Error(HWND_DESKTOP, HWND_DESKTOP, pszSrcFile, __LINE__,
199 PCSZ_DRGACCESSDRAGINFO);
200 }
201 else {
202 numitems = DrgQueryDragitemCount(pDInfo);
203 pDItem = DrgQueryDragitemPtr(pDInfo,0);
204 if (buflen && buffer) {
205 if (DrgVerifyRMF(pDItem, /* Check valid rendering */
206 (CHAR *) DRM_OS2FILE, /* mechanisms and data */
207 NULL) && !(pDItem->fsControl & DC_PREPARE))
208 ret = FullDrgName(pDItem, buffer, buflen);
209 }
210 // Return targetfail to source for all items - fixme to know why
211 for (curitem = 0; curitem < numitems; curitem++) {
212 pDItem = DrgQueryDragitemPtr(pDInfo,curitem);
213 DrgSendTransferMsg(pDInfo->hwndSource, DM_ENDCONVERSATION,
214 MPFROMLONG(pDItem->ulItemID),
215 MPFROMLONG(DMFL_TARGETFAIL));
216 }
217 FreeDragInfoData(hwnd, pDInfo);
218 }
219 }
220
221 return ret;
222}
223
224BOOL AcceptOneDrop(HWND hwnd, MPARAM mp1, MPARAM mp2)
225{
226 PDRAGITEM pDItem; /* Pointer to DRAGITEM */
227 PDRAGINFO pDInfo; /* Pointer to DRAGINFO */
228 BOOL ret = FALSE;
229
230 pDInfo = (PDRAGINFO) mp1; /* Get DRAGINFO pointer */
231 if (pDInfo) {
232 if (!DrgAccessDraginfo(pDInfo)) {
233 Win_Error(HWND_DESKTOP, HWND_DESKTOP, pszSrcFile, __LINE__,
234 PCSZ_DRGACCESSDRAGINFO);
235 }
236 else {
237 pDItem = DrgQueryDragitemPtr(pDInfo, 0);
238
239 /* Check valid rendering mechanisms and data formats */
240 if (DrgVerifyRMF(pDItem, (CHAR *) DRM_OS2FILE, NULL))
241 ret = TRUE;
242
243 DrgFreeDraginfo(pDInfo);
244 }
245 }
246 return ret;
247}
248
249static ULONG GetDropCount(HWND hwnd, MPARAM mp1)
250{
251 PDRAGINFO pDInfo;
252 ULONG numitems;
253
254 pDInfo = mp1;
255 if (pDInfo) {
256 if (!DrgAccessDraginfo(pDInfo)) {
257 Win_Error(HWND_DESKTOP, HWND_DESKTOP, pszSrcFile, __LINE__,
258 PCSZ_DRGACCESSDRAGINFO);
259 numitems = 0; // Oh well
260 }
261 else {
262 numitems = DrgQueryDragitemCount(pDInfo);
263 FreeDragInfoData(hwnd, pDInfo);
264 }
265 }
266 return numitems;
267}
268
269void DropHelp(MPARAM mp1, MPARAM mp2, HWND hwnd, PCSZ text)
270{
271 ULONG numitems;
272
273 numitems = GetDropCount(hwnd, mp1);
274 saymsg(MB_ENTER | MB_ICONASTERISK,
275 hwnd, GetPString(IDS_FM2DROPHELPTEXT), text, numitems, numitems);
276}
277
278LISTINFO *DoFileDrop(HWND hwndCnr, PCSZ directory, BOOL arcfilesok,
279 MPARAM mp1, MPARAM mp2)
280{
281 /* builds a list from the dropped files */
282
283 BOOL isArc = FALSE, arctest = FALSE;
284 PDRAGITEM pDItem;
285 PDRAGINFO pDInfo;
286 PCNRITEM pci;
287 CHAR szFrom[CCHMAXPATH + 1], szArc[CCHMAXPATH + 1];
288 CHAR **files = NULL;
289 UINT numfiles = 0, numalloc = 0;
290 ULONG curitem, numitems;
291 PULONGLONG pcbFile = NULL;
292 PULONG pulitemID = NULL;
293 LISTINFO *li = NULL;
294 ARC_TYPE *arcinfo = NULL;
295 USHORT Operation;
296
297 UINT numok = 0; // 02 Aug 07 SHL fixme to be gone someday
298 UINT numfail = 0;
299
300 *szArc = 0;
301 pci = (PCNRITEM) ((PCNRDRAGINFO) mp2)->pRecord;
302 pDInfo = ((PCNRDRAGINFO) mp2)->pDragInfo;
303 if (!pDInfo) {
304 Runtime_Error(pszSrcFile, __LINE__, "No drag info");
305 return NULL;
306 }
307 if (!DrgAccessDraginfo(pDInfo)) {
308 Win_Error(HWND_DESKTOP, HWND_DESKTOP, pszSrcFile, __LINE__,
309 PCSZ_DRGACCESSDRAGINFO);
310 numitems = 0; // Avoid death
311 }
312 else {
313 numitems = DrgQueryDragitemCount(pDInfo);
314 Operation = pDInfo->usOperation;
315 pDItem = DrgQueryDragitemPtr(pDInfo, 0);
316 if (!pDItem) {
317 Win_Error(HWND_DESKTOP, HWND_DESKTOP, pszSrcFile, __LINE__,
318 "DrgQueryDragitemPtr");
319 }
320 else {
321 if (Operation == DO_MOVE && !(pDItem->fsSupportedOps & DO_MOVEABLE)) {
322 saymsg(MB_ENTER, HWND_DESKTOP, GetPString(IDS_WARNINGTEXT),
323 GetPString(IDS_FORCINGCOPYTEXT));
324 Operation = DO_COPY;
325 }
326 }
327 }
328
329 for (curitem = 0; curitem < numitems; curitem++) {
330 pDItem = DrgQueryDragitemPtr(pDInfo, curitem);
331 if (!pDItem) {
332 Win_Error(hwndCnr, hwndCnr, pszSrcFile, __LINE__,
333 "DrgQueryDragitemPtr(%u)", curitem);
334 break;
335 }
336
337 /* ambiguous drop request -- see what's allowed */
338 if (Operation == DO_DEFAULT || Operation >= DO_UNKNOWN) {
339 if (pDItem->fsSupportedOps & DO_COPYABLE)
340 Operation = DO_COPY;
341 else if (pDItem->fsSupportedOps & DO_MOVEABLE)
342 Operation = DO_MOVE;
343 else if (pDItem->fsSupportedOps & DO_LINKABLE)
344 Operation = DO_LINK;
345 }
346 else {
347 /* ignore object if selected command not allowed for it */
348 BOOL ok;
349 switch (Operation) {
350 case DO_MOVE:
351 ok = pDItem->fsSupportedOps & DO_MOVEABLE;
352 break;
353 case DO_COPY:
354 ok = pDItem->fsSupportedOps & DO_COPYABLE;
355 break;
356 case DO_LINK:
357 ok = pDItem->fsSupportedOps & DO_LINKABLE;
358 break;
359 default:
360 ok = FALSE;
361 }
362 if (!ok) {
363 // Fail request
364 DrgSendTransferMsg(pDItem->hwndItem,
365 DM_ENDCONVERSATION,
366 MPFROMLONG(pDItem->ulItemID),
367 MPFROMLONG(DMFL_TARGETFAIL));
368 numfail++;
369 continue;
370 }
371 }
372
373 if (DrgVerifyRMF(pDItem,
374 (CHAR *) DRM_OS2FILE,
375 NULL) ||
376 (arcfilesok &&
377 ((arctest = DrgVerifyRMF(pDItem,
378 (CHAR *) DRM_FM2ARCMEMBER,
379 (CHAR *) DRF_FM2ARCHIVE)) != FALSE))) {
380 if (pDItem->fsControl & DC_PREPARE) {
381 DrgSendTransferMsg(pDItem->hwndItem,
382 DM_ENDCONVERSATION,
383 MPFROMLONG(pDItem->ulItemID),
384 MPFROMLONG(DMFL_TARGETFAIL));
385 numfail++;
386 continue;
387 }
388
389 if (arctest || isArc) {
390 if (!isArc) {
391 if (TwoDrgNames(pDItem,
392 szArc,
393 sizeof(szArc),
394 szFrom, sizeof(szFrom)) && *szArc && *szFrom) {
395 isArc = TRUE;
396 arcinfo = find_type(szArc, arcsighead);
397 }
398 if (!arcinfo || !arcinfo->extract || !*arcinfo->extract) {
399 *szArc = *szFrom = 0;
400 isArc = FALSE;
401 }
402 }
403 else
404 TwoDrgNames(pDItem, NULL, 0, szFrom, sizeof(szFrom));
405 }
406 else
407 FullDrgName(pDItem, szFrom, sizeof(szFrom));
408
409 if (!*szFrom) {
410 DrgSendTransferMsg(pDItem->hwndItem,
411 DM_ENDCONVERSATION,
412 MPFROMLONG(pDItem->ulItemID),
413 MPFROMLONG(DMFL_TARGETFAIL));
414 numfail++;
415 continue;
416 }
417
418 if (numfiles + 2 > numalloc) {
419
420 CHAR **test;
421 PULONG pltest;
422 PULONGLONG plltest;
423
424 numalloc += 12;
425 test =
426 xrealloc(files, numalloc * sizeof(CHAR *), pszSrcFile, __LINE__);
427 if (!test)
428 break;
429 files = test;
430 plltest =
431 xrealloc(pcbFile, numalloc * sizeof(ULONGLONG), pszSrcFile, __LINE__);
432 if (!plltest)
433 break;
434 pcbFile = plltest;
435 pltest =
436 xrealloc(pulitemID, numalloc * sizeof(ULONG), pszSrcFile, __LINE__);
437 if (!pltest)
438 break;
439 pulitemID = pltest;
440 }
441 pcbFile[numfiles] = 0;
442 if (!isArc) {
443
444 FILESTATUS4L fsa4;
445
446 if (!DosQueryPathInfo(szFrom, FIL_QUERYEASIZEL, &fsa4, sizeof(fsa4)))
447 pcbFile[numfiles] = fsa4.cbFile + CBLIST_TO_EASIZE(fsa4.cbList);
448 }
449 pulitemID[numfiles] = pDItem->ulItemID;
450 files[numfiles] = xstrdup(szFrom, pszSrcFile, __LINE__);
451 files[numfiles + 1] = NULL;
452 if (!files[numfiles])
453 break;
454 numfiles++;
455 DrgSendTransferMsg(pDItem->hwndItem,
456 DM_ENDCONVERSATION,
457 MPFROMLONG(pDItem->ulItemID),
458 MPFROMLONG(DMFL_TARGETSUCCESSFUL));
459 numok++;
460 }
461 else {
462 DrgSendTransferMsg(pDItem->hwndItem,
463 DM_ENDCONVERSATION,
464 MPFROMLONG(pDItem->ulItemID),
465 MPFROMLONG(DMFL_TARGETFAIL));
466 numfail++;
467 }
468 } // for curitem
469
470 if (files && numfiles && files[0] && pcbFile && pulitemID) {
471# ifdef FORTIFY
472 Fortify_EnterScope();
473# endif
474 li = xmallocz(sizeof(LISTINFO), pszSrcFile, __LINE__);
475 if (li) {
476 li->type = Operation;
477 li->hwnd = hwndCnr;
478 li->list = files;
479 li->cbFile = pcbFile;
480 li->ulitemID = pulitemID;
481 li->hwndS = pDInfo->hwndSource;
482 if (!pci && directory)
483 strcpy(li->targetpath, directory);
484 else if (pci)
485 strcpy(li->targetpath, pci->pszFileName);
486 if (isArc) {
487 strcpy(li->arcname, szArc);
488 li->info = arcinfo;
489 }
490 SortList(li);
491 }
492 else {
493 xfree(pcbFile, pszSrcFile, __LINE__);
494 xfree(pulitemID, pszSrcFile, __LINE__);
495 if (files)
496 FreeList(files);
497 }
498 }
499 else {
500 xfree(pcbFile, pszSrcFile, __LINE__);
501 xfree(pulitemID, pszSrcFile, __LINE__);
502 if (files)
503 FreeList(files);
504 }
505
506 FreeDragInfoData(hwndCnr, pDInfo);
507# ifdef FORTIFY
508 Fortify_LeaveScope();
509# endif
510
511 // 02 Aug 07 SHL fixme to be gone someday or use Runtime_Error if really an error
512 if (numfail || numok == 0)
513 DbgMsg(pszSrcFile, __LINE__, "calling FreeDragInfoData with %u ok, %u failed", numok, numfail);
514
515 return li;
516}
517
518#pragma alloc_text(DROPLIST,DoFileDrop,FullDrgName,TwoDrgNames,GetOneDrop,CheckPmDrgLimit)
Note: See TracBrowser for help on using the repository browser.