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 "config.h" 23 24 #include <stdarg.h> 25 26 #include "windef.h" 27 #include "winbase.h" 28 #include "twain.h" 29 #include "twain_i.h" 30 #include "wine/debug.h" 31 32 WINE_DEFAULT_DEBUG_CHANNEL(twain); 33 34 extern HINSTANCE DSM_hinstance; 35 36 BOOL WINAPI DllMain (HINSTANCE hinstance, DWORD reason, LPVOID reserved) 37 { 38 TRACE("%p,%x,%p\n", hinstance, reason, reserved); 39 40 switch (reason) 41 { 42 case DLL_PROCESS_ATTACH: 43 DisableThreadLibraryCalls(hinstance); 44 DSM_hinstance = hinstance; 45 break; 46 case DLL_PROCESS_DETACH: 47 break; 48 } 49 return TRUE; 50 } 51 52 /* A helper function that looks up a destination identity in the active 53 source list */ 54 static activeDS *TWAIN_LookupSource (const TW_IDENTITY *pDest) 55 { 56 activeDS *pSource; 57 58 for (pSource = activeSources; pSource; pSource = pSource->next) 59 if (pSource->identity.Id == pDest->Id) 60 break; 61 return pSource; 62 } 63 64 static TW_UINT16 TWAIN_SourceManagerHandler ( 65 pTW_IDENTITY pOrigin, 66 TW_UINT16 DAT, 67 TW_UINT16 MSG, 68 TW_MEMREF pData) 69 { 70 TW_UINT16 twRC = TWRC_SUCCESS; 71 72 switch (DAT) 73 { 74 case DAT_IDENTITY: 75 switch (MSG) 76 { 77 case MSG_CLOSEDS: 78 twRC = TWAIN_CloseDS (pOrigin, pData); 79 break; 80 81 case MSG_GETDEFAULT: 82 twRC = TWAIN_IdentityGetDefault (pOrigin, pData); 83 break; 84 85 case MSG_GETFIRST: 86 twRC = TWAIN_IdentityGetFirst (pOrigin, pData); 87 break; 88 89 case MSG_GETNEXT: 90 twRC = TWAIN_IdentityGetNext (pOrigin, pData); 91 break; 92 93 case MSG_OPENDS: 94 twRC = TWAIN_OpenDS (pOrigin, pData); 95 break; 96 97 case MSG_USERSELECT: 98 twRC = TWAIN_UserSelect (pOrigin, pData); 99 break; 100 101 default: 102 /* Unrecognized operation triplet */ 103 twRC = TWRC_FAILURE; 104 DSM_twCC = TWCC_BADPROTOCOL; 105 WARN("unrecognized operation triplet\n"); 106 break; 107 } 108 break; 109 110 case DAT_PARENT: 111 switch (MSG) 112 { 113 case MSG_CLOSEDSM: 114 twRC = TWAIN_CloseDSM (pOrigin, pData); 115 break; 116 117 case MSG_OPENDSM: 118 twRC = TWAIN_OpenDSM (pOrigin, pData); 119 break; 120 121 default: 122 /* Unrecognized operation triplet */ 123 twRC = TWRC_FAILURE; 124 DSM_twCC = TWCC_BADPROTOCOL; 125 WARN("unrecognized operation triplet\n"); 126 } 127 break; 128 129 case DAT_STATUS: 130 if (MSG == MSG_GET) { 131 twRC = TWAIN_GetDSMStatus (pOrigin, pData); 132 } else { 133 twRC = TWRC_FAILURE; 134 DSM_twCC = TWCC_BADPROTOCOL; 135 WARN("unrecognized operation triplet\n"); 136 } 137 break; 138 139 default: 140 twRC = TWRC_FAILURE; 141 DSM_twCC = TWCC_BADPROTOCOL; 142 WARN("unrecognized operation triplet\n"); 143 break; 144 } 145 146 return twRC; 147 } 148 149 150 /* Main entry point for the TWAIN library */ 151 TW_UINT16 WINAPI 152 DSM_Entry (pTW_IDENTITY pOrigin, 153 pTW_IDENTITY pDest, 154 TW_UINT32 DG, 155 TW_UINT16 DAT, 156 TW_UINT16 MSG, 157 TW_MEMREF pData) 158 { 159 TW_UINT16 twRC = TWRC_SUCCESS; /* Return Code */ 160 161 TRACE("(DG=%d DAT=%d MSG=%d)\n", DG, DAT, MSG); 162 163 if (DG == DG_CONTROL && DAT == DAT_NULL) 164 { 165 activeDS *pSource = TWAIN_LookupSource (pOrigin); 166 if (!pSource) 167 { 168 ERR("No source associated with pSource %p\n", pDest); 169 DSM_twCC = TWCC_BADPROTOCOL; 170 return TWRC_FAILURE; 171 } 172 173 return TWAIN_ControlNull (pOrigin, pDest, pSource, MSG, pData); 174 } 175 176 if (pDest) 177 { 178 activeDS *pSource = TWAIN_LookupSource (pDest); 179 /* This operation's destination is a source */ 180 181 if (!pSource) { 182 ERR("No source associated with pDest %p\n", pDest); 183 DSM_twCC = TWCC_BADDEST; 184 return TWRC_FAILURE; 185 } 186 187 if (DG == DG_CONTROL && DAT == DAT_EVENT && MSG == MSG_PROCESSEVENT) 188 { 189 twRC = TWAIN_ProcessEvent(pOrigin, pSource, pData); 190 if (twRC == TWRC_DSEVENT) 191 return twRC; 192 } 193 194 if (DG == DG_CONTROL && DAT == DAT_USERINTERFACE && 195 (MSG == MSG_ENABLEDS || MSG == MSG_ENABLEDSUIONLY) && 196 pData != NULL) 197 { 198 pSource->ui_window = ((TW_USERINTERFACE*)pData)->hParent; 199 } 200 201 DSM_twCC = TWCC_SUCCESS; 202 TRACE("Forwarding %d/%d/%d/%p to DS.\n", DG, DAT, MSG, pData); 203 twRC = pSource->dsEntry(pOrigin, DG, DAT, MSG, pData); 204 TRACE("return value is %d\n", twRC); 205 return twRC; 206 } 207 switch (DG) 208 { 209 case DG_CONTROL: 210 twRC = TWAIN_SourceManagerHandler (pOrigin, DAT, MSG, pData); 211 break; 212 default: 213 FIXME("The DSM does not handle DG %d\n", DG); 214 DSM_twCC = TWCC_BADPROTOCOL; 215 twRC = TWRC_FAILURE; 216 } 217 return twRC; 218 } 219