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