source: trunk/dll/droplist.c@ 689

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

Update History and file headers for CheckPmDrgLimit etc changes

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 12.9 KB
Line 
1
2/***********************************************************************
3
4 $Id: droplist.c 688 2007-06-10 22:06:03Z gyoung $
5
6 Drop support
7
8 Copyright (c) 1993-98 M. Kimes
9 Copyright (c) 2003, 2006 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
22***********************************************************************/
23
24#define INCL_DOS
25#define INCL_WIN
26#include <os2.h>
27
28#include <stdio.h>
29#include <stdlib.h>
30#include <string.h>
31#include <ctype.h>
32
33#include "fm3dll.h"
34#include "fm3str.h"
35
36static PSZ pszSrcFile = __FILE__;
37
38static ULONG GetDropCount(HWND hwnd, MPARAM mp1);
39
40#pragma alloc_text(DROPLIST,DoFileDrop,FullDrgName,TwoDrgNames,GetOneDrop,CheckPmDrgLimit)
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
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 INT numfiles = 0, numalloc = 0;
290 ULONG curitem, numitems, *cbFile = NULL, *ulitemID = NULL;
291 LISTINFO *li = NULL;
292 ARC_TYPE *arcinfo = NULL;
293 USHORT Operation;
294
295 *szArc = 0;
296 pci = (PCNRITEM) ((PCNRDRAGINFO) mp2)->pRecord;
297 pDInfo = ((PCNRDRAGINFO) mp2)->pDragInfo;
298 if (!pDInfo) {
299 Runtime_Error(pszSrcFile, __LINE__, "No drag info");
300 return NULL;
301 }
302 if (!DrgAccessDraginfo(pDInfo)) {
303 Win_Error(HWND_DESKTOP, HWND_DESKTOP, pszSrcFile, __LINE__,
304 "DrgAccessDraginfo");
305 numitems = 0; // Avoid death
306 }
307 else {
308 numitems = DrgQueryDragitemCount(pDInfo);
309 Operation = pDInfo->usOperation;
310 pDItem = DrgQueryDragitemPtr(pDInfo, 0);
311 if (!pDItem) {
312 Win_Error(HWND_DESKTOP, HWND_DESKTOP, pszSrcFile, __LINE__,
313 "DrgQueryDragitemPtr");
314 }
315 else {
316 if (Operation == DO_MOVE && !(pDItem->fsSupportedOps & DO_MOVEABLE)) {
317 saymsg(MB_ENTER, HWND_DESKTOP, GetPString(IDS_WARNINGTEXT),
318 GetPString(IDS_FORCINGCOPYTEXT));
319 Operation = DO_COPY;
320 }
321 }
322 }
323
324 for (curitem = 0; curitem < numitems; curitem++) {
325 pDItem = DrgQueryDragitemPtr(pDInfo, curitem);
326 if (!pDItem) {
327 Win_Error(hwndCnr, hwndCnr, pszSrcFile, __LINE__,
328 "DrgQueryDragitemPtr(%u)", curitem);
329 break;
330 }
331
332 /* ambiguous drop request -- see what's allowed */
333 if (Operation == DO_DEFAULT || Operation >= DO_UNKNOWN) {
334 if (pDItem->fsSupportedOps & DO_COPYABLE)
335 Operation = DO_COPY;
336 else if (pDItem->fsSupportedOps & DO_MOVEABLE)
337 Operation = DO_MOVE;
338 else if (pDItem->fsSupportedOps & DO_LINKABLE)
339 Operation = DO_LINK;
340 }
341 else {
342 /* ignore object if selected command not allowed for it */
343 BOOL ok;
344 switch (Operation) {
345 case DO_MOVE:
346 ok = pDItem->fsSupportedOps & DO_MOVEABLE;
347 break;
348 case DO_COPY:
349 ok = pDItem->fsSupportedOps & DO_COPYABLE;
350 break;
351 case DO_LINK:
352 ok = pDItem->fsSupportedOps & DO_LINKABLE;
353 break;
354 default:
355 ok = FALSE;
356 }
357 if (!ok) {
358 // Fail request
359 DrgSendTransferMsg(pDItem->hwndItem,
360 DM_ENDCONVERSATION,
361 MPFROMLONG(pDItem->ulItemID),
362 MPFROMLONG(DMFL_TARGETFAIL));
363 continue;
364 }
365 }
366
367 if (DrgVerifyRMF(pDItem,
368 DRM_OS2FILE,
369 NULL) ||
370 (arcfilesok &&
371 ((arctest = DrgVerifyRMF(pDItem,
372 DRM_FM2ARCMEMBER,
373 DRF_FM2ARCHIVE)) != FALSE))) {
374 if (pDItem->fsControl & DC_PREPARE) {
375 DrgSendTransferMsg(pDItem->hwndItem,
376 DM_ENDCONVERSATION,
377 MPFROMLONG(pDItem->ulItemID),
378 MPFROMLONG(DMFL_TARGETFAIL));
379 continue;
380 }
381
382 if (arctest || isArc) {
383 if (!isArc) {
384 if (TwoDrgNames(pDItem,
385 szArc,
386 sizeof(szArc),
387 szFrom, sizeof(szFrom)) && *szArc && *szFrom) {
388 isArc = TRUE;
389 arcinfo = find_type(szArc, arcsighead);
390 }
391 if (!arcinfo || !arcinfo->extract || !*arcinfo->extract) {
392 *szArc = *szFrom = 0;
393 isArc = FALSE;
394 }
395 }
396 else
397 TwoDrgNames(pDItem, NULL, 0, szFrom, sizeof(szFrom));
398 }
399 else
400 FullDrgName(pDItem, szFrom, sizeof(szFrom));
401
402 if (!*szFrom) {
403 DrgSendTransferMsg(pDItem->hwndItem,
404 DM_ENDCONVERSATION,
405 MPFROMLONG(pDItem->ulItemID),
406 MPFROMLONG(DMFL_TARGETFAIL));
407 continue;
408 }
409
410 if (numfiles + 2 > numalloc) {
411
412 CHAR **test;
413 ULONG *ltest;
414
415 numalloc += 12;
416 test =
417 xrealloc(files, numalloc * sizeof(CHAR *), pszSrcFile, __LINE__);
418 if (!test)
419 break;
420 files = test;
421 ltest =
422 xrealloc(cbFile, numalloc * sizeof(ULONG), pszSrcFile, __LINE__);
423 if (!ltest)
424 break;
425 cbFile = ltest;
426 ltest =
427 xrealloc(ulitemID, numalloc * sizeof(ULONG), pszSrcFile, __LINE__);
428 if (!ltest)
429 break;
430 ulitemID = ltest;
431 }
432 cbFile[numfiles] = 0;
433 if (!isArc) {
434
435 FILESTATUS4 fsa4;
436
437 if (!DosQueryPathInfo(szFrom, FIL_QUERYEASIZE, &fsa4, sizeof(fsa4)))
438 cbFile[numfiles] = fsa4.cbFile + CBLIST_TO_EASIZE(fsa4.cbList);
439 }
440 ulitemID[numfiles] = pDItem->ulItemID;
441 files[numfiles] = xstrdup(szFrom, pszSrcFile, __LINE__);
442 files[numfiles + 1] = NULL;
443 if (!files[numfiles])
444 break;
445 numfiles++;
446 DrgSendTransferMsg(pDItem->hwndItem,
447 DM_ENDCONVERSATION,
448 MPFROMLONG(pDItem->ulItemID),
449 MPFROMLONG(DMFL_TARGETSUCCESSFUL));
450 }
451 else
452 DrgSendTransferMsg(pDItem->hwndItem,
453 DM_ENDCONVERSATION,
454 MPFROMLONG(pDItem->ulItemID),
455 MPFROMLONG(DMFL_TARGETFAIL));
456 } // for curitem
457
458 if (files && numfiles && files[0] && cbFile && ulitemID) {
459 li = xmallocz(sizeof(LISTINFO), pszSrcFile, __LINE__);
460 if (li) {
461 li->type = Operation;
462 li->hwnd = hwndCnr;
463 li->list = files;
464 li->cbFile = cbFile;
465 li->ulitemID = ulitemID;
466 li->hwndS = pDInfo->hwndSource;
467 if (!pci && directory)
468 strcpy(li->targetpath, directory);
469 else if (pci)
470 strcpy(li->targetpath, pci->szFileName);
471 if (isArc) {
472 strcpy(li->arcname, szArc);
473 li->info = arcinfo;
474 }
475 SortList(li);
476 }
477 else {
478 if (cbFile)
479 free(cbFile);
480 if (ulitemID)
481 free(ulitemID);
482 if (files)
483 FreeList(files);
484 }
485 }
486 else {
487 if (cbFile)
488 free(cbFile);
489 if (ulitemID)
490 free(ulitemID);
491 if (files)
492 FreeList(files);
493 }
494
495 // fixme to know why PM thinks drop not done
496 // this will avoid DrgFreeDraginfo complaints from FreeDragInfoData
497 DbgMsg(pszSrcFile, __LINE__, "calling FreeDragInfoData");
498 FreeDragInfoData(hwndCnr, pDInfo);
499
500 return li;
501}
Note: See TracBrowser for help on using the repository browser.