xref: /reactos/dll/win32/twain_32/twain32_main.c (revision 019f21ee)
1 /*
2  * TWAIN32 functions
3  *
4  * Copyright 2000 Shi Quan He <shiquan@cyberdude.com>
5  * Copyright 2006 Marcus Meissner
6  *
7  * This library is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Lesser General Public
9  * License as published by the Free Software Foundation; either
10  * version 2.1 of the License, or (at your option) any later version.
11  *
12  * This library is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15  * Lesser General Public License for more details.
16  *
17  * You should have received a copy of the GNU Lesser General Public
18  * License along with this library; if not, write to the Free Software
19  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
20  */
21 
22 #include <stdarg.h>
23 
24 #include "windef.h"
25 #include "winbase.h"
26 #include "twain.h"
27 #include "twain_i.h"
28 #include "wine/debug.h"
29 
30 WINE_DEFAULT_DEBUG_CHANNEL(twain);
31 
32 extern HINSTANCE DSM_hinstance;
33 
34 BOOL WINAPI DllMain (HINSTANCE hinstance, DWORD reason, LPVOID reserved)
35 {
36     TRACE("%p,%x,%p\n", hinstance, reason, reserved);
37 
38     switch (reason)
39     {
40         case DLL_PROCESS_ATTACH:
41             DisableThreadLibraryCalls(hinstance);
42             DSM_hinstance = hinstance;
43             break;
44         case DLL_PROCESS_DETACH:
45             break;
46     }
47     return TRUE;
48 }
49 
50 /* A helper function that looks up a destination identity in the active
51    source list */
52 static activeDS *TWAIN_LookupSource (const TW_IDENTITY *pDest)
53 {
54     activeDS *pSource;
55 
56     for (pSource = activeSources; pSource; pSource = pSource->next)
57         if (pSource->identity.Id == pDest->Id)
58             break;
59     return pSource;
60 }
61 
62 static TW_UINT16 TWAIN_SourceManagerHandler (
63            pTW_IDENTITY pOrigin,
64            TW_UINT16   DAT,
65            TW_UINT16   MSG,
66            TW_MEMREF   pData)
67 {
68     TW_UINT16 twRC = TWRC_SUCCESS;
69 
70     switch (DAT)
71     {
72         case DAT_IDENTITY:
73             switch (MSG)
74             {
75                 case MSG_CLOSEDS:
76                     twRC = TWAIN_CloseDS (pOrigin, pData);
77                     break;
78 
79                 case MSG_GETDEFAULT:
80                     twRC = TWAIN_IdentityGetDefault (pOrigin, pData);
81                     break;
82 
83                 case MSG_GETFIRST:
84                     twRC = TWAIN_IdentityGetFirst (pOrigin, pData);
85                     break;
86 
87                 case MSG_GETNEXT:
88                     twRC = TWAIN_IdentityGetNext (pOrigin, pData);
89                     break;
90 
91                 case MSG_OPENDS:
92                     twRC = TWAIN_OpenDS (pOrigin, pData);
93                     break;
94 
95                 case MSG_USERSELECT:
96                     twRC = TWAIN_UserSelect (pOrigin, pData);
97                     break;
98 
99                 default:
100                     /* Unrecognized operation triplet */
101                     twRC = TWRC_FAILURE;
102                     DSM_twCC = TWCC_BADPROTOCOL;
103                     WARN("unrecognized operation triplet\n");
104                     break;
105             }
106             break;
107 
108         case DAT_PARENT:
109             switch (MSG)
110             {
111                 case MSG_CLOSEDSM:
112                     twRC = TWAIN_CloseDSM (pOrigin, pData);
113                     break;
114 
115                 case MSG_OPENDSM:
116                     twRC = TWAIN_OpenDSM (pOrigin, pData);
117                     break;
118 
119                 default:
120                     /* Unrecognized operation triplet */
121                     twRC = TWRC_FAILURE;
122                     DSM_twCC = TWCC_BADPROTOCOL;
123                     WARN("unrecognized operation triplet\n");
124             }
125             break;
126 
127         case DAT_STATUS:
128             if (MSG == MSG_GET) {
129                 twRC = TWAIN_GetDSMStatus (pOrigin, pData);
130             } else {
131                 twRC = TWRC_FAILURE;
132                 DSM_twCC = TWCC_BADPROTOCOL;
133                 WARN("unrecognized operation triplet\n");
134             }
135             break;
136 
137         default:
138             twRC = TWRC_FAILURE;
139             DSM_twCC = TWCC_BADPROTOCOL;
140             WARN("unrecognized operation triplet\n");
141             break;
142     }
143 
144     return twRC;
145 }
146 
147 
148 /* Main entry point for the TWAIN library */
149 TW_UINT16 WINAPI
150 DSM_Entry (pTW_IDENTITY pOrigin,
151            pTW_IDENTITY pDest,
152            TW_UINT32    DG,
153            TW_UINT16    DAT,
154            TW_UINT16    MSG,
155            TW_MEMREF    pData)
156 {
157     TW_UINT16 twRC = TWRC_SUCCESS;  /* Return Code */
158 
159     TRACE("(DG=%d DAT=%d MSG=%d)\n", DG, DAT, MSG);
160 
161     if (DG == DG_CONTROL && DAT == DAT_NULL)
162     {
163         activeDS *pSource = TWAIN_LookupSource (pOrigin);
164         if (!pSource)
165         {
166             ERR("No source associated with pSource %p\n", pDest);
167             DSM_twCC = TWCC_BADPROTOCOL;
168             return TWRC_FAILURE;
169         }
170 
171         return TWAIN_ControlNull (pOrigin, pDest, pSource, MSG, pData);
172     }
173 
174     if (pDest)
175     {
176         activeDS *pSource = TWAIN_LookupSource (pDest);
177 	/* This operation's destination is a source */
178 
179         if (!pSource) {
180 	    ERR("No source associated with pDest %p\n", pDest);
181 	    DSM_twCC = TWCC_BADDEST;
182 	    return TWRC_FAILURE;
183 	}
184 
185         if (DG == DG_CONTROL && DAT == DAT_EVENT && MSG == MSG_PROCESSEVENT)
186         {
187             twRC = TWAIN_ProcessEvent(pOrigin, pSource, pData);
188             if (twRC == TWRC_DSEVENT)
189                 return twRC;
190         }
191 
192         if (DG == DG_CONTROL && DAT == DAT_USERINTERFACE &&
193             (MSG == MSG_ENABLEDS || MSG == MSG_ENABLEDSUIONLY) &&
194             pData != NULL)
195         {
196             pSource->ui_window = ((TW_USERINTERFACE*)pData)->hParent;
197         }
198 
199 	DSM_twCC = TWCC_SUCCESS;
200         TRACE("Forwarding %d/%d/%d/%p to DS.\n", DG, DAT, MSG, pData);
201 	twRC = pSource->dsEntry(pOrigin, DG, DAT, MSG, pData);
202 	TRACE("return value is %d\n", twRC);
203 	return twRC;
204     }
205     switch (DG)
206     {
207         case DG_CONTROL:
208             twRC = TWAIN_SourceManagerHandler (pOrigin, DAT, MSG, pData);
209             break;
210         default:
211             FIXME("The DSM does not handle DG %d\n", DG);
212             DSM_twCC = TWCC_BADPROTOCOL;
213             twRC = TWRC_FAILURE;
214     }
215     return twRC;
216 }
217