source: trunk/dll/droplist.c@ 672

Last change on this file since 672 was 629, checked in by Steven Levine, 18 years ago

Add debug code to track down reason for PMERR_SOURCE_SAME_AS_TARGET

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