source: trunk/dll/droplist.c@ 593

Last change on this file since 593 was 593, checked in by Gregg Young, 19 years ago

Changes to remove GetPString from window class names

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