1 /* Unit test suite for Twain DSM functions
3 * Copyright 2009 Jeremy White, CodeWeavers, Inc.
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Lesser General Public
7 * License as published by the Free Software Foundation; either
8 * version 2.1 of the License, or (at your option) any later version.
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Lesser General Public License for more details.
15 * You should have received a copy of the GNU Lesser General Public
16 * License along with this library; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
29 #include "wine/test.h"
31 static DSMENTRYPROC pDSM_Entry
;
33 static BOOL
dsm_RegisterWindowClasses(void)
38 cls
.lpfnWndProc
= DefWindowProc
;
41 cls
.hInstance
= GetModuleHandleA(0);
43 cls
.hCursor
= LoadCursorA(0, IDC_ARROW
);
44 cls
.hbrBackground
= GetStockObject(WHITE_BRUSH
);
45 cls
.lpszMenuName
= NULL
;
46 cls
.lpszClassName
= "TWAIN_dsm_class";
47 if (!RegisterClassA(&cls
)) return FALSE
;
53 static void get_condition_code(TW_IDENTITY
*appid
, TW_IDENTITY
*source
, TW_STATUS
*status
)
56 rc
= pDSM_Entry(appid
, source
, DG_CONTROL
, DAT_STATUS
, MSG_GET
, status
);
57 ok(rc
== TWRC_SUCCESS
, "Condition code not available, rc %d\n", rc
);
60 static BOOL
get_onevalue(TW_HANDLE hcontainer
, TW_UINT32
*ret
, TW_UINT16
*type
)
63 onev
= GlobalLock(hcontainer
);
68 *type
= onev
->ItemType
;
69 GlobalUnlock(hcontainer
);
75 static TW_HANDLE
alloc_and_set_onevalue(TW_UINT32 val
, TW_UINT16 type
)
79 hcontainer
= GlobalAlloc(0, sizeof(*onev
));
82 onev
= GlobalLock(hcontainer
);
85 onev
->ItemType
= type
;
87 GlobalUnlock(hcontainer
);
91 GlobalFree(hcontainer
);
98 static void check_get(TW_CAPABILITY
*pCapability
, TW_INT32 actual_support
,
99 TW_UINT32 orig_value
, TW_UINT32 default_value
, TW_UINT32
*suggested_set_value
)
102 if (suggested_set_value
)
103 *suggested_set_value
= orig_value
+ 1;
104 p
= GlobalLock(pCapability
->hContainer
);
107 if (pCapability
->ConType
== TWON_ONEVALUE
)
109 TW_ONEVALUE
*onev
= (TW_ONEVALUE
*) p
;
110 ok(onev
->Item
== orig_value
|| !(actual_support
& TWQC_GETCURRENT
), "MSG_GET of 0x%x returned 0x%x, expecting 0x%x\n",
111 pCapability
->Cap
, onev
->Item
, orig_value
);
113 else if (pCapability
->ConType
== TWON_ENUMERATION
)
119 TW_ENUMERATION
*enumv
= (TW_ENUMERATION
*) p
;
120 p8
= enumv
->ItemList
;
121 p16
= (TW_UINT16
*) p8
;
122 p32
= (TW_UINT32
*) p8
;
123 trace("MSG_GET of 0x%x returned %d items:\n", pCapability
->Cap
, enumv
->NumItems
);
124 for (i
= 0; i
< enumv
->NumItems
; i
++)
126 if (enumv
->ItemType
== TWTY_UINT8
|| enumv
->ItemType
== TWTY_INT8
)
127 trace(" %d: 0x%x\n", i
, p8
[i
]);
128 if (enumv
->ItemType
== TWTY_UINT16
|| enumv
->ItemType
== TWTY_INT16
)
129 trace(" %d: 0x%x\n", i
, p16
[i
]);
130 if (enumv
->ItemType
== TWTY_UINT32
|| enumv
->ItemType
== TWTY_INT32
)
131 trace(" %d: 0x%x\n", i
, p32
[i
]);
133 if (enumv
->ItemType
== TWTY_UINT16
|| enumv
->ItemType
== TWTY_INT16
)
135 ok(p16
[enumv
->CurrentIndex
] == orig_value
,
136 "Type 0x%x, values from MSG_GET (0x%x) and MSG_GETCURRENT (0x%x) do not match.\n",
137 pCapability
->Cap
, p16
[enumv
->CurrentIndex
], orig_value
);
138 ok(p16
[enumv
->DefaultIndex
] == default_value
,
139 "Type 0x%x, values from MSG_GET (0x%x) and MSG_GETDEFAULT (0x%x) do not match.\n",
140 pCapability
->Cap
, p16
[enumv
->DefaultIndex
], default_value
);
141 if (suggested_set_value
)
142 *suggested_set_value
= p16
[(enumv
->CurrentIndex
+ 1) % enumv
->NumItems
];
144 if (enumv
->ItemType
== TWTY_UINT32
|| enumv
->ItemType
== TWTY_INT32
)
146 ok(p32
[enumv
->CurrentIndex
] == orig_value
,
147 "Type 0x%x, values from MSG_GET (0x%x) and MSG_GETCURRENT (0x%x) do not match.\n",
148 pCapability
->Cap
, p32
[enumv
->CurrentIndex
], orig_value
);
149 ok(p32
[enumv
->DefaultIndex
] == default_value
,
150 "Type 0x%x, values from MSG_GET (0x%x) and MSG_GETDEFAULT (0x%x) do not match.\n",
151 pCapability
->Cap
, p32
[enumv
->DefaultIndex
], default_value
);
152 if (suggested_set_value
)
153 *suggested_set_value
= p32
[(enumv
->CurrentIndex
+ 1) % enumv
->NumItems
];
157 trace("MSG_GET on type 0x%x returned type 0x%x, which we didn't check.\n", pCapability
->Cap
, pCapability
->ConType
);
158 GlobalUnlock(pCapability
->hContainer
);
162 static void test_onevalue_cap(TW_IDENTITY
*appid
, TW_IDENTITY
*source
, TW_UINT16 captype
, TW_UINT16 type
, TW_INT32 minimum_support
)
168 TW_UINT32 orig_value
= 0;
170 TW_UINT32 default_value
= 0;
171 TW_INT32 actual_support
;
173 memset(&cap
, 0, sizeof(cap
));
175 cap
.ConType
= TWON_DONTCARE16
;
177 rc
= pDSM_Entry(appid
, source
, DG_CONTROL
, DAT_CAPABILITY
, MSG_QUERYSUPPORT
, &cap
);
178 get_condition_code(appid
, source
, &status
);
179 ok(rc
== TWRC_SUCCESS
&& status
.ConditionCode
== TWCC_SUCCESS
,
180 "Error [rc %d|cc %d] doing MSG_QUERYSUPPORT for type 0x%x\n", rc
, status
.ConditionCode
, captype
);
181 if (rc
!= TWRC_SUCCESS
)
183 ok(get_onevalue(cap
.hContainer
, (TW_UINT32
*) &actual_support
, NULL
), "Returned cap.hContainer invalid for QuerySupport on type 0x%x\n", captype
);
184 ok((actual_support
& minimum_support
) == minimum_support
,
185 "Error: minimum support 0x%x for type 0x%x, got 0x%x\n", minimum_support
,
186 captype
, actual_support
);
189 if (actual_support
& TWQC_GETCURRENT
)
191 memset(&cap
, 0, sizeof(cap
));
193 cap
.ConType
= TWON_DONTCARE16
;
195 rc
= pDSM_Entry(appid
, source
, DG_CONTROL
, DAT_CAPABILITY
, MSG_GETCURRENT
, &cap
);
196 get_condition_code(appid
, source
, &status
);
197 ok(rc
== TWRC_SUCCESS
&& status
.ConditionCode
== TWCC_SUCCESS
,
198 "Error [rc %d|cc %d] doing MSG_GETCURRENT for type 0x%x\n", rc
, status
.ConditionCode
, captype
);
199 if (rc
== TWRC_SUCCESS
)
201 ok(get_onevalue(cap
.hContainer
, &orig_value
, &rtype
), "Returned cap.hContainer invalid for GETCURRENT on type 0x%x\n", captype
);
202 ok(rtype
== type
, "Returned GETCURRENT type 0x%x for cap 0x%x is not expected 0x%x\n", rtype
, captype
, type
);
203 GlobalFree(cap
.hContainer
);
207 if (actual_support
& TWQC_GETDEFAULT
)
209 memset(&cap
, 0, sizeof(cap
));
211 cap
.ConType
= TWON_DONTCARE16
;
213 rc
= pDSM_Entry(appid
, source
, DG_CONTROL
, DAT_CAPABILITY
, MSG_GETDEFAULT
, &cap
);
214 get_condition_code(appid
, source
, &status
);
215 ok(rc
== TWRC_SUCCESS
&& status
.ConditionCode
== TWCC_SUCCESS
,
216 "Error [rc %d|cc %d] doing MSG_GETDEFAULT for type 0x%x\n", rc
, status
.ConditionCode
, captype
);
217 if (rc
== TWRC_SUCCESS
)
219 ok(get_onevalue(cap
.hContainer
, &default_value
, &rtype
), "Returned cap.hContainer invalid for GETDEFAULT on type 0x%x\n", captype
);
220 ok(rtype
== type
, "Returned GETDEFAULT type 0x%x for cap 0x%x is not expected 0x%x\n", rtype
, captype
, type
);
221 GlobalFree(cap
.hContainer
);
225 new_value
= orig_value
;
226 if (actual_support
& TWQC_GET
)
228 memset(&cap
, 0, sizeof(cap
));
230 cap
.ConType
= TWON_DONTCARE16
;
232 rc
= pDSM_Entry(appid
, source
, DG_CONTROL
, DAT_CAPABILITY
, MSG_GET
, &cap
);
233 get_condition_code(appid
, source
, &status
);
234 ok(rc
== TWRC_SUCCESS
&& status
.ConditionCode
== TWCC_SUCCESS
,
235 "Error [rc %d|cc %d] doing MSG_GET for type 0x%x\n", rc
, status
.ConditionCode
, captype
);
236 check_get(&cap
, actual_support
, orig_value
, default_value
, &new_value
);
237 if (rc
== TWRC_SUCCESS
)
238 GlobalFree(cap
.hContainer
);
241 if (actual_support
& TWQC_SET
)
243 memset(&cap
, 0, sizeof(cap
));
245 cap
.ConType
= TWON_ONEVALUE
;
246 cap
.hContainer
= alloc_and_set_onevalue(new_value
, type
);
248 rc
= pDSM_Entry(appid
, source
, DG_CONTROL
, DAT_CAPABILITY
, MSG_SET
, &cap
);
249 get_condition_code(appid
, source
, &status
);
250 ok(rc
== TWRC_SUCCESS
&& status
.ConditionCode
== TWCC_SUCCESS
,
251 "Error [rc %d|cc %d] doing MSG_SET for type 0x%x\n", rc
, status
.ConditionCode
, captype
);
252 GlobalFree(cap
.hContainer
);
255 if (actual_support
& TWQC_RESET
)
257 memset(&cap
, 0, sizeof(cap
));
259 cap
.ConType
= TWON_DONTCARE16
;
261 rc
= pDSM_Entry(appid
, source
, DG_CONTROL
, DAT_CAPABILITY
, MSG_RESET
, &cap
);
262 get_condition_code(appid
, source
, &status
);
263 ok(rc
== TWRC_SUCCESS
&& status
.ConditionCode
== TWCC_SUCCESS
,
264 "Error [rc %d|cc %d] doing MSG_RESET for type 0x%x\n", rc
, status
.ConditionCode
, captype
);
265 if (rc
== TWRC_SUCCESS
)
266 GlobalFree(cap
.hContainer
);
270 static void test_resolution(TW_IDENTITY
*appid
, TW_IDENTITY
*source
, TW_UINT16 captype
, TW_INT32 minimum_support
)
277 TW_INT32 actual_support
;
278 TW_FIX32 orig_value
= { 0, 0 };
279 TW_UINT32 new_value
= 0;
280 TW_FIX32 default_value
= { 0, 0 };
282 memset(&cap
, 0, sizeof(cap
));
284 cap
.ConType
= TWON_DONTCARE16
;
286 rc
= pDSM_Entry(appid
, source
, DG_CONTROL
, DAT_CAPABILITY
, MSG_QUERYSUPPORT
, &cap
);
287 get_condition_code(appid
, source
, &status
);
288 ok(rc
== TWRC_SUCCESS
&& status
.ConditionCode
== TWCC_SUCCESS
,
289 "Error [rc %d|cc %d] doing MSG_QUERYSUPPORT for type 0x%x\n", rc
, status
.ConditionCode
, captype
);
290 if (rc
!= TWRC_SUCCESS
)
292 ok(get_onevalue(cap
.hContainer
, (TW_UINT32
*) &actual_support
, NULL
), "Returned cap.hContainer invalid for QuerySupport on type 0x%x\n", captype
);
293 ok((actual_support
& minimum_support
) == minimum_support
,
294 "Error: minimum support 0x%x for type 0x%x, got 0x%x\n", minimum_support
,
295 captype
, actual_support
);
298 if (actual_support
& TWQC_GETCURRENT
)
300 memset(&cap
, 0, sizeof(cap
));
302 cap
.ConType
= TWON_DONTCARE16
;
304 rc
= pDSM_Entry(appid
, source
, DG_CONTROL
, DAT_CAPABILITY
, MSG_GETCURRENT
, &cap
);
305 get_condition_code(appid
, source
, &status
);
306 ok(rc
== TWRC_SUCCESS
&& status
.ConditionCode
== TWCC_SUCCESS
,
307 "Error [rc %d|cc %d] doing MSG_GETCURRENT for type 0x%x\n", rc
, status
.ConditionCode
, captype
);
308 if (rc
== TWRC_SUCCESS
)
310 get_onevalue(cap
.hContainer
, &val
, &type
);
311 ok(type
== TWTY_FIX32
, "GETCURRENT for RESOLUTION is not type FIX32, is type %d\n", type
);
312 memcpy(&orig_value
, &val
, sizeof(orig_value
));
313 GlobalFree(cap
.hContainer
);
317 if (actual_support
& TWQC_GETDEFAULT
)
319 memset(&cap
, 0, sizeof(cap
));
321 cap
.ConType
= TWON_DONTCARE16
;
323 rc
= pDSM_Entry(appid
, source
, DG_CONTROL
, DAT_CAPABILITY
, MSG_GETDEFAULT
, &cap
);
324 get_condition_code(appid
, source
, &status
);
325 ok(rc
== TWRC_SUCCESS
&& status
.ConditionCode
== TWCC_SUCCESS
,
326 "Error [rc %d|cc %d] doing MSG_GETDEFAULT for type 0x%x\n", rc
, status
.ConditionCode
, captype
);
327 if (rc
== TWRC_SUCCESS
)
329 ok(type
== TWTY_FIX32
, "GETDEFAULT for RESOLUTION is not type FIX32, is type %d\n", type
);
330 memcpy(&default_value
, &val
, sizeof(default_value
));
331 GlobalFree(cap
.hContainer
);
335 if (actual_support
& TWQC_GET
)
337 memset(&cap
, 0, sizeof(cap
));
339 cap
.ConType
= TWON_DONTCARE16
;
341 rc
= pDSM_Entry(appid
, source
, DG_CONTROL
, DAT_CAPABILITY
, MSG_GET
, &cap
);
342 get_condition_code(appid
, source
, &status
);
343 ok(rc
== TWRC_SUCCESS
&& status
.ConditionCode
== TWCC_SUCCESS
,
344 "Error [rc %d|cc %d] doing MSG_GET for type 0x%x\n", rc
, status
.ConditionCode
, captype
);
345 if (rc
== TWRC_SUCCESS
)
348 ok(cap
.ConType
== TWON_RANGE
, "MSG_GET for ICAP_[XY]RESOLUTION did not return TWON_RANGE, but %d\n", cap
.ConType
);
349 range
= GlobalLock(cap
.hContainer
);
350 trace("MSG_GET of 0x%x returned [ItemType %d|MinValue %d|MaxValue %d|StepSize %d|DefaultValue %d|CurrentValue %d]:\n",
351 cap
.Cap
, range
->ItemType
, range
->MinValue
, range
->MaxValue
, range
->StepSize
,
352 range
->DefaultValue
, range
->CurrentValue
);
353 for (new_value
= range
->MinValue
; new_value
< range
->MaxValue
; new_value
+= range
->StepSize
)
354 if (new_value
!= range
->CurrentValue
)
356 GlobalUnlock(cap
.hContainer
);
357 GlobalFree(cap
.hContainer
);
361 if (actual_support
& TWQC_SET
)
363 memset(&cap
, 0, sizeof(cap
));
365 cap
.ConType
= TWON_ONEVALUE
;
366 cap
.hContainer
= alloc_and_set_onevalue(new_value
, TWTY_FIX32
);
368 rc
= pDSM_Entry(appid
, source
, DG_CONTROL
, DAT_CAPABILITY
, MSG_SET
, &cap
);
369 get_condition_code(appid
, source
, &status
);
370 ok(rc
== TWRC_SUCCESS
&& status
.ConditionCode
== TWCC_SUCCESS
,
371 "Error [rc %d|cc %d] doing MSG_SET for type 0x%x\n", rc
, status
.ConditionCode
, captype
);
372 GlobalFree(cap
.hContainer
);
376 if (actual_support
& TWQC_RESET
)
378 memset(&cap
, 0, sizeof(cap
));
380 cap
.ConType
= TWON_DONTCARE16
;
382 rc
= pDSM_Entry(appid
, source
, DG_CONTROL
, DAT_CAPABILITY
, MSG_RESET
, &cap
);
383 get_condition_code(appid
, source
, &status
);
384 ok(rc
== TWRC_SUCCESS
&& status
.ConditionCode
== TWCC_SUCCESS
,
385 "Error [rc %d|cc %d] doing MSG_RESET for type 0x%x\n", rc
, status
.ConditionCode
, captype
);
386 if (rc
== TWRC_SUCCESS
)
387 GlobalFree(cap
.hContainer
);
392 static void test_single_source(TW_IDENTITY
*appid
, TW_IDENTITY
*source
)
397 UINT16 capabilities
[CAP_CUSTOMBASE
];
399 memset(&cap
, 0, sizeof(cap
));
400 cap
.Cap
= CAP_SUPPORTEDCAPS
;
401 cap
.ConType
= TWON_DONTCARE16
;
403 rc
= pDSM_Entry(appid
, source
, DG_CONTROL
, DAT_CAPABILITY
, MSG_GET
, &cap
);
404 get_condition_code(appid
, source
, &status
);
405 ok(rc
== TWRC_SUCCESS
|| status
.ConditionCode
== TWCC_SUCCESS
,
406 "Error obtaining CAP_SUPPORTEDCAPS\n");
408 memset(capabilities
, 0, sizeof(capabilities
));
409 if (rc
== TWRC_SUCCESS
&& cap
.ConType
== TWON_ARRAY
)
412 a
= GlobalLock(cap
.hContainer
);
415 if (a
->ItemType
== TWTY_UINT16
)
418 UINT16
*u
= (UINT16
*) a
->ItemList
;
419 trace("%d Capabilities:\n", a
->NumItems
);
420 for (i
= 0; i
< a
->NumItems
; i
++)
421 if (u
[i
] < sizeof(capabilities
) / sizeof(capabilities
[0]))
423 capabilities
[u
[i
]] = 1;
424 trace(" %d: 0x%x\n", i
, u
[i
]);
427 GlobalUnlock(cap
.hContainer
);
431 /* For Twain 1.6, all sources must support: */
432 ok(capabilities
[CAP_SUPPORTEDCAPS
], "CAP_SUPPORTEDCAPS not supported\n");
433 ok(capabilities
[CAP_XFERCOUNT
], "CAP_XFERCOUNT not supported\n");
434 if (capabilities
[CAP_XFERCOUNT
])
435 test_onevalue_cap(appid
, source
, CAP_XFERCOUNT
, TWTY_INT16
,
436 TWQC_GET
| TWQC_SET
| TWQC_GETDEFAULT
| TWQC_GETCURRENT
| TWQC_RESET
);
437 ok(capabilities
[CAP_UICONTROLLABLE
], "CAP_UICONTROLLABLE not supported\n");
438 if (capabilities
[CAP_UICONTROLLABLE
])
439 test_onevalue_cap(appid
, source
, CAP_UICONTROLLABLE
, TWTY_BOOL
, TWQC_GET
);
441 if (source
->SupportedGroups
& DG_IMAGE
)
444 Sources that supply image information must support DG_CONTROL / DAT_CAPABILITY /
445 MSG_GET, MSG_GETCURRENT, MSG_GETDEFAULT on:
447 ok(capabilities
[ICAP_COMPRESSION
], "ICAP_COMPRESSION not supported\n");
448 if (capabilities
[ICAP_COMPRESSION
])
449 test_onevalue_cap(appid
, source
, ICAP_COMPRESSION
, TWTY_UINT16
,
450 TWQC_GET
| TWQC_GETDEFAULT
| TWQC_GETCURRENT
);
452 ok(capabilities
[ICAP_PLANARCHUNKY
], "ICAP_PLANARCHUNKY not supported\n");
454 ok(capabilities
[ICAP_PHYSICALHEIGHT
], "ICAP_PHYSICALHEIGHT not supported\n");
456 ok(capabilities
[ICAP_PHYSICALWIDTH
], "ICAP_PHYSICALWIDTH not supported\n");
457 ok(capabilities
[ICAP_PIXELFLAVOR
], "ICAP_PIXELFLAVOR not supported\n");
458 if (capabilities
[ICAP_PIXELFLAVOR
])
459 test_onevalue_cap(appid
, source
, ICAP_PIXELFLAVOR
, TWTY_UINT16
,
460 TWQC_GET
| TWQC_SET
| TWQC_GETDEFAULT
| TWQC_GETCURRENT
| TWQC_RESET
);
463 Sources that supply image information must support DG_CONTROL / DAT_CAPABILITY /
464 MSG_GET, MSG_GETCURRENT, MSG_GETDEFAULT, MSG_RESET and MSG_SET on:
467 ok(capabilities
[ICAP_BITDEPTH
], "ICAP_BITDEPTH not supported\n");
469 ok(capabilities
[ICAP_BITORDER
], "ICAP_BITORDER not supported\n");
470 ok(capabilities
[ICAP_PIXELTYPE
], "ICAP_PIXELTYPE not supported\n");
471 if (capabilities
[ICAP_PIXELTYPE
])
472 test_onevalue_cap(appid
, source
, ICAP_PIXELTYPE
, TWTY_UINT16
,
473 TWQC_GET
| TWQC_SET
| TWQC_GETDEFAULT
| TWQC_GETCURRENT
| TWQC_RESET
);
475 ok(capabilities
[ICAP_UNITS
], "ICAP_UNITS not supported\n");
476 ok(capabilities
[ICAP_XFERMECH
], "ICAP_XFERMECH not supported\n");
477 if (capabilities
[ICAP_XFERMECH
])
478 test_onevalue_cap(appid
, source
, ICAP_XFERMECH
, TWTY_UINT16
,
479 TWQC_GET
| TWQC_SET
| TWQC_GETDEFAULT
| TWQC_GETCURRENT
| TWQC_RESET
);
480 ok(capabilities
[ICAP_XRESOLUTION
], "ICAP_XRESOLUTION not supported\n");
481 if (capabilities
[ICAP_XRESOLUTION
])
482 test_resolution(appid
, source
, ICAP_XRESOLUTION
,
483 TWQC_GET
| TWQC_SET
| TWQC_GETDEFAULT
| TWQC_GETCURRENT
| TWQC_RESET
);
484 ok(capabilities
[ICAP_YRESOLUTION
], "ICAP_YRESOLUTION not supported\n");
485 if (capabilities
[ICAP_YRESOLUTION
])
486 test_resolution(appid
, source
, ICAP_YRESOLUTION
,
487 TWQC_GET
| TWQC_SET
| TWQC_GETDEFAULT
| TWQC_GETCURRENT
| TWQC_RESET
);
491 static void test_sources(TW_IDENTITY
*appid
)
496 int scannercount
= 0;
498 memset(&source
, 0, sizeof(source
));
499 rc
= pDSM_Entry(appid
, NULL
, DG_CONTROL
, DAT_IDENTITY
, MSG_GETFIRST
, &source
);
500 get_condition_code(appid
, NULL
, &status
);
501 ok( (rc
== TWRC_SUCCESS
&& status
.ConditionCode
== TWCC_SUCCESS
) ||
502 (rc
== TWRC_FAILURE
&& status
.ConditionCode
== TWCC_NODS
),
503 "Get first invalid condition code, rc %d, cc %d\n", rc
, status
.ConditionCode
);
505 while (rc
== TWRC_SUCCESS
)
508 trace("[Scanner %d|Version %d.%d(%s)|Protocol %d.%d|SupportedGroups 0x%x|Manufacturer %s|Family %s|ProductName %s]\n",
510 source
.Version
.MajorNum
, source
.Version
.MinorNum
, source
.Version
.Info
,
511 source
.ProtocolMajor
, source
.ProtocolMinor
, source
.SupportedGroups
,
512 source
.Manufacturer
, source
.ProductFamily
, source
.ProductName
);
513 memset(&source
, 0, sizeof(source
));
514 rc
= pDSM_Entry(appid
, NULL
, DG_CONTROL
, DAT_IDENTITY
, MSG_GETNEXT
, &source
);
515 get_condition_code(appid
, NULL
, &status
);
516 ok(rc
== TWRC_SUCCESS
|| rc
== TWRC_ENDOFLIST
, "Get next source failed, rc %d, cc %d\n", rc
, status
.ConditionCode
);
519 memset(&source
, 0, sizeof(source
));
520 rc
= pDSM_Entry(appid
, NULL
, DG_CONTROL
, DAT_IDENTITY
, MSG_GETDEFAULT
, &source
);
521 get_condition_code(appid
, NULL
, &status
);
522 ok( (rc
== TWRC_SUCCESS
&& status
.ConditionCode
== TWCC_SUCCESS
) ||
523 (rc
== TWRC_FAILURE
&& status
.ConditionCode
== TWCC_NODS
),
524 "Get default invalid condition code, rc %d, cc %d\n", rc
, status
.ConditionCode
);
526 if (rc
== TWRC_SUCCESS
&& status
.ConditionCode
== TWCC_SUCCESS
)
528 rc
= pDSM_Entry(appid
, NULL
, DG_CONTROL
, DAT_IDENTITY
, MSG_OPENDS
, &source
);
529 get_condition_code(appid
, NULL
, &status
);
531 if (rc
== TWRC_SUCCESS
&& status
.ConditionCode
== TWCC_SUCCESS
)
533 rc
= pDSM_Entry(appid
, NULL
, DG_CONTROL
, DAT_IDENTITY
, MSG_CLOSEDS
, &source
);
534 get_condition_code(appid
, NULL
, &status
);
535 ok(rc
== TWRC_SUCCESS
, "Close DS Failed, rc %d, cc %d\n", rc
, status
.ConditionCode
);
539 if (winetest_interactive
)
541 trace("Interactive, so trying userselect\n");
542 memset(&source
, 0, sizeof(source
));
543 rc
= pDSM_Entry(appid
, NULL
, DG_CONTROL
, DAT_IDENTITY
, MSG_USERSELECT
, &source
);
544 get_condition_code(appid
, NULL
, &status
);
545 ok(rc
== TWRC_SUCCESS
|| rc
== TWRC_CANCEL
, "Userselect failed, rc %d, cc %d\n", rc
, status
.ConditionCode
);
547 if (rc
== TWRC_SUCCESS
&& status
.ConditionCode
== TWCC_SUCCESS
)
549 rc
= pDSM_Entry(appid
, NULL
, DG_CONTROL
, DAT_IDENTITY
, MSG_OPENDS
, &source
);
550 get_condition_code(appid
, NULL
, &status
);
551 if (rc
== TWRC_SUCCESS
&& status
.ConditionCode
== TWCC_SUCCESS
)
553 test_single_source(appid
, &source
);
554 rc
= pDSM_Entry(appid
, NULL
, DG_CONTROL
, DAT_IDENTITY
, MSG_CLOSEDS
, &source
);
555 get_condition_code(appid
, NULL
, &status
);
556 ok(rc
== TWRC_SUCCESS
, "Close DS Failed, rc %d, cc %d\n", rc
, status
.ConditionCode
);
570 if (!dsm_RegisterWindowClasses()) assert(0);
572 htwain
= LoadLibraryA("twain_32.dll");
575 skip("twain_32.dll not available, skipping tests\n");
578 pDSM_Entry
= (void*)GetProcAddress(htwain
, "DSM_Entry");
579 ok(pDSM_Entry
!= NULL
, "Unable to GetProcAddress DSM_Entry\n");
582 skip("DSM_Entry not available, skipping tests\n");
586 memset(&appid
, 0, sizeof(appid
));
587 appid
.Version
.Language
= TWLG_ENGLISH_USA
;
588 appid
.Version
.Country
= TWCY_USA
;
589 appid
.ProtocolMajor
= TWON_PROTOCOLMAJOR
;
590 appid
.ProtocolMinor
= TWON_PROTOCOLMINOR
;
591 appid
.SupportedGroups
= DG_CONTROL
| DG_IMAGE
;
593 hwnd
= CreateWindow("TWAIN_dsm_class", "Twain Test", 0,
594 CW_USEDEFAULT
, CW_USEDEFAULT
, CW_USEDEFAULT
, CW_USEDEFAULT
,
595 NULL
, NULL
, GetModuleHandleA(0), NULL
);
597 rc
= pDSM_Entry(&appid
, NULL
, DG_CONTROL
, DAT_PARENT
, MSG_OPENDSM
, (TW_MEMREF
) &hwnd
);
598 ok(rc
== TWRC_SUCCESS
, "MSG_OPENDSM returned %d\n", rc
);
600 test_sources(&appid
);
602 rc
= pDSM_Entry(&appid
, NULL
, DG_CONTROL
, DAT_PARENT
, MSG_CLOSEDSM
, (TW_MEMREF
) &hwnd
);
603 ok(rc
== TWRC_SUCCESS
, "MSG_CLOSEDSM returned %d\n", rc
);