ole32: Avoid a deadlock when a being loaded DLL calls CoRegisterClassObject from...
[wine.git] / dlls / twain_32 / twain32_main.c
blob9eb27547f14de50d136aa40ecdf5189763b21654
1 /*
2 * TWAIN32 functions
4 * Copyright 2000 Shi Quan He <shiquan@cyberdude.com>
5 * Copyright 2006 Marcus Meissner
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.
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.
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
22 #include "config.h"
24 #include <stdarg.h>
26 #include "windef.h"
27 #include "winbase.h"
28 #include "twain.h"
29 #include "twain_i.h"
30 #include "wine/debug.h"
32 WINE_DEFAULT_DEBUG_CHANNEL(twain);
34 /* A helper function that looks up a destination identity in the active
35 source list */
36 static activeDS *TWAIN_LookupSource (const TW_IDENTITY *pDest)
38 activeDS *pSource;
40 for (pSource = activeSources; pSource; pSource = pSource->next)
41 if (pSource->identity.Id == pDest->Id)
42 break;
43 return pSource;
46 BOOL WINAPI DllMain (HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
48 TRACE("%p,%x,%p\n", hinstDLL, fdwReason, lpvReserved);
50 switch (fdwReason)
52 case DLL_PROCESS_ATTACH:
53 DisableThreadLibraryCalls(hinstDLL);
54 DSM_currentState = 2;
55 break;
57 case DLL_PROCESS_DETACH:
58 DSM_currentState = 1;
59 break;
62 return TRUE;
65 static TW_UINT16 TWAIN_SourceManagerHandler (
66 pTW_IDENTITY pOrigin,
67 TW_UINT16 DAT,
68 TW_UINT16 MSG,
69 TW_MEMREF pData)
71 TW_UINT16 twRC = TWRC_SUCCESS;
73 switch (DAT)
75 case DAT_IDENTITY:
76 switch (MSG)
78 case MSG_CLOSEDS:
79 twRC = TWAIN_CloseDS (pOrigin, pData);
80 break;
82 case MSG_GETDEFAULT:
83 twRC = TWAIN_IdentityGetDefault (pOrigin, pData);
84 break;
86 case MSG_GETFIRST:
87 twRC = TWAIN_IdentityGetFirst (pOrigin, pData);
88 break;
90 case MSG_GETNEXT:
91 twRC = TWAIN_IdentityGetNext (pOrigin, pData);
92 break;
94 case MSG_OPENDS:
95 twRC = TWAIN_OpenDS (pOrigin, pData);
96 break;
98 case MSG_USERSELECT:
99 twRC = TWAIN_UserSelect (pOrigin, pData);
100 break;
102 default:
103 /* Unrecognized operation triplet */
104 twRC = TWRC_FAILURE;
105 DSM_twCC = TWCC_BADPROTOCOL;
106 WARN("unrecognized operation triplet\n");
107 break;
109 break;
111 case DAT_PARENT:
112 switch (MSG)
114 case MSG_CLOSEDSM:
115 twRC = TWAIN_CloseDSM (pOrigin, pData);
116 break;
118 case MSG_OPENDSM:
119 twRC = TWAIN_OpenDSM (pOrigin, pData);
120 break;
122 default:
123 /* Unrecognized operation triplet */
124 twRC = TWRC_FAILURE;
125 DSM_twCC = TWCC_BADPROTOCOL;
126 WARN("unrecognized operation triplet\n");
128 break;
130 case DAT_STATUS:
131 if (MSG == MSG_GET) {
132 twRC = TWAIN_GetDSMStatus (pOrigin, pData);
133 } else {
134 twRC = TWRC_FAILURE;
135 DSM_twCC = TWCC_BADPROTOCOL;
136 WARN("unrecognized operation triplet\n");
138 break;
140 default:
141 twRC = TWRC_FAILURE;
142 DSM_twCC = TWCC_BADPROTOCOL;
143 WARN("unrecognized operation triplet\n");
144 break;
147 return twRC;
151 /* Main entry point for the TWAIN library */
152 TW_UINT16 WINAPI
153 DSM_Entry (pTW_IDENTITY pOrigin,
154 pTW_IDENTITY pDest,
155 TW_UINT32 DG,
156 TW_UINT16 DAT,
157 TW_UINT16 MSG,
158 TW_MEMREF pData)
160 TW_UINT16 twRC = TWRC_SUCCESS; /* Return Code */
162 TRACE("(DG=%d DAT=%d MSG=%d)\n", DG, DAT, MSG);
164 if (pDest)
166 activeDS *pSource = TWAIN_LookupSource (pDest);
167 /* This operation's destination is a source */
169 if (!pSource) {
170 ERR("No source associated with pDest %p\n", pDest);
171 DSM_twCC = TWCC_BADDEST;
172 return TWRC_FAILURE;
174 DSM_twCC = TWCC_SUCCESS;
175 TRACE("Forwarding %d/%d/%d/%p to DS.\n", DG, DAT, MSG, pData);
176 twRC = pSource->dsEntry(pOrigin, DG, DAT, MSG, pData);
177 TRACE("return value is %d\n", twRC);
178 return twRC;
180 switch (DG)
182 case DG_CONTROL:
183 twRC = TWAIN_SourceManagerHandler (pOrigin, DAT, MSG, pData);
184 break;
185 default:
186 FIXME("The DSM does not handle DG %d\n", DG);
187 DSM_twCC = TWCC_BADPROTOCOL;
188 twRC = TWRC_FAILURE;
190 return twRC;