source: trunk/dll/droplist.c@ 796

Last change on this file since 796 was 793, checked in by Gregg Young, 18 years ago

Move #pragma alloc_text to end for OpenWatcom compat

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