rpcrt4: Retrieve the maximum token length from the security provider rather than...
[wine] / dlls / gphoto2.ds / ds_ctrl.c
1 /*
2  * Copyright 2000 Corel Corporation
3  * Copyright 2006 Marcus Meissner
4  *
5  * This library is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU Lesser General Public
7  * License as published by the Free Software Foundation; either
8  * version 2.1 of the License, or (at your option) any later version.
9  *
10  * This library is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13  * Lesser General Public License for more details.
14  *
15  * You should have received a copy of the GNU Lesser General Public
16  * License along with this library; if not, write to the Free Software
17  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
18  */
19
20 #include "config.h"
21
22 #ifdef HAVE_UNISTD_H
23 # include <unistd.h>
24 #endif
25 #include <stdlib.h>
26 #include <stdio.h>
27 #include "twain.h"
28 #include "gphoto2_i.h"
29 #include "wine/debug.h"
30
31 WINE_DEFAULT_DEBUG_CHANNEL(twain);
32
33 static void
34 load_filesystem(const char *folder) {
35 #ifdef HAVE_GPHOTO2
36     int         i, count, ret;
37     CameraList  *list;
38
39     ret = gp_list_new (&list);
40     if (ret < GP_OK)
41         return;
42     ret = gp_camera_folder_list_files (activeDS.camera, folder, list, activeDS.context);
43     if (ret < GP_OK) {
44         gp_list_free (list);
45         return;
46     }
47     count = gp_list_count (list);
48     if (count < GP_OK) {
49         gp_list_free (list);
50         return;
51     }
52     for (i = 0; i < count; i++) {
53         const char *name;
54         struct gphoto2_file *gpfile;
55
56         ret = gp_list_get_name (list, i, &name);
57         if (ret < GP_OK)
58             continue;
59         gpfile = malloc(sizeof(struct gphoto2_file));
60         if (!gpfile)
61             continue;
62         TRACE("adding %s/%s\n", folder, name);
63         gpfile->folder = strdup(folder);
64         gpfile->filename = strdup(name);
65         gpfile->download = FALSE;
66         list_add_head( &activeDS.files, &gpfile->entry );
67     }
68     gp_list_reset (list);
69
70     ret = gp_camera_folder_list_folders (activeDS.camera, folder, list, activeDS.context);
71     if (ret < GP_OK) {
72         FIXME("list_folders failed\n");
73         gp_list_free (list);
74         return;
75     }
76     count = gp_list_count (list);
77     if (count < GP_OK) {
78         FIXME("list_folders failed\n");
79         gp_list_free (list);
80         return;
81     }
82     for (i = 0; i < count; i++) {
83         const char *name;
84         char *newfolder;
85         ret = gp_list_get_name (list, i, &name);
86         if (ret < GP_OK)
87             continue;
88         TRACE("recursing into %s\n", name);
89         newfolder = malloc(strlen(folder)+1+strlen(name)+1);
90         if (!strcmp(folder,"/"))
91             sprintf (newfolder, "/%s", name);
92         else
93             sprintf (newfolder, "%s/%s", folder, name);
94         load_filesystem (newfolder); /* recurse ... happily */
95     }
96     gp_list_free (list);
97 #endif
98 }
99
100 /* DG_CONTROL/DAT_CAPABILITY/MSG_GET */
101 TW_UINT16 GPHOTO2_CapabilityGet (pTW_IDENTITY pOrigin, TW_MEMREF pData)
102 {
103     pTW_CAPABILITY pCapability = (pTW_CAPABILITY) pData;
104
105     TRACE("DG_CONTROL/DAT_CAPABILITY/MSG_GET\n");
106     if (activeDS.currentState < 4 || activeDS.currentState > 7) {
107         activeDS.twCC = TWCC_SEQERROR;
108         return TWRC_FAILURE;
109     }
110     activeDS.twCC = GPHOTO2_SaneCapability (pCapability, MSG_GET);
111     return (activeDS.twCC == TWCC_SUCCESS)?TWRC_SUCCESS:TWRC_FAILURE;
112 }
113
114 /* DG_CONTROL/DAT_CAPABILITY/MSG_GETCURRENT */
115 TW_UINT16 GPHOTO2_CapabilityGetCurrent (pTW_IDENTITY pOrigin, TW_MEMREF pData)
116 {
117     pTW_CAPABILITY pCapability = (pTW_CAPABILITY) pData;
118
119     TRACE("DG_CONTROL/DAT_CAPABILITY/MSG_GETCURRENT\n");
120
121     if (activeDS.currentState < 4 || activeDS.currentState > 7) {
122         activeDS.twCC = TWCC_SEQERROR;
123         return TWRC_FAILURE;
124     }
125     activeDS.twCC = GPHOTO2_SaneCapability (pCapability, MSG_GETCURRENT);
126     return (activeDS.twCC == TWCC_SUCCESS)?TWRC_SUCCESS:TWRC_FAILURE;
127 }
128
129 /* DG_CONTROL/DAT_CAPABILITY/MSG_GETDEFAULT */
130 TW_UINT16 GPHOTO2_CapabilityGetDefault (pTW_IDENTITY pOrigin, TW_MEMREF pData)
131 {
132     pTW_CAPABILITY pCapability = (pTW_CAPABILITY) pData;
133
134     TRACE("DG_CONTROL/DAT_CAPABILITY/MSG_GETDEFAULT\n");
135     if (activeDS.currentState < 4 || activeDS.currentState > 7) {
136         activeDS.twCC = TWCC_SEQERROR;
137         return TWRC_FAILURE;
138     }
139     activeDS.twCC = GPHOTO2_SaneCapability (pCapability, MSG_GETDEFAULT);
140     return (activeDS.twCC == TWCC_SUCCESS)?TWRC_SUCCESS:TWRC_FAILURE;
141 }
142
143 /* DG_CONTROL/DAT_CAPABILITY/MSG_QUERYSUPPORT */
144 TW_UINT16 GPHOTO2_CapabilityQuerySupport (pTW_IDENTITY pOrigin,
145                                         TW_MEMREF pData)
146 {
147     FIXME ("stub!\n");
148
149     return TWRC_FAILURE;
150 }
151
152 /* DG_CONTROL/DAT_CAPABILITY/MSG_RESET */
153 TW_UINT16 GPHOTO2_CapabilityReset (pTW_IDENTITY pOrigin, 
154                                  TW_MEMREF pData)
155 {
156     pTW_CAPABILITY pCapability = (pTW_CAPABILITY) pData;
157
158     TRACE("DG_CONTROL/DAT_CAPABILITY/MSG_RESET\n");
159
160     if (activeDS.currentState < 4 || activeDS.currentState > 7) {
161         activeDS.twCC = TWCC_SEQERROR;
162         return TWRC_FAILURE;
163     }
164     activeDS.twCC = GPHOTO2_SaneCapability (pCapability, MSG_RESET);
165     return (activeDS.twCC == TWCC_SUCCESS)?TWRC_SUCCESS:TWRC_FAILURE;
166 }
167
168 /* DG_CONTROL/DAT_CAPABILITY/MSG_SET */
169 TW_UINT16 GPHOTO2_CapabilitySet (pTW_IDENTITY pOrigin, 
170                                TW_MEMREF pData)
171 {
172     pTW_CAPABILITY pCapability = (pTW_CAPABILITY) pData;
173
174     TRACE ("DG_CONTROL/DAT_CAPABILITY/MSG_SET\n");
175
176     if (activeDS.currentState != 4) {
177         activeDS.twCC = TWCC_SEQERROR;
178         return TWRC_FAILURE;
179     }
180     activeDS.twCC = GPHOTO2_SaneCapability (pCapability, MSG_SET);
181     return (activeDS.twCC == TWCC_SUCCESS)?TWRC_SUCCESS:TWRC_FAILURE;
182 }
183
184 /* DG_CONTROL/DAT_CUSTOMDSDATA/MSG_GET */
185 TW_UINT16 GPHOTO2_CustomDSDataGet (pTW_IDENTITY pOrigin, 
186                                 TW_MEMREF pData)
187 {
188     FIXME ("stub!\n");
189
190     return TWRC_FAILURE;
191 }
192
193 /* DG_CONTROL/DAT_CUSTOMDSDATA/MSG_SET */
194 TW_UINT16 GPHOTO2_CustomDSDataSet (pTW_IDENTITY pOrigin, 
195                                  TW_MEMREF pData)
196 {
197     FIXME ("stub!\n");
198
199     return TWRC_FAILURE;
200 }
201
202 /* DG_CONTROL/DAT_FILESYSTEM/MSG_AUTOMATICCAPTUREDIRECTORY */
203 TW_UINT16 GPHOTO2_AutomaticCaptureDirectory (pTW_IDENTITY pOrigin,
204                                            
205                                            TW_MEMREF pData)
206 {
207     FIXME ("stub!\n");
208
209     return TWRC_FAILURE;
210 }
211
212 /* DG_CONTROL/DAT_FILESYSTEM/MSG_CHANGEDIRECTORY */
213 TW_UINT16 GPHOTO2_ChangeDirectory (pTW_IDENTITY pOrigin, 
214                                  TW_MEMREF pData)
215 {
216     FIXME ("stub!\n");
217
218     return TWRC_FAILURE;
219 }
220
221 /* DG_CONTROL/DAT_FILESYSTEM/MSG_COPY */
222 TW_UINT16 GPHOTO2_FileSystemCopy (pTW_IDENTITY pOrigin, 
223                                 TW_MEMREF pData)
224 {
225     FIXME ("stub!\n");
226
227     return TWRC_FAILURE;
228 }
229
230 /* DG_CONTROL/DAT_FILESYSTEM/MSG_CREATEDIRECTORY */
231 TW_UINT16 GPHOTO2_CreateDirectory (pTW_IDENTITY pOrigin, 
232                                  TW_MEMREF pData)
233 {
234     FIXME ("stub!\n");
235
236     return TWRC_FAILURE;
237 }
238
239 /* DG_CONTROL/DAT_FILESYSTEM/MSG_DELETE */
240 TW_UINT16 GPHOTO2_FileSystemDelete (pTW_IDENTITY pOrigin, 
241                                   TW_MEMREF pData)
242 {
243     FIXME ("stub!\n");
244
245     return TWRC_FAILURE;
246 }
247
248 /* DG_CONTROL/DAT_FILESYSTEM/MSG_FORMATMEDIA */
249 TW_UINT16 GPHOTO2_FormatMedia (pTW_IDENTITY pOrigin, 
250                              TW_MEMREF pData)
251 {
252     FIXME ("stub!\n");
253
254     return TWRC_FAILURE;
255 }
256
257 /* DG_CONTROL/DAT_FILESYSTEM/MSG_GETCLOSE */
258 TW_UINT16 GPHOTO2_FileSystemGetClose (pTW_IDENTITY pOrigin, 
259                                     TW_MEMREF pData)
260 {
261     FIXME ("stub!\n");
262
263     return TWRC_FAILURE;
264 }
265
266 /* DG_CONTROL/DAT_FILESYSTEM/MSG_GETFIRSTFILE */
267 TW_UINT16 GPHOTO2_FileSystemGetFirstFile (pTW_IDENTITY pOrigin,
268                                         
269                                         TW_MEMREF pData)
270 {
271     FIXME ("stub!\n");
272
273     return TWRC_FAILURE;
274 }
275
276 /* DG_CONTROL/DAT_FILESYSTEM/MSG_GETINFO */
277 TW_UINT16 GPHOTO2_FileSystemGetInfo (pTW_IDENTITY pOrigin, 
278                                    TW_MEMREF pData)
279 {
280     FIXME ("stub!\n");
281
282     return TWRC_FAILURE;
283 }
284
285 /* DG_CONTROL/DAT_FILESYSTEM/MSG_GETNEXTFILE */
286 TW_UINT16 GPHOTO2_FileSystemGetNextFile (pTW_IDENTITY pOrigin,
287                                        
288                                        TW_MEMREF pData)
289 {
290     FIXME ("stub!\n");
291
292     return TWRC_FAILURE;
293 }
294
295 /* DG_CONTROL/DAT_FILESYSTEM/MSG_RENAME */
296 TW_UINT16 GPHOTO2_FileSystemRename (pTW_IDENTITY pOrigin, 
297                                   TW_MEMREF pData)
298 {
299     FIXME ("stub!\n");
300
301     return TWRC_FAILURE;
302 }
303
304 /* DG_CONTROL/DAT_EVENT/MSG_PROCESSEVENT */
305 TW_UINT16 GPHOTO2_ProcessEvent (pTW_IDENTITY pOrigin, 
306                               TW_MEMREF pData)
307 {
308     TW_UINT16 twRC = TWRC_SUCCESS;
309     pTW_EVENT pEvent = (pTW_EVENT) pData;
310
311     TRACE("DG_CONTROL/DAT_EVENT/MSG_PROCESSEVENT\n");
312
313     if (activeDS.currentState < 5 || activeDS.currentState > 7) {
314         activeDS.twCC = TWCC_SEQERROR;
315         return TWRC_FAILURE;
316     }
317
318     if (activeDS.pendingEvent.TWMessage != MSG_NULL) {
319         pEvent->TWMessage = activeDS.pendingEvent.TWMessage;
320         activeDS.pendingEvent.TWMessage = MSG_NULL;
321         twRC = TWRC_SUCCESS;
322     } else {
323         pEvent->TWMessage = MSG_NULL;  /* no message to the application */
324         twRC = TWRC_NOTDSEVENT;
325     }
326     activeDS.twCC = TWCC_SUCCESS;
327     return twRC;
328 }
329
330 /* DG_CONTROL/DAT_PASSTHRU/MSG_PASSTHRU */
331 TW_UINT16 GPHOTO2_PassThrough (pTW_IDENTITY pOrigin, 
332                              TW_MEMREF pData)
333 {
334     FIXME ("stub!\n");
335
336     return TWRC_FAILURE;
337 }
338
339 /* DG_CONTROL/DAT_PENDINGXFERS/MSG_ENDXFER */
340 TW_UINT16 GPHOTO2_PendingXfersEndXfer (pTW_IDENTITY pOrigin, 
341                                      TW_MEMREF pData)
342 {
343     TW_UINT32 count;
344     pTW_PENDINGXFERS pPendingXfers = (pTW_PENDINGXFERS) pData;
345     struct gphoto2_file *file;
346
347     TRACE("DG_CONTROL/DAT_PENDINGXFERS/MSG_ENDXFER\n");
348
349     if (activeDS.currentState != 6 && activeDS.currentState != 7) {
350         activeDS.twCC = TWCC_SEQERROR;
351         return TWRC_FAILURE;
352     }
353     count = 0;
354     LIST_FOR_EACH_ENTRY( file, &activeDS.files, struct gphoto2_file, entry ) {
355         if (file->download)
356             count++;
357     }
358     TRACE("count = %ld\n", count);
359     pPendingXfers->Count = count;
360     if (pPendingXfers->Count != 0) {
361         activeDS.currentState = 6;
362     } else {
363         activeDS.currentState = 5;
364         /* Notify the application that it can close the data source */
365         activeDS.pendingEvent.TWMessage = MSG_CLOSEDSREQ;
366         /* close any Transferring dialog */
367         TransferringDialogBox(activeDS.progressWnd,-1);
368         activeDS.progressWnd = 0;
369     }
370     activeDS.twCC = TWCC_SUCCESS;
371     return TWRC_SUCCESS;
372 }
373
374 /* DG_CONTROL/DAT_PENDINGXFERS/MSG_GET */
375 TW_UINT16 GPHOTO2_PendingXfersGet (pTW_IDENTITY pOrigin, 
376                                  TW_MEMREF pData)
377 {
378     TW_UINT32 count;
379     pTW_PENDINGXFERS pPendingXfers = (pTW_PENDINGXFERS) pData;
380     struct gphoto2_file *file;
381
382     TRACE("DG_CONTROL/DAT_PENDINGXFERS/MSG_GET\n");
383
384     if (activeDS.currentState < 4 || activeDS.currentState > 7) {
385         activeDS.twCC = TWCC_SEQERROR;
386         return TWRC_FAILURE;
387     }
388
389     count = 0;
390     LIST_FOR_EACH_ENTRY( file, &activeDS.files, struct gphoto2_file, entry ) {
391         if (file->download)
392             count++;
393     }
394     TRACE("count = %ld\n", count);
395     pPendingXfers->Count = count;
396     activeDS.twCC = TWCC_SUCCESS;
397     return TWRC_SUCCESS;
398 }
399
400 /* DG_CONTROL/DAT_PENDINGXFERS/MSG_RESET */
401 TW_UINT16 GPHOTO2_PendingXfersReset (pTW_IDENTITY pOrigin, 
402                                    TW_MEMREF pData)
403 {
404     pTW_PENDINGXFERS pPendingXfers = (pTW_PENDINGXFERS) pData;
405
406     TRACE("DG_CONTROL/DAT_PENDINGXFERS/MSG_RESET\n");
407
408     if (activeDS.currentState != 6) {
409         activeDS.twCC = TWCC_SEQERROR;
410         return TWRC_FAILURE;
411     }
412     pPendingXfers->Count = 0;
413     activeDS.currentState = 5;
414     activeDS.twCC = TWCC_SUCCESS;
415     return TWRC_SUCCESS;
416 }
417
418 /* DG_CONTROL/DAT_PENDINGXFERS/MSG_STOPFEEDER */
419 TW_UINT16 GPHOTO2_PendingXfersStopFeeder (pTW_IDENTITY pOrigin,
420                                         TW_MEMREF pData)
421 {
422     FIXME ("stub!\n");
423
424     return TWRC_FAILURE;
425 }
426
427 /* DG_CONTROL/DAT_SETUPFILEXFER/MSG_GET */
428 TW_UINT16 GPHOTO2_SetupFileXferGet (pTW_IDENTITY pOrigin, 
429                                   TW_MEMREF pData)
430 {
431     FIXME ("stub!\n");
432
433     return TWRC_FAILURE;
434 }
435
436 /* DG_CONTROL/DAT_SETUPXFER/MSG_GETDEFAULT */
437 TW_UINT16 GPHOTO2_SetupFileXferGetDefault (pTW_IDENTITY pOrigin, 
438                                          TW_MEMREF pData)
439 {
440     FIXME ("stub!\n");
441
442     return TWRC_FAILURE;
443 }
444
445
446 /* DG_CONTROL/DAT_SETUPFILEXFER/MSG_RESET */
447 TW_UINT16 GPHOTO2_SetupFileXferReset (pTW_IDENTITY pOrigin, 
448                                     TW_MEMREF pData)
449 {
450     FIXME ("stub!\n");
451
452     return TWRC_FAILURE;
453 }
454
455 /* DG_CONTROL/DAT_SETUPFILEXFER/MSG_SET */
456 TW_UINT16 GPHOTO2_SetupFileXferSet (pTW_IDENTITY pOrigin, 
457                                   TW_MEMREF pData)
458 {
459     FIXME ("stub!\n");
460
461     return TWRC_FAILURE;
462 }
463
464 /* DG_CONTROL/DAT_SETUPFILEXFER2/MSG_GET */
465 TW_UINT16 GPHOTO2_SetupFileXfer2Get (pTW_IDENTITY pOrigin, 
466                                    TW_MEMREF pData)
467 {
468     FIXME ("stub!\n");
469
470     return TWRC_FAILURE;
471 }
472
473 /* DG_CONTROL/DAT_SETUPFILEXFER2/MSG_GETDEFAULT */
474 TW_UINT16 GPHOTO2_SetupFileXfer2GetDefault (pTW_IDENTITY pOrigin, 
475                                          TW_MEMREF pData)
476 {
477     FIXME ("stub!\n");
478
479     return TWRC_FAILURE;
480 }
481
482 /* DG_CONTROL/DAT_SETUPFILEXFER2/MSG_RESET */
483 TW_UINT16 GPHOTO2_SetupFileXfer2Reset (pTW_IDENTITY pOrigin, 
484                                   TW_MEMREF pData)
485 {
486     FIXME ("stub!\n");
487
488     return TWRC_FAILURE;
489 }
490
491 /* DG_CONTROL/DAT_SETUPFILEXFER2/MSG_SET */
492 TW_UINT16 GPHOTO2_SetupFileXfer2Set (pTW_IDENTITY pOrigin, 
493                                   TW_MEMREF pData)
494 {
495     FIXME ("stub!\n");
496
497     return TWRC_FAILURE;
498 }
499
500 /* DG_CONTROL/DAT_SETUPMEMXFER/MSG_GET */
501 TW_UINT16 GPHOTO2_SetupMemXferGet (pTW_IDENTITY pOrigin, 
502                                   TW_MEMREF pData)
503 {
504     pTW_SETUPMEMXFER  pSetupMemXfer = (pTW_SETUPMEMXFER)pData;
505
506     TRACE("DG_CONTROL/DAT_SETUPMEMXFER/MSG_GET\n");
507     /* Guessing */
508     pSetupMemXfer->MinBufSize = 20000;
509     pSetupMemXfer->MaxBufSize = 80000;
510     pSetupMemXfer->Preferred = 40000;
511     return TWRC_SUCCESS;
512 }
513
514 /* DG_CONTROL/DAT_STATUS/MSG_GET */
515 TW_UINT16 GPHOTO2_GetDSStatus (pTW_IDENTITY pOrigin, 
516                              TW_MEMREF pData)
517 {
518     pTW_STATUS pSourceStatus = (pTW_STATUS) pData;
519
520     TRACE ("DG_CONTROL/DAT_STATUS/MSG_GET\n");
521     pSourceStatus->ConditionCode = activeDS.twCC;
522     /* Reset the condition code */
523     activeDS.twCC = TWCC_SUCCESS;
524     return TWRC_SUCCESS;
525 }
526
527 /* DG_CONTROL/DAT_USERINTERFACE/MSG_DISABLEDS */
528 TW_UINT16 GPHOTO2_DisableDSUserInterface (pTW_IDENTITY pOrigin,
529                                         TW_MEMREF pData)
530 {
531     TRACE ("DG_CONTROL/DAT_USERINTERFACE/MSG_DISABLEDS\n");
532
533     if (activeDS.currentState != 5) {
534         activeDS.twCC = TWCC_SEQERROR;
535         return TWRC_FAILURE;
536     }
537     activeDS.currentState = 4;
538     activeDS.twCC = TWCC_SUCCESS;
539     return TWRC_SUCCESS;
540 }
541
542 /* DG_CONTROL/DAT_USERINTERFACE/MSG_ENABLEDS */
543 TW_UINT16 GPHOTO2_EnableDSUserInterface (pTW_IDENTITY pOrigin,
544                                        TW_MEMREF pData)
545 {
546     pTW_USERINTERFACE pUserInterface = (pTW_USERINTERFACE) pData;
547
548     load_filesystem("/");
549
550     TRACE ("DG_CONTROL/DAT_USERINTERFACE/MSG_ENABLEDS\n");
551     if (activeDS.currentState != 4) {
552         FIXME("Sequence error %d\n", activeDS.currentState);
553         activeDS.twCC = TWCC_SEQERROR;
554         return TWRC_FAILURE;
555     }
556     activeDS.hwndOwner = pUserInterface->hParent;
557     if (pUserInterface->ShowUI)
558     {
559         BOOL rc;
560         activeDS.currentState = 5; /* Transitions to state 5 */
561         rc = DoCameraUI();
562         if (!rc) {
563             activeDS.pendingEvent.TWMessage = MSG_CLOSEDSREQ;
564         } else {
565             /* FIXME: The GUI should have marked the files to download... */
566             activeDS.pendingEvent.TWMessage = MSG_XFERREADY;
567             activeDS.currentState = 6; /* Transitions to state 6 directly */
568         }
569     } else {
570         /* no UI will be displayed, so source is ready to transfer data */
571         activeDS.pendingEvent.TWMessage = MSG_XFERREADY;
572         activeDS.currentState = 6; /* Transitions to state 6 directly */
573     }
574     activeDS.hwndOwner = pUserInterface->hParent;
575     activeDS.twCC = TWCC_SUCCESS;
576     return TWRC_SUCCESS;
577 }
578
579 /* DG_CONTROL/DAT_USERINTERFACE/MSG_ENABLEDSUIONLY */
580 TW_UINT16 GPHOTO2_EnableDSUIOnly (pTW_IDENTITY pOrigin, 
581                                 TW_MEMREF pData)
582 {
583     TRACE("DG_CONTROL/DAT_USERINTERFACE/MSG_ENABLEDSUIONLY\n");
584
585     if (activeDS.currentState != 4) {
586         activeDS.twCC = TWCC_SEQERROR;
587         return TWRC_FAILURE;
588     }
589     /* FIXME: we should replace xscanimage with our own UI */
590     FIXME ("not implemented!\n");
591     activeDS.currentState = 5;
592     activeDS.twCC = TWCC_SUCCESS;
593     return TWRC_SUCCESS;
594 }
595
596 /* DG_CONTROL/DAT_XFERGROUP/MSG_GET */
597 TW_UINT16 GPHOTO2_XferGroupGet (pTW_IDENTITY pOrigin, 
598                               TW_MEMREF pData)
599 {
600     FIXME ("stub!\n");
601     return TWRC_FAILURE;
602 }
603
604 /* DG_CONTROL/DAT_XFERGROUP/MSG_SET */
605 TW_UINT16 GPHOTO2_XferGroupSet (pTW_IDENTITY pOrigin, 
606                                   TW_MEMREF pData)
607 {
608     FIXME ("stub!\n");
609     return TWRC_FAILURE;
610 }