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