Added regedit unit test, a couple minor changes to regedit.
[wine] / dlls / twain / twain32_main.c
1 /*
2  * TWAIN32 functions
3  *
4  * Copyright 2000 Shi Quan He <shiquan@cyberdude.com>
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2.1 of the License, or (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this library; if not, write to the Free Software
18  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19  */
20
21 #include "windef.h"
22 #include "winbase.h"
23 #include "twain.h"
24 #include "twain_i.h"
25 #include "wine/debug.h"
26
27 WINE_DEFAULT_DEBUG_CHANNEL(twain);
28
29 BOOL WINAPI
30 TWAIN_LibMain (HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
31 {
32     TRACE("%x,%lx,%p\n", hinstDLL, fdwReason, lpvReserved);
33
34     switch (fdwReason)
35     {
36         case DLL_PROCESS_ATTACH:
37             DSM_currentState = 2;
38             break;
39
40         case DLL_THREAD_ATTACH:
41             break;
42
43         case DLL_THREAD_DETACH:
44             break;
45
46         case DLL_PROCESS_DETACH:
47             DSM_currentState = 1;
48             break;
49     }
50
51     return TRUE;
52 }
53
54 TW_UINT16 TWAIN_SourceManagerHandler (
55            pTW_IDENTITY pOrigin,
56            TW_UINT16   DAT,
57            TW_UINT16   MSG,
58            TW_MEMREF   pData)
59 {
60     TW_UINT16 twRC = TWRC_SUCCESS;
61
62     switch (DAT)
63     {
64         case DAT_IDENTITY:
65             switch (MSG)
66             {
67                 case MSG_CLOSEDS:
68                     twRC = TWAIN_CloseDS (pOrigin, pData);
69                     break;
70
71                 case MSG_GETDEFAULT:
72                     twRC = TWAIN_IdentityGetDefault (pOrigin, pData);
73                     break;
74
75                 case MSG_GETFIRST:
76                     twRC = TWAIN_IdentityGetFirst (pOrigin, pData);
77                     break;
78
79                 case MSG_GETNEXT:
80                     twRC = TWAIN_IdentityGetNext (pOrigin, pData);
81                     break;
82
83                 case MSG_OPENDS:
84                     twRC = TWAIN_OpenDS (pOrigin, pData);
85                     break;
86
87                 case MSG_USERSELECT:
88                     twRC = TWAIN_UserSelect (pOrigin, pData);
89                     break;
90
91                 default:
92                     /* Unrecognized operation triplet */
93                     twRC = TWRC_FAILURE;
94                     DSM_twCC = TWCC_BADPROTOCOL;
95                     WARN("unrecognized operation triplet\n");
96                     break;
97             }
98             break;
99
100         case DAT_PARENT:
101             switch (MSG)
102             {
103                 case MSG_CLOSEDSM:
104                     twRC = TWAIN_CloseDSM (pOrigin, pData);
105                     break;
106
107                 case MSG_OPENDSM:
108                     twRC = TWAIN_OpenDSM (pOrigin, pData);
109                     break;
110
111                 default:
112                     /* Unrecognized operation triplet */
113                     twRC = TWRC_FAILURE;
114                     DSM_twCC = TWCC_BADPROTOCOL;
115                     WARN("unrecognized operation triplet\n");
116             }
117             break;
118
119         case DAT_STATUS:
120             if (MSG == MSG_GET)
121             {
122                 twRC = TWAIN_GetDSMStatus (pOrigin, pData);
123             }
124             else
125             {
126                 twRC = TWRC_FAILURE;
127                 DSM_twCC = TWCC_BADPROTOCOL;
128                 WARN("unrecognized operation triplet\n");
129             }
130             break;
131
132         default:
133             twRC = TWRC_FAILURE;
134             DSM_twCC = TWCC_BADPROTOCOL;
135             WARN("unrecognized operation triplet\n");
136             break;
137     }
138
139     return twRC;
140 }
141
142 TW_UINT16 TWAIN_SourceControlHandler (
143            pTW_IDENTITY pOrigin,
144            pTW_IDENTITY pDest,
145            TW_UINT16    DAT,
146            TW_UINT16    MSG,
147            TW_MEMREF    pData)
148 {
149     TW_UINT16 twRC = TWRC_SUCCESS;
150
151     switch (DAT)
152     {
153         case DAT_CAPABILITY:
154             switch (MSG)
155             {
156                 case MSG_GET:
157                     twRC = TWAIN_CapabilityGet (pOrigin, pDest, pData);
158                     break;
159                 case MSG_GETCURRENT:
160                     twRC = TWAIN_CapabilityGetCurrent (pOrigin, pDest, pData);
161                     break;
162                 case MSG_GETDEFAULT:
163                     twRC = TWAIN_CapabilityGetDefault (pOrigin, pDest, pData);
164                     break;
165                 case MSG_QUERYSUPPORT:
166                     twRC = TWAIN_CapabilityQuerySupport (pOrigin, pDest, pData);
167                     break;
168                 case MSG_RESET:
169                     twRC = TWAIN_CapabilityReset (pOrigin, pDest, pData);
170                     break;
171                 case MSG_SET:
172                     twRC = TWAIN_CapabilitySet (pOrigin, pDest, pData);
173                     break;
174                 default:
175                     twRC = TWRC_FAILURE;
176                     WARN("unrecognized opertion triplet\n");
177             }
178             break;
179
180         case DAT_CUSTOMDSDATA:
181             switch (MSG)
182             {
183                 case MSG_GET:
184                     twRC = TWAIN_CustomDSDataGet (pOrigin, pDest, pData);
185                     break;
186                 case MSG_SET:
187                     twRC = TWAIN_CustomDSDataSet (pOrigin, pDest, pData);
188                     break;
189                 default:
190                     break;
191             }
192             break;
193
194         case DAT_FILESYSTEM:
195             switch (MSG)
196             {
197                 /*case MSG_AUTOMATICCAPTUREDIRECTORY:
198                     twRC = TWAIN_AutomaticCaptureDirectory
199                                (pOrigin, pDest, pData);
200                     break;*/
201                 case MSG_CHANGEDIRECTORY:
202                     twRC = TWAIN_ChangeDirectory (pOrigin, pDest, pData);
203                     break;
204                 /*case MSG_COPY:
205                     twRC = TWAIN_FileSystemCopy (pOrigin, pDest, pData);
206                     break;*/
207                 case MSG_CREATEDIRECTORY:
208                     twRC = TWAIN_CreateDirectory (pOrigin, pDest, pData);
209                     break;
210                 case MSG_DELETE:
211                     twRC = TWAIN_FileSystemDelete (pOrigin, pDest, pData);
212                     break;
213                 case MSG_FORMATMEDIA:
214                     twRC = TWAIN_FormatMedia (pOrigin, pDest, pData);
215                     break;
216                 case MSG_GETCLOSE:
217                     twRC = TWAIN_FileSystemGetClose (pOrigin, pDest, pData);
218                     break;
219                 case MSG_GETFIRSTFILE:
220                     twRC = TWAIN_FileSystemGetFirstFile
221                                (pOrigin, pDest, pData);
222                     break;
223                 case MSG_GETINFO:
224                     twRC = TWAIN_FileSystemGetInfo (pOrigin, pDest, pData);
225                     break;
226                 case MSG_GETNEXTFILE:
227                     twRC = TWAIN_FileSystemGetNextFile
228                                (pOrigin, pDest, pData);
229                     break;
230                 case MSG_RENAME:
231                     twRC = TWAIN_FileSystemRename (pOrigin, pDest, pData);
232                     break;
233                 default:
234                     twRC = TWRC_FAILURE;
235                     break;
236             }
237             break;
238
239         case DAT_EVENT:
240             if (MSG == MSG_PROCESSEVENT)
241                 twRC = TWAIN_ProcessEvent (pOrigin, pDest, pData);
242             else
243                 twRC = TWRC_FAILURE;
244             break;
245
246         case DAT_PASSTHRU:
247             if (MSG == MSG_PASSTHRU)
248                 twRC = TWAIN_PassThrough (pOrigin, pDest, pData);
249             else
250                 twRC = TWRC_FAILURE;
251             break;
252
253         case DAT_PENDINGXFERS:
254             switch (MSG)
255             {
256                 case MSG_ENDXFER:
257                     twRC = TWAIN_PendingXfersEndXfer (pOrigin, pDest, pData);
258                     break;
259                 case MSG_GET:
260                     twRC = TWAIN_PendingXfersGet (pOrigin, pDest, pData);
261                     break;
262                 case MSG_RESET:
263                     twRC = TWAIN_PendingXfersReset (pOrigin, pDest, pData);
264                     break;
265                 /*case MSG_STOPFEEDER:
266                     twRC = TWAIN_PendingXfersStopFeeder
267                                (pOrigin, pDest, pData);
268                     break;*/
269                 default:
270                     twRC = TWRC_FAILURE;
271             }
272             break;
273
274         case DAT_SETUPFILEXFER:
275             switch (MSG)
276             {
277                 case MSG_GET:
278                     twRC = TWAIN_SetupFileXferGet (pOrigin, pDest, pData);
279                     break;
280                 case MSG_GETDEFAULT:
281                     twRC = TWAIN_SetupFileXferGetDefault
282                                (pOrigin, pDest, pData);
283                     break;
284                 case MSG_RESET:
285                     twRC = TWAIN_SetupFileXferReset (pOrigin, pDest, pData);
286                     break;
287                 case MSG_SET:
288                     twRC = TWAIN_SetupFileXferSet (pOrigin, pDest, pData);
289                     break;
290                 default:
291                     twRC = TWRC_FAILURE;
292                     break;
293             }
294             break;
295
296         /*case DAT_SETUPFILEXFER2:
297             switch (MSG)
298             {
299                 case MSG_GET:
300                     twRC = TWAIN_SetupFileXfer2Get (pOrigin, pDest, pData);
301                     break;
302                 case MSG_GETDEFAULT:
303                     twRC = TWAIN_SetupFileXfer2GetDefault
304                                (pOrigin, pDest, pData);
305                     break;
306                 case MSG_RESET:
307                     twRC = TWAIN_SetupFileXfer2Reset (pOrigin, pDest, pData);
308                     break;
309                 case MSG_SET:
310                     twRC = TWAIN_SetupFileXfer2Set (pOrigin, pDest, pData);
311                     break;
312             }
313             break;*/
314         case DAT_SETUPMEMXFER:
315             if (MSG == MSG_GET)
316                 twRC = TWAIN_SetupMemXferGet (pOrigin, pDest, pData);
317             else
318                 twRC = TWRC_FAILURE;
319             break;
320
321         case DAT_STATUS:
322             if (MSG == MSG_GET)
323                 twRC = TWAIN_GetDSStatus (pOrigin, pDest, pData);
324             else
325                 twRC = TWRC_FAILURE;
326             break;
327
328         case DAT_USERINTERFACE:
329             switch (MSG)
330             {
331                 case MSG_DISABLEDS:
332                     twRC = TWAIN_DisableDSUserInterface
333                                (pOrigin, pDest, pData);
334                     break;
335                 case MSG_ENABLEDS:
336                     twRC = TWAIN_EnableDSUserInterface
337                                (pOrigin, pDest, pData);
338                     break;
339                 case MSG_ENABLEDSUIONLY:
340                     twRC = TWAIN_EnableDSUIOnly (pOrigin, pDest, pData);
341                     break;
342                 default:
343                     twRC = TWRC_FAILURE;
344                     break;
345             }
346             break;
347
348         case DAT_XFERGROUP:
349             switch (MSG)
350             {
351                 case MSG_GET:
352                     twRC = TWAIN_XferGroupGet (pOrigin, pDest, pData);
353                     break;
354                 case MSG_SET:
355                     twRC = TWAIN_XferGroupSet (pOrigin, pDest, pData);
356                     break;
357                 default:
358                     twRC = TWRC_FAILURE;
359                     break;
360             }
361             break;
362
363         default:
364             twRC = TWRC_FAILURE;
365             break;
366     }
367
368     return twRC;
369 }
370
371 TW_UINT16 TWAIN_ControlGroupHandler (
372            pTW_IDENTITY pOrigin,
373            pTW_IDENTITY pDest,
374            TW_UINT16    DAT,
375            TW_UINT16    MSG,
376            TW_MEMREF    pData)
377 {
378     TW_UINT16 twRC = TWRC_SUCCESS;
379
380     if (pDest)
381     {
382         /* This operation's destination is a source */
383         twRC = TWAIN_SourceControlHandler (pOrigin, pDest, DAT, MSG, pData);
384     }
385     else
386     {
387         /* This operation's destination is the Source Manager */
388         twRC = TWAIN_SourceManagerHandler (pOrigin, DAT, MSG, pData);
389     }
390
391     return twRC;
392 }
393
394 TW_UINT16 TWAIN_ImageGroupHandler (
395            pTW_IDENTITY pOrigin,
396            pTW_IDENTITY pDest,
397            TW_UINT16    DAT,
398            TW_UINT16    MSG,
399            TW_MEMREF    pData)
400 {
401     TW_UINT16 twRC = TWRC_SUCCESS;
402
403     if (pDest == NULL)
404     {
405         DSM_twCC = TWCC_BADDEST;
406         return TWRC_FAILURE;
407     }
408
409     switch (DAT)
410     {
411         case DAT_CIECOLOR:
412             if (MSG == MSG_GET)
413                 twRC = TWAIN_CIEColorGet (pOrigin, pDest, pData);
414             else
415                 twRC = TWRC_FAILURE;
416             break;
417
418         case DAT_EXTIMAGEINFO:
419             if (MSG == MSG_GET)
420                 twRC = TWAIN_ExtImageInfoGet (pOrigin, pDest, pData);
421             else
422                 twRC = TWRC_FAILURE;
423             break;
424
425         case DAT_GRAYRESPONSE:
426             switch (MSG)
427             {
428                 case MSG_RESET:
429                     twRC = TWAIN_GrayResponseReset (pOrigin, pDest, pData);
430                     break;
431                 case MSG_SET:
432                     twRC = TWAIN_GrayResponseSet (pOrigin, pDest, pData);
433                     break;
434                 default:
435                     twRC = TWRC_FAILURE;
436                     DSM_twCC = TWCC_BADPROTOCOL;
437                     WARN("unrecognized operation triplet\n");
438                     break;
439             }
440             break;
441         case DAT_IMAGEFILEXFER:
442             if (MSG == MSG_GET)
443                 twRC = TWAIN_ImageFileXferGet (pOrigin, pDest, pData);
444             else
445                 twRC = TWRC_FAILURE;
446             break;
447
448         case DAT_IMAGEINFO:
449             if (MSG == MSG_GET)
450                 twRC = TWAIN_ImageInfoGet (pOrigin, pDest, pData);
451             else
452                 twRC = TWRC_FAILURE;
453             break;
454
455         case DAT_IMAGELAYOUT:
456             switch (MSG)
457             {
458                 case MSG_GET:
459                     twRC = TWAIN_ImageLayoutGet (pOrigin, pDest, pData);
460                     break;
461                 case MSG_GETDEFAULT:
462                     twRC = TWAIN_ImageLayoutGetDefault (pOrigin, pDest, pData);
463                     break;
464                 case MSG_RESET:
465                     twRC = TWAIN_ImageLayoutReset (pOrigin, pDest, pData);
466                     break;
467                 case MSG_SET:
468                     twRC = TWAIN_ImageLayoutSet (pOrigin, pDest, pData);
469                     break;
470                 default:
471                     twRC = TWRC_FAILURE;
472                     DSM_twCC = TWCC_BADPROTOCOL;
473                     WARN("unrecognized operation triplet\n");
474                     break;
475             }
476             break;
477
478         case DAT_IMAGEMEMXFER:
479             if (MSG == MSG_GET)
480                 twRC = TWAIN_ImageMemXferGet (pOrigin, pDest, pData);
481             else
482                 twRC = TWRC_FAILURE;
483             break;
484
485         case DAT_IMAGENATIVEXFER:
486             if (MSG == MSG_GET)
487                 twRC = TWAIN_ImageNativeXferGet (pOrigin, pDest, pData);
488             else
489                 twRC = TWRC_FAILURE;
490             break;
491
492         case DAT_JPEGCOMPRESSION:
493             switch (MSG)
494             {
495                 case MSG_GET:
496                     twRC = TWAIN_JPEGCompressionGet (pOrigin, pDest, pData);
497                     break;
498                 case MSG_GETDEFAULT:
499                     twRC = TWAIN_JPEGCompressionGetDefault
500                                (pOrigin, pDest, pData);
501                     break;
502                 case MSG_RESET:
503                     twRC = TWAIN_JPEGCompressionReset (pOrigin, pDest, pData);
504                     break;
505                 case MSG_SET:
506                     twRC = TWAIN_JPEGCompressionSet (pOrigin, pDest, pData);
507                     break;
508                 default:
509                     twRC = TWRC_FAILURE;
510                     DSM_twCC = TWCC_BADPROTOCOL;
511                     WARN("unrecognized operation triplet\n");
512                     break;
513             }
514             break;
515
516         case DAT_PALETTE8:
517             switch (MSG)
518             {
519                 case MSG_GET:
520                     twRC = TWAIN_Palette8Get (pOrigin, pDest, pData);
521                     break;
522                 case MSG_GETDEFAULT:
523                     twRC = TWAIN_Palette8GetDefault (pOrigin, pDest, pData);
524                     break;
525                 case MSG_RESET:
526                     twRC = TWAIN_Palette8Reset (pOrigin, pDest, pData);
527                     break;
528                 case MSG_SET:
529                     twRC = TWAIN_Palette8Set (pOrigin, pDest, pData);
530                     break;
531                 default:
532                     twRC = TWRC_FAILURE;
533                     DSM_twCC = TWCC_BADPROTOCOL;
534                     WARN("unrecognized operation triplet\n");
535             }
536             break;
537
538         case DAT_RGBRESPONSE:
539             switch (MSG)
540             {
541                 case MSG_RESET:
542                     twRC = TWAIN_RGBResponseReset (pOrigin, pDest, pData);
543                     break;
544                 case MSG_SET:
545                     twRC = TWAIN_RGBResponseSet (pOrigin, pDest, pData);
546                     break;
547                 default:
548                     twRC = TWRC_FAILURE;
549                     DSM_twCC = TWCC_BADPROTOCOL;
550                     WARN("unrecognized operation triplet\n");
551                     break;
552             }
553             break;
554
555         default:
556             twRC = TWRC_FAILURE;
557             DSM_twCC = TWCC_BADPROTOCOL;
558             WARN("unrecognized operation triplet\n");
559     }
560     return twRC;
561 }
562
563 TW_UINT16 TWAIN_AudioGroupHandler (
564            pTW_IDENTITY pOrigin,
565            pTW_IDENTITY pDest,
566            TW_UINT16    DAT,
567            TW_UINT16    MSG,
568            TW_MEMREF    pData)
569 {
570     TW_UINT16 twRC = TWRC_FAILURE;
571
572     switch (DAT)
573     {
574         case DAT_AUDIOFILEXFER:
575             if (MSG == MSG_GET)
576                 twRC = TWAIN_AudioFileXferGet (pOrigin, pDest, pData);
577             break;
578
579         case DAT_AUDIOINFO:
580             if (MSG == MSG_GET)
581                 twRC = TWAIN_AudioInfoGet (pOrigin, pDest, pData);
582             break;
583
584         case DAT_AUDIONATIVEXFER:
585             if (MSG == MSG_GET)
586                 twRC = TWAIN_AudioNativeXferGet (pOrigin, pDest, pData);
587             break;
588
589         default:
590             DSM_twCC = TWCC_BADPROTOCOL;
591             twRC = TWRC_FAILURE;
592             break;
593     }
594
595     return twRC;
596 }
597
598 /* Main entry point for the TWAIN library */
599 TW_UINT16 WINAPI
600 DSM_Entry (pTW_IDENTITY pOrigin,
601            pTW_IDENTITY pDest,
602            TW_UINT32    DG,
603            TW_UINT16    DAT,
604            TW_UINT16    MSG,
605            TW_MEMREF    pData)
606 {
607     TW_UINT16 twRC = TWRC_SUCCESS;  /* Return Code */
608
609     TRACE("(DG=%ld DAT=%d MSG=%d)\n", DG, DAT, MSG);
610
611     switch (DG)
612     {
613         case DG_CONTROL:
614             twRC = TWAIN_ControlGroupHandler (pOrigin,pDest,DAT,MSG,pData);
615             break;
616         case DG_IMAGE:
617             twRC = TWAIN_ImageGroupHandler (pOrigin,pDest,DAT,MSG,pData);
618             break;
619         case DG_AUDIO:
620             twRC = TWAIN_AudioGroupHandler (pOrigin,pDest,DAT,MSG,pData);
621             break;
622         default:
623             DSM_twCC = TWCC_BADPROTOCOL;
624             twRC = TWRC_FAILURE;
625     }
626
627     return twRC;
628 }
629
630 /* A helper function that looks up a destination identity in the active
631    source list */
632 activeDS *TWAIN_LookupSource (pTW_IDENTITY pDest)
633 {
634     activeDS *pSource;
635
636     for (pSource = activeSources; pSource; pSource = pSource->next)
637         if (pSource->identity.Id == pDest->Id)
638             break;
639
640     return pSource;
641 }