source: trunk/dll/droplist.c@ 536

Last change on this file since 536 was 451, checked in by root, 19 years ago

Comments

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