Repository: twain/twain-cs Branch: master Commit: 74fe02ed78a6 Files: 178 Total size: 3.4 MB Directory structure: gitextract_1n84szq5/ ├── .gitignore ├── README.md ├── releases/ │ ├── makerelease.bat │ ├── twain-cs_02041000/ │ │ ├── TWAIN CS.rtf │ │ ├── twaincscert/ │ │ │ ├── AnyCPU/ │ │ │ │ ├── Debug/ │ │ │ │ │ └── twaincscert.exe.config │ │ │ │ └── Release/ │ │ │ │ └── twaincscert.exe.config │ │ │ ├── x64/ │ │ │ │ ├── Debug/ │ │ │ │ │ └── twaincscert.exe.config │ │ │ │ └── Release/ │ │ │ │ └── twaincscert.exe.config │ │ │ └── x86/ │ │ │ ├── Debug/ │ │ │ │ └── twaincscert.exe.config │ │ │ └── Release/ │ │ │ └── twaincscert.exe.config │ │ ├── twaincsscan/ │ │ │ ├── AnyCPU/ │ │ │ │ ├── Debug/ │ │ │ │ │ └── twaincsscan.exe.config │ │ │ │ └── Release/ │ │ │ │ └── twaincsscan.exe.config │ │ │ ├── x64/ │ │ │ │ ├── Debug/ │ │ │ │ │ └── twaincsscan.exe.config │ │ │ │ └── Release/ │ │ │ │ └── twaincsscan.exe.config │ │ │ └── x86/ │ │ │ ├── Debug/ │ │ │ │ └── twaincsscan.exe.config │ │ │ └── Release/ │ │ │ └── twaincsscan.exe.config │ │ └── twaincstst/ │ │ ├── AnyCPU/ │ │ │ ├── Debug/ │ │ │ │ └── twaincstst.exe.config │ │ │ └── Release/ │ │ │ └── twaincstst.exe.config │ │ ├── x64/ │ │ │ ├── Debug/ │ │ │ │ └── twaincstst.exe.config │ │ │ └── Release/ │ │ │ └── twaincstst.exe.config │ │ └── x86/ │ │ ├── Debug/ │ │ │ └── twaincstst.exe.config │ │ └── Release/ │ │ └── twaincstst.exe.config │ └── twain-cs_02041100/ │ ├── TWAIN CS.rtf │ ├── twaincscert/ │ │ ├── AnyCPU/ │ │ │ ├── Debug/ │ │ │ │ └── twaincscert.exe.config │ │ │ └── Release/ │ │ │ └── twaincscert.exe.config │ │ ├── x64/ │ │ │ ├── Debug/ │ │ │ │ └── twaincscert.exe.config │ │ │ └── Release/ │ │ │ └── twaincscert.exe.config │ │ └── x86/ │ │ ├── Debug/ │ │ │ └── twaincscert.exe.config │ │ └── Release/ │ │ └── twaincscert.exe.config │ ├── twaincsscan/ │ │ ├── AnyCPU/ │ │ │ ├── Debug/ │ │ │ │ └── twaincsscan.exe.config │ │ │ └── Release/ │ │ │ └── twaincsscan.exe.config │ │ ├── x64/ │ │ │ ├── Debug/ │ │ │ │ └── twaincsscan.exe.config │ │ │ └── Release/ │ │ │ └── twaincsscan.exe.config │ │ └── x86/ │ │ ├── Debug/ │ │ │ └── twaincsscan.exe.config │ │ └── Release/ │ │ └── twaincsscan.exe.config │ └── twaincstst/ │ ├── AnyCPU/ │ │ ├── Debug/ │ │ │ └── twaincstst.exe.config │ │ └── Release/ │ │ └── twaincstst.exe.config │ ├── x64/ │ │ ├── Debug/ │ │ │ └── twaincstst.exe.config │ │ └── Release/ │ │ └── twaincstst.exe.config │ └── x86/ │ ├── Debug/ │ │ └── twaincstst.exe.config │ └── Release/ │ └── twaincstst.exe.config └── twaincs/ └── source/ ├── Properties/ │ └── AssemblyInfo.cs ├── TWAIN CS.rtf ├── TWAIN.cs ├── TWAINH.cs ├── twaincs.csproj ├── twaincs.sln ├── twaincscert/ │ └── source/ │ ├── FormMain.Designer.cs │ ├── FormMain.cs │ ├── FormMain.resx │ ├── MsBuildAL1073WarningWorkaround.targets │ ├── Program.cs │ ├── Properties/ │ │ ├── AssemblyInfo.cs │ │ ├── Resources.Designer.cs │ │ ├── Resources.resx │ │ ├── Settings.Designer.cs │ │ └── Settings.settings │ ├── app.config │ ├── data/ │ │ ├── certification/ │ │ │ ├── 010 - TWAIN Standard Capability Tests/ │ │ │ │ ├── CAP_SUPPORTEDCAPS.tc │ │ │ │ ├── Certification.tc │ │ │ │ ├── DAT_CAPABILITY.tc │ │ │ │ ├── ICAP_PIXELTYPE.tc │ │ │ │ └── ICAP_XFERMECH.tc │ │ │ ├── 020 - Vendor Custom Capability Tests/ │ │ │ │ ├── Certification.tc │ │ │ │ └── DAT_CAPABILITY.tc │ │ │ ├── 030 - Status Return Tests/ │ │ │ │ ├── Certification.tc │ │ │ │ └── Status Return Tests.tc │ │ │ ├── 040 - Stress Tests/ │ │ │ │ └── Certification.tc │ │ │ ├── 050 - Non-UI Image Transfer Tests/ │ │ │ │ ├── Certification.tc │ │ │ │ ├── DAT_IMAGEFILEXFER.tc │ │ │ │ ├── DAT_IMAGEMEMFILEXFER.tc │ │ │ │ ├── DAT_IMAGEMEMXFER.tc │ │ │ │ └── DAT_IMAGENATIVEXFER.tc │ │ │ ├── 060 - UI Image Transfer Tests/ │ │ │ │ ├── Certification.tc │ │ │ │ ├── DAT_IMAGEFILEXFER.tc │ │ │ │ ├── DAT_IMAGEMEMFILEXFER.tc │ │ │ │ ├── DAT_IMAGEMEMXFER.tc │ │ │ │ └── DAT_IMAGENATIVEXFER.tc │ │ │ ├── 070 - CAP_XFERCOUNT Tests/ │ │ │ │ ├── Certification.tc │ │ │ │ ├── DAT_IMAGEFILEXFER.tc │ │ │ │ ├── DAT_IMAGEMEMFILEXFER.tc │ │ │ │ ├── DAT_IMAGEMEMXFER.tc │ │ │ │ └── DAT_IMAGENATIVEXFER.tc │ │ │ ├── 080 - Version Tests/ │ │ │ │ ├── Certification.tc │ │ │ │ └── DAT_IMAGEMEMXFER.tc │ │ │ ├── 090 - Verify Values for MSG_OPENDS, MSG_RESET, and MSG_RESETALL/ │ │ │ │ ├── Certification.tc │ │ │ │ ├── MSG_OPENDS.tc │ │ │ │ ├── MSG_RESET.tc │ │ │ │ └── MSG_RESETALL.tc │ │ │ ├── 100 - TWAIN Direct Badge/ │ │ │ │ ├── Certification.tc │ │ │ │ ├── DAT_EXTIMAGEINFO.tc │ │ │ │ ├── DAT_IMAGEMEMFILEXFER.tc │ │ │ │ └── TWAIN Direct Badge.tc │ │ │ ├── 110 - Printing Badge/ │ │ │ │ ├── Certification.tc │ │ │ │ ├── DAT_EXTIMAGEINFO.tc │ │ │ │ ├── DAT_IMAGEFILEXFER.tc │ │ │ │ ├── DAT_IMAGEMEMFILEXFER.tc │ │ │ │ ├── DAT_IMAGEMEMXFER.tc │ │ │ │ ├── DAT_IMAGENATIVEXFER.tc │ │ │ │ ├── Printing Badge.tc │ │ │ │ └── SetCapabilities.tc │ │ │ ├── 120 - Patch Code Badge/ │ │ │ │ ├── Certification.tc │ │ │ │ ├── DAT_EXTIMAGEINFO.tc │ │ │ │ ├── DAT_IMAGEFILEXFER.tc │ │ │ │ ├── DAT_IMAGEMEMFILEXFER.tc │ │ │ │ ├── DAT_IMAGEMEMXFER.tc │ │ │ │ ├── DAT_IMAGENATIVEXFER.tc │ │ │ │ ├── Patch Code Badge.tc │ │ │ │ ├── SetCapabilities.tc │ │ │ │ └── _README.txt │ │ │ ├── 130 - Barcode Badge/ │ │ │ │ ├── Barcode Badge.tc │ │ │ │ ├── Certification.tc │ │ │ │ ├── DAT_EXTIMAGEINFO.tc │ │ │ │ ├── DAT_IMAGEFILEXFER.tc │ │ │ │ ├── DAT_IMAGEMEMFILEXFER.tc │ │ │ │ ├── DAT_IMAGEMEMXFER.tc │ │ │ │ ├── DAT_IMAGENATIVEXFER.tc │ │ │ │ └── SetCapabilities.tc │ │ │ ├── 140 - Image Address Badge/ │ │ │ │ ├── Certification.tc │ │ │ │ ├── DAT_EXTIMAGEINFO.tc │ │ │ │ ├── DAT_IMAGEFILEXFER.tc │ │ │ │ ├── DAT_IMAGEMEMFILEXFER.tc │ │ │ │ ├── DAT_IMAGEMEMXFER.tc │ │ │ │ ├── DAT_IMAGENATIVEXFER.tc │ │ │ │ ├── Image Address Badge.tc │ │ │ │ └── SetCapabilities.tc │ │ │ ├── Certification.tc │ │ │ ├── Closeds.tc │ │ │ ├── LoadTables.tc │ │ │ ├── Opends.tc │ │ │ └── __README.md │ │ ├── scripts/ │ │ │ ├── LoadTables.tc │ │ │ ├── __README.md │ │ │ ├── cap_supportedcaps.tc │ │ │ ├── capget.tc │ │ │ ├── close.tc │ │ │ ├── copybytes.tc │ │ │ ├── datget.tc │ │ │ ├── extimageinfo.tc │ │ │ ├── list.tc │ │ │ ├── open.tc │ │ │ ├── scanfile.tc │ │ │ ├── scanmemfile.tc │ │ │ ├── scanmemory.tc │ │ │ └── scannative.tc │ │ └── twaincscert.appdata.installed.txt │ ├── terminal.cs │ ├── twaincscert.csproj │ └── version.bat ├── twaincsscan/ │ └── source/ │ ├── FormScan.Designer.cs │ ├── FormScan.cs │ ├── FormScan.resx │ ├── FormSelect.Designer.cs │ ├── FormSelect.cs │ ├── FormSelect.resx │ ├── FormSetup.Designer.cs │ ├── FormSetup.cs │ ├── FormSetup.resx │ ├── Program.cs │ ├── Properties/ │ │ ├── AssemblyInfo.cs │ │ ├── Resources.Designer.cs │ │ ├── Resources.resx │ │ ├── Settings.Designer.cs │ │ └── Settings.settings │ ├── app.config │ └── twaincsscan.csproj └── twaincstst/ └── source/ ├── Main.Designer.cs ├── Main.cs ├── Main.resx ├── Program.cs ├── Properties/ │ ├── AssemblyInfo.cs │ ├── Resources.Designer.cs │ ├── Resources.resx │ ├── Settings.Designer.cs │ ├── Settings.settings │ └── Settings1.Designer.cs ├── app.config └── twaincstst.csproj ================================================ FILE CONTENTS ================================================ ================================================ FILE: .gitignore ================================================ ################################################################################ # This .gitignore file was automatically created by Microsoft(R) Visual Studio. ################################################################################ *.suo /twaincs/source/bin/x86/Debug/TWAIN.dll *.pdb /twaincs/source/obj /twaincs/source/twaincsscan/source/bin/x86/Debug /twaincs/source/twaincsscan/source/obj /twaincs/source/twaincstool/source/bin/x86/Debug /twaincs/source/twaincstool/source/obj /twaincs/source/twaincstst/source/bin/x86/Debug /twaincs/source/twaincstst/source/obj /twaincs/source/.vs/ /twaincs/source/bin/ /releases/twain-cs_02041100/twaincsscan/x64/Release/TWAINCSScan.log /releases/twain-cs_02041100/twaincsscan/x64/Release/twaindsm.log /releases/twain-cs_02041100/twaincstst/x86/Release/TWAINCSTst.log /twaincs/source/twaincscert/source/Properties/data.zip /twaincs/source/twaincscert/source/TWAIN-2.4-Specification.pdf /twaincs/source/twaincscert/source/bin/ /twaincs/source/twaincscert/source/data/version.txt /twaincs/source/twaincscert/source/obj/ /twaincs/source/twaincscert/source/twaincscert.csproj.user /twaincs/source/twaincsscan/source/bin/ /twaincs/source/twaincstool/source/bin/ /twaincs/source/twaincstst/source/bin/ ================================================ FILE: README.md ================================================ # TWAIN CS A C# interface for the TWAIN image capture API, that also includes a toolkit layer, a diagnostic application and a sample application. ## Features - Runs on Windows (.NET or Mono) - Runs on Linux and Mac OS X (Mono) - 32bit and 64bit support - Follows TWAIN "best practices" ================================================ FILE: releases/makerelease.bat ================================================ @echo off :: :: makerelease v1.1 08-Nov-2021 :: Ask some questions, and copy the built files into this folder :: to make releasing stuff easier and less error prone. :: :: :: Show the version info, and get an okay on it... :: echo. echo | set /p dummyName="TWAIN CS........................." findstr /C:"AssemblyFileVersion" "%~dp0%..\twaincs\source\Properties\AssemblyInfo.cs" :: echo | set /p dummyName="TWAIN CS Certification..........." findstr /C:"AssemblyFileVersion" "%~dp0%..\twaincs\source\twaincscert\source\Properties\AssemblyInfo.cs" :: echo | set /p dummyName="TWAIN CS Scan...................." findstr /C:"AssemblyFileVersion" "%~dp0%..\twaincs\source\twaincsscan\source\Properties\AssemblyInfo.cs" :: echo | set /p dummyName="TWAIN CS Test...................." findstr /C:"AssemblyFileVersion" "%~dp0%..\twaincs\source\twaincstst\source\Properties\AssemblyInfo.cs" :: echo. set answer= set /p answer="Are you happy with the version info (Y/n)? " if "%answer%" == "" goto VERSIONDONE if "%answer%" == "y" goto VERSIONDONE goto:EOF :: :VERSIONDONE :: :: Delete the current folder, and recreate it with subfolders... :: echo. echo *** Cleaning the twain-cs_00000000 folder... rmdir /s /q "%~dp0%twain-cs_00000000" > NUL 2>&1 mkdir "%~dp0%twain-cs_00000000" :: mkdir "%~dp0%twain-cs_00000000\twaincscert\AnyCPU\Debug" mkdir "%~dp0%twain-cs_00000000\twaincscert\AnyCPU\Release" mkdir "%~dp0%twain-cs_00000000\twaincscert\x64\Debug" mkdir "%~dp0%twain-cs_00000000\twaincscert\x64\Release" mkdir "%~dp0%twain-cs_00000000\twaincscert\x86\Debug" mkdir "%~dp0%twain-cs_00000000\twaincscert\x86\Release" :: mkdir "%~dp0%twain-cs_00000000\twaincsscan\AnyCPU\Debug" mkdir "%~dp0%twain-cs_00000000\twaincsscan\AnyCPU\Release" mkdir "%~dp0%twain-cs_00000000\twaincsscan\x64\Debug" mkdir "%~dp0%twain-cs_00000000\twaincsscan\x64\Release" mkdir "%~dp0%twain-cs_00000000\twaincsscan\x86\Debug" mkdir "%~dp0%twain-cs_00000000\twaincsscan\x86\Release" :: mkdir "%~dp0%twain-cs_00000000\twaincstst\AnyCPU\Debug" mkdir "%~dp0%twain-cs_00000000\twaincstst\AnyCPU\Release" mkdir "%~dp0%twain-cs_00000000\twaincstst\x64\Debug" mkdir "%~dp0%twain-cs_00000000\twaincstst\x64\Release" mkdir "%~dp0%twain-cs_00000000\twaincstst\x86\Debug" mkdir "%~dp0%twain-cs_00000000\twaincstst\x86\Release" :: :: Copy the files... :: echo. echo *** Copying TWAIN CS.rtf to the twain-cs_00000000 folder... xcopy "%~dp0%..\twaincs\source\TWAIN CS.rtf" "twain-cs_00000000\" | find /V "File(s)" :: echo. echo *** Copying TWAIN CS Certification files to the twain-cs_00000000 folder... xcopy "%~dp0%..\twaincs\source\twaincscert\source\bin\AnyCPU\Debug\TWAIN.dll" "twain-cs_00000000\twaincscert\AnyCPU\Debug\" | find /V "File(s)" xcopy "%~dp0%..\twaincs\source\twaincscert\source\bin\AnyCPU\Debug\TWAIN.pdb" "twain-cs_00000000\twaincscert\AnyCPU\Debug\" | find /V "File(s)" xcopy "%~dp0%..\twaincs\source\twaincscert\source\bin\AnyCPU\Debug\twaincscert.exe" "twain-cs_00000000\twaincscert\AnyCPU\Debug\" | find /V "File(s)" xcopy "%~dp0%..\twaincs\source\twaincscert\source\bin\AnyCPU\Debug\twaincscert.pdb" "twain-cs_00000000\twaincscert\AnyCPU\Debug\" | find /V "File(s)" xcopy "%~dp0%..\twaincs\source\twaincscert\source\bin\AnyCPU\Debug\twaincscert.exe.config" "twain-cs_00000000\twaincscert\AnyCPU\Debug\" | find /V "File(s)" :: xcopy "%~dp0%..\twaincs\source\twaincscert\source\bin\AnyCPU\Release\TWAIN.dll" "twain-cs_00000000\twaincscert\AnyCPU\Release\" | find /V "File(s)" xcopy "%~dp0%..\twaincs\source\twaincscert\source\bin\AnyCPU\Release\TWAIN.pdb" "twain-cs_00000000\twaincscert\AnyCPU\Release\" | find /V "File(s)" xcopy "%~dp0%..\twaincs\source\twaincscert\source\bin\AnyCPU\Release\twaincscert.exe" "twain-cs_00000000\twaincscert\AnyCPU\Release\" | find /V "File(s)" xcopy "%~dp0%..\twaincs\source\twaincscert\source\bin\AnyCPU\Release\twaincscert.pdb" "twain-cs_00000000\twaincscert\AnyCPU\Release\" | find /V "File(s)" xcopy "%~dp0%..\twaincs\source\twaincscert\source\bin\AnyCPU\Release\twaincscert.exe.config" "twain-cs_00000000\twaincscert\AnyCPU\Release\" | find /V "File(s)" :: xcopy "%~dp0%..\twaincs\source\twaincscert\source\bin\x64\Debug\TWAIN.dll" "twain-cs_00000000\twaincscert\x64\Debug\" | find /V "File(s)" xcopy "%~dp0%..\twaincs\source\twaincscert\source\bin\x64\Debug\TWAIN.pdb" "twain-cs_00000000\twaincscert\x64\Debug\" | find /V "File(s)" xcopy "%~dp0%..\twaincs\source\twaincscert\source\bin\x64\Debug\twaincscert.exe" "twain-cs_00000000\twaincscert\x64\Debug\" | find /V "File(s)" xcopy "%~dp0%..\twaincs\source\twaincscert\source\bin\x64\Debug\twaincscert.pdb" "twain-cs_00000000\twaincscert\x64\Debug\" | find /V "File(s)" xcopy "%~dp0%..\twaincs\source\twaincscert\source\bin\x64\Debug\twaincscert.exe.config" "twain-cs_00000000\twaincscert\x64\Debug\" | find /V "File(s)" :: xcopy "%~dp0%..\twaincs\source\twaincscert\source\bin\x64\Release\TWAIN.dll" "twain-cs_00000000\twaincscert\x64\Release\" | find /V "File(s)" xcopy "%~dp0%..\twaincs\source\twaincscert\source\bin\x64\Release\TWAIN.pdb" "twain-cs_00000000\twaincscert\x64\Release\" | find /V "File(s)" xcopy "%~dp0%..\twaincs\source\twaincscert\source\bin\x64\Release\twaincscert.exe" "twain-cs_00000000\twaincscert\x64\Release\" | find /V "File(s)" xcopy "%~dp0%..\twaincs\source\twaincscert\source\bin\x64\Release\twaincscert.pdb" "twain-cs_00000000\twaincscert\x64\Release\" | find /V "File(s)" xcopy "%~dp0%..\twaincs\source\twaincscert\source\bin\x64\Release\twaincscert.exe.config" "twain-cs_00000000\twaincscert\x64\Release\" | find /V "File(s)" :: xcopy "%~dp0%..\twaincs\source\twaincscert\source\bin\x86\Debug\TWAIN.dll" "twain-cs_00000000\twaincscert\x86\Debug\" | find /V "File(s)" xcopy "%~dp0%..\twaincs\source\twaincscert\source\bin\x86\Debug\TWAIN.pdb" "twain-cs_00000000\twaincscert\x86\Debug\" | find /V "File(s)" xcopy "%~dp0%..\twaincs\source\twaincscert\source\bin\x86\Debug\twaincscert.exe" "twain-cs_00000000\twaincscert\x86\Debug\" | find /V "File(s)" xcopy "%~dp0%..\twaincs\source\twaincscert\source\bin\x86\Debug\twaincscert.pdb" "twain-cs_00000000\twaincscert\x86\Debug\" | find /V "File(s)" xcopy "%~dp0%..\twaincs\source\twaincscert\source\bin\x86\Debug\twaincscert.exe.config" "twain-cs_00000000\twaincscert\x86\Debug\" | find /V "File(s)" :: xcopy "%~dp0%..\twaincs\source\twaincscert\source\bin\x86\Release\TWAIN.dll" "twain-cs_00000000\twaincscert\x86\Release\" | find /V "File(s)" xcopy "%~dp0%..\twaincs\source\twaincscert\source\bin\x86\Release\TWAIN.pdb" "twain-cs_00000000\twaincscert\x86\Release\" | find /V "File(s)" xcopy "%~dp0%..\twaincs\source\twaincscert\source\bin\x86\Release\twaincscert.exe" "twain-cs_00000000\twaincscert\x86\Release\" | find /V "File(s)" xcopy "%~dp0%..\twaincs\source\twaincscert\source\bin\x86\Release\twaincscert.pdb" "twain-cs_00000000\twaincscert\x86\Release\" | find /V "File(s)" xcopy "%~dp0%..\twaincs\source\twaincscert\source\bin\x86\Release\twaincscert.exe.config" "twain-cs_00000000\twaincscert\x86\Release\" | find /V "File(s)" :: echo. echo *** Copying TWAIN CS Scan files to the twain-cs_00000000 folder... xcopy "%~dp0%..\twaincs\source\twaincsscan\source\bin\AnyCPU\Debug\TWAIN.dll" "twain-cs_00000000\twaincsscan\AnyCPU\Debug\" | find /V "File(s)" xcopy "%~dp0%..\twaincs\source\twaincsscan\source\bin\AnyCPU\Debug\TWAIN.pdb" "twain-cs_00000000\twaincsscan\AnyCPU\Debug\" | find /V "File(s)" xcopy "%~dp0%..\twaincs\source\twaincsscan\source\bin\AnyCPU\Debug\twaincsscan.exe" "twain-cs_00000000\twaincsscan\AnyCPU\Debug\" | find /V "File(s)" xcopy "%~dp0%..\twaincs\source\twaincsscan\source\bin\AnyCPU\Debug\twaincsscan.pdb" "twain-cs_00000000\twaincsscan\AnyCPU\Debug\" | find /V "File(s)" xcopy "%~dp0%..\twaincs\source\twaincsscan\source\bin\AnyCPU\Debug\twaincsscan.exe.config" "twain-cs_00000000\twaincsscan\AnyCPU\Debug\" | find /V "File(s)" :: xcopy "%~dp0%..\twaincs\source\twaincsscan\source\bin\AnyCPU\Release\TWAIN.dll" "twain-cs_00000000\twaincsscan\AnyCPU\Release\" | find /V "File(s)" xcopy "%~dp0%..\twaincs\source\twaincsscan\source\bin\AnyCPU\Release\TWAIN.pdb" "twain-cs_00000000\twaincsscan\AnyCPU\Release\" | find /V "File(s)" xcopy "%~dp0%..\twaincs\source\twaincsscan\source\bin\AnyCPU\Release\twaincsscan.exe" "twain-cs_00000000\twaincsscan\AnyCPU\Release\" | find /V "File(s)" xcopy "%~dp0%..\twaincs\source\twaincsscan\source\bin\AnyCPU\Release\twaincsscan.pdb" "twain-cs_00000000\twaincsscan\AnyCPU\Release\" | find /V "File(s)" xcopy "%~dp0%..\twaincs\source\twaincsscan\source\bin\AnyCPU\Release\twaincsscan.exe.config" "twain-cs_00000000\twaincsscan\AnyCPU\Release\" | find /V "File(s)" :: xcopy "%~dp0%..\twaincs\source\twaincsscan\source\bin\x64\Debug\TWAIN.dll" "twain-cs_00000000\twaincsscan\x64\Debug\" | find /V "File(s)" xcopy "%~dp0%..\twaincs\source\twaincsscan\source\bin\x64\Debug\TWAIN.pdb" "twain-cs_00000000\twaincsscan\x64\Debug\" | find /V "File(s)" xcopy "%~dp0%..\twaincs\source\twaincsscan\source\bin\x64\Debug\twaincsscan.exe" "twain-cs_00000000\twaincsscan\x64\Debug\" | find /V "File(s)" xcopy "%~dp0%..\twaincs\source\twaincsscan\source\bin\x64\Debug\twaincsscan.pdb" "twain-cs_00000000\twaincsscan\x64\Debug\" | find /V "File(s)" xcopy "%~dp0%..\twaincs\source\twaincsscan\source\bin\x64\Debug\twaincsscan.exe.config" "twain-cs_00000000\twaincsscan\x64\Debug\" | find /V "File(s)" :: xcopy "%~dp0%..\twaincs\source\twaincsscan\source\bin\x64\Release\TWAIN.dll" "twain-cs_00000000\twaincsscan\x64\Release\" | find /V "File(s)" xcopy "%~dp0%..\twaincs\source\twaincsscan\source\bin\x64\Release\TWAIN.pdb" "twain-cs_00000000\twaincsscan\x64\Release\" | find /V "File(s)" xcopy "%~dp0%..\twaincs\source\twaincsscan\source\bin\x64\Release\twaincsscan.exe" "twain-cs_00000000\twaincsscan\x64\Release\" | find /V "File(s)" xcopy "%~dp0%..\twaincs\source\twaincsscan\source\bin\x64\Release\twaincsscan.pdb" "twain-cs_00000000\twaincsscan\x64\Release\" | find /V "File(s)" xcopy "%~dp0%..\twaincs\source\twaincsscan\source\bin\x64\Release\twaincsscan.exe.config" "twain-cs_00000000\twaincsscan\x64\Release\" | find /V "File(s)" :: xcopy "%~dp0%..\twaincs\source\twaincsscan\source\bin\x86\Debug\TWAIN.dll" "twain-cs_00000000\twaincsscan\x86\Debug\" | find /V "File(s)" xcopy "%~dp0%..\twaincs\source\twaincsscan\source\bin\x86\Debug\TWAIN.pdb" "twain-cs_00000000\twaincsscan\x86\Debug\" | find /V "File(s)" xcopy "%~dp0%..\twaincs\source\twaincsscan\source\bin\x86\Debug\twaincsscan.exe" "twain-cs_00000000\twaincsscan\x86\Debug\" | find /V "File(s)" xcopy "%~dp0%..\twaincs\source\twaincsscan\source\bin\x86\Debug\twaincsscan.pdb" "twain-cs_00000000\twaincsscan\x86\Debug\" | find /V "File(s)" xcopy "%~dp0%..\twaincs\source\twaincsscan\source\bin\x86\Debug\twaincsscan.exe.config" "twain-cs_00000000\twaincsscan\x86\Debug\" | find /V "File(s)" :: xcopy "%~dp0%..\twaincs\source\twaincsscan\source\bin\x86\Release\TWAIN.dll" "twain-cs_00000000\twaincsscan\x86\Release\" | find /V "File(s)" xcopy "%~dp0%..\twaincs\source\twaincsscan\source\bin\x86\Release\TWAIN.pdb" "twain-cs_00000000\twaincsscan\x86\Release\" | find /V "File(s)" xcopy "%~dp0%..\twaincs\source\twaincsscan\source\bin\x86\Release\twaincsscan.exe" "twain-cs_00000000\twaincsscan\x86\Release\" | find /V "File(s)" xcopy "%~dp0%..\twaincs\source\twaincsscan\source\bin\x86\Release\twaincsscan.pdb" "twain-cs_00000000\twaincsscan\x86\Release\" | find /V "File(s)" xcopy "%~dp0%..\twaincs\source\twaincsscan\source\bin\x86\Release\twaincsscan.exe.config" "twain-cs_00000000\twaincsscan\x86\Release\" | find /V "File(s)" :: echo. echo *** Copying TWAIN CS Test files to the twain-cs_00000000 folder... xcopy "%~dp0%..\twaincs\source\twaincstst\source\bin\AnyCPU\Debug\TWAIN.dll" "twain-cs_00000000\twaincstst\AnyCPU\Debug\" | find /V "File(s)" xcopy "%~dp0%..\twaincs\source\twaincstst\source\bin\AnyCPU\Debug\TWAIN.pdb" "twain-cs_00000000\twaincstst\AnyCPU\Debug\" | find /V "File(s)" xcopy "%~dp0%..\twaincs\source\twaincstst\source\bin\AnyCPU\Debug\twaincstst.exe" "twain-cs_00000000\twaincstst\AnyCPU\Debug\" | find /V "File(s)" xcopy "%~dp0%..\twaincs\source\twaincstst\source\bin\AnyCPU\Debug\twaincstst.pdb" "twain-cs_00000000\twaincstst\AnyCPU\Debug\" | find /V "File(s)" xcopy "%~dp0%..\twaincs\source\twaincstst\source\bin\AnyCPU\Debug\twaincstst.exe.config" "twain-cs_00000000\twaincstst\AnyCPU\Debug\" | find /V "File(s)" :: xcopy "%~dp0%..\twaincs\source\twaincstst\source\bin\AnyCPU\Release\TWAIN.dll" "twain-cs_00000000\twaincstst\AnyCPU\Release\" | find /V "File(s)" xcopy "%~dp0%..\twaincs\source\twaincstst\source\bin\AnyCPU\Release\TWAIN.pdb" "twain-cs_00000000\twaincstst\AnyCPU\Release\" | find /V "File(s)" xcopy "%~dp0%..\twaincs\source\twaincstst\source\bin\AnyCPU\Release\twaincstst.exe" "twain-cs_00000000\twaincstst\AnyCPU\Release\" | find /V "File(s)" xcopy "%~dp0%..\twaincs\source\twaincstst\source\bin\AnyCPU\Release\twaincstst.pdb" "twain-cs_00000000\twaincstst\AnyCPU\Release\" | find /V "File(s)" xcopy "%~dp0%..\twaincs\source\twaincstst\source\bin\AnyCPU\Release\twaincstst.exe.config" "twain-cs_00000000\twaincstst\AnyCPU\Release\" | find /V "File(s)" :: xcopy "%~dp0%..\twaincs\source\twaincstst\source\bin\x64\Debug\TWAIN.dll" "twain-cs_00000000\twaincstst\x64\Debug\" | find /V "File(s)" xcopy "%~dp0%..\twaincs\source\twaincstst\source\bin\x64\Debug\TWAIN.pdb" "twain-cs_00000000\twaincstst\x64\Debug\" | find /V "File(s)" xcopy "%~dp0%..\twaincs\source\twaincstst\source\bin\x64\Debug\twaincstst.exe" "twain-cs_00000000\twaincstst\x64\Debug\" | find /V "File(s)" xcopy "%~dp0%..\twaincs\source\twaincstst\source\bin\x64\Debug\twaincstst.pdb" "twain-cs_00000000\twaincstst\x64\Debug\" | find /V "File(s)" xcopy "%~dp0%..\twaincs\source\twaincstst\source\bin\x64\Debug\twaincstst.exe.config" "twain-cs_00000000\twaincstst\x64\Debug\" | find /V "File(s)" :: xcopy "%~dp0%..\twaincs\source\twaincstst\source\bin\x64\Release\TWAIN.dll" "twain-cs_00000000\twaincstst\x64\Release\" | find /V "File(s)" xcopy "%~dp0%..\twaincs\source\twaincstst\source\bin\x64\Release\TWAIN.pdb" "twain-cs_00000000\twaincstst\x64\Release\" | find /V "File(s)" xcopy "%~dp0%..\twaincs\source\twaincstst\source\bin\x64\Release\twaincstst.exe" "twain-cs_00000000\twaincstst\x64\Release\" | find /V "File(s)" xcopy "%~dp0%..\twaincs\source\twaincstst\source\bin\x64\Release\twaincstst.pdb" "twain-cs_00000000\twaincstst\x64\Release\" | find /V "File(s)" xcopy "%~dp0%..\twaincs\source\twaincstst\source\bin\x64\Release\twaincstst.exe.config" "twain-cs_00000000\twaincstst\x64\Release\" | find /V "File(s)" :: xcopy "%~dp0%..\twaincs\source\twaincstst\source\bin\x86\Debug\TWAIN.dll" "twain-cs_00000000\twaincstst\x86\Debug\" | find /V "File(s)" xcopy "%~dp0%..\twaincs\source\twaincstst\source\bin\x86\Debug\TWAIN.pdb" "twain-cs_00000000\twaincstst\x86\Debug\" | find /V "File(s)" xcopy "%~dp0%..\twaincs\source\twaincstst\source\bin\x86\Debug\twaincstst.exe" "twain-cs_00000000\twaincstst\x86\Debug\" | find /V "File(s)" xcopy "%~dp0%..\twaincs\source\twaincstst\source\bin\x86\Debug\twaincstst.pdb" "twain-cs_00000000\twaincstst\x86\Debug\" | find /V "File(s)" xcopy "%~dp0%..\twaincs\source\twaincstst\source\bin\x86\Debug\twaincstst.exe.config" "twain-cs_00000000\twaincstst\x86\Debug\" | find /V "File(s)" :: xcopy "%~dp0%..\twaincs\source\twaincstst\source\bin\x86\Release\TWAIN.dll" "twain-cs_00000000\twaincstst\x86\Release\" | find /V "File(s)" xcopy "%~dp0%..\twaincs\source\twaincstst\source\bin\x86\Release\TWAIN.pdb" "twain-cs_00000000\twaincstst\x86\Release\" | find /V "File(s)" xcopy "%~dp0%..\twaincs\source\twaincstst\source\bin\x86\Release\twaincstst.exe" "twain-cs_00000000\twaincstst\x86\Release\" | find /V "File(s)" xcopy "%~dp0%..\twaincs\source\twaincstst\source\bin\x86\Release\twaincstst.pdb" "twain-cs_00000000\twaincstst\x86\Release\" | find /V "File(s)" xcopy "%~dp0%..\twaincs\source\twaincstst\source\bin\x86\Release\twaincstst.exe.config" "twain-cs_00000000\twaincstst\x86\Release\" | find /V "File(s)" :: :: All done... :: echo. echo *** All done, be sure to rename the twain-cs_00000000 folder before committing... goto:EOF ================================================ FILE: releases/twain-cs_02041000/TWAIN CS.rtf ================================================ {\rtf1\adeflang1025\ansi\ansicpg1252\uc1\adeff44\deff0\stshfdbch0\stshfloch0\stshfhich0\stshfbi0\deflang1033\deflangfe1033\themelang1033\themelangfe0\themelangcs0{\fonttbl{\f0\fbidi \froman\fcharset0\fprq2{\*\panose 02020603050405020304}Times New Roman{\*\falt Times New Roman};} {\f1\fbidi \fswiss\fcharset0\fprq2{\*\panose 020b0604020202020204}Arial{\*\falt Arial};}{\f2\fbidi \fmodern\fcharset0\fprq1{\*\panose 02070309020205020404}Courier New{\*\falt Courier New};} {\f3\fbidi \froman\fcharset2\fprq2{\*\panose 05050102010706020507}Symbol;}{\f4\fbidi \fswiss\fcharset0\fprq2{\*\panose 020b0604020202020204}Helvetica;}{\f5\fbidi \fmodern\fcharset0\fprq1{\*\panose 02070409020205020404}Courier{\*\falt Courier New};} {\f10\fbidi \fnil\fcharset2\fprq2{\*\panose 05000000000000000000}Wingdings;}{\f34\fbidi \froman\fcharset0\fprq2{\*\panose 02040503050406030204}Cambria Math;} {\f37\fbidi \fswiss\fcharset0\fprq2{\*\panose 020f0502020204030204}Calibri{\*\falt Century Gothic};}{\f42\fbidi \froman\fcharset0\fprq2{\*\panose 02040503050406030204}Cambria{\*\falt Palatino Linotype};} {\f43\fbidi \fswiss\fcharset0\fprq2{\*\panose 020b0604030504040204}Tahoma;}{\f44\fbidi \froman\fcharset0\fprq2{\*\panose 02040602050305030304}Book Antiqua{\*\falt Book Antiqua};} {\f45\fbidi \froman\fcharset0\fprq0{\*\panose 00000000000000000000}BookAntiqua{\*\falt Book Antiqua};}{\f46\fbidi \froman\fcharset0\fprq2{\*\panose 00000000000000000000}MS Serif;} {\f47\fbidi \fswiss\fcharset0\fprq2{\*\panose 00000000000000000000}Geneva{\*\falt Arial};}{\f48\fbidi \fnil\fcharset0\fprq0{\*\panose 00000000000000000000}Courier Std;}{\f49\fbidi \fmodern\fcharset0\fprq1{\*\panose 00000000000000000000}Consolas;} {\f50\fbidi \froman\fcharset0\fprq0{\*\panose 00000000000000000000}CourierNewPSMT;}{\flomajor\f31500\fbidi \froman\fcharset0\fprq2{\*\panose 02020603050405020304}Times New Roman{\*\falt Times New Roman};} {\fdbmajor\f31501\fbidi \froman\fcharset0\fprq2{\*\panose 02020603050405020304}Times New Roman{\*\falt Times New Roman};}{\fhimajor\f31502\fbidi \froman\fcharset0\fprq2{\*\panose 02040503050406030204}Cambria{\*\falt Palatino Linotype};} {\fbimajor\f31503\fbidi \froman\fcharset0\fprq2{\*\panose 02020603050405020304}Times New Roman{\*\falt Times New Roman};}{\flominor\f31504\fbidi \froman\fcharset0\fprq2{\*\panose 02020603050405020304}Times New Roman{\*\falt Times New Roman};} {\fdbminor\f31505\fbidi \froman\fcharset0\fprq2{\*\panose 02020603050405020304}Times New Roman{\*\falt Times New Roman};}{\fhiminor\f31506\fbidi \fswiss\fcharset0\fprq2{\*\panose 020f0502020204030204}Calibri{\*\falt Century Gothic};} {\fbiminor\f31507\fbidi \froman\fcharset0\fprq2{\*\panose 02020603050405020304}Times New Roman{\*\falt Times New Roman};}{\f52\fbidi \froman\fcharset238\fprq2 Times New Roman CE{\*\falt Times New Roman};} {\f53\fbidi \froman\fcharset204\fprq2 Times New Roman Cyr{\*\falt Times New Roman};}{\f55\fbidi \froman\fcharset161\fprq2 Times New Roman Greek{\*\falt Times New Roman};}{\f56\fbidi \froman\fcharset162\fprq2 Times New Roman Tur{\*\falt Times New Roman};} {\f57\fbidi \froman\fcharset177\fprq2 Times New Roman (Hebrew){\*\falt Times New Roman};}{\f58\fbidi \froman\fcharset178\fprq2 Times New Roman (Arabic){\*\falt Times New Roman};} {\f59\fbidi \froman\fcharset186\fprq2 Times New Roman Baltic{\*\falt Times New Roman};}{\f60\fbidi \froman\fcharset163\fprq2 Times New Roman (Vietnamese){\*\falt Times New Roman};}{\f62\fbidi \fswiss\fcharset238\fprq2 Arial CE{\*\falt Arial};} {\f63\fbidi \fswiss\fcharset204\fprq2 Arial Cyr{\*\falt Arial};}{\f65\fbidi \fswiss\fcharset161\fprq2 Arial Greek{\*\falt Arial};}{\f66\fbidi \fswiss\fcharset162\fprq2 Arial Tur{\*\falt Arial};} {\f67\fbidi \fswiss\fcharset177\fprq2 Arial (Hebrew){\*\falt Arial};}{\f68\fbidi \fswiss\fcharset178\fprq2 Arial (Arabic){\*\falt Arial};}{\f69\fbidi \fswiss\fcharset186\fprq2 Arial Baltic{\*\falt Arial};} {\f70\fbidi \fswiss\fcharset163\fprq2 Arial (Vietnamese){\*\falt Arial};}{\f72\fbidi \fmodern\fcharset238\fprq1 Courier New CE{\*\falt Courier New};}{\f73\fbidi \fmodern\fcharset204\fprq1 Courier New Cyr{\*\falt Courier New};} {\f75\fbidi \fmodern\fcharset161\fprq1 Courier New Greek{\*\falt Courier New};}{\f76\fbidi \fmodern\fcharset162\fprq1 Courier New Tur{\*\falt Courier New};}{\f77\fbidi \fmodern\fcharset177\fprq1 Courier New (Hebrew){\*\falt Courier New};} {\f78\fbidi \fmodern\fcharset178\fprq1 Courier New (Arabic){\*\falt Courier New};}{\f79\fbidi \fmodern\fcharset186\fprq1 Courier New Baltic{\*\falt Courier New};}{\f80\fbidi \fmodern\fcharset163\fprq1 Courier New (Vietnamese){\*\falt Courier New};} {\f92\fbidi \fswiss\fcharset238\fprq2 Helvetica CE;}{\f93\fbidi \fswiss\fcharset204\fprq2 Helvetica Cyr;}{\f95\fbidi \fswiss\fcharset161\fprq2 Helvetica Greek;}{\f96\fbidi \fswiss\fcharset162\fprq2 Helvetica Tur;} {\f97\fbidi \fswiss\fcharset177\fprq2 Helvetica (Hebrew);}{\f98\fbidi \fswiss\fcharset178\fprq2 Helvetica (Arabic);}{\f99\fbidi \fswiss\fcharset186\fprq2 Helvetica Baltic;}{\f100\fbidi \fswiss\fcharset163\fprq2 Helvetica (Vietnamese);} {\f392\fbidi \froman\fcharset238\fprq2 Cambria Math CE;}{\f393\fbidi \froman\fcharset204\fprq2 Cambria Math Cyr;}{\f395\fbidi \froman\fcharset161\fprq2 Cambria Math Greek;}{\f396\fbidi \froman\fcharset162\fprq2 Cambria Math Tur;} {\f399\fbidi \froman\fcharset186\fprq2 Cambria Math Baltic;}{\f400\fbidi \froman\fcharset163\fprq2 Cambria Math (Vietnamese);}{\f422\fbidi \fswiss\fcharset238\fprq2 Calibri CE{\*\falt Century Gothic};} {\f423\fbidi \fswiss\fcharset204\fprq2 Calibri Cyr{\*\falt Century Gothic};}{\f425\fbidi \fswiss\fcharset161\fprq2 Calibri Greek{\*\falt Century Gothic};}{\f426\fbidi \fswiss\fcharset162\fprq2 Calibri Tur{\*\falt Century Gothic};} {\f427\fbidi \fswiss\fcharset177\fprq2 Calibri (Hebrew){\*\falt Century Gothic};}{\f428\fbidi \fswiss\fcharset178\fprq2 Calibri (Arabic){\*\falt Century Gothic};}{\f429\fbidi \fswiss\fcharset186\fprq2 Calibri Baltic{\*\falt Century Gothic};} {\f430\fbidi \fswiss\fcharset163\fprq2 Calibri (Vietnamese){\*\falt Century Gothic};}{\f472\fbidi \froman\fcharset238\fprq2 Cambria CE{\*\falt Palatino Linotype};}{\f473\fbidi \froman\fcharset204\fprq2 Cambria Cyr{\*\falt Palatino Linotype};} {\f475\fbidi \froman\fcharset161\fprq2 Cambria Greek{\*\falt Palatino Linotype};}{\f476\fbidi \froman\fcharset162\fprq2 Cambria Tur{\*\falt Palatino Linotype};}{\f479\fbidi \froman\fcharset186\fprq2 Cambria Baltic{\*\falt Palatino Linotype};} {\f480\fbidi \froman\fcharset163\fprq2 Cambria (Vietnamese){\*\falt Palatino Linotype};}{\f482\fbidi \fswiss\fcharset238\fprq2 Tahoma CE;}{\f483\fbidi \fswiss\fcharset204\fprq2 Tahoma Cyr;}{\f485\fbidi \fswiss\fcharset161\fprq2 Tahoma Greek;} {\f486\fbidi \fswiss\fcharset162\fprq2 Tahoma Tur;}{\f487\fbidi \fswiss\fcharset177\fprq2 Tahoma (Hebrew);}{\f488\fbidi \fswiss\fcharset178\fprq2 Tahoma (Arabic);}{\f489\fbidi \fswiss\fcharset186\fprq2 Tahoma Baltic;} {\f490\fbidi \fswiss\fcharset163\fprq2 Tahoma (Vietnamese);}{\f491\fbidi \fswiss\fcharset222\fprq2 Tahoma (Thai);}{\f492\fbidi \froman\fcharset238\fprq2 Book Antiqua CE{\*\falt Book Antiqua};} {\f493\fbidi \froman\fcharset204\fprq2 Book Antiqua Cyr{\*\falt Book Antiqua};}{\f495\fbidi \froman\fcharset161\fprq2 Book Antiqua Greek{\*\falt Book Antiqua};}{\f496\fbidi \froman\fcharset162\fprq2 Book Antiqua Tur{\*\falt Book Antiqua};} {\f499\fbidi \froman\fcharset186\fprq2 Book Antiqua Baltic{\*\falt Book Antiqua};}{\f542\fbidi \fmodern\fcharset238\fprq1 Consolas CE;}{\f543\fbidi \fmodern\fcharset204\fprq1 Consolas Cyr;}{\f545\fbidi \fmodern\fcharset161\fprq1 Consolas Greek;} {\f546\fbidi \fmodern\fcharset162\fprq1 Consolas Tur;}{\f549\fbidi \fmodern\fcharset186\fprq1 Consolas Baltic;}{\f550\fbidi \fmodern\fcharset163\fprq1 Consolas (Vietnamese);} {\flomajor\f31508\fbidi \froman\fcharset238\fprq2 Times New Roman CE{\*\falt Times New Roman};}{\flomajor\f31509\fbidi \froman\fcharset204\fprq2 Times New Roman Cyr{\*\falt Times New Roman};} {\flomajor\f31511\fbidi \froman\fcharset161\fprq2 Times New Roman Greek{\*\falt Times New Roman};}{\flomajor\f31512\fbidi \froman\fcharset162\fprq2 Times New Roman Tur{\*\falt Times New Roman};} {\flomajor\f31513\fbidi \froman\fcharset177\fprq2 Times New Roman (Hebrew){\*\falt Times New Roman};}{\flomajor\f31514\fbidi \froman\fcharset178\fprq2 Times New Roman (Arabic){\*\falt Times New Roman};} {\flomajor\f31515\fbidi \froman\fcharset186\fprq2 Times New Roman Baltic{\*\falt Times New Roman};}{\flomajor\f31516\fbidi \froman\fcharset163\fprq2 Times New Roman (Vietnamese){\*\falt Times New Roman};} {\fdbmajor\f31518\fbidi \froman\fcharset238\fprq2 Times New Roman CE{\*\falt Times New Roman};}{\fdbmajor\f31519\fbidi \froman\fcharset204\fprq2 Times New Roman Cyr{\*\falt Times New Roman};} {\fdbmajor\f31521\fbidi \froman\fcharset161\fprq2 Times New Roman Greek{\*\falt Times New Roman};}{\fdbmajor\f31522\fbidi \froman\fcharset162\fprq2 Times New Roman Tur{\*\falt Times New Roman};} {\fdbmajor\f31523\fbidi \froman\fcharset177\fprq2 Times New Roman (Hebrew){\*\falt Times New Roman};}{\fdbmajor\f31524\fbidi \froman\fcharset178\fprq2 Times New Roman (Arabic){\*\falt Times New Roman};} {\fdbmajor\f31525\fbidi \froman\fcharset186\fprq2 Times New Roman Baltic{\*\falt Times New Roman};}{\fdbmajor\f31526\fbidi \froman\fcharset163\fprq2 Times New Roman (Vietnamese){\*\falt Times New Roman};} {\fhimajor\f31528\fbidi \froman\fcharset238\fprq2 Cambria CE{\*\falt Palatino Linotype};}{\fhimajor\f31529\fbidi \froman\fcharset204\fprq2 Cambria Cyr{\*\falt Palatino Linotype};} {\fhimajor\f31531\fbidi \froman\fcharset161\fprq2 Cambria Greek{\*\falt Palatino Linotype};}{\fhimajor\f31532\fbidi \froman\fcharset162\fprq2 Cambria Tur{\*\falt Palatino Linotype};} {\fhimajor\f31535\fbidi \froman\fcharset186\fprq2 Cambria Baltic{\*\falt Palatino Linotype};}{\fhimajor\f31536\fbidi \froman\fcharset163\fprq2 Cambria (Vietnamese){\*\falt Palatino Linotype};} {\fbimajor\f31538\fbidi \froman\fcharset238\fprq2 Times New Roman CE{\*\falt Times New Roman};}{\fbimajor\f31539\fbidi \froman\fcharset204\fprq2 Times New Roman Cyr{\*\falt Times New Roman};} {\fbimajor\f31541\fbidi \froman\fcharset161\fprq2 Times New Roman Greek{\*\falt Times New Roman};}{\fbimajor\f31542\fbidi \froman\fcharset162\fprq2 Times New Roman Tur{\*\falt Times New Roman};} {\fbimajor\f31543\fbidi \froman\fcharset177\fprq2 Times New Roman (Hebrew){\*\falt Times New Roman};}{\fbimajor\f31544\fbidi \froman\fcharset178\fprq2 Times New Roman (Arabic){\*\falt Times New Roman};} {\fbimajor\f31545\fbidi \froman\fcharset186\fprq2 Times New Roman Baltic{\*\falt Times New Roman};}{\fbimajor\f31546\fbidi \froman\fcharset163\fprq2 Times New Roman (Vietnamese){\*\falt Times New Roman};} {\flominor\f31548\fbidi \froman\fcharset238\fprq2 Times New Roman CE{\*\falt Times New Roman};}{\flominor\f31549\fbidi \froman\fcharset204\fprq2 Times New Roman Cyr{\*\falt Times New Roman};} {\flominor\f31551\fbidi \froman\fcharset161\fprq2 Times New Roman Greek{\*\falt Times New Roman};}{\flominor\f31552\fbidi \froman\fcharset162\fprq2 Times New Roman Tur{\*\falt Times New Roman};} {\flominor\f31553\fbidi \froman\fcharset177\fprq2 Times New Roman (Hebrew){\*\falt Times New Roman};}{\flominor\f31554\fbidi \froman\fcharset178\fprq2 Times New Roman (Arabic){\*\falt Times New Roman};} {\flominor\f31555\fbidi \froman\fcharset186\fprq2 Times New Roman Baltic{\*\falt Times New Roman};}{\flominor\f31556\fbidi \froman\fcharset163\fprq2 Times New Roman (Vietnamese){\*\falt Times New Roman};} {\fdbminor\f31558\fbidi \froman\fcharset238\fprq2 Times New Roman CE{\*\falt Times New Roman};}{\fdbminor\f31559\fbidi \froman\fcharset204\fprq2 Times New Roman Cyr{\*\falt Times New Roman};} {\fdbminor\f31561\fbidi \froman\fcharset161\fprq2 Times New Roman Greek{\*\falt Times New Roman};}{\fdbminor\f31562\fbidi \froman\fcharset162\fprq2 Times New Roman Tur{\*\falt Times New Roman};} {\fdbminor\f31563\fbidi \froman\fcharset177\fprq2 Times New Roman (Hebrew){\*\falt Times New Roman};}{\fdbminor\f31564\fbidi \froman\fcharset178\fprq2 Times New Roman (Arabic){\*\falt Times New Roman};} {\fdbminor\f31565\fbidi \froman\fcharset186\fprq2 Times New Roman Baltic{\*\falt Times New Roman};}{\fdbminor\f31566\fbidi \froman\fcharset163\fprq2 Times New Roman (Vietnamese){\*\falt Times New Roman};} {\fhiminor\f31568\fbidi \fswiss\fcharset238\fprq2 Calibri CE{\*\falt Century Gothic};}{\fhiminor\f31569\fbidi \fswiss\fcharset204\fprq2 Calibri Cyr{\*\falt Century Gothic};} {\fhiminor\f31571\fbidi \fswiss\fcharset161\fprq2 Calibri Greek{\*\falt Century Gothic};}{\fhiminor\f31572\fbidi \fswiss\fcharset162\fprq2 Calibri Tur{\*\falt Century Gothic};} {\fhiminor\f31573\fbidi \fswiss\fcharset177\fprq2 Calibri (Hebrew){\*\falt Century Gothic};}{\fhiminor\f31574\fbidi \fswiss\fcharset178\fprq2 Calibri (Arabic){\*\falt Century Gothic};} {\fhiminor\f31575\fbidi \fswiss\fcharset186\fprq2 Calibri Baltic{\*\falt Century Gothic};}{\fhiminor\f31576\fbidi \fswiss\fcharset163\fprq2 Calibri (Vietnamese){\*\falt Century Gothic};} {\fbiminor\f31578\fbidi \froman\fcharset238\fprq2 Times New Roman CE{\*\falt Times New Roman};}{\fbiminor\f31579\fbidi \froman\fcharset204\fprq2 Times New Roman Cyr{\*\falt Times New Roman};} {\fbiminor\f31581\fbidi \froman\fcharset161\fprq2 Times New Roman Greek{\*\falt Times New Roman};}{\fbiminor\f31582\fbidi \froman\fcharset162\fprq2 Times New Roman Tur{\*\falt Times New Roman};} {\fbiminor\f31583\fbidi \froman\fcharset177\fprq2 Times New Roman (Hebrew){\*\falt Times New Roman};}{\fbiminor\f31584\fbidi \froman\fcharset178\fprq2 Times New Roman (Arabic){\*\falt Times New Roman};} {\fbiminor\f31585\fbidi \froman\fcharset186\fprq2 Times New Roman Baltic{\*\falt Times New Roman};}{\fbiminor\f31586\fbidi \froman\fcharset163\fprq2 Times New Roman (Vietnamese){\*\falt Times New Roman};}}{\colortbl;\red0\green0\blue0; \red0\green0\blue255;\red0\green255\blue255;\red0\green255\blue0;\red255\green0\blue255;\red255\green0\blue0;\red255\green255\blue0;\red255\green255\blue255;\red0\green0\blue128;\red0\green128\blue128;\red0\green128\blue0;\red128\green0\blue128; \red128\green0\blue0;\red128\green128\blue0;\red128\green128\blue128;\red192\green192\blue192;\red0\green0\blue0;\red0\green0\blue0;\cfollowedhyperlink\ctint255\cshade255\red128\green0\blue128;\red96\green94\blue92;\red225\green223\blue221; \red31\green73\blue125;\red0\green176\blue80;}{\*\defchp \fs22 }{\*\defpap \ql \li0\ri0\sa200\sl276\slmult1\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 }\noqfpromote {\stylesheet{ \ql \li1440\ri0\sb180\widctlpar\wrapdefault\nooverflow\faroman\rin0\lin1440\itap0 \rtlch\fcs1 \af44\afs20\alang1025 \ltrch\fcs0 \f44\fs20\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \snext0 \sqformat \spriority0 Normal;}{ \s1\ql \li0\ri0\sb720\keepn\widctlpar\brdrt\brdrs\brdrw30\brsp120 \wrapdefault\nooverflow\faroman\outlinelevel0\rin0\lin0\itap0 \rtlch\fcs1 \ab\af1\afs36\alang1025 \ltrch\fcs0 \b\f1\fs36\cf9\lang1024\langfe1024\cgrid\noproof\langnp1033\langfenp1033 \sbasedon0 \snext0 \slink15 \sqformat heading 1;}{\s2\ql \li720\ri0\sb360\keepn\widctlpar\wrapdefault\nooverflow\faroman\outlinelevel1\rin0\lin720\itap0 \rtlch\fcs1 \ab\af1\afs20\alang1025 \ltrch\fcs0 \b\f1\fs20\cf13\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \sbasedon0 \snext0 \slink16 \sqformat heading 2;}{\s3\ql \li1440\ri0\sb180\keepn\widctlpar\wrapdefault\nooverflow\faroman\outlinelevel2\rin0\lin1440\itap0 \rtlch\fcs1 \ab\af1\afs20\alang1025 \ltrch\fcs0 \b\f1\fs20\cf10\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \sbasedon0 \snext24 \slink17 \sqformat heading 3;}{\s4\ql \li1440\ri0\sb180\widctlpar\wrapdefault\nooverflow\faroman\outlinelevel3\rin0\lin1440\itap0 \rtlch\fcs1 \af46\afs24\alang1025 \ltrch\fcs0 \f46\fs24\ul\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \sbasedon0 \snext24 \slink18 \sqformat heading 4;}{ \s5\ql \li1440\ri0\sb180\widctlpar\wrapdefault\nooverflow\faroman\outlinelevel4\rin0\lin1440\itap0 \rtlch\fcs1 \ab\af46\afs20\alang1025 \ltrch\fcs0 \b\f46\fs20\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \sbasedon0 \snext24 \slink19 \sqformat heading 5;}{\s6\ql \li1440\ri0\sb180\widctlpar\wrapdefault\nooverflow\faroman\outlinelevel5\rin0\lin1440\itap0 \rtlch\fcs1 \af46\afs20\alang1025 \ltrch\fcs0 \f46\fs20\ul\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \sbasedon0 \snext24 \slink20 \sqformat heading 6;}{\s7\ql \li1440\ri0\sb180\widctlpar\wrapdefault\nooverflow\faroman\outlinelevel6\rin0\lin1440\itap0 \rtlch\fcs1 \ai\af46\afs20\alang1025 \ltrch\fcs0 \i\f46\fs20\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \sbasedon0 \snext24 \slink21 \sqformat heading 7;}{\s8\ql \li1440\ri0\sb240\sa60\widctlpar\wrapdefault\nooverflow\faroman\outlinelevel7\rin0\lin1440\itap0 \rtlch\fcs1 \ai\af44\afs20\alang1025 \ltrch\fcs0 \i\f44\fs20\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \sbasedon0 \snext0 \slink22 \sqformat heading 8;}{\s9\ql \li1440\ri0\sb240\sa60\widctlpar\wrapdefault\nooverflow\faroman\outlinelevel8\rin0\lin1440\itap0 \rtlch\fcs1 \ab\ai\af44\afs18\alang1025 \ltrch\fcs0 \b\i\f44\fs18\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \sbasedon0 \snext0 \slink23 \sqformat heading 9;}{\*\cs10 \additive \ssemihidden Default Paragraph Font;}{\* \ts11\tsrowd\trftsWidthB3\trpaddl108\trpaddr108\trpaddfl3\trpaddft3\trpaddfb3\trpaddfr3\trcbpat1\trcfpat1\tblind0\tblindtype3\tsvertalt\tsbrdrt\tsbrdrl\tsbrdrb\tsbrdrr\tsbrdrdgl\tsbrdrdgr\tsbrdrh\tsbrdrv \ql \li0\ri0\sa200\sl276\slmult1 \widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 \rtlch\fcs1 \af0\afs22\alang1025 \ltrch\fcs0 \fs22\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \snext11 \ssemihidden \sunhideused Normal Table;}{\*\cs15 \additive \rtlch\fcs1 \ab\af0\afs32 \ltrch\fcs0 \b\f42\fs32\kerning32 \sbasedon10 \slink1 \slocked Heading 1 Char;}{\*\cs16 \additive \rtlch\fcs1 \ab\ai\af0\afs28 \ltrch\fcs0 \b\i\f42\fs28 \sbasedon10 \slink2 \slocked \ssemihidden Heading 2 Char;}{\*\cs17 \additive \rtlch\fcs1 \ab\af0\afs26 \ltrch\fcs0 \b\f42\fs26 \sbasedon10 \slink3 \slocked \ssemihidden Heading 3 Char;}{\*\cs18 \additive \rtlch\fcs1 \ab\af0\afs28 \ltrch\fcs0 \b\f37\fs28 \sbasedon10 \slink4 \slocked \ssemihidden Heading 4 Char;}{\*\cs19 \additive \rtlch\fcs1 \ab\ai\af0\afs26 \ltrch\fcs0 \b\i\f37\fs26 \sbasedon10 \slink5 \slocked \ssemihidden Heading 5 Char;}{\*\cs20 \additive \rtlch\fcs1 \ab\af0 \ltrch\fcs0 \b\f37 \sbasedon10 \slink6 \slocked \ssemihidden Heading 6 Char;}{\*\cs21 \additive \rtlch\fcs1 \af0\afs24 \ltrch\fcs0 \f37\fs24 \sbasedon10 \slink7 \slocked \ssemihidden Heading 7 Char;}{\*\cs22 \additive \rtlch\fcs1 \ai\af0\afs24 \ltrch\fcs0 \i\f37\fs24 \sbasedon10 \slink8 \slocked \ssemihidden Heading 8 Char;}{\*\cs23 \additive \rtlch\fcs1 \af0 \ltrch\fcs0 \f42 \sbasedon10 \slink9 \slocked \ssemihidden Heading 9 Char;}{\s24\ql \li1800\ri0\sb180\widctlpar\wrapdefault\nooverflow\faroman\rin0\lin1800\itap0 \rtlch\fcs1 \af44\afs20\alang1025 \ltrch\fcs0 \f44\fs20\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \sbasedon0 \snext24 Normal Indent;}{\s25\ql \li0\ri0\widctlpar\tqr\tx9360\wrapdefault\nooverflow\faroman\rin0\lin0\itap0 \rtlch\fcs1 \ai\af1\afs16\alang1025 \ltrch\fcs0 \i\f1\fs16\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \sbasedon0 \snext25 \slink26 footer;}{\*\cs26 \additive \rtlch\fcs1 \af44\afs20 \ltrch\fcs0 \f44\fs20 \sbasedon10 \slink25 \slocked \ssemihidden Footer Char;}{\s27\ql \li0\ri0\widctlpar \tqr\tx9900\wrapdefault\nooverflow\faroman\rin0\lin0\itap0 \rtlch\fcs1 \ab\ai\af1\afs20\alang1025 \ltrch\fcs0 \b\i\f1\fs20\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \sbasedon0 \snext27 \slink28 header;}{\*\cs28 \additive \rtlch\fcs1 \af44\afs20 \ltrch\fcs0 \f44\fs20 \sbasedon10 \slink27 \slocked \ssemihidden Header Char;}{\s29\ql \li2160\ri0\sb40\widctlpar\wrapdefault\nooverflow\faroman\rin0\lin2160\itap0 \rtlch\fcs1 \af2\afs18\alang1025 \ltrch\fcs0 \f2\fs18\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \sbasedon30 \snext29 prog indent;}{\s30\ql \li1800\ri0\sb40\widctlpar\wrapdefault\nooverflow\faroman\rin0\lin1800\itap0 \rtlch\fcs1 \af2\afs18\alang1025 \ltrch\fcs0 \f2\fs18\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \sbasedon31 \snext30 prog;}{\s31\ql \fi-360\li360\ri0\sb180\widctlpar\wrapdefault\nooverflow\faroman\rin0\lin360\itap0 \rtlch\fcs1 \af44\afs20\alang1025 \ltrch\fcs0 \f44\fs20\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \sbasedon0 \snext31 List;}{\*\cs32 \additive \rtlch\fcs1 \af0 \ltrch\fcs0 \sbasedon10 page number;}{\s33\ql \fi-216\li2016\ri0\sb40\widctlpar\wrapdefault{\*\pn \pnlvlblt\ilvl10\ls2047\pnrnot0 \pnf5\pnstart1\pnindent216\pnhang {\pntxtb ?}}\nooverflow\faroman\ls2047\ilvl10\rin0\lin2016\itap0 \rtlch\fcs1 \af44\afs20\alang1025 \ltrch\fcs0 \f44\fs20\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \sbasedon0 \snext33 bullet;}{ \s34\ql \li0\ri0\sb720\keepn\widctlpar\brdrt\brdrs\brdrw30\brsp120 \wrapdefault\nooverflow\faroman\rin0\lin0\itap0 \rtlch\fcs1 \ab\af1\afs36\alang1025 \ltrch\fcs0 \b\f1\fs36\cf9\lang1024\langfe1024\cgrid\noproof\langnp1033\langfenp1033 \sbasedon1 \snext34 Style1;}{\s35\ql \fi-216\li2016\ri0\sb120\widctlpar\wrapdefault{\*\pn \pnlvlblt\ilvl10\ls2047\pnrnot0\pnf5\pnstart1\pnindent216\pnhang {\pntxtb ?}}\nooverflow\faroman\ls2047\ilvl10\rin0\lin2016\itap0 \rtlch\fcs1 \af44\afs20\alang1025 \ltrch\fcs0 \f44\fs20\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \sbasedon33 \snext33 bullet first;}{\s36\ql \li1440\ri0\sb180\widctlpar\tx5220\wrapdefault\nooverflow\faroman\rin0\lin1440\itap0 \rtlch\fcs1 \ab\af1\afs20\alang1025 \ltrch\fcs0 \b\f1\fs20\cf13\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \sbasedon0 \snext38 chapter contents;}{\s37\ql \li1440\ri0\sb40\widctlpar\tx5400\wrapdefault\nooverflow\faroman\rin0\lin1440\itap0 \rtlch\fcs1 \af44\afs20\alang1025 \ltrch\fcs0 \f44\fs20\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \sbasedon0 \snext37 chapter contents list;}{\s38\ql \li1440\ri0\sb80\widctlpar\tx5400\wrapdefault\nooverflow\faroman\rin0\lin1440\itap0 \rtlch\fcs1 \af44\afs20\alang1025 \ltrch\fcs0 \f44\fs20\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \sbasedon0 \snext37 chapter contents list first;}{\s39\ql \li0\ri0\widctlpar\wrapdefault\nooverflow\faroman\rin0\lin0\itap0 \rtlch\fcs1 \ab\af1\afs200\alang1025 \ltrch\fcs0 \b\f1\fs200\lang1024\langfe1024\cgrid\noproof\langnp1033\langfenp1033 \snext0 chapter num;}{\s40\qr \li0\ri0\sa720\widctlpar\brdrt\brdrs\brdrw60\brsp20 \wrapdefault\nooverflow\faroman\rin0\lin0\itap0 \rtlch\fcs1 \ab\af1\afs54\alang1025 \ltrch\fcs0 \b\f1\fs54\cf9\lang1024\langfe1024\cgrid\noproof\langnp1033\langfenp1033 \snext36 chapter title;}{\s41\ql \li1800\ri0\sb120\widctlpar\wrapdefault\nooverflow\faroman\rin0\lin1800\itap0 \rtlch\fcs1 \af44\afs20\alang1025 \ltrch\fcs0 \f44\fs20\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \sbasedon31 \snext31 list first;}{\s42\ql \fi-216\li2376\ri0\sb40\widctlpar\wrapdefault{\*\pn \pnlvlblt\ilvl10\ls2047\pnrnot0\pnf47\pnstart1\pnindent216\pnhang {\pntxtb ?}} \nooverflow\faroman\ls2047\ilvl10\rin0\lin2376\itap0 \rtlch\fcs1 \af44\afs20\alang1025 \ltrch\fcs0 \f44\fs20\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \sbasedon0 \snext42 bullet indent;}{ \s43\ql \li1440\ri0\sb120\widctlpar\wrapdefault\nooverflow\faroman\rin0\lin1440\itap0 \rtlch\fcs1 \af44\afs20\alang1025 \ltrch\fcs0 \f44\fs20\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \sbasedon0 \snext0 normal after heading 3;}{ \s44\ql \fi-216\li2376\ri0\sb80\widctlpar\wrapdefault{\*\pn \pnlvlblt\ilvl10\ls2047\pnrnot0\pnf47\pnstart1\pnindent216\pnhang {\pntxtb ?}}\nooverflow\faroman\ls2047\ilvl10\rin0\lin2376\itap0 \rtlch\fcs1 \af44\afs20\alang1025 \ltrch\fcs0 \f44\fs20\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \sbasedon33 \snext42 bullet indent first;}{\s45\qr \li720\ri0\sa360\sl-1060\slmult0\widctlpar\wrapdefault\nooverflow\faroman\rin0\lin720\itap0 \rtlch\fcs1 \ab\ai\af1\afs48\alang1025 \ltrch\fcs0 \b\i\f1\fs48\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \sbasedon0 \snext0 contents title;}{\s46\ql \li2160\ri0\sb40\widctlpar\wrapdefault\nooverflow\faroman\rin0\lin2160\itap0 \rtlch\fcs1 \af44\afs20\alang1025 \ltrch\fcs0 \f44\fs20\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \sbasedon31 \snext46 def;}{\s47\ql \li2160\ri0\sb80\widctlpar\wrapdefault\nooverflow\faroman\rin0\lin2160\itap0 \rtlch\fcs1 \af44\afs20\alang1025 \ltrch\fcs0 \f44\fs20\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \sbasedon46 \snext47 def 2;}{\s48\ql \li1080\ri0\sb120\widctlpar\wrapdefault\nooverflow\faroman\rin0\lin1080\itap0 \rtlch\fcs1 \af44\afs20\alang1025 \ltrch\fcs0 \f44\fs20\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \sbasedon41 \snext46 def first;}{\s49\ql \li2160\ri0\sb40\widctlpar\wrapdefault\nooverflow\faroman\rin0\lin2160\itap0 \rtlch\fcs1 \af44\afs20\alang1025 \ltrch\fcs0 \f44\fs20\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \sbasedon46 \snext0 def last;}{\s50\ql \li2160\ri0\sb80\widctlpar\wrapdefault\nooverflow\faroman\rin0\lin2160\itap0 \rtlch\fcs1 \af44\afs20\alang1025 \ltrch\fcs0 \f44\fs20\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \sbasedon49 \snext0 def last 2;}{\s51\ql \li1800\ri0\sb120\keepn\widctlpar\wrapdefault\nooverflow\faroman\rin0\lin1800\itap0 \rtlch\fcs1 \ab\af44\afs20\alang1025 \ltrch\fcs0 \b\f44\fs20\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \sbasedon41 \snext46 def term;}{\s52\ql \li1800\ri0\sb120\keepn\widctlpar\wrapdefault\nooverflow\faroman\rin0\lin1800\itap0 \rtlch\fcs1 \ab\af44\afs20\alang1025 \ltrch\fcs0 \b\f44\fs20\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \sbasedon41 \snext52 def term first;}{\s53\qc \li1440\ri0\sb240\keepn\widctlpar\wrapdefault\nooverflow\faroman\rin0\lin1440\itap0 \rtlch\fcs1 \af44\afs20\alang1025 \ltrch\fcs0 \f44\fs20\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \sbasedon0 \snext54 figure;}{\s54\qc \li1440\ri0\sb180\sa240\widctlpar\wrapdefault\nooverflow\faroman\rin0\lin1440\itap0 \rtlch\fcs1 \ab\af1\afs20\alang1025 \ltrch\fcs0 \b\f1\fs20\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \sbasedon0 \snext0 figure title;}{\s55\qc \li1440\ri0\sb240\keepn\widctlpar\wrapdefault\nooverflow\faroman\rin0\lin1440\itap0 \rtlch\fcs1 \af44\afs20\alang1025 \ltrch\fcs0 \f44\fs20\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \sbasedon53 \snext0 figure after step;}{\s56\qc \li1440\ri0\sb180\sa240\widctlpar\wrapdefault\nooverflow\faroman\rin0\lin1440\itap0 \rtlch\fcs1 \ab\af1\afs20\alang1025 \ltrch\fcs0 \b\f1\fs20\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \sbasedon54 \snext56 figure title after step;}{\s57\qc \li1440\ri0\sb180\sa360\widctlpar\wrapdefault\nooverflow\faroman\rin0\lin1440\itap0 \rtlch\fcs1 \ab\af1\afs20\alang1025 \ltrch\fcs0 \b\f1\fs20\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \sbasedon54 \snext0 figure title continued;}{\*\cs58 \additive \rtlch\fcs1 \af0 \ltrch\fcs0 \sbasedon10 line number;}{ \s59\ql \li2160\ri0\sb40\widctlpar\wrapdefault\nooverflow\faroman\rin0\lin2160\itap0 \rtlch\fcs1 \af44\afs20\alang1025 \ltrch\fcs0 \f44\fs20\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \sbasedon31 \snext59 list indent;}{ \s60\ql \li2160\ri0\sb80\widctlpar\wrapdefault\nooverflow\faroman\rin0\lin2160\itap0 \rtlch\fcs1 \af44\afs20\alang1025 \ltrch\fcs0 \f44\fs20\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \sbasedon31 \snext59 list indent first;}{ \s61\ql \fi-360\li2160\ri0\sb120\widctlpar\wrapdefault{\*\pn \pnlvlbody\ilvl11\ls2047\pnrnot0\pndec\pnstart1\pnindent360\pnhang {\pntxta .}}\nooverflow\faroman\ls2047\ilvl11\rin0\lin2160\itap0 \rtlch\fcs1 \af44\afs20\alang1025 \ltrch\fcs0 \f44\fs20\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \sbasedon0 \snext61 List Number;}{\s62\ql \li2160\ri0\sb80\widctlpar\wrapdefault\nooverflow\faroman\rin0\lin2160\itap0 \rtlch\fcs1 \af44\afs20\alang1025 \ltrch\fcs0 \f44\fs20\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \sbasedon60 \snext62 list number no number;}{\s63\ql \li720\ri0\sb180\widctlpar\wrapdefault\nooverflow\faroman\rin0\lin720\itap0 \rtlch\fcs1 \af44\afs20\alang1025 \ltrch\fcs0 \f44\fs20\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \sbasedon0 \snext63 normal before table;}{\s64\ql \fi-806\li2246\ri0\sb240\sa120\widctlpar\brdrt\brdrs\brdrw15\brsp100 \brdrb\brdrs\brdrw15\brsp100 \tx2250\wrapdefault\nooverflow\faroman\rin0\lin2246\itap0 \rtlch\fcs1 \af44\afs20\alang1025 \ltrch\fcs0 \f44\fs20\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \sbasedon0 \snext0 note;}{ \s65\qr \li0\ri0\sb180\widctlpar\wrapdefault\nooverflow\faroman\rin0\lin0\itap0 \rtlch\fcs1 \ai\af1\afs20\alang1025 \ltrch\fcs0 \i\f1\fs20\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \sbasedon0 \snext65 part number;}{ \s66\ql \li1800\ri0\sb120\widctlpar\tx4770\wrapdefault\nooverflow\faroman\rin0\lin1800\itap0 \rtlch\fcs1 \af2\afs18\alang1025 \ltrch\fcs0 \f2\fs18\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \sbasedon41 \snext30 prog first;}{ \s67\ql \li1800\ri0\sb40\widctlpar\wrapdefault\nooverflow\faroman\rin0\lin1800\itap0 \rtlch\fcs1 \af2\afs18\alang1025 \ltrch\fcs0 \f2\fs18\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \sbasedon31 \snext67 prog last;}{ \s68\ql \li1800\ri0\sb120\widctlpar\tx4770\wrapdefault\nooverflow\faroman\rin0\lin1800\itap0 \rtlch\fcs1 \af2\afs18\alang1025 \ltrch\fcs0 \f2\fs18\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \sbasedon66 \snext68 prog single;}{ \s69\ql \li878\ri144\sl-180\slmult0\widctlpar\brdrt\brdrs\brdrw15\brsp100 \brdrl\brdrs\brdrw15\brsp100 \brdrb\brdrs\brdrw15\brsp100 \brdrr\brdrs\brdrw15\brsp100 \tx1152\tx1440\tx1728\tx2016\tx2304\tx2592\tx2880\wrapdefault\nooverflow\faroman\rin144\lin878\itap0 \rtlch\fcs1 \af2\afs15\alang1025 \ltrch\fcs0 \f2\fs15\lang1024\langfe1024\cgrid\noproof\langnp1033\langfenp1033 \snext69 program text;}{ \s70\ql \fi-360\li2520\ri0\sb80\widctlpar\wrapdefault{\*\pn \pnlvlbody\ilvl11\ls2047\pnrnot0\pnlcltr\pnb0\pni0\pnf4\pnfs20\pnstart1\pnindent360\pnhang {\pntxta . }}\nooverflow\faroman\ls2047\ilvl11\rin0\lin2520\itap0 \rtlch\fcs1 \af44\afs20\alang1025 \ltrch\fcs0 \f44\fs20\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \sbasedon0 \snext70 substep;}{\s71\ql \li72\ri72\sb80\sa80\keepn\widctlpar\wrapdefault\nooverflow\faroman\rin72\lin72\itap0 \rtlch\fcs1 \ab\af44\afs20\alang1025 \ltrch\fcs0 \b\f44\fs20\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \sbasedon0 \snext0 table head;}{\s72\ql \li72\ri72\sb80\sa80\widctlpar\wrapdefault\nooverflow\faroman\rin72\lin72\itap0 \rtlch\fcs1 \af44\afs18\alang1025 \ltrch\fcs0 \f44\fs18\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \snext72 table text;}{\s73\qc \li1440\ri0\sb300\sa120\keepn\widctlpar\wrapdefault\nooverflow\faroman\rin0\lin1440\itap0 \rtlch\fcs1 \ab\af1\afs20\alang1025 \ltrch\fcs0 \b\f1\fs20\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \sbasedon0 \snext71 table title;}{\s74\qc \li1440\ri0\sb300\sa120\keepn\widctlpar\wrapdefault\nooverflow\faroman\rin0\lin1440\itap0 \rtlch\fcs1 \ab\af1\afs20\alang1025 \ltrch\fcs0 \b\f1\fs20\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \sbasedon73 \snext71 table title continued;}{\s75\ql \li1800\ri0\sb120\widctlpar\wrapdefault\nooverflow\faroman\rin0\lin1800\itap0 \rtlch\fcs1 \af1\afs20\alang1025 \ltrch\fcs0 \f1\fs20\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \sbasedon0 \snext0 triplet single;}{\s76\ql \li720\ri0\sb360\keepn\widctlpar\wrapdefault\nooverflow\faroman\rin0\lin720\itap0 \rtlch\fcs1 \ab\af1\afs20\alang1025 \ltrch\fcs0 \b\f1\fs20\cf13\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \sbasedon2 \snext0 triplet heading 2;}{\s77\ql \li0\ri0\sb180\keepn\pagebb\widctlpar\brdrt\brdrs\brdrw30\brsp120 \tqr\tx9893\wrapdefault\nooverflow\faroman\rin0\lin0\itap0 \rtlch\fcs1 \ab\af1\afs24\alang1025 \ltrch\fcs0 \b\f1\fs24\cf9\lang1024\langfe1024\cgrid\noproof\langnp1033\langfenp1033 \sbasedon1 \snext77 triplet heading;}{\s78\ql \li1080\ri0\sb120\widctlpar\wrapdefault\nooverflow\faroman\rin0\lin1080\itap0 \rtlch\fcs1 \af44\afs20\alang1025 \ltrch\fcs0 \f44\fs20\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \sbasedon0 \snext79 glossary def;}{\s79\ql \li720\ri0\sb180\keepn\widctlpar\wrapdefault\nooverflow\faroman\rin0\lin720\itap0 \rtlch\fcs1 \ab\af44\afs20\alang1025 \ltrch\fcs0 \b\f44\fs20\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \sbasedon80 \snext78 glossary word;}{\s80\ql \li720\ri0\sb180\keepn\widctlpar\wrapdefault\nooverflow\faroman\rin0\lin720\itap0 \rtlch\fcs1 \ab\af44\afs20\alang1025 \ltrch\fcs0 \b\f44\fs20\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \sbasedon0 \snext78 glossary word first;}{\s81\ql \li1080\ri0\sb120\widctlpar\wrapdefault\nooverflow\faroman\rin0\lin1080\itap0 \rtlch\fcs1 \af44\afs20\alang1025 \ltrch\fcs0 \f44\fs20\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \sbasedon78 \snext0 glossary def last;}{\s82\ql \fi-216\li2736\ri0\sb80\widctlpar\wrapdefault{\*\pn \pnlvlblt\ilvl10\ls2047\pnrnot0 \pnf5\pnstart1\pnindent216\pnhang {\pntxtb ?}}\nooverflow\faroman\ls2047\ilvl10\rin0\lin2736\itap0 \rtlch\fcs1 \af44\afs20\alang1025 \ltrch\fcs0 \f44\fs20\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \sbasedon0 \snext82 ref bullet 1;}{ \s83\ql \fi-216\li2736\ri0\sb40\widctlpar\wrapdefault{\*\pn \pnlvlblt\ilvl10\ls2047\pnrnot0\pnf5\pnstart1\pnindent216\pnhang {\pntxtb ?}}\nooverflow\faroman\ls2047\ilvl10\rin0\lin2736\itap0 \rtlch\fcs1 \af44\afs20\alang1025 \ltrch\fcs0 \f44\fs20\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \sbasedon82 \snext83 ref bullet 2;}{\s84\ql \fi-1440\li2160\ri0\sb180\widctlpar\tx2160\wrapdefault\nooverflow\faroman\rin0\lin2160\itap0 \rtlch\fcs1 \af44\afs20\alang1025 \ltrch\fcs0 \f44\fs20\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \sbasedon0 \snext84 ref para 1;}{\s85\ql \li2160\ri0\sb80\widctlpar\wrapdefault\nooverflow\faroman\rin0\lin2160\itap0 \rtlch\fcs1 \af44\afs20\alang1025 \ltrch\fcs0 \f44\fs20\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \sbasedon84 \snext84 ref para 2;}{\s86\ql \li2520\ri0\sb80\widctlpar\wrapdefault\nooverflow\faroman\rin0\lin2520\itap0 \rtlch\fcs1 \af2\afs18\alang1025 \ltrch\fcs0 \f2\fs18\lang1024\langfe1024\cgrid\noproof\langnp1033\langfenp1033 \snext86 ref prog 1;}{\s87\ql \li2520\ri0\sb40\widctlpar\wrapdefault\nooverflow\faroman\rin0\lin2520\itap0 \rtlch\fcs1 \af2\afs18\alang1025 \ltrch\fcs0 \f2\fs18\lang1024\langfe1024\cgrid\noproof\langnp1033\langfenp1033 \sbasedon86 \snext87 ref prog 2;}{\s88\ql \li2160\ri0\sb120\widctlpar\tx4770\wrapdefault\nooverflow\faroman\rin0\lin2160\itap0 \rtlch\fcs1 \af2\afs18\alang1025 \ltrch\fcs0 \f2\fs18\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \sbasedon66 \snext88 prog indent first;}{\s89\ql \li2160\ri0\sb40\widctlpar\wrapdefault\nooverflow\faroman\rin0\lin2160\itap0 \rtlch\fcs1 \af2\afs18\alang1025 \ltrch\fcs0 \f2\fs18\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \sbasedon67 \snext89 prog indent last;}{\s90\ql \li0\ri0\sb180\keepn\pagebb\widctlpar\brdrt\brdrs\brdrw30\brsp120 \tqr\tx9893\wrapdefault\nooverflow\faroman\rin0\lin0\itap0 \rtlch\fcs1 \ab\af1\afs24\alang1025 \ltrch\fcs0 \b\f1\fs24\cf9\lang1024\langfe1024\cgrid\noproof\langnp1033\langfenp1033 \sbasedon77 \snext0 ref heading;}{\s91\ql \li720\ri0\sb360\keepn\widctlpar\wrapdefault\nooverflow\faroman\rin0\lin720\itap0 \rtlch\fcs1 \ab\af1\afs20\alang1025 \ltrch\fcs0 \b\f1\fs20\cf13\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \sbasedon76 \snext0 ref heading 2;}{\s92\ql \li1440\ri0\sb120\widctlpar\wrapdefault\nooverflow\faroman\rin0\lin1440\itap0 \rtlch\fcs1 \af44\afs20\alang1025 \ltrch\fcs0 \f44\fs20\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \sbasedon41 \snext93 ref list first;}{\s93\ql \li1440\ri0\sb40\widctlpar\wrapdefault\nooverflow\faroman\rin0\lin1440\itap0 \rtlch\fcs1 \af44\afs20\alang1025 \ltrch\fcs0 \f44\fs20\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \sbasedon31 \snext93 ref list;}{\s94\ql \fi-2160\li3240\ri0\sb120\widctlpar\tx3240\wrapdefault\nooverflow\faroman\rin0\lin3240\itap0 \rtlch\fcs1 \af44\afs20\alang1025 \ltrch\fcs0 \f44\fs20\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \sbasedon43 \snext94 ref subhead first;}{\s95\ql \fi-2160\li3240\ri0\sb40\widctlpar\tx3240\wrapdefault\nooverflow\faroman\rin0\lin3240\itap0 \rtlch\fcs1 \af44\afs20\alang1025 \ltrch\fcs0 \f44\fs20\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \sbasedon0 \snext94 ref subhead last;}{\s96\ql \li1440\ri0\sb180\sa120\widctlpar\wrapdefault\nooverflow\faroman\rin0\lin1440\itap0 \rtlch\fcs1 \af44\afs20\alang1025 \ltrch\fcs0 \f44\fs20\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \sbasedon0 \snext96 \slink97 Body Text;}{\*\cs97 \additive \rtlch\fcs1 \af44\afs20 \ltrch\fcs0 \f44\fs20 \sbasedon10 \slink96 \slocked \ssemihidden Body Text Char;}{ \s98\ql \li1080\ri0\sb120\keepn\widctlpar\tqr\tldot\tx9893\wrapdefault\nooverflow\faroman\rin0\lin1080\itap0 \rtlch\fcs1 \ab\af1\afs20\alang1025 \ltrch\fcs0 \b\f1\fs20\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \sbasedon0 \snext0 \sautoupd \spriority39 toc 1;}{\s99\ql \li1440\ri1440\sb180\sa120\widctlpar\wrapdefault\nooverflow\faroman\rin1440\lin1440\itap0 \rtlch\fcs1 \af44\afs20\alang1025 \ltrch\fcs0 \f44\fs20\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \sbasedon0 \snext99 Block Text;}{\s100\ql \li360\ri0\sb180\sa120\widctlpar\wrapdefault\nooverflow\faroman\rin0\lin360\itap0 \rtlch\fcs1 \af44\afs20\alang1025 \ltrch\fcs0 \f44\fs20\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \sbasedon0 \snext100 \slink101 Body Text 2;}{\*\cs101 \additive \rtlch\fcs1 \af44\afs20 \ltrch\fcs0 \f44\fs20 \sbasedon10 \slink100 \slocked \ssemihidden Body Text 2 Char;}{ \s102\ql \li1440\ri0\sb180\sa120\widctlpar\wrapdefault\nooverflow\faroman\rin0\lin1440\itap0 \rtlch\fcs1 \af44\afs16\alang1025 \ltrch\fcs0 \f44\fs16\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \sbasedon0 \snext102 \slink103 Body Text 3;}{\*\cs103 \additive \rtlch\fcs1 \af44\afs16 \ltrch\fcs0 \f44\fs16 \sbasedon10 \slink102 \slocked \ssemihidden Body Text 3 Char;}{\s104\ql \fi210\li1440\ri0\sb180\sa120\widctlpar\wrapdefault\nooverflow\faroman\rin0\lin1440\itap0 \rtlch\fcs1 \af44\afs20\alang1025 \ltrch\fcs0 \f44\fs20\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \sbasedon96 \snext104 \slink105 Body Text First Indent;}{\*\cs105 \additive \rtlch\fcs1 \af44\afs20 \ltrch\fcs0 \f44\fs20 \sbasedon97 \slink104 \slocked \ssemihidden Body Text First Indent Char;}{\s106\ql \li283\ri0\sb180\sa120\widctlpar\wrapdefault\nooverflow\faroman\rin0\lin283\itap0 \rtlch\fcs1 \af44\afs20\alang1025 \ltrch\fcs0 \f44\fs20\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \sbasedon0 \snext106 \slink107 Body Text Indent;}{\*\cs107 \additive \rtlch\fcs1 \af44\afs20 \ltrch\fcs0 \f44\fs20 \sbasedon10 \slink106 \slocked \ssemihidden Body Text Indent Char;}{ \s108\ql \fi210\li360\ri0\sb180\sa120\widctlpar\wrapdefault\nooverflow\faroman\rin0\lin360\itap0 \rtlch\fcs1 \af44\afs20\alang1025 \ltrch\fcs0 \f44\fs20\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \sbasedon100 \snext108 \slink109 Body Text First Indent 2;}{\*\cs109 \additive \rtlch\fcs1 \af44\afs20 \ltrch\fcs0 \f44\fs20 \sbasedon107 \slink108 \slocked \ssemihidden Body Text First Indent 2 Char;}{\s110\ql \li360\ri0\sb180\sa120\sl480\slmult1 \widctlpar\wrapdefault\nooverflow\faroman\rin0\lin360\itap0 \rtlch\fcs1 \af44\afs20\alang1025 \ltrch\fcs0 \f44\fs20\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \sbasedon0 \snext110 \slink111 Body Text Indent 2;}{\*\cs111 \additive \rtlch\fcs1 \af44\afs20 \ltrch\fcs0 \f44\fs20 \sbasedon10 \slink110 \slocked \ssemihidden Body Text Indent 2 Char;}{\s112\ql \li360\ri0\sb180\sa120\widctlpar\wrapdefault\nooverflow\faroman\rin0\lin360\itap0 \rtlch\fcs1 \af44\afs16\alang1025 \ltrch\fcs0 \f44\fs16\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \sbasedon0 \snext112 \slink113 Body Text Indent 3;}{\*\cs113 \additive \rtlch\fcs1 \af44\afs16 \ltrch\fcs0 \f44\fs16 \sbasedon10 \slink112 \slocked \ssemihidden Body Text Indent 3 Char;}{ \s114\ql \li1440\ri0\sb120\sa120\widctlpar\wrapdefault\nooverflow\faroman\rin0\lin1440\itap0 \rtlch\fcs1 \ab\af44\afs20\alang1025 \ltrch\fcs0 \b\f44\fs20\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \sbasedon0 \snext0 \sqformat caption;}{ \s115\ql \li4320\ri0\sb180\widctlpar\wrapdefault\nooverflow\faroman\rin0\lin4320\itap0 \rtlch\fcs1 \af44\afs20\alang1025 \ltrch\fcs0 \f44\fs20\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \sbasedon0 \snext115 \slink116 Closing;}{\*\cs116 \additive \rtlch\fcs1 \af44\afs20 \ltrch\fcs0 \f44\fs20 \sbasedon10 \slink115 \slocked \ssemihidden Closing Char;}{\s117\ql \li1440\ri0\sb180\widctlpar\wrapdefault\nooverflow\faroman\rin0\lin1440\itap0 \rtlch\fcs1 \af44\afs20\alang1025 \ltrch\fcs0 \f44\fs20\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \sbasedon0 \snext117 \slink118 \ssemihidden annotation text;}{\*\cs118 \additive \rtlch\fcs1 \af44\afs20 \ltrch\fcs0 \f44\fs20 \sbasedon10 \slink117 \slocked \ssemihidden Comment Text Char;}{ \s119\ql \li1440\ri0\sb180\widctlpar\wrapdefault\nooverflow\faroman\rin0\lin1440\itap0 \rtlch\fcs1 \af44\afs20\alang1025 \ltrch\fcs0 \f44\fs20\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \sbasedon0 \snext0 \slink120 Date;}{\*\cs120 \additive \rtlch\fcs1 \af44\afs20 \ltrch\fcs0 \f44\fs20 \sbasedon10 \slink119 \slocked \ssemihidden Date Char;}{\s121\ql \li1440\ri0\sb180\widctlpar\wrapdefault\nooverflow\faroman\rin0\lin1440\itap0 \cbpat9 \rtlch\fcs1 \af43\afs20\alang1025 \ltrch\fcs0 \f43\fs20\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \sbasedon0 \snext121 \slink122 \ssemihidden Document Map;}{\*\cs122 \additive \rtlch\fcs1 \af43\afs16 \ltrch\fcs0 \f43\fs16 \sbasedon10 \slink121 \slocked \ssemihidden Document Map Char;}{ \s123\ql \li1440\ri0\sb180\widctlpar\wrapdefault\nooverflow\faroman\rin0\lin1440\itap0 \rtlch\fcs1 \af44\afs20\alang1025 \ltrch\fcs0 \f44\fs20\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \sbasedon0 \snext123 \slink124 \ssemihidden endnote text;}{\* \cs124 \additive \rtlch\fcs1 \af44\afs20 \ltrch\fcs0 \f44\fs20 \sbasedon10 \slink123 \slocked \ssemihidden Endnote Text Char;}{ \s125\ql \li2880\ri0\sb180\widctlpar\phpg\posxc\posyb\absh-1980\absw7920\dxfrtext180\dfrmtxtx180\dfrmtxty0\wrapdefault\nooverflow\faroman\rin0\lin2880\itap0 \rtlch\fcs1 \af1\afs24\alang1025 \ltrch\fcs0 \f1\fs24\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \sbasedon0 \snext125 envelope address;}{\s126\ql \li1440\ri0\sb180\widctlpar\wrapdefault\nooverflow\faroman\rin0\lin1440\itap0 \rtlch\fcs1 \af1\afs20\alang1025 \ltrch\fcs0 \f1\fs20\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \sbasedon0 \snext126 envelope return;}{\s127\ql \li1440\ri0\sb180\widctlpar\wrapdefault\nooverflow\faroman\rin0\lin1440\itap0 \rtlch\fcs1 \af44\afs20\alang1025 \ltrch\fcs0 \f44\fs20\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \sbasedon0 \snext127 \slink128 \ssemihidden footnote text;}{\*\cs128 \additive \rtlch\fcs1 \af44\afs20 \ltrch\fcs0 \f44\fs20 \sbasedon10 \slink127 \slocked \ssemihidden Footnote Text Char;}{ \s129\ql \fi-200\li200\ri0\sb180\widctlpar\wrapdefault\nooverflow\faroman\rin0\lin200\itap0 \rtlch\fcs1 \af44\afs20\alang1025 \ltrch\fcs0 \f44\fs20\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \sbasedon0 \snext0 \sautoupd \ssemihidden index 1;}{ \s130\ql \fi-200\li400\ri0\sb180\widctlpar\wrapdefault\nooverflow\faroman\rin0\lin400\itap0 \rtlch\fcs1 \af44\afs20\alang1025 \ltrch\fcs0 \f44\fs20\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \sbasedon0 \snext0 \sautoupd \ssemihidden index 2;}{ \s131\ql \fi-200\li600\ri0\sb180\widctlpar\wrapdefault\nooverflow\faroman\rin0\lin600\itap0 \rtlch\fcs1 \af44\afs20\alang1025 \ltrch\fcs0 \f44\fs20\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \sbasedon0 \snext0 \sautoupd \ssemihidden index 3;}{ \s132\ql \fi-200\li800\ri0\sb180\widctlpar\wrapdefault\nooverflow\faroman\rin0\lin800\itap0 \rtlch\fcs1 \af44\afs20\alang1025 \ltrch\fcs0 \f44\fs20\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \sbasedon0 \snext0 \sautoupd \ssemihidden index 4;}{ \s133\ql \fi-200\li1000\ri0\sb180\widctlpar\wrapdefault\nooverflow\faroman\rin0\lin1000\itap0 \rtlch\fcs1 \af44\afs20\alang1025 \ltrch\fcs0 \f44\fs20\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \sbasedon0 \snext0 \sautoupd \ssemihidden index 5;}{ \s134\ql \fi-200\li1200\ri0\sb180\widctlpar\wrapdefault\nooverflow\faroman\rin0\lin1200\itap0 \rtlch\fcs1 \af44\afs20\alang1025 \ltrch\fcs0 \f44\fs20\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \sbasedon0 \snext0 \sautoupd \ssemihidden index 6;}{ \s135\ql \fi-200\li1400\ri0\sb180\widctlpar\wrapdefault\nooverflow\faroman\rin0\lin1400\itap0 \rtlch\fcs1 \af44\afs20\alang1025 \ltrch\fcs0 \f44\fs20\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \sbasedon0 \snext0 \sautoupd \ssemihidden index 7;}{ \s136\ql \fi-200\li1600\ri0\sb180\widctlpar\wrapdefault\nooverflow\faroman\rin0\lin1600\itap0 \rtlch\fcs1 \af44\afs20\alang1025 \ltrch\fcs0 \f44\fs20\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \sbasedon0 \snext0 \sautoupd \ssemihidden index 8;}{ \s137\ql \fi-200\li1800\ri0\sb180\widctlpar\wrapdefault\nooverflow\faroman\rin0\lin1800\itap0 \rtlch\fcs1 \af44\afs20\alang1025 \ltrch\fcs0 \f44\fs20\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \sbasedon0 \snext0 \sautoupd \ssemihidden index 9;}{ \s138\ql \li1440\ri0\sb180\widctlpar\wrapdefault\nooverflow\faroman\rin0\lin1440\itap0 \rtlch\fcs1 \ab\af1\afs20\alang1025 \ltrch\fcs0 \b\f1\fs20\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \sbasedon0 \snext129 \ssemihidden index heading;}{ \s139\ql \fi-360\li720\ri0\sb180\widctlpar\wrapdefault\nooverflow\faroman\rin0\lin720\itap0 \rtlch\fcs1 \af44\afs20\alang1025 \ltrch\fcs0 \f44\fs20\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \sbasedon0 \snext139 List 2;}{ \s140\ql \fi-360\li1080\ri0\sb180\widctlpar\wrapdefault\nooverflow\faroman\rin0\lin1080\itap0 \rtlch\fcs1 \af44\afs20\alang1025 \ltrch\fcs0 \f44\fs20\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \sbasedon0 \snext140 List 3;}{ \s141\ql \fi-360\li1440\ri0\sb180\widctlpar\wrapdefault\nooverflow\faroman\rin0\lin1440\itap0 \rtlch\fcs1 \af44\afs20\alang1025 \ltrch\fcs0 \f44\fs20\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \sbasedon0 \snext141 List 4;}{ \s142\ql \fi-360\li1800\ri0\sb180\widctlpar\wrapdefault\nooverflow\faroman\rin0\lin1800\itap0 \rtlch\fcs1 \af44\afs20\alang1025 \ltrch\fcs0 \f44\fs20\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \sbasedon0 \snext142 List 5;}{ \s143\ql \fi-360\li360\ri0\sb180\widctlpar\jclisttab\tx360\wrapdefault{\*\pn \pnlvlbody\ilvl0\ls1\pnrnot0\pndec }\nooverflow\faroman\ls1\rin0\lin360\itap0 \rtlch\fcs1 \af44\afs20\alang1025 \ltrch\fcs0 \f44\fs20\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \sbasedon0 \snext143 \sautoupd List Bullet;}{\s144\ql \fi-360\li720\ri0\sb180\widctlpar\jclisttab\tx720\wrapdefault{\*\pn \pnlvlbody\ilvl0\ls2\pnrnot0\pndec } \nooverflow\faroman\ls2\rin0\lin720\itap0 \rtlch\fcs1 \af44\afs20\alang1025 \ltrch\fcs0 \f44\fs20\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \sbasedon0 \snext144 \sautoupd List Bullet 2;}{\s145\ql \fi-360\li1080\ri0\sb180\widctlpar \jclisttab\tx1080\wrapdefault{\*\pn \pnlvlbody\ilvl0\ls3\pnrnot0\pndec }\nooverflow\faroman\ls3\rin0\lin1080\itap0 \rtlch\fcs1 \af44\afs20\alang1025 \ltrch\fcs0 \f44\fs20\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \sbasedon0 \snext145 \sautoupd List Bullet 3;}{\s146\ql \fi-360\li1440\ri0\sb180\widctlpar\jclisttab\tx1440\wrapdefault{\*\pn \pnlvlbody\ilvl0\ls4\pnrnot0\pndec }\nooverflow\faroman\ls4\rin0\lin1440\itap0 \rtlch\fcs1 \af44\afs20\alang1025 \ltrch\fcs0 \f44\fs20\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \sbasedon0 \snext146 \sautoupd List Bullet 4;}{\s147\ql \fi-360\li1800\ri0\sb180\widctlpar\jclisttab\tx1800\wrapdefault{\*\pn \pnlvlbody\ilvl0\ls5\pnrnot0\pndec } \nooverflow\faroman\ls5\rin0\lin1800\itap0 \rtlch\fcs1 \af44\afs20\alang1025 \ltrch\fcs0 \f44\fs20\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \sbasedon0 \snext147 \sautoupd List Bullet 5;}{ \s148\ql \li360\ri0\sb180\sa120\widctlpar\wrapdefault\nooverflow\faroman\rin0\lin360\itap0 \rtlch\fcs1 \af44\afs20\alang1025 \ltrch\fcs0 \f44\fs20\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \sbasedon0 \snext148 List Continue;}{ \s149\ql \li720\ri0\sb180\sa120\widctlpar\wrapdefault\nooverflow\faroman\rin0\lin720\itap0 \rtlch\fcs1 \af44\afs20\alang1025 \ltrch\fcs0 \f44\fs20\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \sbasedon0 \snext149 List Continue 2;}{ \s150\ql \li1080\ri0\sb180\sa120\widctlpar\wrapdefault\nooverflow\faroman\rin0\lin1080\itap0 \rtlch\fcs1 \af44\afs20\alang1025 \ltrch\fcs0 \f44\fs20\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \sbasedon0 \snext150 List Continue 3;}{ \s151\ql \li1440\ri0\sb180\sa120\widctlpar\wrapdefault\nooverflow\faroman\rin0\lin1440\itap0 \rtlch\fcs1 \af44\afs20\alang1025 \ltrch\fcs0 \f44\fs20\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \sbasedon0 \snext151 List Continue 4;}{ \s152\ql \li1800\ri0\sb180\sa120\widctlpar\wrapdefault\nooverflow\faroman\rin0\lin1800\itap0 \rtlch\fcs1 \af44\afs20\alang1025 \ltrch\fcs0 \f44\fs20\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \sbasedon0 \snext152 List Continue 5;}{ \s153\ql \fi-360\li720\ri0\sb180\widctlpar\jclisttab\tx720\wrapdefault{\*\pn \pnlvlbody\ilvl0\ls6\pnrnot0\pndec }\nooverflow\faroman\ls6\rin0\lin720\itap0 \rtlch\fcs1 \af44\afs20\alang1025 \ltrch\fcs0 \f44\fs20\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \sbasedon0 \snext153 List Number 2;}{\s154\ql \fi-360\li1080\ri0\sb180\widctlpar\jclisttab\tx1080\wrapdefault{\*\pn \pnlvlbody\ilvl0\ls7\pnrnot0\pndec }\nooverflow\faroman\ls7\rin0\lin1080\itap0 \rtlch\fcs1 \af44\afs20\alang1025 \ltrch\fcs0 \f44\fs20\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \sbasedon0 \snext154 List Number 3;}{\s155\ql \fi-360\li1440\ri0\sb180\widctlpar\jclisttab\tx1440\wrapdefault{\*\pn \pnlvlbody\ilvl0\ls8\pnrnot0 \pndec }\nooverflow\faroman\ls8\rin0\lin1440\itap0 \rtlch\fcs1 \af44\afs20\alang1025 \ltrch\fcs0 \f44\fs20\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \sbasedon0 \snext155 List Number 4;}{\s156\ql \fi-360\li1800\ri0\sb180\widctlpar \jclisttab\tx1800\wrapdefault{\*\pn \pnlvlbody\ilvl0\ls9\pnrnot0\pndec }\nooverflow\faroman\ls9\rin0\lin1800\itap0 \rtlch\fcs1 \af44\afs20\alang1025 \ltrch\fcs0 \f44\fs20\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \sbasedon0 \snext156 List Number 5;}{\s157\ql \li1440\ri0\sb180\widctlpar\tx480\tx960\tx1440\tx1920\tx2400\tx2880\tx3360\tx3840\tx4320\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin1440\itap0 \rtlch\fcs1 \af2\afs20\alang1025 \ltrch\fcs0 \f2\fs20\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \snext157 \slink158 \ssemihidden macro;}{\*\cs158 \additive \rtlch\fcs1 \af2\afs20 \ltrch\fcs0 \f2\fs20 \sbasedon10 \slink157 \slocked \ssemihidden Macro Text Char;}{ \s159\ql \fi-1080\li1080\ri0\sb180\widctlpar\brdrt\brdrs\brdrw15\brsp20 \brdrl\brdrs\brdrw15\brsp20 \brdrb\brdrs\brdrw15\brsp20 \brdrr\brdrs\brdrw15\brsp20 \wrapdefault\nooverflow\faroman\rin0\lin1080\itap0 \shading2000 \rtlch\fcs1 \af1\afs24\alang1025 \ltrch\fcs0 \f1\fs24\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \sbasedon0 \snext159 \slink160 Message Header;}{\*\cs160 \additive \rtlch\fcs1 \af0\afs24 \ltrch\fcs0 \f42\fs24\chshdng2000\chcfpat0\chcbpat0 \sbasedon10 \slink159 \slocked \ssemihidden Message Header Char;}{\s161\ql \li1440\ri0\sb180\widctlpar\wrapdefault\nooverflow\faroman\rin0\lin1440\itap0 \rtlch\fcs1 \af44\afs20\alang1025 \ltrch\fcs0 \f44\fs20\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \sbasedon0 \snext0 \slink162 Note Heading;}{\*\cs162 \additive \rtlch\fcs1 \af44\afs20 \ltrch\fcs0 \f44\fs20 \sbasedon10 \slink161 \slocked \ssemihidden Note Heading Char;}{ \s163\ql \li1440\ri0\sb180\widctlpar\wrapdefault\nooverflow\faroman\rin0\lin1440\itap0 \rtlch\fcs1 \af2\afs20\alang1025 \ltrch\fcs0 \f2\fs20\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \sbasedon0 \snext163 \slink164 Plain Text;}{\*\cs164 \additive \rtlch\fcs1 \af2\afs20 \ltrch\fcs0 \f2\fs20 \sbasedon10 \slink163 \slocked \ssemihidden Plain Text Char;}{\s165\ql \li1440\ri0\sb180\widctlpar\wrapdefault\nooverflow\faroman\rin0\lin1440\itap0 \rtlch\fcs1 \af44\afs20\alang1025 \ltrch\fcs0 \f44\fs20\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \sbasedon0 \snext0 \slink166 Salutation;}{\*\cs166 \additive \rtlch\fcs1 \af44\afs20 \ltrch\fcs0 \f44\fs20 \sbasedon10 \slink165 \slocked \ssemihidden Salutation Char;}{ \s167\ql \li4320\ri0\sb180\widctlpar\wrapdefault\nooverflow\faroman\rin0\lin4320\itap0 \rtlch\fcs1 \af44\afs20\alang1025 \ltrch\fcs0 \f44\fs20\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \sbasedon0 \snext167 \slink168 Signature;}{\*\cs168 \additive \rtlch\fcs1 \af44\afs20 \ltrch\fcs0 \f44\fs20 \sbasedon10 \slink167 \slocked \ssemihidden Signature Char;}{\s169\qc \li1440\ri0\sb180\sa60\widctlpar\wrapdefault\nooverflow\faroman\outlinelevel1\rin0\lin1440\itap0 \rtlch\fcs1 \af1\afs24\alang1025 \ltrch\fcs0 \f1\fs24\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \sbasedon0 \snext169 \slink170 \sqformat Subtitle;}{\*\cs170 \additive \rtlch\fcs1 \af0\afs24 \ltrch\fcs0 \f42\fs24 \sbasedon10 \slink169 \slocked Subtitle Char;}{ \s171\ql \fi-200\li200\ri0\sb180\widctlpar\wrapdefault\nooverflow\faroman\rin0\lin200\itap0 \rtlch\fcs1 \af44\afs20\alang1025 \ltrch\fcs0 \f44\fs20\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \sbasedon0 \snext0 \ssemihidden table of authorities;}{ \s172\ql \fi-400\li400\ri0\sb180\widctlpar\wrapdefault\nooverflow\faroman\rin0\lin400\itap0 \rtlch\fcs1 \af44\afs20\alang1025 \ltrch\fcs0 \f44\fs20\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \sbasedon0 \snext0 \ssemihidden table of figures;}{ \s173\qc \li1440\ri0\sb240\sa60\widctlpar\wrapdefault\nooverflow\faroman\outlinelevel0\rin0\lin1440\itap0 \rtlch\fcs1 \ab\af1\afs32\alang1025 \ltrch\fcs0 \b\f1\fs32\lang1033\langfe1033\kerning28\cgrid\langnp1033\langfenp1033 \sbasedon0 \snext173 \slink174 \sqformat Title;}{\*\cs174 \additive \rtlch\fcs1 \ab\af0\afs32 \ltrch\fcs0 \b\f42\fs32\kerning28 \sbasedon10 \slink173 \slocked Title Char;}{ \s175\ql \li1440\ri0\sb120\widctlpar\wrapdefault\nooverflow\faroman\rin0\lin1440\itap0 \rtlch\fcs1 \ab\af1\afs24\alang1025 \ltrch\fcs0 \b\f1\fs24\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \sbasedon0 \snext0 \ssemihidden toa heading;}{ \s176\ql \li1440\ri0\sb180\widctlpar\tqr\tldot\tx9883\wrapdefault\nooverflow\faroman\rin0\lin1440\itap0 \rtlch\fcs1 \af44\afs20\alang1025 \ltrch\fcs0 \f44\fs20\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \sbasedon0 \snext0 \sautoupd \spriority39 toc 2;}{\s177\ql \li400\ri0\sb180\widctlpar\wrapdefault\nooverflow\faroman\rin0\lin400\itap0 \rtlch\fcs1 \af44\afs20\alang1025 \ltrch\fcs0 \f44\fs20\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \sbasedon0 \snext0 \sautoupd \ssemihidden toc 3;}{ \s178\ql \li600\ri0\sb180\widctlpar\wrapdefault\nooverflow\faroman\rin0\lin600\itap0 \rtlch\fcs1 \af44\afs20\alang1025 \ltrch\fcs0 \f44\fs20\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \sbasedon0 \snext0 \sautoupd \ssemihidden toc 4;}{ \s179\ql \li800\ri0\sb180\widctlpar\wrapdefault\nooverflow\faroman\rin0\lin800\itap0 \rtlch\fcs1 \af44\afs20\alang1025 \ltrch\fcs0 \f44\fs20\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \sbasedon0 \snext0 \sautoupd \ssemihidden toc 5;}{ \s180\ql \li1000\ri0\sb180\widctlpar\wrapdefault\nooverflow\faroman\rin0\lin1000\itap0 \rtlch\fcs1 \af44\afs20\alang1025 \ltrch\fcs0 \f44\fs20\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \sbasedon0 \snext0 \sautoupd \ssemihidden toc 6;}{ \s181\ql \li1200\ri0\sb180\widctlpar\wrapdefault\nooverflow\faroman\rin0\lin1200\itap0 \rtlch\fcs1 \af44\afs20\alang1025 \ltrch\fcs0 \f44\fs20\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \sbasedon0 \snext0 \sautoupd \ssemihidden toc 7;}{ \s182\ql \li1400\ri0\sb180\widctlpar\wrapdefault\nooverflow\faroman\rin0\lin1400\itap0 \rtlch\fcs1 \af44\afs20\alang1025 \ltrch\fcs0 \f44\fs20\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \sbasedon0 \snext0 \sautoupd \ssemihidden toc 8;}{ \s183\ql \li1600\ri0\sb180\widctlpar\wrapdefault\nooverflow\faroman\rin0\lin1600\itap0 \rtlch\fcs1 \af44\afs20\alang1025 \ltrch\fcs0 \f44\fs20\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \sbasedon0 \snext0 \sautoupd \ssemihidden toc 9;}{ \s184\ql \li1440\ri0\sb180\widctlpar\wrapdefault\nooverflow\faroman\rin0\lin1440\itap0 \rtlch\fcs1 \af43\afs16\alang1025 \ltrch\fcs0 \f43\fs16\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \sbasedon0 \snext184 \slink185 \ssemihidden Balloon Text;}{\* \cs185 \additive \rtlch\fcs1 \af43\afs16 \ltrch\fcs0 \f43\fs16 \sbasedon10 \slink184 \slocked \ssemihidden Balloon Text Char;}{\*\ts186\tsrowd\trbrdrt\brdrs\brdrw10 \trbrdrl\brdrs\brdrw10 \trbrdrb\brdrs\brdrw10 \trbrdrr\brdrs\brdrw10 \trbrdrh \brdrs\brdrw10 \trbrdrv\brdrs\brdrw10 \trftsWidthB3\trpaddl108\trpaddr108\trpaddfl3\trpaddft3\trpaddfb3\trpaddfr3\trcbpat1\trcfpat1\tblind0\tblindtype3\tsvertalt\tsbrdrt\tsbrdrl\tsbrdrb\tsbrdrr\tsbrdrdgl\tsbrdrdgr\tsbrdrh\tsbrdrv \ql \li1440\ri0\sb180\widctlpar\wrapdefault\nooverflow\faroman\rin0\lin1440\itap0 \rtlch\fcs1 \af0\afs20\alang1025 \ltrch\fcs0 \fs20\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \sbasedon11 \snext186 Table Grid;}{\*\cs187 \additive \rtlch\fcs1 \af0 \ltrch\fcs0 \ul\cf2 \sbasedon10 Hyperlink;}{\*\cs188 \additive \rtlch\fcs1 \af0\afs19 \ltrch\fcs0 \fs19 \sbasedon10 postbody1;}{\s189\ql \li0\ri0\keepn\pagebb\widctlpar\brdrt\brdrs\brdrw30\brsp120 \wrapdefault\nooverflow\faroman\outlinelevel0\rin0\lin0\itap0 \rtlch\fcs1 \ab\af1\afs24\alang1025 \ltrch\fcs0 \b\f1\fs24\cf9\lang1024\langfe1024\cgrid\noproof\langnp1033\langfenp1033 \sbasedon1 \snext189 \slink190 TWAIN Header;}{\*\cs190 \additive \rtlch\fcs1 \ab\af1\afs24 \ltrch\fcs0 \b\f1\fs24\cf9\lang1024\langfe1024\kerning32\noproof \sbasedon15 \slink189 \slocked TWAIN Header Char;}{\s191\ql \li720\ri0\sb360\sl240\slmult0\widctlpar\tx720\wrapdefault\hyphpar0\faauto\rin0\lin720\itap0 \rtlch\fcs1 \af44\afs20\alang1025 \ltrch\fcs0 \f44\fs20\cf1\lang1033\langfe1033\charscalex0\cgrid\langnp1033\langfenp1033 \snext191 body;}{\s192\ql \li1440\ri0\sb120\sl240\slmult0\widctlpar \tx720\tx1080\tx1440\tx1800\tx2160\tx2520\tx2880\tx3240\tx3600\tx3960\tx4320\tx4680\tx5040\tx5400\tx5760\tx6120\tx6480\tx6840\tx7200\tx7560\tx7920\tx8280\tx8640\tx9000\wrapdefault\hyphpar0\faauto\rin0\lin1440\itap0 \rtlch\fcs1 \af48\afs20\alang1025 \ltrch\fcs0 \f48\fs20\cf1\lang1033\langfe1033\charscalex0\cgrid\langnp1033\langfenp1033 \snext0 Code;}{\s193\ql \fi-3240\li4680\ri0\sb120\sl240\slmult0\widctlpar\tx4680\tx7400\wrapdefault\hyphpar0\faauto\rin0\lin4680\itap0 \rtlch\fcs1 \af44\afs20\alang1025 \ltrch\fcs0 \f44\fs20\cf1\lang1033\langfe1033\charscalex0\cgrid\langnp1033\langfenp1033 \snext31 twocol;}{\*\cs194 \additive \f2 Code2;}{\s195\ql \li0\ri0\widctlpar\wrapdefault\faauto\adjustright\rin0\lin0\itap0 \rtlch\fcs1 \af0\afs24\alang1025 \ltrch\fcs0 \fs24\cf1\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \sbasedon0 \snext195 Default;}{\*\cs196 \additive \rtlch\fcs1 \af0 \ltrch\fcs0 \sbasedon10 \spriority0 postbody;}{\*\cs197 \additive \rtlch\fcs1 \af0 \ltrch\fcs0 \ul\cf19 \sbasedon10 \slocked \ssemihidden \sunhideused FollowedHyperlink;}{\s198\ql \li60\ri60\sb80\sa80\sl240\slmult0\widctlpar\tx720\tx2520\wrapdefault\hyphpar0\faauto\rin60\lin60\itap0 \rtlch\fcs1 \af2\afs20\alang1025 \ltrch\fcs0 \fs20\cf1\lang1033\langfe2052\loch\f2\hich\af2\dbch\af31505\charscalex0\cgrid\langnp1033\langfenp2052 \snext198 table_code;}{\s199\ql \li720\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin720\itap0 \rtlch\fcs1 \af37\afs22\alang1025 \ltrch\fcs0 \f37\fs22\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \sbasedon0 \snext199 \sqformat \spriority34 List Paragraph;}{\*\cs200 \additive \rtlch\fcs1 \af0 \ltrch\fcs0 \cf20\chshdng0\chcfpat0\chcbpat21 \sbasedon10 \ssemihidden \sunhideused Unresolved Mention;}}{\*\listtable{\list\listtemplateid-1403649448\listsimple{\listlevel\levelnfc0\levelnfcn0\leveljc0\leveljcn0\levelfollow0\levelstartat1\levelspace0\levelindent0{\leveltext\'02\'00.;}{\levelnumbers\'01;}\rtlch\fcs1 \af0 \ltrch\fcs0 \s156\fi-360\li1800\jclisttab\tx1800\lin1800 }{\listname ;}\listid-132}{\list\listtemplateid-537102814\listsimple{\listlevel\levelnfc0\levelnfcn0\leveljc0\leveljcn0\levelfollow0\levelstartat1\levelspace0\levelindent0{\leveltext\'02\'00.;}{\levelnumbers \'01;}\rtlch\fcs1 \af0 \ltrch\fcs0 \fi-360\li1440\jclisttab\tx1440\lin1440 }{\listname ;}\listid-131}{\list\listtemplateid-241933882\listsimple{\listlevel\levelnfc0\levelnfcn0\leveljc0\leveljcn0\levelfollow0\levelstartat1\levelspace0\levelindent0 {\leveltext\'02\'00.;}{\levelnumbers\'01;}\rtlch\fcs1 \af0 \ltrch\fcs0 \fi-360\li1080\jclisttab\tx1080\lin1080 }{\listname ;}\listid-130}{\list\listtemplateid894471834\listsimple{\listlevel\levelnfc0\levelnfcn0\leveljc0\leveljcn0\levelfollow0 \levelstartat1\levelspace0\levelindent0{\leveltext\'02\'00.;}{\levelnumbers\'01;}\rtlch\fcs1 \af0 \ltrch\fcs0 \fi-360\li720\jclisttab\tx720\lin720 }{\listname ;}\listid-129}{\list\listtemplateid-1633241602\listsimple{\listlevel\levelnfc23\levelnfcn23 \leveljc0\leveljcn0\levelfollow0\levelstartat1\levelspace0\levelindent0{\leveltext\'01\u-3913 ?;}{\levelnumbers;}\f3\fbias0 \fi-360\li1800\jclisttab\tx1800\lin1800 }{\listname ;}\listid-128}{\list\listtemplateid-203631750\listsimple{\listlevel\levelnfc23 \levelnfcn23\leveljc0\leveljcn0\levelfollow0\levelstartat1\levelspace0\levelindent0{\leveltext\'01\u-3913 ?;}{\levelnumbers;}\f3\fbias0 \fi-360\li1440\jclisttab\tx1440\lin1440 }{\listname ;}\listid-127}{\list\listtemplateid360335964\listsimple{\listlevel \levelnfc23\levelnfcn23\leveljc0\leveljcn0\levelfollow0\levelstartat1\levelspace0\levelindent0{\leveltext\'01\u-3913 ?;}{\levelnumbers;}\f3\fbias0 \fi-360\li1080\jclisttab\tx1080\lin1080 }{\listname ;}\listid-126}{\list\listtemplateid627448582\listsimple {\listlevel\levelnfc23\levelnfcn23\leveljc0\leveljcn0\levelfollow0\levelstartat1\levelspace0\levelindent0{\leveltext\'01\u-3913 ?;}{\levelnumbers;}\f3\fbias0 \fi-360\li720\jclisttab\tx720\lin720 }{\listname ;}\listid-125}{\list\listtemplateid507960418 \listsimple{\listlevel\levelnfc0\levelnfcn0\leveljc0\leveljcn0\levelfollow0\levelstartat1\levelspace0\levelindent0{\leveltext\'02\'00.;}{\levelnumbers\'01;}\rtlch\fcs1 \af0 \ltrch\fcs0 \fi-360\li360\jclisttab\tx360\lin360 }{\listname ;}\listid-120} {\list\listtemplateid-1407048446\listsimple{\listlevel\levelnfc23\levelnfcn23\leveljc0\leveljcn0\levelfollow0\levelstartat1\levelspace0\levelindent0{\leveltext\'01\u-3913 ?;}{\levelnumbers;}\f3\fbias0 \fi-360\li360\jclisttab\tx360\lin360 }{\listname ;}\listid-119}{\list\listtemplateid-950138062\listhybrid{\listlevel\levelnfc23\levelnfcn23\leveljc0\leveljcn0\levelfollow0\levelstartat0\levelspace0\levelindent0{\leveltext\leveltemplateid-129700622\'01-;}{\levelnumbers;} \loch\af37\hich\af37\dbch\af0\fbias0 \fi-360\li720\lin720 }{\listlevel\levelnfc23\levelnfcn23\leveljc0\leveljcn0\levelfollow0\levelstartat1\lvltentative\levelspace0\levelindent0{\leveltext\leveltemplateid67698691\'01o;}{\levelnumbers;}\f2\fbias0 \fi-360\li1440\lin1440 }{\listlevel\levelnfc23\levelnfcn23\leveljc0\leveljcn0\levelfollow0\levelstartat1\lvltentative\levelspace0\levelindent0{\leveltext\leveltemplateid67698693\'01\u-3929 ?;}{\levelnumbers;}\f10\fbias0 \fi-360\li2160\lin2160 }{\listlevel \levelnfc23\levelnfcn23\leveljc0\leveljcn0\levelfollow0\levelstartat1\lvltentative\levelspace0\levelindent0{\leveltext\leveltemplateid67698689\'01\u-3913 ?;}{\levelnumbers;}\f3\fbias0 \fi-360\li2880\lin2880 }{\listlevel\levelnfc23\levelnfcn23\leveljc0 \leveljcn0\levelfollow0\levelstartat1\lvltentative\levelspace0\levelindent0{\leveltext\leveltemplateid67698691\'01o;}{\levelnumbers;}\f2\fbias0 \fi-360\li3600\lin3600 }{\listlevel\levelnfc23\levelnfcn23\leveljc0\leveljcn0\levelfollow0\levelstartat1 \lvltentative\levelspace0\levelindent0{\leveltext\leveltemplateid67698693\'01\u-3929 ?;}{\levelnumbers;}\f10\fbias0 \fi-360\li4320\lin4320 }{\listlevel\levelnfc23\levelnfcn23\leveljc0\leveljcn0\levelfollow0\levelstartat1\lvltentative\levelspace0 \levelindent0{\leveltext\leveltemplateid67698689\'01\u-3913 ?;}{\levelnumbers;}\f3\fbias0 \fi-360\li5040\lin5040 }{\listlevel\levelnfc23\levelnfcn23\leveljc0\leveljcn0\levelfollow0\levelstartat1\lvltentative\levelspace0\levelindent0{\leveltext \leveltemplateid67698691\'01o;}{\levelnumbers;}\f2\fbias0 \fi-360\li5760\lin5760 }{\listlevel\levelnfc23\levelnfcn23\leveljc0\leveljcn0\levelfollow0\levelstartat1\lvltentative\levelspace0\levelindent0{\leveltext\leveltemplateid67698693 \'01\u-3929 ?;}{\levelnumbers;}\f10\fbias0 \fi-360\li6480\lin6480 }{\listname ;}\listid162478944}{\list\listtemplateid181715488\listhybrid{\listlevel\levelnfc23\levelnfcn23\leveljc0\leveljcn0\levelfollow0\levelstartat0\levelspace0\levelindent0{\leveltext \leveltemplateid1324631620\'01-;}{\levelnumbers;}\loch\af0\hich\af0\dbch\af0\fbias0 \fi-360\li720\lin720 }{\listlevel\levelnfc23\levelnfcn23\leveljc0\leveljcn0\levelfollow0\levelstartat1\lvltentative\levelspace0\levelindent0{\leveltext \leveltemplateid67698691\'01o;}{\levelnumbers;}\f2\fbias0 \fi-360\li1440\lin1440 }{\listlevel\levelnfc23\levelnfcn23\leveljc0\leveljcn0\levelfollow0\levelstartat1\lvltentative\levelspace0\levelindent0{\leveltext\leveltemplateid67698693 \'01\u-3929 ?;}{\levelnumbers;}\f10\fbias0 \fi-360\li2160\lin2160 }{\listlevel\levelnfc23\levelnfcn23\leveljc0\leveljcn0\levelfollow0\levelstartat1\lvltentative\levelspace0\levelindent0{\leveltext\leveltemplateid67698689\'01\u-3913 ?;}{\levelnumbers;} \f3\fbias0 \fi-360\li2880\lin2880 }{\listlevel\levelnfc23\levelnfcn23\leveljc0\leveljcn0\levelfollow0\levelstartat1\lvltentative\levelspace0\levelindent0{\leveltext\leveltemplateid67698691\'01o;}{\levelnumbers;}\f2\fbias0 \fi-360\li3600\lin3600 } {\listlevel\levelnfc23\levelnfcn23\leveljc0\leveljcn0\levelfollow0\levelstartat1\lvltentative\levelspace0\levelindent0{\leveltext\leveltemplateid67698693\'01\u-3929 ?;}{\levelnumbers;}\f10\fbias0 \fi-360\li4320\lin4320 }{\listlevel\levelnfc23\levelnfcn23 \leveljc0\leveljcn0\levelfollow0\levelstartat1\lvltentative\levelspace0\levelindent0{\leveltext\leveltemplateid67698689\'01\u-3913 ?;}{\levelnumbers;}\f3\fbias0 \fi-360\li5040\lin5040 }{\listlevel\levelnfc23\levelnfcn23\leveljc0\leveljcn0\levelfollow0 \levelstartat1\lvltentative\levelspace0\levelindent0{\leveltext\leveltemplateid67698691\'01o;}{\levelnumbers;}\f2\fbias0 \fi-360\li5760\lin5760 }{\listlevel\levelnfc23\levelnfcn23\leveljc0\leveljcn0\levelfollow0\levelstartat1\lvltentative\levelspace0 \levelindent0{\leveltext\leveltemplateid67698693\'01\u-3929 ?;}{\levelnumbers;}\f10\fbias0 \fi-360\li6480\lin6480 }{\listname ;}\listid984241419}{\list\listtemplateid81190112\listhybrid{\listlevel\levelnfc0\levelnfcn0\leveljc0\leveljcn0\levelfollow0 \levelstartat1\levelspace0\levelindent0{\leveltext\leveltemplateid1970803460\'02\'00);}{\levelnumbers\'01;}\rtlch\fcs1 \af0 \ltrch\fcs0 \fs22\cf22\loch\af37\hich\af37\dbch\af0\fbias0 \fi-360\li720\lin720 }{\listlevel\levelnfc4\levelnfcn4\leveljc0 \leveljcn0\levelfollow0\levelstartat1\levelspace0\levelindent0{\leveltext\leveltemplateid67698713\'02\'01.;}{\levelnumbers\'01;}\rtlch\fcs1 \af0 \ltrch\fcs0 \fi-360\li1440\lin1440 }{\listlevel\levelnfc2\levelnfcn2\leveljc2\leveljcn2\levelfollow0 \levelstartat1\levelspace0\levelindent0{\leveltext\leveltemplateid67698715\'02\'02.;}{\levelnumbers\'01;}\rtlch\fcs1 \af0 \ltrch\fcs0 \fi-180\li2160\lin2160 }{\listlevel\levelnfc0\levelnfcn0\leveljc0\leveljcn0\levelfollow0\levelstartat1\levelspace0 \levelindent0{\leveltext\leveltemplateid67698703\'02\'03.;}{\levelnumbers\'01;}\rtlch\fcs1 \af0 \ltrch\fcs0 \fi-360\li2880\lin2880 }{\listlevel\levelnfc4\levelnfcn4\leveljc0\leveljcn0\levelfollow0\levelstartat1\levelspace0\levelindent0{\leveltext \leveltemplateid67698713\'02\'04.;}{\levelnumbers\'01;}\rtlch\fcs1 \af0 \ltrch\fcs0 \fi-360\li3600\lin3600 }{\listlevel\levelnfc2\levelnfcn2\leveljc2\leveljcn2\levelfollow0\levelstartat1\levelspace0\levelindent0{\leveltext\leveltemplateid67698715 \'02\'05.;}{\levelnumbers\'01;}\rtlch\fcs1 \af0 \ltrch\fcs0 \fi-180\li4320\lin4320 }{\listlevel\levelnfc0\levelnfcn0\leveljc0\leveljcn0\levelfollow0\levelstartat1\levelspace0\levelindent0{\leveltext\leveltemplateid67698703\'02\'06.;}{\levelnumbers\'01;} \rtlch\fcs1 \af0 \ltrch\fcs0 \fi-360\li5040\lin5040 }{\listlevel\levelnfc4\levelnfcn4\leveljc0\leveljcn0\levelfollow0\levelstartat1\levelspace0\levelindent0{\leveltext\leveltemplateid67698713\'02\'07.;}{\levelnumbers\'01;}\rtlch\fcs1 \af0 \ltrch\fcs0 \fi-360\li5760\lin5760 }{\listlevel\levelnfc2\levelnfcn2\leveljc2\leveljcn2\levelfollow0\levelstartat1\levelspace0\levelindent0{\leveltext\leveltemplateid67698715\'02\'08.;}{\levelnumbers\'01;}\rtlch\fcs1 \af0 \ltrch\fcs0 \fi-180\li6480\lin6480 } {\listname ;}\listid2094470365}}{\*\listoverridetable{\listoverride\listid-120\listoverridecount0\ls1}{\listoverride\listid-119\listoverridecount0\ls2}{\listoverride\listid-125\listoverridecount0\ls3}{\listoverride\listid-126\listoverridecount0\ls4} {\listoverride\listid-127\listoverridecount0\ls5}{\listoverride\listid-128\listoverridecount0\ls6}{\listoverride\listid-129\listoverridecount0\ls7}{\listoverride\listid-130\listoverridecount0\ls8}{\listoverride\listid-131\listoverridecount0\ls9} {\listoverride\listid-132\listoverridecount0\ls10}{\listoverride\listid-120\listoverridecount0\ls11}{\listoverride\listid-119\listoverridecount0\ls12}{\listoverride\listid-125\listoverridecount0\ls13}{\listoverride\listid-126\listoverridecount0\ls14} {\listoverride\listid-127\listoverridecount0\ls15}{\listoverride\listid-128\listoverridecount0\ls16}{\listoverride\listid-129\listoverridecount0\ls17}{\listoverride\listid-130\listoverridecount0\ls18}{\listoverride\listid-131\listoverridecount0\ls19} {\listoverride\listid2094470365\listoverridecount9{\lfolevel\listoverridestartat\levelstartat1}{\lfolevel\listoverridestartat\levelstartat1}{\lfolevel\listoverridestartat\levelstartat1}{\lfolevel\listoverridestartat\levelstartat1}{\lfolevel \listoverridestartat\levelstartat1}{\lfolevel\listoverridestartat\levelstartat1}{\lfolevel\listoverridestartat\levelstartat1}{\lfolevel\listoverridestartat\levelstartat1}{\lfolevel\listoverridestartat\levelstartat1}\ls20}{\listoverride\listid984241419 \listoverridecount0\ls21}{\listoverride\listid162478944\listoverridecount0\ls22}}{\*\pgptbl {\pgp\ipgp0\itap0\li0\ri0\sb0\sa0}{\pgp\ipgp0\itap0\li0\ri0\sb0\sa0}{\pgp\ipgp0\itap0\li0\ri0\sb0\sa0}{\pgp\ipgp0\itap0\li0\ri0\sb0\sa0}{\pgp\ipgp0\itap0\li0\ri0 \sb0\sa0}{\pgp\ipgp0\itap0\li0\ri0\sb0\sa0}{\pgp\ipgp0\itap0\li0\ri0\sb0\sa0}{\pgp\ipgp0\itap0\li0\ri0\sb0\sa0}{\pgp\ipgp0\itap0\li0\ri0\sb0\sa0}{\pgp\ipgp0\itap0\li0\ri0\sb0\sa0}{\pgp\ipgp0\itap0\li0\ri0\sb0\sa0}{\pgp\ipgp0\itap0\li0\ri0\sb0\sa0}{\pgp \ipgp0\itap0\li0\ri0\sb0\sa0}{\pgp\ipgp0\itap0\li0\ri0\sb0\sa0}{\pgp\ipgp0\itap0\li0\ri0\sb0\sa0}}{\mmathPr\mmathFont34\mbrkBin0\mbrkBinSub0\msmallFrac0\mdispDef1\mlMargin0\mrMargin0\mdefJc1\mwrapIndent1440\mintLim0\mnaryLim1}{\info {\title Spec 1.9a - Title page}{\author The TWAIN Working Group}{\operator Mark Mclaughlin}{\creatim\yr2013\mo11\dy4\hr16\min24}{\revtim\yr2020\mo6\dy5\hr7\min45}{\printim\yr2010\mo7\dy28\hr8\min8}{\version42}{\edmins167}{\nofpages15}{\nofwords5390} {\nofchars30729}{\*\company JFL Peripheral Solutions Inc.}{\nofcharsws36047}{\vern111}}{\*\xmlnstbl {\xmlns1 http://schemas.microsoft.com/office/word/2003/wordml}}\paperw12240\paperh15840\margl1260\margr1080\margt1440\margb1080\gutter0\ltrsect\rtlgutter \widowctrl\ftnbj\aenddoc\trackmoves0\trackformatting1\donotembedsysfont0\relyonvml0\donotembedlingdata1\grfdocevents0\validatexml0\showplaceholdtext0\ignoremixedcontent0\saveinvalidxml0\showxmlerrors0\margmirror \noextrasprl\cvmme\sprsspbf\brkfrm\swpbdr\noxlattoyen\expshrtn\noultrlspc\dntblnsbdb\nospaceforul\lytprtmet\hyphcaps0\horzdoc\fracwidth\dghspace180\dgvspace180\dghorigin1701\dgvorigin1984\dghshow0\dgvshow0 \jexpand\viewkind1\viewscale100\pgbrdrhead\pgbrdrfoot\bdrrlswsix\nolnhtadjtbl \fet0{\*\wgrffmtfilter 013f}\ilfomacatclnup12{\*\ftnsep \ltrpar \pard\plain \ltrpar\ql \li1440\ri0\sb180\widctlpar\wrapdefault\nooverflow\faroman\rin0\lin1440\itap0 \rtlch\fcs1 \af44\afs20\alang1025 \ltrch\fcs0 \f44\fs20\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 {\rtlch\fcs1 \af44 \ltrch\fcs0 \chftnsep \par }}{\*\ftnsepc \ltrpar \pard\plain \ltrpar\ql \li1440\ri0\sb180\widctlpar\wrapdefault\nooverflow\faroman\rin0\lin1440\itap0 \rtlch\fcs1 \af44\afs20\alang1025 \ltrch\fcs0 \f44\fs20\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 {\rtlch\fcs1 \af44 \ltrch\fcs0 \chftnsepc \par }}{\*\aftnsep \ltrpar \pard\plain \ltrpar\ql \li1440\ri0\sb180\widctlpar\wrapdefault\nooverflow\faroman\rin0\lin1440\itap0 \rtlch\fcs1 \af44\afs20\alang1025 \ltrch\fcs0 \f44\fs20\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 {\rtlch\fcs1 \af44 \ltrch\fcs0 \chftnsep \par }}{\*\aftnsepc \ltrpar \pard\plain \ltrpar\ql \li1440\ri0\sb180\widctlpar\wrapdefault\nooverflow\faroman\rin0\lin1440\itap0 \rtlch\fcs1 \af44\afs20\alang1025 \ltrch\fcs0 \f44\fs20\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 {\rtlch\fcs1 \af44 \ltrch\fcs0 \chftnsepc \par }}\ltrpar \sectd \ltrsect\rtlgutter\psz1\linex0\endnhere\pgbrdropt32\sectdefaultcl\sectrsid6896082\sftnbj {\footerr \ltrpar \pard\plain \ltrpar\s25\ql \li0\ri0\widctlpar\tqr\tx9900\wrapdefault\nooverflow\faroman\rin0\lin0\itap0 \rtlch\fcs1 \ai\af1\afs16\alang1025 \ltrch\fcs0 \i\f1\fs16\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 {\rtlch\fcs1 \af1 \ltrch\fcs0 TWAIN for C#\tab }{\field{\*\fldinst {\rtlch\fcs1 \af1 \ltrch\fcs0 \cs32 PAGE }}{\fldrslt {\rtlch\fcs1 \af1 \ltrch\fcs0 \cs32\lang1024\langfe1024\noproof 11}}}\sectd \ltrsect\linex0\endnhere\sectdefaultcl\sftnbj {\rtlch\fcs1 \af1 \ltrch\fcs0 \cs32 \par Kodak Alaris Inc.}{\rtlch\fcs1 \af1 \ltrch\fcs0 \par }}{\*\pnseclvl1\pnucrm\pnstart1\pnindent720\pnhang {\pntxta .}}{\*\pnseclvl2\pnucltr\pnstart1\pnindent720\pnhang {\pntxta .}}{\*\pnseclvl3\pndec\pnstart1\pnindent720\pnhang {\pntxta .}}{\*\pnseclvl4\pnlcltr\pnstart1\pnindent720\pnhang {\pntxta )}} {\*\pnseclvl5\pndec\pnstart1\pnindent720\pnhang {\pntxtb (}{\pntxta )}}{\*\pnseclvl6\pnlcltr\pnstart1\pnindent720\pnhang {\pntxtb (}{\pntxta )}}{\*\pnseclvl7\pnlcrm\pnstart1\pnindent720\pnhang {\pntxtb (}{\pntxta )}}{\*\pnseclvl8 \pnlcltr\pnstart1\pnindent720\pnhang {\pntxtb (}{\pntxta )}}{\*\pnseclvl9\pnlcrm\pnstart1\pnindent720\pnhang {\pntxtb (}{\pntxta )}}\pard\plain \ltrpar\ql \li0\ri0\sb1440\widctlpar\brdrt\brdrs\brdrw60\brsp20\brdrcf13 \wrapdefault\nooverflow\faroman\rin0\lin0\itap0 \rtlch\fcs1 \af44\afs20\alang1025 \ltrch\fcs0 \f44\fs20\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 {\rtlch\fcs1 \af44 \ltrch\fcs0 \f31506 \par }\pard \ltrpar\ql \li1440\ri0\sb180\widctlpar\wrapdefault\nooverflow\faroman\rin0\lin1440\itap0 {\rtlch\fcs1 \af1\afs56 \ltrch\fcs0 \b\f31506\fs56\cf9 TWAIN for C# \par }\pard \ltrpar\ql \li1440\ri0\sb120\widctlpar\wrapdefault\nooverflow\faroman\rin0\lin1440\itap0 {\rtlch\fcs1 \ab\af1\afs28 \ltrch\fcs0 \b\f31506\fs28\cf13 For Version 2.4.10.0 \par }\pard \ltrpar\ql \li1440\ri0\sb180\widctlpar\wrapdefault\nooverflow\faroman\rin0\lin1440\itap0 {\rtlch\fcs1 \ab\af1\afs28 \ltrch\fcs0 \b\f31506\fs28 June 5}{\rtlch\fcs1 \ab\af1\afs28 \ltrch\fcs0 \b\f31506\fs28\super th}{\rtlch\fcs1 \ab\af1\afs28 \ltrch\fcs0 \b\f31506\fs28 , 2020 \par }\pard \ltrpar\ql \li1440\ri0\sb360\widctlpar\wrapdefault\nooverflow\faroman\rin0\lin1440\itap0 {\rtlch\fcs1 \af1\afs28 \ltrch\fcs0 \f31506\fs28 \par }\pard \ltrpar\ql \li0\ri0\sb120\widctlpar\brdrt\brdrs\brdrw60\brsp20\brdrcf13 \wrapdefault\nooverflow\faroman\rin0\lin0\itap0 {\rtlch\fcs1 \af44 \ltrch\fcs0 \f31506 \par }\pard \ltrpar\ql \li1440\ri0\sb240\widctlpar\wrapdefault\nooverflow\faroman\rin0\lin1440\itap0 {\rtlch\fcs1 \af44 \ltrch\fcs0 \f31506 \par }\pard \ltrpar\ql \li1440\ri0\sb360\widctlpar\wrapdefault\nooverflow\faroman\rin0\lin1440\itap0 {\rtlch\fcs1 \af44 \ltrch\fcs0 \f31506 \par \par }\pard \ltrpar\qc \li0\ri0\sb180\widctlpar\wrapdefault\nooverflow\faroman\rin0\lin0\itap0 {\rtlch\fcs1 \af44 \ltrch\fcs0 \f31506 \par }\pard \ltrpar\ql \li720\ri0\sb180\widctlpar\wrapdefault\nooverflow\faroman\rin0\lin720\itap0 {\rtlch\fcs1 \af44\afs40 \ltrch\fcs0 \f31506\fs40 \page }{\rtlch\fcs1 \af1\afs36 \ltrch\fcs0 \b\f31506\fs36\cf9 \par }\pard \ltrpar\ql \li720\ri0\sb180\keep\keepn\widctlpar\wrapdefault\nooverflow\faroman\rin0\lin720\itap0 {\rtlch\fcs1 \af1\afs36 \ltrch\fcs0 \b\f31506\fs36\cf9 Contents \par }\pard\plain \ltrpar\s98\ql \li1080\ri0\sb120\keepn\widctlpar\tqr\tldot\tx9893\wrapdefault\nooverflow\faroman\rin0\lin1080\itap0 \rtlch\fcs1 \ab\af1\afs20\alang1025 \ltrch\fcs0 \b\f1\fs20\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 {\field\fldedit{\*\fldinst {\rtlch\fcs1 \af1 \ltrch\fcs0 \b0\f31506 TOC \\o "1-3" \\h \\z \\u }}{\fldrslt {\field\fldedit{\*\fldinst {\rtlch\fcs1 \af0 \ltrch\fcs0 \cs187\ul\cf2\lang1024\langfe1024\noproof }{\rtlch\fcs1 \af1 \ltrch\fcs0 \lang1024\langfe1024\noproof HYPERLINK \\l "_Toc36456524"}{\rtlch\fcs1 \af0 \ltrch\fcs0 \cs187\ul\cf2\lang1024\langfe1024\noproof }{\rtlch\fcs1 \af0 \ltrch\fcs0 \cs187\ul\cf2\lang1024\langfe1024\noproof {\*\datafield 08d0c9ea79f9bace118c8200aa004ba90b02000000080000000d0000005f0054006f006300330036003400350036003500320034000000000000}}}{\fldrslt {\rtlch\fcs1 \af0 \ltrch\fcs0 \cs187\f37\ul\cf2\lang1024\langfe1024\noproof Purpose}{\rtlch\fcs1 \af1 \ltrch\fcs0 \lang1024\langfe1024\noproof\webhidden \tab }{\field{\*\fldinst {\rtlch\fcs1 \af1 \ltrch\fcs0 \lang1024\langfe1024\noproof\webhidden PAGEREF _Toc36456524 \\h }{\rtlch\fcs1 \af1 \ltrch\fcs0 \lang1024\langfe1024\noproof\webhidden {\*\datafield 08d0c9ea79f9bace118c8200aa004ba90b02000000080000000d0000005f0054006f006300330036003400350036003500320034000000007300}}}{\fldrslt {\rtlch\fcs1 \af1 \ltrch\fcs0 \lang1024\langfe1024\noproof\webhidden 4}}}\sectd \ltrsect\rtlgutter \psz1\linex0\endnhere\pgbrdropt32\sectdefaultcl\sectrsid6896082\sftnbj }}\sectd \ltrsect\rtlgutter\psz1\linex0\endnhere\pgbrdropt32\sectdefaultcl\sectrsid6896082\sftnbj {\rtlch\fcs1 \ab0\af0\afs22 \ltrch\fcs0 \b0\fs22\lang1024\langfe1024\loch\af31506\hich\af31506\dbch\af31505\noproof \par }{\field\fldedit{\*\fldinst {\rtlch\fcs1 \af0 \ltrch\fcs0 \cs187\ul\cf2\lang1024\langfe1024\noproof }{\rtlch\fcs1 \af1 \ltrch\fcs0 \lang1024\langfe1024\noproof HYPERLINK \\l "_Toc36456525"}{\rtlch\fcs1 \af0 \ltrch\fcs0 \cs187\ul\cf2\lang1024\langfe1024\noproof }{\rtlch\fcs1 \af0 \ltrch\fcs0 \cs187\ul\cf2\lang1024\langfe1024\noproof {\*\datafield 08d0c9ea79f9bace118c8200aa004ba90b02000000080000000d0000005f0054006f006300330036003400350036003500320035000000003500}} }{\fldrslt {\rtlch\fcs1 \af0 \ltrch\fcs0 \cs187\f37\ul\cf2\lang1024\langfe1024\noproof License}{\rtlch\fcs1 \af1 \ltrch\fcs0 \lang1024\langfe1024\noproof\webhidden \tab }{\field{\*\fldinst {\rtlch\fcs1 \af1 \ltrch\fcs0 \lang1024\langfe1024\noproof\webhidden PAGEREF _Toc36456525 \\h }{\rtlch\fcs1 \af1 \ltrch\fcs0 \lang1024\langfe1024\noproof\webhidden {\*\datafield 08d0c9ea79f9bace118c8200aa004ba90b02000000080000000d0000005f0054006f006300330036003400350036003500320035000000000300}}}{\fldrslt {\rtlch\fcs1 \af1 \ltrch\fcs0 \lang1024\langfe1024\noproof\webhidden 4}}}\sectd \ltrsect\rtlgutter \psz1\linex0\endnhere\pgbrdropt32\sectdefaultcl\sectrsid6896082\sftnbj }}\sectd \ltrsect\rtlgutter\psz1\linex0\endnhere\pgbrdropt32\sectdefaultcl\sectrsid6896082\sftnbj {\rtlch\fcs1 \ab0\af0\afs22 \ltrch\fcs0 \b0\fs22\lang1024\langfe1024\loch\af31506\hich\af31506\dbch\af31505\noproof \par }{\field\fldedit{\*\fldinst {\rtlch\fcs1 \af0 \ltrch\fcs0 \cs187\ul\cf2\lang1024\langfe1024\noproof }{\rtlch\fcs1 \af1 \ltrch\fcs0 \lang1024\langfe1024\noproof HYPERLINK \\l "_Toc36456526"}{\rtlch\fcs1 \af0 \ltrch\fcs0 \cs187\ul\cf2\lang1024\langfe1024\noproof }{\rtlch\fcs1 \af0 \ltrch\fcs0 \cs187\ul\cf2\lang1024\langfe1024\noproof {\*\datafield 08d0c9ea79f9bace118c8200aa004ba90b02000000080000000d0000005f0054006f006300330036003400350036003500320036000000000000}} }{\fldrslt {\rtlch\fcs1 \af0 \ltrch\fcs0 \cs187\ul\cf2\lang1024\langfe1024\noproof Project Repository}{\rtlch\fcs1 \af1 \ltrch\fcs0 \lang1024\langfe1024\noproof\webhidden \tab }{\field{\*\fldinst {\rtlch\fcs1 \af1 \ltrch\fcs0 \lang1024\langfe1024\noproof\webhidden PAGEREF _Toc36456526 \\h }{\rtlch\fcs1 \af1 \ltrch\fcs0 \lang1024\langfe1024\noproof\webhidden {\*\datafield 08d0c9ea79f9bace118c8200aa004ba90b02000000080000000d0000005f0054006f006300330036003400350036003500320036000000000000}}}{\fldrslt {\rtlch\fcs1 \af1 \ltrch\fcs0 \lang1024\langfe1024\noproof\webhidden 5}}}\sectd \ltrsect\rtlgutter \psz1\linex0\endnhere\pgbrdropt32\sectdefaultcl\sectrsid6896082\sftnbj }}\sectd \ltrsect\rtlgutter\psz1\linex0\endnhere\pgbrdropt32\sectdefaultcl\sectrsid6896082\sftnbj {\rtlch\fcs1 \ab0\af0\afs22 \ltrch\fcs0 \b0\fs22\lang1024\langfe1024\loch\af31506\hich\af31506\dbch\af31505\noproof \par }\pard\plain \ltrpar\s176\ql \li1440\ri0\sb180\widctlpar\tqr\tldot\tx9883\wrapdefault\nooverflow\faroman\rin0\lin1440\itap0 \rtlch\fcs1 \af44\afs20\alang1025 \ltrch\fcs0 \f44\fs20\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 {\field\fldedit{\*\fldinst {\rtlch\fcs1 \af0 \ltrch\fcs0 \cs187\ul\cf2\lang1024\langfe1024\noproof }{\rtlch\fcs1 \af44 \ltrch\fcs0 \lang1024\langfe1024\noproof HYPERLINK \\l "_Toc36456527"}{\rtlch\fcs1 \af0 \ltrch\fcs0 \cs187\ul\cf2\lang1024\langfe1024\noproof }{\rtlch\fcs1 \af0 \ltrch\fcs0 \cs187\ul\cf2\lang1024\langfe1024\noproof {\*\datafield 08d0c9ea79f9bace118c8200aa004ba90b02000000080000000d0000005f0054006f006300330036003400350036003500320037000000000000}} }{\fldrslt {\rtlch\fcs1 \af0 \ltrch\fcs0 \cs187\b\ul\cf2\lang1024\langfe1024\noproof Installation}{\rtlch\fcs1 \af44 \ltrch\fcs0 \lang1024\langfe1024\noproof\webhidden \tab }{\field{\*\fldinst {\rtlch\fcs1 \af44 \ltrch\fcs0 \lang1024\langfe1024\noproof\webhidden PAGEREF _Toc36456527 \\h }{\rtlch\fcs1 \af44 \ltrch\fcs0 \lang1024\langfe1024\noproof\webhidden {\*\datafield 08d0c9ea79f9bace118c8200aa004ba90b02000000080000000d0000005f0054006f006300330036003400350036003500320037000000000000}}}{\fldrslt {\rtlch\fcs1 \af44 \ltrch\fcs0 \lang1024\langfe1024\noproof\webhidden 5}}}\sectd \ltrsect\rtlgutter \psz1\linex0\endnhere\pgbrdropt32\sectdefaultcl\sectrsid6896082\sftnbj }}\sectd \ltrsect\rtlgutter\psz1\linex0\endnhere\pgbrdropt32\sectdefaultcl\sectrsid6896082\sftnbj {\rtlch\fcs1 \af0\afs22 \ltrch\fcs0 \fs22\lang1024\langfe1024\loch\af31506\hich\af31506\dbch\af31505\noproof \par }{\field\fldedit{\*\fldinst {\rtlch\fcs1 \af0 \ltrch\fcs0 \cs187\ul\cf2\lang1024\langfe1024\noproof }{\rtlch\fcs1 \af44 \ltrch\fcs0 \lang1024\langfe1024\noproof HYPERLINK \\l "_Toc36456528"}{\rtlch\fcs1 \af0 \ltrch\fcs0 \cs187\ul\cf2\lang1024\langfe1024\noproof }{\rtlch\fcs1 \af0 \ltrch\fcs0 \cs187\ul\cf2\lang1024\langfe1024\noproof {\*\datafield 08d0c9ea79f9bace118c8200aa004ba90b02000000080000000d0000005f0054006f006300330036003400350036003500320038000000000059}} }{\fldrslt {\rtlch\fcs1 \af0 \ltrch\fcs0 \cs187\b\ul\cf2\lang1024\langfe1024\noproof Versioning}{\rtlch\fcs1 \af44 \ltrch\fcs0 \lang1024\langfe1024\noproof\webhidden \tab }{\field{\*\fldinst {\rtlch\fcs1 \af44 \ltrch\fcs0 \lang1024\langfe1024\noproof\webhidden PAGEREF _Toc36456528 \\h }{\rtlch\fcs1 \af44 \ltrch\fcs0 \lang1024\langfe1024\noproof\webhidden {\*\datafield 08d0c9ea79f9bace118c8200aa004ba90b02000000080000000d0000005f0054006f0063003300360034003500360035003200380000000000d2}}}{\fldrslt {\rtlch\fcs1 \af44 \ltrch\fcs0 \lang1024\langfe1024\noproof\webhidden 5}}}\sectd \ltrsect\rtlgutter \psz1\linex0\endnhere\pgbrdropt32\sectdefaultcl\sectrsid6896082\sftnbj }}\sectd \ltrsect\rtlgutter\psz1\linex0\endnhere\pgbrdropt32\sectdefaultcl\sectrsid6896082\sftnbj {\rtlch\fcs1 \af0\afs22 \ltrch\fcs0 \fs22\lang1024\langfe1024\loch\af31506\hich\af31506\dbch\af31505\noproof \par }\pard\plain \ltrpar\s98\ql \li1080\ri0\sb120\keepn\widctlpar\tqr\tldot\tx9893\wrapdefault\nooverflow\faroman\rin0\lin1080\itap0 \rtlch\fcs1 \ab\af1\afs20\alang1025 \ltrch\fcs0 \b\f1\fs20\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 {\field\fldedit{\*\fldinst {\rtlch\fcs1 \af0 \ltrch\fcs0 \cs187\ul\cf2\lang1024\langfe1024\noproof }{\rtlch\fcs1 \af1 \ltrch\fcs0 \lang1024\langfe1024\noproof HYPERLINK \\l "_Toc36456529"}{\rtlch\fcs1 \af0 \ltrch\fcs0 \cs187\ul\cf2\lang1024\langfe1024\noproof }{\rtlch\fcs1 \af0 \ltrch\fcs0 \cs187\ul\cf2\lang1024\langfe1024\noproof {\*\datafield 08d0c9ea79f9bace118c8200aa004ba90b02000000080000000d0000005f0054006f006300330036003400350036003500320039000000004f00}} }{\fldrslt {\rtlch\fcs1 \af0 \ltrch\fcs0 \cs187\ul\cf2\lang1024\langfe1024\noproof Project Layout}{\rtlch\fcs1 \af1 \ltrch\fcs0 \lang1024\langfe1024\noproof\webhidden \tab }{\field{\*\fldinst {\rtlch\fcs1 \af1 \ltrch\fcs0 \lang1024\langfe1024\noproof\webhidden PAGEREF _Toc36456529 \\h }{\rtlch\fcs1 \af1 \ltrch\fcs0 \lang1024\langfe1024\noproof\webhidden {\*\datafield 08d0c9ea79f9bace118c8200aa004ba90b02000000080000000d0000005f0054006f006300330036003400350036003500320039000000693600}}}{\fldrslt {\rtlch\fcs1 \af1 \ltrch\fcs0 \lang1024\langfe1024\noproof\webhidden 6}}}\sectd \ltrsect\rtlgutter \psz1\linex0\endnhere\pgbrdropt32\sectdefaultcl\sectrsid6896082\sftnbj }}\sectd \ltrsect\rtlgutter\psz1\linex0\endnhere\pgbrdropt32\sectdefaultcl\sectrsid6896082\sftnbj {\rtlch\fcs1 \ab0\af0\afs22 \ltrch\fcs0 \b0\fs22\lang1024\langfe1024\loch\af31506\hich\af31506\dbch\af31505\noproof \par }\pard\plain \ltrpar\s176\ql \li1440\ri0\sb180\widctlpar\tqr\tldot\tx9883\wrapdefault\nooverflow\faroman\rin0\lin1440\itap0 \rtlch\fcs1 \af44\afs20\alang1025 \ltrch\fcs0 \f44\fs20\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 {\field\fldedit{\*\fldinst {\rtlch\fcs1 \af0 \ltrch\fcs0 \cs187\ul\cf2\lang1024\langfe1024\noproof }{\rtlch\fcs1 \af44 \ltrch\fcs0 \lang1024\langfe1024\noproof HYPERLINK \\l "_Toc36456530"}{\rtlch\fcs1 \af0 \ltrch\fcs0 \cs187\ul\cf2\lang1024\langfe1024\noproof }{\rtlch\fcs1 \af0 \ltrch\fcs0 \cs187\ul\cf2\lang1024\langfe1024\noproof {\*\datafield 08d0c9ea79f9bace118c8200aa004ba90b02000000080000000d0000005f0054006f006300330036003400350036003500330030000000002200}} }{\fldrslt {\rtlch\fcs1 \af0 \ltrch\fcs0 \cs187\b\ul\cf2\lang1024\langfe1024\noproof Basic TWAIN C# Definitions and Helper Functions}{\rtlch\fcs1 \af44 \ltrch\fcs0 \lang1024\langfe1024\noproof\webhidden \tab }{\field{\*\fldinst {\rtlch\fcs1 \af44 \ltrch\fcs0 \lang1024\langfe1024\noproof\webhidden PAGEREF _Toc36456530 \\h }{\rtlch\fcs1 \af44 \ltrch\fcs0 \lang1024\langfe1024\noproof\webhidden {\*\datafield 08d0c9ea79f9bace118c8200aa004ba90b02000000080000000d0000005f0054006f006300330036003400350036003500330030000000004500}}}{\fldrslt {\rtlch\fcs1 \af44 \ltrch\fcs0 \lang1024\langfe1024\noproof\webhidden 6}}}\sectd \ltrsect\rtlgutter \psz1\linex0\endnhere\pgbrdropt32\sectdefaultcl\sectrsid6896082\sftnbj }}\sectd \ltrsect\rtlgutter\psz1\linex0\endnhere\pgbrdropt32\sectdefaultcl\sectrsid6896082\sftnbj {\rtlch\fcs1 \af0\afs22 \ltrch\fcs0 \fs22\lang1024\langfe1024\loch\af31506\hich\af31506\dbch\af31505\noproof \par }{\field\fldedit{\*\fldinst {\rtlch\fcs1 \af0 \ltrch\fcs0 \cs187\ul\cf2\lang1024\langfe1024\noproof }{\rtlch\fcs1 \af44 \ltrch\fcs0 \lang1024\langfe1024\noproof HYPERLINK \\l "_Toc36456531"}{\rtlch\fcs1 \af0 \ltrch\fcs0 \cs187\ul\cf2\lang1024\langfe1024\noproof }{\rtlch\fcs1 \af0 \ltrch\fcs0 \cs187\ul\cf2\lang1024\langfe1024\noproof {\*\datafield 08d0c9ea79f9bace118c8200aa004ba90b02000000080000000d0000005f0054006f006300330036003400350036003500330031000000690f00}} }{\fldrslt {\rtlch\fcs1 \af0 \ltrch\fcs0 \cs187\b\ul\cf2\lang1024\langfe1024\noproof A TWAIN C# Toolkit}{\rtlch\fcs1 \af44 \ltrch\fcs0 \lang1024\langfe1024\noproof\webhidden \tab }{\field{\*\fldinst {\rtlch\fcs1 \af44 \ltrch\fcs0 \lang1024\langfe1024\noproof\webhidden PAGEREF _Toc36456531 \\h }{\rtlch\fcs1 \af44 \ltrch\fcs0 \lang1024\langfe1024\noproof\webhidden {\*\datafield 08d0c9ea79f9bace118c8200aa004ba90b02000000080000000d0000005f0054006f00630033003600340035003600350033003100000000d400}}}{\fldrslt {\rtlch\fcs1 \af44 \ltrch\fcs0 \lang1024\langfe1024\noproof\webhidden 7}}}\sectd \ltrsect\rtlgutter \psz1\linex0\endnhere\pgbrdropt32\sectdefaultcl\sectrsid6896082\sftnbj }}\sectd \ltrsect\rtlgutter\psz1\linex0\endnhere\pgbrdropt32\sectdefaultcl\sectrsid6896082\sftnbj {\rtlch\fcs1 \af0\afs22 \ltrch\fcs0 \fs22\lang1024\langfe1024\loch\af31506\hich\af31506\dbch\af31505\noproof \par }{\field\fldedit{\*\fldinst {\rtlch\fcs1 \af0 \ltrch\fcs0 \cs187\ul\cf2\lang1024\langfe1024\noproof }{\rtlch\fcs1 \af44 \ltrch\fcs0 \lang1024\langfe1024\noproof HYPERLINK \\l "_Toc36456532"}{\rtlch\fcs1 \af0 \ltrch\fcs0 \cs187\ul\cf2\lang1024\langfe1024\noproof }{\rtlch\fcs1 \af0 \ltrch\fcs0 \cs187\ul\cf2\lang1024\langfe1024\noproof {\*\datafield 08d0c9ea79f9bace118c8200aa004ba90b02000000080000000d0000005f0054006f006300330036003400350036003500330032000000007f02}} }{\fldrslt {\rtlch\fcs1 \af0 \ltrch\fcs0 \cs187\b\ul\cf2\lang1024\langfe1024\noproof A TWAIN C# Diagnostic Application}{\rtlch\fcs1 \af44 \ltrch\fcs0 \lang1024\langfe1024\noproof\webhidden \tab }{\field{\*\fldinst {\rtlch\fcs1 \af44 \ltrch\fcs0 \lang1024\langfe1024\noproof\webhidden PAGEREF _Toc36456532 \\h }{\rtlch\fcs1 \af44 \ltrch\fcs0 \lang1024\langfe1024\noproof\webhidden {\*\datafield 08d0c9ea79f9bace118c8200aa004ba90b02000000080000000d0000005f0054006f006300330036003400350036003500330032000000006800}}}{\fldrslt {\rtlch\fcs1 \af44 \ltrch\fcs0 \lang1024\langfe1024\noproof\webhidden 7}}}\sectd \ltrsect\rtlgutter \psz1\linex0\endnhere\pgbrdropt32\sectdefaultcl\sectrsid6896082\sftnbj }}\sectd \ltrsect\rtlgutter\psz1\linex0\endnhere\pgbrdropt32\sectdefaultcl\sectrsid6896082\sftnbj {\rtlch\fcs1 \af0\afs22 \ltrch\fcs0 \fs22\lang1024\langfe1024\loch\af31506\hich\af31506\dbch\af31505\noproof \par }{\field\fldedit{\*\fldinst {\rtlch\fcs1 \af0 \ltrch\fcs0 \cs187\ul\cf2\lang1024\langfe1024\noproof }{\rtlch\fcs1 \af44 \ltrch\fcs0 \lang1024\langfe1024\noproof HYPERLINK \\l "_Toc36456533"}{\rtlch\fcs1 \af0 \ltrch\fcs0 \cs187\ul\cf2\lang1024\langfe1024\noproof }{\rtlch\fcs1 \af0 \ltrch\fcs0 \cs187\ul\cf2\lang1024\langfe1024\noproof {\*\datafield 08d0c9ea79f9bace118c8200aa004ba90b02000000080000000d0000005f0054006f006300330036003400350036003500330033000000000506}} }{\fldrslt {\rtlch\fcs1 \af0 \ltrch\fcs0 \cs187\b\ul\cf2\lang1024\langfe1024\noproof A TWAIN C# Sample Application}{\rtlch\fcs1 \af44 \ltrch\fcs0 \lang1024\langfe1024\noproof\webhidden \tab }{\field{\*\fldinst {\rtlch\fcs1 \af44 \ltrch\fcs0 \lang1024\langfe1024\noproof\webhidden PAGEREF _Toc36456533 \\h }{\rtlch\fcs1 \af44 \ltrch\fcs0 \lang1024\langfe1024\noproof\webhidden {\*\datafield 08d0c9ea79f9bace118c8200aa004ba90b02000000080000000d0000005f0054006f0063003300360034003500360035003300330000000001d7}}}{\fldrslt {\rtlch\fcs1 \af44 \ltrch\fcs0 \lang1024\langfe1024\noproof\webhidden 8}}}\sectd \ltrsect\rtlgutter \psz1\linex0\endnhere\pgbrdropt32\sectdefaultcl\sectrsid6896082\sftnbj }}\sectd \ltrsect\rtlgutter\psz1\linex0\endnhere\pgbrdropt32\sectdefaultcl\sectrsid6896082\sftnbj {\rtlch\fcs1 \af0\afs22 \ltrch\fcs0 \fs22\lang1024\langfe1024\loch\af31506\hich\af31506\dbch\af31505\noproof \par }{\field\fldedit{\*\fldinst {\rtlch\fcs1 \af0 \ltrch\fcs0 \cs187\ul\cf2\lang1024\langfe1024\noproof }{\rtlch\fcs1 \af44 \ltrch\fcs0 \lang1024\langfe1024\noproof HYPERLINK \\l "_Toc36456534"}{\rtlch\fcs1 \af0 \ltrch\fcs0 \cs187\ul\cf2\lang1024\langfe1024\noproof }{\rtlch\fcs1 \af0 \ltrch\fcs0 \cs187\ul\cf2\lang1024\langfe1024\noproof {\*\datafield 08d0c9ea79f9bace118c8200aa004ba90b02000000080000000d0000005f0054006f006300330036003400350036003500330034000000001000}} }{\fldrslt {\rtlch\fcs1 \af0 \ltrch\fcs0 \cs187\b\ul\cf2\lang1024\langfe1024\noproof A TWAIN C# Self Certification Application}{\rtlch\fcs1 \af44 \ltrch\fcs0 \lang1024\langfe1024\noproof\webhidden \tab }{\field{\*\fldinst {\rtlch\fcs1 \af44 \ltrch\fcs0 \lang1024\langfe1024\noproof\webhidden PAGEREF _Toc36456534 \\h }{\rtlch\fcs1 \af44 \ltrch\fcs0 \lang1024\langfe1024\noproof\webhidden {\*\datafield 08d0c9ea79f9bace118c8200aa004ba90b02000000080000000d0000005f0054006f0063003300360034003500360035003300340000000000b0}}}{\fldrslt {\rtlch\fcs1 \af44 \ltrch\fcs0 \lang1024\langfe1024\noproof\webhidden 8}}}\sectd \ltrsect\rtlgutter \psz1\linex0\endnhere\pgbrdropt32\sectdefaultcl\sectrsid6896082\sftnbj }}\sectd \ltrsect\rtlgutter\psz1\linex0\endnhere\pgbrdropt32\sectdefaultcl\sectrsid6896082\sftnbj {\rtlch\fcs1 \af0\afs22 \ltrch\fcs0 \fs22\lang1024\langfe1024\loch\af31506\hich\af31506\dbch\af31505\noproof \par }\pard\plain \ltrpar\s98\ql \li1080\ri0\sb120\keepn\widctlpar\tqr\tldot\tx9893\wrapdefault\nooverflow\faroman\rin0\lin1080\itap0 \rtlch\fcs1 \ab\af1\afs20\alang1025 \ltrch\fcs0 \b\f1\fs20\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 {\field\fldedit{\*\fldinst {\rtlch\fcs1 \af0 \ltrch\fcs0 \cs187\ul\cf2\lang1024\langfe1024\noproof }{\rtlch\fcs1 \af1 \ltrch\fcs0 \lang1024\langfe1024\noproof HYPERLINK \\l "_Toc36456535"}{\rtlch\fcs1 \af0 \ltrch\fcs0 \cs187\ul\cf2\lang1024\langfe1024\noproof }{\rtlch\fcs1 \af0 \ltrch\fcs0 \cs187\ul\cf2\lang1024\langfe1024\noproof {\*\datafield 08d0c9ea79f9bace118c8200aa004ba90b02000000080000000d0000005f0054006f006300330036003400350036003500330035000000000000}} }{\fldrslt {\rtlch\fcs1 \af0 \ltrch\fcs0 \cs187\ul\cf2\lang1024\langfe1024\noproof Release Notes}{\rtlch\fcs1 \af1 \ltrch\fcs0 \lang1024\langfe1024\noproof\webhidden \tab }{\field{\*\fldinst {\rtlch\fcs1 \af1 \ltrch\fcs0 \lang1024\langfe1024\noproof\webhidden PAGEREF _Toc36456535 \\h }{\rtlch\fcs1 \af1 \ltrch\fcs0 \lang1024\langfe1024\noproof\webhidden {\*\datafield 08d0c9ea79f9bace118c8200aa004ba90b02000000080000000d0000005f0054006f006300330036003400350036003500330035000000000000}}}{\fldrslt {\rtlch\fcs1 \af1 \ltrch\fcs0 \lang1024\langfe1024\noproof\webhidden 10}}}\sectd \ltrsect\rtlgutter \psz1\linex0\endnhere\pgbrdropt32\sectdefaultcl\sectrsid6896082\sftnbj }}\sectd \ltrsect\rtlgutter\psz1\linex0\endnhere\pgbrdropt32\sectdefaultcl\sectrsid6896082\sftnbj {\rtlch\fcs1 \ab0\af0\afs22 \ltrch\fcs0 \b0\fs22\lang1024\langfe1024\loch\af31506\hich\af31506\dbch\af31505\noproof \par }\pard\plain \ltrpar\s176\ql \li1440\ri0\sb180\widctlpar\tqr\tldot\tx9883\wrapdefault\nooverflow\faroman\rin0\lin1440\itap0 \rtlch\fcs1 \af44\afs20\alang1025 \ltrch\fcs0 \f44\fs20\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 {\field\fldedit{\*\fldinst {\rtlch\fcs1 \af0 \ltrch\fcs0 \cs187\ul\cf2\lang1024\langfe1024\noproof }{\rtlch\fcs1 \af44 \ltrch\fcs0 \lang1024\langfe1024\noproof HYPERLINK \\l "_Toc36456536"}{\rtlch\fcs1 \af0 \ltrch\fcs0 \cs187\ul\cf2\lang1024\langfe1024\noproof }{\rtlch\fcs1 \af0 \ltrch\fcs0 \cs187\ul\cf2\lang1024\langfe1024\noproof {\*\datafield 08d0c9ea79f9bace118c8200aa004ba90b02000000080000000d0000005f0054006f006300330036003400350036003500330036000000000000}} }{\fldrslt {\rtlch\fcs1 \af0 \ltrch\fcs0 \cs187\b\ul\cf2\lang1024\langfe1024\noproof V2.4.8.0 (30-Mar-2020)}{\rtlch\fcs1 \af44 \ltrch\fcs0 \lang1024\langfe1024\noproof\webhidden \tab }{\field{\*\fldinst {\rtlch\fcs1 \af44 \ltrch\fcs0 \lang1024\langfe1024\noproof\webhidden PAGEREF _Toc36456536 \\h }{\rtlch\fcs1 \af44 \ltrch\fcs0 \lang1024\langfe1024\noproof\webhidden {\*\datafield 08d0c9ea79f9bace118c8200aa004ba90b02000000080000000d0000005f0054006f006300330036003400350036003500330036000000ff00c9}}}{\fldrslt {\rtlch\fcs1 \af44 \ltrch\fcs0 \lang1024\langfe1024\noproof\webhidden 10}}}\sectd \ltrsect\rtlgutter \psz1\linex0\endnhere\pgbrdropt32\sectdefaultcl\sectrsid6896082\sftnbj }}\sectd \ltrsect\rtlgutter\psz1\linex0\endnhere\pgbrdropt32\sectdefaultcl\sectrsid6896082\sftnbj {\rtlch\fcs1 \af0\afs22 \ltrch\fcs0 \fs22\lang1024\langfe1024\loch\af31506\hich\af31506\dbch\af31505\noproof \par }{\field\fldedit{\*\fldinst {\rtlch\fcs1 \af0 \ltrch\fcs0 \cs187\ul\cf2\lang1024\langfe1024\noproof }{\rtlch\fcs1 \af44 \ltrch\fcs0 \lang1024\langfe1024\noproof HYPERLINK \\l "_Toc36456537"}{\rtlch\fcs1 \af0 \ltrch\fcs0 \cs187\ul\cf2\lang1024\langfe1024\noproof }{\rtlch\fcs1 \af0 \ltrch\fcs0 \cs187\ul\cf2\lang1024\langfe1024\noproof {\*\datafield 08d0c9ea79f9bace118c8200aa004ba90b02000000080000000d0000005f0054006f006300330036003400350036003500330037000000000035}} }{\fldrslt {\rtlch\fcs1 \af0 \ltrch\fcs0 \cs187\b\ul\cf2\lang1024\langfe1024\noproof V2.4.6.0 (26-Mar-2020)}{\rtlch\fcs1 \af44 \ltrch\fcs0 \lang1024\langfe1024\noproof\webhidden \tab }{\field{\*\fldinst {\rtlch\fcs1 \af44 \ltrch\fcs0 \lang1024\langfe1024\noproof\webhidden PAGEREF _Toc36456537 \\h }{\rtlch\fcs1 \af44 \ltrch\fcs0 \lang1024\langfe1024\noproof\webhidden {\*\datafield 08d0c9ea79f9bace118c8200aa004ba90b02000000080000000d0000005f0054006f006300330036003400350036003500330037000000000000}}}{\fldrslt {\rtlch\fcs1 \af44 \ltrch\fcs0 \lang1024\langfe1024\noproof\webhidden 10}}}\sectd \ltrsect\rtlgutter \psz1\linex0\endnhere\pgbrdropt32\sectdefaultcl\sectrsid6896082\sftnbj }}\sectd \ltrsect\rtlgutter\psz1\linex0\endnhere\pgbrdropt32\sectdefaultcl\sectrsid6896082\sftnbj {\rtlch\fcs1 \af0\afs22 \ltrch\fcs0 \fs22\lang1024\langfe1024\loch\af31506\hich\af31506\dbch\af31505\noproof \par }{\field\fldedit{\*\fldinst {\rtlch\fcs1 \af0 \ltrch\fcs0 \cs187\ul\cf2\lang1024\langfe1024\noproof }{\rtlch\fcs1 \af44 \ltrch\fcs0 \lang1024\langfe1024\noproof HYPERLINK \\l "_Toc36456538"}{\rtlch\fcs1 \af0 \ltrch\fcs0 \cs187\ul\cf2\lang1024\langfe1024\noproof }{\rtlch\fcs1 \af0 \ltrch\fcs0 \cs187\ul\cf2\lang1024\langfe1024\noproof {\*\datafield 08d0c9ea79f9bace118c8200aa004ba90b02000000080000000d0000005f0054006f006300330036003400350036003500330038000000007100}} }{\fldrslt {\rtlch\fcs1 \af0 \ltrch\fcs0 \cs187\b\ul\cf2\lang1024\langfe1024\noproof V2.4.5.0 (24-Mar-2020)}{\rtlch\fcs1 \af44 \ltrch\fcs0 \lang1024\langfe1024\noproof\webhidden \tab }{\field{\*\fldinst {\rtlch\fcs1 \af44 \ltrch\fcs0 \lang1024\langfe1024\noproof\webhidden PAGEREF _Toc36456538 \\h }{\rtlch\fcs1 \af44 \ltrch\fcs0 \lang1024\langfe1024\noproof\webhidden {\*\datafield 08d0c9ea79f9bace118c8200aa004ba90b02000000080000000d0000005f0054006f006300330036003400350036003500330038000000002000}}}{\fldrslt {\rtlch\fcs1 \af44 \ltrch\fcs0 \lang1024\langfe1024\noproof\webhidden 10}}}\sectd \ltrsect\rtlgutter \psz1\linex0\endnhere\pgbrdropt32\sectdefaultcl\sectrsid6896082\sftnbj }}\sectd \ltrsect\rtlgutter\psz1\linex0\endnhere\pgbrdropt32\sectdefaultcl\sectrsid6896082\sftnbj {\rtlch\fcs1 \af0\afs22 \ltrch\fcs0 \fs22\lang1024\langfe1024\loch\af31506\hich\af31506\dbch\af31505\noproof \par }{\field\fldedit{\*\fldinst {\rtlch\fcs1 \af0 \ltrch\fcs0 \cs187\ul\cf2\lang1024\langfe1024\noproof }{\rtlch\fcs1 \af44 \ltrch\fcs0 \lang1024\langfe1024\noproof HYPERLINK \\l "_Toc36456539"}{\rtlch\fcs1 \af0 \ltrch\fcs0 \cs187\ul\cf2\lang1024\langfe1024\noproof }{\rtlch\fcs1 \af0 \ltrch\fcs0 \cs187\ul\cf2\lang1024\langfe1024\noproof {\*\datafield 08d0c9ea79f9bace118c8200aa004ba90b02000000080000000d0000005f0054006f006300330036003400350036003500330039000000001816}} }{\fldrslt {\rtlch\fcs1 \af0 \ltrch\fcs0 \cs187\b\ul\cf2\lang1024\langfe1024\noproof V2.4.4.0 (24-Mar-2020)}{\rtlch\fcs1 \af44 \ltrch\fcs0 \lang1024\langfe1024\noproof\webhidden \tab }{\field{\*\fldinst {\rtlch\fcs1 \af44 \ltrch\fcs0 \lang1024\langfe1024\noproof\webhidden PAGEREF _Toc36456539 \\h }{\rtlch\fcs1 \af44 \ltrch\fcs0 \lang1024\langfe1024\noproof\webhidden {\*\datafield 08d0c9ea79f9bace118c8200aa004ba90b02000000080000000d0000005f0054006f006300330036003400350036003500330039000000005200}}}{\fldrslt {\rtlch\fcs1 \af44 \ltrch\fcs0 \lang1024\langfe1024\noproof\webhidden 10}}}\sectd \ltrsect\rtlgutter \psz1\linex0\endnhere\pgbrdropt32\sectdefaultcl\sectrsid6896082\sftnbj }}\sectd \ltrsect\rtlgutter\psz1\linex0\endnhere\pgbrdropt32\sectdefaultcl\sectrsid6896082\sftnbj {\rtlch\fcs1 \af0\afs22 \ltrch\fcs0 \fs22\lang1024\langfe1024\loch\af31506\hich\af31506\dbch\af31505\noproof \par }{\field\fldedit{\*\fldinst {\rtlch\fcs1 \af0 \ltrch\fcs0 \cs187\ul\cf2\lang1024\langfe1024\noproof }{\rtlch\fcs1 \af44 \ltrch\fcs0 \lang1024\langfe1024\noproof HYPERLINK \\l "_Toc36456540"}{\rtlch\fcs1 \af0 \ltrch\fcs0 \cs187\ul\cf2\lang1024\langfe1024\noproof }{\rtlch\fcs1 \af0 \ltrch\fcs0 \cs187\ul\cf2\lang1024\langfe1024\noproof {\*\datafield 08d0c9ea79f9bace118c8200aa004ba90b02000000080000000d0000005f0054006f006300330036003400350036003500340030000000006f08}} }{\fldrslt {\rtlch\fcs1 \af0 \ltrch\fcs0 \cs187\b\ul\cf2\lang1024\langfe1024\noproof V2.4.3.0 (20-Mar-2020)}{\rtlch\fcs1 \af44 \ltrch\fcs0 \lang1024\langfe1024\noproof\webhidden \tab }{\field{\*\fldinst {\rtlch\fcs1 \af44 \ltrch\fcs0 \lang1024\langfe1024\noproof\webhidden PAGEREF _Toc36456540 \\h }{\rtlch\fcs1 \af44 \ltrch\fcs0 \lang1024\langfe1024\noproof\webhidden {\*\datafield 08d0c9ea79f9bace118c8200aa004ba90b02000000080000000d0000005f0054006f006300330036003400350036003500340030000000004500}}}{\fldrslt {\rtlch\fcs1 \af44 \ltrch\fcs0 \lang1024\langfe1024\noproof\webhidden 11}}}\sectd \ltrsect\rtlgutter \psz1\linex0\endnhere\pgbrdropt32\sectdefaultcl\sectrsid6896082\sftnbj }}\sectd \ltrsect\rtlgutter\psz1\linex0\endnhere\pgbrdropt32\sectdefaultcl\sectrsid6896082\sftnbj {\rtlch\fcs1 \af0\afs22 \ltrch\fcs0 \fs22\lang1024\langfe1024\loch\af31506\hich\af31506\dbch\af31505\noproof \par }{\field\fldedit{\*\fldinst {\rtlch\fcs1 \af0 \ltrch\fcs0 \cs187\ul\cf2\lang1024\langfe1024\noproof }{\rtlch\fcs1 \af44 \ltrch\fcs0 \lang1024\langfe1024\noproof HYPERLINK \\l "_Toc36456541"}{\rtlch\fcs1 \af0 \ltrch\fcs0 \cs187\ul\cf2\lang1024\langfe1024\noproof }{\rtlch\fcs1 \af0 \ltrch\fcs0 \cs187\ul\cf2\lang1024\langfe1024\noproof {\*\datafield 08d0c9ea79f9bace118c8200aa004ba90b02000000080000000d0000005f0054006f006300330036003400350036003500340031000000000feb}} }{\fldrslt {\rtlch\fcs1 \af0 \ltrch\fcs0 \cs187\b\ul\cf2\lang1024\langfe1024\noproof V2.4.2.0 (13-Mar-2020)}{\rtlch\fcs1 \af44 \ltrch\fcs0 \lang1024\langfe1024\noproof\webhidden \tab }{\field{\*\fldinst {\rtlch\fcs1 \af44 \ltrch\fcs0 \lang1024\langfe1024\noproof\webhidden PAGEREF _Toc36456541 \\h }{\rtlch\fcs1 \af44 \ltrch\fcs0 \lang1024\langfe1024\noproof\webhidden {\*\datafield 08d0c9ea79f9bace118c8200aa004ba90b02000000080000000d0000005f0054006f00630033003600340035003600350034003100000000d400}}}{\fldrslt {\rtlch\fcs1 \af44 \ltrch\fcs0 \lang1024\langfe1024\noproof\webhidden 11}}}\sectd \ltrsect\rtlgutter \psz1\linex0\endnhere\pgbrdropt32\sectdefaultcl\sectrsid6896082\sftnbj }}\sectd \ltrsect\rtlgutter\psz1\linex0\endnhere\pgbrdropt32\sectdefaultcl\sectrsid6896082\sftnbj {\rtlch\fcs1 \af0\afs22 \ltrch\fcs0 \fs22\lang1024\langfe1024\loch\af31506\hich\af31506\dbch\af31505\noproof \par }{\field\fldedit{\*\fldinst {\rtlch\fcs1 \af0 \ltrch\fcs0 \cs187\ul\cf2\lang1024\langfe1024\noproof }{\rtlch\fcs1 \af44 \ltrch\fcs0 \lang1024\langfe1024\noproof HYPERLINK \\l "_Toc36456542"}{\rtlch\fcs1 \af0 \ltrch\fcs0 \cs187\ul\cf2\lang1024\langfe1024\noproof }{\rtlch\fcs1 \af0 \ltrch\fcs0 \cs187\ul\cf2\lang1024\langfe1024\noproof {\*\datafield 08d0c9ea79f9bace118c8200aa004ba90b02000000080000000d0000005f0054006f006300330036003400350036003500340032000000007f01}} }{\fldrslt {\rtlch\fcs1 \af0 \ltrch\fcs0 \cs187\b\ul\cf2\lang1024\langfe1024\noproof V2.4.1.0 (30-Jan-2020)}{\rtlch\fcs1 \af44 \ltrch\fcs0 \lang1024\langfe1024\noproof\webhidden \tab }{\field{\*\fldinst {\rtlch\fcs1 \af44 \ltrch\fcs0 \lang1024\langfe1024\noproof\webhidden PAGEREF _Toc36456542 \\h }{\rtlch\fcs1 \af44 \ltrch\fcs0 \lang1024\langfe1024\noproof\webhidden {\*\datafield 08d0c9ea79f9bace118c8200aa004ba90b02000000080000000d0000005f0054006f006300330036003400350036003500340032000000006801}}}{\fldrslt {\rtlch\fcs1 \af44 \ltrch\fcs0 \lang1024\langfe1024\noproof\webhidden 11}}}\sectd \ltrsect\rtlgutter \psz1\linex0\endnhere\pgbrdropt32\sectdefaultcl\sectrsid6896082\sftnbj }}\sectd \ltrsect\rtlgutter\psz1\linex0\endnhere\pgbrdropt32\sectdefaultcl\sectrsid6896082\sftnbj {\rtlch\fcs1 \af0\afs22 \ltrch\fcs0 \fs22\lang1024\langfe1024\loch\af31506\hich\af31506\dbch\af31505\noproof \par }{\field\fldedit{\*\fldinst {\rtlch\fcs1 \af0 \ltrch\fcs0 \cs187\ul\cf2\lang1024\langfe1024\noproof }{\rtlch\fcs1 \af44 \ltrch\fcs0 \lang1024\langfe1024\noproof HYPERLINK \\l "_Toc36456543"}{\rtlch\fcs1 \af0 \ltrch\fcs0 \cs187\ul\cf2\lang1024\langfe1024\noproof }{\rtlch\fcs1 \af0 \ltrch\fcs0 \cs187\ul\cf2\lang1024\langfe1024\noproof {\*\datafield 08d0c9ea79f9bace118c8200aa004ba90b02000000080000000d0000005f0054006f006300330036003400350036003500340033000000004074}} }{\fldrslt {\rtlch\fcs1 \af0 \ltrch\fcs0 \cs187\b\ul\cf2\lang1024\langfe1024\noproof V2.4.0.3 (13-Mar-2019)}{\rtlch\fcs1 \af44 \ltrch\fcs0 \lang1024\langfe1024\noproof\webhidden \tab }{\field{\*\fldinst {\rtlch\fcs1 \af44 \ltrch\fcs0 \lang1024\langfe1024\noproof\webhidden PAGEREF _Toc36456543 \\h }{\rtlch\fcs1 \af44 \ltrch\fcs0 \lang1024\langfe1024\noproof\webhidden {\*\datafield 08d0c9ea79f9bace118c8200aa004ba90b02000000080000000d0000005f0054006f006300330036003400350036003500340033000000003604}}}{\fldrslt {\rtlch\fcs1 \af44 \ltrch\fcs0 \lang1024\langfe1024\noproof\webhidden 11}}}\sectd \ltrsect\rtlgutter \psz1\linex0\endnhere\pgbrdropt32\sectdefaultcl\sectrsid6896082\sftnbj }}\sectd \ltrsect\rtlgutter\psz1\linex0\endnhere\pgbrdropt32\sectdefaultcl\sectrsid6896082\sftnbj {\rtlch\fcs1 \af0\afs22 \ltrch\fcs0 \fs22\lang1024\langfe1024\loch\af31506\hich\af31506\dbch\af31505\noproof \par }{\field\fldedit{\*\fldinst {\rtlch\fcs1 \af0 \ltrch\fcs0 \cs187\ul\cf2\lang1024\langfe1024\noproof }{\rtlch\fcs1 \af44 \ltrch\fcs0 \lang1024\langfe1024\noproof HYPERLINK \\l "_Toc36456544"}{\rtlch\fcs1 \af0 \ltrch\fcs0 \cs187\ul\cf2\lang1024\langfe1024\noproof }{\rtlch\fcs1 \af0 \ltrch\fcs0 \cs187\ul\cf2\lang1024\langfe1024\noproof {\*\datafield 08d0c9ea79f9bace118c8200aa004ba90b02000000080000000d0000005f0054006f0063003300360034003500360035003400340000000017b0}} }{\fldrslt {\rtlch\fcs1 \af0 \ltrch\fcs0 \cs187\b\ul\cf2\lang1024\langfe1024\noproof V2.4.0.2 (25-Jan-2019)}{\rtlch\fcs1 \af44 \ltrch\fcs0 \lang1024\langfe1024\noproof\webhidden \tab }{\field{\*\fldinst {\rtlch\fcs1 \af44 \ltrch\fcs0 \lang1024\langfe1024\noproof\webhidden PAGEREF _Toc36456544 \\h }{\rtlch\fcs1 \af44 \ltrch\fcs0 \lang1024\langfe1024\noproof\webhidden {\*\datafield 08d0c9ea79f9bace118c8200aa004ba90b02000000080000000d0000005f0054006f00630033003600340035003600350034003400000000bcca}}}{\fldrslt {\rtlch\fcs1 \af44 \ltrch\fcs0 \lang1024\langfe1024\noproof\webhidden 12}}}\sectd \ltrsect\rtlgutter \psz1\linex0\endnhere\pgbrdropt32\sectdefaultcl\sectrsid6896082\sftnbj }}\sectd \ltrsect\rtlgutter\psz1\linex0\endnhere\pgbrdropt32\sectdefaultcl\sectrsid6896082\sftnbj {\rtlch\fcs1 \af0\afs22 \ltrch\fcs0 \fs22\lang1024\langfe1024\loch\af31506\hich\af31506\dbch\af31505\noproof \par }{\field\fldedit{\*\fldinst {\rtlch\fcs1 \af0 \ltrch\fcs0 \cs187\ul\cf2\lang1024\langfe1024\noproof }{\rtlch\fcs1 \af44 \ltrch\fcs0 \lang1024\langfe1024\noproof HYPERLINK \\l "_Toc36456545"}{\rtlch\fcs1 \af0 \ltrch\fcs0 \cs187\ul\cf2\lang1024\langfe1024\noproof }{\rtlch\fcs1 \af0 \ltrch\fcs0 \cs187\ul\cf2\lang1024\langfe1024\noproof {\*\datafield 08d0c9ea79f9bace118c8200aa004ba90b02000000080000000d0000005f0054006f00630033003600340035003600350034003500000000186e}} }{\fldrslt {\rtlch\fcs1 \af0 \ltrch\fcs0 \cs187\b\ul\cf2\lang1024\langfe1024\noproof V2.4.0.1 (19-Apr-2018)}{\rtlch\fcs1 \af44 \ltrch\fcs0 \lang1024\langfe1024\noproof\webhidden \tab }{\field{\*\fldinst {\rtlch\fcs1 \af44 \ltrch\fcs0 \lang1024\langfe1024\noproof\webhidden PAGEREF _Toc36456545 \\h }{\rtlch\fcs1 \af44 \ltrch\fcs0 \lang1024\langfe1024\noproof\webhidden {\*\datafield 08d0c9ea79f9bace118c8200aa004ba90b02000000080000000d0000005f0054006f006300330036003400350036003500340035000000005100}}}{\fldrslt {\rtlch\fcs1 \af44 \ltrch\fcs0 \lang1024\langfe1024\noproof\webhidden 12}}}\sectd \ltrsect\rtlgutter \psz1\linex0\endnhere\pgbrdropt32\sectdefaultcl\sectrsid6896082\sftnbj }}\sectd \ltrsect\rtlgutter\psz1\linex0\endnhere\pgbrdropt32\sectdefaultcl\sectrsid6896082\sftnbj {\rtlch\fcs1 \af0\afs22 \ltrch\fcs0 \fs22\lang1024\langfe1024\loch\af31506\hich\af31506\dbch\af31505\noproof \par }{\field\fldedit{\*\fldinst {\rtlch\fcs1 \af0 \ltrch\fcs0 \cs187\ul\cf2\lang1024\langfe1024\noproof }{\rtlch\fcs1 \af44 \ltrch\fcs0 \lang1024\langfe1024\noproof HYPERLINK \\l "_Toc36456546"}{\rtlch\fcs1 \af0 \ltrch\fcs0 \cs187\ul\cf2\lang1024\langfe1024\noproof }{\rtlch\fcs1 \af0 \ltrch\fcs0 \cs187\ul\cf2\lang1024\langfe1024\noproof {\*\datafield 08d0c9ea79f9bace118c8200aa004ba90b02000000080000000d0000005f0054006f006300330036003400350036003500340036000000004500}} }{\fldrslt {\rtlch\fcs1 \af0 \ltrch\fcs0 \cs187\b\ul\cf2\lang1024\langfe1024\noproof V2.4.0.0 (darned if I know, 2017)}{\rtlch\fcs1 \af44 \ltrch\fcs0 \lang1024\langfe1024\noproof\webhidden \tab }{\field{\*\fldinst {\rtlch\fcs1 \af44 \ltrch\fcs0 \lang1024\langfe1024\noproof\webhidden PAGEREF _Toc36456546 \\h }{\rtlch\fcs1 \af44 \ltrch\fcs0 \lang1024\langfe1024\noproof\webhidden {\*\datafield 08d0c9ea79f9bace118c8200aa004ba90b02000000080000000d0000005f0054006f006300330036003400350036003500340036000000000f00}}}{\fldrslt {\rtlch\fcs1 \af44 \ltrch\fcs0 \lang1024\langfe1024\noproof\webhidden 12}}}\sectd \ltrsect\rtlgutter \psz1\linex0\endnhere\pgbrdropt32\sectdefaultcl\sectrsid6896082\sftnbj }}\sectd \ltrsect\rtlgutter\psz1\linex0\endnhere\pgbrdropt32\sectdefaultcl\sectrsid6896082\sftnbj {\rtlch\fcs1 \af0\afs22 \ltrch\fcs0 \fs22\lang1024\langfe1024\loch\af31506\hich\af31506\dbch\af31505\noproof \par }{\field\fldedit{\*\fldinst {\rtlch\fcs1 \af0 \ltrch\fcs0 \cs187\ul\cf2\lang1024\langfe1024\noproof }{\rtlch\fcs1 \af44 \ltrch\fcs0 \lang1024\langfe1024\noproof HYPERLINK \\l "_Toc36456547"}{\rtlch\fcs1 \af0 \ltrch\fcs0 \cs187\ul\cf2\lang1024\langfe1024\noproof }{\rtlch\fcs1 \af0 \ltrch\fcs0 \cs187\ul\cf2\lang1024\langfe1024\noproof {\*\datafield 08d0c9ea79f9bace118c8200aa004ba90b02000000080000000d0000005f0054006f00630033003600340035003600350034003700000000d400}} }{\fldrslt {\rtlch\fcs1 \af0 \ltrch\fcs0 \cs187\b\ul\cf2\lang1024\langfe1024\noproof V2.3.2.0 (18-Oct-2015)}{\rtlch\fcs1 \af44 \ltrch\fcs0 \lang1024\langfe1024\noproof\webhidden \tab }{\field{\*\fldinst {\rtlch\fcs1 \af44 \ltrch\fcs0 \lang1024\langfe1024\noproof\webhidden PAGEREF _Toc36456547 \\h }{\rtlch\fcs1 \af44 \ltrch\fcs0 \lang1024\langfe1024\noproof\webhidden {\*\datafield 08d0c9ea79f9bace118c8200aa004ba90b02000000080000000d0000005f0054006f006300330036003400350036003500340037000000007f00}}}{\fldrslt {\rtlch\fcs1 \af44 \ltrch\fcs0 \lang1024\langfe1024\noproof\webhidden 12}}}\sectd \ltrsect\rtlgutter \psz1\linex0\endnhere\pgbrdropt32\sectdefaultcl\sectrsid6896082\sftnbj }}\sectd \ltrsect\rtlgutter\psz1\linex0\endnhere\pgbrdropt32\sectdefaultcl\sectrsid6896082\sftnbj {\rtlch\fcs1 \af0\afs22 \ltrch\fcs0 \fs22\lang1024\langfe1024\loch\af31506\hich\af31506\dbch\af31505\noproof \par }{\field\fldedit{\*\fldinst {\rtlch\fcs1 \af0 \ltrch\fcs0 \cs187\ul\cf2\lang1024\langfe1024\noproof }{\rtlch\fcs1 \af44 \ltrch\fcs0 \lang1024\langfe1024\noproof HYPERLINK \\l "_Toc36456548"}{\rtlch\fcs1 \af0 \ltrch\fcs0 \cs187\ul\cf2\lang1024\langfe1024\noproof }{\rtlch\fcs1 \af0 \ltrch\fcs0 \cs187\ul\cf2\lang1024\langfe1024\noproof {\*\datafield 08d0c9ea79f9bace118c8200aa004ba90b02000000080000000d0000005f0054006f006300330036003400350036003500340038000000006820}} }{\fldrslt {\rtlch\fcs1 \af0 \ltrch\fcs0 \cs187\b\ul\cf2\lang1024\langfe1024\noproof V2.3.1.2 (13-Sep-2015)}{\rtlch\fcs1 \af44 \ltrch\fcs0 \lang1024\langfe1024\noproof\webhidden \tab }{\field{\*\fldinst {\rtlch\fcs1 \af44 \ltrch\fcs0 \lang1024\langfe1024\noproof\webhidden PAGEREF _Toc36456548 \\h }{\rtlch\fcs1 \af44 \ltrch\fcs0 \lang1024\langfe1024\noproof\webhidden {\*\datafield 08d0c9ea79f9bace118c8200aa004ba90b02000000080000000d0000005f0054006f006300330036003400350036003500340038000000006475}}}{\fldrslt {\rtlch\fcs1 \af44 \ltrch\fcs0 \lang1024\langfe1024\noproof\webhidden 13}}}\sectd \ltrsect\rtlgutter \psz1\linex0\endnhere\pgbrdropt32\sectdefaultcl\sectrsid6896082\sftnbj }}\sectd \ltrsect\rtlgutter\psz1\linex0\endnhere\pgbrdropt32\sectdefaultcl\sectrsid6896082\sftnbj {\rtlch\fcs1 \af0\afs22 \ltrch\fcs0 \fs22\lang1024\langfe1024\loch\af31506\hich\af31506\dbch\af31505\noproof \par }{\field\fldedit{\*\fldinst {\rtlch\fcs1 \af0 \ltrch\fcs0 \cs187\ul\cf2\lang1024\langfe1024\noproof }{\rtlch\fcs1 \af44 \ltrch\fcs0 \lang1024\langfe1024\noproof HYPERLINK \\l "_Toc36456549"}{\rtlch\fcs1 \af0 \ltrch\fcs0 \cs187\ul\cf2\lang1024\langfe1024\noproof }{\rtlch\fcs1 \af0 \ltrch\fcs0 \cs187\ul\cf2\lang1024\langfe1024\noproof {\*\datafield 08d0c9ea79f9bace118c8200aa004ba90b02000000080000000d0000005f0054006f006300330036003400350036003500340039000000006f33}} }{\fldrslt {\rtlch\fcs1 \af0 \ltrch\fcs0 \cs187\b\ul\cf2\lang1024\langfe1024\noproof V2.3.1.1 (27-Aug-2015)}{\rtlch\fcs1 \af44 \ltrch\fcs0 \lang1024\langfe1024\noproof\webhidden \tab }{\field{\*\fldinst {\rtlch\fcs1 \af44 \ltrch\fcs0 \lang1024\langfe1024\noproof\webhidden PAGEREF _Toc36456549 \\h }{\rtlch\fcs1 \af44 \ltrch\fcs0 \lang1024\langfe1024\noproof\webhidden {\*\datafield 08d0c9ea79f9bace118c8200aa004ba90b02000000080000000d0000005f0054006f006300330036003400350036003500340039000000006700}}}{\fldrslt {\rtlch\fcs1 \af44 \ltrch\fcs0 \lang1024\langfe1024\noproof\webhidden 13}}}\sectd \ltrsect\rtlgutter \psz1\linex0\endnhere\pgbrdropt32\sectdefaultcl\sectrsid6896082\sftnbj }}\sectd \ltrsect\rtlgutter\psz1\linex0\endnhere\pgbrdropt32\sectdefaultcl\sectrsid6896082\sftnbj {\rtlch\fcs1 \af0\afs22 \ltrch\fcs0 \fs22\lang1024\langfe1024\loch\af31506\hich\af31506\dbch\af31505\noproof \par }{\field\fldedit{\*\fldinst {\rtlch\fcs1 \af0 \ltrch\fcs0 \cs187\ul\cf2\lang1024\langfe1024\noproof }{\rtlch\fcs1 \af44 \ltrch\fcs0 \lang1024\langfe1024\noproof HYPERLINK \\l "_Toc36456550"}{\rtlch\fcs1 \af0 \ltrch\fcs0 \cs187\ul\cf2\lang1024\langfe1024\noproof }{\rtlch\fcs1 \af0 \ltrch\fcs0 \cs187\ul\cf2\lang1024\langfe1024\noproof {\*\datafield 08d0c9ea79f9bace118c8200aa004ba90b02000000080000000d0000005f0054006f006300330036003400350036003500350030000000006772}} }{\fldrslt {\rtlch\fcs1 \af0 \ltrch\fcs0 \cs187\b\ul\cf2\lang1024\langfe1024\noproof V2.3.1.0 (13-Mar-2015)}{\rtlch\fcs1 \af44 \ltrch\fcs0 \lang1024\langfe1024\noproof\webhidden \tab }{\field{\*\fldinst {\rtlch\fcs1 \af44 \ltrch\fcs0 \lang1024\langfe1024\noproof\webhidden PAGEREF _Toc36456550 \\h }{\rtlch\fcs1 \af44 \ltrch\fcs0 \lang1024\langfe1024\noproof\webhidden {\*\datafield 08d0c9ea79f9bace118c8200aa004ba90b02000000080000000d0000005f0054006f00630033003600340035003600350035003000000000732d}}}{\fldrslt {\rtlch\fcs1 \af44 \ltrch\fcs0 \lang1024\langfe1024\noproof\webhidden 13}}}\sectd \ltrsect\rtlgutter \psz1\linex0\endnhere\pgbrdropt32\sectdefaultcl\sectrsid6896082\sftnbj }}\sectd \ltrsect\rtlgutter\psz1\linex0\endnhere\pgbrdropt32\sectdefaultcl\sectrsid6896082\sftnbj {\rtlch\fcs1 \af0\afs22 \ltrch\fcs0 \fs22\lang1024\langfe1024\loch\af31506\hich\af31506\dbch\af31505\noproof \par }{\field\fldedit{\*\fldinst {\rtlch\fcs1 \af0 \ltrch\fcs0 \cs187\ul\cf2\lang1024\langfe1024\noproof }{\rtlch\fcs1 \af44 \ltrch\fcs0 \lang1024\langfe1024\noproof HYPERLINK \\l "_Toc36456551"}{\rtlch\fcs1 \af0 \ltrch\fcs0 \cs187\ul\cf2\lang1024\langfe1024\noproof }{\rtlch\fcs1 \af0 \ltrch\fcs0 \cs187\ul\cf2\lang1024\langfe1024\noproof {\*\datafield 08d0c9ea79f9bace118c8200aa004ba90b02000000080000000d0000005f0054006f00630033003600340035003600350035003100000000676e}} }{\fldrslt {\rtlch\fcs1 \af0 \ltrch\fcs0 \cs187\b\ul\cf2\lang1024\langfe1024\noproof V2.3.0.6 (30-Oct-2014)}{\rtlch\fcs1 \af44 \ltrch\fcs0 \lang1024\langfe1024\noproof\webhidden \tab }{\field{\*\fldinst {\rtlch\fcs1 \af44 \ltrch\fcs0 \lang1024\langfe1024\noproof\webhidden PAGEREF _Toc36456551 \\h }{\rtlch\fcs1 \af44 \ltrch\fcs0 \lang1024\langfe1024\noproof\webhidden {\*\datafield 08d0c9ea79f9bace118c8200aa004ba90b02000000080000000d0000005f0054006f006300330036003400350036003500350031000000006754}}}{\fldrslt {\rtlch\fcs1 \af44 \ltrch\fcs0 \lang1024\langfe1024\noproof\webhidden 13}}}\sectd \ltrsect\rtlgutter \psz1\linex0\endnhere\pgbrdropt32\sectdefaultcl\sectrsid6896082\sftnbj }}\sectd \ltrsect\rtlgutter\psz1\linex0\endnhere\pgbrdropt32\sectdefaultcl\sectrsid6896082\sftnbj {\rtlch\fcs1 \af0\afs22 \ltrch\fcs0 \fs22\lang1024\langfe1024\loch\af31506\hich\af31506\dbch\af31505\noproof \par }{\field\fldedit{\*\fldinst {\rtlch\fcs1 \af0 \ltrch\fcs0 \cs187\ul\cf2\lang1024\langfe1024\noproof }{\rtlch\fcs1 \af44 \ltrch\fcs0 \lang1024\langfe1024\noproof HYPERLINK \\l "_Toc36456552"}{\rtlch\fcs1 \af0 \ltrch\fcs0 \cs187\ul\cf2\lang1024\langfe1024\noproof }{\rtlch\fcs1 \af0 \ltrch\fcs0 \cs187\ul\cf2\lang1024\langfe1024\noproof {\*\datafield 08d0c9ea79f9bace118c8200aa004ba90b02000000080000000d0000005f0054006f006300330036003400350036003500350032000000000030}} }{\fldrslt {\rtlch\fcs1 \af0 \ltrch\fcs0 \cs187\b\ul\cf2\lang1024\langfe1024\noproof V2.3.0.5 (19-Oct-2014)}{\rtlch\fcs1 \af44 \ltrch\fcs0 \lang1024\langfe1024\noproof\webhidden \tab }{\field{\*\fldinst {\rtlch\fcs1 \af44 \ltrch\fcs0 \lang1024\langfe1024\noproof\webhidden PAGEREF _Toc36456552 \\h }{\rtlch\fcs1 \af44 \ltrch\fcs0 \lang1024\langfe1024\noproof\webhidden {\*\datafield 08d0c9ea79f9bace118c8200aa004ba90b02000000080000000d0000005f0054006f006300330036003400350036003500350032000000005800}}}{\fldrslt {\rtlch\fcs1 \af44 \ltrch\fcs0 \lang1024\langfe1024\noproof\webhidden 14}}}\sectd \ltrsect\rtlgutter \psz1\linex0\endnhere\pgbrdropt32\sectdefaultcl\sectrsid6896082\sftnbj }}\sectd \ltrsect\rtlgutter\psz1\linex0\endnhere\pgbrdropt32\sectdefaultcl\sectrsid6896082\sftnbj {\rtlch\fcs1 \af0\afs22 \ltrch\fcs0 \fs22\lang1024\langfe1024\loch\af31506\hich\af31506\dbch\af31505\noproof \par }{\field\fldedit{\*\fldinst {\rtlch\fcs1 \af0 \ltrch\fcs0 \cs187\ul\cf2\lang1024\langfe1024\noproof }{\rtlch\fcs1 \af44 \ltrch\fcs0 \lang1024\langfe1024\noproof HYPERLINK \\l "_Toc36456553"}{\rtlch\fcs1 \af0 \ltrch\fcs0 \cs187\ul\cf2\lang1024\langfe1024\noproof }{\rtlch\fcs1 \af0 \ltrch\fcs0 \cs187\ul\cf2\lang1024\langfe1024\noproof {\*\datafield 08d0c9ea79f9bace118c8200aa004ba90b02000000080000000d0000005f0054006f00630033003600340035003600350035003300000000b000}} }{\fldrslt {\rtlch\fcs1 \af0 \ltrch\fcs0 \cs187\b\ul\cf2\lang1024\langfe1024\noproof V2.3.0.4 (13-Oct-2014)}{\rtlch\fcs1 \af44 \ltrch\fcs0 \lang1024\langfe1024\noproof\webhidden \tab }{\field{\*\fldinst {\rtlch\fcs1 \af44 \ltrch\fcs0 \lang1024\langfe1024\noproof\webhidden PAGEREF _Toc36456553 \\h }{\rtlch\fcs1 \af44 \ltrch\fcs0 \lang1024\langfe1024\noproof\webhidden {\*\datafield 08d0c9ea79f9bace118c8200aa004ba90b02000000080000000d0000005f0054006f006300330036003400350036003500350033000000000000}}}{\fldrslt {\rtlch\fcs1 \af44 \ltrch\fcs0 \lang1024\langfe1024\noproof\webhidden 14}}}\sectd \ltrsect\rtlgutter \psz1\linex0\endnhere\pgbrdropt32\sectdefaultcl\sectrsid6896082\sftnbj }}\sectd \ltrsect\rtlgutter\psz1\linex0\endnhere\pgbrdropt32\sectdefaultcl\sectrsid6896082\sftnbj {\rtlch\fcs1 \af0\afs22 \ltrch\fcs0 \fs22\lang1024\langfe1024\loch\af31506\hich\af31506\dbch\af31505\noproof \par }{\field\fldedit{\*\fldinst {\rtlch\fcs1 \af0 \ltrch\fcs0 \cs187\ul\cf2\lang1024\langfe1024\noproof }{\rtlch\fcs1 \af44 \ltrch\fcs0 \lang1024\langfe1024\noproof HYPERLINK \\l "_Toc36456554"}{\rtlch\fcs1 \af0 \ltrch\fcs0 \cs187\ul\cf2\lang1024\langfe1024\noproof }{\rtlch\fcs1 \af0 \ltrch\fcs0 \cs187\ul\cf2\lang1024\langfe1024\noproof {\*\datafield 08d0c9ea79f9bace118c8200aa004ba90b02000000080000000d0000005f0054006f006300330036003400350036003500350034000000004800}} }{\fldrslt {\rtlch\fcs1 \af0 \ltrch\fcs0 \cs187\b\ul\cf2\lang1024\langfe1024\noproof V2.2.0 (11-Jul-2014)}{\rtlch\fcs1 \af44 \ltrch\fcs0 \lang1024\langfe1024\noproof\webhidden \tab }{\field{\*\fldinst {\rtlch\fcs1 \af44 \ltrch\fcs0 \lang1024\langfe1024\noproof\webhidden PAGEREF _Toc36456554 \\h }{\rtlch\fcs1 \af44 \ltrch\fcs0 \lang1024\langfe1024\noproof\webhidden {\*\datafield 08d0c9ea79f9bace118c8200aa004ba90b02000000080000000d0000005f0054006f006300330036003400350036003500350034000000006f01}}}{\fldrslt {\rtlch\fcs1 \af44 \ltrch\fcs0 \lang1024\langfe1024\noproof\webhidden 15}}}\sectd \ltrsect\rtlgutter \psz1\linex0\endnhere\pgbrdropt32\sectdefaultcl\sectrsid6896082\sftnbj }}\sectd \ltrsect\rtlgutter\psz1\linex0\endnhere\pgbrdropt32\sectdefaultcl\sectrsid6896082\sftnbj {\rtlch\fcs1 \af0\afs22 \ltrch\fcs0 \fs22\lang1024\langfe1024\loch\af31506\hich\af31506\dbch\af31505\noproof \par }{\field\fldedit{\*\fldinst {\rtlch\fcs1 \af0 \ltrch\fcs0 \cs187\ul\cf2\lang1024\langfe1024\noproof }{\rtlch\fcs1 \af44 \ltrch\fcs0 \lang1024\langfe1024\noproof HYPERLINK \\l "_Toc36456555"}{\rtlch\fcs1 \af0 \ltrch\fcs0 \cs187\ul\cf2\lang1024\langfe1024\noproof }{\rtlch\fcs1 \af0 \ltrch\fcs0 \cs187\ul\cf2\lang1024\langfe1024\noproof {\*\datafield 08d0c9ea79f9bace118c8200aa004ba90b02000000080000000d0000005f0054006f006300330036003400350036003500350035000000004501}} }{\fldrslt {\rtlch\fcs1 \af0 \ltrch\fcs0 \cs187\b\ul\cf2\lang1024\langfe1024\noproof V2.1.0 (09-Jul-2014)}{\rtlch\fcs1 \af44 \ltrch\fcs0 \lang1024\langfe1024\noproof\webhidden \tab }{\field{\*\fldinst {\rtlch\fcs1 \af44 \ltrch\fcs0 \lang1024\langfe1024\noproof\webhidden PAGEREF _Toc36456555 \\h }{\rtlch\fcs1 \af44 \ltrch\fcs0 \lang1024\langfe1024\noproof\webhidden {\*\datafield 08d0c9ea79f9bace118c8200aa004ba90b02000000080000000d0000005f0054006f006300330036003400350036003500350035000000000f02}}}{\fldrslt {\rtlch\fcs1 \af44 \ltrch\fcs0 \lang1024\langfe1024\noproof\webhidden 15}}}\sectd \ltrsect\rtlgutter \psz1\linex0\endnhere\pgbrdropt32\sectdefaultcl\sectrsid6896082\sftnbj }}\sectd \ltrsect\rtlgutter\psz1\linex0\endnhere\pgbrdropt32\sectdefaultcl\sectrsid6896082\sftnbj {\rtlch\fcs1 \af0\afs22 \ltrch\fcs0 \fs22\lang1024\langfe1024\loch\af31506\hich\af31506\dbch\af31505\noproof \par }{\field\fldedit{\*\fldinst {\rtlch\fcs1 \af0 \ltrch\fcs0 \cs187\ul\cf2\lang1024\langfe1024\noproof }{\rtlch\fcs1 \af44 \ltrch\fcs0 \lang1024\langfe1024\noproof HYPERLINK \\l "_Toc36456556"}{\rtlch\fcs1 \af0 \ltrch\fcs0 \cs187\ul\cf2\lang1024\langfe1024\noproof }{\rtlch\fcs1 \af0 \ltrch\fcs0 \cs187\ul\cf2\lang1024\langfe1024\noproof {\*\datafield 08d0c9ea79f9bace118c8200aa004ba90b02000000080000000d0000005f0054006f00630033003600340035003600350035003600000000d403}} }{\fldrslt {\rtlch\fcs1 \af0 \ltrch\fcs0 \cs187\b\ul\cf2\lang1024\langfe1024\noproof V2.0.0 (21-May-2014)}{\rtlch\fcs1 \af44 \ltrch\fcs0 \lang1024\langfe1024\noproof\webhidden \tab }{\field{\*\fldinst {\rtlch\fcs1 \af44 \ltrch\fcs0 \lang1024\langfe1024\noproof\webhidden PAGEREF _Toc36456556 \\h }{\rtlch\fcs1 \af44 \ltrch\fcs0 \lang1024\langfe1024\noproof\webhidden {\*\datafield 08d0c9ea79f9bace118c8200aa004ba90b02000000080000000d0000005f0054006f006300330036003400350036003500350036000000007f04}}}{\fldrslt {\rtlch\fcs1 \af44 \ltrch\fcs0 \lang1024\langfe1024\noproof\webhidden 15}}}\sectd \ltrsect\rtlgutter \psz1\linex0\endnhere\pgbrdropt32\sectdefaultcl\sectrsid6896082\sftnbj }}\sectd \ltrsect\rtlgutter\psz1\linex0\endnhere\pgbrdropt32\sectdefaultcl\sectrsid6896082\sftnbj {\rtlch\fcs1 \af0\afs22 \ltrch\fcs0 \fs22\lang1024\langfe1024\loch\af31506\hich\af31506\dbch\af31505\noproof \par }{\field\fldedit{\*\fldinst {\rtlch\fcs1 \af0 \ltrch\fcs0 \cs187\ul\cf2\lang1024\langfe1024\noproof }{\rtlch\fcs1 \af44 \ltrch\fcs0 \lang1024\langfe1024\noproof HYPERLINK \\l "_Toc36456557"}{\rtlch\fcs1 \af0 \ltrch\fcs0 \cs187\ul\cf2\lang1024\langfe1024\noproof }{\rtlch\fcs1 \af0 \ltrch\fcs0 \cs187\ul\cf2\lang1024\langfe1024\noproof {\*\datafield 08d0c9ea79f9bace118c8200aa004ba90b02000000080000000d0000005f0054006f006300330036003400350036003500350037000000006800}} }{\fldrslt {\rtlch\fcs1 \af0 \ltrch\fcs0 \cs187\b\ul\cf2\lang1024\langfe1024\noproof V1.1.0 (27-Feb-2014)}{\rtlch\fcs1 \af44 \ltrch\fcs0 \lang1024\langfe1024\noproof\webhidden \tab }{\field{\*\fldinst {\rtlch\fcs1 \af44 \ltrch\fcs0 \lang1024\langfe1024\noproof\webhidden PAGEREF _Toc36456557 \\h }{\rtlch\fcs1 \af44 \ltrch\fcs0 \lang1024\langfe1024\noproof\webhidden {\*\datafield 08d0c9ea79f9bace118c8200aa004ba90b02000000080000000d0000005f0054006f006300330036003400350036003500350037000000006400}}}{\fldrslt {\rtlch\fcs1 \af44 \ltrch\fcs0 \lang1024\langfe1024\noproof\webhidden 16}}}\sectd \ltrsect\rtlgutter \psz1\linex0\endnhere\pgbrdropt32\sectdefaultcl\sectrsid6896082\sftnbj }}\sectd \ltrsect\rtlgutter\psz1\linex0\endnhere\pgbrdropt32\sectdefaultcl\sectrsid6896082\sftnbj {\rtlch\fcs1 \af0\afs22 \ltrch\fcs0 \fs22\lang1024\langfe1024\loch\af31506\hich\af31506\dbch\af31505\noproof \par }{\field\fldedit{\*\fldinst {\rtlch\fcs1 \af0 \ltrch\fcs0 \cs187\ul\cf2\lang1024\langfe1024\noproof }{\rtlch\fcs1 \af44 \ltrch\fcs0 \lang1024\langfe1024\noproof HYPERLINK \\l "_Toc36456558"}{\rtlch\fcs1 \af0 \ltrch\fcs0 \cs187\ul\cf2\lang1024\langfe1024\noproof }{\rtlch\fcs1 \af0 \ltrch\fcs0 \cs187\ul\cf2\lang1024\langfe1024\noproof {\*\datafield 08d0c9ea79f9bace118c8200aa004ba90b02000000080000000d0000005f0054006f006300330036003400350036003500350038000000006100}} }{\fldrslt {\rtlch\fcs1 \af0 \ltrch\fcs0 \cs187\b\ul\cf2\lang1024\langfe1024\noproof V1.0.0 (05-Nov-2013)}{\rtlch\fcs1 \af44 \ltrch\fcs0 \lang1024\langfe1024\noproof\webhidden \tab }{\field{\*\fldinst {\rtlch\fcs1 \af44 \ltrch\fcs0 \lang1024\langfe1024\noproof\webhidden PAGEREF _Toc36456558 \\h }{\rtlch\fcs1 \af44 \ltrch\fcs0 \lang1024\langfe1024\noproof\webhidden {\*\datafield 08d0c9ea79f9bace118c8200aa004ba90b02000000080000000d0000005f0054006f006300330036003400350036003500350038000000006700}}}{\fldrslt {\rtlch\fcs1 \af44 \ltrch\fcs0 \lang1024\langfe1024\noproof\webhidden 16}}}\sectd \ltrsect\rtlgutter \psz1\linex0\endnhere\pgbrdropt32\sectdefaultcl\sectrsid6896082\sftnbj }}\sectd \ltrsect\rtlgutter\psz1\linex0\endnhere\pgbrdropt32\sectdefaultcl\sectrsid6896082\sftnbj {\rtlch\fcs1 \af0\afs22 \ltrch\fcs0 \fs22\lang1024\langfe1024\loch\af31506\hich\af31506\dbch\af31505\noproof \par }\pard\plain \ltrpar\s98\ql \li1440\ri0\sb120\keep\keepn\widctlpar\tqr\tldot\tx9893\wrapdefault\nooverflow\faroman\rin0\lin1440\itap0 \rtlch\fcs1 \ab\af1\afs20\alang1025 \ltrch\fcs0 \b\f1\fs20\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 }} \pard\plain \ltrpar\s98\ql \li1440\ri0\sb120\keep\keepn\widctlpar\tqr\tldot\tx9893\wrapdefault\nooverflow\faroman\rin0\lin1440\itap0 \rtlch\fcs1 \ab\af1\afs20\alang1025 \ltrch\fcs0 \b\f1\fs20\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \sectd \ltrsect\rtlgutter\psz1\linex0\endnhere\pgbrdropt32\sectdefaultcl\sectrsid6896082\sftnbj {\rtlch\fcs1 \af1 \ltrch\fcs0 \f31506\cf9 {\*\bkmkstart _Toc234021027} \par }\pard\plain \ltrpar\ql \li720\ri0\sb180\widctlpar\wrapdefault\nooverflow\faroman\rin0\lin720\itap0 \rtlch\fcs1 \af44\afs20\alang1025 \ltrch\fcs0 \f44\fs20\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 {\rtlch\fcs1 \af44 \ltrch\fcs0 \f31506 \par }\pard \ltrpar\ql \li0\ri0\widctlpar\wrapdefault\nooverflow\faroman\rin0\lin0\itap0 {\rtlch\fcs1 \af50 \ltrch\fcs0 \f31506 \par }\pard \ltrpar\ql \li720\ri0\sb180\widctlpar\wrapdefault\nooverflow\faroman\rin0\lin720\itap0 {\rtlch\fcs1 \af1\afs36 \ltrch\fcs0 \b\f37\fs36\cf9 \par }\pard\plain \ltrpar\s1\ql \li90\ri0\sb720\keepn\widctlpar\brdrt\brdrs\brdrw30\brsp120 \wrapdefault\nooverflow\faroman\outlinelevel0\rin0\lin90\itap0 \rtlch\fcs1 \ab\af1\afs36\alang1025 \ltrch\fcs0 \b\f1\fs36\cf9\lang1024\langfe1024\cgrid\noproof\langnp1033\langfenp1033 {\rtlch\fcs1 \af1 \ltrch\fcs0 \b0\f37 \page }{\rtlch\fcs1 \af1 \ltrch\fcs0 \f37\noproof0 {\*\bkmkstart _Toc36456524}Purpose{\*\bkmkend _Toc36456524} \par }\pard\plain \ltrpar\ql \li1440\ri0\sb180\widctlpar\wrapdefault\nooverflow\faroman\rin0\lin1440\itap0 \rtlch\fcs1 \af44\afs20\alang1025 \ltrch\fcs0 \f44\fs20\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 {\rtlch\fcs1 \af44\afs22 \ltrch\fcs0 \f37\fs22 This document serves as a brief introduction to the TWAIN CS projects. It assumes familiarity with the C# programming language, and a basic understanding of the TWAIN Specification. \par The version number supplied in the title is a guide to when the document wa s last modified. TWAIN supports feature negotiated interoperability between all versions of TWAIN enabled applications, TWAIN drivers (data sources), and the TWAIN Data Source Manager. \par }{\rtlch\fcs1 \af44 \ltrch\fcs0 \f37 \par }\pard\plain \ltrpar\s1\ql \li0\ri0\sb720\keepn\widctlpar\brdrt\brdrs\brdrw30\brsp120 \wrapdefault\nooverflow\faroman\outlinelevel0\rin0\lin0\itap0 \rtlch\fcs1 \ab\af1\afs36\alang1025 \ltrch\fcs0 \b\f1\fs36\cf9\lang1024\langfe1024\cgrid\noproof\langnp1033\langfenp1033 {\rtlch\fcs1 \af1 \ltrch\fcs0 \f37 {\*\bkmkstart _Toc36456525}License{\*\bkmkend _Toc36456525} \par }\pard\plain \ltrpar\ql \li1440\ri0\widctlpar\wrapdefault\faauto\rin0\lin1440\itap0 \rtlch\fcs1 \af44\afs20\alang1025 \ltrch\fcs0 \f44\fs20\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 {\rtlch\fcs1 \af49 \ltrch\fcs0 \f37 \par }{\rtlch\fcs1 \af49\afs22 \ltrch\fcs0 \f37\fs22 Copyright (C) 2013-2020 Kodak Alaris Inc. \par \par Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, mod ify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: \par \par The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. \par \par THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. \par }\pard \ltrpar\ql \li720\ri0\sb180\keep\keepn\widctlpar\wrapdefault\nooverflow\faroman\rin0\lin720\itap0 {\rtlch\fcs1 \af1\afs36 \ltrch\fcs0 \b\f37\fs36\cf9 \par }\pard \ltrpar\ql \li720\ri0\widctlpar\wrapdefault\nooverflow\faroman\rin0\lin720\itap0 {\rtlch\fcs1 \af50 \ltrch\fcs0 \f31506 \par }\pard\plain \ltrpar\s189\ql \li0\ri0\keepn\pagebb\widctlpar\brdrt\brdrs\brdrw30\brsp120 \wrapdefault\nooverflow\faroman\outlinelevel0\rin0\lin0\itap0 \rtlch\fcs1 \ab\af1\afs24\alang1025 \ltrch\fcs0 \b\f1\fs24\cf9\lang1024\langfe1024\cgrid\noproof\langnp1033\langfenp1033 {\rtlch\fcs1 \af1\afs36 \ltrch\fcs0 \f31506\fs36\noproof0 {\*\bkmkstart _Toc36456526}Project Repository{\*\bkmkend _Toc36456526} \par }\pard\plain \ltrpar\ql \li0\ri0\widctlpar\wrapdefault\nooverflow\faroman\rin0\lin0\itap0 \rtlch\fcs1 \af44\afs20\alang1025 \ltrch\fcs0 \f44\fs20\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 {\rtlch\fcs1 \af0 \ltrch\fcs0 \v\f31506\cf6 \par }\pard\plain \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 \rtlch\fcs1 \af37\afs22\alang1025 \ltrch\fcs0 \f37\fs22\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 {\rtlch\fcs1 \af0 \ltrch\fcs0 \v\f31506\cf6 [Technical Notes]}{\rtlch\fcs1 \af0\afs20 \ltrch\fcs0 \i\v\f31506\fs20\cf6 \par }{\rtlch\fcs1 \af37 \ltrch\fcs0 \i\v\f31506\cf6 I think we made a mistake here. All of the capabilities that use TW_ARRAY containers only show TW_ONEVALUE as the valid container for MSG_SET. It should be TW_ONEVALUE and TW_ARRAY. \par }{\rtlch\fcs1 \af37 \ltrch\fcs0 \i\f31506\cf6 \par }{\rtlch\fcs1 \af37 \ltrch\fcs0 \f31506 TWAIN for C-Sharp (C#) resides on GitHub at }{\field{\*\fldinst {\rtlch\fcs1 \af37 \ltrch\fcs0 HYPERLINK "https://github.com/twain/twain-cs" }{\rtlch\fcs1 \af37 \ltrch\fcs0 {\*\datafield 00d0c9ea79f9bace118c8200aa004ba90b0200000003000000e0c9ea79f9bace118c8200aa004ba90b5c000000680074007400700073003a002f002f006700690074006800750062002e0063006f006d002f0074007700610069006e002f0074007700610069006e002d00630073000000795881f43b1d7f48af2c825dc485 276300000000a5ab00030000001500ef00}}}{\fldrslt {\rtlch\fcs1 \af37 \ltrch\fcs0 \cs187\ul\cf2 https://github.com/twain/twain-cs}}}\sectd \ltrsect\rtlgutter\psz1\linex0\endnhere\pgbrdropt32\sectdefaultcl\sectrsid6896082\sftnbj {\rtlch\fcs1 \af37 \ltrch\fcs0 \f31506 . \par }{\rtlch\fcs1 \af37 \ltrch\fcs0 \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\outlinelevel1\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 \b\ul {\*\bkmkstart _Toc36456527}Installation{\*\bkmkend _Toc36456527} \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 \par There is a releases folder that contains release and debug copies of the binaries. There is no installation kit, just run them as-is. If running on Linux or macOS it may be necessary to install or upgrade Mono to v4.8 or higher. The certification tool automatically creates a \lquote TWAIN Self Certification\rquote folder on the user\rquote s desktop, which contains all the stuff needed for certification. \par \par \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\outlinelevel1\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 \b\ul {\*\bkmkstart _Toc36456528}Versioning{\*\bkmkend _Toc36456528} \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 \f31506 \par The versioning scheme takes the form: TWAIN-ProtocolMajor.TWAIN-ProtocolMinor.Interface.Build \par \par If the TWAIN Specification is at 2.3 then the version will be 2.3.i.b. This is for notational purposes only, TWAIN interoperates at all versions of the protocol, so there is no requirement that a developer has to use any specific version, or i mmediately upgrade if there is a change to the TWAIN Specification. \par \par The interface number rises if there is a modification to the TWAINCS or TWAINCSToolkit that requires a code change in TWAINCSTest or TWAINCSScan. For instance, adding a new argument to t he ReportImage function. This lets a developer know that downloading the new version will most likely require some work in their code before they can use it. This assumption always applies when the TWAIN Specification changes, so the interface number re sets to 0 when they are modified. \par \par The build number tracks releases for a given version of the TWAIN Specification, and always rises until a new version of the spec is adopted. \par \par So, for example (fictitious sequence, just to show how it works): \par \par 2.3.0.0 \endash initial release to go with TWAIN 2.3 \par 2.3.0.1 \endash bug fix \par 2.3.0.2 \endash bug fix \par 2.3.1.3 \endash interface change \par 2.3.1.4 \endash bug fix \par 2.4.0.0 \endash initial release to go with TWAIN 2.4 \par \par }\pard\plain \ltrpar\s189\ql \li0\ri0\keepn\pagebb\widctlpar\brdrt\brdrs\brdrw30\brsp120 \wrapdefault\nooverflow\faroman\outlinelevel0\rin0\lin0\itap0 \rtlch\fcs1 \ab\af1\afs24\alang1025 \ltrch\fcs0 \b\f1\fs24\cf9\lang1024\langfe1024\cgrid\noproof\langnp1033\langfenp1033 {\rtlch\fcs1 \af1\afs36 \ltrch\fcs0 \f31506\fs36\noproof0 {\*\bkmkstart _Toc36456529}Project Layout{\*\bkmkend _Toc36456529} \par }\pard\plain \ltrpar\ql \li0\ri0\widctlpar\wrapdefault\nooverflow\faroman\rin0\lin0\itap0 \rtlch\fcs1 \af44\afs20\alang1025 \ltrch\fcs0 \f44\fs20\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 {\rtlch\fcs1 \af0 \ltrch\fcs0 \v\f31506\cf6 \par }\pard\plain \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 \rtlch\fcs1 \af37\afs22\alang1025 \ltrch\fcs0 \f37\fs22\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 {\rtlch\fcs1 \af0 \ltrch\fcs0 \v\f31506\cf6 [Technical Notes]}{\rtlch\fcs1 \af0\afs20 \ltrch\fcs0 \i\v\f31506\fs20\cf6 \par }{\rtlch\fcs1 \af37 \ltrch\fcs0 \i\v\f31506\cf6 I think we made a mistake here. All of the capabilities that use TW_ARRAY containers only show TW_ONEVALUE as the valid container for MSG_SET. It should be TW_ONEVALUE and TW_ARRAY. \par }{\rtlch\fcs1 \af37 \ltrch\fcs0 \i\f31506\cf6 \par }\pard \ltrpar\s199\ql \li360\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin360\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 \f31506 There are five projects in the TWAIN CS repository, with a single solution file to access them all: \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22 \hich\af37\dbch\af0\loch\f37 -\tab}}\pard \ltrpar\s199\ql \fi-360\li720\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\ls22\adjustright\rin0\lin720\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 \f31506 Basic TWAIN C# Definitions and Helper Functions \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22 \hich\af37\dbch\af0\loch\f37 -\tab}A TWAIN C# Toolkit \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22 \hich\af37\dbch\af0\loch\f37 -\tab}A TWAIN C# Diagnostic Application \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22 \hich\af37\dbch\af0\loch\f37 -\tab}A TWAIN C# Sample Application \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22 \hich\af37\dbch\af0\loch\f37 -\tab}}{\rtlch\fcs1 \af37 \ltrch\fcs0 A TWAIN C# Self Certification Application \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 \f31506 \par }\pard \ltrpar\s199\ql \li360\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin360\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 \f31506 The toolkit references the base definitions, and the applications reference the toolkit (with the exception of of the Certification app). This is done to maximize the amount of shared code within the repository, and to allow for the seamless addition of new projects. \par \par The toolkit seemed like a good idea once. However, after writing the Certification tool the basic functions are so completely developed that a strong case can be made for accessing them directly. If interested in doing that, then base any code on the Ce rtification tool instead of the Sample application. \par \par Application writers must not assume that these references will remain stable. They will not be versioned. The projects will be updated as needed, resulting in assemblies that are not compatible with prior releases. \par \par It\rquote s assumed that application writers will opt to pull this source code into a single assembly, the most common selection being the basic definitions, the toolkit and the sample application. Updates will be accomplished by pulling in newer v ersions of these files. Updates will typically come from the basic definitions and the toolkit. \par \par If you decide to keep the items as separate projects, then make a note of the inside of each of the .csproj files. Replacing the platform\\configuration folder names with }{\rtlch\fcs1 \af37 \ltrch\fcs0 $(Platform)\\ $(Configuration) makes for a much better build experience, since the references correctly track to the current settings. \par }{\rtlch\fcs1 \af37 \ltrch\fcs0 \f31506 \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 \f31506 \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\outlinelevel1\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 \b\f31506\ul {\*\bkmkstart _Toc36456530}Basic TWAIN C# Definitions and Helper Functions {\*\bkmkend _Toc36456530} \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af0 \ltrch\fcs0 \f31506 \par }\pard \ltrpar\s199\ql \li360\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin360\itap0 {\rtlch\fcs1 \af0 \ltrch\fcs0 \f31506 TWAINH.CS contains all o f the C/C++ TWAIN.H definitions for the version of TWAIN referenced on the title page of this document. \par \par TWAIN.CS contains helper functions designed to hide platform specific details, and to promote best practices when interfacing with the TWAIN Data Source Manager and TWAIN drivers. Best practices cover a few areas: \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af0\afs22 \ltrch\fcs0 \f37\fs22 \hich\af37\dbch\af0\loch\f37 -\tab}}\pard \ltrpar\s199\ql \fi-360\li720\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\ls22\adjustright\rin0\lin720\itap0 {\rtlch\fcs1 \af0 \ltrch\fcs0 \f31506 Funnel all commands through a single thread \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af0\afs22 \ltrch\fcs0 \f37\fs22 \hich\af37\dbch\af0\loch\f37 -\tab}Automatically collect the condition code when TWRC.Failure is detected \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af0\afs22 \ltrch\fcs0 \f37\fs22 \hich\af37\dbch\af0\loch\f37 -\tab}Automatically resynchronize the TWAIN state if a sequence error is detected \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af0\afs22 \ltrch\fcs0 \f37\fs22 \hich\af37\dbch\af0\loch\f37 -\tab}Provide ways to acess the data through CSV strings \par }\pard \ltrpar\s199\ql \li360\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin360\itap0 {\rtlch\fcs1 \af0 \ltrch\fcs0 \f31506 \par Both files expose their functionality through the TWAIN class in the TWAINWorkingGroup namespace. \par \par \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 \f31506 \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\outlinelevel1\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 \b\f31506\ul {\*\bkmkstart _Toc36456531}A TWAIN C# Toolkit{\*\bkmkend _Toc36456531} \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af0 \ltrch\fcs0 \f31506 \par }\pard \ltrpar\s199\ql \li360\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin360\itap0 {\rtlch\fcs1 \af0 \ltrch\fcs0 \f31506 The TWAIN C# Toolkit references TWAIN. This toolkit isn\rquote t as comprehensive as some designed for C/C++, which aim to hide much of the complexity of TWAIN. Instead, this toolkit addresses two main concerns: the data marshaling challenges of using a C/C++ API with C#, and the complexities of the scan loop. \par \par Honestly, it\rquote s a bit of a mess. Especially the ScanCallback function. Give serious consideration to skipping it, using the TWAIN Cerification tool as a better template for code development. At some point I\rquote ll make another project to demonstrate that. \par \par TWAIN depends upon C/C++ structures and pointers for communication bet ween the application and the driver. The TWAIN C# Toolkit addresses this by translating data into CSV strings. These strings follow the format of the TWAIN structures (position and type), but are rendered as text. This makes it relatively easy for a ca ller to get and set data, while still fully operating within the TWAIN name and number space. \par \par The TWAIN C# Diagnostic Application presents and consumes CSV data in its user interface, so it\rquote s easiest to see this system in action there, it can be used as a test bed when seeking to understand how to construct CSV strings to send to the driver. The TWAIN C# Sample Application also uses CSV to examine data, and to set capabilities, but does so programmatically instead of through a user interface. It helps to have access to a copy of TWAINH.CS handy when looking at the CSV data. \par \par The scan loop is the second main issue most applications run into. The loop runs inside of the TWAIN thread using callbacks to give the application access to the images and metadata r eturned by the TWAIN driver. This reduces that amount of code an application needs without sacrificing access to the full set of supported ICAP_XFERMECH transfer options. It also guarantees the responsiveness of the application, since operations never i mpede the windowing message loop. \par \par Assuming a well-behaved TWAIN driver, the application user is able to gracefully exit from the application at any time they choose, even in the middle of scanning. \par \par This TWAIN Toolkit exposes its functionality through the TWAINCSToolkit class in the TWAINWorkingGroupToolkit namespace. \par \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 \f31506 \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\outlinelevel1\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 \b\f31506\ul {\*\bkmkstart _Toc36456532}A TWAIN C# Diagnostic Application{\*\bkmkend _Toc36456532} \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af0 \ltrch\fcs0 \f31506 \par }\pard \ltrpar\s199\ql \li360\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin360\itap0 {\rtlch\fcs1 \af0 \ltrch\fcs0 \f31506 This application references TWAINCSToolkit. The code is not intended as seed code for applications. It is a comprehensive fronten d to the TWAIN API. It allows the selection of any combination of TWAIN triplets, including ones that are illegal or are out of sequence with the current TWAIN state. It is best compared to the TWACKER application, which has long been the main way to ex ercise TWAIN drivers on Microsoft Windows systems. \par \par Data is presented and consumed in the form of CSV strings. Familiarity with the various TWAIN structures is essential, since these strings do not include self-referential metadata, aside from the content described by the TWAIN Specification. As mentioned above, }{\rtlch\fcs1 \af0 \ltrch\fcs0 it helps to have access to a copy of TWAINH.CS handy when looking at the CSV data.}{\rtlch\fcs1 \af0 \ltrch\fcs0 \f31506 \par \par The application tries to reduce mouse clicks for some common operations. For instance, upon successful completio n of the DG_CONTROL / DAT_PARENT / MSG_OPENDSM operation, the dropdown values are set to DG_CONTROL / DAT_IDENTITY / MSG_GETFIRST, to enumerate the first TWAIN driver in the list of drivers. After a few uses it\rquote ll be apparent when the application is trying to help. \par \par A @-command system has been added. It doesn\rquote t do much at the moment, but it could be expanded to allow for more complex behavior. For instance, some kind of scripting system that would allow the diagnostic tool to help with automated tests. It becomes available after opening a DSM. Type @help in the text box and press the Send button to get the list of supported commands. \par \par \par \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 \f31506 \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\outlinelevel1\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 \b\f31506\ul {\*\bkmkstart _Toc36456533}A TWAIN C# Sample Application{\*\bkmkend _Toc36456533} \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af0 \ltrch\fcs0 \f31506 \par }\pard \ltrpar\s199\ql \li360\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin360\itap0 {\rtlch\fcs1 \af0 \ltrch\fcs0 \f31506 This application references TWAINCSToolkit. The code is intended as seed code for applications, and demonstrates the easiest way to access the full range of functionality present in TWAIN. \par \par For TWAIN drivers that support DG_CONTROL / DAT_USERINTERFACE / MSG_ENABLEDSUIONLY and DG_CONTROL / DAT_CUSTOMDSDATA / MSG_*, the application supports a \'93snapshot\'94 system. This allows a user to configure a TWAIN driver and save its setting under a descriptive name that can be used to restore those settings prior to scanning. \par \par For drivers that don\rquote t support these operations the application defaults to the older }{\rtlch\fcs1 \af0 \ltrch\fcs0 DG_CONTROL / DAT_USERINTERFACE / MSG_ENABLEDS system, with TW_USERINTERFACE.ShowUI set to TRUE. \par \par An application writer also has the option to programmatically negotiate capabilities. The sample app doesn\rquote t show this path, but it\rquote s relatively easy to add for a small number of configurable items.}{\rtlch\fcs1 \af0 \ltrch\fcs0 \f31506 \par }{\rtlch\fcs1 \af0 \ltrch\fcs0 \par \par \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\outlinelevel1\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 \b\ul {\*\bkmkstart _Toc36456534}A TWAIN C# Self Certification Application{\*\bkmkend _Toc36456534} \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af0 \ltrch\fcs0 \par }\pard \ltrpar\s199\ql \li360\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin360\itap0 {\rtlch\fcs1 \af0 \ltrch\fcs0 This application serves three purposes. It shows a reasonably good way of interfacing with TWAIN from C#. It allows a user to interact directly with a TWAIN driver (with the aid of scripts). And it offers a way to certify that a TWAIN driver is compliant with the specification. \par \par Note that the correct binary must be run to interface with 32-bit or 64-bit drivers. This code has been tested on Windows, Linux, and Mac (the last two using Mono 4.8 or later). \par \par The tool has help built into it. It also comes with a large collection of scripts. If you use the \lquote runv\rquote command with the script, you\rquote ll get some insight into what arguments are needed for the \lquote dsmentry\rquote command. \par \par It should be a good tool for developers, allowing them to explore the kind of commands they\rquote ll need to issue from other languages, like C++. \par \par If developing with the tool, it\rquote ll use the data folder located with the binary. The release version normally defaults to the \'93TWAIN Self Certification/data\'94 folder on the desktop. \par }\pard\plain \ltrpar\ql \li0\ri0\widctlpar\wrapdefault\faauto\rin0\lin0\itap0 \rtlch\fcs1 \af44\afs20\alang1025 \ltrch\fcs0 \f44\fs20\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 {\rtlch\fcs1 \af45 \ltrch\fcs0 \f31506 \par }\pard\plain \ltrpar\s189\ql \li0\ri0\keepn\pagebb\widctlpar\brdrt\brdrs\brdrw30\brsp120 \wrapdefault\nooverflow\faroman\outlinelevel0\rin0\lin0\itap0 \rtlch\fcs1 \ab\af1\afs24\alang1025 \ltrch\fcs0 \b\f1\fs24\cf9\lang1024\langfe1024\cgrid\noproof\langnp1033\langfenp1033 {\rtlch\fcs1 \af1\afs36 \ltrch\fcs0 \f31506\fs36\noproof0 {\*\bkmkstart _Toc36456535}Release Notes{\*\bkmkend _Toc36456535} \par }\pard\plain \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 \rtlch\fcs1 \af37\afs22\alang1025 \ltrch\fcs0 \f37\fs22\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 {\rtlch\fcs1 \af37 \ltrch\fcs0 \i\cf6 \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\outlinelevel1\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 \b\ul {\*\bkmkstart _Toc36456536}V2.4.}{\rtlch\fcs1 \af37 \ltrch\fcs0 \b\ul 10}{\rtlch\fcs1 \af37 \ltrch\fcs0 \b\ul .0 (}{\rtlch\fcs1 \af37 \ltrch\fcs0 \b\ul 06}{\rtlch\fcs1 \af37 \ltrch\fcs0 \b\ul -}{\rtlch\fcs1 \af37 \ltrch\fcs0 \b\ul Jun}{\rtlch\fcs1 \af37 \ltrch\fcs0 \b\ul -2020)}{\rtlch\fcs1 \af37 \ltrch\fcs0 \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 New Features: \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22 \hich\af37\dbch\af0\loch\f37 -\tab}}\pard \ltrpar\s199\ql \fi-360\li720\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\ls22\adjustright\rin0\lin720\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 (none) \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 Bug Fixes: \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22 \hich\af37\dbch\af0\loch\f37 -\tab}}\pard \ltrpar\s199\ql \fi-360\li720\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\ls22\adjustright\rin0\lin720\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 Fixed twaincert.exe to run from the releases folder without thinking it\rquote s a development path, so it correctly creates the \lquote data\rquote folder in the \lquote }{\rtlch\fcs1 \af37 \ltrch\fcs0 TWAIN Self Certification}{ \rtlch\fcs1 \af37 \ltrch\fcs0 \rquote folder on the desktop.}{\rtlch\fcs1 \af37 \ltrch\fcs0 \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 Known Issues: \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22 \hich\af37\dbch\af0\loch\f37 -\tab}}\pard \ltrpar\s199\ql \fi-360\li720\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\ls22\adjustright\rin0\lin720\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 (none) \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 Wish List: \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22 \hich\af37\dbch\af0\loch\f37 -\tab}}\pard \ltrpar\s199\ql \fi-360\li720\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\ls22\adjustright\rin0\lin720\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 Want to switch to something other than WinForms, especially for macOS \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22 \hich\af37\dbch\af0\loch\f37 -\tab}Need to add some more certification tests, especially for things like printer, barcode, patch \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 \i\cf6 \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\outlinelevel1\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 \b\ul V2.4.9.0 (30-Apr-2020)}{\rtlch\fcs1 \af37 \ltrch\fcs0 {\*\bkmkend _Toc36456536} \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 New Features: \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22 \hich\af37\dbch\af0\loch\f37 -\tab}}\pard \ltrpar\s199\ql \fi-360\li720\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\ls22\adjustright\rin0\lin720\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 (none) \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 Bug Fixes: \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22 \hich\af37\dbch\af0\loch\f37 -\tab}}\pard \ltrpar\s199\ql \fi-360\li720\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\ls22\adjustright\rin0\lin720\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 The MSG_SET certification test was using the MSG_GET container, when the 2.4 spec states that it should only use TW_ONEVALUE or TW_ARRAY (the others being for MSG_SETCONTAINER), so that\rquote s fixed now \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22 \hich\af37\dbch\af0\loch\f37 -\tab} Fixed TWBP_* values to not return symbolic names, the support for symbolic names with TW_RANGE gets too weird too fast, staying with numbers offers fewer problems \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 Known Issues: \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22 \hich\af37\dbch\af0\loch\f37 -\tab}}\pard \ltrpar\s199\ql \fi-360\li720\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\ls22\adjustright\rin0\lin720\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 (none) \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 Wish List: \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22 \hich\af37\dbch\af0\loch\f37 -\tab}}\pard \ltrpar\s199\ql \fi-360\li720\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\ls22\adjustright\rin0\lin720\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 Want to switch to something other than WinForms, especially for macOS \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22 \hich\af37\dbch\af0\loch\f37 -\tab}Need to add some more certification tests, especially for things like printer, barcode, patch \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 \i\cf6 \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\outlinelevel1\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 \b\ul V2.4.8.0 (30-Mar-2020)}{\rtlch\fcs1 \af37 \ltrch\fcs0 \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 New Features: \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22 \hich\af37\dbch\af0\loch\f37 -\tab}}\pard \ltrpar\s199\ql \fi-360\li720\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\ls22\adjustright\rin0\lin720\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 Switched almost all of the csv functions to static \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22 \hich\af37\dbch\af0\loch\f37 -\tab}(yah, skipped 2.4.7, kinda) \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 Bug Fixes: \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22 \hich\af37\dbch\af0\loch\f37 -\tab}}\pard \ltrpar\s199\ql \fi-360\li720\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\ls22\adjustright\rin0\lin720\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 (none) \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 Known Issues: \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22 \hich\af37\dbch\af0\loch\f37 -\tab}}\pard \ltrpar\s199\ql \fi-360\li720\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\ls22\adjustright\rin0\lin720\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 (none) \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 Wish List: \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22 \hich\af37\dbch\af0\loch\f37 -\tab}}\pard \ltrpar\s199\ql \fi-360\li720\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\ls22\adjustright\rin0\lin720\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 Want to switch to something other than WinForms, especially for macOS \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22 \hich\af37\dbch\af0\loch\f37 -\tab}Need to add some more certification tests, especially for things like printer, barcode, patch \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 \i\cf6 \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\outlinelevel1\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 \b\ul {\*\bkmkstart _Toc36456537}V2.4.6.0 (26-Mar-2020)}{\rtlch\fcs1 \af37 \ltrch\fcs0 {\*\bkmkend _Toc36456537} \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 New Features: \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22 \hich\af37\dbch\af0\loch\f37 -\tab}}\pard \ltrpar\s199\ql \fi-360\li720\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\ls22\adjustright\rin0\lin720\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 (none) \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 Bug Fixes: \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22 \hich\af37\dbch\af0\loch\f37 -\tab}}\pard \ltrpar\s199\ql \fi-360\li720\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\ls22\adjustright\rin0\lin720\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 MSG_XFERREADY wasn\rquote t being handled properly if ShowUI was TRUE \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 Known Issues: \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22 \hich\af37\dbch\af0\loch\f37 -\tab}}\pard \ltrpar\s199\ql \fi-360\li720\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\ls22\adjustright\rin0\lin720\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 (none) \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 Wish List: \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22 \hich\af37\dbch\af0\loch\f37 -\tab}}\pard \ltrpar\s199\ql \fi-360\li720\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\ls22\adjustright\rin0\lin720\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 Want to switch to something other than WinForms, especially for macOS \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22 \hich\af37\dbch\af0\loch\f37 -\tab}Need to add some more certification tests, especially for things like printer, barcode, patch \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\outlinelevel1\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 \b\ul {\*\bkmkstart _Toc36456538}V2.4.5.0 (24-Mar-2020)}{\rtlch\fcs1 \af37 \ltrch\fcs0 {\*\bkmkend _Toc36456538} \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 New Features: \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22 \hich\af37\dbch\af0\loch\f37 -\tab}}\pard \ltrpar\s199\ql \fi-360\li720\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\ls22\adjustright\rin0\lin720\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 (none) \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 Bug Fixes: \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22 \hich\af37\dbch\af0\loch\f37 -\tab}}\pard \ltrpar\s199\ql \fi-360\li720\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\ls22\adjustright\rin0\lin720\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 Stupid data folder wasn\rquote t being properly created (grrr) \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 Known Issues: \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22 \hich\af37\dbch\af0\loch\f37 -\tab}}\pard \ltrpar\s199\ql \fi-360\li720\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\ls22\adjustright\rin0\lin720\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 (none) \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 Wish List: \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22 \hich\af37\dbch\af0\loch\f37 -\tab}}\pard \ltrpar\s199\ql \fi-360\li720\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\ls22\adjustright\rin0\lin720\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 Want to switch to something other than WinForms, especially for macOS \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22 \hich\af37\dbch\af0\loch\f37 -\tab}Need to add some more certification tests, especially for things like printer, barcode, patch \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 \i\cf6 \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\outlinelevel1\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 \b\ul {\*\bkmkstart _Toc36456539}V2.4.4.0 (24-Mar-2020)}{\rtlch\fcs1 \af37 \ltrch\fcs0 {\*\bkmkend _Toc36456539} \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 New Features: \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22 \hich\af37\dbch\af0\loch\f37 -\tab}}\pard \ltrpar\s199\ql \fi-360\li720\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\ls22\adjustright\rin0\lin720\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 Fixed issues related to TWAIN Direct support, and added it to certification \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22 \hich\af37\dbch\af0\loch\f37 -\tab}Added makerelease.bat file \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 Bug Fixes: \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22 \hich\af37\dbch\af0\loch\f37 -\tab}}\pard \ltrpar\s199\ql \fi-360\li720\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\ls22\adjustright\rin0\lin720\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 (none) \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 Known Issues: \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22 \hich\af37\dbch\af0\loch\f37 -\tab}}\pard \ltrpar\s199\ql \fi-360\li720\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\ls22\adjustright\rin0\lin720\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 (none) \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 Wish List: \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22 \hich\af37\dbch\af0\loch\f37 -\tab}}\pard \ltrpar\s199\ql \fi-360\li720\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\ls22\adjustright\rin0\lin720\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 Want to switch to something other than WinForms, especially for macOS \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22 \hich\af37\dbch\af0\loch\f37 -\tab}Need to add some more certification tests, especially for things like printer, barcode, patch \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 \i\cf6 \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\outlinelevel1\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 \b\ul {\*\bkmkstart _Toc36456540}V2.4.3.0 (20-Mar-2020)}{\rtlch\fcs1 \af37 \ltrch\fcs0 {\*\bkmkend _Toc36456540} \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 New Features: \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22 \hich\af37\dbch\af0\loch\f37 -\tab}}\pard \ltrpar\s199\ql \fi-360\li720\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\ls22\adjustright\rin0\lin720\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 Switched twaincsscan and twaincstst to directly access TWAIN.CS \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22 \hich\af37\dbch\af0\loch\f37 -\tab}The toolkit is officially deprecated now, don\rquote t use it \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 Bug Fixes: \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22 \hich\af37\dbch\af0\loch\f37 -\tab}}\pard \ltrpar\s199\ql \fi-360\li720\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\ls22\adjustright\rin0\lin720\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 Fixed an issue where xferready during enableds could be missed \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 Known Issues: \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22 \hich\af37\dbch\af0\loch\f37 -\tab}}\pard \ltrpar\s199\ql \fi-360\li720\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\ls22\adjustright\rin0\lin720\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 (none) \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 Wish List: \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22 \hich\af37\dbch\af0\loch\f37 -\tab}}\pard \ltrpar\s199\ql \fi-360\li720\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\ls22\adjustright\rin0\lin720\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 Want to switch to something other than WinForms, especially for macOS \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22 \hich\af37\dbch\af0\loch\f37 -\tab}Need to add some more certification tests, especially for things like printer, barcode, patch \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 \i\cf6 \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\outlinelevel1\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 \b\ul {\*\bkmkstart _Toc36456541}V2.4.2.0 (13-Mar-2020)}{\rtlch\fcs1 \af37 \ltrch\fcs0 {\*\bkmkend _Toc36456541} \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 New Features: \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22 \hich\af37\dbch\af0\loch\f37 -\tab}}\pard \ltrpar\s199\ql \fi-360\li720\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\ls22\adjustright\rin0\lin720\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 Massive update to TWAIN.CS \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22 \hich\af37\dbch\af0\loch\f37 -\tab}twaincscert is pretty much done \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 Bug Fixes: \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22 \hich\af37\dbch\af0\loch\f37 -\tab}}\pard \ltrpar\s199\ql \fi-360\li720\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\ls22\adjustright\rin0\lin720\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 Too many to count, twaincscert helped scrub the code \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 Known Issues: \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22 \hich\af37\dbch\af0\loch\f37 -\tab}}\pard \ltrpar\s199\ql \fi-360\li720\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\ls22\adjustright\rin0\lin720\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 (none) \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 Wish List: \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22 \hich\af37\dbch\af0\loch\f37 -\tab}}\pard \ltrpar\s199\ql \fi-360\li720\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\ls22\adjustright\rin0\lin720\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 Want to switch to something other than WinForms, especially for macOS \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22 \hich\af37\dbch\af0\loch\f37 -\tab}Need to add some more certification tests, especially for things like printer, barcode, patch \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 \i\cf6 \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\outlinelevel1\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 \b\ul {\*\bkmkstart _Toc36456542}V2.4.1.0 (30-Jan-2020)}{\rtlch\fcs1 \af37 \ltrch\fcs0 {\*\bkmkend _Toc36456542} \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 New Features: \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22 \hich\af37\dbch\af0\loch\f37 -\tab}}\pard \ltrpar\s199\ql \fi-360\li720\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\ls22\adjustright\rin0\lin720\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 Added twaincscert project (it\rquote s not done yet, but it is useable) \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22 \hich\af37\dbch\af0\loch\f37 -\tab}Fixed reflection to allow use of capability enumerations in the CSV (ex: TWPT_RGB) \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22 \hich\af37\dbch\af0\loch\f37 -\tab}Expanded ability to use TWAIN.CS without the toolkit (needed for cert) \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 Bug Fixes: \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22 \hich\af37\dbch\af0\loch\f37 -\tab}}\pard \ltrpar\s199\ql \fi-360\li720\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\ls22\adjustright\rin0\lin720\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 (none) \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 Known Issues: \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22 \hich\af37\dbch\af0\loch\f37 -\tab}}\pard \ltrpar\s199\ql \fi-360\li720\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\ls22\adjustright\rin0\lin720\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 Runs rather slowly on Mac OS X \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22 \hich\af37\dbch\af0\loch\f37 -\tab}Setup Dialog sometimes freaks out on Mac OS X (appears to be a WinForms bug) \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 Wish List: \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22 \hich\af37\dbch\af0\loch\f37 -\tab}}\pard \ltrpar\s199\ql \fi-360\li720\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\ls22\adjustright\rin0\lin720\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 64-bit Mono support on Mac OS X (should just work, but needs building / testing) \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22 \hich\af37\dbch\af0\loch\f37 -\tab}Want to switch to Xamarin \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 \i\cf6 \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\outlinelevel1\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 \b\ul {\*\bkmkstart _Toc36456543}V2.4.0.3 (13-Mar-2019)}{\rtlch\fcs1 \af37 \ltrch\fcs0 {\*\bkmkend _Toc36456543} \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 New Features: \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22 \hich\af37\dbch\af0\loch\f37 -\tab}}\pard \ltrpar\s199\ql \fi-360\li720\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\ls22\adjustright\rin0\lin720\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 (none) \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 Bug Fixes: \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22 \hich\af37\dbch\af0\loch\f37 -\tab}}\pard \ltrpar\s199\ql \fi-360\li720\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\ls22\adjustright\rin0\lin720\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 Fixed an encoding problem, TWAIN on Windows requires strings in the encoding specified by the driver (either through it\rquote s TW_IDENTITY.Version.Language or the last successful set of CAP_LANGUAGE). Until this fix TWAIN CS was sending strings as UTF-8. Note that on Linux and macOS UTF-8 is the encoding, that hasn\rquote t changed. \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 Known Issues: \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22 \hich\af37\dbch\af0\loch\f37 -\tab}}\pard \ltrpar\s199\ql \fi-360\li720\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\ls22\adjustright\rin0\lin720\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 Runs rather slowly on Mac OS X \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22 \hich\af37\dbch\af0\loch\f37 -\tab}Setup Dialog sometimes freaks out on Mac OS X (appears to be a WinForms bug) \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 Wish List: \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22 \hich\af37\dbch\af0\loch\f37 -\tab}}\pard \ltrpar\s199\ql \fi-360\li720\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\ls22\adjustright\rin0\lin720\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 64-bit Mono support on Mac OS X (should just work, but needs building / testing) \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22 \hich\af37\dbch\af0\loch\f37 -\tab}Want to switch to Xamarin \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\outlinelevel1\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 \b\ul {\*\bkmkstart _Toc36456544}V2.4.0.2 (25-Jan-2019)}{\rtlch\fcs1 \af37 \ltrch\fcs0 {\*\bkmkend _Toc36456544} \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 New Features: \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22 \hich\af37\dbch\af0\loch\f37 -\tab}}\pard \ltrpar\s199\ql \fi-360\li720\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\ls22\adjustright\rin0\lin720\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 In sync with TWAIN Direct \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22 \hich\af37\dbch\af0\loch\f37 -\tab}Updated to VS2017 \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 Bug Fixes: \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22 \hich\af37\dbch\af0\loch\f37 -\tab}}\pard \ltrpar\s199\ql \fi-360\li720\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\ls22\adjustright\rin0\lin720\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 Fixed problem with FIX32 in TW_RANGE \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22 \hich\af37\dbch\af0\loch\f37 -\tab}Fixed problems with SendDat for custom DAT support \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 Known Issues: \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22 \hich\af37\dbch\af0\loch\f37 -\tab}}\pard \ltrpar\s199\ql \fi-360\li720\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\ls22\adjustright\rin0\lin720\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 Runs rather slowly on Mac OS X \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22 \hich\af37\dbch\af0\loch\f37 -\tab}Setup Dialog sometimes freaks out on Mac OS X (appears to be a WinForms bug) \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 Wish List: \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22 \hich\af37\dbch\af0\loch\f37 -\tab}}\pard \ltrpar\s199\ql \fi-360\li720\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\ls22\adjustright\rin0\lin720\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 64-bit Mono support on Mac OS X (should just work, but needs building / testing) \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22 \hich\af37\dbch\af0\loch\f37 -\tab}Want to switch to Xamarin \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 \i\cf6 \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\outlinelevel1\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 \b\ul {\*\bkmkstart _Toc36456545}V2.4.0.1 (19-Apr-2018)}{\rtlch\fcs1 \af37 \ltrch\fcs0 {\*\bkmkend _Toc36456545} \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 New Features: \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22 \hich\af37\dbch\af0\loch\f37 -\tab}}\pard \ltrpar\s199\ql \fi-360\li720\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\ls22\adjustright\rin0\lin720\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 In sync with TWAIN Direct \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 Bug Fixes: \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22 \hich\af37\dbch\af0\loch\f37 -\tab}}\pard \ltrpar\s199\ql \fi-360\li720\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\ls22\adjustright\rin0\lin720\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 Code analysis with VS2015, fixed up everything, supressed some stuff \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22 \hich\af37\dbch\af0\loch\f37 -\tab}Finally got the Linux 64-bit thing right (lots of edge cases) \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 Known Issues: \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22 \hich\af37\dbch\af0\loch\f37 -\tab}}\pard \ltrpar\s199\ql \fi-360\li720\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\ls22\adjustright\rin0\lin720\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 Runs rather slowly on Mac OS X \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22 \hich\af37\dbch\af0\loch\f37 -\tab}Setup Dialog sometimes freaks out on Mac OS X (appears to be a WinForms bug) \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 Wish List: \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22 \hich\af37\dbch\af0\loch\f37 -\tab}}\pard \ltrpar\s199\ql \fi-360\li720\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\ls22\adjustright\rin0\lin720\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 64-bit Mono support on Mac OS X (should just work, but needs building / testing) \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22 \hich\af37\dbch\af0\loch\f37 -\tab}Want to switch to Xamarin, and VS2017 \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 \i\cf6 \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\outlinelevel1\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 \b\ul {\*\bkmkstart _Toc36456546}V2.4.0.0 (darned if I know, 2017)}{\rtlch\fcs1 \af37 \ltrch\fcs0 {\*\bkmkend _Toc36456546} \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 New Features: \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22 \hich\af37\dbch\af0\loch\f37 -\tab}}\pard \ltrpar\s199\ql \fi-360\li720\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\ls22\adjustright\rin0\lin720\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 Linux 64-bit support, despite the TW_INT32/TW_UINT32 fiasco \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22 \hich\af37\dbch\af0\loch\f37 -\tab}Switched to log file backup scheme \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22 \hich\af37\dbch\af0\loch\f37 -\tab}In sync with TWAIN Direct \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 Known Issues: \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22 \hich\af37\dbch\af0\loch\f37 -\tab}}\pard \ltrpar\s199\ql \fi-360\li720\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\ls22\adjustright\rin0\lin720\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 Runs rather slowly on Mac OS X \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22 \hich\af37\dbch\af0\loch\f37 -\tab}Setup Dialog sometimes freaks out on Mac OS X (appears to be a WinForms bug) \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 Wish List: \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22 \hich\af37\dbch\af0\loch\f37 -\tab}}\pard \ltrpar\s199\ql \fi-360\li720\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\ls22\adjustright\rin0\lin720\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 64-bit Mono support on Mac OS X (should just work, but needs building / testing) \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 \i\cf6 \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\outlinelevel1\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 \b\ul {\*\bkmkstart _Toc36456547}V2.3.2.0 (18-Oct-2015)}{\rtlch\fcs1 \af37 \ltrch\fcs0 {\*\bkmkend _Toc36456547} \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 New Features: \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22 \hich\af37\dbch\af0\loch\f37 -\tab}}\pard \ltrpar\s199\ql \fi-360\li720\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\ls22\adjustright\rin0\lin720\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 Override capability for logging \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22 \hich\af37\dbch\af0\loch\f37 -\tab}Log files are now read shared, so they can be viewed while the code is running \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22 \hich\af37\dbch\af0\loch\f37 -\tab}RunInGuiThread scheme added to support Windows for bug listed below \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22 \hich\af37\dbch\af0\loch\f37 -\tab}Added thread and state to the log lines, added OS to the title line \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 Bug Fixes: \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22 \hich\af37\dbch\af0\loch\f37 -\tab}}\pard \ltrpar\s199\ql \fi-360\li720\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\ls22\adjustright\rin0\lin720\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 DAT_USERINTERFACE and DAT_IMAGE*XFER run on the HWND thread on Windows, this fixes problems with a number of drivers that run their code in the message loop (addresses Ticket #11 and Ticket #14) \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22 \hich\af37\dbch\af0\loch\f37 -\tab}DsmMemLock on the native transfer handle (addresses Ticket #15) \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22 \hich\af37\dbch\af0\loch\f37 -\tab}I\rquote m not closing the tickets until I get feedback, or if I hear nothing for a month or two \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 Known Issues: \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22 \hich\af37\dbch\af0\loch\f37 -\tab}}\pard \ltrpar\s199\ql \fi-360\li720\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\ls22\adjustright\rin0\lin720\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 Runs rather slowly on Mac OS X \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22 \hich\af37\dbch\af0\loch\f37 -\tab}Setup Dialog sometimes freaks out on Mac OS X (appears to be a WinForms bug) \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 Wish List: \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22 \hich\af37\dbch\af0\loch\f37 -\tab}}\pard \ltrpar\s199\ql \fi-360\li720\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\ls22\adjustright\rin0\lin720\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 64-bit Mono support on Mac OS X (should just work, but needs building / testing) \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 \i\cf6 \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\outlinelevel1\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 \b\ul {\*\bkmkstart _Toc36456548}V2.3.1.2 (13-Sep-2015)}{\rtlch\fcs1 \af37 \ltrch\fcs0 {\*\bkmkend _Toc36456548} \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 New Features: \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22 \hich\af37\dbch\af0\loch\f37 -\tab}}\pard \ltrpar\s199\ql \fi-360\li720\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\ls22\adjustright\rin0\lin720\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 (none) \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 Bug Fixes: \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22 \hich\af37\dbch\af0\loch\f37 -\tab}}\pard \ltrpar\s199\ql \fi-360\li720\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\ls22\adjustright\rin0\lin720\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 Solved issues with the DsmMem* functions \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 Known Issues: \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22 \hich\af37\dbch\af0\loch\f37 -\tab}}\pard \ltrpar\s199\ql \fi-360\li720\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\ls22\adjustright\rin0\lin720\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 Runs rather slowly on Mac OS X \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22 \hich\af37\dbch\af0\loch\f37 -\tab}Setup Dialog sometimes freaks out on Mac OS X (appears to be a WinForms bug) \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 Wish List: \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22 \hich\af37\dbch\af0\loch\f37 -\tab}}\pard \ltrpar\s199\ql \fi-360\li720\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\ls22\adjustright\rin0\lin720\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 64-bit Mono support on Mac OS X (should just work, but needs building / testing) \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\outlinelevel1\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 \b\ul {\*\bkmkstart _Toc36456549}V2.3.1.1 (27-Aug-2015)}{\rtlch\fcs1 \af37 \ltrch\fcs0 {\*\bkmkend _Toc36456549} \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 New Features: \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22 \hich\af37\dbch\af0\loch\f37 -\tab}}\pard \ltrpar\s199\ql \fi-360\li720\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\ls22\adjustright\rin0\lin720\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 (none) \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 Bug Fixes: \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22 \hich\af37\dbch\af0\loch\f37 -\tab}}\pard \ltrpar\s199\ql \fi-360\li720\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\ls22\adjustright\rin0\lin720\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 Log fix and sync with TWAIN Direct \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 Known Issues: \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22 \hich\af37\dbch\af0\loch\f37 -\tab}}\pard \ltrpar\s199\ql \fi-360\li720\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\ls22\adjustright\rin0\lin720\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 Runs rather slowly on Mac OS X \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22 \hich\af37\dbch\af0\loch\f37 -\tab}Setup Dialog sometimes freaks out on Mac OS X (appears to be a WinForms bug) \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 Wish List: \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22 \hich\af37\dbch\af0\loch\f37 -\tab}}\pard \ltrpar\s199\ql \fi-360\li720\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\ls22\adjustright\rin0\lin720\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 64-bit Mono support on Mac OS X (should just work, but needs building / testing) \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\outlinelevel1\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 \b\ul {\*\bkmkstart _Toc36456550}V2.3.1.0 (13-Mar-2015)}{\rtlch\fcs1 \af37 \ltrch\fcs0 {\*\bkmkend _Toc36456550} \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 New Features: \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22 \hich\af37\dbch\af0\loch\f37 -\tab}}\pard \ltrpar\s199\ql \fi-360\li720\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\ls22\adjustright\rin0\lin720\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 Additional arguments to the ReportImage callback \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 Bug Fixes: \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22 \hich\af37\dbch\af0\loch\f37 -\tab}}\pard \ltrpar\s199\ql \fi-360\li720\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\ls22\adjustright\rin0\lin720\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 Tested building using MonoDevelop on Ubuntu 14.04 (32-bit) using Mono 3.12.1, fixed two problems \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 Known Issues: \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22 \hich\af37\dbch\af0\loch\f37 -\tab}}\pard \ltrpar\s199\ql \fi-360\li720\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\ls22\adjustright\rin0\lin720\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 Runs rather slowly on Mac OS X \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22 \hich\af37\dbch\af0\loch\f37 -\tab}Setup Dialog sometimes freaks out on Mac OS X (appears to be a WinForms bug) \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 Wish List: \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22 \hich\af37\dbch\af0\loch\f37 -\tab}}\pard \ltrpar\s199\ql \fi-360\li720\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\ls22\adjustright\rin0\lin720\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 64-bit Mono support on Mac OS X (should just work, but needs building / testing) \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\outlinelevel1\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 \b\ul {\*\bkmkstart _Toc36456551}V2.3.0.6 (30-Oct-2014)}{\rtlch\fcs1 \af37 \ltrch\fcs0 {\*\bkmkend _Toc36456551} \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 New Features: \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22 \hich\af37\dbch\af0\loch\f37 -\tab}}\pard \ltrpar\s199\ql \fi-360\li720\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\ls22\adjustright\rin0\lin720\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 (none) \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 Bug Fixes: \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22 \hich\af37\dbch\af0\loch\f37 -\tab}}\pard \ltrpar\s199\ql \fi-360\li720\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\ls22\adjustright\rin0\lin720\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 Closed Ticket #6: DsmMemFree - Validate \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22 \hich\af37\dbch\af0\loch\f37 -\tab}Ticket #5 has been resisting, this time I got it right\'85 \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22 \hich\af37\dbch\af0\loch\f37 -\tab}Removed embedded tabs \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22 \hich\af37\dbch\af0\loch\f37 -\tab}Confirmed successful tests with other vendors \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22 \hich\af37\dbch\af0\loch\f37 -\tab}Fixed code to better handle when TWAIN DSM isn\rquote t installed \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 Known Issues: \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22 \hich\af37\dbch\af0\loch\f37 -\tab}}\pard \ltrpar\s199\ql \fi-360\li720\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\ls22\adjustright\rin0\lin720\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 Runs rather slowly on Mac OS X \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22 \hich\af37\dbch\af0\loch\f37 -\tab}Setup Dialog sometimes freaks out on Mac OS X (appears to be a WinForms bug) \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 Wish List: \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22 \hich\af37\dbch\af0\loch\f37 -\tab}}\pard \ltrpar\s199\ql \fi-360\li720\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\ls22\adjustright\rin0\lin720\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 64-bit Mono support on Mac OS X (should just work, but needs building / testing) \par }\pard\plain \ltrpar\ql \li0\ri0\widctlpar\wrapdefault\nooverflow\faroman\rin0\lin0\itap0 \rtlch\fcs1 \af44\afs20\alang1025 \ltrch\fcs0 \f44\fs20\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 {\rtlch\fcs1 \af0 \ltrch\fcs0 \v\f37\cf6 \par }\pard\plain \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 \rtlch\fcs1 \af37\afs22\alang1025 \ltrch\fcs0 \f37\fs22\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 {\rtlch\fcs1 \af0 \ltrch\fcs0 \v\cf6 [Technical Notes]}{\rtlch\fcs1 \af0\afs20 \ltrch\fcs0 \i\v\fs20\cf6 \par }{\rtlch\fcs1 \af37 \ltrch\fcs0 \i\v\cf6 I think we made a mistake here. All of the capabilities that use TW_ARRAY containers only show TW_ONEVALUE as the valid container for MSG_SET. It should be TW_ONEVALUE and TW_ARRAY. \par }\pard\plain \ltrpar\ql \li0\ri0\widctlpar\wrapdefault\nooverflow\faroman\rin0\lin0\itap0 \rtlch\fcs1 \af44\afs20\alang1025 \ltrch\fcs0 \f44\fs20\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 {\rtlch\fcs1 \af0 \ltrch\fcs0 \v\f37\cf6 \par }\pard\plain \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 \rtlch\fcs1 \af37\afs22\alang1025 \ltrch\fcs0 \f37\fs22\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 {\rtlch\fcs1 \af0 \ltrch\fcs0 \v\cf6 [Technical Notes]}{\rtlch\fcs1 \af0\afs20 \ltrch\fcs0 \i\v\fs20\cf6 \par }{\rtlch\fcs1 \af37 \ltrch\fcs0 \i\v\cf6 I think we made a mistake here. All of the capabilities that use TW_ARRAY containers only show TW_ONEVALUE as the valid container for MSG_SET. It should be TW_ONEVALUE and TW_ARRAY. \par }{\rtlch\fcs1 \af37 \ltrch\fcs0 \i\cf6 \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\outlinelevel1\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 \b\ul {\*\bkmkstart _Toc36456552}V2.3.0.5 (19-Oct-2014)}{\rtlch\fcs1 \af37 \ltrch\fcs0 {\*\bkmkend _Toc36456552} \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 New Features: \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22 \hich\af37\dbch\af0\loch\f37 -\tab}}\pard \ltrpar\s199\ql \fi-360\li720\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\ls22\adjustright\rin0\lin720\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 (none) \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 Bug Fixes: \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22 \hich\af37\dbch\af0\loch\f37 -\tab}}\pard \ltrpar\s199\ql \fi-360\li720\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\ls22\adjustright\rin0\lin720\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 Closed Ticket #3: can\'b4t get capabilities; what can i get out of a_szMemref? \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22 \hich\af37\dbch\af0\loch\f37 -\tab}Closed Ticket #4: Setup Scanner does not work in twancsscan (dialog freezes) \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22 \hich\af37\dbch\af0\loch\f37 -\tab}Closed Ticket #5: Twain.DatParent - CloseDs should be CloseDsm \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22 \hich\af37\dbch\af0\loch\f37 -\tab}Figured out the message pump issue \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22 \hich\af37\dbch\af0\loch\f37 -\tab}Fixed SetImagePath to impact file transfers \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 Known Issues: \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22 \hich\af37\dbch\af0\loch\f37 -\tab}}\pard \ltrpar\s199\ql \fi-360\li720\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\ls22\adjustright\rin0\lin720\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 Runs rather slowly on Mac OS X \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22 \hich\af37\dbch\af0\loch\f37 -\tab}Setup Dialog sometimes freaks out on Mac OS X (looks like a race condition) \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22 \hich\af37\dbch\af0\loch\f37 -\tab}Only tested on Kodak Alaris products and the TWAIN Sample Data Source \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 Wish List: \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22 \hich\af37\dbch\af0\loch\f37 -\tab}}\pard \ltrpar\s199\ql \fi-360\li720\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\ls22\adjustright\rin0\lin720\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 Test with other vendors \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22 \hich\af37\dbch\af0\loch\f37 -\tab}64-bit Mono support on Mac OS X (should just work, but needs building / testing) \par }\pard\plain \ltrpar\ql \li0\ri0\widctlpar\wrapdefault\nooverflow\faroman\rin0\lin0\itap0 \rtlch\fcs1 \af44\afs20\alang1025 \ltrch\fcs0 \f44\fs20\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 {\rtlch\fcs1 \af0 \ltrch\fcs0 \v\f37\cf6 \par }\pard\plain \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 \rtlch\fcs1 \af37\afs22\alang1025 \ltrch\fcs0 \f37\fs22\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 {\rtlch\fcs1 \af0 \ltrch\fcs0 \v\cf6 [Technical Notes]}{\rtlch\fcs1 \af0\afs20 \ltrch\fcs0 \i\v\fs20\cf6 \par }{\rtlch\fcs1 \af37 \ltrch\fcs0 \i\v\cf6 I think we made a mistake here. All of the capabilities that use TW_ARRAY containers only show TW_ONEVALUE as the valid container for MSG_SET. It should be TW_ONEVALUE and TW_ARRAY. \par }{\rtlch\fcs1 \af37 \ltrch\fcs0 \i\cf6 \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\outlinelevel1\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 \b\ul {\*\bkmkstart _Toc36456553}V2.3.0.4 (13-Oct-2014)}{\rtlch\fcs1 \af37 \ltrch\fcs0 {\*\bkmkend _Toc36456553} \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 New Features: \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22 \hich\af37\dbch\af0\loch\f37 -\tab}}\pard \ltrpar\s199\ql \fi-360\li720\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\ls22\adjustright\rin0\lin720\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 Tracking the version number to the TWAIN Specification, so the major and minor will be the protocol value, the third number will call out major changes in the API within a version, and the fourth number will count minor changes to the API (like bug fixes) \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22 \hich\af37\dbch\af0\loch\f37 -\tab}Added logging (still some work to do on this) \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22 \hich\af37\dbch\af0\loch\f37 -\tab}Added auto JPEG/TIFF option for file transfers \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 Bug Fixes: \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22 \hich\af37\dbch\af0\loch\f37 -\tab}}\pard \ltrpar\s199\ql \fi-360\li720\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\ls22\adjustright\rin0\lin720\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 Fixed DAT_IMAGEMEMFILEXFER for Mac OS X \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 Known Issues: \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22 \hich\af37\dbch\af0\loch\f37 -\tab}}\pard \ltrpar\s199\ql \fi-360\li720\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\ls22\adjustright\rin0\lin720\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 Runs rather slowly on Mac OS X \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22 \hich\af37\dbch\af0\loch\f37 -\tab}Setup Dialog sometimes freaks out on Mac OS X (looks like a race condition) \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22 \hich\af37\dbch\af0\loch\f37 -\tab}Only tested on Kodak Alaris products and the TWAIN Sample Data Source \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 Wish List: \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22 \hich\af37\dbch\af0\loch\f37 -\tab}}\pard \ltrpar\s199\ql \fi-360\li720\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\ls22\adjustright\rin0\lin720\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 Test with other vendors \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22 \hich\af37\dbch\af0\loch\f37 -\tab}64-bit Mono support on Mac OS X (should just work, but needs testing) \par }\pard\plain \ltrpar\ql \li0\ri0\widctlpar\wrapdefault\nooverflow\faroman\rin0\lin0\itap0 \rtlch\fcs1 \af44\afs20\alang1025 \ltrch\fcs0 \f44\fs20\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 {\rtlch\fcs1 \af0 \ltrch\fcs0 \v\f37\cf6 \par }\pard\plain \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 \rtlch\fcs1 \af37\afs22\alang1025 \ltrch\fcs0 \f37\fs22\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 {\rtlch\fcs1 \af0 \ltrch\fcs0 \v\cf6 [Technical Notes]}{\rtlch\fcs1 \af0\afs20 \ltrch\fcs0 \i\v\fs20\cf6 \par }{\rtlch\fcs1 \af37 \ltrch\fcs0 \i\v\cf6 I think we made a mistake here. All of the capabilities that use TW_ARRAY containers only show TW_ONEVALUE as the valid container for MSG_SET. It should be TW_ONEVALUE and TW_ARRAY. \par }{\rtlch\fcs1 \af37 \ltrch\fcs0 \i\cf6 \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\outlinelevel1\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 \b\ul {\*\bkmkstart _Toc36456554}V2.2.0 (11-Jul-2014)}{\rtlch\fcs1 \af37 \ltrch\fcs0 {\*\bkmkend _Toc36456554} \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 New Features: \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22 \hich\af37\dbch\af0\loch\f37 -\tab}}\pard \ltrpar\s199\ql \fi-360\li720\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\ls22\adjustright\rin0\lin720\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 (none) \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 Bug Fixes: \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22 \hich\af37\dbch\af0\loch\f37 -\tab}}\pard \ltrpar\s199\ql \fi-360\li720\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\ls22\adjustright\rin0\lin720\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 Fixed DAT_IMAGEMEMFILEXFER \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 Known Issues: \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22 \hich\af37\dbch\af0\loch\f37 -\tab}}\pard \ltrpar\s199\ql \fi-360\li720\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\ls22\adjustright\rin0\lin720\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 Runs rather slowly on Mac OS X \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22 \hich\af37\dbch\af0\loch\f37 -\tab}Setup Dialog sometimes freaks out on Mac OS X (looks like a race condition) \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22 \hich\af37\dbch\af0\loch\f37 -\tab}Only tested on Kodak Alaris products and the TWAIN Sample Data Source \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 Wish List: \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22 \hich\af37\dbch\af0\loch\f37 -\tab}}\pard \ltrpar\s199\ql \fi-360\li720\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\ls22\adjustright\rin0\lin720\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 Test with other vendors \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22 \hich\af37\dbch\af0\loch\f37 -\tab}64-bit Mono support on Mac OS X (should just work, but needs testing) \par }\pard\plain \ltrpar\ql \li0\ri0\widctlpar\wrapdefault\nooverflow\faroman\rin0\lin0\itap0 \rtlch\fcs1 \af44\afs20\alang1025 \ltrch\fcs0 \f44\fs20\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 {\rtlch\fcs1 \af0 \ltrch\fcs0 \v\f31506\cf6 \par }\pard\plain \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 \rtlch\fcs1 \af37\afs22\alang1025 \ltrch\fcs0 \f37\fs22\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 {\rtlch\fcs1 \af0 \ltrch\fcs0 \v\f31506\cf6 [Technical Notes]}{\rtlch\fcs1 \af0\afs20 \ltrch\fcs0 \i\v\f31506\fs20\cf6 \par }{\rtlch\fcs1 \af37 \ltrch\fcs0 \i\v\f31506\cf6 I think we made a mistake here. All of the capabilities that use TW_ARRAY containers only show TW_ONEVALUE as the valid container for MSG_SET. It should be TW_ONEVALUE and TW_ARRAY. \par }{\rtlch\fcs1 \af37 \ltrch\fcs0 \i\f31506\cf6 \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\outlinelevel1\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 \b\ul {\*\bkmkstart _Toc36456555}V2.1.0 (09-Jul-2014)}{\rtlch\fcs1 \af37 \ltrch\fcs0 {\*\bkmkend _Toc36456555} \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 New Features: \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22 \hich\af37\dbch\af0\loch\f37 -\tab}}\pard \ltrpar\s199\ql \fi-360\li720\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\ls22\adjustright\rin0\lin720\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 ReportImage\rquote s bitmap no long locks access to the file \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 Bug Fixes: \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22 \hich\af37\dbch\af0\loch\f37 -\tab}}\pard \ltrpar\s199\ql \fi-360\li720\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\ls22\adjustright\rin0\lin720\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 Handles MSG_XFERREADY when issued from MSG_ENABLEDS \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 Known Issues: \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22 \hich\af37\dbch\af0\loch\f37 -\tab}}\pard \ltrpar\s199\ql \fi-360\li720\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\ls22\adjustright\rin0\lin720\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 Runs rather slowly on Mac OS X \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22 \hich\af37\dbch\af0\loch\f37 -\tab}Setup Dialog sometimes freaks out on Mac OS X (looks like a race condition) \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22 \hich\af37\dbch\af0\loch\f37 -\tab}Only tested on Kodak Alaris products and the TWAIN Sample Data Source \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 Wish List: \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22 \hich\af37\dbch\af0\loch\f37 -\tab}}\pard \ltrpar\s199\ql \fi-360\li720\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\ls22\adjustright\rin0\lin720\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 Test with other vendors \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22 \hich\af37\dbch\af0\loch\f37 -\tab}64-bit Mono support on Mac OS X (should just work, but needs testing) \par }\pard \ltrpar\s199\ql \li720\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin720\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\outlinelevel1\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 \b\f31506\ul {\*\bkmkstart _Toc36456556}V2.0.0 (21-May-2014)}{\rtlch\fcs1 \af37 \ltrch\fcs0 \f31506 {\*\bkmkend _Toc36456556} \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 \f31506 New Features: \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22 \hich\af37\dbch\af0\loch\f37 -\tab}}\pard \ltrpar\s199\ql \fi-360\li720\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\ls22\adjustright\rin0\lin720\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 \f31506 Support for 64-bit Linux (native only, 32-bit on 64-bit is too nasty) \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22 \hich\af37\dbch\af0\loch\f37 -\tab}ShowImage renamed to ReportImage \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 \f31506 Known Issues: \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22 \hich\af37\dbch\af0\loch\f37 -\tab}}\pard \ltrpar\s199\ql \fi-360\li720\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\ls22\adjustright\rin0\lin720\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 \f31506 Runs rather slowly on Mac OS X \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22 \hich\af37\dbch\af0\loch\f37 -\tab}Setup Dialog sometimes freaks out on Mac OS X (looks like a race condition) \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22 \hich\af37\dbch\af0\loch\f37 -\tab}Only tested on Kodak Alaris products \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 \f31506 Wish List: \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22 \hich\af37\dbch\af0\loch\f37 -\tab}}\pard \ltrpar\s199\ql \fi-360\li720\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\ls22\adjustright\rin0\lin720\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 \f31506 Test with other vendors \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22 \hich\af37\dbch\af0\loch\f37 -\tab}64-bit Mono support on Mac OS X (should just work, but needs testing) \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 \i\cf6 \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\outlinelevel1\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 \b\ul {\*\bkmkstart _Toc36456557}V1.1.0 (27-Feb-2014)}{\rtlch\fcs1 \af37 \ltrch\fcs0 {\*\bkmkend _Toc36456557} \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 New Features: \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22 \hich\af37\dbch\af0\loch\f37 -\tab}}\pard \ltrpar\s199\ql \fi-360\li720\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\ls22\adjustright\rin0\lin720\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 Additional arguments in ShowImage \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22 \hich\af37\dbch\af0\loch\f37 -\tab}Code example of CAP_INDICATORS in TWAINCSScan \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22 \hich\af37\dbch\af0\loch\f37 -\tab}Fixed projects to handle conditional references \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22 \hich\af37\dbch\af0\loch\f37 -\tab}Added AnyCPU support \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 Known Issues: \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22 \hich\af37\dbch\af0\loch\f37 -\tab}}\pard \ltrpar\s199\ql \fi-360\li720\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\ls22\adjustright\rin0\lin720\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 Runs rather slowly on Mac OS X \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22 \hich\af37\dbch\af0\loch\f37 -\tab}Setup Dialog sometimes freaks out on Mac OS X (looks like a race condition) \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22 \hich\af37\dbch\af0\loch\f37 -\tab}Only tested on Kodak Alaris products \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 Wish List: \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22 \hich\af37\dbch\af0\loch\f37 -\tab}}\pard \ltrpar\s199\ql \fi-360\li720\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\ls22\adjustright\rin0\lin720\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 Test with other vendors \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22 \hich\af37\dbch\af0\loch\f37 -\tab}64-bit Mono support on Linux and Mac OS X \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 \i\cf6 \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\outlinelevel1\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 \b\ul {\*\bkmkstart _Toc36456558}V1.0.0 (05-Nov-2013)}{\rtlch\fcs1 \af37 \ltrch\fcs0 {\*\bkmkend _Toc36456558} \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 New Features: \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22 \hich\af37\dbch\af0\loch\f37 -\tab}}\pard \ltrpar\s199\ql \fi-360\li720\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\ls22\adjustright\rin0\lin720\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 Initial release \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 Known Issues: \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22 \hich\af37\dbch\af0\loch\f37 -\tab}}\pard \ltrpar\s199\ql \fi-360\li720\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\ls22\adjustright\rin0\lin720\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 Runs rather slowly on Mac OS X \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22 \hich\af37\dbch\af0\loch\f37 -\tab}Setup Dialog sometimes freaks out on Mac OS X (looks like a race condition) \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22 \hich\af37\dbch\af0\loch\f37 -\tab}Only tested on Kodak Alaris products \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 Wish List: \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22 \hich\af37\dbch\af0\loch\f37 -\tab}}\pard \ltrpar\s199\ql \fi-360\li720\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\ls22\adjustright\rin0\lin720\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 Test with other vendors \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22 \hich\af37\dbch\af0\loch\f37 -\tab}64-bit Mono support on Linux and Mac OS X}{\rtlch\fcs1 \af45 \ltrch\fcs0 \f31506 \par }\pard\plain \ltrpar\s189\ql \li0\ri0\keepn\widctlpar\brdrt\brdrs\brdrw30\brsp120 \wrapdefault\nooverflow\faroman\outlinelevel0\rin0\lin0\itap0 \rtlch\fcs1 \ab\af1\afs24\alang1025 \ltrch\fcs0 \b\f1\fs24\cf9\lang1024\langfe1024\cgrid\noproof\langnp1033\langfenp1033 {\rtlch\fcs1 \af1 \ltrch\fcs0 \v\f31506\noproof0 {\*\bkmkend _Toc234021027}General Comments }{\rtlch\fcs1 \af1 \ltrch\fcs0 \v\f31506\cf6\noproof0 [DONE]}{\rtlch\fcs1 \af1 \ltrch\fcs0 \v\f31506\noproof0 \par }\pard\plain \ltrpar\ql \li0\ri0\widctlpar\wrapdefault\nooverflow\faroman\rin0\lin0\itap0 \rtlch\fcs1 \af44\afs20\alang1025 \ltrch\fcs0 \f44\fs20\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 {\rtlch\fcs1 \af0 \ltrch\fcs0 \v\f31506\cf6 \par }\pard\plain \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 \rtlch\fcs1 \af37\afs22\alang1025 \ltrch\fcs0 \f37\fs22\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 {\rtlch\fcs1 \af0 \ltrch\fcs0 \v\f31506\cf6 [Technical Notes]}{\rtlch\fcs1 \af0\afs20 \ltrch\fcs0 \i\v\f31506\fs20\cf6 \par These are areas of discussion which may or may not lead to changes in the TWAIN Specification. If changes do result, they\rquote ll be moved into their own area. There are no Update Instructions in this section. When we\rquote re done with it, it \rquote ll be moved to the end of the document and given a status of \'93DONE\'94\'85 \par }\pard\plain \ltrpar\ql \li0\ri0\widctlpar\wrapdefault\nooverflow\faroman\rin0\lin0\itap0 \rtlch\fcs1 \af44\afs20\alang1025 \ltrch\fcs0 \f44\fs20\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 {\rtlch\fcs1 \af0 \ltrch\fcs0 \v\f31506 \par \par }{\rtlch\fcs1 \af0 \ltrch\fcs0 \v\f31506\cf6 [Note] \endash DONE \par }\pard \ltrpar\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af0\afs22 \ltrch\fcs0 \i\v\f31506\fs22 Does a Boolean enumeration have an expected order to the TRUE/FALSE values in the list? \par 8-22 (hunt this down and fix it) \par We don\rquote t want the values ordered, except in the context where the order impacts the UI, but there is no way to know if this is happening or not\'85 \par }\pard \ltrpar\ql \li0\ri0\widctlpar\wrapdefault\faauto\rin0\lin0\itap0 {\rtlch\fcs1 \af45 \ltrch\fcs0 \v\f31506 Stores a group of individual values describing a capability. The values are ordered from lowest to \par highest values, but the step size between each value is probably not uniform. Such a list would be \par useful to describe the discreet resolutions of a capture device supporting, say, 75, 150, 300, 400, \par }\pard \ltrpar\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af45 \ltrch\fcs0 \v\f31506 and 800 dots per inch.}{\rtlch\fcs1 \af0\afs22 \ltrch\fcs0 \i\v\f31506\fs22 \par \par {\listtext\pard\plain\ltrpar \rtlch\fcs1 \af0\afs22 \ltrch\fcs0 \v\fs22 \hich\af0\dbch\af0\loch\f0 -\tab}}\pard \ltrpar\ql \fi-360\li720\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\ls21\adjustright\rin0\lin720\itap0 {\rtlch\fcs1 \af0\afs22 \ltrch\fcs0 \i\v\f31506\fs22 No, there is no required order for items in an enumeration or an array. Ideally the Data Source would maintain the order of items send to it, and display the items in that order in the GUI, but I don\rquote t believe there is anything in the Specification that even suggests that much. \par }\pard \ltrpar\ql \li0\ri0\widctlpar\wrapdefault\nooverflow\faroman\rin0\lin0\itap0 {\rtlch\fcs1 \af0 \ltrch\fcs0 \v\f31506 \par \par }{\rtlch\fcs1 \af0 \ltrch\fcs0 \v\f31506\cf6 [Note] \endash DONE \par }\pard \ltrpar\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af0\afs22 \ltrch\fcs0 \i\v\f31506\fs22 In particular, I was working on ICAP_BITDEPTH. If a Data Source only supports a single bitdepth for each specific pixeltype, wouldn\rquote t it make sense to respond that SET and RESET are not supported? There would be no reason to do a set of Bitdepth, since only a single value is supported at a time. \par \par {\listtext\pard\plain\ltrpar \rtlch\fcs1 \af0\afs22 \ltrch\fcs0 \v\fs22 \hich\af0\dbch\af0\loch\f0 -\tab}}\pard \ltrpar\ql \fi-360\li720\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\ls21\adjustright\rin0\lin720\itap0 {\rtlch\fcs1 \af0\afs22 \ltrch\fcs0 \i\v\f31506\fs22 I wonder if there should be a paragraph on this matter. Here\rquote s my take on it. Applications tend to do one of two things when confronted by an error: they ignore it or they fail (sometimes they crash). With tha t in mind a driver should always avoid returning an error if it has a valid alternative that allows it to return success instead. Therefore, MSG_RESET and MSG_SET should always be allowed for capabilities that support a single value, except in those cas es where the Specification makes it clear that the value is read only (like CAP_DEVICEONLINE). \par }\pard \ltrpar\ql \li0\ri0\widctlpar\wrapdefault\nooverflow\faroman\rin0\lin0\itap0 {\rtlch\fcs1 \af0 \ltrch\fcs0 \v\f31506 \par \par }{\rtlch\fcs1 \af0 \ltrch\fcs0 \v\f31506\cf6 [Note] \endash DONE \par }\pard \ltrpar\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af0\afs22 \ltrch\fcs0 \i\v\f31506\fs22 Also regarding ICAP_BITDEPTH, am I correct in understanding that a MSG_GET for this capability should only report the available values based on the current setting for PIXELTYPE? Ie. Don\rquote t report all the bitdepths supported, only those supported for the current pixel type? \par \par {\listtext\pard\plain\ltrpar \rtlch\fcs1 \af0\afs22 \ltrch\fcs0 \v\fs22 \hich\af0\dbch\af0\loch\f0 -\tab}}\pard \ltrpar\ql \fi-360\li720\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\ls21\adjustright\rin0\lin720\itap0 {\rtlch\fcs1 \af0\afs22 \ltrch\fcs0 \i\v\f31506\fs22 This is correct. We know that some drivers show all of the bitdepth values for all of the supported pixeltypes. It doesn\rquote t look like we have a comment on this in the Legacy Issues section (3-39, PDF 71). \par {\listtext\pard\plain\ltrpar \rtlch\fcs1 \af0\afs22 \ltrch\fcs0 \v\fs22 \hich\af0\dbch\af0\loch\f0 -\tab}Add a test to the self cert to watch out for this\'85 (this has been added to the Proposed Changes doc) \par }\pard \ltrpar\ql \li0\ri0\widctlpar\wrapdefault\nooverflow\faroman\rin0\lin0\itap0 {\rtlch\fcs1 \af0 \ltrch\fcs0 \v\f31506 \par \par }{\rtlch\fcs1 \af0 \ltrch\fcs0 \v\f31506\cf6 \page [Note] \endash DONE \par }\pard \ltrpar\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af0\afs22 \ltrch\fcs0 \i\v\f31506\fs22 I have a question regarding the filename extension used in a File Transfer. The filename is provided in the DG_CONTROL/DAT_SETUPFILEXFER/MSG_SET message. Do I need to make sure the requested filename extension matches the type of the file I end up creating? \par }{\rtlch\fcs1 \af0\afs22 \ltrch\fcs0 \v\f31506\fs22 \par A couple of examples: \par {\listtext\pard\plain\ltrpar \rtlch\fcs1 \af0\afs22 \ltrch\fcs0 \v\f37\fs22\cf22 \hich\af37\dbch\af0\loch\f37 1)\tab}}\pard \ltrpar\ql \fi-360\li720\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\ls20\adjustright\rin0\lin720\itap0 {\rtlch\fcs1 \af0\afs22 \ltrch\fcs0 \v\f31506\fs22 Simple case: if \'93filexfer.tmp\'94 is requested, I\rquote m guessing I should use the file extension as requested regardless of file type that I create. (ie. Even though I save a tiff/jpg/bmp etc. file, continue using the .tmp extention) Is this correct? \par {\listtext\pard\plain\ltrpar \rtlch\fcs1 \af0\afs22 \ltrch\fcs0 \v\f37\fs22\cf22 \hich\af37\dbch\af0\loch\f37 2)\tab}More complex case: Assume I\rquote m doing auto color detect, and my non-color will be mapped to BW. If \'93filexfer.jpg\'94 is requested and I detect a non-color image, this will be an *}{\rtlch\fcs1 \ab\af0\afs22 \ltrch\fcs0 \b\v\f31506\fs22 incorrect}{\rtlch\fcs1 \af0\afs22 \ltrch\fcs0 \v\f31506\fs22 * name in the end since I cannot save a BW image as a JPG file. I will create a BMP file instead. Should I change the requested filename to \'93filexfer.bmp\'94 in this case? Or still use the filename as requested even though it gives the wrong impression of filetype? \par }\pard \ltrpar\ql \li360\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin360\itap0 {\rtlch\fcs1 \af0\afs22 \ltrch\fcs0 \v\f31506\fs22 \par }\pard \ltrpar\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af0\afs22 \ltrch\fcs0 \v\f31506\fs22 If I don\rquote t use the filename exactly as requested, does the TWAIN app think the transfer failed? They really have no way to know what I saved it as if I make a change, so it seems the filename better not change, even in the case that it is incorrect. \par \par Do you know of some TWAIN apps that use FileXfer that I could try this with? \par \par {\listtext\pard\plain\ltrpar \rtlch\fcs1 \af0\afs22 \ltrch\fcs0 \v\fs22 \hich\af0\dbch\af0\loch\f0 -\tab}}\pard \ltrpar\ql \fi-360\li720\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\ls21\adjustright\rin0\lin720\itap0 {\rtlch\fcs1 \af0\afs22 \ltrch\fcs0 \v\f31506\fs22 TWAIN doesn\rquote t recommend or enforce filename extensions for TWFF_* file formats. This means that someone could produce a ridiculous result (like image.bmp for a JPEG image), but that\rquote s okay, because application writers are free to use whatever naming system they need. \par }\pard \ltrpar\ql \li720\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin720\itap0 {\rtlch\fcs1 \af0\afs22 \ltrch\fcs0 \v\f31506\fs22 \par {\listtext\pard\plain\ltrpar \rtlch\fcs1 \af0\afs22 \ltrch\fcs0 \v\fs22 \hich\af0\dbch\af0\loch\f0 -\tab}}\pard \ltrpar\ql \fi-360\li720\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\ls21\adjustright\rin0\lin720\itap0 {\rtlch\fcs1 \af0\afs22 \ltrch\fcs0 \v\f31506\fs22 The only time a file transfer should fail is in situations where the application\rquote s request can\rquote t be met. For example, if TWFF_JFIF is requested for a TWPT_BW TWCP_GROUP4 compressed image. \par }\pard\plain \ltrpar\s199\ql \li720\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin720\itap0 \rtlch\fcs1 \af37\afs22\alang1025 \ltrch\fcs0 \f37\fs22\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 {\rtlch\fcs1 \af0 \ltrch\fcs0 \v\f31506 \par {\listtext\pard\plain\ltrpar \rtlch\fcs1 \af0\afs22 \ltrch\fcs0 \v\fs22 \hich\af0\dbch\af0\loch\f0 -\tab}}\pard\plain \ltrpar\ql \fi-360\li720\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\ls21\adjustright\rin0\lin720\itap0 \rtlch\fcs1 \af44\afs20\alang1025 \ltrch\fcs0 \f44\fs20\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 {\rtlch\fcs1 \af0\afs22 \ltrch\fcs0 \v\f31506\fs22 Note that DAT_IMAGEFILEXFER is still considered optional, so few drivers support it. It was designed as a low memory transfer option, since the driver is able to transfer the image directly to disk. Most application choose to do this th emselves, and using DAT_IMAGEMEMXFER can achieve results that require little memory, though an extra step is often needed to create the finished file, since the metadata that describes the image isn\rquote t available until state 7. \par }\pard\plain \ltrpar\s199\ql \li720\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin720\itap0 \rtlch\fcs1 \af37\afs22\alang1025 \ltrch\fcs0 \f37\fs22\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 {\rtlch\fcs1 \af0 \ltrch\fcs0 \v\f31506 \par {\listtext\pard\plain\ltrpar \rtlch\fcs1 \af0\afs22 \ltrch\fcs0 \v\fs22 \hich\af0\dbch\af0\loch\f0 -\tab}}\pard\plain \ltrpar\ql \fi-360\li720\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\ls21\adjustright\rin0\lin720\itap0 \rtlch\fcs1 \af44\afs20\alang1025 \ltrch\fcs0 \f44\fs20\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 {\rtlch\fcs1 \af0\afs22 \ltrch\fcs0 \v\f31506\fs22 I don\rquote t know of any commonly used TWAIN applications that use DAT_IMAGEFILEXFER. \par }\pard \ltrpar\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \v\f31506\fs22\cf22 \par }\pard \ltrpar\ql \li0\ri0\sb180\widctlpar\wrapdefault\nooverflow\faroman\rin0\lin0\itap0 {\rtlch\fcs1 \af0 \ltrch\fcs0 \v\f31506 \page \par }\pard \ltrpar\ql \li0\ri0\widctlpar\wrapdefault\nooverflow\faroman\rin0\lin0\itap0 {\rtlch\fcs1 \af0 \ltrch\fcs0 \v\f31506\cf6 [Note] \endash DONE \par }\pard \ltrpar\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af0\afs22 \ltrch\fcs0 \v\f31506\fs22 For capabilities (ch.10 pages), if MSG_GET supports both TW_ONEVALUE and TW_ENUMERATION; should MSG_SET support both as well? Nowhere does the spec include TW_ ENUMERATION as a valid set container, but I think this is allowed. \par \par Oh....ICAP_HALFTONETYPES is the only cap I found that lists TW_ENUMERATION as a SET Container type. \par \par Do I correctly understand that you could replace MSG_SET with MSG_SETCONSTRAINT, and never use MSG_SET anymore? Ie. If sending a TW_ONEVALUE or TW_ARRAY via the MSG_SETCONSTRAINT, this is equivalent to the MSG_SET functionality. \par \par {\listtext\pard\plain\ltrpar \rtlch\fcs1 \af0\afs22 \ltrch\fcs0 \v\fs22 \hich\af0\dbch\af0\loch\f0 -\tab}}\pard \ltrpar\ql \fi-360\li720\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\ls21\adjustright\rin0\lin720\itap0 {\rtlch\fcs1 \af0\afs22 \ltrch\fcs0 \v\f31506\fs22 I can say with confidence that this part of the Spec hasn\rquote t exactly turned out as planned. The intention was to separate setting values from setting constraints. However, I would always expect that one can call MSG_GET, MSG_GETCURRENT and take the result and pass it into MSG_SET. The difference is that if bot h the application and the driver report themselves as 2.2 or higher the driver only takes the value from MSG_SET. \par }\pard \ltrpar\ql \li360\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin360\itap0 {\rtlch\fcs1 \af0\afs22 \ltrch\fcs0 \v\f31506\fs22 \par {\listtext\pard\plain\ltrpar \rtlch\fcs1 \af0\afs22 \ltrch\fcs0 \v\fs22 \hich\af0\dbch\af0\loch\f0 -\tab}}\pard \ltrpar\ql \fi-360\li720\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\ls21\adjustright\rin0\lin720\itap0 {\rtlch\fcs1 \af0\afs22 \ltrch\fcs0 \v\f31506\fs22 The situation as described means that MSG_GET cannot be used as the input to MSG_SET. I think that results in too much work for applications and drivers, given the radical departure from previous behavior. \par }\pard\plain \ltrpar\s199\ql \li720\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin720\itap0 \rtlch\fcs1 \af37\afs22\alang1025 \ltrch\fcs0 \f37\fs22\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 {\rtlch\fcs1 \af0 \ltrch\fcs0 \v\f31506 \par {\listtext\pard\plain\ltrpar \rtlch\fcs1 \af0\afs22 \ltrch\fcs0 \v\fs22 \hich\af0\dbch\af0\loch\f0 -\tab}}\pard\plain \ltrpar\ql \fi-360\li720\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\ls21\adjustright\rin0\lin720\itap0 \rtlch\fcs1 \af44\afs20\alang1025 \ltrch\fcs0 \f44\fs20\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 {\rtlch\fcs1 \af0\afs22 \ltrch\fcs0 \v\f31506\fs22 Using TW_ONEVALUE with MSG_SETCONTRAINT should constrain the capability to that one value. Also, the value is always set with MSG_SETCONTRAINT. \par }\pard \ltrpar\ql \li720\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin720\itap0 {\rtlch\fcs1 \af0\afs22 \ltrch\fcs0 \v\f31506\fs22 \par {\listtext\pard\plain\ltrpar \rtlch\fcs1 \af0\afs22 \ltrch\fcs0 \v\fs22 \hich\af0\dbch\af0\loch\f0 -\tab}}\pard \ltrpar\ql \fi-360\li720\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\ls21\adjustright\rin0\lin720\itap0 {\rtlch\fcs1 \af0\afs22 \ltrch\fcs0 \v\f31506\fs22 Therefore, we need to make sure that the Spec clearly explains the difference between MSG_SET and MSG_SETCON TRAINT, and then make sure that for all capabilities the allowed containers for both MSG_SET and MSG_SETCONSTRAINT are identical. \par }\pard\plain \ltrpar\s199\ql \li720\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin720\itap0 \rtlch\fcs1 \af37\afs22\alang1025 \ltrch\fcs0 \f37\fs22\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 {\rtlch\fcs1 \af0 \ltrch\fcs0 \v\f31506 \par {\listtext\pard\plain\ltrpar \rtlch\fcs1 \af0\afs22 \ltrch\fcs0 \v\fs22 \hich\af0\dbch\af0\loch\f0 -\tab}}\pard\plain \ltrpar\ql \fi-360\li720\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\ls21\adjustright\rin0\lin720\itap0 \rtlch\fcs1 \af44\afs20\alang1025 \ltrch\fcs0 \f44\fs20\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 {\rtlch\fcs1 \af0\afs22 \ltrch\fcs0 \v\f31506\fs22 I\rquote m pretty sure that Self-Cert will support this change (meaning that it assumes that a MSG_GET can always be followed by a MSG_SET). I\rquote d be very surprised if anybody changed the behavior of MSG_SET without asking us what we\rquote re thinking... \par }\pard\plain \ltrpar\s199\ql \li720\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin720\itap0 \rtlch\fcs1 \af37\afs22\alang1025 \ltrch\fcs0 \f37\fs22\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 {\rtlch\fcs1 \af0 \ltrch\fcs0 \v\f31506 \par {\listtext\pard\plain\ltrpar \rtlch\fcs1 \af0\afs22 \ltrch\fcs0 \v\fs22 \hich\af0\dbch\af0\loch\f0 -\tab}}\pard\plain \ltrpar\ql \fi-360\li720\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\ls21\adjustright\rin0\lin720\itap0 \rtlch\fcs1 \af44\afs20\alang1025 \ltrch\fcs0 \f44\fs20\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 {\rtlch\fcs1 \af0\afs22 \ltrch\fcs0 \v\f31506\fs22 MSG_SET will only impact the current value\'85 \par }\pard \ltrpar\ql \li0\ri0\sb180\widctlpar\wrapdefault\nooverflow\faroman\rin0\lin0\itap0 {\rtlch\fcs1 \af0 \ltrch\fcs0 \v\f31506 \par }\pard \ltrpar\ql \li0\ri0\widctlpar\wrapdefault\nooverflow\faroman\rin0\lin0\itap0 {\rtlch\fcs1 \af0 \ltrch\fcs0 \v\f31506\cf6 \page [Note] \endash DONE \par }\pard \ltrpar\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af0\afs22 \ltrch\fcs0 \v\f31506\fs22 ICAP_XFERMECH (ch. 10, pg. 10-197): under Application section it reads, \'93Th e current value of ICAP_XFERMECH must match the data argument type when starting the transfer using the triplet: DG_IMAGE / DAT_IMAGExxxxXFER / MSG_GET.\'94 If it does not match, what should happen? \par (NOTE: already discussed in the working group meeting on 17 July 2012) \par \par {\listtext\pard\plain\ltrpar \rtlch\fcs1 \af0\afs22 \ltrch\fcs0 \v\fs22 \hich\af0\dbch\af0\loch\f0 -\tab}}\pard \ltrpar\ql \fi-360\li720\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\ls21\adjustright\rin0\lin720\itap0 {\rtlch\fcs1 \af0\afs22 \ltrch\fcs0 \v\f31506\fs22 My recollection from the meeting is as follows: \par }\pard \ltrpar\ql \li720\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin720\itap0 {\rtlch\fcs1 \af0\afs22 \ltrch\fcs0 \v\f31506\fs22 \par {\listtext\pard\plain\ltrpar \rtlch\fcs1 \af0\afs22 \ltrch\fcs0 \v\fs22 \hich\af0\dbch\af0\loch\f0 -\tab}}\pard \ltrpar\ql \fi-360\li720\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\ls21\adjustright\rin0\lin720\itap0 {\rtlch\fcs1 \af0\afs22 \ltrch\fcs0 \v\f31506\fs22 The TWAIN Spec says that apps need to set ICAP_XFERMECH in state 4 to the transfer mechanism that\rquote ll be used in state 6 and 7. However, some apps don\rquote t bother to do this. \par }\pard\plain \ltrpar\s199\ql \li720\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin720\itap0 \rtlch\fcs1 \af37\afs22\alang1025 \ltrch\fcs0 \f37\fs22\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 {\rtlch\fcs1 \af0 \ltrch\fcs0 \v\f31506 \par {\listtext\pard\plain\ltrpar \rtlch\fcs1 \af0\afs22 \ltrch\fcs0 \v\fs22 \hich\af0\dbch\af0\loch\f0 -\tab}}\pard\plain \ltrpar\ql \fi-360\li720\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\ls21\adjustright\rin0\lin720\itap0 \rtlch\fcs1 \af44\afs20\alang1025 \ltrch\fcs0 \f44\fs20\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 {\rtlch\fcs1 \af0\afs22 \ltrch\fcs0 \v\f31506\fs22 The thought is to leave the requirement intact, but add a bit to the Legacy Issues section warning driver writers not to assume this will happen. \par }\pard \ltrpar\ql \li0\ri0\sb180\widctlpar\wrapdefault\nooverflow\faroman\rin0\lin0\itap0 {\rtlch\fcs1 \af0 \ltrch\fcs0 \v\f31506 \par }\pard \ltrpar\ql \li0\ri0\widctlpar\wrapdefault\nooverflow\faroman\rin0\lin0\itap0 {\rtlch\fcs1 \af0 \ltrch\fcs0 \v\f31506\cf6 [Note] \endash DONE \par }\pard \ltrpar\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af0\afs22 \ltrch\fcs0 \v\f31506\fs22 (ch. 2, pg. 2-16) I think a couple of string types are missing. It says: \'93There are }{\rtlch\fcs1 \af0\afs22 \ltrch\fcs0 \v\f31506\fs22\ul four}{\rtlch\fcs1 \af0\afs22 \ltrch\fcs0 \v\f31506\fs22 types of TWAIN strings defined for developer use:\'94 , and then lists TW_STR32, TW_STR64, TW_STR128, and TW_STR256. But in twain.h, there are now TW_STR1024 and a TW_UNI512 types defined. Should these be added, for a total of 6? \par {\listtext\pard\plain\ltrpar \rtlch\fcs1 \af0\afs20 \ltrch\fcs0 \v\fs20 \hich\af0\dbch\af0\loch\f0 -\tab}}\pard \ltrpar\ql \fi-360\li720\ri0\sb180\widctlpar\wrapdefault\nooverflow\faroman\ls21\rin0\lin720\itap0 {\rtlch\fcs1 \af0 \ltrch\fcs0 \v\f31506 TW_STR1024 and TW_UNI512 have been deprecated, so the number \lquote four\rquote is right.}{\rtlch\fcs1 \ab\af0\afs22 \ltrch\fcs0 \b\v\f31506\fs22 \par }\pard \ltrpar\ql \li0\ri0\sb180\widctlpar\wrapdefault\nooverflow\faroman\rin0\lin0\itap0 {\rtlch\fcs1 \af0 \ltrch\fcs0 \v\f31506 \par }\pard \ltrpar\ql \li0\ri0\widctlpar\wrapdefault\nooverflow\faroman\rin0\lin0\itap0 {\rtlch\fcs1 \af0 \ltrch\fcs0 \v\f31506\cf6 [Note] \endash DONE \par }\pard \ltrpar\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \v\f31506\fs22 Do I understand correctly that MSG_GETDEFAULT should return the Source\rquote s *}{\rtlch\fcs1 \ab\af37\afs22 \ltrch\fcs0 \b\v\f31506\fs22 Preferred}{\rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \v\f31506\fs22 * default. But this may *}{\rtlch\fcs1 \ab\af37\afs22 \ltrch\fcs0 \b\v\f31506\fs22 not}{\rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \v\f31506\fs22 * be the value set when calling MSG_RESET, since MSG_RESET resets to the TWAIN default? If there is a Mandatory default, does MSG_GETDEFAULT need to return the mandatory default? \par }\pard \ltrpar\ql \li0\ri0\sb180\widctlpar\wrapdefault\nooverflow\faroman\rin0\lin0\itap0 {\rtlch\fcs1 \af0 \ltrch\fcs0 \v\f31506 \par }\pard \ltrpar\ql \li0\ri0\widctlpar\wrapdefault\nooverflow\faroman\rin0\lin0\itap0 {\rtlch\fcs1 \af0 \ltrch\fcs0 \v\f31506\cf6 [Note] \endash DONE \par }\pard \ltrpar\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \v\f31506\fs22 So is MSG_RESET meant to reset to the value listed in Ch. 10 always? (whether or not this is a mandatory default) Only if Ch. 10 says \'93no default\'94 can the source reset it to a preferred or user value? \par }\pard\plain \ltrpar\s199\ql \li360\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin360\itap0 \rtlch\fcs1 \af37\afs22\alang1025 \ltrch\fcs0 \f37\fs22\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 {\rtlch\fcs1 \af37 \ltrch\fcs0 \i\v\f31506\cf6 \par }\pard\plain \ltrpar\ql \li720\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin720\itap0 \rtlch\fcs1 \af44\afs20\alang1025 \ltrch\fcs0 \f44\fs20\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 {\rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \v\f31506\fs22\cf23 \par }{\*\themedata 504b030414000600080000002100e9de0fbfff0000001c020000130000005b436f6e74656e745f54797065735d2e786d6cac91cb4ec3301045f748fc83e52d4a 9cb2400825e982c78ec7a27cc0c8992416c9d8b2a755fbf74cd25442a820166c2cd933f79e3be372bd1f07b5c3989ca74aaff2422b24eb1b475da5df374fd9ad 5689811a183c61a50f98f4babebc2837878049899a52a57be670674cb23d8e90721f90a4d2fa3802cb35762680fd800ecd7551dc18eb899138e3c943d7e503b6 b01d583deee5f99824e290b4ba3f364eac4a430883b3c092d4eca8f946c916422ecab927f52ea42b89a1cd59c254f919b0e85e6535d135a8de20f20b8c12c3b0 0c895fcf6720192de6bf3b9e89ecdbd6596cbcdd8eb28e7c365ecc4ec1ff1460f53fe813d3cc7f5b7f020000ffff0300504b030414000600080000002100a5d6 a7e7c0000000360100000b0000005f72656c732f2e72656c73848fcf6ac3300c87ef85bd83d17d51d2c31825762fa590432fa37d00e1287f68221bdb1bebdb4f c7060abb0884a4eff7a93dfeae8bf9e194e720169aaa06c3e2433fcb68e1763dbf7f82c985a4a725085b787086a37bdbb55fbc50d1a33ccd311ba548b6309512 0f88d94fbc52ae4264d1c910d24a45db3462247fa791715fd71f989e19e0364cd3f51652d73760ae8fa8c9ffb3c330cc9e4fc17faf2ce545046e37944c69e462 a1a82fe353bd90a865aad41ed0b5b8f9d6fd010000ffff0300504b0304140006000800000021006b799616830000008a0000001c0000007468656d652f746865 6d652f7468656d654d616e616765722e786d6c0ccc4d0ac3201040e17da17790d93763bb284562b2cbaebbf600439c1a41c7a0d29fdbd7e5e38337cedf14d59b 4b0d592c9c070d8a65cd2e88b7f07c2ca71ba8da481cc52c6ce1c715e6e97818c9b48d13df49c873517d23d59085adb5dd20d6b52bd521ef2cdd5eb9246a3d8b 4757e8d3f729e245eb2b260a0238fd010000ffff0300504b03041400060008000000210096b5ade296060000501b0000160000007468656d652f7468656d652f 7468656d65312e786d6cec594f6fdb3614bf0fd87720746f6327761a07758ad8b19b2d4d1bc46e871e698996d850a240d2497d1bdae38001c3ba618715d86d87 615b8116d8a5fb34d93a6c1dd0afb0475292c5585e9236d88aad3e2412f9e3fbff1e1fa9abd7eec70c1d1221294fda5efd72cd4324f1794093b0eddd1ef62fad 79482a9c0498f184b4bd2991deb58df7dfbb8ad755446282607d22d771db8b944ad79796a40fc3585ee62949606ecc458c15bc8a702910f808e8c66c69b9565b 5d8a314d3c94e018c8de1a8fa94fd05093f43672e23d06af89927ac06762a049136785c10607758d9053d965021d62d6f6804fc08f86e4bef210c352c144dbab 999fb7b4717509af678b985ab0b6b4ae6f7ed9ba6c4170b06c788a705430adf71bad2b5b057d03606a1ed7ebf5babd7a41cf00b0ef83a6569632cd467faddec9 699640f6719e76b7d6ac355c7c89feca9cccad4ea7d36c65b258a206641f1b73f8b5da6a6373d9c11b90c537e7f08dce66b7bbeae00dc8e257e7f0fd2badd586 8b37a088d1e4600ead1ddaef67d40bc898b3ed4af81ac0d76a197c86826828a24bb318f3442d8ab518dfe3a20f000d6458d104a9694ac6d88728eee2782428d6 0cf03ac1a5193be4cbb921cd0b495fd054b5bd0f530c1931a3f7eaf9f7af9e3f45c70f9e1d3ff8e9f8e1c3e3073f5a42ceaa6d9c84e5552fbffdeccfc71fa33f 9e7ef3f2d117d57859c6fffac327bffcfc793510d26726ce8b2f9ffcf6ecc98baf3efdfdbb4715f04d814765f890c644a29be408edf3181433567125272371be 15c308d3f28acd249438c19a4b05fd9e8a1cf4cd296699771c393ac4b5e01d01e5a30a787d72cf1178108989a2159c77a2d801ee72ce3a5c545a6147f32a9979 3849c26ae66252c6ed637c58c5bb8b13c7bfbd490a75330f4b47f16e441c31f7184e140e494214d273fc80900aedee52ead87597fa824b3e56e82e451d4c2b4d 32a423279a668bb6690c7e9956e90cfe766cb37b077538abd27a8b1cba48c80acc2a841f12e698f13a9e281c57911ce298950d7e03aba84ac8c154f8655c4f2a f074481847bd804859b5e696007d4b4edfc150b12addbecba6b18b148a1e54d1bc81392f23b7f84137c2715a851dd0242a633f900710a218ed715505dfe56e86 e877f0034e16bafb0e258ebb4faf06b769e888340b103d3311da9750aa9d0a1cd3e4efca31a3508f6d0c5c5c398602f8e2ebc71591f5b616e24dd893aa3261fb 44f95d843b5974bb5c04f4edafb95b7892ec1108f3f98de75dc97d5772bdff7cc95d94cf672db4b3da0a6557f70db629362d72bcb0431e53c6066acac80d699a 6409fb44d08741bdce9c0e4971624a2378cceaba830b05366b90e0ea23aaa241845368b0eb9e2612ca8c742851ca251ceccc70256d8d87265dd96361531f186c 3d9058edf2c00eafe8e1fc5c509031bb4d680e9f39a3154de0accc56ae644441edd76156d7429d995bdd88664a9dc3ad50197c38af1a0c16d684060441db0256 5e85f3b9660d0713cc48a0ed6ef7dedc2dc60b17e92219e180643ed27acffba86e9c94c78ab90980d8a9f0913ee49d62b512b79626fb06dccee2a432bbc60276 b9f7dec44b7904cfbca4f3f6443ab2a49c9c2c41476dafd55c6e7ac8c769db1bc399161ee314bc2e75cf8759081743be1236ec4f4d6693e5336fb672c5dc24a8 c33585b5fb9cc24e1d4885545b58463634cc5416022cd19cacfccb4d30eb45296023fd35a458598360f8d7a4003bbaae25e331f155d9d9a5116d3bfb9a95523e 51440ca2e0088dd844ec6370bf0e55d027a012ae264c45d02f708fa6ad6da6dce29c255df9f6cae0ec38666984b372ab5334cf640b37795cc860de4ae2816e95 b21be5ceaf8a49f90b52a51cc6ff3355f47e0237052b81f6800fd7b802239daf6d8f0b1571a8426944fdbe80c6c1d40e8816b88b8569082ab84c36ff0539d4ff 6dce591a26ade1c0a7f669880485fd484582903d284b26fa4e2156cff62e4b9265844c4495c495a9157b440e091bea1ab8aaf7760f4510eaa69a6465c0e04ec6 9ffb9e65d028d44d4e39df9c1a52ecbd3607fee9cec7263328e5d661d3d0e4f62f44acd855ed7ab33cdf7bcb8ae889599bd5c8b3029895b6825696f6af29c239 b75a5bb1e6345e6ee6c28117e73586c1a2214ae1be07e93fb0ff51e133fb65426fa843be0fb515c187064d0cc206a2fa926d3c902e907670048d931db4c1a449 59d366ad93b65abe595f70a75bf03d616c2dd959fc7d4e6317cd99cbcec9c58b34766661c7d6766ca1a9c1b327531486c6f941c638c67cd22a7f75e2a37be0e8 2db8df9f30254d30c1372581a1f51c983c80e4b71ccdd28dbf000000ffff0300504b0304140006000800000021000dd1909fb60000001b010000270000007468 656d652f7468656d652f5f72656c732f7468656d654d616e616765722e786d6c2e72656c73848f4d0ac2301484f78277086f6fd3ba109126dd88d0add40384e4 350d363f2451eced0dae2c082e8761be9969bb979dc9136332de3168aa1a083ae995719ac16db8ec8e4052164e89d93b64b060828e6f37ed1567914b284d2624 52282e3198720e274a939cd08a54f980ae38a38f56e422a3a641c8bbd048f7757da0f19b017cc524bd62107bd5001996509affb3fd381a89672f1f165dfe5141 73d9850528a2c6cce0239baa4c04ca5bbabac4df000000ffff0300504b01022d0014000600080000002100e9de0fbfff0000001c020000130000000000000000 0000000000000000005b436f6e74656e745f54797065735d2e786d6c504b01022d0014000600080000002100a5d6a7e7c0000000360100000b00000000000000 000000000000300100005f72656c732f2e72656c73504b01022d00140006000800000021006b799616830000008a0000001c0000000000000000000000000019 0200007468656d652f7468656d652f7468656d654d616e616765722e786d6c504b01022d001400060008000000210096b5ade296060000501b00001600000000 000000000000000000d60200007468656d652f7468656d652f7468656d65312e786d6c504b01022d00140006000800000021000dd1909fb60000001b01000027 00000000000000000000000000a00900007468656d652f7468656d652f5f72656c732f7468656d654d616e616765722e786d6c2e72656c73504b050600000000050005005d0100009b0a00000000} {\*\colorschememapping 3c3f786d6c2076657273696f6e3d22312e302220656e636f64696e673d225554462d3822207374616e64616c6f6e653d22796573223f3e0d0a3c613a636c724d 617020786d6c6e733a613d22687474703a2f2f736368656d61732e6f70656e786d6c666f726d6174732e6f72672f64726177696e676d6c2f323030362f6d6169 6e22206267313d226c743122207478313d22646b3122206267323d226c743222207478323d22646b322220616363656e74313d22616363656e74312220616363 656e74323d22616363656e74322220616363656e74333d22616363656e74332220616363656e74343d22616363656e74342220616363656e74353d22616363656e74352220616363656e74363d22616363656e74362220686c696e6b3d22686c696e6b2220666f6c486c696e6b3d22666f6c486c696e6b222f3e} {\*\latentstyles\lsdstimax377\lsdlockeddef0\lsdsemihiddendef0\lsdunhideuseddef0\lsdqformatdef0\lsdprioritydef99{\lsdlockedexcept \lsdqformat1 \lsdpriority0 \lsdlocked0 Normal;\lsdqformat1 \lsdpriority0 \lsdlocked0 heading 1; \lsdqformat1 \lsdpriority0 \lsdlocked0 heading 2;\lsdqformat1 \lsdpriority0 \lsdlocked0 heading 3;\lsdqformat1 \lsdpriority0 \lsdlocked0 heading 4;\lsdqformat1 \lsdpriority0 \lsdlocked0 heading 5;\lsdqformat1 \lsdpriority0 \lsdlocked0 heading 6; \lsdqformat1 \lsdpriority0 \lsdlocked0 heading 7;\lsdqformat1 \lsdpriority0 \lsdlocked0 heading 8;\lsdqformat1 \lsdpriority0 \lsdlocked0 heading 9;\lsdsemihidden1 \lsdunhideused1 index 1;\lsdsemihidden1 \lsdunhideused1 index 2; \lsdsemihidden1 \lsdunhideused1 index 3;\lsdsemihidden1 \lsdunhideused1 index 4;\lsdsemihidden1 \lsdunhideused1 index 5;\lsdsemihidden1 \lsdunhideused1 index 6;\lsdsemihidden1 \lsdunhideused1 index 7;\lsdsemihidden1 \lsdunhideused1 index 8; \lsdsemihidden1 \lsdunhideused1 index 9;\lsdpriority39 \lsdlocked0 toc 1;\lsdpriority39 \lsdlocked0 toc 2;\lsdpriority0 \lsdlocked0 toc 3;\lsdpriority0 \lsdlocked0 toc 4;\lsdpriority0 \lsdlocked0 toc 5;\lsdpriority0 \lsdlocked0 toc 6; \lsdpriority0 \lsdlocked0 toc 7;\lsdpriority0 \lsdlocked0 toc 8;\lsdpriority0 \lsdlocked0 toc 9;\lsdsemihidden1 \lsdunhideused1 Normal Indent;\lsdsemihidden1 \lsdunhideused1 footnote text;\lsdsemihidden1 \lsdunhideused1 annotation text; \lsdsemihidden1 \lsdunhideused1 header;\lsdsemihidden1 \lsdunhideused1 footer;\lsdsemihidden1 \lsdunhideused1 index heading;\lsdqformat1 \lsdpriority0 \lsdlocked0 caption;\lsdsemihidden1 \lsdunhideused1 table of figures; \lsdsemihidden1 \lsdunhideused1 envelope address;\lsdsemihidden1 \lsdunhideused1 envelope return;\lsdsemihidden1 \lsdunhideused1 footnote reference;\lsdsemihidden1 \lsdunhideused1 annotation reference;\lsdsemihidden1 \lsdunhideused1 line number; \lsdsemihidden1 \lsdunhideused1 page number;\lsdsemihidden1 \lsdunhideused1 endnote reference;\lsdsemihidden1 \lsdunhideused1 endnote text;\lsdsemihidden1 \lsdunhideused1 table of authorities;\lsdsemihidden1 \lsdunhideused1 macro; \lsdsemihidden1 \lsdunhideused1 toa heading;\lsdsemihidden1 \lsdunhideused1 List;\lsdsemihidden1 \lsdunhideused1 List Bullet;\lsdsemihidden1 \lsdunhideused1 List Number;\lsdsemihidden1 \lsdunhideused1 List 2;\lsdsemihidden1 \lsdunhideused1 List 3; \lsdsemihidden1 \lsdunhideused1 List 4;\lsdsemihidden1 \lsdunhideused1 List 5;\lsdsemihidden1 \lsdunhideused1 List Bullet 2;\lsdsemihidden1 \lsdunhideused1 List Bullet 3;\lsdsemihidden1 \lsdunhideused1 List Bullet 4; \lsdsemihidden1 \lsdunhideused1 List Bullet 5;\lsdsemihidden1 \lsdunhideused1 List Number 2;\lsdsemihidden1 \lsdunhideused1 List Number 3;\lsdsemihidden1 \lsdunhideused1 List Number 4;\lsdsemihidden1 \lsdunhideused1 List Number 5; \lsdqformat1 \lsdpriority0 \lsdlocked0 Title;\lsdsemihidden1 \lsdunhideused1 Closing;\lsdsemihidden1 \lsdunhideused1 Signature;\lsdpriority0 \lsdlocked0 Default Paragraph Font;\lsdsemihidden1 \lsdunhideused1 Body Text; \lsdsemihidden1 \lsdunhideused1 Body Text Indent;\lsdsemihidden1 \lsdunhideused1 List Continue;\lsdsemihidden1 \lsdunhideused1 List Continue 2;\lsdsemihidden1 \lsdunhideused1 List Continue 3;\lsdsemihidden1 \lsdunhideused1 List Continue 4; \lsdsemihidden1 \lsdunhideused1 List Continue 5;\lsdsemihidden1 \lsdunhideused1 Message Header;\lsdqformat1 \lsdpriority0 \lsdlocked0 Subtitle;\lsdsemihidden1 \lsdunhideused1 Salutation;\lsdsemihidden1 \lsdunhideused1 Date; \lsdsemihidden1 \lsdunhideused1 Body Text First Indent;\lsdsemihidden1 \lsdunhideused1 Body Text First Indent 2;\lsdsemihidden1 \lsdunhideused1 Note Heading;\lsdsemihidden1 \lsdunhideused1 Body Text 2;\lsdsemihidden1 \lsdunhideused1 Body Text 3; \lsdsemihidden1 \lsdunhideused1 Body Text Indent 2;\lsdsemihidden1 \lsdunhideused1 Body Text Indent 3;\lsdsemihidden1 \lsdunhideused1 Block Text;\lsdsemihidden1 \lsdunhideused1 Hyperlink;\lsdsemihidden1 \lsdunhideused1 FollowedHyperlink; \lsdqformat1 \lsdpriority0 \lsdlocked0 Strong;\lsdqformat1 \lsdpriority0 \lsdlocked0 Emphasis;\lsdsemihidden1 \lsdunhideused1 Document Map;\lsdsemihidden1 \lsdunhideused1 Plain Text;\lsdsemihidden1 \lsdunhideused1 E-mail Signature; \lsdsemihidden1 \lsdunhideused1 HTML Top of Form;\lsdsemihidden1 \lsdunhideused1 HTML Bottom of Form;\lsdsemihidden1 \lsdunhideused1 Normal (Web);\lsdsemihidden1 \lsdunhideused1 HTML Acronym;\lsdsemihidden1 \lsdunhideused1 HTML Address; \lsdsemihidden1 \lsdunhideused1 HTML Cite;\lsdsemihidden1 \lsdunhideused1 HTML Code;\lsdsemihidden1 \lsdunhideused1 HTML Definition;\lsdsemihidden1 \lsdunhideused1 HTML Keyboard;\lsdsemihidden1 \lsdunhideused1 HTML Preformatted; \lsdsemihidden1 \lsdunhideused1 HTML Sample;\lsdsemihidden1 \lsdunhideused1 HTML Typewriter;\lsdsemihidden1 \lsdunhideused1 HTML Variable;Normal Table;\lsdsemihidden1 \lsdunhideused1 annotation subject;\lsdsemihidden1 \lsdunhideused1 No List; \lsdsemihidden1 \lsdunhideused1 Outline List 1;\lsdsemihidden1 \lsdunhideused1 Outline List 2;\lsdsemihidden1 \lsdunhideused1 Outline List 3;Table Simple 1;Table Simple 2;Table Simple 3;Table Classic 1;Table Classic 2;Table Classic 3;Table Classic 4; Table Colorful 1;Table Colorful 2;Table Colorful 3;Table Columns 1;Table Columns 2;Table Columns 3;Table Columns 4;Table Columns 5;Table Grid 1;Table Grid 2;Table Grid 3;Table Grid 4;Table Grid 5;Table Grid 6;Table Grid 7;Table Grid 8;Table List 1; Table List 2;Table List 3;Table List 4;Table List 5;Table List 6;Table List 7;Table List 8;Table 3D effects 1;Table 3D effects 2;Table 3D effects 3;Table Contemporary;Table Elegant;Table Professional;Table Subtle 1;Table Subtle 2;Table Web 1;Table Web 2; Table Web 3;\lsdsemihidden1 \lsdunhideused1 Balloon Text;\lsdpriority0 \lsdlocked0 Table Grid;Table Theme;\lsdsemihidden1 \lsdlocked0 Placeholder Text;\lsdqformat1 \lsdpriority1 \lsdlocked0 No Spacing;\lsdpriority60 \lsdlocked0 Light Shading; \lsdpriority61 \lsdlocked0 Light List;\lsdpriority62 \lsdlocked0 Light Grid;\lsdpriority63 \lsdlocked0 Medium Shading 1;\lsdpriority64 \lsdlocked0 Medium Shading 2;\lsdpriority65 \lsdlocked0 Medium List 1;\lsdpriority66 \lsdlocked0 Medium List 2; \lsdpriority67 \lsdlocked0 Medium Grid 1;\lsdpriority68 \lsdlocked0 Medium Grid 2;\lsdpriority69 \lsdlocked0 Medium Grid 3;\lsdpriority70 \lsdlocked0 Dark List;\lsdpriority71 \lsdlocked0 Colorful Shading;\lsdpriority72 \lsdlocked0 Colorful List; \lsdpriority73 \lsdlocked0 Colorful Grid;\lsdpriority60 \lsdlocked0 Light Shading Accent 1;\lsdpriority61 \lsdlocked0 Light List Accent 1;\lsdpriority62 \lsdlocked0 Light Grid Accent 1;\lsdpriority63 \lsdlocked0 Medium Shading 1 Accent 1; \lsdpriority64 \lsdlocked0 Medium Shading 2 Accent 1;\lsdpriority65 \lsdlocked0 Medium List 1 Accent 1;\lsdqformat1 \lsdpriority34 \lsdlocked0 List Paragraph;\lsdqformat1 \lsdpriority29 \lsdlocked0 Quote; \lsdqformat1 \lsdpriority30 \lsdlocked0 Intense Quote;\lsdpriority66 \lsdlocked0 Medium List 2 Accent 1;\lsdpriority67 \lsdlocked0 Medium Grid 1 Accent 1;\lsdpriority68 \lsdlocked0 Medium Grid 2 Accent 1;\lsdpriority69 \lsdlocked0 Medium Grid 3 Accent 1; \lsdpriority70 \lsdlocked0 Dark List Accent 1;\lsdpriority71 \lsdlocked0 Colorful Shading Accent 1;\lsdpriority72 \lsdlocked0 Colorful List Accent 1;\lsdpriority73 \lsdlocked0 Colorful Grid Accent 1;\lsdpriority60 \lsdlocked0 Light Shading Accent 2; \lsdpriority61 \lsdlocked0 Light List Accent 2;\lsdpriority62 \lsdlocked0 Light Grid Accent 2;\lsdpriority63 \lsdlocked0 Medium Shading 1 Accent 2;\lsdpriority64 \lsdlocked0 Medium Shading 2 Accent 2;\lsdpriority65 \lsdlocked0 Medium List 1 Accent 2; \lsdpriority66 \lsdlocked0 Medium List 2 Accent 2;\lsdpriority67 \lsdlocked0 Medium Grid 1 Accent 2;\lsdpriority68 \lsdlocked0 Medium Grid 2 Accent 2;\lsdpriority69 \lsdlocked0 Medium Grid 3 Accent 2;\lsdpriority70 \lsdlocked0 Dark List Accent 2; \lsdpriority71 \lsdlocked0 Colorful Shading Accent 2;\lsdpriority72 \lsdlocked0 Colorful List Accent 2;\lsdpriority73 \lsdlocked0 Colorful Grid Accent 2;\lsdpriority60 \lsdlocked0 Light Shading Accent 3;\lsdpriority61 \lsdlocked0 Light List Accent 3; \lsdpriority62 \lsdlocked0 Light Grid Accent 3;\lsdpriority63 \lsdlocked0 Medium Shading 1 Accent 3;\lsdpriority64 \lsdlocked0 Medium Shading 2 Accent 3;\lsdpriority65 \lsdlocked0 Medium List 1 Accent 3;\lsdpriority66 \lsdlocked0 Medium List 2 Accent 3; \lsdpriority67 \lsdlocked0 Medium Grid 1 Accent 3;\lsdpriority68 \lsdlocked0 Medium Grid 2 Accent 3;\lsdpriority69 \lsdlocked0 Medium Grid 3 Accent 3;\lsdpriority70 \lsdlocked0 Dark List Accent 3;\lsdpriority71 \lsdlocked0 Colorful Shading Accent 3; \lsdpriority72 \lsdlocked0 Colorful List Accent 3;\lsdpriority73 \lsdlocked0 Colorful Grid Accent 3;\lsdpriority60 \lsdlocked0 Light Shading Accent 4;\lsdpriority61 \lsdlocked0 Light List Accent 4;\lsdpriority62 \lsdlocked0 Light Grid Accent 4; \lsdpriority63 \lsdlocked0 Medium Shading 1 Accent 4;\lsdpriority64 \lsdlocked0 Medium Shading 2 Accent 4;\lsdpriority65 \lsdlocked0 Medium List 1 Accent 4;\lsdpriority66 \lsdlocked0 Medium List 2 Accent 4; \lsdpriority67 \lsdlocked0 Medium Grid 1 Accent 4;\lsdpriority68 \lsdlocked0 Medium Grid 2 Accent 4;\lsdpriority69 \lsdlocked0 Medium Grid 3 Accent 4;\lsdpriority70 \lsdlocked0 Dark List Accent 4;\lsdpriority71 \lsdlocked0 Colorful Shading Accent 4; \lsdpriority72 \lsdlocked0 Colorful List Accent 4;\lsdpriority73 \lsdlocked0 Colorful Grid Accent 4;\lsdpriority60 \lsdlocked0 Light Shading Accent 5;\lsdpriority61 \lsdlocked0 Light List Accent 5;\lsdpriority62 \lsdlocked0 Light Grid Accent 5; \lsdpriority63 \lsdlocked0 Medium Shading 1 Accent 5;\lsdpriority64 \lsdlocked0 Medium Shading 2 Accent 5;\lsdpriority65 \lsdlocked0 Medium List 1 Accent 5;\lsdpriority66 \lsdlocked0 Medium List 2 Accent 5; \lsdpriority67 \lsdlocked0 Medium Grid 1 Accent 5;\lsdpriority68 \lsdlocked0 Medium Grid 2 Accent 5;\lsdpriority69 \lsdlocked0 Medium Grid 3 Accent 5;\lsdpriority70 \lsdlocked0 Dark List Accent 5;\lsdpriority71 \lsdlocked0 Colorful Shading Accent 5; \lsdpriority72 \lsdlocked0 Colorful List Accent 5;\lsdpriority73 \lsdlocked0 Colorful Grid Accent 5;\lsdpriority60 \lsdlocked0 Light Shading Accent 6;\lsdpriority61 \lsdlocked0 Light List Accent 6;\lsdpriority62 \lsdlocked0 Light Grid Accent 6; \lsdpriority63 \lsdlocked0 Medium Shading 1 Accent 6;\lsdpriority64 \lsdlocked0 Medium Shading 2 Accent 6;\lsdpriority65 \lsdlocked0 Medium List 1 Accent 6;\lsdpriority66 \lsdlocked0 Medium List 2 Accent 6; \lsdpriority67 \lsdlocked0 Medium Grid 1 Accent 6;\lsdpriority68 \lsdlocked0 Medium Grid 2 Accent 6;\lsdpriority69 \lsdlocked0 Medium Grid 3 Accent 6;\lsdpriority70 \lsdlocked0 Dark List Accent 6;\lsdpriority71 \lsdlocked0 Colorful Shading Accent 6; \lsdpriority72 \lsdlocked0 Colorful List Accent 6;\lsdpriority73 \lsdlocked0 Colorful Grid Accent 6;\lsdqformat1 \lsdpriority19 \lsdlocked0 Subtle Emphasis;\lsdqformat1 \lsdpriority21 \lsdlocked0 Intense Emphasis; \lsdqformat1 \lsdpriority31 \lsdlocked0 Subtle Reference;\lsdqformat1 \lsdpriority32 \lsdlocked0 Intense Reference;\lsdqformat1 \lsdpriority33 \lsdlocked0 Book Title;\lsdsemihidden1 \lsdunhideused1 \lsdpriority37 \lsdlocked0 Bibliography; \lsdsemihidden1 \lsdunhideused1 \lsdqformat1 \lsdpriority39 \lsdlocked0 TOC Heading;\lsdpriority41 \lsdlocked0 Plain Table 1;\lsdpriority42 \lsdlocked0 Plain Table 2;\lsdpriority43 \lsdlocked0 Plain Table 3;\lsdpriority44 \lsdlocked0 Plain Table 4; \lsdpriority45 \lsdlocked0 Plain Table 5;\lsdpriority40 \lsdlocked0 Grid Table Light;\lsdpriority46 \lsdlocked0 Grid Table 1 Light;\lsdpriority47 \lsdlocked0 Grid Table 2;\lsdpriority48 \lsdlocked0 Grid Table 3;\lsdpriority49 \lsdlocked0 Grid Table 4; \lsdpriority50 \lsdlocked0 Grid Table 5 Dark;\lsdpriority51 \lsdlocked0 Grid Table 6 Colorful;\lsdpriority52 \lsdlocked0 Grid Table 7 Colorful;\lsdpriority46 \lsdlocked0 Grid Table 1 Light Accent 1;\lsdpriority47 \lsdlocked0 Grid Table 2 Accent 1; \lsdpriority48 \lsdlocked0 Grid Table 3 Accent 1;\lsdpriority49 \lsdlocked0 Grid Table 4 Accent 1;\lsdpriority50 \lsdlocked0 Grid Table 5 Dark Accent 1;\lsdpriority51 \lsdlocked0 Grid Table 6 Colorful Accent 1; \lsdpriority52 \lsdlocked0 Grid Table 7 Colorful Accent 1;\lsdpriority46 \lsdlocked0 Grid Table 1 Light Accent 2;\lsdpriority47 \lsdlocked0 Grid Table 2 Accent 2;\lsdpriority48 \lsdlocked0 Grid Table 3 Accent 2; \lsdpriority49 \lsdlocked0 Grid Table 4 Accent 2;\lsdpriority50 \lsdlocked0 Grid Table 5 Dark Accent 2;\lsdpriority51 \lsdlocked0 Grid Table 6 Colorful Accent 2;\lsdpriority52 \lsdlocked0 Grid Table 7 Colorful Accent 2; \lsdpriority46 \lsdlocked0 Grid Table 1 Light Accent 3;\lsdpriority47 \lsdlocked0 Grid Table 2 Accent 3;\lsdpriority48 \lsdlocked0 Grid Table 3 Accent 3;\lsdpriority49 \lsdlocked0 Grid Table 4 Accent 3; \lsdpriority50 \lsdlocked0 Grid Table 5 Dark Accent 3;\lsdpriority51 \lsdlocked0 Grid Table 6 Colorful Accent 3;\lsdpriority52 \lsdlocked0 Grid Table 7 Colorful Accent 3;\lsdpriority46 \lsdlocked0 Grid Table 1 Light Accent 4; \lsdpriority47 \lsdlocked0 Grid Table 2 Accent 4;\lsdpriority48 \lsdlocked0 Grid Table 3 Accent 4;\lsdpriority49 \lsdlocked0 Grid Table 4 Accent 4;\lsdpriority50 \lsdlocked0 Grid Table 5 Dark Accent 4; \lsdpriority51 \lsdlocked0 Grid Table 6 Colorful Accent 4;\lsdpriority52 \lsdlocked0 Grid Table 7 Colorful Accent 4;\lsdpriority46 \lsdlocked0 Grid Table 1 Light Accent 5;\lsdpriority47 \lsdlocked0 Grid Table 2 Accent 5; \lsdpriority48 \lsdlocked0 Grid Table 3 Accent 5;\lsdpriority49 \lsdlocked0 Grid Table 4 Accent 5;\lsdpriority50 \lsdlocked0 Grid Table 5 Dark Accent 5;\lsdpriority51 \lsdlocked0 Grid Table 6 Colorful Accent 5; \lsdpriority52 \lsdlocked0 Grid Table 7 Colorful Accent 5;\lsdpriority46 \lsdlocked0 Grid Table 1 Light Accent 6;\lsdpriority47 \lsdlocked0 Grid Table 2 Accent 6;\lsdpriority48 \lsdlocked0 Grid Table 3 Accent 6; \lsdpriority49 \lsdlocked0 Grid Table 4 Accent 6;\lsdpriority50 \lsdlocked0 Grid Table 5 Dark Accent 6;\lsdpriority51 \lsdlocked0 Grid Table 6 Colorful Accent 6;\lsdpriority52 \lsdlocked0 Grid Table 7 Colorful Accent 6; \lsdpriority46 \lsdlocked0 List Table 1 Light;\lsdpriority47 \lsdlocked0 List Table 2;\lsdpriority48 \lsdlocked0 List Table 3;\lsdpriority49 \lsdlocked0 List Table 4;\lsdpriority50 \lsdlocked0 List Table 5 Dark; \lsdpriority51 \lsdlocked0 List Table 6 Colorful;\lsdpriority52 \lsdlocked0 List Table 7 Colorful;\lsdpriority46 \lsdlocked0 List Table 1 Light Accent 1;\lsdpriority47 \lsdlocked0 List Table 2 Accent 1;\lsdpriority48 \lsdlocked0 List Table 3 Accent 1; \lsdpriority49 \lsdlocked0 List Table 4 Accent 1;\lsdpriority50 \lsdlocked0 List Table 5 Dark Accent 1;\lsdpriority51 \lsdlocked0 List Table 6 Colorful Accent 1;\lsdpriority52 \lsdlocked0 List Table 7 Colorful Accent 1; \lsdpriority46 \lsdlocked0 List Table 1 Light Accent 2;\lsdpriority47 \lsdlocked0 List Table 2 Accent 2;\lsdpriority48 \lsdlocked0 List Table 3 Accent 2;\lsdpriority49 \lsdlocked0 List Table 4 Accent 2; \lsdpriority50 \lsdlocked0 List Table 5 Dark Accent 2;\lsdpriority51 \lsdlocked0 List Table 6 Colorful Accent 2;\lsdpriority52 \lsdlocked0 List Table 7 Colorful Accent 2;\lsdpriority46 \lsdlocked0 List Table 1 Light Accent 3; \lsdpriority47 \lsdlocked0 List Table 2 Accent 3;\lsdpriority48 \lsdlocked0 List Table 3 Accent 3;\lsdpriority49 \lsdlocked0 List Table 4 Accent 3;\lsdpriority50 \lsdlocked0 List Table 5 Dark Accent 3; \lsdpriority51 \lsdlocked0 List Table 6 Colorful Accent 3;\lsdpriority52 \lsdlocked0 List Table 7 Colorful Accent 3;\lsdpriority46 \lsdlocked0 List Table 1 Light Accent 4;\lsdpriority47 \lsdlocked0 List Table 2 Accent 4; \lsdpriority48 \lsdlocked0 List Table 3 Accent 4;\lsdpriority49 \lsdlocked0 List Table 4 Accent 4;\lsdpriority50 \lsdlocked0 List Table 5 Dark Accent 4;\lsdpriority51 \lsdlocked0 List Table 6 Colorful Accent 4; \lsdpriority52 \lsdlocked0 List Table 7 Colorful Accent 4;\lsdpriority46 \lsdlocked0 List Table 1 Light Accent 5;\lsdpriority47 \lsdlocked0 List Table 2 Accent 5;\lsdpriority48 \lsdlocked0 List Table 3 Accent 5; \lsdpriority49 \lsdlocked0 List Table 4 Accent 5;\lsdpriority50 \lsdlocked0 List Table 5 Dark Accent 5;\lsdpriority51 \lsdlocked0 List Table 6 Colorful Accent 5;\lsdpriority52 \lsdlocked0 List Table 7 Colorful Accent 5; \lsdpriority46 \lsdlocked0 List Table 1 Light Accent 6;\lsdpriority47 \lsdlocked0 List Table 2 Accent 6;\lsdpriority48 \lsdlocked0 List Table 3 Accent 6;\lsdpriority49 \lsdlocked0 List Table 4 Accent 6; \lsdpriority50 \lsdlocked0 List Table 5 Dark Accent 6;\lsdpriority51 \lsdlocked0 List Table 6 Colorful Accent 6;\lsdpriority52 \lsdlocked0 List Table 7 Colorful Accent 6;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Mention; \lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Smart Hyperlink;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Hashtag;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Unresolved Mention;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Smart Link; \lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Smart Link Error;}}{\*\datastore 0105000002000000180000004d73786d6c322e534158584d4c5265616465722e362e30000000000000000000000e0000 d0cf11e0a1b11ae1000000000000000000000000000000003e000300feff0900060000000000000000000000010000000100000000000000001000000200000001000000feffffff0000000000000000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff fffffffffffffffffdffffff04000000feffffff05000000fefffffffeffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffff52006f006f007400200045006e00740072007900000000000000000000000000000000000000000000000000000000000000000000000000000000000000000016000500ffffffffffffffff010000000c6ad98892f1d411a65f0040963251e5000000000000000000000000e042 f1c72e3bd60103000000c0020000000000004d0073006f004400610074006100530074006f0072006500000000000000000000000000000000000000000000000000000000000000000000000000000000001a000101ffffffffffffffff020000000000000000000000000000000000000000000000e042f1c72e3bd601 e042f1c72e3bd601000000000000000000000000df004b00cc00df00d200c4004900c000c700c40034003000c400d000470049004300300041005000d000c0003d003d000000000000000000000000000000000032000101ffffffffffffffff030000000000000000000000000000000000000000000000e042f1c72e3b d601e042f1c72e3bd6010000000000000000000000004900740065006d0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000a000201ffffffff04000000ffffffff000000000000000000000000000000000000000000000000 000000000000000000000000000000000e0100000000000001000000020000000300000004000000feffffff060000000700000008000000090000000a000000feffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff3c3f786d6c2076657273696f6e3d22312e302220656e636f64696e673d225554462d3822207374616e64616c6f6e653d226e6f223f3e3c623a536f75726365732053656c65637465645374796c653d225c4150412e58534c22205374796c 654e616d653d224150412220786d6c6e733a623d22687474703a2f2f736368656d61732e6f70656e786d6c666f726d6174732e6f72672f6f6666696365446f63756d656e742f323030362f6269626c696f6772617068792220786d6c6e733d22687474703a2f2f736368656d61732e6f70656e786d6c666f726d6174732e 6f72672f6f6666696365446f63756d656e742f323030362f6269626c696f677261706879223e3c2f623a536f75726365733e00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003c3f786d6c2076657273696f6e3d22312e302220656e636f6469 6e673d225554462d3822207374616e64616c6f6e653d226e6f223f3e0d0a3c64733a6461746173746f72654974656d2064733a6974656d49443d227b43413346414246432d323034322d343739452d394139332d3031383830394130304643327d2220786d6c6e733a64733d22687474703a2f2f736368656d61732e6f70 656e786d6c666f726d6174732e6f72672f6f6666696365446f63756d656e742f323030362f637573500072006f007000650072007400690065007300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000016000200ffffffffffffffffffffffff000000000000 0000000000000000000000000000000000000000000000000000000000000500000055010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ffffffffffffffffffffffff00000000 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ffffffffffffffffffffffff0000 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ffffffffffffffffffffffff 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000746f6d586d6c223e3c64733a736368656d61526566733e3c64733a736368656d615265662064733a7572693d22687474703a2f2f736368656d61732e6f70656e786d6c666f726d6174732e6f7267 2f6f6666696365446f63756d656e742f323030362f6269626c696f677261706879222f3e3c2f64733a736368656d61526566733e3c2f64733a6461746173746f72654974656d3e00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000105000000000000}} ================================================ FILE: releases/twain-cs_02041000/twaincscert/AnyCPU/Debug/twaincscert.exe.config ================================================ ================================================ FILE: releases/twain-cs_02041000/twaincscert/AnyCPU/Release/twaincscert.exe.config ================================================ ================================================ FILE: releases/twain-cs_02041000/twaincscert/x64/Debug/twaincscert.exe.config ================================================ ================================================ FILE: releases/twain-cs_02041000/twaincscert/x64/Release/twaincscert.exe.config ================================================ ================================================ FILE: releases/twain-cs_02041000/twaincscert/x86/Debug/twaincscert.exe.config ================================================ ================================================ FILE: releases/twain-cs_02041000/twaincscert/x86/Release/twaincscert.exe.config ================================================ ================================================ FILE: releases/twain-cs_02041000/twaincsscan/AnyCPU/Debug/twaincsscan.exe.config ================================================ ================================================ FILE: releases/twain-cs_02041000/twaincsscan/AnyCPU/Release/twaincsscan.exe.config ================================================ ================================================ FILE: releases/twain-cs_02041000/twaincsscan/x64/Debug/twaincsscan.exe.config ================================================ ================================================ FILE: releases/twain-cs_02041000/twaincsscan/x64/Release/twaincsscan.exe.config ================================================ ================================================ FILE: releases/twain-cs_02041000/twaincsscan/x86/Debug/twaincsscan.exe.config ================================================ ================================================ FILE: releases/twain-cs_02041000/twaincsscan/x86/Release/twaincsscan.exe.config ================================================ ================================================ FILE: releases/twain-cs_02041000/twaincstst/AnyCPU/Debug/twaincstst.exe.config ================================================  ================================================ FILE: releases/twain-cs_02041000/twaincstst/AnyCPU/Release/twaincstst.exe.config ================================================  ================================================ FILE: releases/twain-cs_02041000/twaincstst/x64/Debug/twaincstst.exe.config ================================================  ================================================ FILE: releases/twain-cs_02041000/twaincstst/x64/Release/twaincstst.exe.config ================================================  ================================================ FILE: releases/twain-cs_02041000/twaincstst/x86/Debug/twaincstst.exe.config ================================================  ================================================ FILE: releases/twain-cs_02041000/twaincstst/x86/Release/twaincstst.exe.config ================================================  ================================================ FILE: releases/twain-cs_02041100/TWAIN CS.rtf ================================================ {\rtf1\adeflang1025\ansi\ansicpg1252\uc1\adeff44\deff0\stshfdbch0\stshfloch0\stshfhich0\stshfbi0\deflang1033\deflangfe1033\themelang1033\themelangfe0\themelangcs0{\fonttbl{\f0\fbidi \froman\fcharset0\fprq2{\*\panose 02020603050405020304}Times New Roman{\*\falt Times New Roman};} {\f1\fbidi \fswiss\fcharset0\fprq2{\*\panose 020b0604020202020204}Arial{\*\falt Arial};}{\f2\fbidi \fmodern\fcharset0\fprq1{\*\panose 02070309020205020404}Courier New{\*\falt Courier New};} {\f3\fbidi \froman\fcharset2\fprq2{\*\panose 05050102010706020507}Symbol;}{\f4\fbidi \fswiss\fcharset0\fprq2{\*\panose 020b0604020202020204}Helvetica;}{\f5\fbidi \fmodern\fcharset0\fprq1{\*\panose 02070409020205020404}Courier{\*\falt Courier New};} {\f10\fbidi \fnil\fcharset2\fprq2{\*\panose 05000000000000000000}Wingdings;}{\f34\fbidi \froman\fcharset0\fprq2{\*\panose 02040503050406030204}Cambria Math;} {\f37\fbidi \fswiss\fcharset0\fprq2{\*\panose 020f0502020204030204}Calibri{\*\falt Century Gothic};}{\f42\fbidi \froman\fcharset0\fprq2{\*\panose 00000000000000000000}Cambria{\*\falt Palatino Linotype};} {\f43\fbidi \fswiss\fcharset0\fprq2{\*\panose 00000000000000000000}Tahoma;}{\f44\fbidi \froman\fcharset0\fprq2{\*\panose 00000000000000000000}Book Antiqua{\*\falt Book Antiqua};} {\f45\fbidi \froman\fcharset0\fprq0{\*\panose 00000000000000000000}BookAntiqua{\*\falt Book Antiqua};}{\f46\fbidi \froman\fcharset0\fprq2{\*\panose 00000000000000000000}MS Serif;} {\f47\fbidi \fswiss\fcharset0\fprq2{\*\panose 00000000000000000000}Geneva{\*\falt Arial};}{\f48\fbidi \fnil\fcharset0\fprq0{\*\panose 00000000000000000000}Courier Std;}{\f49\fbidi \fmodern\fcharset0\fprq1{\*\panose 020b0609020204030204}Consolas;} {\f50\fbidi \froman\fcharset0\fprq0{\*\panose 00000000000000000000}CourierNewPSMT;}{\flomajor\f31500\fbidi \froman\fcharset0\fprq2{\*\panose 02020603050405020304}Times New Roman{\*\falt Times New Roman};} {\fdbmajor\f31501\fbidi \froman\fcharset0\fprq2{\*\panose 02020603050405020304}Times New Roman{\*\falt Times New Roman};}{\fhimajor\f31502\fbidi \froman\fcharset0\fprq2{\*\panose 00000000000000000000}Cambria{\*\falt Palatino Linotype};} {\fbimajor\f31503\fbidi \froman\fcharset0\fprq2{\*\panose 02020603050405020304}Times New Roman{\*\falt Times New Roman};}{\flominor\f31504\fbidi \froman\fcharset0\fprq2{\*\panose 02020603050405020304}Times New Roman{\*\falt Times New Roman};} {\fdbminor\f31505\fbidi \froman\fcharset0\fprq2{\*\panose 02020603050405020304}Times New Roman{\*\falt Times New Roman};}{\fhiminor\f31506\fbidi \fswiss\fcharset0\fprq2{\*\panose 020f0502020204030204}Calibri{\*\falt Century Gothic};} {\fbiminor\f31507\fbidi \froman\fcharset0\fprq2{\*\panose 02020603050405020304}Times New Roman{\*\falt Times New Roman};}{\f52\fbidi \froman\fcharset238\fprq2 Times New Roman CE{\*\falt Times New Roman};} {\f53\fbidi \froman\fcharset204\fprq2 Times New Roman Cyr{\*\falt Times New Roman};}{\f55\fbidi \froman\fcharset161\fprq2 Times New Roman Greek{\*\falt Times New Roman};}{\f56\fbidi \froman\fcharset162\fprq2 Times New Roman Tur{\*\falt Times New Roman};} {\f57\fbidi \froman\fcharset177\fprq2 Times New Roman (Hebrew){\*\falt Times New Roman};}{\f58\fbidi \froman\fcharset178\fprq2 Times New Roman (Arabic){\*\falt Times New Roman};} {\f59\fbidi \froman\fcharset186\fprq2 Times New Roman Baltic{\*\falt Times New Roman};}{\f60\fbidi \froman\fcharset163\fprq2 Times New Roman (Vietnamese){\*\falt Times New Roman};}{\f62\fbidi \fswiss\fcharset238\fprq2 Arial CE{\*\falt Arial};} {\f63\fbidi \fswiss\fcharset204\fprq2 Arial Cyr{\*\falt Arial};}{\f65\fbidi \fswiss\fcharset161\fprq2 Arial Greek{\*\falt Arial};}{\f66\fbidi \fswiss\fcharset162\fprq2 Arial Tur{\*\falt Arial};} {\f67\fbidi \fswiss\fcharset177\fprq2 Arial (Hebrew){\*\falt Arial};}{\f68\fbidi \fswiss\fcharset178\fprq2 Arial (Arabic){\*\falt Arial};}{\f69\fbidi \fswiss\fcharset186\fprq2 Arial Baltic{\*\falt Arial};} {\f70\fbidi \fswiss\fcharset163\fprq2 Arial (Vietnamese){\*\falt Arial};}{\f72\fbidi \fmodern\fcharset238\fprq1 Courier New CE{\*\falt Courier New};}{\f73\fbidi \fmodern\fcharset204\fprq1 Courier New Cyr{\*\falt Courier New};} {\f75\fbidi \fmodern\fcharset161\fprq1 Courier New Greek{\*\falt Courier New};}{\f76\fbidi \fmodern\fcharset162\fprq1 Courier New Tur{\*\falt Courier New};}{\f77\fbidi \fmodern\fcharset177\fprq1 Courier New (Hebrew){\*\falt Courier New};} {\f78\fbidi \fmodern\fcharset178\fprq1 Courier New (Arabic){\*\falt Courier New};}{\f79\fbidi \fmodern\fcharset186\fprq1 Courier New Baltic{\*\falt Courier New};}{\f80\fbidi \fmodern\fcharset163\fprq1 Courier New (Vietnamese){\*\falt Courier New};} {\f92\fbidi \fswiss\fcharset238\fprq2 Helvetica CE;}{\f93\fbidi \fswiss\fcharset204\fprq2 Helvetica Cyr;}{\f95\fbidi \fswiss\fcharset161\fprq2 Helvetica Greek;}{\f96\fbidi \fswiss\fcharset162\fprq2 Helvetica Tur;} {\f97\fbidi \fswiss\fcharset177\fprq2 Helvetica (Hebrew);}{\f98\fbidi \fswiss\fcharset178\fprq2 Helvetica (Arabic);}{\f99\fbidi \fswiss\fcharset186\fprq2 Helvetica Baltic;}{\f100\fbidi \fswiss\fcharset163\fprq2 Helvetica (Vietnamese);} {\f392\fbidi \froman\fcharset238\fprq2 Cambria Math CE;}{\f393\fbidi \froman\fcharset204\fprq2 Cambria Math Cyr;}{\f395\fbidi \froman\fcharset161\fprq2 Cambria Math Greek;}{\f396\fbidi \froman\fcharset162\fprq2 Cambria Math Tur;} {\f399\fbidi \froman\fcharset186\fprq2 Cambria Math Baltic;}{\f400\fbidi \froman\fcharset163\fprq2 Cambria Math (Vietnamese);}{\f422\fbidi \fswiss\fcharset238\fprq2 Calibri CE{\*\falt Century Gothic};} {\f423\fbidi \fswiss\fcharset204\fprq2 Calibri Cyr{\*\falt Century Gothic};}{\f425\fbidi \fswiss\fcharset161\fprq2 Calibri Greek{\*\falt Century Gothic};}{\f426\fbidi \fswiss\fcharset162\fprq2 Calibri Tur{\*\falt Century Gothic};} {\f427\fbidi \fswiss\fcharset177\fprq2 Calibri (Hebrew){\*\falt Century Gothic};}{\f428\fbidi \fswiss\fcharset178\fprq2 Calibri (Arabic){\*\falt Century Gothic};}{\f429\fbidi \fswiss\fcharset186\fprq2 Calibri Baltic{\*\falt Century Gothic};} {\f430\fbidi \fswiss\fcharset163\fprq2 Calibri (Vietnamese){\*\falt Century Gothic};}{\f472\fbidi \froman\fcharset238\fprq2 Cambria CE{\*\falt Palatino Linotype};}{\f473\fbidi \froman\fcharset204\fprq2 Cambria Cyr{\*\falt Palatino Linotype};} {\f475\fbidi \froman\fcharset161\fprq2 Cambria Greek{\*\falt Palatino Linotype};}{\f476\fbidi \froman\fcharset162\fprq2 Cambria Tur{\*\falt Palatino Linotype};}{\f479\fbidi \froman\fcharset186\fprq2 Cambria Baltic{\*\falt Palatino Linotype};} {\f480\fbidi \froman\fcharset163\fprq2 Cambria (Vietnamese){\*\falt Palatino Linotype};}{\f482\fbidi \fswiss\fcharset238\fprq2 Tahoma CE;}{\f483\fbidi \fswiss\fcharset204\fprq2 Tahoma Cyr;}{\f485\fbidi \fswiss\fcharset161\fprq2 Tahoma Greek;} {\f486\fbidi \fswiss\fcharset162\fprq2 Tahoma Tur;}{\f487\fbidi \fswiss\fcharset177\fprq2 Tahoma (Hebrew);}{\f488\fbidi \fswiss\fcharset178\fprq2 Tahoma (Arabic);}{\f489\fbidi \fswiss\fcharset186\fprq2 Tahoma Baltic;} {\f490\fbidi \fswiss\fcharset163\fprq2 Tahoma (Vietnamese);}{\f491\fbidi \fswiss\fcharset222\fprq2 Tahoma (Thai);}{\f492\fbidi \froman\fcharset238\fprq2 Book Antiqua CE{\*\falt Book Antiqua};} {\f493\fbidi \froman\fcharset204\fprq2 Book Antiqua Cyr{\*\falt Book Antiqua};}{\f495\fbidi \froman\fcharset161\fprq2 Book Antiqua Greek{\*\falt Book Antiqua};}{\f496\fbidi \froman\fcharset162\fprq2 Book Antiqua Tur{\*\falt Book Antiqua};} {\f499\fbidi \froman\fcharset186\fprq2 Book Antiqua Baltic{\*\falt Book Antiqua};}{\f542\fbidi \fmodern\fcharset238\fprq1 Consolas CE;}{\f543\fbidi \fmodern\fcharset204\fprq1 Consolas Cyr;}{\f545\fbidi \fmodern\fcharset161\fprq1 Consolas Greek;} {\f546\fbidi \fmodern\fcharset162\fprq1 Consolas Tur;}{\f549\fbidi \fmodern\fcharset186\fprq1 Consolas Baltic;}{\f550\fbidi \fmodern\fcharset163\fprq1 Consolas (Vietnamese);} {\flomajor\f31508\fbidi \froman\fcharset238\fprq2 Times New Roman CE{\*\falt Times New Roman};}{\flomajor\f31509\fbidi \froman\fcharset204\fprq2 Times New Roman Cyr{\*\falt Times New Roman};} {\flomajor\f31511\fbidi \froman\fcharset161\fprq2 Times New Roman Greek{\*\falt Times New Roman};}{\flomajor\f31512\fbidi \froman\fcharset162\fprq2 Times New Roman Tur{\*\falt Times New Roman};} {\flomajor\f31513\fbidi \froman\fcharset177\fprq2 Times New Roman (Hebrew){\*\falt Times New Roman};}{\flomajor\f31514\fbidi \froman\fcharset178\fprq2 Times New Roman (Arabic){\*\falt Times New Roman};} {\flomajor\f31515\fbidi \froman\fcharset186\fprq2 Times New Roman Baltic{\*\falt Times New Roman};}{\flomajor\f31516\fbidi \froman\fcharset163\fprq2 Times New Roman (Vietnamese){\*\falt Times New Roman};} {\fdbmajor\f31518\fbidi \froman\fcharset238\fprq2 Times New Roman CE{\*\falt Times New Roman};}{\fdbmajor\f31519\fbidi \froman\fcharset204\fprq2 Times New Roman Cyr{\*\falt Times New Roman};} {\fdbmajor\f31521\fbidi \froman\fcharset161\fprq2 Times New Roman Greek{\*\falt Times New Roman};}{\fdbmajor\f31522\fbidi \froman\fcharset162\fprq2 Times New Roman Tur{\*\falt Times New Roman};} {\fdbmajor\f31523\fbidi \froman\fcharset177\fprq2 Times New Roman (Hebrew){\*\falt Times New Roman};}{\fdbmajor\f31524\fbidi \froman\fcharset178\fprq2 Times New Roman (Arabic){\*\falt Times New Roman};} {\fdbmajor\f31525\fbidi \froman\fcharset186\fprq2 Times New Roman Baltic{\*\falt Times New Roman};}{\fdbmajor\f31526\fbidi \froman\fcharset163\fprq2 Times New Roman (Vietnamese){\*\falt Times New Roman};} {\fhimajor\f31528\fbidi \froman\fcharset238\fprq2 Cambria CE{\*\falt Palatino Linotype};}{\fhimajor\f31529\fbidi \froman\fcharset204\fprq2 Cambria Cyr{\*\falt Palatino Linotype};} {\fhimajor\f31531\fbidi \froman\fcharset161\fprq2 Cambria Greek{\*\falt Palatino Linotype};}{\fhimajor\f31532\fbidi \froman\fcharset162\fprq2 Cambria Tur{\*\falt Palatino Linotype};} {\fhimajor\f31535\fbidi \froman\fcharset186\fprq2 Cambria Baltic{\*\falt Palatino Linotype};}{\fhimajor\f31536\fbidi \froman\fcharset163\fprq2 Cambria (Vietnamese){\*\falt Palatino Linotype};} {\fbimajor\f31538\fbidi \froman\fcharset238\fprq2 Times New Roman CE{\*\falt Times New Roman};}{\fbimajor\f31539\fbidi \froman\fcharset204\fprq2 Times New Roman Cyr{\*\falt Times New Roman};} {\fbimajor\f31541\fbidi \froman\fcharset161\fprq2 Times New Roman Greek{\*\falt Times New Roman};}{\fbimajor\f31542\fbidi \froman\fcharset162\fprq2 Times New Roman Tur{\*\falt Times New Roman};} {\fbimajor\f31543\fbidi \froman\fcharset177\fprq2 Times New Roman (Hebrew){\*\falt Times New Roman};}{\fbimajor\f31544\fbidi \froman\fcharset178\fprq2 Times New Roman (Arabic){\*\falt Times New Roman};} {\fbimajor\f31545\fbidi \froman\fcharset186\fprq2 Times New Roman Baltic{\*\falt Times New Roman};}{\fbimajor\f31546\fbidi \froman\fcharset163\fprq2 Times New Roman (Vietnamese){\*\falt Times New Roman};} {\flominor\f31548\fbidi \froman\fcharset238\fprq2 Times New Roman CE{\*\falt Times New Roman};}{\flominor\f31549\fbidi \froman\fcharset204\fprq2 Times New Roman Cyr{\*\falt Times New Roman};} {\flominor\f31551\fbidi \froman\fcharset161\fprq2 Times New Roman Greek{\*\falt Times New Roman};}{\flominor\f31552\fbidi \froman\fcharset162\fprq2 Times New Roman Tur{\*\falt Times New Roman};} {\flominor\f31553\fbidi \froman\fcharset177\fprq2 Times New Roman (Hebrew){\*\falt Times New Roman};}{\flominor\f31554\fbidi \froman\fcharset178\fprq2 Times New Roman (Arabic){\*\falt Times New Roman};} {\flominor\f31555\fbidi \froman\fcharset186\fprq2 Times New Roman Baltic{\*\falt Times New Roman};}{\flominor\f31556\fbidi \froman\fcharset163\fprq2 Times New Roman (Vietnamese){\*\falt Times New Roman};} {\fdbminor\f31558\fbidi \froman\fcharset238\fprq2 Times New Roman CE{\*\falt Times New Roman};}{\fdbminor\f31559\fbidi \froman\fcharset204\fprq2 Times New Roman Cyr{\*\falt Times New Roman};} {\fdbminor\f31561\fbidi \froman\fcharset161\fprq2 Times New Roman Greek{\*\falt Times New Roman};}{\fdbminor\f31562\fbidi \froman\fcharset162\fprq2 Times New Roman Tur{\*\falt Times New Roman};} {\fdbminor\f31563\fbidi \froman\fcharset177\fprq2 Times New Roman (Hebrew){\*\falt Times New Roman};}{\fdbminor\f31564\fbidi \froman\fcharset178\fprq2 Times New Roman (Arabic){\*\falt Times New Roman};} {\fdbminor\f31565\fbidi \froman\fcharset186\fprq2 Times New Roman Baltic{\*\falt Times New Roman};}{\fdbminor\f31566\fbidi \froman\fcharset163\fprq2 Times New Roman (Vietnamese){\*\falt Times New Roman};} {\fhiminor\f31568\fbidi \fswiss\fcharset238\fprq2 Calibri CE{\*\falt Century Gothic};}{\fhiminor\f31569\fbidi \fswiss\fcharset204\fprq2 Calibri Cyr{\*\falt Century Gothic};} {\fhiminor\f31571\fbidi \fswiss\fcharset161\fprq2 Calibri Greek{\*\falt Century Gothic};}{\fhiminor\f31572\fbidi \fswiss\fcharset162\fprq2 Calibri Tur{\*\falt Century Gothic};} {\fhiminor\f31573\fbidi \fswiss\fcharset177\fprq2 Calibri (Hebrew){\*\falt Century Gothic};}{\fhiminor\f31574\fbidi \fswiss\fcharset178\fprq2 Calibri (Arabic){\*\falt Century Gothic};} {\fhiminor\f31575\fbidi \fswiss\fcharset186\fprq2 Calibri Baltic{\*\falt Century Gothic};}{\fhiminor\f31576\fbidi \fswiss\fcharset163\fprq2 Calibri (Vietnamese){\*\falt Century Gothic};} {\fbiminor\f31578\fbidi \froman\fcharset238\fprq2 Times New Roman CE{\*\falt Times New Roman};}{\fbiminor\f31579\fbidi \froman\fcharset204\fprq2 Times New Roman Cyr{\*\falt Times New Roman};} {\fbiminor\f31581\fbidi \froman\fcharset161\fprq2 Times New Roman Greek{\*\falt Times New Roman};}{\fbiminor\f31582\fbidi \froman\fcharset162\fprq2 Times New Roman Tur{\*\falt Times New Roman};} {\fbiminor\f31583\fbidi \froman\fcharset177\fprq2 Times New Roman (Hebrew){\*\falt Times New Roman};}{\fbiminor\f31584\fbidi \froman\fcharset178\fprq2 Times New Roman (Arabic){\*\falt Times New Roman};} {\fbiminor\f31585\fbidi \froman\fcharset186\fprq2 Times New Roman Baltic{\*\falt Times New Roman};}{\fbiminor\f31586\fbidi \froman\fcharset163\fprq2 Times New Roman (Vietnamese){\*\falt Times New Roman};}}{\colortbl;\red0\green0\blue0; \red0\green0\blue255;\red0\green255\blue255;\red0\green255\blue0;\red255\green0\blue255;\red255\green0\blue0;\red255\green255\blue0;\red255\green255\blue255;\red0\green0\blue128;\red0\green128\blue128;\red0\green128\blue0;\red128\green0\blue128; \red128\green0\blue0;\red128\green128\blue0;\red128\green128\blue128;\red192\green192\blue192;\red0\green0\blue0;\red0\green0\blue0;\cfollowedhyperlink\ctint255\cshade255\red128\green0\blue128;\red96\green94\blue92;\red225\green223\blue221; \red31\green73\blue125;\red0\green176\blue80;}{\*\defchp \fs22 }{\*\defpap \ql \li0\ri0\sa200\sl276\slmult1\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 }\noqfpromote {\stylesheet{ \ql \li1440\ri0\sb180\widctlpar\wrapdefault\nooverflow\faroman\rin0\lin1440\itap0 \rtlch\fcs1 \af44\afs20\alang1025 \ltrch\fcs0 \f44\fs20\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \snext0 \sqformat \spriority0 Normal;}{ \s1\ql \li0\ri0\sb720\keepn\widctlpar\brdrt\brdrs\brdrw30\brsp120 \wrapdefault\nooverflow\faroman\outlinelevel0\rin0\lin0\itap0 \rtlch\fcs1 \ab\af1\afs36\alang1025 \ltrch\fcs0 \b\f1\fs36\cf9\lang1024\langfe1024\cgrid\noproof\langnp1033\langfenp1033 \sbasedon0 \snext0 \slink15 \sqformat heading 1;}{\s2\ql \li720\ri0\sb360\keepn\widctlpar\wrapdefault\nooverflow\faroman\outlinelevel1\rin0\lin720\itap0 \rtlch\fcs1 \ab\af1\afs20\alang1025 \ltrch\fcs0 \b\f1\fs20\cf13\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \sbasedon0 \snext0 \slink16 \sqformat heading 2;}{\s3\ql \li1440\ri0\sb180\keepn\widctlpar\wrapdefault\nooverflow\faroman\outlinelevel2\rin0\lin1440\itap0 \rtlch\fcs1 \ab\af1\afs20\alang1025 \ltrch\fcs0 \b\f1\fs20\cf10\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \sbasedon0 \snext24 \slink17 \sqformat heading 3;}{\s4\ql \li1440\ri0\sb180\widctlpar\wrapdefault\nooverflow\faroman\outlinelevel3\rin0\lin1440\itap0 \rtlch\fcs1 \af46\afs24\alang1025 \ltrch\fcs0 \f46\fs24\ul\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \sbasedon0 \snext24 \slink18 \sqformat heading 4;}{ \s5\ql \li1440\ri0\sb180\widctlpar\wrapdefault\nooverflow\faroman\outlinelevel4\rin0\lin1440\itap0 \rtlch\fcs1 \ab\af46\afs20\alang1025 \ltrch\fcs0 \b\f46\fs20\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \sbasedon0 \snext24 \slink19 \sqformat heading 5;}{\s6\ql \li1440\ri0\sb180\widctlpar\wrapdefault\nooverflow\faroman\outlinelevel5\rin0\lin1440\itap0 \rtlch\fcs1 \af46\afs20\alang1025 \ltrch\fcs0 \f46\fs20\ul\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \sbasedon0 \snext24 \slink20 \sqformat heading 6;}{\s7\ql \li1440\ri0\sb180\widctlpar\wrapdefault\nooverflow\faroman\outlinelevel6\rin0\lin1440\itap0 \rtlch\fcs1 \ai\af46\afs20\alang1025 \ltrch\fcs0 \i\f46\fs20\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \sbasedon0 \snext24 \slink21 \sqformat heading 7;}{\s8\ql \li1440\ri0\sb240\sa60\widctlpar\wrapdefault\nooverflow\faroman\outlinelevel7\rin0\lin1440\itap0 \rtlch\fcs1 \ai\af44\afs20\alang1025 \ltrch\fcs0 \i\f44\fs20\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \sbasedon0 \snext0 \slink22 \sqformat heading 8;}{\s9\ql \li1440\ri0\sb240\sa60\widctlpar\wrapdefault\nooverflow\faroman\outlinelevel8\rin0\lin1440\itap0 \rtlch\fcs1 \ab\ai\af44\afs18\alang1025 \ltrch\fcs0 \b\i\f44\fs18\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \sbasedon0 \snext0 \slink23 \sqformat heading 9;}{\*\cs10 \additive \ssemihidden Default Paragraph Font;}{\* \ts11\tsrowd\trftsWidthB3\trpaddl108\trpaddr108\trpaddfl3\trpaddft3\trpaddfb3\trpaddfr3\trcbpat1\trcfpat1\tblind0\tblindtype3\tsvertalt\tsbrdrt\tsbrdrl\tsbrdrb\tsbrdrr\tsbrdrdgl\tsbrdrdgr\tsbrdrh\tsbrdrv \ql \li0\ri0\sa200\sl276\slmult1 \widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 \rtlch\fcs1 \af0\afs22\alang1025 \ltrch\fcs0 \fs22\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \snext11 \ssemihidden \sunhideused Normal Table;}{\*\cs15 \additive \rtlch\fcs1 \ab\af0\afs32 \ltrch\fcs0 \b\f42\fs32\kerning32 \sbasedon10 \slink1 \slocked Heading 1 Char;}{\*\cs16 \additive \rtlch\fcs1 \ab\ai\af0\afs28 \ltrch\fcs0 \b\i\f42\fs28 \sbasedon10 \slink2 \slocked \ssemihidden Heading 2 Char;}{\*\cs17 \additive \rtlch\fcs1 \ab\af0\afs26 \ltrch\fcs0 \b\f42\fs26 \sbasedon10 \slink3 \slocked \ssemihidden Heading 3 Char;}{\*\cs18 \additive \rtlch\fcs1 \ab\af0\afs28 \ltrch\fcs0 \b\f37\fs28 \sbasedon10 \slink4 \slocked \ssemihidden Heading 4 Char;}{\*\cs19 \additive \rtlch\fcs1 \ab\ai\af0\afs26 \ltrch\fcs0 \b\i\f37\fs26 \sbasedon10 \slink5 \slocked \ssemihidden Heading 5 Char;}{\*\cs20 \additive \rtlch\fcs1 \ab\af0 \ltrch\fcs0 \b\f37 \sbasedon10 \slink6 \slocked \ssemihidden Heading 6 Char;}{\*\cs21 \additive \rtlch\fcs1 \af0\afs24 \ltrch\fcs0 \f37\fs24 \sbasedon10 \slink7 \slocked \ssemihidden Heading 7 Char;}{\*\cs22 \additive \rtlch\fcs1 \ai\af0\afs24 \ltrch\fcs0 \i\f37\fs24 \sbasedon10 \slink8 \slocked \ssemihidden Heading 8 Char;}{\*\cs23 \additive \rtlch\fcs1 \af0 \ltrch\fcs0 \f42 \sbasedon10 \slink9 \slocked \ssemihidden Heading 9 Char;}{\s24\ql \li1800\ri0\sb180\widctlpar\wrapdefault\nooverflow\faroman\rin0\lin1800\itap0 \rtlch\fcs1 \af44\afs20\alang1025 \ltrch\fcs0 \f44\fs20\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \sbasedon0 \snext24 Normal Indent;}{\s25\ql \li0\ri0\widctlpar\tqr\tx9360\wrapdefault\nooverflow\faroman\rin0\lin0\itap0 \rtlch\fcs1 \ai\af1\afs16\alang1025 \ltrch\fcs0 \i\f1\fs16\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \sbasedon0 \snext25 \slink26 footer;}{\*\cs26 \additive \rtlch\fcs1 \af44\afs20 \ltrch\fcs0 \f44\fs20 \sbasedon10 \slink25 \slocked \ssemihidden Footer Char;}{\s27\ql \li0\ri0\widctlpar \tqr\tx9900\wrapdefault\nooverflow\faroman\rin0\lin0\itap0 \rtlch\fcs1 \ab\ai\af1\afs20\alang1025 \ltrch\fcs0 \b\i\f1\fs20\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \sbasedon0 \snext27 \slink28 header;}{\*\cs28 \additive \rtlch\fcs1 \af44\afs20 \ltrch\fcs0 \f44\fs20 \sbasedon10 \slink27 \slocked \ssemihidden Header Char;}{\s29\ql \li2160\ri0\sb40\widctlpar\wrapdefault\nooverflow\faroman\rin0\lin2160\itap0 \rtlch\fcs1 \af2\afs18\alang1025 \ltrch\fcs0 \f2\fs18\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \sbasedon30 \snext29 prog indent;}{\s30\ql \li1800\ri0\sb40\widctlpar\wrapdefault\nooverflow\faroman\rin0\lin1800\itap0 \rtlch\fcs1 \af2\afs18\alang1025 \ltrch\fcs0 \f2\fs18\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \sbasedon31 \snext30 prog;}{\s31\ql \fi-360\li360\ri0\sb180\widctlpar\wrapdefault\nooverflow\faroman\rin0\lin360\itap0 \rtlch\fcs1 \af44\afs20\alang1025 \ltrch\fcs0 \f44\fs20\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \sbasedon0 \snext31 List;}{\*\cs32 \additive \rtlch\fcs1 \af0 \ltrch\fcs0 \sbasedon10 page number;}{\s33\ql \fi-216\li2016\ri0\sb40\widctlpar\wrapdefault{\*\pn \pnlvlblt\ilvl10\ls2047\pnrnot0 \pnf5\pnstart1\pnindent216\pnhang {\pntxtb ?}}\nooverflow\faroman\ls2047\ilvl10\rin0\lin2016\itap0 \rtlch\fcs1 \af44\afs20\alang1025 \ltrch\fcs0 \f44\fs20\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \sbasedon0 \snext33 bullet;}{ \s34\ql \li0\ri0\sb720\keepn\widctlpar\brdrt\brdrs\brdrw30\brsp120 \wrapdefault\nooverflow\faroman\rin0\lin0\itap0 \rtlch\fcs1 \ab\af1\afs36\alang1025 \ltrch\fcs0 \b\f1\fs36\cf9\lang1024\langfe1024\cgrid\noproof\langnp1033\langfenp1033 \sbasedon1 \snext34 Style1;}{\s35\ql \fi-216\li2016\ri0\sb120\widctlpar\wrapdefault{\*\pn \pnlvlblt\ilvl10\ls2047\pnrnot0\pnf5\pnstart1\pnindent216\pnhang {\pntxtb ?}}\nooverflow\faroman\ls2047\ilvl10\rin0\lin2016\itap0 \rtlch\fcs1 \af44\afs20\alang1025 \ltrch\fcs0 \f44\fs20\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \sbasedon33 \snext33 bullet first;}{\s36\ql \li1440\ri0\sb180\widctlpar\tx5220\wrapdefault\nooverflow\faroman\rin0\lin1440\itap0 \rtlch\fcs1 \ab\af1\afs20\alang1025 \ltrch\fcs0 \b\f1\fs20\cf13\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \sbasedon0 \snext38 chapter contents;}{\s37\ql \li1440\ri0\sb40\widctlpar\tx5400\wrapdefault\nooverflow\faroman\rin0\lin1440\itap0 \rtlch\fcs1 \af44\afs20\alang1025 \ltrch\fcs0 \f44\fs20\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \sbasedon0 \snext37 chapter contents list;}{\s38\ql \li1440\ri0\sb80\widctlpar\tx5400\wrapdefault\nooverflow\faroman\rin0\lin1440\itap0 \rtlch\fcs1 \af44\afs20\alang1025 \ltrch\fcs0 \f44\fs20\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \sbasedon0 \snext37 chapter contents list first;}{\s39\ql \li0\ri0\widctlpar\wrapdefault\nooverflow\faroman\rin0\lin0\itap0 \rtlch\fcs1 \ab\af1\afs200\alang1025 \ltrch\fcs0 \b\f1\fs200\lang1024\langfe1024\cgrid\noproof\langnp1033\langfenp1033 \snext0 chapter num;}{\s40\qr \li0\ri0\sa720\widctlpar\brdrt\brdrs\brdrw60\brsp20 \wrapdefault\nooverflow\faroman\rin0\lin0\itap0 \rtlch\fcs1 \ab\af1\afs54\alang1025 \ltrch\fcs0 \b\f1\fs54\cf9\lang1024\langfe1024\cgrid\noproof\langnp1033\langfenp1033 \snext36 chapter title;}{\s41\ql \li1800\ri0\sb120\widctlpar\wrapdefault\nooverflow\faroman\rin0\lin1800\itap0 \rtlch\fcs1 \af44\afs20\alang1025 \ltrch\fcs0 \f44\fs20\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \sbasedon31 \snext31 list first;}{\s42\ql \fi-216\li2376\ri0\sb40\widctlpar\wrapdefault{\*\pn \pnlvlblt\ilvl10\ls2047\pnrnot0\pnf47\pnstart1\pnindent216\pnhang {\pntxtb ?}} \nooverflow\faroman\ls2047\ilvl10\rin0\lin2376\itap0 \rtlch\fcs1 \af44\afs20\alang1025 \ltrch\fcs0 \f44\fs20\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \sbasedon0 \snext42 bullet indent;}{ \s43\ql \li1440\ri0\sb120\widctlpar\wrapdefault\nooverflow\faroman\rin0\lin1440\itap0 \rtlch\fcs1 \af44\afs20\alang1025 \ltrch\fcs0 \f44\fs20\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \sbasedon0 \snext0 normal after heading 3;}{ \s44\ql \fi-216\li2376\ri0\sb80\widctlpar\wrapdefault{\*\pn \pnlvlblt\ilvl10\ls2047\pnrnot0\pnf47\pnstart1\pnindent216\pnhang {\pntxtb ?}}\nooverflow\faroman\ls2047\ilvl10\rin0\lin2376\itap0 \rtlch\fcs1 \af44\afs20\alang1025 \ltrch\fcs0 \f44\fs20\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \sbasedon33 \snext42 bullet indent first;}{\s45\qr \li720\ri0\sa360\sl-1060\slmult0\widctlpar\wrapdefault\nooverflow\faroman\rin0\lin720\itap0 \rtlch\fcs1 \ab\ai\af1\afs48\alang1025 \ltrch\fcs0 \b\i\f1\fs48\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \sbasedon0 \snext0 contents title;}{\s46\ql \li2160\ri0\sb40\widctlpar\wrapdefault\nooverflow\faroman\rin0\lin2160\itap0 \rtlch\fcs1 \af44\afs20\alang1025 \ltrch\fcs0 \f44\fs20\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \sbasedon31 \snext46 def;}{\s47\ql \li2160\ri0\sb80\widctlpar\wrapdefault\nooverflow\faroman\rin0\lin2160\itap0 \rtlch\fcs1 \af44\afs20\alang1025 \ltrch\fcs0 \f44\fs20\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \sbasedon46 \snext47 def 2;}{\s48\ql \li1080\ri0\sb120\widctlpar\wrapdefault\nooverflow\faroman\rin0\lin1080\itap0 \rtlch\fcs1 \af44\afs20\alang1025 \ltrch\fcs0 \f44\fs20\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \sbasedon41 \snext46 def first;}{\s49\ql \li2160\ri0\sb40\widctlpar\wrapdefault\nooverflow\faroman\rin0\lin2160\itap0 \rtlch\fcs1 \af44\afs20\alang1025 \ltrch\fcs0 \f44\fs20\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \sbasedon46 \snext0 def last;}{\s50\ql \li2160\ri0\sb80\widctlpar\wrapdefault\nooverflow\faroman\rin0\lin2160\itap0 \rtlch\fcs1 \af44\afs20\alang1025 \ltrch\fcs0 \f44\fs20\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \sbasedon49 \snext0 def last 2;}{\s51\ql \li1800\ri0\sb120\keepn\widctlpar\wrapdefault\nooverflow\faroman\rin0\lin1800\itap0 \rtlch\fcs1 \ab\af44\afs20\alang1025 \ltrch\fcs0 \b\f44\fs20\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \sbasedon41 \snext46 def term;}{\s52\ql \li1800\ri0\sb120\keepn\widctlpar\wrapdefault\nooverflow\faroman\rin0\lin1800\itap0 \rtlch\fcs1 \ab\af44\afs20\alang1025 \ltrch\fcs0 \b\f44\fs20\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \sbasedon41 \snext52 def term first;}{\s53\qc \li1440\ri0\sb240\keepn\widctlpar\wrapdefault\nooverflow\faroman\rin0\lin1440\itap0 \rtlch\fcs1 \af44\afs20\alang1025 \ltrch\fcs0 \f44\fs20\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \sbasedon0 \snext54 figure;}{\s54\qc \li1440\ri0\sb180\sa240\widctlpar\wrapdefault\nooverflow\faroman\rin0\lin1440\itap0 \rtlch\fcs1 \ab\af1\afs20\alang1025 \ltrch\fcs0 \b\f1\fs20\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \sbasedon0 \snext0 figure title;}{\s55\qc \li1440\ri0\sb240\keepn\widctlpar\wrapdefault\nooverflow\faroman\rin0\lin1440\itap0 \rtlch\fcs1 \af44\afs20\alang1025 \ltrch\fcs0 \f44\fs20\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \sbasedon53 \snext0 figure after step;}{\s56\qc \li1440\ri0\sb180\sa240\widctlpar\wrapdefault\nooverflow\faroman\rin0\lin1440\itap0 \rtlch\fcs1 \ab\af1\afs20\alang1025 \ltrch\fcs0 \b\f1\fs20\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \sbasedon54 \snext56 figure title after step;}{\s57\qc \li1440\ri0\sb180\sa360\widctlpar\wrapdefault\nooverflow\faroman\rin0\lin1440\itap0 \rtlch\fcs1 \ab\af1\afs20\alang1025 \ltrch\fcs0 \b\f1\fs20\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \sbasedon54 \snext0 figure title continued;}{\*\cs58 \additive \rtlch\fcs1 \af0 \ltrch\fcs0 \sbasedon10 line number;}{ \s59\ql \li2160\ri0\sb40\widctlpar\wrapdefault\nooverflow\faroman\rin0\lin2160\itap0 \rtlch\fcs1 \af44\afs20\alang1025 \ltrch\fcs0 \f44\fs20\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \sbasedon31 \snext59 list indent;}{ \s60\ql \li2160\ri0\sb80\widctlpar\wrapdefault\nooverflow\faroman\rin0\lin2160\itap0 \rtlch\fcs1 \af44\afs20\alang1025 \ltrch\fcs0 \f44\fs20\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \sbasedon31 \snext59 list indent first;}{ \s61\ql \fi-360\li2160\ri0\sb120\widctlpar\wrapdefault{\*\pn \pnlvlbody\ilvl11\ls2047\pnrnot0\pndec\pnstart1\pnindent360\pnhang {\pntxta .}}\nooverflow\faroman\ls2047\ilvl11\rin0\lin2160\itap0 \rtlch\fcs1 \af44\afs20\alang1025 \ltrch\fcs0 \f44\fs20\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \sbasedon0 \snext61 List Number;}{\s62\ql \li2160\ri0\sb80\widctlpar\wrapdefault\nooverflow\faroman\rin0\lin2160\itap0 \rtlch\fcs1 \af44\afs20\alang1025 \ltrch\fcs0 \f44\fs20\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \sbasedon60 \snext62 list number no number;}{\s63\ql \li720\ri0\sb180\widctlpar\wrapdefault\nooverflow\faroman\rin0\lin720\itap0 \rtlch\fcs1 \af44\afs20\alang1025 \ltrch\fcs0 \f44\fs20\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \sbasedon0 \snext63 normal before table;}{\s64\ql \fi-806\li2246\ri0\sb240\sa120\widctlpar\brdrt\brdrs\brdrw15\brsp100 \brdrb\brdrs\brdrw15\brsp100 \tx2250\wrapdefault\nooverflow\faroman\rin0\lin2246\itap0 \rtlch\fcs1 \af44\afs20\alang1025 \ltrch\fcs0 \f44\fs20\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \sbasedon0 \snext0 note;}{ \s65\qr \li0\ri0\sb180\widctlpar\wrapdefault\nooverflow\faroman\rin0\lin0\itap0 \rtlch\fcs1 \ai\af1\afs20\alang1025 \ltrch\fcs0 \i\f1\fs20\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \sbasedon0 \snext65 part number;}{ \s66\ql \li1800\ri0\sb120\widctlpar\tx4770\wrapdefault\nooverflow\faroman\rin0\lin1800\itap0 \rtlch\fcs1 \af2\afs18\alang1025 \ltrch\fcs0 \f2\fs18\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \sbasedon41 \snext30 prog first;}{ \s67\ql \li1800\ri0\sb40\widctlpar\wrapdefault\nooverflow\faroman\rin0\lin1800\itap0 \rtlch\fcs1 \af2\afs18\alang1025 \ltrch\fcs0 \f2\fs18\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \sbasedon31 \snext67 prog last;}{ \s68\ql \li1800\ri0\sb120\widctlpar\tx4770\wrapdefault\nooverflow\faroman\rin0\lin1800\itap0 \rtlch\fcs1 \af2\afs18\alang1025 \ltrch\fcs0 \f2\fs18\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \sbasedon66 \snext68 prog single;}{ \s69\ql \li878\ri144\sl-180\slmult0\widctlpar\brdrt\brdrs\brdrw15\brsp100 \brdrl\brdrs\brdrw15\brsp100 \brdrb\brdrs\brdrw15\brsp100 \brdrr\brdrs\brdrw15\brsp100 \tx1152\tx1440\tx1728\tx2016\tx2304\tx2592\tx2880\wrapdefault\nooverflow\faroman\rin144\lin878\itap0 \rtlch\fcs1 \af2\afs15\alang1025 \ltrch\fcs0 \f2\fs15\lang1024\langfe1024\cgrid\noproof\langnp1033\langfenp1033 \snext69 program text;}{ \s70\ql \fi-360\li2520\ri0\sb80\widctlpar\wrapdefault{\*\pn \pnlvlbody\ilvl11\ls2047\pnrnot0\pnlcltr\pnb0\pni0\pnf4\pnfs20\pnstart1\pnindent360\pnhang {\pntxta . }}\nooverflow\faroman\ls2047\ilvl11\rin0\lin2520\itap0 \rtlch\fcs1 \af44\afs20\alang1025 \ltrch\fcs0 \f44\fs20\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \sbasedon0 \snext70 substep;}{\s71\ql \li72\ri72\sb80\sa80\keepn\widctlpar\wrapdefault\nooverflow\faroman\rin72\lin72\itap0 \rtlch\fcs1 \ab\af44\afs20\alang1025 \ltrch\fcs0 \b\f44\fs20\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \sbasedon0 \snext0 table head;}{\s72\ql \li72\ri72\sb80\sa80\widctlpar\wrapdefault\nooverflow\faroman\rin72\lin72\itap0 \rtlch\fcs1 \af44\afs18\alang1025 \ltrch\fcs0 \f44\fs18\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \snext72 table text;}{\s73\qc \li1440\ri0\sb300\sa120\keepn\widctlpar\wrapdefault\nooverflow\faroman\rin0\lin1440\itap0 \rtlch\fcs1 \ab\af1\afs20\alang1025 \ltrch\fcs0 \b\f1\fs20\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \sbasedon0 \snext71 table title;}{\s74\qc \li1440\ri0\sb300\sa120\keepn\widctlpar\wrapdefault\nooverflow\faroman\rin0\lin1440\itap0 \rtlch\fcs1 \ab\af1\afs20\alang1025 \ltrch\fcs0 \b\f1\fs20\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \sbasedon73 \snext71 table title continued;}{\s75\ql \li1800\ri0\sb120\widctlpar\wrapdefault\nooverflow\faroman\rin0\lin1800\itap0 \rtlch\fcs1 \af1\afs20\alang1025 \ltrch\fcs0 \f1\fs20\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \sbasedon0 \snext0 triplet single;}{\s76\ql \li720\ri0\sb360\keepn\widctlpar\wrapdefault\nooverflow\faroman\rin0\lin720\itap0 \rtlch\fcs1 \ab\af1\afs20\alang1025 \ltrch\fcs0 \b\f1\fs20\cf13\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \sbasedon2 \snext0 triplet heading 2;}{\s77\ql \li0\ri0\sb180\keepn\pagebb\widctlpar\brdrt\brdrs\brdrw30\brsp120 \tqr\tx9893\wrapdefault\nooverflow\faroman\rin0\lin0\itap0 \rtlch\fcs1 \ab\af1\afs24\alang1025 \ltrch\fcs0 \b\f1\fs24\cf9\lang1024\langfe1024\cgrid\noproof\langnp1033\langfenp1033 \sbasedon1 \snext77 triplet heading;}{\s78\ql \li1080\ri0\sb120\widctlpar\wrapdefault\nooverflow\faroman\rin0\lin1080\itap0 \rtlch\fcs1 \af44\afs20\alang1025 \ltrch\fcs0 \f44\fs20\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \sbasedon0 \snext79 glossary def;}{\s79\ql \li720\ri0\sb180\keepn\widctlpar\wrapdefault\nooverflow\faroman\rin0\lin720\itap0 \rtlch\fcs1 \ab\af44\afs20\alang1025 \ltrch\fcs0 \b\f44\fs20\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \sbasedon80 \snext78 glossary word;}{\s80\ql \li720\ri0\sb180\keepn\widctlpar\wrapdefault\nooverflow\faroman\rin0\lin720\itap0 \rtlch\fcs1 \ab\af44\afs20\alang1025 \ltrch\fcs0 \b\f44\fs20\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \sbasedon0 \snext78 glossary word first;}{\s81\ql \li1080\ri0\sb120\widctlpar\wrapdefault\nooverflow\faroman\rin0\lin1080\itap0 \rtlch\fcs1 \af44\afs20\alang1025 \ltrch\fcs0 \f44\fs20\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \sbasedon78 \snext0 glossary def last;}{\s82\ql \fi-216\li2736\ri0\sb80\widctlpar\wrapdefault{\*\pn \pnlvlblt\ilvl10\ls2047\pnrnot0 \pnf5\pnstart1\pnindent216\pnhang {\pntxtb ?}}\nooverflow\faroman\ls2047\ilvl10\rin0\lin2736\itap0 \rtlch\fcs1 \af44\afs20\alang1025 \ltrch\fcs0 \f44\fs20\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \sbasedon0 \snext82 ref bullet 1;}{ \s83\ql \fi-216\li2736\ri0\sb40\widctlpar\wrapdefault{\*\pn \pnlvlblt\ilvl10\ls2047\pnrnot0\pnf5\pnstart1\pnindent216\pnhang {\pntxtb ?}}\nooverflow\faroman\ls2047\ilvl10\rin0\lin2736\itap0 \rtlch\fcs1 \af44\afs20\alang1025 \ltrch\fcs0 \f44\fs20\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \sbasedon82 \snext83 ref bullet 2;}{\s84\ql \fi-1440\li2160\ri0\sb180\widctlpar\tx2160\wrapdefault\nooverflow\faroman\rin0\lin2160\itap0 \rtlch\fcs1 \af44\afs20\alang1025 \ltrch\fcs0 \f44\fs20\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \sbasedon0 \snext84 ref para 1;}{\s85\ql \li2160\ri0\sb80\widctlpar\wrapdefault\nooverflow\faroman\rin0\lin2160\itap0 \rtlch\fcs1 \af44\afs20\alang1025 \ltrch\fcs0 \f44\fs20\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \sbasedon84 \snext84 ref para 2;}{\s86\ql \li2520\ri0\sb80\widctlpar\wrapdefault\nooverflow\faroman\rin0\lin2520\itap0 \rtlch\fcs1 \af2\afs18\alang1025 \ltrch\fcs0 \f2\fs18\lang1024\langfe1024\cgrid\noproof\langnp1033\langfenp1033 \snext86 ref prog 1;}{\s87\ql \li2520\ri0\sb40\widctlpar\wrapdefault\nooverflow\faroman\rin0\lin2520\itap0 \rtlch\fcs1 \af2\afs18\alang1025 \ltrch\fcs0 \f2\fs18\lang1024\langfe1024\cgrid\noproof\langnp1033\langfenp1033 \sbasedon86 \snext87 ref prog 2;}{\s88\ql \li2160\ri0\sb120\widctlpar\tx4770\wrapdefault\nooverflow\faroman\rin0\lin2160\itap0 \rtlch\fcs1 \af2\afs18\alang1025 \ltrch\fcs0 \f2\fs18\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \sbasedon66 \snext88 prog indent first;}{\s89\ql \li2160\ri0\sb40\widctlpar\wrapdefault\nooverflow\faroman\rin0\lin2160\itap0 \rtlch\fcs1 \af2\afs18\alang1025 \ltrch\fcs0 \f2\fs18\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \sbasedon67 \snext89 prog indent last;}{\s90\ql \li0\ri0\sb180\keepn\pagebb\widctlpar\brdrt\brdrs\brdrw30\brsp120 \tqr\tx9893\wrapdefault\nooverflow\faroman\rin0\lin0\itap0 \rtlch\fcs1 \ab\af1\afs24\alang1025 \ltrch\fcs0 \b\f1\fs24\cf9\lang1024\langfe1024\cgrid\noproof\langnp1033\langfenp1033 \sbasedon77 \snext0 ref heading;}{\s91\ql \li720\ri0\sb360\keepn\widctlpar\wrapdefault\nooverflow\faroman\rin0\lin720\itap0 \rtlch\fcs1 \ab\af1\afs20\alang1025 \ltrch\fcs0 \b\f1\fs20\cf13\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \sbasedon76 \snext0 ref heading 2;}{\s92\ql \li1440\ri0\sb120\widctlpar\wrapdefault\nooverflow\faroman\rin0\lin1440\itap0 \rtlch\fcs1 \af44\afs20\alang1025 \ltrch\fcs0 \f44\fs20\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \sbasedon41 \snext93 ref list first;}{\s93\ql \li1440\ri0\sb40\widctlpar\wrapdefault\nooverflow\faroman\rin0\lin1440\itap0 \rtlch\fcs1 \af44\afs20\alang1025 \ltrch\fcs0 \f44\fs20\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \sbasedon31 \snext93 ref list;}{\s94\ql \fi-2160\li3240\ri0\sb120\widctlpar\tx3240\wrapdefault\nooverflow\faroman\rin0\lin3240\itap0 \rtlch\fcs1 \af44\afs20\alang1025 \ltrch\fcs0 \f44\fs20\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \sbasedon43 \snext94 ref subhead first;}{\s95\ql \fi-2160\li3240\ri0\sb40\widctlpar\tx3240\wrapdefault\nooverflow\faroman\rin0\lin3240\itap0 \rtlch\fcs1 \af44\afs20\alang1025 \ltrch\fcs0 \f44\fs20\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \sbasedon0 \snext94 ref subhead last;}{\s96\ql \li1440\ri0\sb180\sa120\widctlpar\wrapdefault\nooverflow\faroman\rin0\lin1440\itap0 \rtlch\fcs1 \af44\afs20\alang1025 \ltrch\fcs0 \f44\fs20\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \sbasedon0 \snext96 \slink97 Body Text;}{\*\cs97 \additive \rtlch\fcs1 \af44\afs20 \ltrch\fcs0 \f44\fs20 \sbasedon10 \slink96 \slocked \ssemihidden Body Text Char;}{ \s98\ql \li1080\ri0\sb120\keepn\widctlpar\tqr\tldot\tx9893\wrapdefault\nooverflow\faroman\rin0\lin1080\itap0 \rtlch\fcs1 \ab\af1\afs20\alang1025 \ltrch\fcs0 \b\f1\fs20\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \sbasedon0 \snext0 \sautoupd \spriority39 toc 1;}{\s99\ql \li1440\ri1440\sb180\sa120\widctlpar\wrapdefault\nooverflow\faroman\rin1440\lin1440\itap0 \rtlch\fcs1 \af44\afs20\alang1025 \ltrch\fcs0 \f44\fs20\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \sbasedon0 \snext99 Block Text;}{\s100\ql \li360\ri0\sb180\sa120\widctlpar\wrapdefault\nooverflow\faroman\rin0\lin360\itap0 \rtlch\fcs1 \af44\afs20\alang1025 \ltrch\fcs0 \f44\fs20\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \sbasedon0 \snext100 \slink101 Body Text 2;}{\*\cs101 \additive \rtlch\fcs1 \af44\afs20 \ltrch\fcs0 \f44\fs20 \sbasedon10 \slink100 \slocked \ssemihidden Body Text 2 Char;}{ \s102\ql \li1440\ri0\sb180\sa120\widctlpar\wrapdefault\nooverflow\faroman\rin0\lin1440\itap0 \rtlch\fcs1 \af44\afs16\alang1025 \ltrch\fcs0 \f44\fs16\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \sbasedon0 \snext102 \slink103 Body Text 3;}{\*\cs103 \additive \rtlch\fcs1 \af44\afs16 \ltrch\fcs0 \f44\fs16 \sbasedon10 \slink102 \slocked \ssemihidden Body Text 3 Char;}{\s104\ql \fi210\li1440\ri0\sb180\sa120\widctlpar\wrapdefault\nooverflow\faroman\rin0\lin1440\itap0 \rtlch\fcs1 \af44\afs20\alang1025 \ltrch\fcs0 \f44\fs20\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \sbasedon96 \snext104 \slink105 Body Text First Indent;}{\*\cs105 \additive \rtlch\fcs1 \af44\afs20 \ltrch\fcs0 \f44\fs20 \sbasedon97 \slink104 \slocked \ssemihidden Body Text First Indent Char;}{\s106\ql \li283\ri0\sb180\sa120\widctlpar\wrapdefault\nooverflow\faroman\rin0\lin283\itap0 \rtlch\fcs1 \af44\afs20\alang1025 \ltrch\fcs0 \f44\fs20\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \sbasedon0 \snext106 \slink107 Body Text Indent;}{\*\cs107 \additive \rtlch\fcs1 \af44\afs20 \ltrch\fcs0 \f44\fs20 \sbasedon10 \slink106 \slocked \ssemihidden Body Text Indent Char;}{ \s108\ql \fi210\li360\ri0\sb180\sa120\widctlpar\wrapdefault\nooverflow\faroman\rin0\lin360\itap0 \rtlch\fcs1 \af44\afs20\alang1025 \ltrch\fcs0 \f44\fs20\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \sbasedon100 \snext108 \slink109 Body Text First Indent 2;}{\*\cs109 \additive \rtlch\fcs1 \af44\afs20 \ltrch\fcs0 \f44\fs20 \sbasedon107 \slink108 \slocked \ssemihidden Body Text First Indent 2 Char;}{\s110\ql \li360\ri0\sb180\sa120\sl480\slmult1 \widctlpar\wrapdefault\nooverflow\faroman\rin0\lin360\itap0 \rtlch\fcs1 \af44\afs20\alang1025 \ltrch\fcs0 \f44\fs20\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \sbasedon0 \snext110 \slink111 Body Text Indent 2;}{\*\cs111 \additive \rtlch\fcs1 \af44\afs20 \ltrch\fcs0 \f44\fs20 \sbasedon10 \slink110 \slocked \ssemihidden Body Text Indent 2 Char;}{\s112\ql \li360\ri0\sb180\sa120\widctlpar\wrapdefault\nooverflow\faroman\rin0\lin360\itap0 \rtlch\fcs1 \af44\afs16\alang1025 \ltrch\fcs0 \f44\fs16\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \sbasedon0 \snext112 \slink113 Body Text Indent 3;}{\*\cs113 \additive \rtlch\fcs1 \af44\afs16 \ltrch\fcs0 \f44\fs16 \sbasedon10 \slink112 \slocked \ssemihidden Body Text Indent 3 Char;}{ \s114\ql \li1440\ri0\sb120\sa120\widctlpar\wrapdefault\nooverflow\faroman\rin0\lin1440\itap0 \rtlch\fcs1 \ab\af44\afs20\alang1025 \ltrch\fcs0 \b\f44\fs20\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \sbasedon0 \snext0 \sqformat caption;}{ \s115\ql \li4320\ri0\sb180\widctlpar\wrapdefault\nooverflow\faroman\rin0\lin4320\itap0 \rtlch\fcs1 \af44\afs20\alang1025 \ltrch\fcs0 \f44\fs20\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \sbasedon0 \snext115 \slink116 Closing;}{\*\cs116 \additive \rtlch\fcs1 \af44\afs20 \ltrch\fcs0 \f44\fs20 \sbasedon10 \slink115 \slocked \ssemihidden Closing Char;}{\s117\ql \li1440\ri0\sb180\widctlpar\wrapdefault\nooverflow\faroman\rin0\lin1440\itap0 \rtlch\fcs1 \af44\afs20\alang1025 \ltrch\fcs0 \f44\fs20\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \sbasedon0 \snext117 \slink118 \ssemihidden annotation text;}{\*\cs118 \additive \rtlch\fcs1 \af44\afs20 \ltrch\fcs0 \f44\fs20 \sbasedon10 \slink117 \slocked \ssemihidden Comment Text Char;}{ \s119\ql \li1440\ri0\sb180\widctlpar\wrapdefault\nooverflow\faroman\rin0\lin1440\itap0 \rtlch\fcs1 \af44\afs20\alang1025 \ltrch\fcs0 \f44\fs20\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \sbasedon0 \snext0 \slink120 Date;}{\*\cs120 \additive \rtlch\fcs1 \af44\afs20 \ltrch\fcs0 \f44\fs20 \sbasedon10 \slink119 \slocked \ssemihidden Date Char;}{\s121\ql \li1440\ri0\sb180\widctlpar\wrapdefault\nooverflow\faroman\rin0\lin1440\itap0 \cbpat9 \rtlch\fcs1 \af43\afs20\alang1025 \ltrch\fcs0 \f43\fs20\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \sbasedon0 \snext121 \slink122 \ssemihidden Document Map;}{\*\cs122 \additive \rtlch\fcs1 \af43\afs16 \ltrch\fcs0 \f43\fs16 \sbasedon10 \slink121 \slocked \ssemihidden Document Map Char;}{ \s123\ql \li1440\ri0\sb180\widctlpar\wrapdefault\nooverflow\faroman\rin0\lin1440\itap0 \rtlch\fcs1 \af44\afs20\alang1025 \ltrch\fcs0 \f44\fs20\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \sbasedon0 \snext123 \slink124 \ssemihidden endnote text;}{\* \cs124 \additive \rtlch\fcs1 \af44\afs20 \ltrch\fcs0 \f44\fs20 \sbasedon10 \slink123 \slocked \ssemihidden Endnote Text Char;}{ \s125\ql \li2880\ri0\sb180\widctlpar\phpg\posxc\posyb\absh-1980\absw7920\dxfrtext180\dfrmtxtx180\dfrmtxty0\wrapdefault\nooverflow\faroman\rin0\lin2880\itap0 \rtlch\fcs1 \af1\afs24\alang1025 \ltrch\fcs0 \f1\fs24\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \sbasedon0 \snext125 envelope address;}{\s126\ql \li1440\ri0\sb180\widctlpar\wrapdefault\nooverflow\faroman\rin0\lin1440\itap0 \rtlch\fcs1 \af1\afs20\alang1025 \ltrch\fcs0 \f1\fs20\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \sbasedon0 \snext126 envelope return;}{\s127\ql \li1440\ri0\sb180\widctlpar\wrapdefault\nooverflow\faroman\rin0\lin1440\itap0 \rtlch\fcs1 \af44\afs20\alang1025 \ltrch\fcs0 \f44\fs20\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \sbasedon0 \snext127 \slink128 \ssemihidden footnote text;}{\*\cs128 \additive \rtlch\fcs1 \af44\afs20 \ltrch\fcs0 \f44\fs20 \sbasedon10 \slink127 \slocked \ssemihidden Footnote Text Char;}{ \s129\ql \fi-200\li200\ri0\sb180\widctlpar\wrapdefault\nooverflow\faroman\rin0\lin200\itap0 \rtlch\fcs1 \af44\afs20\alang1025 \ltrch\fcs0 \f44\fs20\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \sbasedon0 \snext0 \sautoupd \ssemihidden index 1;}{ \s130\ql \fi-200\li400\ri0\sb180\widctlpar\wrapdefault\nooverflow\faroman\rin0\lin400\itap0 \rtlch\fcs1 \af44\afs20\alang1025 \ltrch\fcs0 \f44\fs20\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \sbasedon0 \snext0 \sautoupd \ssemihidden index 2;}{ \s131\ql \fi-200\li600\ri0\sb180\widctlpar\wrapdefault\nooverflow\faroman\rin0\lin600\itap0 \rtlch\fcs1 \af44\afs20\alang1025 \ltrch\fcs0 \f44\fs20\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \sbasedon0 \snext0 \sautoupd \ssemihidden index 3;}{ \s132\ql \fi-200\li800\ri0\sb180\widctlpar\wrapdefault\nooverflow\faroman\rin0\lin800\itap0 \rtlch\fcs1 \af44\afs20\alang1025 \ltrch\fcs0 \f44\fs20\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \sbasedon0 \snext0 \sautoupd \ssemihidden index 4;}{ \s133\ql \fi-200\li1000\ri0\sb180\widctlpar\wrapdefault\nooverflow\faroman\rin0\lin1000\itap0 \rtlch\fcs1 \af44\afs20\alang1025 \ltrch\fcs0 \f44\fs20\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \sbasedon0 \snext0 \sautoupd \ssemihidden index 5;}{ \s134\ql \fi-200\li1200\ri0\sb180\widctlpar\wrapdefault\nooverflow\faroman\rin0\lin1200\itap0 \rtlch\fcs1 \af44\afs20\alang1025 \ltrch\fcs0 \f44\fs20\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \sbasedon0 \snext0 \sautoupd \ssemihidden index 6;}{ \s135\ql \fi-200\li1400\ri0\sb180\widctlpar\wrapdefault\nooverflow\faroman\rin0\lin1400\itap0 \rtlch\fcs1 \af44\afs20\alang1025 \ltrch\fcs0 \f44\fs20\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \sbasedon0 \snext0 \sautoupd \ssemihidden index 7;}{ \s136\ql \fi-200\li1600\ri0\sb180\widctlpar\wrapdefault\nooverflow\faroman\rin0\lin1600\itap0 \rtlch\fcs1 \af44\afs20\alang1025 \ltrch\fcs0 \f44\fs20\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \sbasedon0 \snext0 \sautoupd \ssemihidden index 8;}{ \s137\ql \fi-200\li1800\ri0\sb180\widctlpar\wrapdefault\nooverflow\faroman\rin0\lin1800\itap0 \rtlch\fcs1 \af44\afs20\alang1025 \ltrch\fcs0 \f44\fs20\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \sbasedon0 \snext0 \sautoupd \ssemihidden index 9;}{ \s138\ql \li1440\ri0\sb180\widctlpar\wrapdefault\nooverflow\faroman\rin0\lin1440\itap0 \rtlch\fcs1 \ab\af1\afs20\alang1025 \ltrch\fcs0 \b\f1\fs20\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \sbasedon0 \snext129 \ssemihidden index heading;}{ \s139\ql \fi-360\li720\ri0\sb180\widctlpar\wrapdefault\nooverflow\faroman\rin0\lin720\itap0 \rtlch\fcs1 \af44\afs20\alang1025 \ltrch\fcs0 \f44\fs20\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \sbasedon0 \snext139 List 2;}{ \s140\ql \fi-360\li1080\ri0\sb180\widctlpar\wrapdefault\nooverflow\faroman\rin0\lin1080\itap0 \rtlch\fcs1 \af44\afs20\alang1025 \ltrch\fcs0 \f44\fs20\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \sbasedon0 \snext140 List 3;}{ \s141\ql \fi-360\li1440\ri0\sb180\widctlpar\wrapdefault\nooverflow\faroman\rin0\lin1440\itap0 \rtlch\fcs1 \af44\afs20\alang1025 \ltrch\fcs0 \f44\fs20\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \sbasedon0 \snext141 List 4;}{ \s142\ql \fi-360\li1800\ri0\sb180\widctlpar\wrapdefault\nooverflow\faroman\rin0\lin1800\itap0 \rtlch\fcs1 \af44\afs20\alang1025 \ltrch\fcs0 \f44\fs20\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \sbasedon0 \snext142 List 5;}{ \s143\ql \fi-360\li360\ri0\sb180\widctlpar\jclisttab\tx360\wrapdefault{\*\pn \pnlvlbody\ilvl0\ls1\pnrnot0\pndec }\nooverflow\faroman\ls1\rin0\lin360\itap0 \rtlch\fcs1 \af44\afs20\alang1025 \ltrch\fcs0 \f44\fs20\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \sbasedon0 \snext143 \sautoupd List Bullet;}{\s144\ql \fi-360\li720\ri0\sb180\widctlpar\jclisttab\tx720\wrapdefault{\*\pn \pnlvlbody\ilvl0\ls2\pnrnot0\pndec } \nooverflow\faroman\ls2\rin0\lin720\itap0 \rtlch\fcs1 \af44\afs20\alang1025 \ltrch\fcs0 \f44\fs20\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \sbasedon0 \snext144 \sautoupd List Bullet 2;}{\s145\ql \fi-360\li1080\ri0\sb180\widctlpar \jclisttab\tx1080\wrapdefault{\*\pn \pnlvlbody\ilvl0\ls3\pnrnot0\pndec }\nooverflow\faroman\ls3\rin0\lin1080\itap0 \rtlch\fcs1 \af44\afs20\alang1025 \ltrch\fcs0 \f44\fs20\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \sbasedon0 \snext145 \sautoupd List Bullet 3;}{\s146\ql \fi-360\li1440\ri0\sb180\widctlpar\jclisttab\tx1440\wrapdefault{\*\pn \pnlvlbody\ilvl0\ls4\pnrnot0\pndec }\nooverflow\faroman\ls4\rin0\lin1440\itap0 \rtlch\fcs1 \af44\afs20\alang1025 \ltrch\fcs0 \f44\fs20\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \sbasedon0 \snext146 \sautoupd List Bullet 4;}{\s147\ql \fi-360\li1800\ri0\sb180\widctlpar\jclisttab\tx1800\wrapdefault{\*\pn \pnlvlbody\ilvl0\ls5\pnrnot0\pndec } \nooverflow\faroman\ls5\rin0\lin1800\itap0 \rtlch\fcs1 \af44\afs20\alang1025 \ltrch\fcs0 \f44\fs20\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \sbasedon0 \snext147 \sautoupd List Bullet 5;}{ \s148\ql \li360\ri0\sb180\sa120\widctlpar\wrapdefault\nooverflow\faroman\rin0\lin360\itap0 \rtlch\fcs1 \af44\afs20\alang1025 \ltrch\fcs0 \f44\fs20\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \sbasedon0 \snext148 List Continue;}{ \s149\ql \li720\ri0\sb180\sa120\widctlpar\wrapdefault\nooverflow\faroman\rin0\lin720\itap0 \rtlch\fcs1 \af44\afs20\alang1025 \ltrch\fcs0 \f44\fs20\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \sbasedon0 \snext149 List Continue 2;}{ \s150\ql \li1080\ri0\sb180\sa120\widctlpar\wrapdefault\nooverflow\faroman\rin0\lin1080\itap0 \rtlch\fcs1 \af44\afs20\alang1025 \ltrch\fcs0 \f44\fs20\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \sbasedon0 \snext150 List Continue 3;}{ \s151\ql \li1440\ri0\sb180\sa120\widctlpar\wrapdefault\nooverflow\faroman\rin0\lin1440\itap0 \rtlch\fcs1 \af44\afs20\alang1025 \ltrch\fcs0 \f44\fs20\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \sbasedon0 \snext151 List Continue 4;}{ \s152\ql \li1800\ri0\sb180\sa120\widctlpar\wrapdefault\nooverflow\faroman\rin0\lin1800\itap0 \rtlch\fcs1 \af44\afs20\alang1025 \ltrch\fcs0 \f44\fs20\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \sbasedon0 \snext152 List Continue 5;}{ \s153\ql \fi-360\li720\ri0\sb180\widctlpar\jclisttab\tx720\wrapdefault{\*\pn \pnlvlbody\ilvl0\ls6\pnrnot0\pndec }\nooverflow\faroman\ls6\rin0\lin720\itap0 \rtlch\fcs1 \af44\afs20\alang1025 \ltrch\fcs0 \f44\fs20\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \sbasedon0 \snext153 List Number 2;}{\s154\ql \fi-360\li1080\ri0\sb180\widctlpar\jclisttab\tx1080\wrapdefault{\*\pn \pnlvlbody\ilvl0\ls7\pnrnot0\pndec }\nooverflow\faroman\ls7\rin0\lin1080\itap0 \rtlch\fcs1 \af44\afs20\alang1025 \ltrch\fcs0 \f44\fs20\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \sbasedon0 \snext154 List Number 3;}{\s155\ql \fi-360\li1440\ri0\sb180\widctlpar\jclisttab\tx1440\wrapdefault{\*\pn \pnlvlbody\ilvl0\ls8\pnrnot0 \pndec }\nooverflow\faroman\ls8\rin0\lin1440\itap0 \rtlch\fcs1 \af44\afs20\alang1025 \ltrch\fcs0 \f44\fs20\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \sbasedon0 \snext155 List Number 4;}{\s156\ql \fi-360\li1800\ri0\sb180\widctlpar \jclisttab\tx1800\wrapdefault{\*\pn \pnlvlbody\ilvl0\ls9\pnrnot0\pndec }\nooverflow\faroman\ls9\rin0\lin1800\itap0 \rtlch\fcs1 \af44\afs20\alang1025 \ltrch\fcs0 \f44\fs20\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \sbasedon0 \snext156 List Number 5;}{\s157\ql \li1440\ri0\sb180\widctlpar\tx480\tx960\tx1440\tx1920\tx2400\tx2880\tx3360\tx3840\tx4320\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin1440\itap0 \rtlch\fcs1 \af2\afs20\alang1025 \ltrch\fcs0 \f2\fs20\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \snext157 \slink158 \ssemihidden macro;}{\*\cs158 \additive \rtlch\fcs1 \af2\afs20 \ltrch\fcs0 \f2\fs20 \sbasedon10 \slink157 \slocked \ssemihidden Macro Text Char;}{ \s159\ql \fi-1080\li1080\ri0\sb180\widctlpar\brdrt\brdrs\brdrw15\brsp20 \brdrl\brdrs\brdrw15\brsp20 \brdrb\brdrs\brdrw15\brsp20 \brdrr\brdrs\brdrw15\brsp20 \wrapdefault\nooverflow\faroman\rin0\lin1080\itap0 \shading2000 \rtlch\fcs1 \af1\afs24\alang1025 \ltrch\fcs0 \f1\fs24\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \sbasedon0 \snext159 \slink160 Message Header;}{\*\cs160 \additive \rtlch\fcs1 \af0\afs24 \ltrch\fcs0 \f42\fs24\chshdng2000\chcfpat0\chcbpat0 \sbasedon10 \slink159 \slocked \ssemihidden Message Header Char;}{\s161\ql \li1440\ri0\sb180\widctlpar\wrapdefault\nooverflow\faroman\rin0\lin1440\itap0 \rtlch\fcs1 \af44\afs20\alang1025 \ltrch\fcs0 \f44\fs20\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \sbasedon0 \snext0 \slink162 Note Heading;}{\*\cs162 \additive \rtlch\fcs1 \af44\afs20 \ltrch\fcs0 \f44\fs20 \sbasedon10 \slink161 \slocked \ssemihidden Note Heading Char;}{ \s163\ql \li1440\ri0\sb180\widctlpar\wrapdefault\nooverflow\faroman\rin0\lin1440\itap0 \rtlch\fcs1 \af2\afs20\alang1025 \ltrch\fcs0 \f2\fs20\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \sbasedon0 \snext163 \slink164 Plain Text;}{\*\cs164 \additive \rtlch\fcs1 \af2\afs20 \ltrch\fcs0 \f2\fs20 \sbasedon10 \slink163 \slocked \ssemihidden Plain Text Char;}{\s165\ql \li1440\ri0\sb180\widctlpar\wrapdefault\nooverflow\faroman\rin0\lin1440\itap0 \rtlch\fcs1 \af44\afs20\alang1025 \ltrch\fcs0 \f44\fs20\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \sbasedon0 \snext0 \slink166 Salutation;}{\*\cs166 \additive \rtlch\fcs1 \af44\afs20 \ltrch\fcs0 \f44\fs20 \sbasedon10 \slink165 \slocked \ssemihidden Salutation Char;}{ \s167\ql \li4320\ri0\sb180\widctlpar\wrapdefault\nooverflow\faroman\rin0\lin4320\itap0 \rtlch\fcs1 \af44\afs20\alang1025 \ltrch\fcs0 \f44\fs20\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \sbasedon0 \snext167 \slink168 Signature;}{\*\cs168 \additive \rtlch\fcs1 \af44\afs20 \ltrch\fcs0 \f44\fs20 \sbasedon10 \slink167 \slocked \ssemihidden Signature Char;}{\s169\qc \li1440\ri0\sb180\sa60\widctlpar\wrapdefault\nooverflow\faroman\outlinelevel1\rin0\lin1440\itap0 \rtlch\fcs1 \af1\afs24\alang1025 \ltrch\fcs0 \f1\fs24\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \sbasedon0 \snext169 \slink170 \sqformat Subtitle;}{\*\cs170 \additive \rtlch\fcs1 \af0\afs24 \ltrch\fcs0 \f42\fs24 \sbasedon10 \slink169 \slocked Subtitle Char;}{ \s171\ql \fi-200\li200\ri0\sb180\widctlpar\wrapdefault\nooverflow\faroman\rin0\lin200\itap0 \rtlch\fcs1 \af44\afs20\alang1025 \ltrch\fcs0 \f44\fs20\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \sbasedon0 \snext0 \ssemihidden table of authorities;}{ \s172\ql \fi-400\li400\ri0\sb180\widctlpar\wrapdefault\nooverflow\faroman\rin0\lin400\itap0 \rtlch\fcs1 \af44\afs20\alang1025 \ltrch\fcs0 \f44\fs20\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \sbasedon0 \snext0 \ssemihidden table of figures;}{ \s173\qc \li1440\ri0\sb240\sa60\widctlpar\wrapdefault\nooverflow\faroman\outlinelevel0\rin0\lin1440\itap0 \rtlch\fcs1 \ab\af1\afs32\alang1025 \ltrch\fcs0 \b\f1\fs32\lang1033\langfe1033\kerning28\cgrid\langnp1033\langfenp1033 \sbasedon0 \snext173 \slink174 \sqformat Title;}{\*\cs174 \additive \rtlch\fcs1 \ab\af0\afs32 \ltrch\fcs0 \b\f42\fs32\kerning28 \sbasedon10 \slink173 \slocked Title Char;}{ \s175\ql \li1440\ri0\sb120\widctlpar\wrapdefault\nooverflow\faroman\rin0\lin1440\itap0 \rtlch\fcs1 \ab\af1\afs24\alang1025 \ltrch\fcs0 \b\f1\fs24\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \sbasedon0 \snext0 \ssemihidden toa heading;}{ \s176\ql \li1440\ri0\sb180\widctlpar\tqr\tldot\tx9883\wrapdefault\nooverflow\faroman\rin0\lin1440\itap0 \rtlch\fcs1 \af44\afs20\alang1025 \ltrch\fcs0 \f44\fs20\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \sbasedon0 \snext0 \sautoupd \spriority39 toc 2;}{\s177\ql \li400\ri0\sb180\widctlpar\wrapdefault\nooverflow\faroman\rin0\lin400\itap0 \rtlch\fcs1 \af44\afs20\alang1025 \ltrch\fcs0 \f44\fs20\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \sbasedon0 \snext0 \sautoupd \ssemihidden toc 3;}{ \s178\ql \li600\ri0\sb180\widctlpar\wrapdefault\nooverflow\faroman\rin0\lin600\itap0 \rtlch\fcs1 \af44\afs20\alang1025 \ltrch\fcs0 \f44\fs20\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \sbasedon0 \snext0 \sautoupd \ssemihidden toc 4;}{ \s179\ql \li800\ri0\sb180\widctlpar\wrapdefault\nooverflow\faroman\rin0\lin800\itap0 \rtlch\fcs1 \af44\afs20\alang1025 \ltrch\fcs0 \f44\fs20\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \sbasedon0 \snext0 \sautoupd \ssemihidden toc 5;}{ \s180\ql \li1000\ri0\sb180\widctlpar\wrapdefault\nooverflow\faroman\rin0\lin1000\itap0 \rtlch\fcs1 \af44\afs20\alang1025 \ltrch\fcs0 \f44\fs20\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \sbasedon0 \snext0 \sautoupd \ssemihidden toc 6;}{ \s181\ql \li1200\ri0\sb180\widctlpar\wrapdefault\nooverflow\faroman\rin0\lin1200\itap0 \rtlch\fcs1 \af44\afs20\alang1025 \ltrch\fcs0 \f44\fs20\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \sbasedon0 \snext0 \sautoupd \ssemihidden toc 7;}{ \s182\ql \li1400\ri0\sb180\widctlpar\wrapdefault\nooverflow\faroman\rin0\lin1400\itap0 \rtlch\fcs1 \af44\afs20\alang1025 \ltrch\fcs0 \f44\fs20\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \sbasedon0 \snext0 \sautoupd \ssemihidden toc 8;}{ \s183\ql \li1600\ri0\sb180\widctlpar\wrapdefault\nooverflow\faroman\rin0\lin1600\itap0 \rtlch\fcs1 \af44\afs20\alang1025 \ltrch\fcs0 \f44\fs20\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \sbasedon0 \snext0 \sautoupd \ssemihidden toc 9;}{ \s184\ql \li1440\ri0\sb180\widctlpar\wrapdefault\nooverflow\faroman\rin0\lin1440\itap0 \rtlch\fcs1 \af43\afs16\alang1025 \ltrch\fcs0 \f43\fs16\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \sbasedon0 \snext184 \slink185 \ssemihidden Balloon Text;}{\* \cs185 \additive \rtlch\fcs1 \af43\afs16 \ltrch\fcs0 \f43\fs16 \sbasedon10 \slink184 \slocked \ssemihidden Balloon Text Char;}{\*\ts186\tsrowd\trbrdrt\brdrs\brdrw10 \trbrdrl\brdrs\brdrw10 \trbrdrb\brdrs\brdrw10 \trbrdrr\brdrs\brdrw10 \trbrdrh \brdrs\brdrw10 \trbrdrv\brdrs\brdrw10 \trftsWidthB3\trpaddl108\trpaddr108\trpaddfl3\trpaddft3\trpaddfb3\trpaddfr3\trcbpat1\trcfpat1\tblind0\tblindtype3\tsvertalt\tsbrdrt\tsbrdrl\tsbrdrb\tsbrdrr\tsbrdrdgl\tsbrdrdgr\tsbrdrh\tsbrdrv \ql \li1440\ri0\sb180\widctlpar\wrapdefault\nooverflow\faroman\rin0\lin1440\itap0 \rtlch\fcs1 \af0\afs20\alang1025 \ltrch\fcs0 \fs20\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \sbasedon11 \snext186 Table Grid;}{\*\cs187 \additive \rtlch\fcs1 \af0 \ltrch\fcs0 \ul\cf2 \sbasedon10 Hyperlink;}{\*\cs188 \additive \rtlch\fcs1 \af0\afs19 \ltrch\fcs0 \fs19 \sbasedon10 postbody1;}{\s189\ql \li0\ri0\keepn\pagebb\widctlpar\brdrt\brdrs\brdrw30\brsp120 \wrapdefault\nooverflow\faroman\outlinelevel0\rin0\lin0\itap0 \rtlch\fcs1 \ab\af1\afs24\alang1025 \ltrch\fcs0 \b\f1\fs24\cf9\lang1024\langfe1024\cgrid\noproof\langnp1033\langfenp1033 \sbasedon1 \snext189 \slink190 TWAIN Header;}{\*\cs190 \additive \rtlch\fcs1 \ab\af1\afs24 \ltrch\fcs0 \b\f1\fs24\cf9\lang1024\langfe1024\kerning32\noproof \sbasedon15 \slink189 \slocked TWAIN Header Char;}{\s191\ql \li720\ri0\sb360\sl240\slmult0\widctlpar\tx720\wrapdefault\hyphpar0\faauto\rin0\lin720\itap0 \rtlch\fcs1 \af44\afs20\alang1025 \ltrch\fcs0 \f44\fs20\cf1\lang1033\langfe1033\charscalex0\cgrid\langnp1033\langfenp1033 \snext191 body;}{\s192\ql \li1440\ri0\sb120\sl240\slmult0\widctlpar \tx720\tx1080\tx1440\tx1800\tx2160\tx2520\tx2880\tx3240\tx3600\tx3960\tx4320\tx4680\tx5040\tx5400\tx5760\tx6120\tx6480\tx6840\tx7200\tx7560\tx7920\tx8280\tx8640\tx9000\wrapdefault\hyphpar0\faauto\rin0\lin1440\itap0 \rtlch\fcs1 \af48\afs20\alang1025 \ltrch\fcs0 \f48\fs20\cf1\lang1033\langfe1033\charscalex0\cgrid\langnp1033\langfenp1033 \snext0 Code;}{\s193\ql \fi-3240\li4680\ri0\sb120\sl240\slmult0\widctlpar\tx4680\tx7400\wrapdefault\hyphpar0\faauto\rin0\lin4680\itap0 \rtlch\fcs1 \af44\afs20\alang1025 \ltrch\fcs0 \f44\fs20\cf1\lang1033\langfe1033\charscalex0\cgrid\langnp1033\langfenp1033 \snext31 twocol;}{\*\cs194 \additive \f2 Code2;}{\s195\ql \li0\ri0\widctlpar\wrapdefault\faauto\adjustright\rin0\lin0\itap0 \rtlch\fcs1 \af0\afs24\alang1025 \ltrch\fcs0 \fs24\cf1\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \sbasedon0 \snext195 Default;}{\*\cs196 \additive \rtlch\fcs1 \af0 \ltrch\fcs0 \sbasedon10 \spriority0 postbody;}{\*\cs197 \additive \rtlch\fcs1 \af0 \ltrch\fcs0 \ul\cf19 \sbasedon10 \slocked \ssemihidden \sunhideused FollowedHyperlink;}{\s198\ql \li60\ri60\sb80\sa80\sl240\slmult0\widctlpar\tx720\tx2520\wrapdefault\hyphpar0\faauto\rin60\lin60\itap0 \rtlch\fcs1 \af2\afs20\alang1025 \ltrch\fcs0 \fs20\cf1\lang1033\langfe2052\loch\f2\hich\af2\dbch\af31505\charscalex0\cgrid\langnp1033\langfenp2052 \snext198 table_code;}{\s199\ql \li720\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin720\itap0 \rtlch\fcs1 \af37\afs22\alang1025 \ltrch\fcs0 \f37\fs22\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \sbasedon0 \snext199 \sqformat \spriority34 List Paragraph;}{\*\cs200 \additive \rtlch\fcs1 \af0 \ltrch\fcs0 \cf20\chshdng0\chcfpat0\chcbpat21 \sbasedon10 \ssemihidden \sunhideused Unresolved Mention;}}{\*\listtable{\list\listtemplateid-1403649448\listsimple{\listlevel\levelnfc0\levelnfcn0\leveljc0\leveljcn0\levelfollow0\levelstartat1\levelspace0\levelindent0{\leveltext\'02\'00.;}{\levelnumbers\'01;}\rtlch\fcs1 \af0 \ltrch\fcs0 \fi-360\li1800\jclisttab\tx1800\lin1800 }{\listname ;}\listid-132}{\list\listtemplateid-537102814\listsimple{\listlevel\levelnfc0\levelnfcn0\leveljc0\leveljcn0\levelfollow0\levelstartat1\levelspace0\levelindent0{\leveltext\'02\'00.;}{\levelnumbers\'01;} \rtlch\fcs1 \af0 \ltrch\fcs0 \fi-360\li1440\jclisttab\tx1440\lin1440 }{\listname ;}\listid-131}{\list\listtemplateid-241933882\listsimple{\listlevel\levelnfc0\levelnfcn0\leveljc0\leveljcn0\levelfollow0\levelstartat1\levelspace0\levelindent0{\leveltext \'02\'00.;}{\levelnumbers\'01;}\rtlch\fcs1 \af0 \ltrch\fcs0 \fi-360\li1080\jclisttab\tx1080\lin1080 }{\listname ;}\listid-130}{\list\listtemplateid894471834\listsimple{\listlevel\levelnfc0\levelnfcn0\leveljc0\leveljcn0\levelfollow0\levelstartat1 \levelspace0\levelindent0{\leveltext\'02\'00.;}{\levelnumbers\'01;}\rtlch\fcs1 \af0 \ltrch\fcs0 \fi-360\li720\jclisttab\tx720\lin720 }{\listname ;}\listid-129}{\list\listtemplateid-1633241602\listsimple{\listlevel\levelnfc23\levelnfcn23\leveljc0\leveljcn0 \levelfollow0\levelstartat1\levelspace0\levelindent0{\leveltext\'01\u-3913 ?;}{\levelnumbers;}\f3\fbias0 \fi-360\li1800\jclisttab\tx1800\lin1800 }{\listname ;}\listid-128}{\list\listtemplateid-203631750\listsimple{\listlevel\levelnfc23\levelnfcn23 \leveljc0\leveljcn0\levelfollow0\levelstartat1\levelspace0\levelindent0{\leveltext\'01\u-3913 ?;}{\levelnumbers;}\f3\fbias0 \fi-360\li1440\jclisttab\tx1440\lin1440 }{\listname ;}\listid-127}{\list\listtemplateid360335964\listsimple{\listlevel\levelnfc23 \levelnfcn23\leveljc0\leveljcn0\levelfollow0\levelstartat1\levelspace0\levelindent0{\leveltext\'01\u-3913 ?;}{\levelnumbers;}\f3\fbias0 \fi-360\li1080\jclisttab\tx1080\lin1080 }{\listname ;}\listid-126}{\list\listtemplateid627448582\listsimple{\listlevel \levelnfc23\levelnfcn23\leveljc0\leveljcn0\levelfollow0\levelstartat1\levelspace0\levelindent0{\leveltext\'01\u-3913 ?;}{\levelnumbers;}\f3\fbias0 \fi-360\li720\jclisttab\tx720\lin720 }{\listname ;}\listid-125}{\list\listtemplateid507960418\listsimple {\listlevel\levelnfc0\levelnfcn0\leveljc0\leveljcn0\levelfollow0\levelstartat1\levelspace0\levelindent0{\leveltext\'02\'00.;}{\levelnumbers\'01;}\rtlch\fcs1 \af0 \ltrch\fcs0 \fi-360\li360\jclisttab\tx360\lin360 }{\listname ;}\listid-120} {\list\listtemplateid-1407048446\listsimple{\listlevel\levelnfc23\levelnfcn23\leveljc0\leveljcn0\levelfollow0\levelstartat1\levelspace0\levelindent0{\leveltext\'01\u-3913 ?;}{\levelnumbers;}\f3\fbias0 \fi-360\li360\jclisttab\tx360\lin360 }{\listname ;}\listid-119}{\list\listtemplateid-950138062\listhybrid{\listlevel\levelnfc23\levelnfcn23\leveljc0\leveljcn0\levelfollow0\levelstartat0\levelspace0\levelindent0{\leveltext\leveltemplateid-129700622\'01-;}{\levelnumbers;} \loch\af37\hich\af37\dbch\af0\fbias0 \fi-360\li720\lin720 }{\listlevel\levelnfc23\levelnfcn23\leveljc0\leveljcn0\levelfollow0\levelstartat1\lvltentative\levelspace0\levelindent0{\leveltext\leveltemplateid67698691\'01o;}{\levelnumbers;}\f2\fbias0 \fi-360\li1440\lin1440 }{\listlevel\levelnfc23\levelnfcn23\leveljc0\leveljcn0\levelfollow0\levelstartat1\lvltentative\levelspace0\levelindent0{\leveltext\leveltemplateid67698693\'01\u-3929 ?;}{\levelnumbers;}\f10\fbias0 \fi-360\li2160\lin2160 }{\listlevel \levelnfc23\levelnfcn23\leveljc0\leveljcn0\levelfollow0\levelstartat1\lvltentative\levelspace0\levelindent0{\leveltext\leveltemplateid67698689\'01\u-3913 ?;}{\levelnumbers;}\f3\fbias0 \fi-360\li2880\lin2880 }{\listlevel\levelnfc23\levelnfcn23\leveljc0 \leveljcn0\levelfollow0\levelstartat1\lvltentative\levelspace0\levelindent0{\leveltext\leveltemplateid67698691\'01o;}{\levelnumbers;}\f2\fbias0 \fi-360\li3600\lin3600 }{\listlevel\levelnfc23\levelnfcn23\leveljc0\leveljcn0\levelfollow0\levelstartat1 \lvltentative\levelspace0\levelindent0{\leveltext\leveltemplateid67698693\'01\u-3929 ?;}{\levelnumbers;}\f10\fbias0 \fi-360\li4320\lin4320 }{\listlevel\levelnfc23\levelnfcn23\leveljc0\leveljcn0\levelfollow0\levelstartat1\lvltentative\levelspace0 \levelindent0{\leveltext\leveltemplateid67698689\'01\u-3913 ?;}{\levelnumbers;}\f3\fbias0 \fi-360\li5040\lin5040 }{\listlevel\levelnfc23\levelnfcn23\leveljc0\leveljcn0\levelfollow0\levelstartat1\lvltentative\levelspace0\levelindent0{\leveltext \leveltemplateid67698691\'01o;}{\levelnumbers;}\f2\fbias0 \fi-360\li5760\lin5760 }{\listlevel\levelnfc23\levelnfcn23\leveljc0\leveljcn0\levelfollow0\levelstartat1\lvltentative\levelspace0\levelindent0{\leveltext\leveltemplateid67698693 \'01\u-3929 ?;}{\levelnumbers;}\f10\fbias0 \fi-360\li6480\lin6480 }{\listname ;}\listid162478944}{\list\listtemplateid181715488\listhybrid{\listlevel\levelnfc23\levelnfcn23\leveljc0\leveljcn0\levelfollow0\levelstartat0\levelspace0\levelindent0{\leveltext \leveltemplateid1324631620\'01-;}{\levelnumbers;}\loch\af0\hich\af0\dbch\af0\fbias0 \fi-360\li720\lin720 }{\listlevel\levelnfc23\levelnfcn23\leveljc0\leveljcn0\levelfollow0\levelstartat1\lvltentative\levelspace0\levelindent0{\leveltext \leveltemplateid67698691\'01o;}{\levelnumbers;}\f2\fbias0 \fi-360\li1440\lin1440 }{\listlevel\levelnfc23\levelnfcn23\leveljc0\leveljcn0\levelfollow0\levelstartat1\lvltentative\levelspace0\levelindent0{\leveltext\leveltemplateid67698693 \'01\u-3929 ?;}{\levelnumbers;}\f10\fbias0 \fi-360\li2160\lin2160 }{\listlevel\levelnfc23\levelnfcn23\leveljc0\leveljcn0\levelfollow0\levelstartat1\lvltentative\levelspace0\levelindent0{\leveltext\leveltemplateid67698689\'01\u-3913 ?;}{\levelnumbers;} \f3\fbias0 \fi-360\li2880\lin2880 }{\listlevel\levelnfc23\levelnfcn23\leveljc0\leveljcn0\levelfollow0\levelstartat1\lvltentative\levelspace0\levelindent0{\leveltext\leveltemplateid67698691\'01o;}{\levelnumbers;}\f2\fbias0 \fi-360\li3600\lin3600 } {\listlevel\levelnfc23\levelnfcn23\leveljc0\leveljcn0\levelfollow0\levelstartat1\lvltentative\levelspace0\levelindent0{\leveltext\leveltemplateid67698693\'01\u-3929 ?;}{\levelnumbers;}\f10\fbias0 \fi-360\li4320\lin4320 }{\listlevel\levelnfc23\levelnfcn23 \leveljc0\leveljcn0\levelfollow0\levelstartat1\lvltentative\levelspace0\levelindent0{\leveltext\leveltemplateid67698689\'01\u-3913 ?;}{\levelnumbers;}\f3\fbias0 \fi-360\li5040\lin5040 }{\listlevel\levelnfc23\levelnfcn23\leveljc0\leveljcn0\levelfollow0 \levelstartat1\lvltentative\levelspace0\levelindent0{\leveltext\leveltemplateid67698691\'01o;}{\levelnumbers;}\f2\fbias0 \fi-360\li5760\lin5760 }{\listlevel\levelnfc23\levelnfcn23\leveljc0\leveljcn0\levelfollow0\levelstartat1\lvltentative\levelspace0 \levelindent0{\leveltext\leveltemplateid67698693\'01\u-3929 ?;}{\levelnumbers;}\f10\fbias0 \fi-360\li6480\lin6480 }{\listname ;}\listid984241419}{\list\listtemplateid81190112\listhybrid{\listlevel\levelnfc0\levelnfcn0\leveljc0\leveljcn0\levelfollow0 \levelstartat1\levelspace0\levelindent0{\leveltext\leveltemplateid1970803460\'02\'00);}{\levelnumbers\'01;}\rtlch\fcs1 \af0 \ltrch\fcs0 \fs22\cf22\loch\af37\hich\af37\dbch\af0\fbias0 \fi-360\li720\lin720 }{\listlevel\levelnfc4\levelnfcn4\leveljc0 \leveljcn0\levelfollow0\levelstartat1\levelspace0\levelindent0{\leveltext\leveltemplateid67698713\'02\'01.;}{\levelnumbers\'01;}\rtlch\fcs1 \af0 \ltrch\fcs0 \fi-360\li1440\lin1440 }{\listlevel\levelnfc2\levelnfcn2\leveljc2\leveljcn2\levelfollow0 \levelstartat1\levelspace0\levelindent0{\leveltext\leveltemplateid67698715\'02\'02.;}{\levelnumbers\'01;}\rtlch\fcs1 \af0 \ltrch\fcs0 \fi-180\li2160\lin2160 }{\listlevel\levelnfc0\levelnfcn0\leveljc0\leveljcn0\levelfollow0\levelstartat1\levelspace0 \levelindent0{\leveltext\leveltemplateid67698703\'02\'03.;}{\levelnumbers\'01;}\rtlch\fcs1 \af0 \ltrch\fcs0 \fi-360\li2880\lin2880 }{\listlevel\levelnfc4\levelnfcn4\leveljc0\leveljcn0\levelfollow0\levelstartat1\levelspace0\levelindent0{\leveltext \leveltemplateid67698713\'02\'04.;}{\levelnumbers\'01;}\rtlch\fcs1 \af0 \ltrch\fcs0 \fi-360\li3600\lin3600 }{\listlevel\levelnfc2\levelnfcn2\leveljc2\leveljcn2\levelfollow0\levelstartat1\levelspace0\levelindent0{\leveltext\leveltemplateid67698715 \'02\'05.;}{\levelnumbers\'01;}\rtlch\fcs1 \af0 \ltrch\fcs0 \fi-180\li4320\lin4320 }{\listlevel\levelnfc0\levelnfcn0\leveljc0\leveljcn0\levelfollow0\levelstartat1\levelspace0\levelindent0{\leveltext\leveltemplateid67698703\'02\'06.;}{\levelnumbers\'01;} \rtlch\fcs1 \af0 \ltrch\fcs0 \fi-360\li5040\lin5040 }{\listlevel\levelnfc4\levelnfcn4\leveljc0\leveljcn0\levelfollow0\levelstartat1\levelspace0\levelindent0{\leveltext\leveltemplateid67698713\'02\'07.;}{\levelnumbers\'01;}\rtlch\fcs1 \af0 \ltrch\fcs0 \fi-360\li5760\lin5760 }{\listlevel\levelnfc2\levelnfcn2\leveljc2\leveljcn2\levelfollow0\levelstartat1\levelspace0\levelindent0{\leveltext\leveltemplateid67698715\'02\'08.;}{\levelnumbers\'01;}\rtlch\fcs1 \af0 \ltrch\fcs0 \fi-180\li6480\lin6480 } {\listname ;}\listid2094470365}}{\*\listoverridetable{\listoverride\listid-120\listoverridecount0\ls1}{\listoverride\listid-119\listoverridecount0\ls2}{\listoverride\listid-125\listoverridecount0\ls3}{\listoverride\listid-126\listoverridecount0\ls4} {\listoverride\listid-127\listoverridecount0\ls5}{\listoverride\listid-128\listoverridecount0\ls6}{\listoverride\listid-129\listoverridecount0\ls7}{\listoverride\listid-130\listoverridecount0\ls8}{\listoverride\listid-131\listoverridecount0\ls9} {\listoverride\listid-132\listoverridecount0\ls10}{\listoverride\listid-120\listoverridecount0\ls11}{\listoverride\listid-119\listoverridecount0\ls12}{\listoverride\listid-125\listoverridecount0\ls13}{\listoverride\listid-126\listoverridecount0\ls14} {\listoverride\listid-127\listoverridecount0\ls15}{\listoverride\listid-128\listoverridecount0\ls16}{\listoverride\listid-129\listoverridecount0\ls17}{\listoverride\listid-130\listoverridecount0\ls18}{\listoverride\listid-131\listoverridecount0\ls19} {\listoverride\listid-132\listoverridecount0\ls20}{\listoverride\listid-120\listoverridecount0\ls21}{\listoverride\listid-119\listoverridecount0\ls22}{\listoverride\listid-125\listoverridecount0\ls23}{\listoverride\listid-126\listoverridecount0\ls24} {\listoverride\listid-127\listoverridecount0\ls25}{\listoverride\listid-128\listoverridecount0\ls26}{\listoverride\listid-129\listoverridecount0\ls27}{\listoverride\listid-130\listoverridecount0\ls28}{\listoverride\listid-131\listoverridecount0\ls29} {\listoverride\listid2094470365\listoverridecount9{\lfolevel\listoverridestartat\levelstartat1}{\lfolevel\listoverridestartat\levelstartat1}{\lfolevel\listoverridestartat\levelstartat1}{\lfolevel\listoverridestartat\levelstartat1}{\lfolevel \listoverridestartat\levelstartat1}{\lfolevel\listoverridestartat\levelstartat1}{\lfolevel\listoverridestartat\levelstartat1}{\lfolevel\listoverridestartat\levelstartat1}{\lfolevel\listoverridestartat\levelstartat1}\ls30}{\listoverride\listid984241419 \listoverridecount0\ls31}{\listoverride\listid162478944\listoverridecount0\ls32}}{\*\pgptbl {\pgp\ipgp0\itap0\li0\ri0\sb0\sa0}{\pgp\ipgp0\itap0\li0\ri0\sb0\sa0}{\pgp\ipgp0\itap0\li0\ri0\sb0\sa0}{\pgp\ipgp0\itap0\li0\ri0\sb0\sa0}{\pgp\ipgp0\itap0\li0\ri0 \sb0\sa0}{\pgp\ipgp0\itap0\li0\ri0\sb0\sa0}{\pgp\ipgp0\itap0\li0\ri0\sb0\sa0}{\pgp\ipgp0\itap0\li0\ri0\sb0\sa0}{\pgp\ipgp0\itap0\li0\ri0\sb0\sa0}{\pgp\ipgp0\itap0\li0\ri0\sb0\sa0}{\pgp\ipgp0\itap0\li0\ri0\sb0\sa0}{\pgp\ipgp0\itap0\li0\ri0\sb0\sa0}{\pgp \ipgp0\itap0\li0\ri0\sb0\sa0}{\pgp\ipgp0\itap0\li0\ri0\sb0\sa0}{\pgp\ipgp0\itap0\li0\ri0\sb0\sa0}}{\mmathPr\mmathFont34\mbrkBin0\mbrkBinSub0\msmallFrac0\mdispDef1\mlMargin0\mrMargin0\mdefJc1\mwrapIndent1440\mintLim0\mnaryLim1}{\info {\title Spec 1.9a - Title page}{\author The TWAIN Working Group}{\operator Mark Mclaughlin}{\creatim\yr2013\mo11\dy4\hr16\min24}{\revtim\yr2020\mo7\dy8\hr10\min28}{\printim\yr2010\mo7\dy28\hr8\min8}{\version43}{\edmins169}{\nofpages15}{\nofwords5493} {\nofchars31316}{\*\company JFL Peripheral Solutions Inc.}{\nofcharsws36736}{\vern111}}{\*\xmlnstbl {\xmlns1 http://schemas.microsoft.com/office/word/2003/wordml}}\paperw12240\paperh15840\margl1260\margr1080\margt1440\margb1080\gutter0\ltrsect\rtlgutter \widowctrl\ftnbj\aenddoc\trackmoves0\trackformatting1\donotembedsysfont0\relyonvml0\donotembedlingdata1\grfdocevents0\validatexml0\showplaceholdtext0\ignoremixedcontent0\saveinvalidxml0\showxmlerrors0\margmirror \noextrasprl\cvmme\sprsspbf\brkfrm\swpbdr\noxlattoyen\expshrtn\noultrlspc\dntblnsbdb\nospaceforul\lytprtmet\hyphcaps0\horzdoc\fracwidth\dghspace180\dgvspace180\dghorigin1701\dgvorigin1984\dghshow0\dgvshow0 \jexpand\viewkind1\viewscale100\pgbrdrhead\pgbrdrfoot\bdrrlswsix\nolnhtadjtbl \fet0{\*\wgrffmtfilter 013f}\ilfomacatclnup12{\*\ftnsep \ltrpar \pard\plain \ltrpar\ql \li1440\ri0\sb180\widctlpar\wrapdefault\nooverflow\faroman\rin0\lin1440\itap0 \rtlch\fcs1 \af44\afs20\alang1025 \ltrch\fcs0 \f44\fs20\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 {\rtlch\fcs1 \af44 \ltrch\fcs0 \chftnsep \par }}{\*\ftnsepc \ltrpar \pard\plain \ltrpar\ql \li1440\ri0\sb180\widctlpar\wrapdefault\nooverflow\faroman\rin0\lin1440\itap0 \rtlch\fcs1 \af44\afs20\alang1025 \ltrch\fcs0 \f44\fs20\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 {\rtlch\fcs1 \af44 \ltrch\fcs0 \chftnsepc \par }}{\*\aftnsep \ltrpar \pard\plain \ltrpar\ql \li1440\ri0\sb180\widctlpar\wrapdefault\nooverflow\faroman\rin0\lin1440\itap0 \rtlch\fcs1 \af44\afs20\alang1025 \ltrch\fcs0 \f44\fs20\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 {\rtlch\fcs1 \af44 \ltrch\fcs0 \chftnsep \par }}{\*\aftnsepc \ltrpar \pard\plain \ltrpar\ql \li1440\ri0\sb180\widctlpar\wrapdefault\nooverflow\faroman\rin0\lin1440\itap0 \rtlch\fcs1 \af44\afs20\alang1025 \ltrch\fcs0 \f44\fs20\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 {\rtlch\fcs1 \af44 \ltrch\fcs0 \chftnsepc \par }}\ltrpar \sectd \ltrsect\rtlgutter\psz1\linex0\endnhere\pgbrdropt32\sectdefaultcl\sectrsid6896082\sftnbj {\footerr \ltrpar \pard\plain \ltrpar\s25\ql \li0\ri0\widctlpar\tqr\tx9900\wrapdefault\nooverflow\faroman\rin0\lin0\itap0 \rtlch\fcs1 \ai\af1\afs16\alang1025 \ltrch\fcs0 \i\f1\fs16\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 {\rtlch\fcs1 \af1 \ltrch\fcs0 TWAIN for C#\tab }{\field{\*\fldinst {\rtlch\fcs1 \af1 \ltrch\fcs0 \cs32 PAGE }}{\fldrslt {\rtlch\fcs1 \af1 \ltrch\fcs0 \cs32\lang1024\langfe1024\noproof 11}}}\sectd \ltrsect\linex0\endnhere\sectdefaultcl\sftnbj {\rtlch\fcs1 \af1 \ltrch\fcs0 \cs32 \par Kodak Alaris Inc.}{\rtlch\fcs1 \af1 \ltrch\fcs0 \par }}{\*\pnseclvl1\pnucrm\pnstart1\pnindent720\pnhang {\pntxta .}}{\*\pnseclvl2\pnucltr\pnstart1\pnindent720\pnhang {\pntxta .}}{\*\pnseclvl3\pndec\pnstart1\pnindent720\pnhang {\pntxta .}}{\*\pnseclvl4\pnlcltr\pnstart1\pnindent720\pnhang {\pntxta )}} {\*\pnseclvl5\pndec\pnstart1\pnindent720\pnhang {\pntxtb (}{\pntxta )}}{\*\pnseclvl6\pnlcltr\pnstart1\pnindent720\pnhang {\pntxtb (}{\pntxta )}}{\*\pnseclvl7\pnlcrm\pnstart1\pnindent720\pnhang {\pntxtb (}{\pntxta )}}{\*\pnseclvl8 \pnlcltr\pnstart1\pnindent720\pnhang {\pntxtb (}{\pntxta )}}{\*\pnseclvl9\pnlcrm\pnstart1\pnindent720\pnhang {\pntxtb (}{\pntxta )}}\pard\plain \ltrpar\ql \li0\ri0\sb1440\widctlpar\brdrt\brdrs\brdrw60\brsp20\brdrcf13 \wrapdefault\nooverflow\faroman\rin0\lin0\itap0 \rtlch\fcs1 \af44\afs20\alang1025 \ltrch\fcs0 \f44\fs20\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 {\rtlch\fcs1 \af44 \ltrch\fcs0 \f31506 \par }\pard \ltrpar\ql \li1440\ri0\sb180\widctlpar\wrapdefault\nooverflow\faroman\rin0\lin1440\itap0 {\rtlch\fcs1 \af1\afs56 \ltrch\fcs0 \b\f31506\fs56\cf9 TWAIN for C# \par }\pard \ltrpar\ql \li1440\ri0\sb120\widctlpar\wrapdefault\nooverflow\faroman\rin0\lin1440\itap0 {\rtlch\fcs1 \ab\af1\afs28 \ltrch\fcs0 \b\f31506\fs28\cf13 For Version 2.4.11.0 \par }\pard \ltrpar\ql \li1440\ri0\sb180\widctlpar\wrapdefault\nooverflow\faroman\rin0\lin1440\itap0 {\rtlch\fcs1 \ab\af1\afs28 \ltrch\fcs0 \b\f31506\fs28 July 8}{\rtlch\fcs1 \ab\af1\afs28 \ltrch\fcs0 \b\f31506\fs28\super th}{\rtlch\fcs1 \ab\af1\afs28 \ltrch\fcs0 \b\f31506\fs28 , 2020 \par }\pard \ltrpar\ql \li1440\ri0\sb360\widctlpar\wrapdefault\nooverflow\faroman\rin0\lin1440\itap0 {\rtlch\fcs1 \af1\afs28 \ltrch\fcs0 \f31506\fs28 \par }\pard \ltrpar\ql \li0\ri0\sb120\widctlpar\brdrt\brdrs\brdrw60\brsp20\brdrcf13 \wrapdefault\nooverflow\faroman\rin0\lin0\itap0 {\rtlch\fcs1 \af44 \ltrch\fcs0 \f31506 \par }\pard \ltrpar\ql \li1440\ri0\sb240\widctlpar\wrapdefault\nooverflow\faroman\rin0\lin1440\itap0 {\rtlch\fcs1 \af44 \ltrch\fcs0 \f31506 \par }\pard \ltrpar\ql \li1440\ri0\sb360\widctlpar\wrapdefault\nooverflow\faroman\rin0\lin1440\itap0 {\rtlch\fcs1 \af44 \ltrch\fcs0 \f31506 \par \par }\pard \ltrpar\qc \li0\ri0\sb180\widctlpar\wrapdefault\nooverflow\faroman\rin0\lin0\itap0 {\rtlch\fcs1 \af44 \ltrch\fcs0 \f31506 \par }\pard \ltrpar\ql \li720\ri0\sb180\widctlpar\wrapdefault\nooverflow\faroman\rin0\lin720\itap0 {\rtlch\fcs1 \af44\afs40 \ltrch\fcs0 \f31506\fs40 \page }{\rtlch\fcs1 \af1\afs36 \ltrch\fcs0 \b\f31506\fs36\cf9 \par }\pard \ltrpar\ql \li720\ri0\sb180\keep\keepn\widctlpar\wrapdefault\nooverflow\faroman\rin0\lin720\itap0 {\rtlch\fcs1 \af1\afs36 \ltrch\fcs0 \b\f31506\fs36\cf9 Contents \par }\pard\plain \ltrpar\s98\ql \li1080\ri0\sb120\keepn\widctlpar\tqr\tldot\tx9893\wrapdefault\nooverflow\faroman\rin0\lin1080\itap0 \rtlch\fcs1 \ab\af1\afs20\alang1025 \ltrch\fcs0 \b\f1\fs20\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 {\field\fldedit{\*\fldinst {\rtlch\fcs1 \af1 \ltrch\fcs0 \b0\f31506 TOC \\o "1-3" \\h \\z \\u }}{\fldrslt {\field\fldedit{\*\fldinst {\rtlch\fcs1 \af0 \ltrch\fcs0 \cs187\ul\cf2\lang1024\langfe1024\noproof }{\rtlch\fcs1 \af1 \ltrch\fcs0 \lang1024\langfe1024\noproof HYPERLINK \\l "_Toc45096514"}{\rtlch\fcs1 \af0 \ltrch\fcs0 \cs187\ul\cf2\lang1024\langfe1024\noproof }{\rtlch\fcs1 \af0 \ltrch\fcs0 \cs187\ul\cf2\lang1024\langfe1024\noproof {\*\datafield 08d0c9ea79f9bace118c8200aa004ba90b02000000080000000d0000005f0054006f006300340035003000390036003500310034000000}}}{\fldrslt {\rtlch\fcs1 \af0 \ltrch\fcs0 \cs187\f37\ul\cf2\lang1024\langfe1024\noproof Purpose}{\rtlch\fcs1 \af1 \ltrch\fcs0 \lang1024\langfe1024\noproof\webhidden \tab }{\field{\*\fldinst {\rtlch\fcs1 \af1 \ltrch\fcs0 \lang1024\langfe1024\noproof\webhidden PAGEREF _Toc45096514 \\h }{\rtlch\fcs1 \af1 \ltrch\fcs0 \lang1024\langfe1024\noproof\webhidden {\*\datafield 08d0c9ea79f9bace118c8200aa004ba90b02000000080000000d0000005f0054006f006300340035003000390036003500310034000000}}}{\fldrslt {\rtlch\fcs1 \af1 \ltrch\fcs0 \lang1024\langfe1024\noproof\webhidden 4}}}\sectd \ltrsect\rtlgutter \psz1\linex0\endnhere\pgbrdropt32\sectdefaultcl\sectrsid6896082\sftnbj }}\sectd \ltrsect\rtlgutter\psz1\linex0\endnhere\pgbrdropt32\sectdefaultcl\sectrsid6896082\sftnbj {\rtlch\fcs1 \ab0\af31507\afs22 \ltrch\fcs0 \b0\fs22\lang1024\langfe1024\loch\af31506\hich\af31506\dbch\af31505\noproof \par }{\field\fldedit{\*\fldinst {\rtlch\fcs1 \af0 \ltrch\fcs0 \cs187\ul\cf2\lang1024\langfe1024\noproof }{\rtlch\fcs1 \af1 \ltrch\fcs0 \lang1024\langfe1024\noproof HYPERLINK \\l "_Toc45096515"}{\rtlch\fcs1 \af0 \ltrch\fcs0 \cs187\ul\cf2\lang1024\langfe1024\noproof }{\rtlch\fcs1 \af0 \ltrch\fcs0 \cs187\ul\cf2\lang1024\langfe1024\noproof {\*\datafield 08d0c9ea79f9bace118c8200aa004ba90b02000000080000000d0000005f0054006f006300340035003000390036003500310035000000}}}{\fldrslt { \rtlch\fcs1 \af0 \ltrch\fcs0 \cs187\f37\ul\cf2\lang1024\langfe1024\noproof License}{\rtlch\fcs1 \af1 \ltrch\fcs0 \lang1024\langfe1024\noproof\webhidden \tab }{\field{\*\fldinst {\rtlch\fcs1 \af1 \ltrch\fcs0 \lang1024\langfe1024\noproof\webhidden PAGEREF _Toc45096515 \\h }{\rtlch\fcs1 \af1 \ltrch\fcs0 \lang1024\langfe1024\noproof\webhidden {\*\datafield 08d0c9ea79f9bace118c8200aa004ba90b02000000080000000d0000005f0054006f006300340035003000390036003500310035000000}}}{\fldrslt {\rtlch\fcs1 \af1 \ltrch\fcs0 \lang1024\langfe1024\noproof\webhidden 4}}}\sectd \ltrsect\rtlgutter\psz1\linex0\endnhere\pgbrdropt32\sectdefaultcl\sectrsid6896082\sftnbj }}\sectd \ltrsect\rtlgutter\psz1\linex0\endnhere\pgbrdropt32\sectdefaultcl\sectrsid6896082\sftnbj {\rtlch\fcs1 \ab0\af31507\afs22 \ltrch\fcs0 \b0\fs22\lang1024\langfe1024\loch\af31506\hich\af31506\dbch\af31505\noproof \par }{\field\fldedit{\*\fldinst {\rtlch\fcs1 \af0 \ltrch\fcs0 \cs187\ul\cf2\lang1024\langfe1024\noproof }{\rtlch\fcs1 \af1 \ltrch\fcs0 \lang1024\langfe1024\noproof HYPERLINK \\l "_Toc45096516"}{\rtlch\fcs1 \af0 \ltrch\fcs0 \cs187\ul\cf2\lang1024\langfe1024\noproof }{\rtlch\fcs1 \af0 \ltrch\fcs0 \cs187\ul\cf2\lang1024\langfe1024\noproof {\*\datafield 08d0c9ea79f9bace118c8200aa004ba90b02000000080000000d0000005f0054006f006300340035003000390036003500310036000000}}}{\fldrslt { \rtlch\fcs1 \af0 \ltrch\fcs0 \cs187\ul\cf2\lang1024\langfe1024\noproof Project Repository}{\rtlch\fcs1 \af1 \ltrch\fcs0 \lang1024\langfe1024\noproof\webhidden \tab }{\field{\*\fldinst {\rtlch\fcs1 \af1 \ltrch\fcs0 \lang1024\langfe1024\noproof\webhidden PAGEREF _Toc45096516 \\h }{\rtlch\fcs1 \af1 \ltrch\fcs0 \lang1024\langfe1024\noproof\webhidden {\*\datafield 08d0c9ea79f9bace118c8200aa004ba90b02000000080000000d0000005f0054006f006300340035003000390036003500310036000000}}}{\fldrslt {\rtlch\fcs1 \af1 \ltrch\fcs0 \lang1024\langfe1024\noproof\webhidden 5}}}\sectd \ltrsect\rtlgutter\psz1\linex0\endnhere\pgbrdropt32\sectdefaultcl\sectrsid6896082\sftnbj }}\sectd \ltrsect\rtlgutter\psz1\linex0\endnhere\pgbrdropt32\sectdefaultcl\sectrsid6896082\sftnbj { \rtlch\fcs1 \ab0\af31507\afs22 \ltrch\fcs0 \b0\fs22\lang1024\langfe1024\loch\af31506\hich\af31506\dbch\af31505\noproof \par }\pard\plain \ltrpar\s176\ql \li1440\ri0\sb180\widctlpar\tqr\tldot\tx9883\wrapdefault\nooverflow\faroman\rin0\lin1440\itap0 \rtlch\fcs1 \af44\afs20\alang1025 \ltrch\fcs0 \f44\fs20\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 {\field\fldedit{\*\fldinst {\rtlch\fcs1 \af0 \ltrch\fcs0 \cs187\ul\cf2\lang1024\langfe1024\noproof }{\rtlch\fcs1 \af44 \ltrch\fcs0 \lang1024\langfe1024\noproof HYPERLINK \\l "_Toc45096517"}{\rtlch\fcs1 \af0 \ltrch\fcs0 \cs187\ul\cf2\lang1024\langfe1024\noproof }{\rtlch\fcs1 \af0 \ltrch\fcs0 \cs187\ul\cf2\lang1024\langfe1024\noproof {\*\datafield 08d0c9ea79f9bace118c8200aa004ba90b02000000080000000d0000005f0054006f006300340035003000390036003500310037000000}}}{\fldrslt { \rtlch\fcs1 \af0 \ltrch\fcs0 \cs187\b\ul\cf2\lang1024\langfe1024\noproof Installation}{\rtlch\fcs1 \af44 \ltrch\fcs0 \lang1024\langfe1024\noproof\webhidden \tab }{\field{\*\fldinst {\rtlch\fcs1 \af44 \ltrch\fcs0 \lang1024\langfe1024\noproof\webhidden PAGEREF _Toc45096517 \\h }{\rtlch\fcs1 \af44 \ltrch\fcs0 \lang1024\langfe1024\noproof\webhidden {\*\datafield 08d0c9ea79f9bace118c8200aa004ba90b02000000080000000d0000005f0054006f006300340035003000390036003500310037000000}}}{\fldrslt {\rtlch\fcs1 \af44 \ltrch\fcs0 \lang1024\langfe1024\noproof\webhidden 5}}}\sectd \ltrsect\rtlgutter\psz1\linex0\endnhere\pgbrdropt32\sectdefaultcl\sectrsid6896082\sftnbj }}\sectd \ltrsect\rtlgutter\psz1\linex0\endnhere\pgbrdropt32\sectdefaultcl\sectrsid6896082\sftnbj { \rtlch\fcs1 \af31507\afs22 \ltrch\fcs0 \fs22\lang1024\langfe1024\loch\af31506\hich\af31506\dbch\af31505\noproof \par }{\field\fldedit{\*\fldinst {\rtlch\fcs1 \af0 \ltrch\fcs0 \cs187\ul\cf2\lang1024\langfe1024\noproof }{\rtlch\fcs1 \af44 \ltrch\fcs0 \lang1024\langfe1024\noproof HYPERLINK \\l "_Toc45096518"}{\rtlch\fcs1 \af0 \ltrch\fcs0 \cs187\ul\cf2\lang1024\langfe1024\noproof }{\rtlch\fcs1 \af0 \ltrch\fcs0 \cs187\ul\cf2\lang1024\langfe1024\noproof {\*\datafield 08d0c9ea79f9bace118c8200aa004ba90b02000000080000000d0000005f0054006f006300340035003000390036003500310038000000}}}{\fldrslt { \rtlch\fcs1 \af0 \ltrch\fcs0 \cs187\b\ul\cf2\lang1024\langfe1024\noproof Versioning}{\rtlch\fcs1 \af44 \ltrch\fcs0 \lang1024\langfe1024\noproof\webhidden \tab }{\field{\*\fldinst {\rtlch\fcs1 \af44 \ltrch\fcs0 \lang1024\langfe1024\noproof\webhidden PAGEREF _Toc45096518 \\h }{\rtlch\fcs1 \af44 \ltrch\fcs0 \lang1024\langfe1024\noproof\webhidden {\*\datafield 08d0c9ea79f9bace118c8200aa004ba90b02000000080000000d0000005f0054006f006300340035003000390036003500310038000000}}}{\fldrslt {\rtlch\fcs1 \af44 \ltrch\fcs0 \lang1024\langfe1024\noproof\webhidden 5}}}\sectd \ltrsect\rtlgutter\psz1\linex0\endnhere\pgbrdropt32\sectdefaultcl\sectrsid6896082\sftnbj }}\sectd \ltrsect\rtlgutter\psz1\linex0\endnhere\pgbrdropt32\sectdefaultcl\sectrsid6896082\sftnbj { \rtlch\fcs1 \af31507\afs22 \ltrch\fcs0 \fs22\lang1024\langfe1024\loch\af31506\hich\af31506\dbch\af31505\noproof \par }\pard\plain \ltrpar\s98\ql \li1080\ri0\sb120\keepn\widctlpar\tqr\tldot\tx9893\wrapdefault\nooverflow\faroman\rin0\lin1080\itap0 \rtlch\fcs1 \ab\af1\afs20\alang1025 \ltrch\fcs0 \b\f1\fs20\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 {\field\fldedit{\*\fldinst {\rtlch\fcs1 \af0 \ltrch\fcs0 \cs187\ul\cf2\lang1024\langfe1024\noproof }{\rtlch\fcs1 \af1 \ltrch\fcs0 \lang1024\langfe1024\noproof HYPERLINK \\l "_Toc45096519"}{\rtlch\fcs1 \af0 \ltrch\fcs0 \cs187\ul\cf2\lang1024\langfe1024\noproof }{\rtlch\fcs1 \af0 \ltrch\fcs0 \cs187\ul\cf2\lang1024\langfe1024\noproof {\*\datafield 08d0c9ea79f9bace118c8200aa004ba90b02000000080000000d0000005f0054006f006300340035003000390036003500310039000000}}}{\fldrslt { \rtlch\fcs1 \af0 \ltrch\fcs0 \cs187\ul\cf2\lang1024\langfe1024\noproof Project Layout}{\rtlch\fcs1 \af1 \ltrch\fcs0 \lang1024\langfe1024\noproof\webhidden \tab }{\field{\*\fldinst {\rtlch\fcs1 \af1 \ltrch\fcs0 \lang1024\langfe1024\noproof\webhidden PAGEREF _Toc45096519 \\h }{\rtlch\fcs1 \af1 \ltrch\fcs0 \lang1024\langfe1024\noproof\webhidden {\*\datafield 08d0c9ea79f9bace118c8200aa004ba90b02000000080000000d0000005f0054006f006300340035003000390036003500310039000000}}}{\fldrslt {\rtlch\fcs1 \af1 \ltrch\fcs0 \lang1024\langfe1024\noproof\webhidden 6}}}\sectd \ltrsect\rtlgutter\psz1\linex0\endnhere\pgbrdropt32\sectdefaultcl\sectrsid6896082\sftnbj }}\sectd \ltrsect\rtlgutter\psz1\linex0\endnhere\pgbrdropt32\sectdefaultcl\sectrsid6896082\sftnbj { \rtlch\fcs1 \ab0\af31507\afs22 \ltrch\fcs0 \b0\fs22\lang1024\langfe1024\loch\af31506\hich\af31506\dbch\af31505\noproof \par }\pard\plain \ltrpar\s176\ql \li1440\ri0\sb180\widctlpar\tqr\tldot\tx9883\wrapdefault\nooverflow\faroman\rin0\lin1440\itap0 \rtlch\fcs1 \af44\afs20\alang1025 \ltrch\fcs0 \f44\fs20\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 {\field\fldedit{\*\fldinst {\rtlch\fcs1 \af0 \ltrch\fcs0 \cs187\ul\cf2\lang1024\langfe1024\noproof }{\rtlch\fcs1 \af44 \ltrch\fcs0 \lang1024\langfe1024\noproof HYPERLINK \\l "_Toc45096520"}{\rtlch\fcs1 \af0 \ltrch\fcs0 \cs187\ul\cf2\lang1024\langfe1024\noproof }{\rtlch\fcs1 \af0 \ltrch\fcs0 \cs187\ul\cf2\lang1024\langfe1024\noproof {\*\datafield 08d0c9ea79f9bace118c8200aa004ba90b02000000080000000d0000005f0054006f006300340035003000390036003500320030000000}}}{\fldrslt { \rtlch\fcs1 \af0 \ltrch\fcs0 \cs187\b\ul\cf2\lang1024\langfe1024\noproof Basic TWAIN C# Definitions and Helper Functions}{\rtlch\fcs1 \af44 \ltrch\fcs0 \lang1024\langfe1024\noproof\webhidden \tab }{\field{\*\fldinst {\rtlch\fcs1 \af44 \ltrch\fcs0 \lang1024\langfe1024\noproof\webhidden PAGEREF _Toc45096520 \\h }{\rtlch\fcs1 \af44 \ltrch\fcs0 \lang1024\langfe1024\noproof\webhidden {\*\datafield 08d0c9ea79f9bace118c8200aa004ba90b02000000080000000d0000005f0054006f006300340035003000390036003500320030000000}}}{\fldrslt {\rtlch\fcs1 \af44 \ltrch\fcs0 \lang1024\langfe1024\noproof\webhidden 6}}}\sectd \ltrsect\rtlgutter \psz1\linex0\endnhere\pgbrdropt32\sectdefaultcl\sectrsid6896082\sftnbj }}\sectd \ltrsect\rtlgutter\psz1\linex0\endnhere\pgbrdropt32\sectdefaultcl\sectrsid6896082\sftnbj {\rtlch\fcs1 \af31507\afs22 \ltrch\fcs0 \fs22\lang1024\langfe1024\loch\af31506\hich\af31506\dbch\af31505\noproof \par }{\field\fldedit{\*\fldinst {\rtlch\fcs1 \af0 \ltrch\fcs0 \cs187\ul\cf2\lang1024\langfe1024\noproof }{\rtlch\fcs1 \af44 \ltrch\fcs0 \lang1024\langfe1024\noproof HYPERLINK \\l "_Toc45096521"}{\rtlch\fcs1 \af0 \ltrch\fcs0 \cs187\ul\cf2\lang1024\langfe1024\noproof }{\rtlch\fcs1 \af0 \ltrch\fcs0 \cs187\ul\cf2\lang1024\langfe1024\noproof {\*\datafield 08d0c9ea79f9bace118c8200aa004ba90b02000000080000000d0000005f0054006f006300340035003000390036003500320031000000}}}{\fldrslt { \rtlch\fcs1 \af0 \ltrch\fcs0 \cs187\b\ul\cf2\lang1024\langfe1024\noproof A TWAIN C# Toolkit}{\rtlch\fcs1 \af44 \ltrch\fcs0 \lang1024\langfe1024\noproof\webhidden \tab }{\field{\*\fldinst {\rtlch\fcs1 \af44 \ltrch\fcs0 \lang1024\langfe1024\noproof\webhidden PAGEREF _Toc45096521 \\h }{\rtlch\fcs1 \af44 \ltrch\fcs0 \lang1024\langfe1024\noproof\webhidden {\*\datafield 08d0c9ea79f9bace118c8200aa004ba90b02000000080000000d0000005f0054006f006300340035003000390036003500320031000000}}}{\fldrslt {\rtlch\fcs1 \af44 \ltrch\fcs0 \lang1024\langfe1024\noproof\webhidden 7}}}\sectd \ltrsect\rtlgutter \psz1\linex0\endnhere\pgbrdropt32\sectdefaultcl\sectrsid6896082\sftnbj }}\sectd \ltrsect\rtlgutter\psz1\linex0\endnhere\pgbrdropt32\sectdefaultcl\sectrsid6896082\sftnbj {\rtlch\fcs1 \af31507\afs22 \ltrch\fcs0 \fs22\lang1024\langfe1024\loch\af31506\hich\af31506\dbch\af31505\noproof \par }{\field\fldedit{\*\fldinst {\rtlch\fcs1 \af0 \ltrch\fcs0 \cs187\ul\cf2\lang1024\langfe1024\noproof }{\rtlch\fcs1 \af44 \ltrch\fcs0 \lang1024\langfe1024\noproof HYPERLINK \\l "_Toc45096522"}{\rtlch\fcs1 \af0 \ltrch\fcs0 \cs187\ul\cf2\lang1024\langfe1024\noproof }{\rtlch\fcs1 \af0 \ltrch\fcs0 \cs187\ul\cf2\lang1024\langfe1024\noproof {\*\datafield 08d0c9ea79f9bace118c8200aa004ba90b02000000080000000d0000005f0054006f006300340035003000390036003500320032000000}}}{\fldrslt { \rtlch\fcs1 \af0 \ltrch\fcs0 \cs187\b\ul\cf2\lang1024\langfe1024\noproof A TWAIN C# Diagnostic Application}{\rtlch\fcs1 \af44 \ltrch\fcs0 \lang1024\langfe1024\noproof\webhidden \tab }{\field{\*\fldinst {\rtlch\fcs1 \af44 \ltrch\fcs0 \lang1024\langfe1024\noproof\webhidden PAGEREF _Toc45096522 \\h }{\rtlch\fcs1 \af44 \ltrch\fcs0 \lang1024\langfe1024\noproof\webhidden {\*\datafield 08d0c9ea79f9bace118c8200aa004ba90b02000000080000000d0000005f0054006f006300340035003000390036003500320032000000}}}{\fldrslt {\rtlch\fcs1 \af44 \ltrch\fcs0 \lang1024\langfe1024\noproof\webhidden 7}}}\sectd \ltrsect\rtlgutter \psz1\linex0\endnhere\pgbrdropt32\sectdefaultcl\sectrsid6896082\sftnbj }}\sectd \ltrsect\rtlgutter\psz1\linex0\endnhere\pgbrdropt32\sectdefaultcl\sectrsid6896082\sftnbj {\rtlch\fcs1 \af31507\afs22 \ltrch\fcs0 \fs22\lang1024\langfe1024\loch\af31506\hich\af31506\dbch\af31505\noproof \par }{\field\fldedit{\*\fldinst {\rtlch\fcs1 \af0 \ltrch\fcs0 \cs187\ul\cf2\lang1024\langfe1024\noproof }{\rtlch\fcs1 \af44 \ltrch\fcs0 \lang1024\langfe1024\noproof HYPERLINK \\l "_Toc45096523"}{\rtlch\fcs1 \af0 \ltrch\fcs0 \cs187\ul\cf2\lang1024\langfe1024\noproof }{\rtlch\fcs1 \af0 \ltrch\fcs0 \cs187\ul\cf2\lang1024\langfe1024\noproof {\*\datafield 08d0c9ea79f9bace118c8200aa004ba90b02000000080000000d0000005f0054006f006300340035003000390036003500320033000000}}}{\fldrslt { \rtlch\fcs1 \af0 \ltrch\fcs0 \cs187\b\ul\cf2\lang1024\langfe1024\noproof A TWAIN C# Sample Application}{\rtlch\fcs1 \af44 \ltrch\fcs0 \lang1024\langfe1024\noproof\webhidden \tab }{\field{\*\fldinst {\rtlch\fcs1 \af44 \ltrch\fcs0 \lang1024\langfe1024\noproof\webhidden PAGEREF _Toc45096523 \\h }{\rtlch\fcs1 \af44 \ltrch\fcs0 \lang1024\langfe1024\noproof\webhidden {\*\datafield 08d0c9ea79f9bace118c8200aa004ba90b02000000080000000d0000005f0054006f006300340035003000390036003500320033000000}}}{\fldrslt {\rtlch\fcs1 \af44 \ltrch\fcs0 \lang1024\langfe1024\noproof\webhidden 8}}}\sectd \ltrsect\rtlgutter \psz1\linex0\endnhere\pgbrdropt32\sectdefaultcl\sectrsid6896082\sftnbj }}\sectd \ltrsect\rtlgutter\psz1\linex0\endnhere\pgbrdropt32\sectdefaultcl\sectrsid6896082\sftnbj {\rtlch\fcs1 \af31507\afs22 \ltrch\fcs0 \fs22\lang1024\langfe1024\loch\af31506\hich\af31506\dbch\af31505\noproof \par }{\field\fldedit{\*\fldinst {\rtlch\fcs1 \af0 \ltrch\fcs0 \cs187\ul\cf2\lang1024\langfe1024\noproof }{\rtlch\fcs1 \af44 \ltrch\fcs0 \lang1024\langfe1024\noproof HYPERLINK \\l "_Toc45096524"}{\rtlch\fcs1 \af0 \ltrch\fcs0 \cs187\ul\cf2\lang1024\langfe1024\noproof }{\rtlch\fcs1 \af0 \ltrch\fcs0 \cs187\ul\cf2\lang1024\langfe1024\noproof {\*\datafield 08d0c9ea79f9bace118c8200aa004ba90b02000000080000000d0000005f0054006f006300340035003000390036003500320034000000}}}{\fldrslt { \rtlch\fcs1 \af0 \ltrch\fcs0 \cs187\b\ul\cf2\lang1024\langfe1024\noproof A TWAIN C# Self Certification Application}{\rtlch\fcs1 \af44 \ltrch\fcs0 \lang1024\langfe1024\noproof\webhidden \tab }{\field{\*\fldinst {\rtlch\fcs1 \af44 \ltrch\fcs0 \lang1024\langfe1024\noproof\webhidden PAGEREF _Toc45096524 \\h }{\rtlch\fcs1 \af44 \ltrch\fcs0 \lang1024\langfe1024\noproof\webhidden {\*\datafield 08d0c9ea79f9bace118c8200aa004ba90b02000000080000000d0000005f0054006f006300340035003000390036003500320034000000}}}{\fldrslt {\rtlch\fcs1 \af44 \ltrch\fcs0 \lang1024\langfe1024\noproof\webhidden 8}}}\sectd \ltrsect\rtlgutter \psz1\linex0\endnhere\pgbrdropt32\sectdefaultcl\sectrsid6896082\sftnbj }}\sectd \ltrsect\rtlgutter\psz1\linex0\endnhere\pgbrdropt32\sectdefaultcl\sectrsid6896082\sftnbj {\rtlch\fcs1 \af31507\afs22 \ltrch\fcs0 \fs22\lang1024\langfe1024\loch\af31506\hich\af31506\dbch\af31505\noproof \par }\pard\plain \ltrpar\s98\ql \li1080\ri0\sb120\keepn\widctlpar\tqr\tldot\tx9893\wrapdefault\nooverflow\faroman\rin0\lin1080\itap0 \rtlch\fcs1 \ab\af1\afs20\alang1025 \ltrch\fcs0 \b\f1\fs20\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 {\field\fldedit{\*\fldinst {\rtlch\fcs1 \af0 \ltrch\fcs0 \cs187\ul\cf2\lang1024\langfe1024\noproof }{\rtlch\fcs1 \af1 \ltrch\fcs0 \lang1024\langfe1024\noproof HYPERLINK \\l "_Toc45096525"}{\rtlch\fcs1 \af0 \ltrch\fcs0 \cs187\ul\cf2\lang1024\langfe1024\noproof }{\rtlch\fcs1 \af0 \ltrch\fcs0 \cs187\ul\cf2\lang1024\langfe1024\noproof {\*\datafield 08d0c9ea79f9bace118c8200aa004ba90b02000000080000000d0000005f0054006f006300340035003000390036003500320035000000}}}{\fldrslt { \rtlch\fcs1 \af0 \ltrch\fcs0 \cs187\ul\cf2\lang1024\langfe1024\noproof Release Notes}{\rtlch\fcs1 \af1 \ltrch\fcs0 \lang1024\langfe1024\noproof\webhidden \tab }{\field{\*\fldinst {\rtlch\fcs1 \af1 \ltrch\fcs0 \lang1024\langfe1024\noproof\webhidden PAGEREF _Toc45096525 \\h }{\rtlch\fcs1 \af1 \ltrch\fcs0 \lang1024\langfe1024\noproof\webhidden {\*\datafield 08d0c9ea79f9bace118c8200aa004ba90b02000000080000000d0000005f0054006f006300340035003000390036003500320035000000}}}{\fldrslt {\rtlch\fcs1 \af1 \ltrch\fcs0 \lang1024\langfe1024\noproof\webhidden 10}}}\sectd \ltrsect\rtlgutter\psz1\linex0\endnhere\pgbrdropt32\sectdefaultcl\sectrsid6896082\sftnbj }}\sectd \ltrsect\rtlgutter\psz1\linex0\endnhere\pgbrdropt32\sectdefaultcl\sectrsid6896082\sftnbj { \rtlch\fcs1 \ab0\af31507\afs22 \ltrch\fcs0 \b0\fs22\lang1024\langfe1024\loch\af31506\hich\af31506\dbch\af31505\noproof \par }\pard\plain \ltrpar\s176\ql \li1440\ri0\sb180\widctlpar\tqr\tldot\tx9883\wrapdefault\nooverflow\faroman\rin0\lin1440\itap0 \rtlch\fcs1 \af44\afs20\alang1025 \ltrch\fcs0 \f44\fs20\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 {\field\fldedit{\*\fldinst {\rtlch\fcs1 \af0 \ltrch\fcs0 \cs187\ul\cf2\lang1024\langfe1024\noproof }{\rtlch\fcs1 \af44 \ltrch\fcs0 \lang1024\langfe1024\noproof HYPERLINK \\l "_Toc45096526"}{\rtlch\fcs1 \af0 \ltrch\fcs0 \cs187\ul\cf2\lang1024\langfe1024\noproof }{\rtlch\fcs1 \af0 \ltrch\fcs0 \cs187\ul\cf2\lang1024\langfe1024\noproof {\*\datafield 08d0c9ea79f9bace118c8200aa004ba90b02000000080000000d0000005f0054006f006300340035003000390036003500320036000000}}}{\fldrslt { \rtlch\fcs1 \af0 \ltrch\fcs0 \cs187\b\ul\cf2\lang1024\langfe1024\noproof V2.4.11.0 (08-Jul-2020)}{\rtlch\fcs1 \af44 \ltrch\fcs0 \lang1024\langfe1024\noproof\webhidden \tab }{\field{\*\fldinst {\rtlch\fcs1 \af44 \ltrch\fcs0 \lang1024\langfe1024\noproof\webhidden PAGEREF _Toc45096526 \\h }{\rtlch\fcs1 \af44 \ltrch\fcs0 \lang1024\langfe1024\noproof\webhidden {\*\datafield 08d0c9ea79f9bace118c8200aa004ba90b02000000080000000d0000005f0054006f006300340035003000390036003500320036000000}}}{\fldrslt {\rtlch\fcs1 \af44 \ltrch\fcs0 \lang1024\langfe1024\noproof\webhidden 10}}}\sectd \ltrsect\rtlgutter \psz1\linex0\endnhere\pgbrdropt32\sectdefaultcl\sectrsid6896082\sftnbj }}\sectd \ltrsect\rtlgutter\psz1\linex0\endnhere\pgbrdropt32\sectdefaultcl\sectrsid6896082\sftnbj {\rtlch\fcs1 \af31507\afs22 \ltrch\fcs0 \fs22\lang1024\langfe1024\loch\af31506\hich\af31506\dbch\af31505\noproof \par }{\field\fldedit{\*\fldinst {\rtlch\fcs1 \af0 \ltrch\fcs0 \cs187\ul\cf2\lang1024\langfe1024\noproof }{\rtlch\fcs1 \af44 \ltrch\fcs0 \lang1024\langfe1024\noproof HYPERLINK \\l "_Toc45096527"}{\rtlch\fcs1 \af0 \ltrch\fcs0 \cs187\ul\cf2\lang1024\langfe1024\noproof }{\rtlch\fcs1 \af0 \ltrch\fcs0 \cs187\ul\cf2\lang1024\langfe1024\noproof {\*\datafield 08d0c9ea79f9bace118c8200aa004ba90b02000000080000000d0000005f0054006f006300340035003000390036003500320037000000}}}{\fldrslt { \rtlch\fcs1 \af0 \ltrch\fcs0 \cs187\b\ul\cf2\lang1024\langfe1024\noproof V2.4.10.0 (06-Jun-2020)}{\rtlch\fcs1 \af44 \ltrch\fcs0 \lang1024\langfe1024\noproof\webhidden \tab }{\field{\*\fldinst {\rtlch\fcs1 \af44 \ltrch\fcs0 \lang1024\langfe1024\noproof\webhidden PAGEREF _Toc45096527 \\h }{\rtlch\fcs1 \af44 \ltrch\fcs0 \lang1024\langfe1024\noproof\webhidden {\*\datafield 08d0c9ea79f9bace118c8200aa004ba90b02000000080000000d0000005f0054006f006300340035003000390036003500320037000000}}}{\fldrslt {\rtlch\fcs1 \af44 \ltrch\fcs0 \lang1024\langfe1024\noproof\webhidden 10}}}\sectd \ltrsect\rtlgutter \psz1\linex0\endnhere\pgbrdropt32\sectdefaultcl\sectrsid6896082\sftnbj }}\sectd \ltrsect\rtlgutter\psz1\linex0\endnhere\pgbrdropt32\sectdefaultcl\sectrsid6896082\sftnbj {\rtlch\fcs1 \af31507\afs22 \ltrch\fcs0 \fs22\lang1024\langfe1024\loch\af31506\hich\af31506\dbch\af31505\noproof \par }{\field\fldedit{\*\fldinst {\rtlch\fcs1 \af0 \ltrch\fcs0 \cs187\ul\cf2\lang1024\langfe1024\noproof }{\rtlch\fcs1 \af44 \ltrch\fcs0 \lang1024\langfe1024\noproof HYPERLINK \\l "_Toc45096528"}{\rtlch\fcs1 \af0 \ltrch\fcs0 \cs187\ul\cf2\lang1024\langfe1024\noproof }{\rtlch\fcs1 \af0 \ltrch\fcs0 \cs187\ul\cf2\lang1024\langfe1024\noproof {\*\datafield 08d0c9ea79f9bace118c8200aa004ba90b02000000080000000d0000005f0054006f006300340035003000390036003500320038000000}}}{\fldrslt { \rtlch\fcs1 \af0 \ltrch\fcs0 \cs187\b\ul\cf2\lang1024\langfe1024\noproof V2.4.9.0 (30-Apr-2020)}{\rtlch\fcs1 \af44 \ltrch\fcs0 \lang1024\langfe1024\noproof\webhidden \tab }{\field{\*\fldinst {\rtlch\fcs1 \af44 \ltrch\fcs0 \lang1024\langfe1024\noproof\webhidden PAGEREF _Toc45096528 \\h }{\rtlch\fcs1 \af44 \ltrch\fcs0 \lang1024\langfe1024\noproof\webhidden {\*\datafield 08d0c9ea79f9bace118c8200aa004ba90b02000000080000000d0000005f0054006f006300340035003000390036003500320038000000}}}{\fldrslt {\rtlch\fcs1 \af44 \ltrch\fcs0 \lang1024\langfe1024\noproof\webhidden 10}}}\sectd \ltrsect\rtlgutter \psz1\linex0\endnhere\pgbrdropt32\sectdefaultcl\sectrsid6896082\sftnbj }}\sectd \ltrsect\rtlgutter\psz1\linex0\endnhere\pgbrdropt32\sectdefaultcl\sectrsid6896082\sftnbj {\rtlch\fcs1 \af31507\afs22 \ltrch\fcs0 \fs22\lang1024\langfe1024\loch\af31506\hich\af31506\dbch\af31505\noproof \par }{\field\fldedit{\*\fldinst {\rtlch\fcs1 \af0 \ltrch\fcs0 \cs187\ul\cf2\lang1024\langfe1024\noproof }{\rtlch\fcs1 \af44 \ltrch\fcs0 \lang1024\langfe1024\noproof HYPERLINK \\l "_Toc45096529"}{\rtlch\fcs1 \af0 \ltrch\fcs0 \cs187\ul\cf2\lang1024\langfe1024\noproof }{\rtlch\fcs1 \af0 \ltrch\fcs0 \cs187\ul\cf2\lang1024\langfe1024\noproof {\*\datafield 08d0c9ea79f9bace118c8200aa004ba90b02000000080000000d0000005f0054006f006300340035003000390036003500320039000000}}}{\fldrslt { \rtlch\fcs1 \af0 \ltrch\fcs0 \cs187\b\ul\cf2\lang1024\langfe1024\noproof V2.4.8.0 (30-Mar-2020)}{\rtlch\fcs1 \af44 \ltrch\fcs0 \lang1024\langfe1024\noproof\webhidden \tab }{\field{\*\fldinst {\rtlch\fcs1 \af44 \ltrch\fcs0 \lang1024\langfe1024\noproof\webhidden PAGEREF _Toc45096529 \\h }{\rtlch\fcs1 \af44 \ltrch\fcs0 \lang1024\langfe1024\noproof\webhidden {\*\datafield 08d0c9ea79f9bace118c8200aa004ba90b02000000080000000d0000005f0054006f006300340035003000390036003500320039000000}}}{\fldrslt {\rtlch\fcs1 \af44 \ltrch\fcs0 \lang1024\langfe1024\noproof\webhidden 10}}}\sectd \ltrsect\rtlgutter \psz1\linex0\endnhere\pgbrdropt32\sectdefaultcl\sectrsid6896082\sftnbj }}\sectd \ltrsect\rtlgutter\psz1\linex0\endnhere\pgbrdropt32\sectdefaultcl\sectrsid6896082\sftnbj {\rtlch\fcs1 \af31507\afs22 \ltrch\fcs0 \fs22\lang1024\langfe1024\loch\af31506\hich\af31506\dbch\af31505\noproof \par }{\field\fldedit{\*\fldinst {\rtlch\fcs1 \af0 \ltrch\fcs0 \cs187\ul\cf2\lang1024\langfe1024\noproof }{\rtlch\fcs1 \af44 \ltrch\fcs0 \lang1024\langfe1024\noproof HYPERLINK \\l "_Toc45096530"}{\rtlch\fcs1 \af0 \ltrch\fcs0 \cs187\ul\cf2\lang1024\langfe1024\noproof }{\rtlch\fcs1 \af0 \ltrch\fcs0 \cs187\ul\cf2\lang1024\langfe1024\noproof {\*\datafield 08d0c9ea79f9bace118c8200aa004ba90b02000000080000000d0000005f0054006f006300340035003000390036003500330030000000}}}{\fldrslt { \rtlch\fcs1 \af0 \ltrch\fcs0 \cs187\b\ul\cf2\lang1024\langfe1024\noproof V2.4.6.0 (26-Mar-2020)}{\rtlch\fcs1 \af44 \ltrch\fcs0 \lang1024\langfe1024\noproof\webhidden \tab }{\field{\*\fldinst {\rtlch\fcs1 \af44 \ltrch\fcs0 \lang1024\langfe1024\noproof\webhidden PAGEREF _Toc45096530 \\h }{\rtlch\fcs1 \af44 \ltrch\fcs0 \lang1024\langfe1024\noproof\webhidden {\*\datafield 08d0c9ea79f9bace118c8200aa004ba90b02000000080000000d0000005f0054006f006300340035003000390036003500330030000000}}}{\fldrslt {\rtlch\fcs1 \af44 \ltrch\fcs0 \lang1024\langfe1024\noproof\webhidden 11}}}\sectd \ltrsect\rtlgutter \psz1\linex0\endnhere\pgbrdropt32\sectdefaultcl\sectrsid6896082\sftnbj }}\sectd \ltrsect\rtlgutter\psz1\linex0\endnhere\pgbrdropt32\sectdefaultcl\sectrsid6896082\sftnbj {\rtlch\fcs1 \af31507\afs22 \ltrch\fcs0 \fs22\lang1024\langfe1024\loch\af31506\hich\af31506\dbch\af31505\noproof \par }{\field\fldedit{\*\fldinst {\rtlch\fcs1 \af0 \ltrch\fcs0 \cs187\ul\cf2\lang1024\langfe1024\noproof }{\rtlch\fcs1 \af44 \ltrch\fcs0 \lang1024\langfe1024\noproof HYPERLINK \\l "_Toc45096531"}{\rtlch\fcs1 \af0 \ltrch\fcs0 \cs187\ul\cf2\lang1024\langfe1024\noproof }{\rtlch\fcs1 \af0 \ltrch\fcs0 \cs187\ul\cf2\lang1024\langfe1024\noproof {\*\datafield 08d0c9ea79f9bace118c8200aa004ba90b02000000080000000d0000005f0054006f006300340035003000390036003500330031000000}}}{\fldrslt { \rtlch\fcs1 \af0 \ltrch\fcs0 \cs187\b\ul\cf2\lang1024\langfe1024\noproof V2.4.5.0 (24-Mar-2020)}{\rtlch\fcs1 \af44 \ltrch\fcs0 \lang1024\langfe1024\noproof\webhidden \tab }{\field{\*\fldinst {\rtlch\fcs1 \af44 \ltrch\fcs0 \lang1024\langfe1024\noproof\webhidden PAGEREF _Toc45096531 \\h }{\rtlch\fcs1 \af44 \ltrch\fcs0 \lang1024\langfe1024\noproof\webhidden {\*\datafield 08d0c9ea79f9bace118c8200aa004ba90b02000000080000000d0000005f0054006f006300340035003000390036003500330031000000}}}{\fldrslt {\rtlch\fcs1 \af44 \ltrch\fcs0 \lang1024\langfe1024\noproof\webhidden 11}}}\sectd \ltrsect\rtlgutter \psz1\linex0\endnhere\pgbrdropt32\sectdefaultcl\sectrsid6896082\sftnbj }}\sectd \ltrsect\rtlgutter\psz1\linex0\endnhere\pgbrdropt32\sectdefaultcl\sectrsid6896082\sftnbj {\rtlch\fcs1 \af31507\afs22 \ltrch\fcs0 \fs22\lang1024\langfe1024\loch\af31506\hich\af31506\dbch\af31505\noproof \par }{\field\fldedit{\*\fldinst {\rtlch\fcs1 \af0 \ltrch\fcs0 \cs187\ul\cf2\lang1024\langfe1024\noproof }{\rtlch\fcs1 \af44 \ltrch\fcs0 \lang1024\langfe1024\noproof HYPERLINK \\l "_Toc45096532"}{\rtlch\fcs1 \af0 \ltrch\fcs0 \cs187\ul\cf2\lang1024\langfe1024\noproof }{\rtlch\fcs1 \af0 \ltrch\fcs0 \cs187\ul\cf2\lang1024\langfe1024\noproof {\*\datafield 08d0c9ea79f9bace118c8200aa004ba90b02000000080000000d0000005f0054006f006300340035003000390036003500330032000000}}}{\fldrslt { \rtlch\fcs1 \af0 \ltrch\fcs0 \cs187\b\ul\cf2\lang1024\langfe1024\noproof V2.4.4.0 (24-Mar-2020)}{\rtlch\fcs1 \af44 \ltrch\fcs0 \lang1024\langfe1024\noproof\webhidden \tab }{\field{\*\fldinst {\rtlch\fcs1 \af44 \ltrch\fcs0 \lang1024\langfe1024\noproof\webhidden PAGEREF _Toc45096532 \\h }{\rtlch\fcs1 \af44 \ltrch\fcs0 \lang1024\langfe1024\noproof\webhidden {\*\datafield 08d0c9ea79f9bace118c8200aa004ba90b02000000080000000d0000005f0054006f006300340035003000390036003500330032000000}}}{\fldrslt {\rtlch\fcs1 \af44 \ltrch\fcs0 \lang1024\langfe1024\noproof\webhidden 11}}}\sectd \ltrsect\rtlgutter \psz1\linex0\endnhere\pgbrdropt32\sectdefaultcl\sectrsid6896082\sftnbj }}\sectd \ltrsect\rtlgutter\psz1\linex0\endnhere\pgbrdropt32\sectdefaultcl\sectrsid6896082\sftnbj {\rtlch\fcs1 \af31507\afs22 \ltrch\fcs0 \fs22\lang1024\langfe1024\loch\af31506\hich\af31506\dbch\af31505\noproof \par }{\field\fldedit{\*\fldinst {\rtlch\fcs1 \af0 \ltrch\fcs0 \cs187\ul\cf2\lang1024\langfe1024\noproof }{\rtlch\fcs1 \af44 \ltrch\fcs0 \lang1024\langfe1024\noproof HYPERLINK \\l "_Toc45096533"}{\rtlch\fcs1 \af0 \ltrch\fcs0 \cs187\ul\cf2\lang1024\langfe1024\noproof }{\rtlch\fcs1 \af0 \ltrch\fcs0 \cs187\ul\cf2\lang1024\langfe1024\noproof {\*\datafield 08d0c9ea79f9bace118c8200aa004ba90b02000000080000000d0000005f0054006f006300340035003000390036003500330033000000}}}{\fldrslt { \rtlch\fcs1 \af0 \ltrch\fcs0 \cs187\b\ul\cf2\lang1024\langfe1024\noproof V2.4.3.0 (20-Mar-2020)}{\rtlch\fcs1 \af44 \ltrch\fcs0 \lang1024\langfe1024\noproof\webhidden \tab }{\field{\*\fldinst {\rtlch\fcs1 \af44 \ltrch\fcs0 \lang1024\langfe1024\noproof\webhidden PAGEREF _Toc45096533 \\h }{\rtlch\fcs1 \af44 \ltrch\fcs0 \lang1024\langfe1024\noproof\webhidden {\*\datafield 08d0c9ea79f9bace118c8200aa004ba90b02000000080000000d0000005f0054006f006300340035003000390036003500330033000000}}}{\fldrslt {\rtlch\fcs1 \af44 \ltrch\fcs0 \lang1024\langfe1024\noproof\webhidden 11}}}\sectd \ltrsect\rtlgutter \psz1\linex0\endnhere\pgbrdropt32\sectdefaultcl\sectrsid6896082\sftnbj }}\sectd \ltrsect\rtlgutter\psz1\linex0\endnhere\pgbrdropt32\sectdefaultcl\sectrsid6896082\sftnbj {\rtlch\fcs1 \af31507\afs22 \ltrch\fcs0 \fs22\lang1024\langfe1024\loch\af31506\hich\af31506\dbch\af31505\noproof \par }{\field\fldedit{\*\fldinst {\rtlch\fcs1 \af0 \ltrch\fcs0 \cs187\ul\cf2\lang1024\langfe1024\noproof }{\rtlch\fcs1 \af44 \ltrch\fcs0 \lang1024\langfe1024\noproof HYPERLINK \\l "_Toc45096534"}{\rtlch\fcs1 \af0 \ltrch\fcs0 \cs187\ul\cf2\lang1024\langfe1024\noproof }{\rtlch\fcs1 \af0 \ltrch\fcs0 \cs187\ul\cf2\lang1024\langfe1024\noproof {\*\datafield 08d0c9ea79f9bace118c8200aa004ba90b02000000080000000d0000005f0054006f006300340035003000390036003500330034000000}}}{\fldrslt { \rtlch\fcs1 \af0 \ltrch\fcs0 \cs187\b\ul\cf2\lang1024\langfe1024\noproof V2.4.2.0 (13-Mar-2020)}{\rtlch\fcs1 \af44 \ltrch\fcs0 \lang1024\langfe1024\noproof\webhidden \tab }{\field{\*\fldinst {\rtlch\fcs1 \af44 \ltrch\fcs0 \lang1024\langfe1024\noproof\webhidden PAGEREF _Toc45096534 \\h }{\rtlch\fcs1 \af44 \ltrch\fcs0 \lang1024\langfe1024\noproof\webhidden {\*\datafield 08d0c9ea79f9bace118c8200aa004ba90b02000000080000000d0000005f0054006f006300340035003000390036003500330034000000}}}{\fldrslt {\rtlch\fcs1 \af44 \ltrch\fcs0 \lang1024\langfe1024\noproof\webhidden 12}}}\sectd \ltrsect\rtlgutter \psz1\linex0\endnhere\pgbrdropt32\sectdefaultcl\sectrsid6896082\sftnbj }}\sectd \ltrsect\rtlgutter\psz1\linex0\endnhere\pgbrdropt32\sectdefaultcl\sectrsid6896082\sftnbj {\rtlch\fcs1 \af31507\afs22 \ltrch\fcs0 \fs22\lang1024\langfe1024\loch\af31506\hich\af31506\dbch\af31505\noproof \par }{\field\fldedit{\*\fldinst {\rtlch\fcs1 \af0 \ltrch\fcs0 \cs187\ul\cf2\lang1024\langfe1024\noproof }{\rtlch\fcs1 \af44 \ltrch\fcs0 \lang1024\langfe1024\noproof HYPERLINK \\l "_Toc45096535"}{\rtlch\fcs1 \af0 \ltrch\fcs0 \cs187\ul\cf2\lang1024\langfe1024\noproof }{\rtlch\fcs1 \af0 \ltrch\fcs0 \cs187\ul\cf2\lang1024\langfe1024\noproof {\*\datafield 08d0c9ea79f9bace118c8200aa004ba90b02000000080000000d0000005f0054006f006300340035003000390036003500330035000000}}}{\fldrslt { \rtlch\fcs1 \af0 \ltrch\fcs0 \cs187\b\ul\cf2\lang1024\langfe1024\noproof V2.4.1.0 (30-Jan-2020)}{\rtlch\fcs1 \af44 \ltrch\fcs0 \lang1024\langfe1024\noproof\webhidden \tab }{\field{\*\fldinst {\rtlch\fcs1 \af44 \ltrch\fcs0 \lang1024\langfe1024\noproof\webhidden PAGEREF _Toc45096535 \\h }{\rtlch\fcs1 \af44 \ltrch\fcs0 \lang1024\langfe1024\noproof\webhidden {\*\datafield 08d0c9ea79f9bace118c8200aa004ba90b02000000080000000d0000005f0054006f006300340035003000390036003500330035000000}}}{\fldrslt {\rtlch\fcs1 \af44 \ltrch\fcs0 \lang1024\langfe1024\noproof\webhidden 12}}}\sectd \ltrsect\rtlgutter \psz1\linex0\endnhere\pgbrdropt32\sectdefaultcl\sectrsid6896082\sftnbj }}\sectd \ltrsect\rtlgutter\psz1\linex0\endnhere\pgbrdropt32\sectdefaultcl\sectrsid6896082\sftnbj {\rtlch\fcs1 \af31507\afs22 \ltrch\fcs0 \fs22\lang1024\langfe1024\loch\af31506\hich\af31506\dbch\af31505\noproof \par }{\field\fldedit{\*\fldinst {\rtlch\fcs1 \af0 \ltrch\fcs0 \cs187\ul\cf2\lang1024\langfe1024\noproof }{\rtlch\fcs1 \af44 \ltrch\fcs0 \lang1024\langfe1024\noproof HYPERLINK \\l "_Toc45096536"}{\rtlch\fcs1 \af0 \ltrch\fcs0 \cs187\ul\cf2\lang1024\langfe1024\noproof }{\rtlch\fcs1 \af0 \ltrch\fcs0 \cs187\ul\cf2\lang1024\langfe1024\noproof {\*\datafield 08d0c9ea79f9bace118c8200aa004ba90b02000000080000000d0000005f0054006f006300340035003000390036003500330036000000}}}{\fldrslt { \rtlch\fcs1 \af0 \ltrch\fcs0 \cs187\b\ul\cf2\lang1024\langfe1024\noproof V2.4.0.3 (13-Mar-2019)}{\rtlch\fcs1 \af44 \ltrch\fcs0 \lang1024\langfe1024\noproof\webhidden \tab }{\field{\*\fldinst {\rtlch\fcs1 \af44 \ltrch\fcs0 \lang1024\langfe1024\noproof\webhidden PAGEREF _Toc45096536 \\h }{\rtlch\fcs1 \af44 \ltrch\fcs0 \lang1024\langfe1024\noproof\webhidden {\*\datafield 08d0c9ea79f9bace118c8200aa004ba90b02000000080000000d0000005f0054006f006300340035003000390036003500330036000000}}}{\fldrslt {\rtlch\fcs1 \af44 \ltrch\fcs0 \lang1024\langfe1024\noproof\webhidden 12}}}\sectd \ltrsect\rtlgutter \psz1\linex0\endnhere\pgbrdropt32\sectdefaultcl\sectrsid6896082\sftnbj }}\sectd \ltrsect\rtlgutter\psz1\linex0\endnhere\pgbrdropt32\sectdefaultcl\sectrsid6896082\sftnbj {\rtlch\fcs1 \af31507\afs22 \ltrch\fcs0 \fs22\lang1024\langfe1024\loch\af31506\hich\af31506\dbch\af31505\noproof \par }{\field\fldedit{\*\fldinst {\rtlch\fcs1 \af0 \ltrch\fcs0 \cs187\ul\cf2\lang1024\langfe1024\noproof }{\rtlch\fcs1 \af44 \ltrch\fcs0 \lang1024\langfe1024\noproof HYPERLINK \\l "_Toc45096537"}{\rtlch\fcs1 \af0 \ltrch\fcs0 \cs187\ul\cf2\lang1024\langfe1024\noproof }{\rtlch\fcs1 \af0 \ltrch\fcs0 \cs187\ul\cf2\lang1024\langfe1024\noproof {\*\datafield 08d0c9ea79f9bace118c8200aa004ba90b02000000080000000d0000005f0054006f006300340035003000390036003500330037000000}}}{\fldrslt { \rtlch\fcs1 \af0 \ltrch\fcs0 \cs187\b\ul\cf2\lang1024\langfe1024\noproof V2.4.0.2 (25-Jan-2019)}{\rtlch\fcs1 \af44 \ltrch\fcs0 \lang1024\langfe1024\noproof\webhidden \tab }{\field{\*\fldinst {\rtlch\fcs1 \af44 \ltrch\fcs0 \lang1024\langfe1024\noproof\webhidden PAGEREF _Toc45096537 \\h }{\rtlch\fcs1 \af44 \ltrch\fcs0 \lang1024\langfe1024\noproof\webhidden {\*\datafield 08d0c9ea79f9bace118c8200aa004ba90b02000000080000000d0000005f0054006f006300340035003000390036003500330037000000}}}{\fldrslt {\rtlch\fcs1 \af44 \ltrch\fcs0 \lang1024\langfe1024\noproof\webhidden 12}}}\sectd \ltrsect\rtlgutter \psz1\linex0\endnhere\pgbrdropt32\sectdefaultcl\sectrsid6896082\sftnbj }}\sectd \ltrsect\rtlgutter\psz1\linex0\endnhere\pgbrdropt32\sectdefaultcl\sectrsid6896082\sftnbj {\rtlch\fcs1 \af31507\afs22 \ltrch\fcs0 \fs22\lang1024\langfe1024\loch\af31506\hich\af31506\dbch\af31505\noproof \par }{\field\fldedit{\*\fldinst {\rtlch\fcs1 \af0 \ltrch\fcs0 \cs187\ul\cf2\lang1024\langfe1024\noproof }{\rtlch\fcs1 \af44 \ltrch\fcs0 \lang1024\langfe1024\noproof HYPERLINK \\l "_Toc45096538"}{\rtlch\fcs1 \af0 \ltrch\fcs0 \cs187\ul\cf2\lang1024\langfe1024\noproof }{\rtlch\fcs1 \af0 \ltrch\fcs0 \cs187\ul\cf2\lang1024\langfe1024\noproof {\*\datafield 08d0c9ea79f9bace118c8200aa004ba90b02000000080000000d0000005f0054006f006300340035003000390036003500330038000000}}}{\fldrslt { \rtlch\fcs1 \af0 \ltrch\fcs0 \cs187\b\ul\cf2\lang1024\langfe1024\noproof V2.4.0.1 (19-Apr-2018)}{\rtlch\fcs1 \af44 \ltrch\fcs0 \lang1024\langfe1024\noproof\webhidden \tab }{\field{\*\fldinst {\rtlch\fcs1 \af44 \ltrch\fcs0 \lang1024\langfe1024\noproof\webhidden PAGEREF _Toc45096538 \\h }{\rtlch\fcs1 \af44 \ltrch\fcs0 \lang1024\langfe1024\noproof\webhidden {\*\datafield 08d0c9ea79f9bace118c8200aa004ba90b02000000080000000d0000005f0054006f006300340035003000390036003500330038000000}}}{\fldrslt {\rtlch\fcs1 \af44 \ltrch\fcs0 \lang1024\langfe1024\noproof\webhidden 13}}}\sectd \ltrsect\rtlgutter \psz1\linex0\endnhere\pgbrdropt32\sectdefaultcl\sectrsid6896082\sftnbj }}\sectd \ltrsect\rtlgutter\psz1\linex0\endnhere\pgbrdropt32\sectdefaultcl\sectrsid6896082\sftnbj {\rtlch\fcs1 \af31507\afs22 \ltrch\fcs0 \fs22\lang1024\langfe1024\loch\af31506\hich\af31506\dbch\af31505\noproof \par }{\field\fldedit{\*\fldinst {\rtlch\fcs1 \af0 \ltrch\fcs0 \cs187\ul\cf2\lang1024\langfe1024\noproof }{\rtlch\fcs1 \af44 \ltrch\fcs0 \lang1024\langfe1024\noproof HYPERLINK \\l "_Toc45096539"}{\rtlch\fcs1 \af0 \ltrch\fcs0 \cs187\ul\cf2\lang1024\langfe1024\noproof }{\rtlch\fcs1 \af0 \ltrch\fcs0 \cs187\ul\cf2\lang1024\langfe1024\noproof {\*\datafield 08d0c9ea79f9bace118c8200aa004ba90b02000000080000000d0000005f0054006f006300340035003000390036003500330039000000}}}{\fldrslt { \rtlch\fcs1 \af0 \ltrch\fcs0 \cs187\b\ul\cf2\lang1024\langfe1024\noproof V2.4.0.0 (darned if I know, 2017)}{\rtlch\fcs1 \af44 \ltrch\fcs0 \lang1024\langfe1024\noproof\webhidden \tab }{\field{\*\fldinst {\rtlch\fcs1 \af44 \ltrch\fcs0 \lang1024\langfe1024\noproof\webhidden PAGEREF _Toc45096539 \\h }{\rtlch\fcs1 \af44 \ltrch\fcs0 \lang1024\langfe1024\noproof\webhidden {\*\datafield 08d0c9ea79f9bace118c8200aa004ba90b02000000080000000d0000005f0054006f006300340035003000390036003500330039000000}}}{\fldrslt {\rtlch\fcs1 \af44 \ltrch\fcs0 \lang1024\langfe1024\noproof\webhidden 13}}}\sectd \ltrsect\rtlgutter \psz1\linex0\endnhere\pgbrdropt32\sectdefaultcl\sectrsid6896082\sftnbj }}\sectd \ltrsect\rtlgutter\psz1\linex0\endnhere\pgbrdropt32\sectdefaultcl\sectrsid6896082\sftnbj {\rtlch\fcs1 \af31507\afs22 \ltrch\fcs0 \fs22\lang1024\langfe1024\loch\af31506\hich\af31506\dbch\af31505\noproof \par }{\field\fldedit{\*\fldinst {\rtlch\fcs1 \af0 \ltrch\fcs0 \cs187\ul\cf2\lang1024\langfe1024\noproof }{\rtlch\fcs1 \af44 \ltrch\fcs0 \lang1024\langfe1024\noproof HYPERLINK \\l "_Toc45096540"}{\rtlch\fcs1 \af0 \ltrch\fcs0 \cs187\ul\cf2\lang1024\langfe1024\noproof }{\rtlch\fcs1 \af0 \ltrch\fcs0 \cs187\ul\cf2\lang1024\langfe1024\noproof {\*\datafield 08d0c9ea79f9bace118c8200aa004ba90b02000000080000000d0000005f0054006f006300340035003000390036003500340030000000}}}{\fldrslt { \rtlch\fcs1 \af0 \ltrch\fcs0 \cs187\b\ul\cf2\lang1024\langfe1024\noproof V2.3.2.0 (18-Oct-2015)}{\rtlch\fcs1 \af44 \ltrch\fcs0 \lang1024\langfe1024\noproof\webhidden \tab }{\field{\*\fldinst {\rtlch\fcs1 \af44 \ltrch\fcs0 \lang1024\langfe1024\noproof\webhidden PAGEREF _Toc45096540 \\h }{\rtlch\fcs1 \af44 \ltrch\fcs0 \lang1024\langfe1024\noproof\webhidden {\*\datafield 08d0c9ea79f9bace118c8200aa004ba90b02000000080000000d0000005f0054006f006300340035003000390036003500340030000000}}}{\fldrslt {\rtlch\fcs1 \af44 \ltrch\fcs0 \lang1024\langfe1024\noproof\webhidden 13}}}\sectd \ltrsect\rtlgutter \psz1\linex0\endnhere\pgbrdropt32\sectdefaultcl\sectrsid6896082\sftnbj }}\sectd \ltrsect\rtlgutter\psz1\linex0\endnhere\pgbrdropt32\sectdefaultcl\sectrsid6896082\sftnbj {\rtlch\fcs1 \af31507\afs22 \ltrch\fcs0 \fs22\lang1024\langfe1024\loch\af31506\hich\af31506\dbch\af31505\noproof \par }{\field\fldedit{\*\fldinst {\rtlch\fcs1 \af0 \ltrch\fcs0 \cs187\ul\cf2\lang1024\langfe1024\noproof }{\rtlch\fcs1 \af44 \ltrch\fcs0 \lang1024\langfe1024\noproof HYPERLINK \\l "_Toc45096541"}{\rtlch\fcs1 \af0 \ltrch\fcs0 \cs187\ul\cf2\lang1024\langfe1024\noproof }{\rtlch\fcs1 \af0 \ltrch\fcs0 \cs187\ul\cf2\lang1024\langfe1024\noproof {\*\datafield 08d0c9ea79f9bace118c8200aa004ba90b02000000080000000d0000005f0054006f006300340035003000390036003500340031000000}}}{\fldrslt { \rtlch\fcs1 \af0 \ltrch\fcs0 \cs187\b\ul\cf2\lang1024\langfe1024\noproof V2.3.1.2 (13-Sep-2015)}{\rtlch\fcs1 \af44 \ltrch\fcs0 \lang1024\langfe1024\noproof\webhidden \tab }{\field{\*\fldinst {\rtlch\fcs1 \af44 \ltrch\fcs0 \lang1024\langfe1024\noproof\webhidden PAGEREF _Toc45096541 \\h }{\rtlch\fcs1 \af44 \ltrch\fcs0 \lang1024\langfe1024\noproof\webhidden {\*\datafield 08d0c9ea79f9bace118c8200aa004ba90b02000000080000000d0000005f0054006f006300340035003000390036003500340031000000}}}{\fldrslt {\rtlch\fcs1 \af44 \ltrch\fcs0 \lang1024\langfe1024\noproof\webhidden 14}}}\sectd \ltrsect\rtlgutter \psz1\linex0\endnhere\pgbrdropt32\sectdefaultcl\sectrsid6896082\sftnbj }}\sectd \ltrsect\rtlgutter\psz1\linex0\endnhere\pgbrdropt32\sectdefaultcl\sectrsid6896082\sftnbj {\rtlch\fcs1 \af31507\afs22 \ltrch\fcs0 \fs22\lang1024\langfe1024\loch\af31506\hich\af31506\dbch\af31505\noproof \par }{\field\fldedit{\*\fldinst {\rtlch\fcs1 \af0 \ltrch\fcs0 \cs187\ul\cf2\lang1024\langfe1024\noproof }{\rtlch\fcs1 \af44 \ltrch\fcs0 \lang1024\langfe1024\noproof HYPERLINK \\l "_Toc45096542"}{\rtlch\fcs1 \af0 \ltrch\fcs0 \cs187\ul\cf2\lang1024\langfe1024\noproof }{\rtlch\fcs1 \af0 \ltrch\fcs0 \cs187\ul\cf2\lang1024\langfe1024\noproof {\*\datafield 08d0c9ea79f9bace118c8200aa004ba90b02000000080000000d0000005f0054006f006300340035003000390036003500340032000000}}}{\fldrslt { \rtlch\fcs1 \af0 \ltrch\fcs0 \cs187\b\ul\cf2\lang1024\langfe1024\noproof V2.3.1.1 (27-Aug-2015)}{\rtlch\fcs1 \af44 \ltrch\fcs0 \lang1024\langfe1024\noproof\webhidden \tab }{\field{\*\fldinst {\rtlch\fcs1 \af44 \ltrch\fcs0 \lang1024\langfe1024\noproof\webhidden PAGEREF _Toc45096542 \\h }{\rtlch\fcs1 \af44 \ltrch\fcs0 \lang1024\langfe1024\noproof\webhidden {\*\datafield 08d0c9ea79f9bace118c8200aa004ba90b02000000080000000d0000005f0054006f006300340035003000390036003500340032000000}}}{\fldrslt {\rtlch\fcs1 \af44 \ltrch\fcs0 \lang1024\langfe1024\noproof\webhidden 14}}}\sectd \ltrsect\rtlgutter \psz1\linex0\endnhere\pgbrdropt32\sectdefaultcl\sectrsid6896082\sftnbj }}\sectd \ltrsect\rtlgutter\psz1\linex0\endnhere\pgbrdropt32\sectdefaultcl\sectrsid6896082\sftnbj {\rtlch\fcs1 \af31507\afs22 \ltrch\fcs0 \fs22\lang1024\langfe1024\loch\af31506\hich\af31506\dbch\af31505\noproof \par }{\field\fldedit{\*\fldinst {\rtlch\fcs1 \af0 \ltrch\fcs0 \cs187\ul\cf2\lang1024\langfe1024\noproof }{\rtlch\fcs1 \af44 \ltrch\fcs0 \lang1024\langfe1024\noproof HYPERLINK \\l "_Toc45096543"}{\rtlch\fcs1 \af0 \ltrch\fcs0 \cs187\ul\cf2\lang1024\langfe1024\noproof }{\rtlch\fcs1 \af0 \ltrch\fcs0 \cs187\ul\cf2\lang1024\langfe1024\noproof {\*\datafield 08d0c9ea79f9bace118c8200aa004ba90b02000000080000000d0000005f0054006f006300340035003000390036003500340033000000}}}{\fldrslt { \rtlch\fcs1 \af0 \ltrch\fcs0 \cs187\b\ul\cf2\lang1024\langfe1024\noproof V2.3.1.0 (13-Mar-2015)}{\rtlch\fcs1 \af44 \ltrch\fcs0 \lang1024\langfe1024\noproof\webhidden \tab }{\field{\*\fldinst {\rtlch\fcs1 \af44 \ltrch\fcs0 \lang1024\langfe1024\noproof\webhidden PAGEREF _Toc45096543 \\h }{\rtlch\fcs1 \af44 \ltrch\fcs0 \lang1024\langfe1024\noproof\webhidden {\*\datafield 08d0c9ea79f9bace118c8200aa004ba90b02000000080000000d0000005f0054006f006300340035003000390036003500340033000000}}}{\fldrslt {\rtlch\fcs1 \af44 \ltrch\fcs0 \lang1024\langfe1024\noproof\webhidden 14}}}\sectd \ltrsect\rtlgutter \psz1\linex0\endnhere\pgbrdropt32\sectdefaultcl\sectrsid6896082\sftnbj }}\sectd \ltrsect\rtlgutter\psz1\linex0\endnhere\pgbrdropt32\sectdefaultcl\sectrsid6896082\sftnbj {\rtlch\fcs1 \af31507\afs22 \ltrch\fcs0 \fs22\lang1024\langfe1024\loch\af31506\hich\af31506\dbch\af31505\noproof \par }{\field\fldedit{\*\fldinst {\rtlch\fcs1 \af0 \ltrch\fcs0 \cs187\ul\cf2\lang1024\langfe1024\noproof }{\rtlch\fcs1 \af44 \ltrch\fcs0 \lang1024\langfe1024\noproof HYPERLINK \\l "_Toc45096544"}{\rtlch\fcs1 \af0 \ltrch\fcs0 \cs187\ul\cf2\lang1024\langfe1024\noproof }{\rtlch\fcs1 \af0 \ltrch\fcs0 \cs187\ul\cf2\lang1024\langfe1024\noproof {\*\datafield 08d0c9ea79f9bace118c8200aa004ba90b02000000080000000d0000005f0054006f006300340035003000390036003500340034000000}}}{\fldrslt { \rtlch\fcs1 \af0 \ltrch\fcs0 \cs187\b\ul\cf2\lang1024\langfe1024\noproof V2.3.0.6 (30-Oct-2014)}{\rtlch\fcs1 \af44 \ltrch\fcs0 \lang1024\langfe1024\noproof\webhidden \tab }{\field{\*\fldinst {\rtlch\fcs1 \af44 \ltrch\fcs0 \lang1024\langfe1024\noproof\webhidden PAGEREF _Toc45096544 \\h }{\rtlch\fcs1 \af44 \ltrch\fcs0 \lang1024\langfe1024\noproof\webhidden {\*\datafield 08d0c9ea79f9bace118c8200aa004ba90b02000000080000000d0000005f0054006f006300340035003000390036003500340034000000}}}{\fldrslt {\rtlch\fcs1 \af44 \ltrch\fcs0 \lang1024\langfe1024\noproof\webhidden 14}}}\sectd \ltrsect\rtlgutter \psz1\linex0\endnhere\pgbrdropt32\sectdefaultcl\sectrsid6896082\sftnbj }}\sectd \ltrsect\rtlgutter\psz1\linex0\endnhere\pgbrdropt32\sectdefaultcl\sectrsid6896082\sftnbj {\rtlch\fcs1 \af31507\afs22 \ltrch\fcs0 \fs22\lang1024\langfe1024\loch\af31506\hich\af31506\dbch\af31505\noproof \par }{\field\fldedit{\*\fldinst {\rtlch\fcs1 \af0 \ltrch\fcs0 \cs187\ul\cf2\lang1024\langfe1024\noproof }{\rtlch\fcs1 \af44 \ltrch\fcs0 \lang1024\langfe1024\noproof HYPERLINK \\l "_Toc45096545"}{\rtlch\fcs1 \af0 \ltrch\fcs0 \cs187\ul\cf2\lang1024\langfe1024\noproof }{\rtlch\fcs1 \af0 \ltrch\fcs0 \cs187\ul\cf2\lang1024\langfe1024\noproof {\*\datafield 08d0c9ea79f9bace118c8200aa004ba90b02000000080000000d0000005f0054006f006300340035003000390036003500340035000000}}}{\fldrslt { \rtlch\fcs1 \af0 \ltrch\fcs0 \cs187\b\ul\cf2\lang1024\langfe1024\noproof V2.3.0.5 (19-Oct-2014)}{\rtlch\fcs1 \af44 \ltrch\fcs0 \lang1024\langfe1024\noproof\webhidden \tab }{\field{\*\fldinst {\rtlch\fcs1 \af44 \ltrch\fcs0 \lang1024\langfe1024\noproof\webhidden PAGEREF _Toc45096545 \\h }{\rtlch\fcs1 \af44 \ltrch\fcs0 \lang1024\langfe1024\noproof\webhidden {\*\datafield 08d0c9ea79f9bace118c8200aa004ba90b02000000080000000d0000005f0054006f006300340035003000390036003500340035000000}}}{\fldrslt {\rtlch\fcs1 \af44 \ltrch\fcs0 \lang1024\langfe1024\noproof\webhidden 15}}}\sectd \ltrsect\rtlgutter \psz1\linex0\endnhere\pgbrdropt32\sectdefaultcl\sectrsid6896082\sftnbj }}\sectd \ltrsect\rtlgutter\psz1\linex0\endnhere\pgbrdropt32\sectdefaultcl\sectrsid6896082\sftnbj {\rtlch\fcs1 \af31507\afs22 \ltrch\fcs0 \fs22\lang1024\langfe1024\loch\af31506\hich\af31506\dbch\af31505\noproof \par }{\field\fldedit{\*\fldinst {\rtlch\fcs1 \af0 \ltrch\fcs0 \cs187\ul\cf2\lang1024\langfe1024\noproof }{\rtlch\fcs1 \af44 \ltrch\fcs0 \lang1024\langfe1024\noproof HYPERLINK \\l "_Toc45096546"}{\rtlch\fcs1 \af0 \ltrch\fcs0 \cs187\ul\cf2\lang1024\langfe1024\noproof }{\rtlch\fcs1 \af0 \ltrch\fcs0 \cs187\ul\cf2\lang1024\langfe1024\noproof {\*\datafield 08d0c9ea79f9bace118c8200aa004ba90b02000000080000000d0000005f0054006f006300340035003000390036003500340036000000}}}{\fldrslt { \rtlch\fcs1 \af0 \ltrch\fcs0 \cs187\b\ul\cf2\lang1024\langfe1024\noproof V2.3.0.4 (13-Oct-2014)}{\rtlch\fcs1 \af44 \ltrch\fcs0 \lang1024\langfe1024\noproof\webhidden \tab }{\field{\*\fldinst {\rtlch\fcs1 \af44 \ltrch\fcs0 \lang1024\langfe1024\noproof\webhidden PAGEREF _Toc45096546 \\h }{\rtlch\fcs1 \af44 \ltrch\fcs0 \lang1024\langfe1024\noproof\webhidden {\*\datafield 08d0c9ea79f9bace118c8200aa004ba90b02000000080000000d0000005f0054006f006300340035003000390036003500340036000000}}}{\fldrslt {\rtlch\fcs1 \af44 \ltrch\fcs0 \lang1024\langfe1024\noproof\webhidden 15}}}\sectd \ltrsect\rtlgutter \psz1\linex0\endnhere\pgbrdropt32\sectdefaultcl\sectrsid6896082\sftnbj }}\sectd \ltrsect\rtlgutter\psz1\linex0\endnhere\pgbrdropt32\sectdefaultcl\sectrsid6896082\sftnbj {\rtlch\fcs1 \af31507\afs22 \ltrch\fcs0 \fs22\lang1024\langfe1024\loch\af31506\hich\af31506\dbch\af31505\noproof \par }{\field\fldedit{\*\fldinst {\rtlch\fcs1 \af0 \ltrch\fcs0 \cs187\ul\cf2\lang1024\langfe1024\noproof }{\rtlch\fcs1 \af44 \ltrch\fcs0 \lang1024\langfe1024\noproof HYPERLINK \\l "_Toc45096547"}{\rtlch\fcs1 \af0 \ltrch\fcs0 \cs187\ul\cf2\lang1024\langfe1024\noproof }{\rtlch\fcs1 \af0 \ltrch\fcs0 \cs187\ul\cf2\lang1024\langfe1024\noproof {\*\datafield 08d0c9ea79f9bace118c8200aa004ba90b02000000080000000d0000005f0054006f006300340035003000390036003500340037000000}}}{\fldrslt { \rtlch\fcs1 \af0 \ltrch\fcs0 \cs187\b\ul\cf2\lang1024\langfe1024\noproof V2.2.0 (11-Jul-2014)}{\rtlch\fcs1 \af44 \ltrch\fcs0 \lang1024\langfe1024\noproof\webhidden \tab }{\field{\*\fldinst {\rtlch\fcs1 \af44 \ltrch\fcs0 \lang1024\langfe1024\noproof\webhidden PAGEREF _Toc45096547 \\h }{\rtlch\fcs1 \af44 \ltrch\fcs0 \lang1024\langfe1024\noproof\webhidden {\*\datafield 08d0c9ea79f9bace118c8200aa004ba90b02000000080000000d0000005f0054006f006300340035003000390036003500340037000000}}}{\fldrslt {\rtlch\fcs1 \af44 \ltrch\fcs0 \lang1024\langfe1024\noproof\webhidden 16}}}\sectd \ltrsect\rtlgutter \psz1\linex0\endnhere\pgbrdropt32\sectdefaultcl\sectrsid6896082\sftnbj }}\sectd \ltrsect\rtlgutter\psz1\linex0\endnhere\pgbrdropt32\sectdefaultcl\sectrsid6896082\sftnbj {\rtlch\fcs1 \af31507\afs22 \ltrch\fcs0 \fs22\lang1024\langfe1024\loch\af31506\hich\af31506\dbch\af31505\noproof \par }{\field\fldedit{\*\fldinst {\rtlch\fcs1 \af0 \ltrch\fcs0 \cs187\ul\cf2\lang1024\langfe1024\noproof }{\rtlch\fcs1 \af44 \ltrch\fcs0 \lang1024\langfe1024\noproof HYPERLINK \\l "_Toc45096548"}{\rtlch\fcs1 \af0 \ltrch\fcs0 \cs187\ul\cf2\lang1024\langfe1024\noproof }{\rtlch\fcs1 \af0 \ltrch\fcs0 \cs187\ul\cf2\lang1024\langfe1024\noproof {\*\datafield 08d0c9ea79f9bace118c8200aa004ba90b02000000080000000d0000005f0054006f006300340035003000390036003500340038000000}}}{\fldrslt { \rtlch\fcs1 \af0 \ltrch\fcs0 \cs187\b\ul\cf2\lang1024\langfe1024\noproof V2.1.0 (09-Jul-2014)}{\rtlch\fcs1 \af44 \ltrch\fcs0 \lang1024\langfe1024\noproof\webhidden \tab }{\field{\*\fldinst {\rtlch\fcs1 \af44 \ltrch\fcs0 \lang1024\langfe1024\noproof\webhidden PAGEREF _Toc45096548 \\h }{\rtlch\fcs1 \af44 \ltrch\fcs0 \lang1024\langfe1024\noproof\webhidden {\*\datafield 08d0c9ea79f9bace118c8200aa004ba90b02000000080000000d0000005f0054006f006300340035003000390036003500340038000000}}}{\fldrslt {\rtlch\fcs1 \af44 \ltrch\fcs0 \lang1024\langfe1024\noproof\webhidden 16}}}\sectd \ltrsect\rtlgutter \psz1\linex0\endnhere\pgbrdropt32\sectdefaultcl\sectrsid6896082\sftnbj }}\sectd \ltrsect\rtlgutter\psz1\linex0\endnhere\pgbrdropt32\sectdefaultcl\sectrsid6896082\sftnbj {\rtlch\fcs1 \af31507\afs22 \ltrch\fcs0 \fs22\lang1024\langfe1024\loch\af31506\hich\af31506\dbch\af31505\noproof \par }{\field\fldedit{\*\fldinst {\rtlch\fcs1 \af0 \ltrch\fcs0 \cs187\ul\cf2\lang1024\langfe1024\noproof }{\rtlch\fcs1 \af44 \ltrch\fcs0 \lang1024\langfe1024\noproof HYPERLINK \\l "_Toc45096549"}{\rtlch\fcs1 \af0 \ltrch\fcs0 \cs187\ul\cf2\lang1024\langfe1024\noproof }{\rtlch\fcs1 \af0 \ltrch\fcs0 \cs187\ul\cf2\lang1024\langfe1024\noproof {\*\datafield 08d0c9ea79f9bace118c8200aa004ba90b02000000080000000d0000005f0054006f006300340035003000390036003500340039000000}}}{\fldrslt { \rtlch\fcs1 \af0 \ltrch\fcs0 \cs187\b\ul\cf2\lang1024\langfe1024\noproof V2.0.0 (21-May-2014)}{\rtlch\fcs1 \af44 \ltrch\fcs0 \lang1024\langfe1024\noproof\webhidden \tab }{\field{\*\fldinst {\rtlch\fcs1 \af44 \ltrch\fcs0 \lang1024\langfe1024\noproof\webhidden PAGEREF _Toc45096549 \\h }{\rtlch\fcs1 \af44 \ltrch\fcs0 \lang1024\langfe1024\noproof\webhidden {\*\datafield 08d0c9ea79f9bace118c8200aa004ba90b02000000080000000d0000005f0054006f006300340035003000390036003500340039000000}}}{\fldrslt {\rtlch\fcs1 \af44 \ltrch\fcs0 \lang1024\langfe1024\noproof\webhidden 16}}}\sectd \ltrsect\rtlgutter \psz1\linex0\endnhere\pgbrdropt32\sectdefaultcl\sectrsid6896082\sftnbj }}\sectd \ltrsect\rtlgutter\psz1\linex0\endnhere\pgbrdropt32\sectdefaultcl\sectrsid6896082\sftnbj {\rtlch\fcs1 \af31507\afs22 \ltrch\fcs0 \fs22\lang1024\langfe1024\loch\af31506\hich\af31506\dbch\af31505\noproof \par }{\field\fldedit{\*\fldinst {\rtlch\fcs1 \af0 \ltrch\fcs0 \cs187\ul\cf2\lang1024\langfe1024\noproof }{\rtlch\fcs1 \af44 \ltrch\fcs0 \lang1024\langfe1024\noproof HYPERLINK \\l "_Toc45096550"}{\rtlch\fcs1 \af0 \ltrch\fcs0 \cs187\ul\cf2\lang1024\langfe1024\noproof }{\rtlch\fcs1 \af0 \ltrch\fcs0 \cs187\ul\cf2\lang1024\langfe1024\noproof {\*\datafield 08d0c9ea79f9bace118c8200aa004ba90b02000000080000000d0000005f0054006f006300340035003000390036003500350030000000}}}{\fldrslt { \rtlch\fcs1 \af0 \ltrch\fcs0 \cs187\b\ul\cf2\lang1024\langfe1024\noproof V1.1.0 (27-Feb-2014)}{\rtlch\fcs1 \af44 \ltrch\fcs0 \lang1024\langfe1024\noproof\webhidden \tab }{\field{\*\fldinst {\rtlch\fcs1 \af44 \ltrch\fcs0 \lang1024\langfe1024\noproof\webhidden PAGEREF _Toc45096550 \\h }{\rtlch\fcs1 \af44 \ltrch\fcs0 \lang1024\langfe1024\noproof\webhidden {\*\datafield 08d0c9ea79f9bace118c8200aa004ba90b02000000080000000d0000005f0054006f006300340035003000390036003500350030000000}}}{\fldrslt {\rtlch\fcs1 \af44 \ltrch\fcs0 \lang1024\langfe1024\noproof\webhidden 16}}}\sectd \ltrsect\rtlgutter \psz1\linex0\endnhere\pgbrdropt32\sectdefaultcl\sectrsid6896082\sftnbj }}\sectd \ltrsect\rtlgutter\psz1\linex0\endnhere\pgbrdropt32\sectdefaultcl\sectrsid6896082\sftnbj {\rtlch\fcs1 \af31507\afs22 \ltrch\fcs0 \fs22\lang1024\langfe1024\loch\af31506\hich\af31506\dbch\af31505\noproof \par }{\field\fldedit{\*\fldinst {\rtlch\fcs1 \af0 \ltrch\fcs0 \cs187\ul\cf2\lang1024\langfe1024\noproof }{\rtlch\fcs1 \af44 \ltrch\fcs0 \lang1024\langfe1024\noproof HYPERLINK \\l "_Toc45096551"}{\rtlch\fcs1 \af0 \ltrch\fcs0 \cs187\ul\cf2\lang1024\langfe1024\noproof }{\rtlch\fcs1 \af0 \ltrch\fcs0 \cs187\ul\cf2\lang1024\langfe1024\noproof {\*\datafield 08d0c9ea79f9bace118c8200aa004ba90b02000000080000000d0000005f0054006f006300340035003000390036003500350031000000}}}{\fldrslt { \rtlch\fcs1 \af0 \ltrch\fcs0 \cs187\b\ul\cf2\lang1024\langfe1024\noproof V1.0.0 (05-Nov-2013)}{\rtlch\fcs1 \af44 \ltrch\fcs0 \lang1024\langfe1024\noproof\webhidden \tab }{\field{\*\fldinst {\rtlch\fcs1 \af44 \ltrch\fcs0 \lang1024\langfe1024\noproof\webhidden PAGEREF _Toc45096551 \\h }{\rtlch\fcs1 \af44 \ltrch\fcs0 \lang1024\langfe1024\noproof\webhidden {\*\datafield 08d0c9ea79f9bace118c8200aa004ba90b02000000080000000d0000005f0054006f006300340035003000390036003500350031000000}}}{\fldrslt {\rtlch\fcs1 \af44 \ltrch\fcs0 \lang1024\langfe1024\noproof\webhidden 17}}}\sectd \ltrsect\rtlgutter \psz1\linex0\endnhere\pgbrdropt32\sectdefaultcl\sectrsid6896082\sftnbj }}\sectd \ltrsect\rtlgutter\psz1\linex0\endnhere\pgbrdropt32\sectdefaultcl\sectrsid6896082\sftnbj {\rtlch\fcs1 \af31507\afs22 \ltrch\fcs0 \fs22\lang1024\langfe1024\loch\af31506\hich\af31506\dbch\af31505\noproof \par }\pard\plain \ltrpar\s98\ql \li1440\ri0\sb120\keep\keepn\widctlpar\tqr\tldot\tx9893\wrapdefault\nooverflow\faroman\rin0\lin1440\itap0 \rtlch\fcs1 \ab\af1\afs20\alang1025 \ltrch\fcs0 \b\f1\fs20\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 }} \pard\plain \ltrpar\s98\ql \li1440\ri0\sb120\keep\keepn\widctlpar\tqr\tldot\tx9893\wrapdefault\nooverflow\faroman\rin0\lin1440\itap0 \rtlch\fcs1 \ab\af1\afs20\alang1025 \ltrch\fcs0 \b\f1\fs20\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \sectd \ltrsect\rtlgutter\psz1\linex0\endnhere\pgbrdropt32\sectdefaultcl\sectrsid6896082\sftnbj {\rtlch\fcs1 \af1 \ltrch\fcs0 \f31506\cf9 {\*\bkmkstart _Toc234021027} \par }\pard\plain \ltrpar\ql \li720\ri0\sb180\widctlpar\wrapdefault\nooverflow\faroman\rin0\lin720\itap0 \rtlch\fcs1 \af44\afs20\alang1025 \ltrch\fcs0 \f44\fs20\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 {\rtlch\fcs1 \af44 \ltrch\fcs0 \f31506 \par }\pard \ltrpar\ql \li0\ri0\widctlpar\wrapdefault\nooverflow\faroman\rin0\lin0\itap0 {\rtlch\fcs1 \af50 \ltrch\fcs0 \f31506 \par }\pard \ltrpar\ql \li720\ri0\sb180\widctlpar\wrapdefault\nooverflow\faroman\rin0\lin720\itap0 {\rtlch\fcs1 \af1\afs36 \ltrch\fcs0 \b\f37\fs36\cf9 \par }\pard\plain \ltrpar\s1\ql \li90\ri0\sb720\keepn\widctlpar\brdrt\brdrs\brdrw30\brsp120 \wrapdefault\nooverflow\faroman\outlinelevel0\rin0\lin90\itap0 \rtlch\fcs1 \ab\af1\afs36\alang1025 \ltrch\fcs0 \b\f1\fs36\cf9\lang1024\langfe1024\cgrid\noproof\langnp1033\langfenp1033 {\rtlch\fcs1 \af1 \ltrch\fcs0 \b0\f37 \page }{\rtlch\fcs1 \af1 \ltrch\fcs0 \f37\noproof0 {\*\bkmkstart _Toc45096514}Purpose{\*\bkmkend _Toc45096514} \par }\pard\plain \ltrpar\ql \li1440\ri0\sb180\widctlpar\wrapdefault\nooverflow\faroman\rin0\lin1440\itap0 \rtlch\fcs1 \af44\afs20\alang1025 \ltrch\fcs0 \f44\fs20\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 {\rtlch\fcs1 \af44\afs22 \ltrch\fcs0 \f37\fs22 This document serves as a brief introduction to the TWAIN CS projects. It assumes familiarity with the C# programming language, and a basic understanding of the TWAIN Specification. \par The version number supp lied in the title is a guide to when the document was last modified. TWAIN supports feature negotiated interoperability between all versions of TWAIN enabled applications, TWAIN drivers (data sources), and the TWAIN Data Source Manager. \par }{\rtlch\fcs1 \af44 \ltrch\fcs0 \f37 \par }\pard\plain \ltrpar\s1\ql \li0\ri0\sb720\keepn\widctlpar\brdrt\brdrs\brdrw30\brsp120 \wrapdefault\nooverflow\faroman\outlinelevel0\rin0\lin0\itap0 \rtlch\fcs1 \ab\af1\afs36\alang1025 \ltrch\fcs0 \b\f1\fs36\cf9\lang1024\langfe1024\cgrid\noproof\langnp1033\langfenp1033 {\rtlch\fcs1 \af1 \ltrch\fcs0 \f37 {\*\bkmkstart _Toc45096515}License{\*\bkmkend _Toc45096515} \par }\pard\plain \ltrpar\ql \li1440\ri0\widctlpar\wrapdefault\faauto\rin0\lin1440\itap0 \rtlch\fcs1 \af44\afs20\alang1025 \ltrch\fcs0 \f44\fs20\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 {\rtlch\fcs1 \af49 \ltrch\fcs0 \f37 \par }{\rtlch\fcs1 \af49\afs22 \ltrch\fcs0 \f37\fs22 Copyright (C) 2013-2020 Kodak Alaris Inc. \par \par Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, inclu ding without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: \par \par The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. \par \par THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. \par }\pard \ltrpar\ql \li720\ri0\sb180\keep\keepn\widctlpar\wrapdefault\nooverflow\faroman\rin0\lin720\itap0 {\rtlch\fcs1 \af1\afs36 \ltrch\fcs0 \b\f37\fs36\cf9 \par }\pard \ltrpar\ql \li720\ri0\widctlpar\wrapdefault\nooverflow\faroman\rin0\lin720\itap0 {\rtlch\fcs1 \af50 \ltrch\fcs0 \f31506 \par }\pard\plain \ltrpar\s189\ql \li0\ri0\keepn\pagebb\widctlpar\brdrt\brdrs\brdrw30\brsp120 \wrapdefault\nooverflow\faroman\outlinelevel0\rin0\lin0\itap0 \rtlch\fcs1 \ab\af1\afs24\alang1025 \ltrch\fcs0 \b\f1\fs24\cf9\lang1024\langfe1024\cgrid\noproof\langnp1033\langfenp1033 {\rtlch\fcs1 \af1\afs36 \ltrch\fcs0 \f31506\fs36\noproof0 {\*\bkmkstart _Toc45096516}Project Repository{\*\bkmkend _Toc45096516} \par }\pard\plain \ltrpar\ql \li0\ri0\widctlpar\wrapdefault\nooverflow\faroman\rin0\lin0\itap0 \rtlch\fcs1 \af44\afs20\alang1025 \ltrch\fcs0 \f44\fs20\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 {\rtlch\fcs1 \af0 \ltrch\fcs0 \v\f31506\cf6 \par }\pard\plain \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 \rtlch\fcs1 \af37\afs22\alang1025 \ltrch\fcs0 \f37\fs22\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 {\rtlch\fcs1 \af0 \ltrch\fcs0 \v\f31506\cf6 [Technical Notes]}{\rtlch\fcs1 \af0\afs20 \ltrch\fcs0 \i\v\f31506\fs20\cf6 \par }{\rtlch\fcs1 \af37 \ltrch\fcs0 \i\v\f31506\cf6 I think we made a mistake here. All of the capabilities that use TW_ARRAY containers only show TW_ONEVALUE as the valid container for MSG_SET. It should be TW_ONEVALUE and TW_ARRAY. \par }{\rtlch\fcs1 \af37 \ltrch\fcs0 \i\f31506\cf6 \par }{\rtlch\fcs1 \af37 \ltrch\fcs0 \f31506 TWAIN for C-Sharp (C#) resides on GitHub at }{\field{\*\fldinst {\rtlch\fcs1 \af37 \ltrch\fcs0 HYPERLINK "https://github.com/twain/twain-cs" }{\rtlch\fcs1 \af37 \ltrch\fcs0 {\*\datafield 00d0c9ea79f9bace118c8200aa004ba90b0200000003000000e0c9ea79f9bace118c8200aa004ba90b5c000000680074007400700073003a002f002f006700690074006800750062002e0063006f006d002f0074007700610069006e002f0074007700610069006e002d00630073000000795881f43b1d7f48af2c825dc485 276300000000a5ab00030000001500ef0000}}}{\fldrslt {\rtlch\fcs1 \af37 \ltrch\fcs0 \cs187\ul\cf2 https://github.com/twain/twain-cs}}}\sectd \ltrsect\rtlgutter\psz1\linex0\endnhere\pgbrdropt32\sectdefaultcl\sectrsid6896082\sftnbj {\rtlch\fcs1 \af37 \ltrch\fcs0 \f31506 . \par }{\rtlch\fcs1 \af37 \ltrch\fcs0 \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\outlinelevel1\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 \b\ul {\*\bkmkstart _Toc45096517}Installation{\*\bkmkend _Toc45096517} \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 \par There is a releases folder that contains release and debug copies of the binaries. There is no installation kit, just run them as-is. If running on Linux or macOS it may be necessary to install or upgrade Mono to v4.8 or higher. The certification tool automatically creates a \lquote TWAIN Self Certification\rquote folder on the user\rquote s desktop, which contains all the stuff needed for certification. \par \par \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\outlinelevel1\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 \b\ul {\*\bkmkstart _Toc45096518}Versioning{\*\bkmkend _Toc45096518} \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 \f31506 \par The versioning scheme takes the form: TWAIN-ProtocolMajor.TWAIN-ProtocolMinor.Interface.Build \par \par If the TWAIN Specification is at 2.3 then the version will be 2.3.i.b. This is for notational purposes only, TWAIN interoperates at all versions of the protocol, so there is no requirement that a developer has to use any specific version, or immediately upgrade if there is a change to the TWAIN Specification. \par \par The interface number rises if there is a modification to the TWAINCS or TWAINCST oolkit that requires a code change in TWAINCSTest or TWAINCSScan. For instance, adding a new argument to the ReportImage function. This lets a developer know that downloading the new version will most likely require some work in their code before they c an use it. This assumption always applies when the TWAIN Specification changes, so the interface number resets to 0 when they are modified. \par \par The build number tracks releases for a given version of the TWAIN Specification, and always rises until a new version of the spec is adopted. \par \par So, for example (fictitious sequence, just to show how it works): \par \par 2.3.0.0 \endash initial release to go with TWAIN 2.3 \par 2.3.0.1 \endash bug fix \par 2.3.0.2 \endash bug fix \par 2.3.1.3 \endash interface change \par 2.3.1.4 \endash bug fix \par 2.4.0.0 \endash initial release to go with TWAIN 2.4 \par \par }\pard\plain \ltrpar\s189\ql \li0\ri0\keepn\pagebb\widctlpar\brdrt\brdrs\brdrw30\brsp120 \wrapdefault\nooverflow\faroman\outlinelevel0\rin0\lin0\itap0 \rtlch\fcs1 \ab\af1\afs24\alang1025 \ltrch\fcs0 \b\f1\fs24\cf9\lang1024\langfe1024\cgrid\noproof\langnp1033\langfenp1033 {\rtlch\fcs1 \af1\afs36 \ltrch\fcs0 \f31506\fs36\noproof0 {\*\bkmkstart _Toc45096519}Project Layout{\*\bkmkend _Toc45096519} \par }\pard\plain \ltrpar\ql \li0\ri0\widctlpar\wrapdefault\nooverflow\faroman\rin0\lin0\itap0 \rtlch\fcs1 \af44\afs20\alang1025 \ltrch\fcs0 \f44\fs20\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 {\rtlch\fcs1 \af0 \ltrch\fcs0 \v\f31506\cf6 \par }\pard\plain \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 \rtlch\fcs1 \af37\afs22\alang1025 \ltrch\fcs0 \f37\fs22\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 {\rtlch\fcs1 \af0 \ltrch\fcs0 \v\f31506\cf6 [Technical Notes]}{\rtlch\fcs1 \af0\afs20 \ltrch\fcs0 \i\v\f31506\fs20\cf6 \par }{\rtlch\fcs1 \af37 \ltrch\fcs0 \i\v\f31506\cf6 I think we made a mistake here. All of the capabilities that use TW_ARRAY containers only show TW_ONEVALUE as the valid container for MSG_SET. It should be TW_ONEVALUE and TW_ARRAY. \par }{\rtlch\fcs1 \af37 \ltrch\fcs0 \i\f31506\cf6 \par }\pard \ltrpar\s199\ql \li360\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin360\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 \f31506 There are five projects in the TWAIN CS repository, with a single solution file to access them all: \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22 \hich\af37\dbch\af0\loch\f37 -\tab}}\pard \ltrpar\s199\ql \fi-360\li720\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\ls32\adjustright\rin0\lin720\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 \f31506 Basic TWAIN C# Definitions and Helper Functions \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22 \hich\af37\dbch\af0\loch\f37 -\tab}A TWAIN C# Toolkit \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22 \hich\af37\dbch\af0\loch\f37 -\tab}A TWAIN C# Diagnostic Application \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22 \hich\af37\dbch\af0\loch\f37 -\tab}A TWAIN C# Sample Application \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22 \hich\af37\dbch\af0\loch\f37 -\tab}}{\rtlch\fcs1 \af37 \ltrch\fcs0 A TWAIN C# Self Certification Application \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 \f31506 \par }\pard \ltrpar\s199\ql \li360\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin360\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 \f31506 The toolkit references the base definitions, and the applications reference the toolkit (with the exception of of the Certification app). This is done to maximize the amount of shared code within the repository, and to allow for the seamless addition of new projects. \par \par The toolkit seemed like a good idea once. However, after writing the Certification tool the basic functions are so completely developed that a strong case can be made for accessing them directly. If interested in doing that, then base any code on the Ce rtification tool instead of the Sample application. \par \par Application writers must not assume that these references will remain stable. They will not be versioned. The projects will be updated as needed, resulting in assemblies that are not compatible with prior releases. \par \par It\rquote s assumed that application writers will opt to pull this source code into a single assembly, the most common selection being the basic definitions, the toolkit and the sample application. Updates will be accomplished by pulling in newer v ersions of these files. Updates will typically come from the basic definitions and the toolkit. \par \par If you decide to keep the items as separate projects, then make a note of the inside of each of the .csproj files. Replacing the platform\\configuration folder names with }{\rtlch\fcs1 \af37 \ltrch\fcs0 $(Platform)\\ $(Configuration) makes for a much better build experience, since the references correctly track to the current settings. \par }{\rtlch\fcs1 \af37 \ltrch\fcs0 \f31506 \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 \f31506 \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\outlinelevel1\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 \b\f31506\ul {\*\bkmkstart _Toc45096520}Basic TWAIN C# Definitions and Helper Functions {\*\bkmkend _Toc45096520} \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af0 \ltrch\fcs0 \f31506 \par }\pard \ltrpar\s199\ql \li360\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin360\itap0 {\rtlch\fcs1 \af0 \ltrch\fcs0 \f31506 TWAINH.CS contains all o f the C/C++ TWAIN.H definitions for the version of TWAIN referenced on the title page of this document. \par \par TWAIN.CS contains helper functions designed to hide platform specific details, and to promote best practices when interfacing with the TWAIN Data Source Manager and TWAIN drivers. Best practices cover a few areas: \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af0\afs22 \ltrch\fcs0 \f37\fs22 \hich\af37\dbch\af0\loch\f37 -\tab}}\pard \ltrpar\s199\ql \fi-360\li720\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\ls32\adjustright\rin0\lin720\itap0 {\rtlch\fcs1 \af0 \ltrch\fcs0 \f31506 Funnel all commands through a single thread \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af0\afs22 \ltrch\fcs0 \f37\fs22 \hich\af37\dbch\af0\loch\f37 -\tab}Automatically collect the condition code when TWRC.Failure is detected \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af0\afs22 \ltrch\fcs0 \f37\fs22 \hich\af37\dbch\af0\loch\f37 -\tab}Automatically resynchronize the TWAIN state if a sequence error is detected \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af0\afs22 \ltrch\fcs0 \f37\fs22 \hich\af37\dbch\af0\loch\f37 -\tab}Provide ways to acess the data through CSV strings \par }\pard \ltrpar\s199\ql \li360\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin360\itap0 {\rtlch\fcs1 \af0 \ltrch\fcs0 \f31506 \par Both files expose their functionality through the TWAIN class in the TWAINWorkingGroup namespace. \par \par \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 \f31506 \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\outlinelevel1\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 \b\f31506\ul {\*\bkmkstart _Toc45096521}A TWAIN C# Toolkit{\*\bkmkend _Toc45096521} \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af0 \ltrch\fcs0 \f31506 \par }\pard \ltrpar\s199\ql \li360\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin360\itap0 {\rtlch\fcs1 \af0 \ltrch\fcs0 \f31506 The TWAIN C# Toolkit references TWAIN. This toolkit isn\rquote t as comprehensive as some designed for C/C++, which aim to hide much of the complexity of TWAIN. Instead, this toolkit addresses two main concerns: the data marshaling challenges of using a C/C++ API with C#, and the complexities of the scan loop. \par \par Honestly, it\rquote s a bit of a mess. Especially the ScanCallback function. Give serious consideration to skipping it, using the TWAIN Cerification tool as a better template for code development. At some point I\rquote ll make another project to demonstrate that. \par \par TWAIN depends upon C/C++ structures and pointers for communication between the application and the driver. The TWAIN C# Toolkit addresses this by translating data into CSV strings. These strings follow the format of the TWAIN structures (position and ty pe), but are rendered as text. This makes it relatively easy for a caller to get and set data, while still fully operating within the TWAIN name and number space. \par \par The TWAIN C# Diagnostic Application presents and consumes CSV data in its user interface, so it\rquote s easiest to see this system in action there, it can be used as a test bed when seeking to understand how to construct CSV strings to send to the driver. The TWAIN C# Sample Application also uses CSV to examine data, and to set capabilities, but does so programmatically instead of through a user interface. It helps to have access to a copy of TWAINH.CS handy when looking at the CSV data. \par \par The scan loop is the second main issue most applications run into. The loop runs inside of the TWAIN thread using callbacks to give the application access to the images and metadata returned by the TWAIN driver. This reduces that amount of code an application needs without sacrificing access to the full set of supported ICAP_XFERMECH transfer options. It also guar antees the responsiveness of the application, since operations never impede the windowing message loop. \par \par Assuming a well-behaved TWAIN driver, the application user is able to gracefully exit from the application at any time they choose, even in the middle of scanning. \par \par This TWAIN Toolkit exposes its functionality through the TWAINCSToolkit class in the TWAINWorkingGroupToolkit namespace. \par \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 \f31506 \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\outlinelevel1\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 \b\f31506\ul {\*\bkmkstart _Toc45096522}A TWAIN C# Diagnostic Application{\*\bkmkend _Toc45096522} \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af0 \ltrch\fcs0 \f31506 \par }\pard \ltrpar\s199\ql \li360\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin360\itap0 {\rtlch\fcs1 \af0 \ltrch\fcs0 \f31506 This application references TWAINCSToolkit. The code is not intended as seed code for applications. It is a comprehensive frontend to the TWAIN API. It allows the selection of any combination of TWAIN triplets, including ones that are illegal or are out of sequence with the current TWAIN state. It is best compa red to the TWACKER application, which has long been the main way to exercise TWAIN drivers on Microsoft Windows systems. \par \par Data is presented and consumed in the form of CSV strings. Familiarity with the various TWAIN structures is essential, since these str ings do not include self-referential metadata, aside from the content described by the TWAIN Specification. As mentioned above, }{\rtlch\fcs1 \af0 \ltrch\fcs0 it helps to have access to a copy of TWAINH.CS handy when looking at the CSV data.}{ \rtlch\fcs1 \af0 \ltrch\fcs0 \f31506 \par \par The application tries to reduce mouse click s for some common operations. For instance, upon successful completion of the DG_CONTROL / DAT_PARENT / MSG_OPENDSM operation, the dropdown values are set to DG_CONTROL / DAT_IDENTITY / MSG_GETFIRST, to enumerate the first TWAIN driver in the list of dri vers. After a few uses it\rquote ll be apparent when the application is trying to help. \par \par A @-command system has been added. It doesn\rquote t do much at the moment, but it could be expanded to allow for more complex behavior. For instance, some kind of scripting syste m that would allow the diagnostic tool to help with automated tests. It becomes available after opening a DSM. Type @help in the text box and press the Send button to get the list of supported commands. \par \par \par \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 \f31506 \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\outlinelevel1\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 \b\f31506\ul {\*\bkmkstart _Toc45096523}A TWAIN C# Sample Application{\*\bkmkend _Toc45096523} \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af0 \ltrch\fcs0 \f31506 \par }\pard \ltrpar\s199\ql \li360\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin360\itap0 {\rtlch\fcs1 \af0 \ltrch\fcs0 \f31506 This application references TWAINCSToolkit. The code is intended as seed code for applications, and demonstrates the easiest way to access the full range of functionality present in TWAIN. \par \par For TWAIN drivers that support DG_CONTROL / DAT_USERINTERFACE / MSG_ENABLEDSUIONLY and DG_CONTROL / DAT_CUSTOMDSDATA / MSG_*, the application supports a \'93snapshot\'94 system. This allows a user to configure a TWAIN driver and save its setting under a descriptive name that can be used to restore those settings prior to scanning. \par \par For drivers that don\rquote t support these operations the application defaults to the older }{\rtlch\fcs1 \af0 \ltrch\fcs0 DG_CONTROL / DAT_USERINTERFACE / MSG_ENABLEDS system, with TW_USERINTERFACE.ShowUI set to TRUE. \par \par An application writer also has the option to programmatically negotiate capabilities. The sample app doesn\rquote t show this path, but it\rquote s relatively easy to add for a small number of configurable items.}{\rtlch\fcs1 \af0 \ltrch\fcs0 \f31506 \par }{\rtlch\fcs1 \af0 \ltrch\fcs0 \par \par \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\outlinelevel1\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 \b\ul {\*\bkmkstart _Toc45096524}A TWAIN C# Self Certification Application{\*\bkmkend _Toc45096524} \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af0 \ltrch\fcs0 \par }\pard \ltrpar\s199\ql \li360\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin360\itap0 {\rtlch\fcs1 \af0 \ltrch\fcs0 This ap plication serves three purposes. It shows a reasonably good way of interfacing with TWAIN from C#. It allows a user to interact directly with a TWAIN driver (with the aid of scripts). And it offers a way to certify that a TWAIN driver is compliant with the specification. \par \par Note that the correct binary must be run to interface with 32-bit or 64-bit drivers. This code has been tested on Windows, Linux, and Mac (the last two using Mono 4.8 or later). \par \par The tool has help built into it. It also comes with a large collection of scripts. If you use the \lquote runv\rquote command with the script, you\rquote ll get some insight into what arguments are needed for the \lquote dsmentry\rquote command. \par \par It should be a good tool for developers, allowing them to explore the kind of commands they\rquote ll need to issue from other languages, like C++. \par \par If developing with the tool, it\rquote ll use the data folder located with the binary. The release version normally defaults to the \'93TWAIN Self Certification/data\'94 folder on the desktop. \par }\pard\plain \ltrpar\ql \li0\ri0\widctlpar\wrapdefault\faauto\rin0\lin0\itap0 \rtlch\fcs1 \af44\afs20\alang1025 \ltrch\fcs0 \f44\fs20\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 {\rtlch\fcs1 \af45 \ltrch\fcs0 \f31506 \par }\pard\plain \ltrpar\s189\ql \li0\ri0\keepn\pagebb\widctlpar\brdrt\brdrs\brdrw30\brsp120 \wrapdefault\nooverflow\faroman\outlinelevel0\rin0\lin0\itap0 \rtlch\fcs1 \ab\af1\afs24\alang1025 \ltrch\fcs0 \b\f1\fs24\cf9\lang1024\langfe1024\cgrid\noproof\langnp1033\langfenp1033 {\rtlch\fcs1 \af1\afs36 \ltrch\fcs0 \f31506\fs36\noproof0 {\*\bkmkstart _Toc45096525}Release Notes{\*\bkmkend _Toc45096525} \par }\pard\plain \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 \rtlch\fcs1 \af37\afs22\alang1025 \ltrch\fcs0 \f37\fs22\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 {\rtlch\fcs1 \af37 \ltrch\fcs0 \i\cf6 \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\outlinelevel1\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 \b\ul {\*\bkmkstart _Toc45096526}V2.4.11.0 (08-Jul-2020)}{\rtlch\fcs1 \af37 \ltrch\fcs0 {\*\bkmkend _Toc45096526} \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 New Features: \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22 \hich\af37\dbch\af0\loch\f37 -\tab}}\pard \ltrpar\s199\ql \fi-360\li720\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\ls32\adjustright\rin0\lin720\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 (none) \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 Bug Fixes: \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22 \hich\af37\dbch\af0\loch\f37 -\tab}}\pard \ltrpar\s199\ql \fi-360\li720\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\ls32\adjustright\rin0\lin720\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 Added deprecated capabilites to LookupTable.tc \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22 \hich\af37\dbch\af0\loch\f37 -\tab}Fixed cert to skip deprecated capabilties \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22 \hich\af37\dbch\af0\loch\f37 -\tab}Fixed to better handle when a driver isn\rquote t successfully opened (skip the tests) \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 Known Issues: \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22 \hich\af37\dbch\af0\loch\f37 -\tab}}\pard \ltrpar\s199\ql \fi-360\li720\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\ls32\adjustright\rin0\lin720\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 (none) \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 Wish List: \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22 \hich\af37\dbch\af0\loch\f37 -\tab}}\pard \ltrpar\s199\ql \fi-360\li720\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\ls32\adjustright\rin0\lin720\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 Want to switch to something other than WinForms, especially for macOS \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22 \hich\af37\dbch\af0\loch\f37 -\tab}Need to add some more certification tests, especially for things like printer, barcode, patch \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 \i\cf6 \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\outlinelevel1\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 \b\ul {\*\bkmkstart _Toc45096527}V2.4.10.0 (06-Jun-2020)}{\rtlch\fcs1 \af37 \ltrch\fcs0 {\*\bkmkend _Toc45096527} \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 New Features: \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22 \hich\af37\dbch\af0\loch\f37 -\tab}}\pard \ltrpar\s199\ql \fi-360\li720\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\ls32\adjustright\rin0\lin720\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 (none) \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 Bug Fixes: \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22 \hich\af37\dbch\af0\loch\f37 -\tab}}\pard \ltrpar\s199\ql \fi-360\li720\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\ls32\adjustright\rin0\lin720\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 Fixed twaincert.exe to run from the releases folder without thinking it\rquote s a development path, so it correctly creates the \lquote data\rquote folder in the \lquote TWAIN Self Certification\rquote folder on the desktop. \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 Known Issues: \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22 \hich\af37\dbch\af0\loch\f37 -\tab}}\pard \ltrpar\s199\ql \fi-360\li720\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\ls32\adjustright\rin0\lin720\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 (none) \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 Wish List: \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22 \hich\af37\dbch\af0\loch\f37 -\tab}}\pard \ltrpar\s199\ql \fi-360\li720\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\ls32\adjustright\rin0\lin720\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 Want to switch to something other than WinForms, especially for macOS \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22 \hich\af37\dbch\af0\loch\f37 -\tab}Need to add some more certification tests, especially for things like printer, barcode, patch \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 \i\cf6 \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\outlinelevel1\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 \b\ul {\*\bkmkstart _Toc45096528}V2.4.9.0 (30-Apr-2020)}{\rtlch\fcs1 \af37 \ltrch\fcs0 {\*\bkmkend _Toc45096528} \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 New Features: \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22 \hich\af37\dbch\af0\loch\f37 -\tab}}\pard \ltrpar\s199\ql \fi-360\li720\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\ls32\adjustright\rin0\lin720\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 (none) \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 Bug Fixes: \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22 \hich\af37\dbch\af0\loch\f37 -\tab}}\pard \ltrpar\s199\ql \fi-360\li720\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\ls32\adjustright\rin0\lin720\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 The MSG_SET certification test was using the MSG_GET container, when the 2.4 spec states that it should only use TW_ONEVALUE or TW_ARRAY (the others being for MSG_SETCONTAINER), so that\rquote s fixed now \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22 \hich\af37\dbch\af0\loch\f37 -\tab} Fixed TWBP_* values to not return symbolic names, the support for symbolic names with TW_RANGE gets too weird too fast, staying with numbers offers fewer problems \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 Known Issues: \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22 \hich\af37\dbch\af0\loch\f37 -\tab}}\pard \ltrpar\s199\ql \fi-360\li720\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\ls32\adjustright\rin0\lin720\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 (none) \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 Wish List: \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22 \hich\af37\dbch\af0\loch\f37 -\tab}}\pard \ltrpar\s199\ql \fi-360\li720\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\ls32\adjustright\rin0\lin720\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 Want to switch to something other than WinForms, especially for macOS \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22 \hich\af37\dbch\af0\loch\f37 -\tab}Need to add some more certification tests, especially for things like printer, barcode, patch \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 \i\cf6 \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\outlinelevel1\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 \b\ul {\*\bkmkstart _Toc45096529}V2.4.8.0 (30-Mar-2020)}{\rtlch\fcs1 \af37 \ltrch\fcs0 {\*\bkmkend _Toc45096529} \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 New Features: \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22 \hich\af37\dbch\af0\loch\f37 -\tab}}\pard \ltrpar\s199\ql \fi-360\li720\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\ls32\adjustright\rin0\lin720\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 Switched almost all of the csv functions to static \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22 \hich\af37\dbch\af0\loch\f37 -\tab}(yah, skipped 2.4.7, kinda) \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 Bug Fixes: \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22 \hich\af37\dbch\af0\loch\f37 -\tab}}\pard \ltrpar\s199\ql \fi-360\li720\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\ls32\adjustright\rin0\lin720\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 (none) \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 Known Issues: \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22 \hich\af37\dbch\af0\loch\f37 -\tab}}\pard \ltrpar\s199\ql \fi-360\li720\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\ls32\adjustright\rin0\lin720\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 (none) \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 Wish List: \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22 \hich\af37\dbch\af0\loch\f37 -\tab}}\pard \ltrpar\s199\ql \fi-360\li720\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\ls32\adjustright\rin0\lin720\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 Want to switch to something other than WinForms, especially for macOS \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22 \hich\af37\dbch\af0\loch\f37 -\tab}Need to add some more certification tests, especially for things like printer, barcode, patch \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 \i\cf6 \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\outlinelevel1\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 \b\ul {\*\bkmkstart _Toc45096530}V2.4.6.0 (26-Mar-2020)}{\rtlch\fcs1 \af37 \ltrch\fcs0 {\*\bkmkend _Toc45096530} \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 New Features: \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22 \hich\af37\dbch\af0\loch\f37 -\tab}}\pard \ltrpar\s199\ql \fi-360\li720\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\ls32\adjustright\rin0\lin720\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 (none) \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 Bug Fixes: \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22 \hich\af37\dbch\af0\loch\f37 -\tab}}\pard \ltrpar\s199\ql \fi-360\li720\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\ls32\adjustright\rin0\lin720\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 MSG_XFERREADY wasn\rquote t being handled properly if ShowUI was TRUE \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 Known Issues: \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22 \hich\af37\dbch\af0\loch\f37 -\tab}}\pard \ltrpar\s199\ql \fi-360\li720\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\ls32\adjustright\rin0\lin720\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 (none) \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 Wish List: \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22 \hich\af37\dbch\af0\loch\f37 -\tab}}\pard \ltrpar\s199\ql \fi-360\li720\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\ls32\adjustright\rin0\lin720\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 Want to switch to something other than WinForms, especially for macOS \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22 \hich\af37\dbch\af0\loch\f37 -\tab}Need to add some more certification tests, especially for things like printer, barcode, patch \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\outlinelevel1\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 \b\ul {\*\bkmkstart _Toc45096531}V2.4.5.0 (24-Mar-2020)}{\rtlch\fcs1 \af37 \ltrch\fcs0 {\*\bkmkend _Toc45096531} \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 New Features: \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22 \hich\af37\dbch\af0\loch\f37 -\tab}}\pard \ltrpar\s199\ql \fi-360\li720\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\ls32\adjustright\rin0\lin720\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 (none) \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 Bug Fixes: \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22 \hich\af37\dbch\af0\loch\f37 -\tab}}\pard \ltrpar\s199\ql \fi-360\li720\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\ls32\adjustright\rin0\lin720\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 Stupid data folder wasn\rquote t being properly created (grrr) \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 Known Issues: \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22 \hich\af37\dbch\af0\loch\f37 -\tab}}\pard \ltrpar\s199\ql \fi-360\li720\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\ls32\adjustright\rin0\lin720\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 (none) \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 Wish List: \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22 \hich\af37\dbch\af0\loch\f37 -\tab}}\pard \ltrpar\s199\ql \fi-360\li720\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\ls32\adjustright\rin0\lin720\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 Want to switch to something other than WinForms, especially for macOS \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22 \hich\af37\dbch\af0\loch\f37 -\tab}Need to add some more certification tests, especially for things like printer, barcode, patch \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 \i\cf6 \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\outlinelevel1\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 \b\ul {\*\bkmkstart _Toc45096532}V2.4.4.0 (24-Mar-2020)}{\rtlch\fcs1 \af37 \ltrch\fcs0 {\*\bkmkend _Toc45096532} \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 New Features: \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22 \hich\af37\dbch\af0\loch\f37 -\tab}}\pard \ltrpar\s199\ql \fi-360\li720\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\ls32\adjustright\rin0\lin720\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 Fixed issues related to TWAIN Direct support, and added it to certification \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22 \hich\af37\dbch\af0\loch\f37 -\tab}Added makerelease.bat file \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 Bug Fixes: \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22 \hich\af37\dbch\af0\loch\f37 -\tab}}\pard \ltrpar\s199\ql \fi-360\li720\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\ls32\adjustright\rin0\lin720\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 (none) \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 Known Issues: \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22 \hich\af37\dbch\af0\loch\f37 -\tab}}\pard \ltrpar\s199\ql \fi-360\li720\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\ls32\adjustright\rin0\lin720\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 (none) \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 Wish List: \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22 \hich\af37\dbch\af0\loch\f37 -\tab}}\pard \ltrpar\s199\ql \fi-360\li720\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\ls32\adjustright\rin0\lin720\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 Want to switch to something other than WinForms, especially for macOS \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22 \hich\af37\dbch\af0\loch\f37 -\tab}Need to add some more certification tests, especially for things like printer, barcode, patch \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 \i\cf6 \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\outlinelevel1\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 \b\ul {\*\bkmkstart _Toc45096533}V2.4.3.0 (20-Mar-2020)}{\rtlch\fcs1 \af37 \ltrch\fcs0 {\*\bkmkend _Toc45096533} \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 New Features: \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22 \hich\af37\dbch\af0\loch\f37 -\tab}}\pard \ltrpar\s199\ql \fi-360\li720\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\ls32\adjustright\rin0\lin720\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 Switched twaincsscan and twaincstst to directly access TWAIN.CS \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22 \hich\af37\dbch\af0\loch\f37 -\tab}The toolkit is officially deprecated now, don\rquote t use it \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 Bug Fixes: \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22 \hich\af37\dbch\af0\loch\f37 -\tab}}\pard \ltrpar\s199\ql \fi-360\li720\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\ls32\adjustright\rin0\lin720\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 Fixed an issue where xferready during enableds could be missed \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 Known Issues: \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22 \hich\af37\dbch\af0\loch\f37 -\tab}}\pard \ltrpar\s199\ql \fi-360\li720\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\ls32\adjustright\rin0\lin720\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 (none) \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 Wish List: \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22 \hich\af37\dbch\af0\loch\f37 -\tab}}\pard \ltrpar\s199\ql \fi-360\li720\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\ls32\adjustright\rin0\lin720\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 Want to switch to something other than WinForms, especially for macOS \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22 \hich\af37\dbch\af0\loch\f37 -\tab}Need to add some more certification tests, especially for things like printer, barcode, patch \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 \i\cf6 \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\outlinelevel1\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 \b\ul {\*\bkmkstart _Toc45096534}V2.4.2.0 (13-Mar-2020)}{\rtlch\fcs1 \af37 \ltrch\fcs0 {\*\bkmkend _Toc45096534} \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 New Features: \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22 \hich\af37\dbch\af0\loch\f37 -\tab}}\pard \ltrpar\s199\ql \fi-360\li720\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\ls32\adjustright\rin0\lin720\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 Massive update to TWAIN.CS \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22 \hich\af37\dbch\af0\loch\f37 -\tab}twaincscert is pretty much done \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 Bug Fixes: \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22 \hich\af37\dbch\af0\loch\f37 -\tab}}\pard \ltrpar\s199\ql \fi-360\li720\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\ls32\adjustright\rin0\lin720\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 Too many to count, twaincscert helped scrub the code \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 Known Issues: \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22 \hich\af37\dbch\af0\loch\f37 -\tab}}\pard \ltrpar\s199\ql \fi-360\li720\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\ls32\adjustright\rin0\lin720\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 (none) \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 Wish List: \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22 \hich\af37\dbch\af0\loch\f37 -\tab}}\pard \ltrpar\s199\ql \fi-360\li720\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\ls32\adjustright\rin0\lin720\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 Want to switch to something other than WinForms, especially for macOS \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22 \hich\af37\dbch\af0\loch\f37 -\tab}Need to add some more certification tests, especially for things like printer, barcode, patch \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 \i\cf6 \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\outlinelevel1\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 \b\ul {\*\bkmkstart _Toc45096535}V2.4.1.0 (30-Jan-2020)}{\rtlch\fcs1 \af37 \ltrch\fcs0 {\*\bkmkend _Toc45096535} \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 New Features: \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22 \hich\af37\dbch\af0\loch\f37 -\tab}}\pard \ltrpar\s199\ql \fi-360\li720\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\ls32\adjustright\rin0\lin720\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 Added twaincscert project (it\rquote s not done yet, but it is useable) \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22 \hich\af37\dbch\af0\loch\f37 -\tab}Fixed reflection to allow use of capability enumerations in the CSV (ex: TWPT_RGB) \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22 \hich\af37\dbch\af0\loch\f37 -\tab}Expanded ability to use TWAIN.CS without the toolkit (needed for cert) \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 Bug Fixes: \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22 \hich\af37\dbch\af0\loch\f37 -\tab}}\pard \ltrpar\s199\ql \fi-360\li720\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\ls32\adjustright\rin0\lin720\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 (none) \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 Known Issues: \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22 \hich\af37\dbch\af0\loch\f37 -\tab}}\pard \ltrpar\s199\ql \fi-360\li720\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\ls32\adjustright\rin0\lin720\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 Runs rather slowly on Mac OS X \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22 \hich\af37\dbch\af0\loch\f37 -\tab}Setup Dialog sometimes freaks out on Mac OS X (appears to be a WinForms bug) \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 Wish List: \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22 \hich\af37\dbch\af0\loch\f37 -\tab}}\pard \ltrpar\s199\ql \fi-360\li720\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\ls32\adjustright\rin0\lin720\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 64-bit Mono support on Mac OS X (should just work, but needs building / testing) \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22 \hich\af37\dbch\af0\loch\f37 -\tab}Want to switch to Xamarin \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 \i\cf6 \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\outlinelevel1\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 \b\ul {\*\bkmkstart _Toc45096536}V2.4.0.3 (13-Mar-2019)}{\rtlch\fcs1 \af37 \ltrch\fcs0 {\*\bkmkend _Toc45096536} \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 New Features: \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22 \hich\af37\dbch\af0\loch\f37 -\tab}}\pard \ltrpar\s199\ql \fi-360\li720\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\ls32\adjustright\rin0\lin720\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 (none) \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 Bug Fixes: \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22 \hich\af37\dbch\af0\loch\f37 -\tab}}\pard \ltrpar\s199\ql \fi-360\li720\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\ls32\adjustright\rin0\lin720\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 Fixed an encoding problem, TWAIN on Windows requires strings in the encoding specified by the driver (either through it\rquote s TW_IDENTITY.Version.Language or the last successful set of CAP_LANGUAGE). Until this fix TWAIN CS was sending strings as UTF-8. Note that on Linux and macOS UTF-8 is the encoding, that hasn\rquote t changed. \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 Known Issues: \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22 \hich\af37\dbch\af0\loch\f37 -\tab}}\pard \ltrpar\s199\ql \fi-360\li720\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\ls32\adjustright\rin0\lin720\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 Runs rather slowly on Mac OS X \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22 \hich\af37\dbch\af0\loch\f37 -\tab}Setup Dialog sometimes freaks out on Mac OS X (appears to be a WinForms bug) \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 Wish List: \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22 \hich\af37\dbch\af0\loch\f37 -\tab}}\pard \ltrpar\s199\ql \fi-360\li720\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\ls32\adjustright\rin0\lin720\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 64-bit Mono support on Mac OS X (should just work, but needs building / testing) \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22 \hich\af37\dbch\af0\loch\f37 -\tab}Want to switch to Xamarin \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\outlinelevel1\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 \b\ul {\*\bkmkstart _Toc45096537}V2.4.0.2 (25-Jan-2019)}{\rtlch\fcs1 \af37 \ltrch\fcs0 {\*\bkmkend _Toc45096537} \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 New Features: \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22 \hich\af37\dbch\af0\loch\f37 -\tab}}\pard \ltrpar\s199\ql \fi-360\li720\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\ls32\adjustright\rin0\lin720\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 In sync with TWAIN Direct \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22 \hich\af37\dbch\af0\loch\f37 -\tab}Updated to VS2017 \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 Bug Fixes: \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22 \hich\af37\dbch\af0\loch\f37 -\tab}}\pard \ltrpar\s199\ql \fi-360\li720\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\ls32\adjustright\rin0\lin720\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 Fixed problem with FIX32 in TW_RANGE \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22 \hich\af37\dbch\af0\loch\f37 -\tab}Fixed problems with SendDat for custom DAT support \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 Known Issues: \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22 \hich\af37\dbch\af0\loch\f37 -\tab}}\pard \ltrpar\s199\ql \fi-360\li720\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\ls32\adjustright\rin0\lin720\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 Runs rather slowly on Mac OS X \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22 \hich\af37\dbch\af0\loch\f37 -\tab}Setup Dialog sometimes freaks out on Mac OS X (appears to be a WinForms bug) \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 Wish List: \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22 \hich\af37\dbch\af0\loch\f37 -\tab}}\pard \ltrpar\s199\ql \fi-360\li720\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\ls32\adjustright\rin0\lin720\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 64-bit Mono support on Mac OS X (should just work, but needs building / testing) \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22 \hich\af37\dbch\af0\loch\f37 -\tab}Want to switch to Xamarin \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 \i\cf6 \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\outlinelevel1\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 \b\ul {\*\bkmkstart _Toc45096538}V2.4.0.1 (19-Apr-2018)}{\rtlch\fcs1 \af37 \ltrch\fcs0 {\*\bkmkend _Toc45096538} \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 New Features: \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22 \hich\af37\dbch\af0\loch\f37 -\tab}}\pard \ltrpar\s199\ql \fi-360\li720\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\ls32\adjustright\rin0\lin720\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 In sync with TWAIN Direct \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 Bug Fixes: \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22 \hich\af37\dbch\af0\loch\f37 -\tab}}\pard \ltrpar\s199\ql \fi-360\li720\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\ls32\adjustright\rin0\lin720\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 Code analysis with VS2015, fixed up everything, supressed some stuff \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22 \hich\af37\dbch\af0\loch\f37 -\tab}Finally got the Linux 64-bit thing right (lots of edge cases) \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 Known Issues: \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22 \hich\af37\dbch\af0\loch\f37 -\tab}}\pard \ltrpar\s199\ql \fi-360\li720\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\ls32\adjustright\rin0\lin720\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 Runs rather slowly on Mac OS X \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22 \hich\af37\dbch\af0\loch\f37 -\tab}Setup Dialog sometimes freaks out on Mac OS X (appears to be a WinForms bug) \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 Wish List: \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22 \hich\af37\dbch\af0\loch\f37 -\tab}}\pard \ltrpar\s199\ql \fi-360\li720\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\ls32\adjustright\rin0\lin720\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 64-bit Mono support on Mac OS X (should just work, but needs building / testing) \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22 \hich\af37\dbch\af0\loch\f37 -\tab}Want to switch to Xamarin, and VS2017 \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 \i\cf6 \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\outlinelevel1\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 \b\ul {\*\bkmkstart _Toc45096539}V2.4.0.0 (darned if I know, 2017)}{\rtlch\fcs1 \af37 \ltrch\fcs0 {\*\bkmkend _Toc45096539} \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 New Features: \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22 \hich\af37\dbch\af0\loch\f37 -\tab}}\pard \ltrpar\s199\ql \fi-360\li720\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\ls32\adjustright\rin0\lin720\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 Linux 64-bit support, despite the TW_INT32/TW_UINT32 fiasco \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22 \hich\af37\dbch\af0\loch\f37 -\tab}Switched to log file backup scheme \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22 \hich\af37\dbch\af0\loch\f37 -\tab}In sync with TWAIN Direct \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 Known Issues: \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22 \hich\af37\dbch\af0\loch\f37 -\tab}}\pard \ltrpar\s199\ql \fi-360\li720\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\ls32\adjustright\rin0\lin720\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 Runs rather slowly on Mac OS X \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22 \hich\af37\dbch\af0\loch\f37 -\tab}Setup Dialog sometimes freaks out on Mac OS X (appears to be a WinForms bug) \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 Wish List: \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22 \hich\af37\dbch\af0\loch\f37 -\tab}}\pard \ltrpar\s199\ql \fi-360\li720\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\ls32\adjustright\rin0\lin720\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 64-bit Mono support on Mac OS X (should just work, but needs building / testing) \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 \i\cf6 \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\outlinelevel1\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 \b\ul {\*\bkmkstart _Toc45096540}V2.3.2.0 (18-Oct-2015)}{\rtlch\fcs1 \af37 \ltrch\fcs0 {\*\bkmkend _Toc45096540} \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 New Features: \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22 \hich\af37\dbch\af0\loch\f37 -\tab}}\pard \ltrpar\s199\ql \fi-360\li720\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\ls32\adjustright\rin0\lin720\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 Override capability for logging \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22 \hich\af37\dbch\af0\loch\f37 -\tab}Log files are now read shared, so they can be viewed while the code is running \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22 \hich\af37\dbch\af0\loch\f37 -\tab}RunInGuiThread scheme added to support Windows for bug listed below \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22 \hich\af37\dbch\af0\loch\f37 -\tab}Added thread and state to the log lines, added OS to the title line \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 Bug Fixes: \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22 \hich\af37\dbch\af0\loch\f37 -\tab}}\pard \ltrpar\s199\ql \fi-360\li720\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\ls32\adjustright\rin0\lin720\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 DAT_USERINTERFACE and DAT_IMAGE*XFER run on the HWND thread on Windows, this fixes problems with a number of drivers that run their code in the message loop (addresses Ticket #11 and Ticket #14) \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22 \hich\af37\dbch\af0\loch\f37 -\tab}DsmMemLock on the native transfer handle (addresses Ticket #15) \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22 \hich\af37\dbch\af0\loch\f37 -\tab}I\rquote m not closing the tickets until I get feedback, or if I hear nothing for a month or two \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 Known Issues: \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22 \hich\af37\dbch\af0\loch\f37 -\tab}}\pard \ltrpar\s199\ql \fi-360\li720\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\ls32\adjustright\rin0\lin720\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 Runs rather slowly on Mac OS X \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22 \hich\af37\dbch\af0\loch\f37 -\tab}Setup Dialog sometimes freaks out on Mac OS X (appears to be a WinForms bug) \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 Wish List: \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22 \hich\af37\dbch\af0\loch\f37 -\tab}}\pard \ltrpar\s199\ql \fi-360\li720\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\ls32\adjustright\rin0\lin720\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 64-bit Mono support on Mac OS X (should just work, but needs building / testing) \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 \i\cf6 \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\outlinelevel1\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 \b\ul {\*\bkmkstart _Toc45096541}V2.3.1.2 (13-Sep-2015)}{\rtlch\fcs1 \af37 \ltrch\fcs0 {\*\bkmkend _Toc45096541} \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 New Features: \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22 \hich\af37\dbch\af0\loch\f37 -\tab}}\pard \ltrpar\s199\ql \fi-360\li720\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\ls32\adjustright\rin0\lin720\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 (none) \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 Bug Fixes: \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22 \hich\af37\dbch\af0\loch\f37 -\tab}}\pard \ltrpar\s199\ql \fi-360\li720\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\ls32\adjustright\rin0\lin720\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 Solved issues with the DsmMem* functions \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 Known Issues: \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22 \hich\af37\dbch\af0\loch\f37 -\tab}}\pard \ltrpar\s199\ql \fi-360\li720\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\ls32\adjustright\rin0\lin720\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 Runs rather slowly on Mac OS X \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22 \hich\af37\dbch\af0\loch\f37 -\tab}Setup Dialog sometimes freaks out on Mac OS X (appears to be a WinForms bug) \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 Wish List: \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22 \hich\af37\dbch\af0\loch\f37 -\tab}}\pard \ltrpar\s199\ql \fi-360\li720\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\ls32\adjustright\rin0\lin720\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 64-bit Mono support on Mac OS X (should just work, but needs building / testing) \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\outlinelevel1\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 \b\ul {\*\bkmkstart _Toc45096542}V2.3.1.1 (27-Aug-2015)}{\rtlch\fcs1 \af37 \ltrch\fcs0 {\*\bkmkend _Toc45096542} \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 New Features: \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22 \hich\af37\dbch\af0\loch\f37 -\tab}}\pard \ltrpar\s199\ql \fi-360\li720\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\ls32\adjustright\rin0\lin720\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 (none) \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 Bug Fixes: \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22 \hich\af37\dbch\af0\loch\f37 -\tab}}\pard \ltrpar\s199\ql \fi-360\li720\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\ls32\adjustright\rin0\lin720\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 Log fix and sync with TWAIN Direct \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 Known Issues: \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22 \hich\af37\dbch\af0\loch\f37 -\tab}}\pard \ltrpar\s199\ql \fi-360\li720\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\ls32\adjustright\rin0\lin720\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 Runs rather slowly on Mac OS X \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22 \hich\af37\dbch\af0\loch\f37 -\tab}Setup Dialog sometimes freaks out on Mac OS X (appears to be a WinForms bug) \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 Wish List: \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22 \hich\af37\dbch\af0\loch\f37 -\tab}}\pard \ltrpar\s199\ql \fi-360\li720\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\ls32\adjustright\rin0\lin720\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 64-bit Mono support on Mac OS X (should just work, but needs building / testing) \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\outlinelevel1\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 \b\ul {\*\bkmkstart _Toc45096543}V2.3.1.0 (13-Mar-2015)}{\rtlch\fcs1 \af37 \ltrch\fcs0 {\*\bkmkend _Toc45096543} \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 New Features: \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22 \hich\af37\dbch\af0\loch\f37 -\tab}}\pard \ltrpar\s199\ql \fi-360\li720\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\ls32\adjustright\rin0\lin720\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 Additional arguments to the ReportImage callback \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 Bug Fixes: \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22 \hich\af37\dbch\af0\loch\f37 -\tab}}\pard \ltrpar\s199\ql \fi-360\li720\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\ls32\adjustright\rin0\lin720\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 Tested building using MonoDevelop on Ubuntu 14.04 (32-bit) using Mono 3.12.1, fixed two problems \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 Known Issues: \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22 \hich\af37\dbch\af0\loch\f37 -\tab}}\pard \ltrpar\s199\ql \fi-360\li720\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\ls32\adjustright\rin0\lin720\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 Runs rather slowly on Mac OS X \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22 \hich\af37\dbch\af0\loch\f37 -\tab}Setup Dialog sometimes freaks out on Mac OS X (appears to be a WinForms bug) \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 Wish List: \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22 \hich\af37\dbch\af0\loch\f37 -\tab}}\pard \ltrpar\s199\ql \fi-360\li720\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\ls32\adjustright\rin0\lin720\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 64-bit Mono support on Mac OS X (should just work, but needs building / testing) \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\outlinelevel1\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 \b\ul {\*\bkmkstart _Toc45096544}V2.3.0.6 (30-Oct-2014)}{\rtlch\fcs1 \af37 \ltrch\fcs0 {\*\bkmkend _Toc45096544} \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 New Features: \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22 \hich\af37\dbch\af0\loch\f37 -\tab}}\pard \ltrpar\s199\ql \fi-360\li720\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\ls32\adjustright\rin0\lin720\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 (none) \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 Bug Fixes: \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22 \hich\af37\dbch\af0\loch\f37 -\tab}}\pard \ltrpar\s199\ql \fi-360\li720\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\ls32\adjustright\rin0\lin720\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 Closed Ticket #6: DsmMemFree - Validate \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22 \hich\af37\dbch\af0\loch\f37 -\tab}Ticket #5 has been resisting, this time I got it right\'85 \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22 \hich\af37\dbch\af0\loch\f37 -\tab}Removed embedded tabs \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22 \hich\af37\dbch\af0\loch\f37 -\tab}Confirmed successful tests with other vendors \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22 \hich\af37\dbch\af0\loch\f37 -\tab}Fixed code to better handle when TWAIN DSM isn\rquote t installed \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 Known Issues: \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22 \hich\af37\dbch\af0\loch\f37 -\tab}}\pard \ltrpar\s199\ql \fi-360\li720\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\ls32\adjustright\rin0\lin720\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 Runs rather slowly on Mac OS X \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22 \hich\af37\dbch\af0\loch\f37 -\tab}Setup Dialog sometimes freaks out on Mac OS X (appears to be a WinForms bug) \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 Wish List: \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22 \hich\af37\dbch\af0\loch\f37 -\tab}}\pard \ltrpar\s199\ql \fi-360\li720\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\ls32\adjustright\rin0\lin720\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 64-bit Mono support on Mac OS X (should just work, but needs building / testing) \par }\pard\plain \ltrpar\ql \li0\ri0\widctlpar\wrapdefault\nooverflow\faroman\rin0\lin0\itap0 \rtlch\fcs1 \af44\afs20\alang1025 \ltrch\fcs0 \f44\fs20\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 {\rtlch\fcs1 \af0 \ltrch\fcs0 \v\f37\cf6 \par }\pard\plain \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 \rtlch\fcs1 \af37\afs22\alang1025 \ltrch\fcs0 \f37\fs22\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 {\rtlch\fcs1 \af0 \ltrch\fcs0 \v\cf6 [Technical Notes]}{\rtlch\fcs1 \af0\afs20 \ltrch\fcs0 \i\v\fs20\cf6 \par }{\rtlch\fcs1 \af37 \ltrch\fcs0 \i\v\cf6 I think we made a mistake here. All of the capabilities that use TW_ARRAY containers only show TW_ONEVALUE as the valid container for MSG_SET. It should be TW_ONEVALUE and TW_ARRAY. \par }\pard\plain \ltrpar\ql \li0\ri0\widctlpar\wrapdefault\nooverflow\faroman\rin0\lin0\itap0 \rtlch\fcs1 \af44\afs20\alang1025 \ltrch\fcs0 \f44\fs20\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 {\rtlch\fcs1 \af0 \ltrch\fcs0 \v\f37\cf6 \par }\pard\plain \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 \rtlch\fcs1 \af37\afs22\alang1025 \ltrch\fcs0 \f37\fs22\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 {\rtlch\fcs1 \af0 \ltrch\fcs0 \v\cf6 [Technical Notes]}{\rtlch\fcs1 \af0\afs20 \ltrch\fcs0 \i\v\fs20\cf6 \par }{\rtlch\fcs1 \af37 \ltrch\fcs0 \i\v\cf6 I think we made a mistake here. All of the capabilities that use TW_ARRAY containers only show TW_ONEVALUE as the valid container for MSG_SET. It should be TW_ONEVALUE and TW_ARRAY. \par }{\rtlch\fcs1 \af37 \ltrch\fcs0 \i\cf6 \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\outlinelevel1\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 \b\ul {\*\bkmkstart _Toc45096545}V2.3.0.5 (19-Oct-2014)}{\rtlch\fcs1 \af37 \ltrch\fcs0 {\*\bkmkend _Toc45096545} \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 New Features: \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22 \hich\af37\dbch\af0\loch\f37 -\tab}}\pard \ltrpar\s199\ql \fi-360\li720\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\ls32\adjustright\rin0\lin720\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 (none) \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 Bug Fixes: \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22 \hich\af37\dbch\af0\loch\f37 -\tab}}\pard \ltrpar\s199\ql \fi-360\li720\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\ls32\adjustright\rin0\lin720\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 Closed Ticket #3: can\'b4t get capabilities; what can i get out of a_szMemref? \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22 \hich\af37\dbch\af0\loch\f37 -\tab}Closed Ticket #4: Setup Scanner does not work in twancsscan (dialog freezes) \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22 \hich\af37\dbch\af0\loch\f37 -\tab}Closed Ticket #5: Twain.DatParent - CloseDs should be CloseDsm \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22 \hich\af37\dbch\af0\loch\f37 -\tab}Figured out the message pump issue \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22 \hich\af37\dbch\af0\loch\f37 -\tab}Fixed SetImagePath to impact file transfers \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 Known Issues: \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22 \hich\af37\dbch\af0\loch\f37 -\tab}}\pard \ltrpar\s199\ql \fi-360\li720\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\ls32\adjustright\rin0\lin720\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 Runs rather slowly on Mac OS X \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22 \hich\af37\dbch\af0\loch\f37 -\tab}Setup Dialog sometimes freaks out on Mac OS X (looks like a race condition) \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22 \hich\af37\dbch\af0\loch\f37 -\tab}Only tested on Kodak Alaris products and the TWAIN Sample Data Source \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 Wish List: \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22 \hich\af37\dbch\af0\loch\f37 -\tab}}\pard \ltrpar\s199\ql \fi-360\li720\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\ls32\adjustright\rin0\lin720\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 Test with other vendors \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22 \hich\af37\dbch\af0\loch\f37 -\tab}64-bit Mono support on Mac OS X (should just work, but needs building / testing) \par }\pard\plain \ltrpar\ql \li0\ri0\widctlpar\wrapdefault\nooverflow\faroman\rin0\lin0\itap0 \rtlch\fcs1 \af44\afs20\alang1025 \ltrch\fcs0 \f44\fs20\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 {\rtlch\fcs1 \af0 \ltrch\fcs0 \v\f37\cf6 \par }\pard\plain \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 \rtlch\fcs1 \af37\afs22\alang1025 \ltrch\fcs0 \f37\fs22\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 {\rtlch\fcs1 \af0 \ltrch\fcs0 \v\cf6 [Technical Notes]}{\rtlch\fcs1 \af0\afs20 \ltrch\fcs0 \i\v\fs20\cf6 \par }{\rtlch\fcs1 \af37 \ltrch\fcs0 \i\v\cf6 I think we made a mistake here. All of the capabilities that use TW_ARRAY containers only show TW_ONEVALUE as the valid container for MSG_SET. It should be TW_ONEVALUE and TW_ARRAY. \par }{\rtlch\fcs1 \af37 \ltrch\fcs0 \i\cf6 \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\outlinelevel1\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 \b\ul {\*\bkmkstart _Toc45096546}V2.3.0.4 (13-Oct-2014)}{\rtlch\fcs1 \af37 \ltrch\fcs0 {\*\bkmkend _Toc45096546} \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 New Features: \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22 \hich\af37\dbch\af0\loch\f37 -\tab}}\pard \ltrpar\s199\ql \fi-360\li720\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\ls32\adjustright\rin0\lin720\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 Tracking the version number to the TWAIN Specification, so the major and minor will be the protocol value, the third number will call out major changes in the API within a version, and the fourth number will count minor changes to the API (like bug fixes) \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22 \hich\af37\dbch\af0\loch\f37 -\tab}Added logging (still some work to do on this) \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22 \hich\af37\dbch\af0\loch\f37 -\tab}Added auto JPEG/TIFF option for file transfers \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 Bug Fixes: \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22 \hich\af37\dbch\af0\loch\f37 -\tab}}\pard \ltrpar\s199\ql \fi-360\li720\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\ls32\adjustright\rin0\lin720\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 Fixed DAT_IMAGEMEMFILEXFER for Mac OS X \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 Known Issues: \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22 \hich\af37\dbch\af0\loch\f37 -\tab}}\pard \ltrpar\s199\ql \fi-360\li720\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\ls32\adjustright\rin0\lin720\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 Runs rather slowly on Mac OS X \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22 \hich\af37\dbch\af0\loch\f37 -\tab}Setup Dialog sometimes freaks out on Mac OS X (looks like a race condition) \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22 \hich\af37\dbch\af0\loch\f37 -\tab}Only tested on Kodak Alaris products and the TWAIN Sample Data Source \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 Wish List: \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22 \hich\af37\dbch\af0\loch\f37 -\tab}}\pard \ltrpar\s199\ql \fi-360\li720\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\ls32\adjustright\rin0\lin720\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 Test with other vendors \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22 \hich\af37\dbch\af0\loch\f37 -\tab}64-bit Mono support on Mac OS X (should just work, but needs testing) \par }\pard\plain \ltrpar\ql \li0\ri0\widctlpar\wrapdefault\nooverflow\faroman\rin0\lin0\itap0 \rtlch\fcs1 \af44\afs20\alang1025 \ltrch\fcs0 \f44\fs20\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 {\rtlch\fcs1 \af0 \ltrch\fcs0 \v\f37\cf6 \par }\pard\plain \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 \rtlch\fcs1 \af37\afs22\alang1025 \ltrch\fcs0 \f37\fs22\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 {\rtlch\fcs1 \af0 \ltrch\fcs0 \v\cf6 [Technical Notes]}{\rtlch\fcs1 \af0\afs20 \ltrch\fcs0 \i\v\fs20\cf6 \par }{\rtlch\fcs1 \af37 \ltrch\fcs0 \i\v\cf6 I think we made a mistake here. All of the capabilities that use TW_ARRAY containers only show TW_ONEVALUE as the valid container for MSG_SET. It should be TW_ONEVALUE and TW_ARRAY. \par }{\rtlch\fcs1 \af37 \ltrch\fcs0 \i\cf6 \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\outlinelevel1\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 \b\ul {\*\bkmkstart _Toc45096547}V2.2.0 (11-Jul-2014)}{\rtlch\fcs1 \af37 \ltrch\fcs0 {\*\bkmkend _Toc45096547} \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 New Features: \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22 \hich\af37\dbch\af0\loch\f37 -\tab}}\pard \ltrpar\s199\ql \fi-360\li720\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\ls32\adjustright\rin0\lin720\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 (none) \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 Bug Fixes: \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22 \hich\af37\dbch\af0\loch\f37 -\tab}}\pard \ltrpar\s199\ql \fi-360\li720\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\ls32\adjustright\rin0\lin720\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 Fixed DAT_IMAGEMEMFILEXFER \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 Known Issues: \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22 \hich\af37\dbch\af0\loch\f37 -\tab}}\pard \ltrpar\s199\ql \fi-360\li720\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\ls32\adjustright\rin0\lin720\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 Runs rather slowly on Mac OS X \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22 \hich\af37\dbch\af0\loch\f37 -\tab}Setup Dialog sometimes freaks out on Mac OS X (looks like a race condition) \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22 \hich\af37\dbch\af0\loch\f37 -\tab}Only tested on Kodak Alaris products and the TWAIN Sample Data Source \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 Wish List: \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22 \hich\af37\dbch\af0\loch\f37 -\tab}}\pard \ltrpar\s199\ql \fi-360\li720\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\ls32\adjustright\rin0\lin720\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 Test with other vendors \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22 \hich\af37\dbch\af0\loch\f37 -\tab}64-bit Mono support on Mac OS X (should just work, but needs testing) \par }\pard\plain \ltrpar\ql \li0\ri0\widctlpar\wrapdefault\nooverflow\faroman\rin0\lin0\itap0 \rtlch\fcs1 \af44\afs20\alang1025 \ltrch\fcs0 \f44\fs20\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 {\rtlch\fcs1 \af0 \ltrch\fcs0 \v\f31506\cf6 \par }\pard\plain \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 \rtlch\fcs1 \af37\afs22\alang1025 \ltrch\fcs0 \f37\fs22\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 {\rtlch\fcs1 \af0 \ltrch\fcs0 \v\f31506\cf6 [Technical Notes]}{\rtlch\fcs1 \af0\afs20 \ltrch\fcs0 \i\v\f31506\fs20\cf6 \par }{\rtlch\fcs1 \af37 \ltrch\fcs0 \i\v\f31506\cf6 I think we made a mistake here. All of the capabilities that use TW_ARRAY containers only show TW_ONEVALUE as the valid container for MSG_SET. It should be TW_ONEVALUE and TW_ARRAY. \par }{\rtlch\fcs1 \af37 \ltrch\fcs0 \i\f31506\cf6 \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\outlinelevel1\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 \b\ul {\*\bkmkstart _Toc45096548}V2.1.0 (09-Jul-2014)}{\rtlch\fcs1 \af37 \ltrch\fcs0 {\*\bkmkend _Toc45096548} \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 New Features: \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22 \hich\af37\dbch\af0\loch\f37 -\tab}}\pard \ltrpar\s199\ql \fi-360\li720\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\ls32\adjustright\rin0\lin720\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 ReportImage\rquote s bitmap no long locks access to the file \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 Bug Fixes: \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22 \hich\af37\dbch\af0\loch\f37 -\tab}}\pard \ltrpar\s199\ql \fi-360\li720\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\ls32\adjustright\rin0\lin720\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 Handles MSG_XFERREADY when issued from MSG_ENABLEDS \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 Known Issues: \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22 \hich\af37\dbch\af0\loch\f37 -\tab}}\pard \ltrpar\s199\ql \fi-360\li720\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\ls32\adjustright\rin0\lin720\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 Runs rather slowly on Mac OS X \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22 \hich\af37\dbch\af0\loch\f37 -\tab}Setup Dialog sometimes freaks out on Mac OS X (looks like a race condition) \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22 \hich\af37\dbch\af0\loch\f37 -\tab}Only tested on Kodak Alaris products and the TWAIN Sample Data Source \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 Wish List: \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22 \hich\af37\dbch\af0\loch\f37 -\tab}}\pard \ltrpar\s199\ql \fi-360\li720\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\ls32\adjustright\rin0\lin720\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 Test with other vendors \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22 \hich\af37\dbch\af0\loch\f37 -\tab}64-bit Mono support on Mac OS X (should just work, but needs testing) \par }\pard \ltrpar\s199\ql \li720\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin720\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\outlinelevel1\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 \b\f31506\ul {\*\bkmkstart _Toc45096549}V2.0.0 (21-May-2014)}{\rtlch\fcs1 \af37 \ltrch\fcs0 \f31506 {\*\bkmkend _Toc45096549} \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 \f31506 New Features: \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22 \hich\af37\dbch\af0\loch\f37 -\tab}}\pard \ltrpar\s199\ql \fi-360\li720\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\ls32\adjustright\rin0\lin720\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 \f31506 Support for 64-bit Linux (native only, 32-bit on 64-bit is too nasty) \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22 \hich\af37\dbch\af0\loch\f37 -\tab}ShowImage renamed to ReportImage \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 \f31506 Known Issues: \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22 \hich\af37\dbch\af0\loch\f37 -\tab}}\pard \ltrpar\s199\ql \fi-360\li720\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\ls32\adjustright\rin0\lin720\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 \f31506 Runs rather slowly on Mac OS X \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22 \hich\af37\dbch\af0\loch\f37 -\tab}Setup Dialog sometimes freaks out on Mac OS X (looks like a race condition) \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22 \hich\af37\dbch\af0\loch\f37 -\tab}Only tested on Kodak Alaris products \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 \f31506 Wish List: \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22 \hich\af37\dbch\af0\loch\f37 -\tab}}\pard \ltrpar\s199\ql \fi-360\li720\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\ls32\adjustright\rin0\lin720\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 \f31506 Test with other vendors \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22 \hich\af37\dbch\af0\loch\f37 -\tab}64-bit Mono support on Mac OS X (should just work, but needs testing) \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 \i\cf6 \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\outlinelevel1\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 \b\ul {\*\bkmkstart _Toc45096550}V1.1.0 (27-Feb-2014)}{\rtlch\fcs1 \af37 \ltrch\fcs0 {\*\bkmkend _Toc45096550} \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 New Features: \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22 \hich\af37\dbch\af0\loch\f37 -\tab}}\pard \ltrpar\s199\ql \fi-360\li720\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\ls32\adjustright\rin0\lin720\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 Additional arguments in ShowImage \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22 \hich\af37\dbch\af0\loch\f37 -\tab}Code example of CAP_INDICATORS in TWAINCSScan \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22 \hich\af37\dbch\af0\loch\f37 -\tab}Fixed projects to handle conditional references \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22 \hich\af37\dbch\af0\loch\f37 -\tab}Added AnyCPU support \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 Known Issues: \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22 \hich\af37\dbch\af0\loch\f37 -\tab}}\pard \ltrpar\s199\ql \fi-360\li720\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\ls32\adjustright\rin0\lin720\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 Runs rather slowly on Mac OS X \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22 \hich\af37\dbch\af0\loch\f37 -\tab}Setup Dialog sometimes freaks out on Mac OS X (looks like a race condition) \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22 \hich\af37\dbch\af0\loch\f37 -\tab}Only tested on Kodak Alaris products \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 Wish List: \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22 \hich\af37\dbch\af0\loch\f37 -\tab}}\pard \ltrpar\s199\ql \fi-360\li720\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\ls32\adjustright\rin0\lin720\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 Test with other vendors \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22 \hich\af37\dbch\af0\loch\f37 -\tab}64-bit Mono support on Linux and Mac OS X \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 \i\cf6 \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\outlinelevel1\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 \b\ul {\*\bkmkstart _Toc45096551}V1.0.0 (05-Nov-2013)}{\rtlch\fcs1 \af37 \ltrch\fcs0 {\*\bkmkend _Toc45096551} \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 New Features: \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22 \hich\af37\dbch\af0\loch\f37 -\tab}}\pard \ltrpar\s199\ql \fi-360\li720\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\ls32\adjustright\rin0\lin720\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 Initial release \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 Known Issues: \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22 \hich\af37\dbch\af0\loch\f37 -\tab}}\pard \ltrpar\s199\ql \fi-360\li720\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\ls32\adjustright\rin0\lin720\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 Runs rather slowly on Mac OS X \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22 \hich\af37\dbch\af0\loch\f37 -\tab}Setup Dialog sometimes freaks out on Mac OS X (looks like a race condition) \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22 \hich\af37\dbch\af0\loch\f37 -\tab}Only tested on Kodak Alaris products \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 Wish List: \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22 \hich\af37\dbch\af0\loch\f37 -\tab}}\pard \ltrpar\s199\ql \fi-360\li720\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\ls32\adjustright\rin0\lin720\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 Test with other vendors \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22 \hich\af37\dbch\af0\loch\f37 -\tab}64-bit Mono support on Linux and Mac OS X}{\rtlch\fcs1 \af45 \ltrch\fcs0 \f31506 \par }\pard\plain \ltrpar\s189\ql \li0\ri0\keepn\widctlpar\brdrt\brdrs\brdrw30\brsp120 \wrapdefault\nooverflow\faroman\outlinelevel0\rin0\lin0\itap0 \rtlch\fcs1 \ab\af1\afs24\alang1025 \ltrch\fcs0 \b\f1\fs24\cf9\lang1024\langfe1024\cgrid\noproof\langnp1033\langfenp1033 {\rtlch\fcs1 \af1 \ltrch\fcs0 \v\f31506\noproof0 {\*\bkmkend _Toc234021027}General Comments }{\rtlch\fcs1 \af1 \ltrch\fcs0 \v\f31506\cf6\noproof0 [DONE]}{\rtlch\fcs1 \af1 \ltrch\fcs0 \v\f31506\noproof0 \par }\pard\plain \ltrpar\ql \li0\ri0\widctlpar\wrapdefault\nooverflow\faroman\rin0\lin0\itap0 \rtlch\fcs1 \af44\afs20\alang1025 \ltrch\fcs0 \f44\fs20\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 {\rtlch\fcs1 \af0 \ltrch\fcs0 \v\f31506\cf6 \par }\pard\plain \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 \rtlch\fcs1 \af37\afs22\alang1025 \ltrch\fcs0 \f37\fs22\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 {\rtlch\fcs1 \af0 \ltrch\fcs0 \v\f31506\cf6 [Technical Notes]}{\rtlch\fcs1 \af0\afs20 \ltrch\fcs0 \i\v\f31506\fs20\cf6 \par These are areas of discussion which may or may not lead to changes in the TWAIN Specification. If changes do result, they\rquote ll be moved into their own area. There are no Update Instructions in this section. When we\rquote re done with it, it \rquote ll be moved to the end of the document and given a status of \'93DONE\'94\'85 \par }\pard\plain \ltrpar\ql \li0\ri0\widctlpar\wrapdefault\nooverflow\faroman\rin0\lin0\itap0 \rtlch\fcs1 \af44\afs20\alang1025 \ltrch\fcs0 \f44\fs20\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 {\rtlch\fcs1 \af0 \ltrch\fcs0 \v\f31506 \par \par }{\rtlch\fcs1 \af0 \ltrch\fcs0 \v\f31506\cf6 [Note] \endash DONE \par }\pard \ltrpar\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af0\afs22 \ltrch\fcs0 \i\v\f31506\fs22 Does a Boolean enumeration have an expected order to the TRUE/FALSE values in the list? \par 8-22 (hunt this down and fix it) \par We don\rquote t want the values ordered, except in the context where the order impacts the UI, but there is no way to know if this is happening or not\'85 \par }\pard \ltrpar\ql \li0\ri0\widctlpar\wrapdefault\faauto\rin0\lin0\itap0 {\rtlch\fcs1 \af45 \ltrch\fcs0 \v\f31506 Stores a group of individual values describing a capability. The values are ordered from lowest to \par highest values, but the step size between each value is probably not uniform. Such a list would be \par useful to describe the discreet resolutions of a capture device supporting, say, 75, 150, 300, 400, \par }\pard \ltrpar\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af45 \ltrch\fcs0 \v\f31506 and 800 dots per inch.}{\rtlch\fcs1 \af0\afs22 \ltrch\fcs0 \i\v\f31506\fs22 \par \par {\listtext\pard\plain\ltrpar \rtlch\fcs1 \af0\afs22 \ltrch\fcs0 \v\fs22 \hich\af0\dbch\af0\loch\f0 -\tab}}\pard \ltrpar\ql \fi-360\li720\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\ls31\adjustright\rin0\lin720\itap0 {\rtlch\fcs1 \af0\afs22 \ltrch\fcs0 \i\v\f31506\fs22 No, there is no required order for items in an enumeration or an array. Ideally the Data Source would maintain the order of items send to it, and display the items in that order in the GUI, but I don\rquote t believe there is anything in the Specification that even suggests that much. \par }\pard \ltrpar\ql \li0\ri0\widctlpar\wrapdefault\nooverflow\faroman\rin0\lin0\itap0 {\rtlch\fcs1 \af0 \ltrch\fcs0 \v\f31506 \par \par }{\rtlch\fcs1 \af0 \ltrch\fcs0 \v\f31506\cf6 [Note] \endash DONE \par }\pard \ltrpar\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af0\afs22 \ltrch\fcs0 \i\v\f31506\fs22 In particular, I was working on ICAP_BITDEPTH. If a Data Source only supports a single bitdepth for each specific pixeltype, wouldn\rquote t it make sense to respond that SET and RESET are not supported? There would be no reason to do a set of Bitdepth, since only a single value is supported at a time. \par \par {\listtext\pard\plain\ltrpar \rtlch\fcs1 \af0\afs22 \ltrch\fcs0 \v\fs22 \hich\af0\dbch\af0\loch\f0 -\tab}}\pard \ltrpar\ql \fi-360\li720\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\ls31\adjustright\rin0\lin720\itap0 {\rtlch\fcs1 \af0\afs22 \ltrch\fcs0 \i\v\f31506\fs22 I wonder if there should be a paragraph on this matter. Here\rquote s my take on it. Applications tend to do one of two things when confronted by an error: they ignore it or they fail (sometimes they crash). With tha t in mind a driver should always avoid returning an error if it has a valid alternative that allows it to return success instead. Therefore, MSG_RESET and MSG_SET should always be allowed for capabilities that support a single value, except in those cas es where the Specification makes it clear that the value is read only (like CAP_DEVICEONLINE). \par }\pard \ltrpar\ql \li0\ri0\widctlpar\wrapdefault\nooverflow\faroman\rin0\lin0\itap0 {\rtlch\fcs1 \af0 \ltrch\fcs0 \v\f31506 \par \par }{\rtlch\fcs1 \af0 \ltrch\fcs0 \v\f31506\cf6 [Note] \endash DONE \par }\pard \ltrpar\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af0\afs22 \ltrch\fcs0 \i\v\f31506\fs22 Also regarding ICAP_BITDEPTH, am I correct in understanding that a MSG_GET for this capability should only report the available values based on the current setting for PIXELTYPE? Ie. Don\rquote t report all the bitdepths supported, only those supported for the current pixel type? \par \par {\listtext\pard\plain\ltrpar \rtlch\fcs1 \af0\afs22 \ltrch\fcs0 \v\fs22 \hich\af0\dbch\af0\loch\f0 -\tab}}\pard \ltrpar\ql \fi-360\li720\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\ls31\adjustright\rin0\lin720\itap0 {\rtlch\fcs1 \af0\afs22 \ltrch\fcs0 \i\v\f31506\fs22 This is correct. We know that some drivers show all of the bitdepth values for all of the supported pixeltypes. It doesn\rquote t look like we have a comment on this in the Legacy Issues section (3-39, PDF 71). \par {\listtext\pard\plain\ltrpar \rtlch\fcs1 \af0\afs22 \ltrch\fcs0 \v\fs22 \hich\af0\dbch\af0\loch\f0 -\tab}Add a test to the self cert to watch out for this\'85 (this has been added to the Proposed Changes doc) \par }\pard \ltrpar\ql \li0\ri0\widctlpar\wrapdefault\nooverflow\faroman\rin0\lin0\itap0 {\rtlch\fcs1 \af0 \ltrch\fcs0 \v\f31506 \par \par }{\rtlch\fcs1 \af0 \ltrch\fcs0 \v\f31506\cf6 \page [Note] \endash DONE \par }\pard \ltrpar\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af0\afs22 \ltrch\fcs0 \i\v\f31506\fs22 I have a question regarding the filename extension used in a File Transfer. The filename is provided in the DG_CONTROL/DAT_SETUPFILEXFER/MSG_SET message. Do I need to make sure the requested filename extension matches the type of the file I end up creating? \par }{\rtlch\fcs1 \af0\afs22 \ltrch\fcs0 \v\f31506\fs22 \par A couple of examples: \par {\listtext\pard\plain\ltrpar \rtlch\fcs1 \af0\afs22 \ltrch\fcs0 \v\f37\fs22\cf22 \hich\af37\dbch\af0\loch\f37 1)\tab}}\pard \ltrpar\ql \fi-360\li720\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\ls30\adjustright\rin0\lin720\itap0 {\rtlch\fcs1 \af0\afs22 \ltrch\fcs0 \v\f31506\fs22 Simple case: if \'93filexfer.tmp\'94 is requested, I\rquote m guessing I should use the file extension as requested regardless of file type that I create. (ie. Even though I save a tiff/jpg/bmp etc. file, continue using the .tmp extention) Is this correct? \par {\listtext\pard\plain\ltrpar \rtlch\fcs1 \af0\afs22 \ltrch\fcs0 \v\f37\fs22\cf22 \hich\af37\dbch\af0\loch\f37 2)\tab}More complex case: Assume I\rquote m doing auto color detect, and my non-color will be mapped to BW. If \'93filexfer.jpg\'94 is requested and I detect a non-color image, this will be an *}{\rtlch\fcs1 \ab\af0\afs22 \ltrch\fcs0 \b\v\f31506\fs22 incorrect}{\rtlch\fcs1 \af0\afs22 \ltrch\fcs0 \v\f31506\fs22 * name in the end since I cannot save a BW image as a JPG file. I will cr eate a BMP file instead. Should I change the requested filename to \'93filexfer.bmp\'94 in this case? Or still use the filename as requested even though it gives the wrong impression of filetype? \par }\pard \ltrpar\ql \li360\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin360\itap0 {\rtlch\fcs1 \af0\afs22 \ltrch\fcs0 \v\f31506\fs22 \par }\pard \ltrpar\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af0\afs22 \ltrch\fcs0 \v\f31506\fs22 If I don\rquote t use the filename exactly as requested, does the TWAIN app think the transfer failed? They really have no way to know what I saved it as if I make a change, so it seems the filename better not change, even in the case that it is incorrect. \par \par Do you know of some TWAIN apps that use FileXfer that I could try this with? \par \par {\listtext\pard\plain\ltrpar \rtlch\fcs1 \af0\afs22 \ltrch\fcs0 \v\fs22 \hich\af0\dbch\af0\loch\f0 -\tab}}\pard \ltrpar\ql \fi-360\li720\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\ls31\adjustright\rin0\lin720\itap0 {\rtlch\fcs1 \af0\afs22 \ltrch\fcs0 \v\f31506\fs22 TWAIN doesn\rquote t recommend or enforce filename extensions for TWFF_* file formats. This means that someone could produce a ridiculous result (like image.bmp for a JPEG image), but that\rquote s okay, because application writers are free to use whatever naming system they need. \par }\pard \ltrpar\ql \li720\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin720\itap0 {\rtlch\fcs1 \af0\afs22 \ltrch\fcs0 \v\f31506\fs22 \par {\listtext\pard\plain\ltrpar \rtlch\fcs1 \af0\afs22 \ltrch\fcs0 \v\fs22 \hich\af0\dbch\af0\loch\f0 -\tab}}\pard \ltrpar\ql \fi-360\li720\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\ls31\adjustright\rin0\lin720\itap0 {\rtlch\fcs1 \af0\afs22 \ltrch\fcs0 \v\f31506\fs22 The only time a file transfer should fail is in situations where the application\rquote s request can\rquote t be met. For example, if TWFF_JFIF is requested for a TWPT_BW TWCP_GROUP4 compressed image. \par }\pard\plain \ltrpar\s199\ql \li720\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin720\itap0 \rtlch\fcs1 \af37\afs22\alang1025 \ltrch\fcs0 \f37\fs22\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 {\rtlch\fcs1 \af0 \ltrch\fcs0 \v\f31506 \par {\listtext\pard\plain\ltrpar \rtlch\fcs1 \af0\afs22 \ltrch\fcs0 \v\fs22 \hich\af0\dbch\af0\loch\f0 -\tab}}\pard\plain \ltrpar\ql \fi-360\li720\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\ls31\adjustright\rin0\lin720\itap0 \rtlch\fcs1 \af44\afs20\alang1025 \ltrch\fcs0 \f44\fs20\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 {\rtlch\fcs1 \af0\afs22 \ltrch\fcs0 \v\f31506\fs22 Note that DAT_IMAGEFILEXFER is still c onsidered optional, so few drivers support it. It was designed as a low memory transfer option, since the driver is able to transfer the image directly to disk. Most application choose to do this themselves, and using DAT_IMAGEMEMXFER can achieve result s that require little memory, though an extra step is often needed to create the finished file, since the metadata that describes the image isn\rquote t available until state 7. \par }\pard\plain \ltrpar\s199\ql \li720\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin720\itap0 \rtlch\fcs1 \af37\afs22\alang1025 \ltrch\fcs0 \f37\fs22\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 {\rtlch\fcs1 \af0 \ltrch\fcs0 \v\f31506 \par {\listtext\pard\plain\ltrpar \rtlch\fcs1 \af0\afs22 \ltrch\fcs0 \v\fs22 \hich\af0\dbch\af0\loch\f0 -\tab}}\pard\plain \ltrpar\ql \fi-360\li720\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\ls31\adjustright\rin0\lin720\itap0 \rtlch\fcs1 \af44\afs20\alang1025 \ltrch\fcs0 \f44\fs20\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 {\rtlch\fcs1 \af0\afs22 \ltrch\fcs0 \v\f31506\fs22 I don\rquote t know of any commonly used TWAIN applications that use DAT_IMAGEFILEXFER. \par }\pard \ltrpar\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \v\f31506\fs22\cf22 \par }\pard \ltrpar\ql \li0\ri0\sb180\widctlpar\wrapdefault\nooverflow\faroman\rin0\lin0\itap0 {\rtlch\fcs1 \af0 \ltrch\fcs0 \v\f31506 \page \par }\pard \ltrpar\ql \li0\ri0\widctlpar\wrapdefault\nooverflow\faroman\rin0\lin0\itap0 {\rtlch\fcs1 \af0 \ltrch\fcs0 \v\f31506\cf6 [Note] \endash DONE \par }\pard \ltrpar\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af0\afs22 \ltrch\fcs0 \v\f31506\fs22 For capabilities (ch.10 pages), if MSG_GET supports both TW_ONEVALUE and TW_ENUMERATION; should MSG_SET support both as well? Nowhere does the spec include TW_ ENUMERATION as a valid set container, but I think this is allowed. \par \par Oh....ICAP_HALFTONETYPES is the only cap I found that lists TW_ENUMERATION as a SET Container type. \par \par Do I correctly understand that you could replace MSG_SET with MSG_SETCONSTRAINT, and never use MSG_SET anymore? Ie. If sending a TW_ONEVALUE or TW_ARRAY via the MSG_SETCONSTRAINT, this is equivalent to the MSG_SET functionality. \par \par {\listtext\pard\plain\ltrpar \rtlch\fcs1 \af0\afs22 \ltrch\fcs0 \v\fs22 \hich\af0\dbch\af0\loch\f0 -\tab}}\pard \ltrpar\ql \fi-360\li720\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\ls31\adjustright\rin0\lin720\itap0 {\rtlch\fcs1 \af0\afs22 \ltrch\fcs0 \v\f31506\fs22 I can say with confidence that this part of the Spec hasn\rquote t exactly turned out as planned. The intention was to separate setting values from setting constraints. However, I woul d always expect that one can call MSG_GET, MSG_GETCURRENT and take the result and pass it into MSG_SET. The difference is that if both the application and the driver report themselves as 2.2 or higher the driver only takes the value from MSG_SET. \par }\pard \ltrpar\ql \li360\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin360\itap0 {\rtlch\fcs1 \af0\afs22 \ltrch\fcs0 \v\f31506\fs22 \par {\listtext\pard\plain\ltrpar \rtlch\fcs1 \af0\afs22 \ltrch\fcs0 \v\fs22 \hich\af0\dbch\af0\loch\f0 -\tab}}\pard \ltrpar\ql \fi-360\li720\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\ls31\adjustright\rin0\lin720\itap0 {\rtlch\fcs1 \af0\afs22 \ltrch\fcs0 \v\f31506\fs22 The situation as described means that MSG_GET cannot be used as the input to MSG_SET. I think that results in too much work for applications and drivers, given the radical departure from previous behavior. \par }\pard\plain \ltrpar\s199\ql \li720\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin720\itap0 \rtlch\fcs1 \af37\afs22\alang1025 \ltrch\fcs0 \f37\fs22\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 {\rtlch\fcs1 \af0 \ltrch\fcs0 \v\f31506 \par {\listtext\pard\plain\ltrpar \rtlch\fcs1 \af0\afs22 \ltrch\fcs0 \v\fs22 \hich\af0\dbch\af0\loch\f0 -\tab}}\pard\plain \ltrpar\ql \fi-360\li720\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\ls31\adjustright\rin0\lin720\itap0 \rtlch\fcs1 \af44\afs20\alang1025 \ltrch\fcs0 \f44\fs20\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 {\rtlch\fcs1 \af0\afs22 \ltrch\fcs0 \v\f31506\fs22 Using TW_ONEVALUE with MSG_SETCONTRAINT should cons train the capability to that one value. Also, the value is always set with MSG_SETCONTRAINT. \par }\pard \ltrpar\ql \li720\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin720\itap0 {\rtlch\fcs1 \af0\afs22 \ltrch\fcs0 \v\f31506\fs22 \par {\listtext\pard\plain\ltrpar \rtlch\fcs1 \af0\afs22 \ltrch\fcs0 \v\fs22 \hich\af0\dbch\af0\loch\f0 -\tab}}\pard \ltrpar\ql \fi-360\li720\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\ls31\adjustright\rin0\lin720\itap0 {\rtlch\fcs1 \af0\afs22 \ltrch\fcs0 \v\f31506\fs22 Therefore, we need to make sure that the Spec clearly explains the difference between MSG_SET and MSG_SETCONTRAINT, and then make sure that for all capabilitie s the allowed containers for both MSG_SET and MSG_SETCONSTRAINT are identical. \par }\pard\plain \ltrpar\s199\ql \li720\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin720\itap0 \rtlch\fcs1 \af37\afs22\alang1025 \ltrch\fcs0 \f37\fs22\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 {\rtlch\fcs1 \af0 \ltrch\fcs0 \v\f31506 \par {\listtext\pard\plain\ltrpar \rtlch\fcs1 \af0\afs22 \ltrch\fcs0 \v\fs22 \hich\af0\dbch\af0\loch\f0 -\tab}}\pard\plain \ltrpar\ql \fi-360\li720\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\ls31\adjustright\rin0\lin720\itap0 \rtlch\fcs1 \af44\afs20\alang1025 \ltrch\fcs0 \f44\fs20\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 {\rtlch\fcs1 \af0\afs22 \ltrch\fcs0 \v\f31506\fs22 I\rquote m pretty sure that Self-Cert will support this change (meaning that it assumes that a MSG_GET can always be followed by a MSG_SET). I\rquote d be very surprised if anybody changed the behavior of MSG_SET without asking us what we\rquote re thinking... \par }\pard\plain \ltrpar\s199\ql \li720\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin720\itap0 \rtlch\fcs1 \af37\afs22\alang1025 \ltrch\fcs0 \f37\fs22\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 {\rtlch\fcs1 \af0 \ltrch\fcs0 \v\f31506 \par {\listtext\pard\plain\ltrpar \rtlch\fcs1 \af0\afs22 \ltrch\fcs0 \v\fs22 \hich\af0\dbch\af0\loch\f0 -\tab}}\pard\plain \ltrpar\ql \fi-360\li720\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\ls31\adjustright\rin0\lin720\itap0 \rtlch\fcs1 \af44\afs20\alang1025 \ltrch\fcs0 \f44\fs20\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 {\rtlch\fcs1 \af0\afs22 \ltrch\fcs0 \v\f31506\fs22 MSG_SET will only impact the current value\'85 \par }\pard \ltrpar\ql \li0\ri0\sb180\widctlpar\wrapdefault\nooverflow\faroman\rin0\lin0\itap0 {\rtlch\fcs1 \af0 \ltrch\fcs0 \v\f31506 \par }\pard \ltrpar\ql \li0\ri0\widctlpar\wrapdefault\nooverflow\faroman\rin0\lin0\itap0 {\rtlch\fcs1 \af0 \ltrch\fcs0 \v\f31506\cf6 \page [Note] \endash DONE \par }\pard \ltrpar\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af0\afs22 \ltrch\fcs0 \v\f31506\fs22 ICAP_XFERMECH (ch. 10, pg. 10-197): under Application section it reads, \'93 The current value of ICAP_XFERMECH must match the data argument type when starting the transfer using the triplet: DG_IMAGE / DAT_IMAGExxxxXFER / MSG_GET.\'94 If it does not match, what should happen? \par (NOTE: already discussed in the working group meeting on 17 July 2012) \par \par {\listtext\pard\plain\ltrpar \rtlch\fcs1 \af0\afs22 \ltrch\fcs0 \v\fs22 \hich\af0\dbch\af0\loch\f0 -\tab}}\pard \ltrpar\ql \fi-360\li720\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\ls31\adjustright\rin0\lin720\itap0 {\rtlch\fcs1 \af0\afs22 \ltrch\fcs0 \v\f31506\fs22 My recollection from the meeting is as follows: \par }\pard \ltrpar\ql \li720\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin720\itap0 {\rtlch\fcs1 \af0\afs22 \ltrch\fcs0 \v\f31506\fs22 \par {\listtext\pard\plain\ltrpar \rtlch\fcs1 \af0\afs22 \ltrch\fcs0 \v\fs22 \hich\af0\dbch\af0\loch\f0 -\tab}}\pard \ltrpar\ql \fi-360\li720\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\ls31\adjustright\rin0\lin720\itap0 {\rtlch\fcs1 \af0\afs22 \ltrch\fcs0 \v\f31506\fs22 The TWAIN Spec says that apps need to set ICAP_XFERMECH in state 4 to the transfer mechanism that\rquote ll be used in state 6 and 7. However, some apps don\rquote t bother to do this. \par }\pard\plain \ltrpar\s199\ql \li720\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin720\itap0 \rtlch\fcs1 \af37\afs22\alang1025 \ltrch\fcs0 \f37\fs22\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 {\rtlch\fcs1 \af0 \ltrch\fcs0 \v\f31506 \par {\listtext\pard\plain\ltrpar \rtlch\fcs1 \af0\afs22 \ltrch\fcs0 \v\fs22 \hich\af0\dbch\af0\loch\f0 -\tab}}\pard\plain \ltrpar\ql \fi-360\li720\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\ls31\adjustright\rin0\lin720\itap0 \rtlch\fcs1 \af44\afs20\alang1025 \ltrch\fcs0 \f44\fs20\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 {\rtlch\fcs1 \af0\afs22 \ltrch\fcs0 \v\f31506\fs22 The thought is to leave the requirement intact, but add a bit to the Legacy Issues section warning driver writers not to assume this will happen. \par }\pard \ltrpar\ql \li0\ri0\sb180\widctlpar\wrapdefault\nooverflow\faroman\rin0\lin0\itap0 {\rtlch\fcs1 \af0 \ltrch\fcs0 \v\f31506 \par }\pard \ltrpar\ql \li0\ri0\widctlpar\wrapdefault\nooverflow\faroman\rin0\lin0\itap0 {\rtlch\fcs1 \af0 \ltrch\fcs0 \v\f31506\cf6 [Note] \endash DONE \par }\pard \ltrpar\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af0\afs22 \ltrch\fcs0 \v\f31506\fs22 (ch. 2, pg. 2-16) I think a couple of string types are missing. It says: \'93There are }{\rtlch\fcs1 \af0\afs22 \ltrch\fcs0 \v\f31506\fs22\ul four}{\rtlch\fcs1 \af0\afs22 \ltrch\fcs0 \v\f31506\fs22 types of TWAIN strings defined for developer use:\'94 , and then lists TW_STR32, TW_STR64, TW_STR128, and TW_STR256. But in twain.h, there are now TW_STR1024 and a TW_UNI512 types defined. Should these be added, for a total of 6? \par {\listtext\pard\plain\ltrpar \rtlch\fcs1 \af0\afs20 \ltrch\fcs0 \v\fs20 \hich\af0\dbch\af0\loch\f0 -\tab}}\pard \ltrpar\ql \fi-360\li720\ri0\sb180\widctlpar\wrapdefault\nooverflow\faroman\ls31\rin0\lin720\itap0 {\rtlch\fcs1 \af0 \ltrch\fcs0 \v\f31506 TW_STR1024 and TW_UNI512 have been deprecated, so the number \lquote four\rquote is right.}{\rtlch\fcs1 \ab\af0\afs22 \ltrch\fcs0 \b\v\f31506\fs22 \par }\pard \ltrpar\ql \li0\ri0\sb180\widctlpar\wrapdefault\nooverflow\faroman\rin0\lin0\itap0 {\rtlch\fcs1 \af0 \ltrch\fcs0 \v\f31506 \par }\pard \ltrpar\ql \li0\ri0\widctlpar\wrapdefault\nooverflow\faroman\rin0\lin0\itap0 {\rtlch\fcs1 \af0 \ltrch\fcs0 \v\f31506\cf6 [Note] \endash DONE \par }\pard \ltrpar\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \v\f31506\fs22 Do I understand correctly that MSG_GETDEFAULT should return the Source\rquote s *}{\rtlch\fcs1 \ab\af37\afs22 \ltrch\fcs0 \b\v\f31506\fs22 Preferred}{\rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \v\f31506\fs22 * default. But this may *}{\rtlch\fcs1 \ab\af37\afs22 \ltrch\fcs0 \b\v\f31506\fs22 not}{\rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \v\f31506\fs22 * be the value set when calling MSG_RESET, since MSG_RESET resets to the TWAIN default? If there is a Mandatory default, does MSG_GETDEFAULT need to return the mandatory default? \par }\pard \ltrpar\ql \li0\ri0\sb180\widctlpar\wrapdefault\nooverflow\faroman\rin0\lin0\itap0 {\rtlch\fcs1 \af0 \ltrch\fcs0 \v\f31506 \par }\pard \ltrpar\ql \li0\ri0\widctlpar\wrapdefault\nooverflow\faroman\rin0\lin0\itap0 {\rtlch\fcs1 \af0 \ltrch\fcs0 \v\f31506\cf6 [Note] \endash DONE \par }\pard \ltrpar\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \v\f31506\fs22 So is MSG_RESET meant to reset to the value listed in Ch. 10 always? (whether or not this is a mandatory default) Only if Ch. 10 says \'93no default\'94 can the source reset it to a preferred or user value? \par }\pard\plain \ltrpar\s199\ql \li360\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin360\itap0 \rtlch\fcs1 \af37\afs22\alang1025 \ltrch\fcs0 \f37\fs22\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 {\rtlch\fcs1 \af37 \ltrch\fcs0 \i\v\f31506\cf6 \par }\pard\plain \ltrpar\ql \li720\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin720\itap0 \rtlch\fcs1 \af44\afs20\alang1025 \ltrch\fcs0 \f44\fs20\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 {\rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \v\f31506\fs22\cf23 \par }{\*\themedata 504b030414000600080000002100e9de0fbfff0000001c020000130000005b436f6e74656e745f54797065735d2e786d6cac91cb4ec3301045f748fc83e52d4a 9cb2400825e982c78ec7a27cc0c8992416c9d8b2a755fbf74cd25442a820166c2cd933f79e3be372bd1f07b5c3989ca74aaff2422b24eb1b475da5df374fd9ad 5689811a183c61a50f98f4babebc2837878049899a52a57be670674cb23d8e90721f90a4d2fa3802cb35762680fd800ecd7551dc18eb899138e3c943d7e503b6 b01d583deee5f99824e290b4ba3f364eac4a430883b3c092d4eca8f946c916422ecab927f52ea42b89a1cd59c254f919b0e85e6535d135a8de20f20b8c12c3b0 0c895fcf6720192de6bf3b9e89ecdbd6596cbcdd8eb28e7c365ecc4ec1ff1460f53fe813d3cc7f5b7f020000ffff0300504b030414000600080000002100a5d6 a7e7c0000000360100000b0000005f72656c732f2e72656c73848fcf6ac3300c87ef85bd83d17d51d2c31825762fa590432fa37d00e1287f68221bdb1bebdb4f c7060abb0884a4eff7a93dfeae8bf9e194e720169aaa06c3e2433fcb68e1763dbf7f82c985a4a725085b787086a37bdbb55fbc50d1a33ccd311ba548b6309512 0f88d94fbc52ae4264d1c910d24a45db3462247fa791715fd71f989e19e0364cd3f51652d73760ae8fa8c9ffb3c330cc9e4fc17faf2ce545046e37944c69e462 a1a82fe353bd90a865aad41ed0b5b8f9d6fd010000ffff0300504b0304140006000800000021006b799616830000008a0000001c0000007468656d652f746865 6d652f7468656d654d616e616765722e786d6c0ccc4d0ac3201040e17da17790d93763bb284562b2cbaebbf600439c1a41c7a0d29fdbd7e5e38337cedf14d59b 4b0d592c9c070d8a65cd2e88b7f07c2ca71ba8da481cc52c6ce1c715e6e97818c9b48d13df49c873517d23d59085adb5dd20d6b52bd521ef2cdd5eb9246a3d8b 4757e8d3f729e245eb2b260a0238fd010000ffff0300504b03041400060008000000210096b5ade296060000501b0000160000007468656d652f7468656d652f 7468656d65312e786d6cec594f6fdb3614bf0fd87720746f6327761a07758ad8b19b2d4d1bc46e871e698996d850a240d2497d1bdae38001c3ba618715d86d87 615b8116d8a5fb34d93a6c1dd0afb0475292c5585e9236d88aad3e2412f9e3fbff1e1fa9abd7eec70c1d1221294fda5efd72cd4324f1794093b0eddd1ef62fad 79482a9c0498f184b4bd2991deb58df7dfbb8ad755446282607d22d771db8b944ad79796a40fc3585ee62949606ecc458c15bc8a702910f808e8c66c69b9565b 5d8a314d3c94e018c8de1a8fa94fd05093f43672e23d06af89927ac06762a049136785c10607758d9053d965021d62d6f6804fc08f86e4bef210c352c144dbab 999fb7b4717509af678b985ab0b6b4ae6f7ed9ba6c4170b06c788a705430adf71bad2b5b057d03606a1ed7ebf5babd7a41cf00b0ef83a6569632cd467faddec9 699640f6719e76b7d6ac355c7c89feca9cccad4ea7d36c65b258a206641f1b73f8b5da6a6373d9c11b90c537e7f08dce66b7bbeae00dc8e257e7f0fd2badd586 8b37a088d1e4600ead1ddaef67d40bc898b3ed4af81ac0d76a197c86826828a24bb318f3442d8ab518dfe3a20f000d6458d104a9694ac6d88728eee2782428d6 0cf03ac1a5193be4cbb921cd0b495fd054b5bd0f530c1931a3f7eaf9f7af9e3f45c70f9e1d3ff8e9f8e1c3e3073f5a42ceaa6d9c84e5552fbffdeccfc71fa33f 9e7ef3f2d117d57859c6fffac327bffcfc793510d26726ce8b2f9ffcf6ecc98baf3efdfdbb4715f04d814765f890c644a29be408edf3181433567125272371be 15c308d3f28acd249438c19a4b05fd9e8a1cf4cd296699771c393ac4b5e01d01e5a30a787d72cf1178108989a2159c77a2d801ee72ce3a5c545a6147f32a9979 3849c26ae66252c6ed637c58c5bb8b13c7bfbd490a75330f4b47f16e441c31f7184e140e494214d273fc80900aedee52ead87597fa824b3e56e82e451d4c2b4d 32a423279a668bb6690c7e9956e90cfe766cb37b077538abd27a8b1cba48c80acc2a841f12e698f13a9e281c57911ce298950d7e03aba84ac8c154f8655c4f2a f074481847bd804859b5e696007d4b4edfc150b12addbecba6b18b148a1e54d1bc81392f23b7f84137c2715a851dd0242a633f900710a218ed715505dfe56e86 e877f0034e16bafb0e258ebb4faf06b769e888340b103d3311da9750aa9d0a1cd3e4efca31a3508f6d0c5c5c398602f8e2ebc71591f5b616e24dd893aa3261fb 44f95d843b5974bb5c04f4edafb95b7892ec1108f3f98de75dc97d5772bdff7cc95d94cf672db4b3da0a6557f70db629362d72bcb0431e53c6066acac80d699a 6409fb44d08741bdce9c0e4971624a2378cceaba830b05366b90e0ea23aaa241845368b0eb9e2612ca8c742851ca251ceccc70256d8d87265dd96361531f186c 3d9058edf2c00eafe8e1fc5c509031bb4d680e9f39a3154de0accc56ae644441edd76156d7429d995bdd88664a9dc3ad50197c38af1a0c16d684060441db0256 5e85f3b9660d0713cc48a0ed6ef7dedc2dc60b17e92219e180643ed27acffba86e9c94c78ab90980d8a9f0913ee49d62b512b79626fb06dccee2a432bbc60276 b9f7dec44b7904cfbca4f3f6443ab2a49c9c2c41476dafd55c6e7ac8c769db1bc399161ee314bc2e75cf8759081743be1236ec4f4d6693e5336fb672c5dc24a8 c33585b5fb9cc24e1d4885545b58463634cc5416022cd19cacfccb4d30eb45296023fd35a458598360f8d7a4003bbaae25e331f155d9d9a5116d3bfb9a95523e 51440ca2e0088dd844ec6370bf0e55d027a012ae264c45d02f708fa6ad6da6dce29c255df9f6cae0ec38666984b372ab5334cf640b37795cc860de4ae2816e95 b21be5ceaf8a49f90b52a51cc6ff3355f47e0237052b81f6800fd7b802239daf6d8f0b1571a8426944fdbe80c6c1d40e8816b88b8569082ab84c36ff0539d4ff 6dce591a26ade1c0a7f669880485fd484582903d284b26fa4e2156cff62e4b9265844c4495c495a9157b440e091bea1ab8aaf7760f4510eaa69a6465c0e04ec6 9ffb9e65d028d44d4e39df9c1a52ecbd3607fee9cec7263328e5d661d3d0e4f62f44acd855ed7ab33cdf7bcb8ae889599bd5c8b3029895b6825696f6af29c239 b75a5bb1e6345e6ee6c28117e73586c1a2214ae1be07e93fb0ff51e133fb65426fa843be0fb515c187064d0cc206a2fa926d3c902e907670048d931db4c1a449 59d366ad93b65abe595f70a75bf03d616c2dd959fc7d4e6317cd99cbcec9c58b34766661c7d6766ca1a9c1b327531486c6f941c638c67cd22a7f75e2a37be0e8 2db8df9f30254d30c1372581a1f51c983c80e4b71ccdd28dbf000000ffff0300504b0304140006000800000021000dd1909fb60000001b010000270000007468 656d652f7468656d652f5f72656c732f7468656d654d616e616765722e786d6c2e72656c73848f4d0ac2301484f78277086f6fd3ba109126dd88d0add40384e4 350d363f2451eced0dae2c082e8761be9969bb979dc9136332de3168aa1a083ae995719ac16db8ec8e4052164e89d93b64b060828e6f37ed1567914b284d2624 52282e3198720e274a939cd08a54f980ae38a38f56e422a3a641c8bbd048f7757da0f19b017cc524bd62107bd5001996509affb3fd381a89672f1f165dfe5141 73d9850528a2c6cce0239baa4c04ca5bbabac4df000000ffff0300504b01022d0014000600080000002100e9de0fbfff0000001c020000130000000000000000 0000000000000000005b436f6e74656e745f54797065735d2e786d6c504b01022d0014000600080000002100a5d6a7e7c0000000360100000b00000000000000 000000000000300100005f72656c732f2e72656c73504b01022d00140006000800000021006b799616830000008a0000001c0000000000000000000000000019 0200007468656d652f7468656d652f7468656d654d616e616765722e786d6c504b01022d001400060008000000210096b5ade296060000501b00001600000000 000000000000000000d60200007468656d652f7468656d652f7468656d65312e786d6c504b01022d00140006000800000021000dd1909fb60000001b01000027 00000000000000000000000000a00900007468656d652f7468656d652f5f72656c732f7468656d654d616e616765722e786d6c2e72656c73504b050600000000050005005d0100009b0a00000000} {\*\colorschememapping 3c3f786d6c2076657273696f6e3d22312e302220656e636f64696e673d225554462d3822207374616e64616c6f6e653d22796573223f3e0d0a3c613a636c724d 617020786d6c6e733a613d22687474703a2f2f736368656d61732e6f70656e786d6c666f726d6174732e6f72672f64726177696e676d6c2f323030362f6d6169 6e22206267313d226c743122207478313d22646b3122206267323d226c743222207478323d22646b322220616363656e74313d22616363656e74312220616363 656e74323d22616363656e74322220616363656e74333d22616363656e74332220616363656e74343d22616363656e74342220616363656e74353d22616363656e74352220616363656e74363d22616363656e74362220686c696e6b3d22686c696e6b2220666f6c486c696e6b3d22666f6c486c696e6b222f3e} {\*\latentstyles\lsdstimax377\lsdlockeddef0\lsdsemihiddendef0\lsdunhideuseddef0\lsdqformatdef0\lsdprioritydef99{\lsdlockedexcept \lsdqformat1 \lsdpriority0 \lsdlocked0 Normal;\lsdqformat1 \lsdpriority0 \lsdlocked0 heading 1; \lsdqformat1 \lsdpriority0 \lsdlocked0 heading 2;\lsdqformat1 \lsdpriority0 \lsdlocked0 heading 3;\lsdqformat1 \lsdpriority0 \lsdlocked0 heading 4;\lsdqformat1 \lsdpriority0 \lsdlocked0 heading 5;\lsdqformat1 \lsdpriority0 \lsdlocked0 heading 6; \lsdqformat1 \lsdpriority0 \lsdlocked0 heading 7;\lsdqformat1 \lsdpriority0 \lsdlocked0 heading 8;\lsdqformat1 \lsdpriority0 \lsdlocked0 heading 9;\lsdsemihidden1 \lsdunhideused1 index 1;\lsdsemihidden1 \lsdunhideused1 index 2; \lsdsemihidden1 \lsdunhideused1 index 3;\lsdsemihidden1 \lsdunhideused1 index 4;\lsdsemihidden1 \lsdunhideused1 index 5;\lsdsemihidden1 \lsdunhideused1 index 6;\lsdsemihidden1 \lsdunhideused1 index 7;\lsdsemihidden1 \lsdunhideused1 index 8; \lsdsemihidden1 \lsdunhideused1 index 9;\lsdpriority39 \lsdlocked0 toc 1;\lsdpriority39 \lsdlocked0 toc 2;\lsdpriority0 \lsdlocked0 toc 3;\lsdpriority0 \lsdlocked0 toc 4;\lsdpriority0 \lsdlocked0 toc 5;\lsdpriority0 \lsdlocked0 toc 6; \lsdpriority0 \lsdlocked0 toc 7;\lsdpriority0 \lsdlocked0 toc 8;\lsdpriority0 \lsdlocked0 toc 9;\lsdsemihidden1 \lsdunhideused1 Normal Indent;\lsdsemihidden1 \lsdunhideused1 footnote text;\lsdsemihidden1 \lsdunhideused1 annotation text; \lsdsemihidden1 \lsdunhideused1 header;\lsdsemihidden1 \lsdunhideused1 footer;\lsdsemihidden1 \lsdunhideused1 index heading;\lsdqformat1 \lsdpriority0 \lsdlocked0 caption;\lsdsemihidden1 \lsdunhideused1 table of figures; \lsdsemihidden1 \lsdunhideused1 envelope address;\lsdsemihidden1 \lsdunhideused1 envelope return;\lsdsemihidden1 \lsdunhideused1 footnote reference;\lsdsemihidden1 \lsdunhideused1 annotation reference;\lsdsemihidden1 \lsdunhideused1 line number; \lsdsemihidden1 \lsdunhideused1 page number;\lsdsemihidden1 \lsdunhideused1 endnote reference;\lsdsemihidden1 \lsdunhideused1 endnote text;\lsdsemihidden1 \lsdunhideused1 table of authorities;\lsdsemihidden1 \lsdunhideused1 macro; \lsdsemihidden1 \lsdunhideused1 toa heading;\lsdsemihidden1 \lsdunhideused1 List;\lsdsemihidden1 \lsdunhideused1 List Bullet;\lsdsemihidden1 \lsdunhideused1 List Number;\lsdsemihidden1 \lsdunhideused1 List 2;\lsdsemihidden1 \lsdunhideused1 List 3; \lsdsemihidden1 \lsdunhideused1 List 4;\lsdsemihidden1 \lsdunhideused1 List 5;\lsdsemihidden1 \lsdunhideused1 List Bullet 2;\lsdsemihidden1 \lsdunhideused1 List Bullet 3;\lsdsemihidden1 \lsdunhideused1 List Bullet 4; \lsdsemihidden1 \lsdunhideused1 List Bullet 5;\lsdsemihidden1 \lsdunhideused1 List Number 2;\lsdsemihidden1 \lsdunhideused1 List Number 3;\lsdsemihidden1 \lsdunhideused1 List Number 4;\lsdsemihidden1 \lsdunhideused1 List Number 5; \lsdqformat1 \lsdpriority0 \lsdlocked0 Title;\lsdsemihidden1 \lsdunhideused1 Closing;\lsdsemihidden1 \lsdunhideused1 Signature;\lsdpriority0 \lsdlocked0 Default Paragraph Font;\lsdsemihidden1 \lsdunhideused1 Body Text; \lsdsemihidden1 \lsdunhideused1 Body Text Indent;\lsdsemihidden1 \lsdunhideused1 List Continue;\lsdsemihidden1 \lsdunhideused1 List Continue 2;\lsdsemihidden1 \lsdunhideused1 List Continue 3;\lsdsemihidden1 \lsdunhideused1 List Continue 4; \lsdsemihidden1 \lsdunhideused1 List Continue 5;\lsdsemihidden1 \lsdunhideused1 Message Header;\lsdqformat1 \lsdpriority0 \lsdlocked0 Subtitle;\lsdsemihidden1 \lsdunhideused1 Salutation;\lsdsemihidden1 \lsdunhideused1 Date; \lsdsemihidden1 \lsdunhideused1 Body Text First Indent;\lsdsemihidden1 \lsdunhideused1 Body Text First Indent 2;\lsdsemihidden1 \lsdunhideused1 Note Heading;\lsdsemihidden1 \lsdunhideused1 Body Text 2;\lsdsemihidden1 \lsdunhideused1 Body Text 3; \lsdsemihidden1 \lsdunhideused1 Body Text Indent 2;\lsdsemihidden1 \lsdunhideused1 Body Text Indent 3;\lsdsemihidden1 \lsdunhideused1 Block Text;\lsdsemihidden1 \lsdunhideused1 Hyperlink;\lsdsemihidden1 \lsdunhideused1 FollowedHyperlink; \lsdqformat1 \lsdpriority0 \lsdlocked0 Strong;\lsdqformat1 \lsdpriority0 \lsdlocked0 Emphasis;\lsdsemihidden1 \lsdunhideused1 Document Map;\lsdsemihidden1 \lsdunhideused1 Plain Text;\lsdsemihidden1 \lsdunhideused1 E-mail Signature; \lsdsemihidden1 \lsdunhideused1 HTML Top of Form;\lsdsemihidden1 \lsdunhideused1 HTML Bottom of Form;\lsdsemihidden1 \lsdunhideused1 Normal (Web);\lsdsemihidden1 \lsdunhideused1 HTML Acronym;\lsdsemihidden1 \lsdunhideused1 HTML Address; \lsdsemihidden1 \lsdunhideused1 HTML Cite;\lsdsemihidden1 \lsdunhideused1 HTML Code;\lsdsemihidden1 \lsdunhideused1 HTML Definition;\lsdsemihidden1 \lsdunhideused1 HTML Keyboard;\lsdsemihidden1 \lsdunhideused1 HTML Preformatted; \lsdsemihidden1 \lsdunhideused1 HTML Sample;\lsdsemihidden1 \lsdunhideused1 HTML Typewriter;\lsdsemihidden1 \lsdunhideused1 HTML Variable;Normal Table;\lsdsemihidden1 \lsdunhideused1 annotation subject;\lsdsemihidden1 \lsdunhideused1 No List; \lsdsemihidden1 \lsdunhideused1 Outline List 1;\lsdsemihidden1 \lsdunhideused1 Outline List 2;\lsdsemihidden1 \lsdunhideused1 Outline List 3;Table Simple 1;Table Simple 2;Table Simple 3;Table Classic 1;Table Classic 2;Table Classic 3;Table Classic 4; Table Colorful 1;Table Colorful 2;Table Colorful 3;Table Columns 1;Table Columns 2;Table Columns 3;Table Columns 4;Table Columns 5;Table Grid 1;Table Grid 2;Table Grid 3;Table Grid 4;Table Grid 5;Table Grid 6;Table Grid 7;Table Grid 8;Table List 1; Table List 2;Table List 3;Table List 4;Table List 5;Table List 6;Table List 7;Table List 8;Table 3D effects 1;Table 3D effects 2;Table 3D effects 3;Table Contemporary;Table Elegant;Table Professional;Table Subtle 1;Table Subtle 2;Table Web 1;Table Web 2; Table Web 3;\lsdsemihidden1 \lsdunhideused1 Balloon Text;\lsdpriority0 \lsdlocked0 Table Grid;Table Theme;\lsdsemihidden1 \lsdlocked0 Placeholder Text;\lsdqformat1 \lsdpriority1 \lsdlocked0 No Spacing;\lsdpriority60 \lsdlocked0 Light Shading; \lsdpriority61 \lsdlocked0 Light List;\lsdpriority62 \lsdlocked0 Light Grid;\lsdpriority63 \lsdlocked0 Medium Shading 1;\lsdpriority64 \lsdlocked0 Medium Shading 2;\lsdpriority65 \lsdlocked0 Medium List 1;\lsdpriority66 \lsdlocked0 Medium List 2; \lsdpriority67 \lsdlocked0 Medium Grid 1;\lsdpriority68 \lsdlocked0 Medium Grid 2;\lsdpriority69 \lsdlocked0 Medium Grid 3;\lsdpriority70 \lsdlocked0 Dark List;\lsdpriority71 \lsdlocked0 Colorful Shading;\lsdpriority72 \lsdlocked0 Colorful List; \lsdpriority73 \lsdlocked0 Colorful Grid;\lsdpriority60 \lsdlocked0 Light Shading Accent 1;\lsdpriority61 \lsdlocked0 Light List Accent 1;\lsdpriority62 \lsdlocked0 Light Grid Accent 1;\lsdpriority63 \lsdlocked0 Medium Shading 1 Accent 1; \lsdpriority64 \lsdlocked0 Medium Shading 2 Accent 1;\lsdpriority65 \lsdlocked0 Medium List 1 Accent 1;\lsdqformat1 \lsdpriority34 \lsdlocked0 List Paragraph;\lsdqformat1 \lsdpriority29 \lsdlocked0 Quote; \lsdqformat1 \lsdpriority30 \lsdlocked0 Intense Quote;\lsdpriority66 \lsdlocked0 Medium List 2 Accent 1;\lsdpriority67 \lsdlocked0 Medium Grid 1 Accent 1;\lsdpriority68 \lsdlocked0 Medium Grid 2 Accent 1;\lsdpriority69 \lsdlocked0 Medium Grid 3 Accent 1; \lsdpriority70 \lsdlocked0 Dark List Accent 1;\lsdpriority71 \lsdlocked0 Colorful Shading Accent 1;\lsdpriority72 \lsdlocked0 Colorful List Accent 1;\lsdpriority73 \lsdlocked0 Colorful Grid Accent 1;\lsdpriority60 \lsdlocked0 Light Shading Accent 2; \lsdpriority61 \lsdlocked0 Light List Accent 2;\lsdpriority62 \lsdlocked0 Light Grid Accent 2;\lsdpriority63 \lsdlocked0 Medium Shading 1 Accent 2;\lsdpriority64 \lsdlocked0 Medium Shading 2 Accent 2;\lsdpriority65 \lsdlocked0 Medium List 1 Accent 2; \lsdpriority66 \lsdlocked0 Medium List 2 Accent 2;\lsdpriority67 \lsdlocked0 Medium Grid 1 Accent 2;\lsdpriority68 \lsdlocked0 Medium Grid 2 Accent 2;\lsdpriority69 \lsdlocked0 Medium Grid 3 Accent 2;\lsdpriority70 \lsdlocked0 Dark List Accent 2; \lsdpriority71 \lsdlocked0 Colorful Shading Accent 2;\lsdpriority72 \lsdlocked0 Colorful List Accent 2;\lsdpriority73 \lsdlocked0 Colorful Grid Accent 2;\lsdpriority60 \lsdlocked0 Light Shading Accent 3;\lsdpriority61 \lsdlocked0 Light List Accent 3; \lsdpriority62 \lsdlocked0 Light Grid Accent 3;\lsdpriority63 \lsdlocked0 Medium Shading 1 Accent 3;\lsdpriority64 \lsdlocked0 Medium Shading 2 Accent 3;\lsdpriority65 \lsdlocked0 Medium List 1 Accent 3;\lsdpriority66 \lsdlocked0 Medium List 2 Accent 3; \lsdpriority67 \lsdlocked0 Medium Grid 1 Accent 3;\lsdpriority68 \lsdlocked0 Medium Grid 2 Accent 3;\lsdpriority69 \lsdlocked0 Medium Grid 3 Accent 3;\lsdpriority70 \lsdlocked0 Dark List Accent 3;\lsdpriority71 \lsdlocked0 Colorful Shading Accent 3; \lsdpriority72 \lsdlocked0 Colorful List Accent 3;\lsdpriority73 \lsdlocked0 Colorful Grid Accent 3;\lsdpriority60 \lsdlocked0 Light Shading Accent 4;\lsdpriority61 \lsdlocked0 Light List Accent 4;\lsdpriority62 \lsdlocked0 Light Grid Accent 4; \lsdpriority63 \lsdlocked0 Medium Shading 1 Accent 4;\lsdpriority64 \lsdlocked0 Medium Shading 2 Accent 4;\lsdpriority65 \lsdlocked0 Medium List 1 Accent 4;\lsdpriority66 \lsdlocked0 Medium List 2 Accent 4; \lsdpriority67 \lsdlocked0 Medium Grid 1 Accent 4;\lsdpriority68 \lsdlocked0 Medium Grid 2 Accent 4;\lsdpriority69 \lsdlocked0 Medium Grid 3 Accent 4;\lsdpriority70 \lsdlocked0 Dark List Accent 4;\lsdpriority71 \lsdlocked0 Colorful Shading Accent 4; \lsdpriority72 \lsdlocked0 Colorful List Accent 4;\lsdpriority73 \lsdlocked0 Colorful Grid Accent 4;\lsdpriority60 \lsdlocked0 Light Shading Accent 5;\lsdpriority61 \lsdlocked0 Light List Accent 5;\lsdpriority62 \lsdlocked0 Light Grid Accent 5; \lsdpriority63 \lsdlocked0 Medium Shading 1 Accent 5;\lsdpriority64 \lsdlocked0 Medium Shading 2 Accent 5;\lsdpriority65 \lsdlocked0 Medium List 1 Accent 5;\lsdpriority66 \lsdlocked0 Medium List 2 Accent 5; \lsdpriority67 \lsdlocked0 Medium Grid 1 Accent 5;\lsdpriority68 \lsdlocked0 Medium Grid 2 Accent 5;\lsdpriority69 \lsdlocked0 Medium Grid 3 Accent 5;\lsdpriority70 \lsdlocked0 Dark List Accent 5;\lsdpriority71 \lsdlocked0 Colorful Shading Accent 5; \lsdpriority72 \lsdlocked0 Colorful List Accent 5;\lsdpriority73 \lsdlocked0 Colorful Grid Accent 5;\lsdpriority60 \lsdlocked0 Light Shading Accent 6;\lsdpriority61 \lsdlocked0 Light List Accent 6;\lsdpriority62 \lsdlocked0 Light Grid Accent 6; \lsdpriority63 \lsdlocked0 Medium Shading 1 Accent 6;\lsdpriority64 \lsdlocked0 Medium Shading 2 Accent 6;\lsdpriority65 \lsdlocked0 Medium List 1 Accent 6;\lsdpriority66 \lsdlocked0 Medium List 2 Accent 6; \lsdpriority67 \lsdlocked0 Medium Grid 1 Accent 6;\lsdpriority68 \lsdlocked0 Medium Grid 2 Accent 6;\lsdpriority69 \lsdlocked0 Medium Grid 3 Accent 6;\lsdpriority70 \lsdlocked0 Dark List Accent 6;\lsdpriority71 \lsdlocked0 Colorful Shading Accent 6; \lsdpriority72 \lsdlocked0 Colorful List Accent 6;\lsdpriority73 \lsdlocked0 Colorful Grid Accent 6;\lsdqformat1 \lsdpriority19 \lsdlocked0 Subtle Emphasis;\lsdqformat1 \lsdpriority21 \lsdlocked0 Intense Emphasis; \lsdqformat1 \lsdpriority31 \lsdlocked0 Subtle Reference;\lsdqformat1 \lsdpriority32 \lsdlocked0 Intense Reference;\lsdqformat1 \lsdpriority33 \lsdlocked0 Book Title;\lsdsemihidden1 \lsdunhideused1 \lsdpriority37 \lsdlocked0 Bibliography; \lsdsemihidden1 \lsdunhideused1 \lsdqformat1 \lsdpriority39 \lsdlocked0 TOC Heading;\lsdpriority41 \lsdlocked0 Plain Table 1;\lsdpriority42 \lsdlocked0 Plain Table 2;\lsdpriority43 \lsdlocked0 Plain Table 3;\lsdpriority44 \lsdlocked0 Plain Table 4; \lsdpriority45 \lsdlocked0 Plain Table 5;\lsdpriority40 \lsdlocked0 Grid Table Light;\lsdpriority46 \lsdlocked0 Grid Table 1 Light;\lsdpriority47 \lsdlocked0 Grid Table 2;\lsdpriority48 \lsdlocked0 Grid Table 3;\lsdpriority49 \lsdlocked0 Grid Table 4; \lsdpriority50 \lsdlocked0 Grid Table 5 Dark;\lsdpriority51 \lsdlocked0 Grid Table 6 Colorful;\lsdpriority52 \lsdlocked0 Grid Table 7 Colorful;\lsdpriority46 \lsdlocked0 Grid Table 1 Light Accent 1;\lsdpriority47 \lsdlocked0 Grid Table 2 Accent 1; \lsdpriority48 \lsdlocked0 Grid Table 3 Accent 1;\lsdpriority49 \lsdlocked0 Grid Table 4 Accent 1;\lsdpriority50 \lsdlocked0 Grid Table 5 Dark Accent 1;\lsdpriority51 \lsdlocked0 Grid Table 6 Colorful Accent 1; \lsdpriority52 \lsdlocked0 Grid Table 7 Colorful Accent 1;\lsdpriority46 \lsdlocked0 Grid Table 1 Light Accent 2;\lsdpriority47 \lsdlocked0 Grid Table 2 Accent 2;\lsdpriority48 \lsdlocked0 Grid Table 3 Accent 2; \lsdpriority49 \lsdlocked0 Grid Table 4 Accent 2;\lsdpriority50 \lsdlocked0 Grid Table 5 Dark Accent 2;\lsdpriority51 \lsdlocked0 Grid Table 6 Colorful Accent 2;\lsdpriority52 \lsdlocked0 Grid Table 7 Colorful Accent 2; \lsdpriority46 \lsdlocked0 Grid Table 1 Light Accent 3;\lsdpriority47 \lsdlocked0 Grid Table 2 Accent 3;\lsdpriority48 \lsdlocked0 Grid Table 3 Accent 3;\lsdpriority49 \lsdlocked0 Grid Table 4 Accent 3; \lsdpriority50 \lsdlocked0 Grid Table 5 Dark Accent 3;\lsdpriority51 \lsdlocked0 Grid Table 6 Colorful Accent 3;\lsdpriority52 \lsdlocked0 Grid Table 7 Colorful Accent 3;\lsdpriority46 \lsdlocked0 Grid Table 1 Light Accent 4; \lsdpriority47 \lsdlocked0 Grid Table 2 Accent 4;\lsdpriority48 \lsdlocked0 Grid Table 3 Accent 4;\lsdpriority49 \lsdlocked0 Grid Table 4 Accent 4;\lsdpriority50 \lsdlocked0 Grid Table 5 Dark Accent 4; \lsdpriority51 \lsdlocked0 Grid Table 6 Colorful Accent 4;\lsdpriority52 \lsdlocked0 Grid Table 7 Colorful Accent 4;\lsdpriority46 \lsdlocked0 Grid Table 1 Light Accent 5;\lsdpriority47 \lsdlocked0 Grid Table 2 Accent 5; \lsdpriority48 \lsdlocked0 Grid Table 3 Accent 5;\lsdpriority49 \lsdlocked0 Grid Table 4 Accent 5;\lsdpriority50 \lsdlocked0 Grid Table 5 Dark Accent 5;\lsdpriority51 \lsdlocked0 Grid Table 6 Colorful Accent 5; \lsdpriority52 \lsdlocked0 Grid Table 7 Colorful Accent 5;\lsdpriority46 \lsdlocked0 Grid Table 1 Light Accent 6;\lsdpriority47 \lsdlocked0 Grid Table 2 Accent 6;\lsdpriority48 \lsdlocked0 Grid Table 3 Accent 6; \lsdpriority49 \lsdlocked0 Grid Table 4 Accent 6;\lsdpriority50 \lsdlocked0 Grid Table 5 Dark Accent 6;\lsdpriority51 \lsdlocked0 Grid Table 6 Colorful Accent 6;\lsdpriority52 \lsdlocked0 Grid Table 7 Colorful Accent 6; \lsdpriority46 \lsdlocked0 List Table 1 Light;\lsdpriority47 \lsdlocked0 List Table 2;\lsdpriority48 \lsdlocked0 List Table 3;\lsdpriority49 \lsdlocked0 List Table 4;\lsdpriority50 \lsdlocked0 List Table 5 Dark; \lsdpriority51 \lsdlocked0 List Table 6 Colorful;\lsdpriority52 \lsdlocked0 List Table 7 Colorful;\lsdpriority46 \lsdlocked0 List Table 1 Light Accent 1;\lsdpriority47 \lsdlocked0 List Table 2 Accent 1;\lsdpriority48 \lsdlocked0 List Table 3 Accent 1; \lsdpriority49 \lsdlocked0 List Table 4 Accent 1;\lsdpriority50 \lsdlocked0 List Table 5 Dark Accent 1;\lsdpriority51 \lsdlocked0 List Table 6 Colorful Accent 1;\lsdpriority52 \lsdlocked0 List Table 7 Colorful Accent 1; \lsdpriority46 \lsdlocked0 List Table 1 Light Accent 2;\lsdpriority47 \lsdlocked0 List Table 2 Accent 2;\lsdpriority48 \lsdlocked0 List Table 3 Accent 2;\lsdpriority49 \lsdlocked0 List Table 4 Accent 2; \lsdpriority50 \lsdlocked0 List Table 5 Dark Accent 2;\lsdpriority51 \lsdlocked0 List Table 6 Colorful Accent 2;\lsdpriority52 \lsdlocked0 List Table 7 Colorful Accent 2;\lsdpriority46 \lsdlocked0 List Table 1 Light Accent 3; \lsdpriority47 \lsdlocked0 List Table 2 Accent 3;\lsdpriority48 \lsdlocked0 List Table 3 Accent 3;\lsdpriority49 \lsdlocked0 List Table 4 Accent 3;\lsdpriority50 \lsdlocked0 List Table 5 Dark Accent 3; \lsdpriority51 \lsdlocked0 List Table 6 Colorful Accent 3;\lsdpriority52 \lsdlocked0 List Table 7 Colorful Accent 3;\lsdpriority46 \lsdlocked0 List Table 1 Light Accent 4;\lsdpriority47 \lsdlocked0 List Table 2 Accent 4; \lsdpriority48 \lsdlocked0 List Table 3 Accent 4;\lsdpriority49 \lsdlocked0 List Table 4 Accent 4;\lsdpriority50 \lsdlocked0 List Table 5 Dark Accent 4;\lsdpriority51 \lsdlocked0 List Table 6 Colorful Accent 4; \lsdpriority52 \lsdlocked0 List Table 7 Colorful Accent 4;\lsdpriority46 \lsdlocked0 List Table 1 Light Accent 5;\lsdpriority47 \lsdlocked0 List Table 2 Accent 5;\lsdpriority48 \lsdlocked0 List Table 3 Accent 5; \lsdpriority49 \lsdlocked0 List Table 4 Accent 5;\lsdpriority50 \lsdlocked0 List Table 5 Dark Accent 5;\lsdpriority51 \lsdlocked0 List Table 6 Colorful Accent 5;\lsdpriority52 \lsdlocked0 List Table 7 Colorful Accent 5; \lsdpriority46 \lsdlocked0 List Table 1 Light Accent 6;\lsdpriority47 \lsdlocked0 List Table 2 Accent 6;\lsdpriority48 \lsdlocked0 List Table 3 Accent 6;\lsdpriority49 \lsdlocked0 List Table 4 Accent 6; \lsdpriority50 \lsdlocked0 List Table 5 Dark Accent 6;\lsdpriority51 \lsdlocked0 List Table 6 Colorful Accent 6;\lsdpriority52 \lsdlocked0 List Table 7 Colorful Accent 6;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Mention; \lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Smart Hyperlink;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Hashtag;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Unresolved Mention;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Smart Link; \lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Smart Link Error;}}{\*\datastore 0105000002000000180000004d73786d6c322e534158584d4c5265616465722e362e30000000000000000000000e0000 d0cf11e0a1b11ae1000000000000000000000000000000003e000300feff0900060000000000000000000000010000000100000000000000001000000200000001000000feffffff0000000000000000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff fffffffffffffffffdffffff04000000feffffff05000000fefffffffeffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffff52006f006f007400200045006e00740072007900000000000000000000000000000000000000000000000000000000000000000000000000000000000000000016000500ffffffffffffffff010000000c6ad98892f1d411a65f0040963251e500000000000000000000000020a3 2f0b3455d60103000000c0020000000000004d0073006f004400610074006100530074006f0072006500000000000000000000000000000000000000000000000000000000000000000000000000000000001a000101ffffffffffffffff02000000000000000000000000000000000000000000000020a32f0b3455d601 20a32f0b3455d60100000000000000000000000056003500d00049004400d00043003000ce00c400da0045004f004b0057004c004f0051004400d7003300c0003d003d000000000000000000000000000000000032000101ffffffffffffffff03000000000000000000000000000000000000000000000020a32f0b3455 d60120a32f0b3455d6010000000000000000000000004900740065006d0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000a000201ffffffff04000000ffffffff000000000000000000000000000000000000000000000000 000000000000000000000000000000000e0100000000000001000000020000000300000004000000feffffff060000000700000008000000090000000a000000feffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff3c3f786d6c2076657273696f6e3d22312e302220656e636f64696e673d225554462d3822207374616e64616c6f6e653d226e6f223f3e3c623a536f75726365732053656c65637465645374796c653d225c4150412e58534c22205374796c 654e616d653d224150412220786d6c6e733a623d22687474703a2f2f736368656d61732e6f70656e786d6c666f726d6174732e6f72672f6f6666696365446f63756d656e742f323030362f6269626c696f6772617068792220786d6c6e733d22687474703a2f2f736368656d61732e6f70656e786d6c666f726d6174732e 6f72672f6f6666696365446f63756d656e742f323030362f6269626c696f677261706879223e3c2f623a536f75726365733e00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003c3f786d6c2076657273696f6e3d22312e302220656e636f6469 6e673d225554462d3822207374616e64616c6f6e653d226e6f223f3e0d0a3c64733a6461746173746f72654974656d2064733a6974656d49443d227b30463038464335352d394130302d344542412d383433382d4135384233393030463737367d2220786d6c6e733a64733d22687474703a2f2f736368656d61732e6f70 656e786d6c666f726d6174732e6f72672f6f6666696365446f63756d656e742f323030362f637573500072006f007000650072007400690065007300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000016000200ffffffffffffffffffffffff000000000000 0000000000000000000000000000000000000000000000000000000000000500000055010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ffffffffffffffffffffffff00000000 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ffffffffffffffffffffffff0000 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ffffffffffffffffffffffff 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000746f6d586d6c223e3c64733a736368656d61526566733e3c64733a736368656d615265662064733a7572693d22687474703a2f2f736368656d61732e6f70656e786d6c666f726d6174732e6f7267 2f6f6666696365446f63756d656e742f323030362f6269626c696f677261706879222f3e3c2f64733a736368656d61526566733e3c2f64733a6461746173746f72654974656d3e00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000105000000000000}} ================================================ FILE: releases/twain-cs_02041100/twaincscert/AnyCPU/Debug/twaincscert.exe.config ================================================ ================================================ FILE: releases/twain-cs_02041100/twaincscert/AnyCPU/Release/twaincscert.exe.config ================================================ ================================================ FILE: releases/twain-cs_02041100/twaincscert/x64/Debug/twaincscert.exe.config ================================================ ================================================ FILE: releases/twain-cs_02041100/twaincscert/x64/Release/twaincscert.exe.config ================================================ ================================================ FILE: releases/twain-cs_02041100/twaincscert/x86/Debug/twaincscert.exe.config ================================================ ================================================ FILE: releases/twain-cs_02041100/twaincscert/x86/Release/twaincscert.exe.config ================================================ ================================================ FILE: releases/twain-cs_02041100/twaincsscan/AnyCPU/Debug/twaincsscan.exe.config ================================================ ================================================ FILE: releases/twain-cs_02041100/twaincsscan/AnyCPU/Release/twaincsscan.exe.config ================================================ ================================================ FILE: releases/twain-cs_02041100/twaincsscan/x64/Debug/twaincsscan.exe.config ================================================ ================================================ FILE: releases/twain-cs_02041100/twaincsscan/x64/Release/twaincsscan.exe.config ================================================ ================================================ FILE: releases/twain-cs_02041100/twaincsscan/x86/Debug/twaincsscan.exe.config ================================================ ================================================ FILE: releases/twain-cs_02041100/twaincsscan/x86/Release/twaincsscan.exe.config ================================================ ================================================ FILE: releases/twain-cs_02041100/twaincstst/AnyCPU/Debug/twaincstst.exe.config ================================================  ================================================ FILE: releases/twain-cs_02041100/twaincstst/AnyCPU/Release/twaincstst.exe.config ================================================  ================================================ FILE: releases/twain-cs_02041100/twaincstst/x64/Debug/twaincstst.exe.config ================================================  ================================================ FILE: releases/twain-cs_02041100/twaincstst/x64/Release/twaincstst.exe.config ================================================  ================================================ FILE: releases/twain-cs_02041100/twaincstst/x86/Debug/twaincstst.exe.config ================================================  ================================================ FILE: releases/twain-cs_02041100/twaincstst/x86/Release/twaincstst.exe.config ================================================  ================================================ FILE: twaincs/source/Properties/AssemblyInfo.cs ================================================ /////////////////////////////////////////////////////////////////////////////////////// // // TWAINCSScan AssemblyInfo // /////////////////////////////////////////////////////////////////////////////////////// // Copyright (C) 2013-2021 Kodak Alaris Inc. // // Permission is hereby granted, free of charge, to any person obtaining a // copy of this software and associated documentation files (the "Software"), // to deal in the Software without restriction, including without limitation // the rights to use, copy, modify, merge, publish, distribute, sublicense, // and/or sell copies of the Software, and to permit persons to whom the // Software is furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL // THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER // DEALINGS IN THE SOFTWARE. /////////////////////////////////////////////////////////////////////////////////////// using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; // General Information about an assembly is controlled through the following // set of attributes. Change these attribute values to modify the information // associated with an assembly. [assembly: AssemblyTitle("TWAIN")] [assembly: AssemblyDescription("TWAIN Driver Interface for C#")] [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany("Kodak Alaris Inc.")] [assembly: AssemblyProduct("TWAIN")] [assembly: AssemblyCopyright("Copyright © 2013-2020, Kodak Alaris Inc.")] [assembly: AssemblyTrademark("")] [assembly: AssemblyCulture("")] // Setting ComVisible to false makes the types in this assembly not visible // to COM components. If you need to access a type in this assembly from // COM, set the ComVisible attribute to true on that type. [assembly: ComVisible(false)] // The following GUID is for the ID of the typelib if this project is exposed to COM [assembly: Guid("d3017689-1db2-4ee8-8d89-b5f78ba9ae90")] // Version information for an assembly consists of the following four values: // // Major Version // Minor Version // Build Number // Revision // // You can specify all the values or you can default the Build and Revision Numbers // by using the '*' as shown below: [assembly: AssemblyVersion("2.5.0.0")] [assembly: AssemblyFileVersion("2.5.0.0")] ================================================ FILE: twaincs/source/TWAIN CS.rtf ================================================ {\rtf1\adeflang1025\ansi\ansicpg1252\uc1\adeff45\deff0\stshfdbch0\stshfloch0\stshfhich0\stshfbi0\deflang1033\deflangfe1033\themelang1033\themelangfe0\themelangcs0{\fonttbl{\f0\fbidi \froman\fcharset0\fprq2{\*\panose 02020603050405020304}Times New Roman{\*\falt Times New Roman};} {\f1\fbidi \fswiss\fcharset0\fprq2{\*\panose 020b0604020202020204}Arial{\*\falt Arial};}{\f2\fbidi \fmodern\fcharset0\fprq1{\*\panose 02070309020205020404}Courier New{\*\falt Courier New};} {\f3\fbidi \froman\fcharset2\fprq2{\*\panose 05050102010706020507}Symbol;}{\f4\fbidi \fswiss\fcharset0\fprq2{\*\panose 020b0604020202020204}Helvetica;}{\f5\fbidi \fmodern\fcharset0\fprq1{\*\panose 02070409020205020404}Courier{\*\falt Courier New};} {\f10\fbidi \fnil\fcharset2\fprq2{\*\panose 05000000000000000000}Wingdings;}{\f34\fbidi \froman\fcharset0\fprq2{\*\panose 02040503050406030204}Cambria Math;} {\f37\fbidi \fswiss\fcharset0\fprq2{\*\panose 020f0502020204030204}Calibri{\*\falt Century Gothic};}{\f43\fbidi \froman\fcharset0\fprq2{\*\panose 00000000000000000000}Cambria{\*\falt Palatino Linotype};} {\f44\fbidi \fswiss\fcharset0\fprq2{\*\panose 00000000000000000000}Tahoma;}{\f45\fbidi \froman\fcharset0\fprq2{\*\panose 00000000000000000000}Book Antiqua{\*\falt Book Antiqua};} {\f46\fbidi \froman\fcharset0\fprq0{\*\panose 00000000000000000000}BookAntiqua{\*\falt Book Antiqua};}{\f47\fbidi \froman\fcharset0\fprq2{\*\panose 00000000000000000000}MS Serif;} {\f48\fbidi \fswiss\fcharset0\fprq2{\*\panose 00000000000000000000}Geneva{\*\falt Arial};}{\f49\fbidi \fmodern\fcharset0\fprq1{\*\panose 00000000000000000000}Courier Std;}{\f50\fbidi \fmodern\fcharset0\fprq1{\*\panose 020b0609020204030204}Consolas;} {\f51\fbidi \froman\fcharset0\fprq0{\*\panose 00000000000000000000}CourierNewPSMT;}{\flomajor\f31500\fbidi \froman\fcharset0\fprq2{\*\panose 02020603050405020304}Times New Roman{\*\falt Times New Roman};} {\fdbmajor\f31501\fbidi \froman\fcharset0\fprq2{\*\panose 02020603050405020304}Times New Roman{\*\falt Times New Roman};}{\fhimajor\f31502\fbidi \froman\fcharset0\fprq2{\*\panose 00000000000000000000}Cambria{\*\falt Palatino Linotype};} {\fbimajor\f31503\fbidi \froman\fcharset0\fprq2{\*\panose 02020603050405020304}Times New Roman{\*\falt Times New Roman};}{\flominor\f31504\fbidi \froman\fcharset0\fprq2{\*\panose 02020603050405020304}Times New Roman{\*\falt Times New Roman};} {\fdbminor\f31505\fbidi \froman\fcharset0\fprq2{\*\panose 02020603050405020304}Times New Roman{\*\falt Times New Roman};}{\fhiminor\f31506\fbidi \fswiss\fcharset0\fprq2{\*\panose 020f0502020204030204}Calibri{\*\falt Century Gothic};} {\fbiminor\f31507\fbidi \froman\fcharset0\fprq2{\*\panose 02020603050405020304}Times New Roman{\*\falt Times New Roman};}{\f53\fbidi \froman\fcharset238\fprq2 Times New Roman CE{\*\falt Times New Roman};} {\f54\fbidi \froman\fcharset204\fprq2 Times New Roman Cyr{\*\falt Times New Roman};}{\f56\fbidi \froman\fcharset161\fprq2 Times New Roman Greek{\*\falt Times New Roman};}{\f57\fbidi \froman\fcharset162\fprq2 Times New Roman Tur{\*\falt Times New Roman};} {\f58\fbidi \froman\fcharset177\fprq2 Times New Roman (Hebrew){\*\falt Times New Roman};}{\f59\fbidi \froman\fcharset178\fprq2 Times New Roman (Arabic){\*\falt Times New Roman};} {\f60\fbidi \froman\fcharset186\fprq2 Times New Roman Baltic{\*\falt Times New Roman};}{\f61\fbidi \froman\fcharset163\fprq2 Times New Roman (Vietnamese){\*\falt Times New Roman};}{\f63\fbidi \fswiss\fcharset238\fprq2 Arial CE{\*\falt Arial};} {\f64\fbidi \fswiss\fcharset204\fprq2 Arial Cyr{\*\falt Arial};}{\f66\fbidi \fswiss\fcharset161\fprq2 Arial Greek{\*\falt Arial};}{\f67\fbidi \fswiss\fcharset162\fprq2 Arial Tur{\*\falt Arial};} {\f68\fbidi \fswiss\fcharset177\fprq2 Arial (Hebrew){\*\falt Arial};}{\f69\fbidi \fswiss\fcharset178\fprq2 Arial (Arabic){\*\falt Arial};}{\f70\fbidi \fswiss\fcharset186\fprq2 Arial Baltic{\*\falt Arial};} {\f71\fbidi \fswiss\fcharset163\fprq2 Arial (Vietnamese){\*\falt Arial};}{\f73\fbidi \fmodern\fcharset238\fprq1 Courier New CE{\*\falt Courier New};}{\f74\fbidi \fmodern\fcharset204\fprq1 Courier New Cyr{\*\falt Courier New};} {\f76\fbidi \fmodern\fcharset161\fprq1 Courier New Greek{\*\falt Courier New};}{\f77\fbidi \fmodern\fcharset162\fprq1 Courier New Tur{\*\falt Courier New};}{\f78\fbidi \fmodern\fcharset177\fprq1 Courier New (Hebrew){\*\falt Courier New};} {\f79\fbidi \fmodern\fcharset178\fprq1 Courier New (Arabic){\*\falt Courier New};}{\f80\fbidi \fmodern\fcharset186\fprq1 Courier New Baltic{\*\falt Courier New};}{\f81\fbidi \fmodern\fcharset163\fprq1 Courier New (Vietnamese){\*\falt Courier New};} {\f93\fbidi \fswiss\fcharset238\fprq2 Helvetica CE;}{\f94\fbidi \fswiss\fcharset204\fprq2 Helvetica Cyr;}{\f96\fbidi \fswiss\fcharset161\fprq2 Helvetica Greek;}{\f97\fbidi \fswiss\fcharset162\fprq2 Helvetica Tur;} {\f98\fbidi \fswiss\fcharset177\fprq2 Helvetica (Hebrew);}{\f99\fbidi \fswiss\fcharset178\fprq2 Helvetica (Arabic);}{\f100\fbidi \fswiss\fcharset186\fprq2 Helvetica Baltic;}{\f101\fbidi \fswiss\fcharset163\fprq2 Helvetica (Vietnamese);} {\f393\fbidi \froman\fcharset238\fprq2 Cambria Math CE;}{\f394\fbidi \froman\fcharset204\fprq2 Cambria Math Cyr;}{\f396\fbidi \froman\fcharset161\fprq2 Cambria Math Greek;}{\f397\fbidi \froman\fcharset162\fprq2 Cambria Math Tur;} {\f400\fbidi \froman\fcharset186\fprq2 Cambria Math Baltic;}{\f401\fbidi \froman\fcharset163\fprq2 Cambria Math (Vietnamese);}{\f423\fbidi \fswiss\fcharset238\fprq2 Calibri CE{\*\falt Century Gothic};} {\f424\fbidi \fswiss\fcharset204\fprq2 Calibri Cyr{\*\falt Century Gothic};}{\f426\fbidi \fswiss\fcharset161\fprq2 Calibri Greek{\*\falt Century Gothic};}{\f427\fbidi \fswiss\fcharset162\fprq2 Calibri Tur{\*\falt Century Gothic};} {\f428\fbidi \fswiss\fcharset177\fprq2 Calibri (Hebrew){\*\falt Century Gothic};}{\f429\fbidi \fswiss\fcharset178\fprq2 Calibri (Arabic){\*\falt Century Gothic};}{\f430\fbidi \fswiss\fcharset186\fprq2 Calibri Baltic{\*\falt Century Gothic};} {\f431\fbidi \fswiss\fcharset163\fprq2 Calibri (Vietnamese){\*\falt Century Gothic};}{\f483\fbidi \froman\fcharset238\fprq2 Cambria CE{\*\falt Palatino Linotype};}{\f484\fbidi \froman\fcharset204\fprq2 Cambria Cyr{\*\falt Palatino Linotype};} {\f486\fbidi \froman\fcharset161\fprq2 Cambria Greek{\*\falt Palatino Linotype};}{\f487\fbidi \froman\fcharset162\fprq2 Cambria Tur{\*\falt Palatino Linotype};}{\f490\fbidi \froman\fcharset186\fprq2 Cambria Baltic{\*\falt Palatino Linotype};} {\f491\fbidi \froman\fcharset163\fprq2 Cambria (Vietnamese){\*\falt Palatino Linotype};}{\f493\fbidi \fswiss\fcharset238\fprq2 Tahoma CE;}{\f494\fbidi \fswiss\fcharset204\fprq2 Tahoma Cyr;}{\f496\fbidi \fswiss\fcharset161\fprq2 Tahoma Greek;} {\f497\fbidi \fswiss\fcharset162\fprq2 Tahoma Tur;}{\f498\fbidi \fswiss\fcharset177\fprq2 Tahoma (Hebrew);}{\f499\fbidi \fswiss\fcharset178\fprq2 Tahoma (Arabic);}{\f500\fbidi \fswiss\fcharset186\fprq2 Tahoma Baltic;} {\f501\fbidi \fswiss\fcharset163\fprq2 Tahoma (Vietnamese);}{\f502\fbidi \fswiss\fcharset222\fprq2 Tahoma (Thai);}{\f503\fbidi \froman\fcharset238\fprq2 Book Antiqua CE{\*\falt Book Antiqua};} {\f504\fbidi \froman\fcharset204\fprq2 Book Antiqua Cyr{\*\falt Book Antiqua};}{\f506\fbidi \froman\fcharset161\fprq2 Book Antiqua Greek{\*\falt Book Antiqua};}{\f507\fbidi \froman\fcharset162\fprq2 Book Antiqua Tur{\*\falt Book Antiqua};} {\f510\fbidi \froman\fcharset186\fprq2 Book Antiqua Baltic{\*\falt Book Antiqua};}{\f553\fbidi \fmodern\fcharset238\fprq1 Consolas CE;}{\f554\fbidi \fmodern\fcharset204\fprq1 Consolas Cyr;}{\f556\fbidi \fmodern\fcharset161\fprq1 Consolas Greek;} {\f557\fbidi \fmodern\fcharset162\fprq1 Consolas Tur;}{\f560\fbidi \fmodern\fcharset186\fprq1 Consolas Baltic;}{\f561\fbidi \fmodern\fcharset163\fprq1 Consolas (Vietnamese);} {\flomajor\f31508\fbidi \froman\fcharset238\fprq2 Times New Roman CE{\*\falt Times New Roman};}{\flomajor\f31509\fbidi \froman\fcharset204\fprq2 Times New Roman Cyr{\*\falt Times New Roman};} {\flomajor\f31511\fbidi \froman\fcharset161\fprq2 Times New Roman Greek{\*\falt Times New Roman};}{\flomajor\f31512\fbidi \froman\fcharset162\fprq2 Times New Roman Tur{\*\falt Times New Roman};} {\flomajor\f31513\fbidi \froman\fcharset177\fprq2 Times New Roman (Hebrew){\*\falt Times New Roman};}{\flomajor\f31514\fbidi \froman\fcharset178\fprq2 Times New Roman (Arabic){\*\falt Times New Roman};} {\flomajor\f31515\fbidi \froman\fcharset186\fprq2 Times New Roman Baltic{\*\falt Times New Roman};}{\flomajor\f31516\fbidi \froman\fcharset163\fprq2 Times New Roman (Vietnamese){\*\falt Times New Roman};} {\fdbmajor\f31518\fbidi \froman\fcharset238\fprq2 Times New Roman CE{\*\falt Times New Roman};}{\fdbmajor\f31519\fbidi \froman\fcharset204\fprq2 Times New Roman Cyr{\*\falt Times New Roman};} {\fdbmajor\f31521\fbidi \froman\fcharset161\fprq2 Times New Roman Greek{\*\falt Times New Roman};}{\fdbmajor\f31522\fbidi \froman\fcharset162\fprq2 Times New Roman Tur{\*\falt Times New Roman};} {\fdbmajor\f31523\fbidi \froman\fcharset177\fprq2 Times New Roman (Hebrew){\*\falt Times New Roman};}{\fdbmajor\f31524\fbidi \froman\fcharset178\fprq2 Times New Roman (Arabic){\*\falt Times New Roman};} {\fdbmajor\f31525\fbidi \froman\fcharset186\fprq2 Times New Roman Baltic{\*\falt Times New Roman};}{\fdbmajor\f31526\fbidi \froman\fcharset163\fprq2 Times New Roman (Vietnamese){\*\falt Times New Roman};} {\fhimajor\f31528\fbidi \froman\fcharset238\fprq2 Cambria CE{\*\falt Palatino Linotype};}{\fhimajor\f31529\fbidi \froman\fcharset204\fprq2 Cambria Cyr{\*\falt Palatino Linotype};} {\fhimajor\f31531\fbidi \froman\fcharset161\fprq2 Cambria Greek{\*\falt Palatino Linotype};}{\fhimajor\f31532\fbidi \froman\fcharset162\fprq2 Cambria Tur{\*\falt Palatino Linotype};} {\fhimajor\f31535\fbidi \froman\fcharset186\fprq2 Cambria Baltic{\*\falt Palatino Linotype};}{\fhimajor\f31536\fbidi \froman\fcharset163\fprq2 Cambria (Vietnamese){\*\falt Palatino Linotype};} {\fbimajor\f31538\fbidi \froman\fcharset238\fprq2 Times New Roman CE{\*\falt Times New Roman};}{\fbimajor\f31539\fbidi \froman\fcharset204\fprq2 Times New Roman Cyr{\*\falt Times New Roman};} {\fbimajor\f31541\fbidi \froman\fcharset161\fprq2 Times New Roman Greek{\*\falt Times New Roman};}{\fbimajor\f31542\fbidi \froman\fcharset162\fprq2 Times New Roman Tur{\*\falt Times New Roman};} {\fbimajor\f31543\fbidi \froman\fcharset177\fprq2 Times New Roman (Hebrew){\*\falt Times New Roman};}{\fbimajor\f31544\fbidi \froman\fcharset178\fprq2 Times New Roman (Arabic){\*\falt Times New Roman};} {\fbimajor\f31545\fbidi \froman\fcharset186\fprq2 Times New Roman Baltic{\*\falt Times New Roman};}{\fbimajor\f31546\fbidi \froman\fcharset163\fprq2 Times New Roman (Vietnamese){\*\falt Times New Roman};} {\flominor\f31548\fbidi \froman\fcharset238\fprq2 Times New Roman CE{\*\falt Times New Roman};}{\flominor\f31549\fbidi \froman\fcharset204\fprq2 Times New Roman Cyr{\*\falt Times New Roman};} {\flominor\f31551\fbidi \froman\fcharset161\fprq2 Times New Roman Greek{\*\falt Times New Roman};}{\flominor\f31552\fbidi \froman\fcharset162\fprq2 Times New Roman Tur{\*\falt Times New Roman};} {\flominor\f31553\fbidi \froman\fcharset177\fprq2 Times New Roman (Hebrew){\*\falt Times New Roman};}{\flominor\f31554\fbidi \froman\fcharset178\fprq2 Times New Roman (Arabic){\*\falt Times New Roman};} {\flominor\f31555\fbidi \froman\fcharset186\fprq2 Times New Roman Baltic{\*\falt Times New Roman};}{\flominor\f31556\fbidi \froman\fcharset163\fprq2 Times New Roman (Vietnamese){\*\falt Times New Roman};} {\fdbminor\f31558\fbidi \froman\fcharset238\fprq2 Times New Roman CE{\*\falt Times New Roman};}{\fdbminor\f31559\fbidi \froman\fcharset204\fprq2 Times New Roman Cyr{\*\falt Times New Roman};} {\fdbminor\f31561\fbidi \froman\fcharset161\fprq2 Times New Roman Greek{\*\falt Times New Roman};}{\fdbminor\f31562\fbidi \froman\fcharset162\fprq2 Times New Roman Tur{\*\falt Times New Roman};} {\fdbminor\f31563\fbidi \froman\fcharset177\fprq2 Times New Roman (Hebrew){\*\falt Times New Roman};}{\fdbminor\f31564\fbidi \froman\fcharset178\fprq2 Times New Roman (Arabic){\*\falt Times New Roman};} {\fdbminor\f31565\fbidi \froman\fcharset186\fprq2 Times New Roman Baltic{\*\falt Times New Roman};}{\fdbminor\f31566\fbidi \froman\fcharset163\fprq2 Times New Roman (Vietnamese){\*\falt Times New Roman};} {\fhiminor\f31568\fbidi \fswiss\fcharset238\fprq2 Calibri CE{\*\falt Century Gothic};}{\fhiminor\f31569\fbidi \fswiss\fcharset204\fprq2 Calibri Cyr{\*\falt Century Gothic};} {\fhiminor\f31571\fbidi \fswiss\fcharset161\fprq2 Calibri Greek{\*\falt Century Gothic};}{\fhiminor\f31572\fbidi \fswiss\fcharset162\fprq2 Calibri Tur{\*\falt Century Gothic};} {\fhiminor\f31573\fbidi \fswiss\fcharset177\fprq2 Calibri (Hebrew){\*\falt Century Gothic};}{\fhiminor\f31574\fbidi \fswiss\fcharset178\fprq2 Calibri (Arabic){\*\falt Century Gothic};} {\fhiminor\f31575\fbidi \fswiss\fcharset186\fprq2 Calibri Baltic{\*\falt Century Gothic};}{\fhiminor\f31576\fbidi \fswiss\fcharset163\fprq2 Calibri (Vietnamese){\*\falt Century Gothic};} {\fbiminor\f31578\fbidi \froman\fcharset238\fprq2 Times New Roman CE{\*\falt Times New Roman};}{\fbiminor\f31579\fbidi \froman\fcharset204\fprq2 Times New Roman Cyr{\*\falt Times New Roman};} {\fbiminor\f31581\fbidi \froman\fcharset161\fprq2 Times New Roman Greek{\*\falt Times New Roman};}{\fbiminor\f31582\fbidi \froman\fcharset162\fprq2 Times New Roman Tur{\*\falt Times New Roman};} {\fbiminor\f31583\fbidi \froman\fcharset177\fprq2 Times New Roman (Hebrew){\*\falt Times New Roman};}{\fbiminor\f31584\fbidi \froman\fcharset178\fprq2 Times New Roman (Arabic){\*\falt Times New Roman};} {\fbiminor\f31585\fbidi \froman\fcharset186\fprq2 Times New Roman Baltic{\*\falt Times New Roman};}{\fbiminor\f31586\fbidi \froman\fcharset163\fprq2 Times New Roman (Vietnamese){\*\falt Times New Roman};}}{\colortbl;\red0\green0\blue0; \red0\green0\blue255;\red0\green255\blue255;\red0\green255\blue0;\red255\green0\blue255;\red255\green0\blue0;\red255\green255\blue0;\red255\green255\blue255;\red0\green0\blue128;\red0\green128\blue128;\red0\green128\blue0;\red128\green0\blue128; \red128\green0\blue0;\red128\green128\blue0;\red128\green128\blue128;\red192\green192\blue192;\red0\green0\blue0;\red0\green0\blue0;\cfollowedhyperlink\ctint255\cshade255\red128\green0\blue128;\red96\green94\blue92;\red225\green223\blue221; \red31\green73\blue125;\red0\green176\blue80;}{\*\defchp \fs22 }{\*\defpap \ql \li0\ri0\sa200\sl276\slmult1\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 }\noqfpromote {\stylesheet{ \ql \li1440\ri0\sb180\widctlpar\wrapdefault\nooverflow\faroman\rin0\lin1440\itap0 \rtlch\fcs1 \af45\afs20\alang1025 \ltrch\fcs0 \f45\fs20\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \snext0 \sqformat \spriority0 Normal;}{ \s1\ql \li0\ri0\sb720\keepn\widctlpar\brdrt\brdrs\brdrw30\brsp120 \wrapdefault\nooverflow\faroman\outlinelevel0\rin0\lin0\itap0 \rtlch\fcs1 \ab\af1\afs36\alang1025 \ltrch\fcs0 \b\f1\fs36\cf9\lang1024\langfe1024\cgrid\noproof\langnp1033\langfenp1033 \sbasedon0 \snext0 \slink15 \sqformat heading 1;}{\s2\ql \li720\ri0\sb360\keepn\widctlpar\wrapdefault\nooverflow\faroman\outlinelevel1\rin0\lin720\itap0 \rtlch\fcs1 \ab\af1\afs20\alang1025 \ltrch\fcs0 \b\f1\fs20\cf13\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \sbasedon0 \snext0 \slink16 \sqformat heading 2;}{\s3\ql \li1440\ri0\sb180\keepn\widctlpar\wrapdefault\nooverflow\faroman\outlinelevel2\rin0\lin1440\itap0 \rtlch\fcs1 \ab\af1\afs20\alang1025 \ltrch\fcs0 \b\f1\fs20\cf10\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \sbasedon0 \snext24 \slink17 \sqformat heading 3;}{\s4\ql \li1440\ri0\sb180\widctlpar\wrapdefault\nooverflow\faroman\outlinelevel3\rin0\lin1440\itap0 \rtlch\fcs1 \af47\afs24\alang1025 \ltrch\fcs0 \f47\fs24\ul\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \sbasedon0 \snext24 \slink18 \sqformat heading 4;}{ \s5\ql \li1440\ri0\sb180\widctlpar\wrapdefault\nooverflow\faroman\outlinelevel4\rin0\lin1440\itap0 \rtlch\fcs1 \ab\af47\afs20\alang1025 \ltrch\fcs0 \b\f47\fs20\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \sbasedon0 \snext24 \slink19 \sqformat heading 5;}{\s6\ql \li1440\ri0\sb180\widctlpar\wrapdefault\nooverflow\faroman\outlinelevel5\rin0\lin1440\itap0 \rtlch\fcs1 \af47\afs20\alang1025 \ltrch\fcs0 \f47\fs20\ul\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \sbasedon0 \snext24 \slink20 \sqformat heading 6;}{\s7\ql \li1440\ri0\sb180\widctlpar\wrapdefault\nooverflow\faroman\outlinelevel6\rin0\lin1440\itap0 \rtlch\fcs1 \ai\af47\afs20\alang1025 \ltrch\fcs0 \i\f47\fs20\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \sbasedon0 \snext24 \slink21 \sqformat heading 7;}{\s8\ql \li1440\ri0\sb240\sa60\widctlpar\wrapdefault\nooverflow\faroman\outlinelevel7\rin0\lin1440\itap0 \rtlch\fcs1 \ai\af45\afs20\alang1025 \ltrch\fcs0 \i\f45\fs20\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \sbasedon0 \snext0 \slink22 \sqformat heading 8;}{\s9\ql \li1440\ri0\sb240\sa60\widctlpar\wrapdefault\nooverflow\faroman\outlinelevel8\rin0\lin1440\itap0 \rtlch\fcs1 \ab\ai\af45\afs18\alang1025 \ltrch\fcs0 \b\i\f45\fs18\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \sbasedon0 \snext0 \slink23 \sqformat heading 9;}{\*\cs10 \additive \ssemihidden Default Paragraph Font;}{\* \ts11\tsrowd\trftsWidthB3\trpaddl108\trpaddr108\trpaddfl3\trpaddft3\trpaddfb3\trpaddfr3\trcbpat1\trcfpat1\tblind0\tblindtype3\tsvertalt\tsbrdrt\tsbrdrl\tsbrdrb\tsbrdrr\tsbrdrdgl\tsbrdrdgr\tsbrdrh\tsbrdrv \ql \li0\ri0\sa200\sl276\slmult1 \widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 \rtlch\fcs1 \af0\afs22\alang1025 \ltrch\fcs0 \fs22\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \snext11 \ssemihidden \sunhideused Normal Table;}{\*\cs15 \additive \rtlch\fcs1 \ab\af0\afs32 \ltrch\fcs0 \b\f43\fs32\kerning32 \sbasedon10 \slink1 \slocked Heading 1 Char;}{\*\cs16 \additive \rtlch\fcs1 \ab\ai\af0\afs28 \ltrch\fcs0 \b\i\f43\fs28 \sbasedon10 \slink2 \slocked \ssemihidden Heading 2 Char;}{\*\cs17 \additive \rtlch\fcs1 \ab\af0\afs26 \ltrch\fcs0 \b\f43\fs26 \sbasedon10 \slink3 \slocked \ssemihidden Heading 3 Char;}{\*\cs18 \additive \rtlch\fcs1 \ab\af0\afs28 \ltrch\fcs0 \b\f37\fs28 \sbasedon10 \slink4 \slocked \ssemihidden Heading 4 Char;}{\*\cs19 \additive \rtlch\fcs1 \ab\ai\af0\afs26 \ltrch\fcs0 \b\i\f37\fs26 \sbasedon10 \slink5 \slocked \ssemihidden Heading 5 Char;}{\*\cs20 \additive \rtlch\fcs1 \ab\af0 \ltrch\fcs0 \b\f37 \sbasedon10 \slink6 \slocked \ssemihidden Heading 6 Char;}{\*\cs21 \additive \rtlch\fcs1 \af0\afs24 \ltrch\fcs0 \f37\fs24 \sbasedon10 \slink7 \slocked \ssemihidden Heading 7 Char;}{\*\cs22 \additive \rtlch\fcs1 \ai\af0\afs24 \ltrch\fcs0 \i\f37\fs24 \sbasedon10 \slink8 \slocked \ssemihidden Heading 8 Char;}{\*\cs23 \additive \rtlch\fcs1 \af0 \ltrch\fcs0 \f43 \sbasedon10 \slink9 \slocked \ssemihidden Heading 9 Char;}{\s24\ql \li1800\ri0\sb180\widctlpar\wrapdefault\nooverflow\faroman\rin0\lin1800\itap0 \rtlch\fcs1 \af45\afs20\alang1025 \ltrch\fcs0 \f45\fs20\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \sbasedon0 \snext24 Normal Indent;}{\s25\ql \li0\ri0\widctlpar\tqr\tx9360\wrapdefault\nooverflow\faroman\rin0\lin0\itap0 \rtlch\fcs1 \ai\af1\afs16\alang1025 \ltrch\fcs0 \i\f1\fs16\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \sbasedon0 \snext25 \slink26 footer;}{\*\cs26 \additive \rtlch\fcs1 \af45\afs20 \ltrch\fcs0 \f45\fs20 \sbasedon10 \slink25 \slocked \ssemihidden Footer Char;}{\s27\ql \li0\ri0\widctlpar \tqr\tx9900\wrapdefault\nooverflow\faroman\rin0\lin0\itap0 \rtlch\fcs1 \ab\ai\af1\afs20\alang1025 \ltrch\fcs0 \b\i\f1\fs20\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \sbasedon0 \snext27 \slink28 header;}{\*\cs28 \additive \rtlch\fcs1 \af45\afs20 \ltrch\fcs0 \f45\fs20 \sbasedon10 \slink27 \slocked \ssemihidden Header Char;}{\s29\ql \li2160\ri0\sb40\widctlpar\wrapdefault\nooverflow\faroman\rin0\lin2160\itap0 \rtlch\fcs1 \af2\afs18\alang1025 \ltrch\fcs0 \f2\fs18\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \sbasedon30 \snext29 prog indent;}{\s30\ql \li1800\ri0\sb40\widctlpar\wrapdefault\nooverflow\faroman\rin0\lin1800\itap0 \rtlch\fcs1 \af2\afs18\alang1025 \ltrch\fcs0 \f2\fs18\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \sbasedon31 \snext30 prog;}{\s31\ql \fi-360\li360\ri0\sb180\widctlpar\wrapdefault\nooverflow\faroman\rin0\lin360\itap0 \rtlch\fcs1 \af45\afs20\alang1025 \ltrch\fcs0 \f45\fs20\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \sbasedon0 \snext31 List;}{\*\cs32 \additive \rtlch\fcs1 \af0 \ltrch\fcs0 \sbasedon10 page number;}{\s33\ql \fi-216\li2016\ri0\sb40\widctlpar\wrapdefault{\*\pn \pnlvlblt\ilvl10\ls2047\pnrnot0 \pnf5\pnstart1\pnindent216\pnhang {\pntxtb ?}}\nooverflow\faroman\ls2047\ilvl10\rin0\lin2016\itap0 \rtlch\fcs1 \af45\afs20\alang1025 \ltrch\fcs0 \f45\fs20\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \sbasedon0 \snext33 bullet;}{ \s34\ql \li0\ri0\sb720\keepn\widctlpar\brdrt\brdrs\brdrw30\brsp120 \wrapdefault\nooverflow\faroman\rin0\lin0\itap0 \rtlch\fcs1 \ab\af1\afs36\alang1025 \ltrch\fcs0 \b\f1\fs36\cf9\lang1024\langfe1024\cgrid\noproof\langnp1033\langfenp1033 \sbasedon1 \snext34 Style1;}{\s35\ql \fi-216\li2016\ri0\sb120\widctlpar\wrapdefault{\*\pn \pnlvlblt\ilvl10\ls2047\pnrnot0\pnf5\pnstart1\pnindent216\pnhang {\pntxtb ?}}\nooverflow\faroman\ls2047\ilvl10\rin0\lin2016\itap0 \rtlch\fcs1 \af45\afs20\alang1025 \ltrch\fcs0 \f45\fs20\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \sbasedon33 \snext33 bullet first;}{\s36\ql \li1440\ri0\sb180\widctlpar\tx5220\wrapdefault\nooverflow\faroman\rin0\lin1440\itap0 \rtlch\fcs1 \ab\af1\afs20\alang1025 \ltrch\fcs0 \b\f1\fs20\cf13\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \sbasedon0 \snext38 chapter contents;}{\s37\ql \li1440\ri0\sb40\widctlpar\tx5400\wrapdefault\nooverflow\faroman\rin0\lin1440\itap0 \rtlch\fcs1 \af45\afs20\alang1025 \ltrch\fcs0 \f45\fs20\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \sbasedon0 \snext37 chapter contents list;}{\s38\ql \li1440\ri0\sb80\widctlpar\tx5400\wrapdefault\nooverflow\faroman\rin0\lin1440\itap0 \rtlch\fcs1 \af45\afs20\alang1025 \ltrch\fcs0 \f45\fs20\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \sbasedon0 \snext37 chapter contents list first;}{\s39\ql \li0\ri0\widctlpar\wrapdefault\nooverflow\faroman\rin0\lin0\itap0 \rtlch\fcs1 \ab\af1\afs200\alang1025 \ltrch\fcs0 \b\f1\fs200\lang1024\langfe1024\cgrid\noproof\langnp1033\langfenp1033 \snext0 chapter num;}{\s40\qr \li0\ri0\sa720\widctlpar\brdrt\brdrs\brdrw60\brsp20 \wrapdefault\nooverflow\faroman\rin0\lin0\itap0 \rtlch\fcs1 \ab\af1\afs54\alang1025 \ltrch\fcs0 \b\f1\fs54\cf9\lang1024\langfe1024\cgrid\noproof\langnp1033\langfenp1033 \snext36 chapter title;}{\s41\ql \li1800\ri0\sb120\widctlpar\wrapdefault\nooverflow\faroman\rin0\lin1800\itap0 \rtlch\fcs1 \af45\afs20\alang1025 \ltrch\fcs0 \f45\fs20\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \sbasedon31 \snext31 list first;}{\s42\ql \fi-216\li2376\ri0\sb40\widctlpar\wrapdefault{\*\pn \pnlvlblt\ilvl10\ls2047\pnrnot0\pnf48\pnstart1\pnindent216\pnhang {\pntxtb ?}} \nooverflow\faroman\ls2047\ilvl10\rin0\lin2376\itap0 \rtlch\fcs1 \af45\afs20\alang1025 \ltrch\fcs0 \f45\fs20\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \sbasedon0 \snext42 bullet indent;}{ \s43\ql \li1440\ri0\sb120\widctlpar\wrapdefault\nooverflow\faroman\rin0\lin1440\itap0 \rtlch\fcs1 \af45\afs20\alang1025 \ltrch\fcs0 \f45\fs20\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \sbasedon0 \snext0 normal after heading 3;}{ \s44\ql \fi-216\li2376\ri0\sb80\widctlpar\wrapdefault{\*\pn \pnlvlblt\ilvl10\ls2047\pnrnot0\pnf48\pnstart1\pnindent216\pnhang {\pntxtb ?}}\nooverflow\faroman\ls2047\ilvl10\rin0\lin2376\itap0 \rtlch\fcs1 \af45\afs20\alang1025 \ltrch\fcs0 \f45\fs20\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \sbasedon33 \snext42 bullet indent first;}{\s45\qr \li720\ri0\sa360\sl-1060\slmult0\widctlpar\wrapdefault\nooverflow\faroman\rin0\lin720\itap0 \rtlch\fcs1 \ab\ai\af1\afs48\alang1025 \ltrch\fcs0 \b\i\f1\fs48\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \sbasedon0 \snext0 contents title;}{\s46\ql \li2160\ri0\sb40\widctlpar\wrapdefault\nooverflow\faroman\rin0\lin2160\itap0 \rtlch\fcs1 \af45\afs20\alang1025 \ltrch\fcs0 \f45\fs20\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \sbasedon31 \snext46 def;}{\s47\ql \li2160\ri0\sb80\widctlpar\wrapdefault\nooverflow\faroman\rin0\lin2160\itap0 \rtlch\fcs1 \af45\afs20\alang1025 \ltrch\fcs0 \f45\fs20\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \sbasedon46 \snext47 def 2;}{\s48\ql \li1080\ri0\sb120\widctlpar\wrapdefault\nooverflow\faroman\rin0\lin1080\itap0 \rtlch\fcs1 \af45\afs20\alang1025 \ltrch\fcs0 \f45\fs20\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \sbasedon41 \snext46 def first;}{\s49\ql \li2160\ri0\sb40\widctlpar\wrapdefault\nooverflow\faroman\rin0\lin2160\itap0 \rtlch\fcs1 \af45\afs20\alang1025 \ltrch\fcs0 \f45\fs20\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \sbasedon46 \snext0 def last;}{\s50\ql \li2160\ri0\sb80\widctlpar\wrapdefault\nooverflow\faroman\rin0\lin2160\itap0 \rtlch\fcs1 \af45\afs20\alang1025 \ltrch\fcs0 \f45\fs20\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \sbasedon49 \snext0 def last 2;}{\s51\ql \li1800\ri0\sb120\keepn\widctlpar\wrapdefault\nooverflow\faroman\rin0\lin1800\itap0 \rtlch\fcs1 \ab\af45\afs20\alang1025 \ltrch\fcs0 \b\f45\fs20\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \sbasedon41 \snext46 def term;}{\s52\ql \li1800\ri0\sb120\keepn\widctlpar\wrapdefault\nooverflow\faroman\rin0\lin1800\itap0 \rtlch\fcs1 \ab\af45\afs20\alang1025 \ltrch\fcs0 \b\f45\fs20\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \sbasedon41 \snext52 def term first;}{\s53\qc \li1440\ri0\sb240\keepn\widctlpar\wrapdefault\nooverflow\faroman\rin0\lin1440\itap0 \rtlch\fcs1 \af45\afs20\alang1025 \ltrch\fcs0 \f45\fs20\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \sbasedon0 \snext54 figure;}{\s54\qc \li1440\ri0\sb180\sa240\widctlpar\wrapdefault\nooverflow\faroman\rin0\lin1440\itap0 \rtlch\fcs1 \ab\af1\afs20\alang1025 \ltrch\fcs0 \b\f1\fs20\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \sbasedon0 \snext0 figure title;}{\s55\qc \li1440\ri0\sb240\keepn\widctlpar\wrapdefault\nooverflow\faroman\rin0\lin1440\itap0 \rtlch\fcs1 \af45\afs20\alang1025 \ltrch\fcs0 \f45\fs20\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \sbasedon53 \snext0 figure after step;}{\s56\qc \li1440\ri0\sb180\sa240\widctlpar\wrapdefault\nooverflow\faroman\rin0\lin1440\itap0 \rtlch\fcs1 \ab\af1\afs20\alang1025 \ltrch\fcs0 \b\f1\fs20\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \sbasedon54 \snext56 figure title after step;}{\s57\qc \li1440\ri0\sb180\sa360\widctlpar\wrapdefault\nooverflow\faroman\rin0\lin1440\itap0 \rtlch\fcs1 \ab\af1\afs20\alang1025 \ltrch\fcs0 \b\f1\fs20\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \sbasedon54 \snext0 figure title continued;}{\*\cs58 \additive \rtlch\fcs1 \af0 \ltrch\fcs0 \sbasedon10 line number;}{ \s59\ql \li2160\ri0\sb40\widctlpar\wrapdefault\nooverflow\faroman\rin0\lin2160\itap0 \rtlch\fcs1 \af45\afs20\alang1025 \ltrch\fcs0 \f45\fs20\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \sbasedon31 \snext59 list indent;}{ \s60\ql \li2160\ri0\sb80\widctlpar\wrapdefault\nooverflow\faroman\rin0\lin2160\itap0 \rtlch\fcs1 \af45\afs20\alang1025 \ltrch\fcs0 \f45\fs20\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \sbasedon31 \snext59 list indent first;}{ \s61\ql \fi-360\li2160\ri0\sb120\widctlpar\wrapdefault{\*\pn \pnlvlbody\ilvl11\ls2047\pnrnot0\pndec\pnstart1\pnindent360\pnhang {\pntxta .}}\nooverflow\faroman\ls2047\ilvl11\rin0\lin2160\itap0 \rtlch\fcs1 \af45\afs20\alang1025 \ltrch\fcs0 \f45\fs20\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \sbasedon0 \snext61 List Number;}{\s62\ql \li2160\ri0\sb80\widctlpar\wrapdefault\nooverflow\faroman\rin0\lin2160\itap0 \rtlch\fcs1 \af45\afs20\alang1025 \ltrch\fcs0 \f45\fs20\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \sbasedon60 \snext62 list number no number;}{\s63\ql \li720\ri0\sb180\widctlpar\wrapdefault\nooverflow\faroman\rin0\lin720\itap0 \rtlch\fcs1 \af45\afs20\alang1025 \ltrch\fcs0 \f45\fs20\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \sbasedon0 \snext63 normal before table;}{\s64\ql \fi-806\li2246\ri0\sb240\sa120\widctlpar\brdrt\brdrs\brdrw15\brsp100 \brdrb\brdrs\brdrw15\brsp100 \tx2250\wrapdefault\nooverflow\faroman\rin0\lin2246\itap0 \rtlch\fcs1 \af45\afs20\alang1025 \ltrch\fcs0 \f45\fs20\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \sbasedon0 \snext0 note;}{ \s65\qr \li0\ri0\sb180\widctlpar\wrapdefault\nooverflow\faroman\rin0\lin0\itap0 \rtlch\fcs1 \ai\af1\afs20\alang1025 \ltrch\fcs0 \i\f1\fs20\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \sbasedon0 \snext65 part number;}{ \s66\ql \li1800\ri0\sb120\widctlpar\tx4770\wrapdefault\nooverflow\faroman\rin0\lin1800\itap0 \rtlch\fcs1 \af2\afs18\alang1025 \ltrch\fcs0 \f2\fs18\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \sbasedon41 \snext30 prog first;}{ \s67\ql \li1800\ri0\sb40\widctlpar\wrapdefault\nooverflow\faroman\rin0\lin1800\itap0 \rtlch\fcs1 \af2\afs18\alang1025 \ltrch\fcs0 \f2\fs18\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \sbasedon31 \snext67 prog last;}{ \s68\ql \li1800\ri0\sb120\widctlpar\tx4770\wrapdefault\nooverflow\faroman\rin0\lin1800\itap0 \rtlch\fcs1 \af2\afs18\alang1025 \ltrch\fcs0 \f2\fs18\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \sbasedon66 \snext68 prog single;}{ \s69\ql \li878\ri144\sl-180\slmult0\widctlpar\brdrt\brdrs\brdrw15\brsp100 \brdrl\brdrs\brdrw15\brsp100 \brdrb\brdrs\brdrw15\brsp100 \brdrr\brdrs\brdrw15\brsp100 \tx1152\tx1440\tx1728\tx2016\tx2304\tx2592\tx2880\wrapdefault\nooverflow\faroman\rin144\lin878\itap0 \rtlch\fcs1 \af2\afs15\alang1025 \ltrch\fcs0 \f2\fs15\lang1024\langfe1024\cgrid\noproof\langnp1033\langfenp1033 \snext69 program text;}{ \s70\ql \fi-360\li2520\ri0\sb80\widctlpar\wrapdefault{\*\pn \pnlvlbody\ilvl11\ls2047\pnrnot0\pnlcltr\pnb0\pni0\pnf4\pnfs20\pnstart1\pnindent360\pnhang {\pntxta . }}\nooverflow\faroman\ls2047\ilvl11\rin0\lin2520\itap0 \rtlch\fcs1 \af45\afs20\alang1025 \ltrch\fcs0 \f45\fs20\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \sbasedon0 \snext70 substep;}{\s71\ql \li72\ri72\sb80\sa80\keepn\widctlpar\wrapdefault\nooverflow\faroman\rin72\lin72\itap0 \rtlch\fcs1 \ab\af45\afs20\alang1025 \ltrch\fcs0 \b\f45\fs20\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \sbasedon0 \snext0 table head;}{\s72\ql \li72\ri72\sb80\sa80\widctlpar\wrapdefault\nooverflow\faroman\rin72\lin72\itap0 \rtlch\fcs1 \af45\afs18\alang1025 \ltrch\fcs0 \f45\fs18\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \snext72 table text;}{\s73\qc \li1440\ri0\sb300\sa120\keepn\widctlpar\wrapdefault\nooverflow\faroman\rin0\lin1440\itap0 \rtlch\fcs1 \ab\af1\afs20\alang1025 \ltrch\fcs0 \b\f1\fs20\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \sbasedon0 \snext71 table title;}{\s74\qc \li1440\ri0\sb300\sa120\keepn\widctlpar\wrapdefault\nooverflow\faroman\rin0\lin1440\itap0 \rtlch\fcs1 \ab\af1\afs20\alang1025 \ltrch\fcs0 \b\f1\fs20\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \sbasedon73 \snext71 table title continued;}{\s75\ql \li1800\ri0\sb120\widctlpar\wrapdefault\nooverflow\faroman\rin0\lin1800\itap0 \rtlch\fcs1 \af1\afs20\alang1025 \ltrch\fcs0 \f1\fs20\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \sbasedon0 \snext0 triplet single;}{\s76\ql \li720\ri0\sb360\keepn\widctlpar\wrapdefault\nooverflow\faroman\rin0\lin720\itap0 \rtlch\fcs1 \ab\af1\afs20\alang1025 \ltrch\fcs0 \b\f1\fs20\cf13\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \sbasedon2 \snext0 triplet heading 2;}{\s77\ql \li0\ri0\sb180\keepn\pagebb\widctlpar\brdrt\brdrs\brdrw30\brsp120 \tqr\tx9893\wrapdefault\nooverflow\faroman\rin0\lin0\itap0 \rtlch\fcs1 \ab\af1\afs24\alang1025 \ltrch\fcs0 \b\f1\fs24\cf9\lang1024\langfe1024\cgrid\noproof\langnp1033\langfenp1033 \sbasedon1 \snext77 triplet heading;}{\s78\ql \li1080\ri0\sb120\widctlpar\wrapdefault\nooverflow\faroman\rin0\lin1080\itap0 \rtlch\fcs1 \af45\afs20\alang1025 \ltrch\fcs0 \f45\fs20\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \sbasedon0 \snext79 glossary def;}{\s79\ql \li720\ri0\sb180\keepn\widctlpar\wrapdefault\nooverflow\faroman\rin0\lin720\itap0 \rtlch\fcs1 \ab\af45\afs20\alang1025 \ltrch\fcs0 \b\f45\fs20\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \sbasedon80 \snext78 glossary word;}{\s80\ql \li720\ri0\sb180\keepn\widctlpar\wrapdefault\nooverflow\faroman\rin0\lin720\itap0 \rtlch\fcs1 \ab\af45\afs20\alang1025 \ltrch\fcs0 \b\f45\fs20\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \sbasedon0 \snext78 glossary word first;}{\s81\ql \li1080\ri0\sb120\widctlpar\wrapdefault\nooverflow\faroman\rin0\lin1080\itap0 \rtlch\fcs1 \af45\afs20\alang1025 \ltrch\fcs0 \f45\fs20\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \sbasedon78 \snext0 glossary def last;}{\s82\ql \fi-216\li2736\ri0\sb80\widctlpar\wrapdefault{\*\pn \pnlvlblt\ilvl10\ls2047\pnrnot0 \pnf5\pnstart1\pnindent216\pnhang {\pntxtb ?}}\nooverflow\faroman\ls2047\ilvl10\rin0\lin2736\itap0 \rtlch\fcs1 \af45\afs20\alang1025 \ltrch\fcs0 \f45\fs20\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \sbasedon0 \snext82 ref bullet 1;}{ \s83\ql \fi-216\li2736\ri0\sb40\widctlpar\wrapdefault{\*\pn \pnlvlblt\ilvl10\ls2047\pnrnot0\pnf5\pnstart1\pnindent216\pnhang {\pntxtb ?}}\nooverflow\faroman\ls2047\ilvl10\rin0\lin2736\itap0 \rtlch\fcs1 \af45\afs20\alang1025 \ltrch\fcs0 \f45\fs20\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \sbasedon82 \snext83 ref bullet 2;}{\s84\ql \fi-1440\li2160\ri0\sb180\widctlpar\tx2160\wrapdefault\nooverflow\faroman\rin0\lin2160\itap0 \rtlch\fcs1 \af45\afs20\alang1025 \ltrch\fcs0 \f45\fs20\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \sbasedon0 \snext84 ref para 1;}{\s85\ql \li2160\ri0\sb80\widctlpar\wrapdefault\nooverflow\faroman\rin0\lin2160\itap0 \rtlch\fcs1 \af45\afs20\alang1025 \ltrch\fcs0 \f45\fs20\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \sbasedon84 \snext84 ref para 2;}{\s86\ql \li2520\ri0\sb80\widctlpar\wrapdefault\nooverflow\faroman\rin0\lin2520\itap0 \rtlch\fcs1 \af2\afs18\alang1025 \ltrch\fcs0 \f2\fs18\lang1024\langfe1024\cgrid\noproof\langnp1033\langfenp1033 \snext86 ref prog 1;}{\s87\ql \li2520\ri0\sb40\widctlpar\wrapdefault\nooverflow\faroman\rin0\lin2520\itap0 \rtlch\fcs1 \af2\afs18\alang1025 \ltrch\fcs0 \f2\fs18\lang1024\langfe1024\cgrid\noproof\langnp1033\langfenp1033 \sbasedon86 \snext87 ref prog 2;}{\s88\ql \li2160\ri0\sb120\widctlpar\tx4770\wrapdefault\nooverflow\faroman\rin0\lin2160\itap0 \rtlch\fcs1 \af2\afs18\alang1025 \ltrch\fcs0 \f2\fs18\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \sbasedon66 \snext88 prog indent first;}{\s89\ql \li2160\ri0\sb40\widctlpar\wrapdefault\nooverflow\faroman\rin0\lin2160\itap0 \rtlch\fcs1 \af2\afs18\alang1025 \ltrch\fcs0 \f2\fs18\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \sbasedon67 \snext89 prog indent last;}{\s90\ql \li0\ri0\sb180\keepn\pagebb\widctlpar\brdrt\brdrs\brdrw30\brsp120 \tqr\tx9893\wrapdefault\nooverflow\faroman\rin0\lin0\itap0 \rtlch\fcs1 \ab\af1\afs24\alang1025 \ltrch\fcs0 \b\f1\fs24\cf9\lang1024\langfe1024\cgrid\noproof\langnp1033\langfenp1033 \sbasedon77 \snext0 ref heading;}{\s91\ql \li720\ri0\sb360\keepn\widctlpar\wrapdefault\nooverflow\faroman\rin0\lin720\itap0 \rtlch\fcs1 \ab\af1\afs20\alang1025 \ltrch\fcs0 \b\f1\fs20\cf13\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \sbasedon76 \snext0 ref heading 2;}{\s92\ql \li1440\ri0\sb120\widctlpar\wrapdefault\nooverflow\faroman\rin0\lin1440\itap0 \rtlch\fcs1 \af45\afs20\alang1025 \ltrch\fcs0 \f45\fs20\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \sbasedon41 \snext93 ref list first;}{\s93\ql \li1440\ri0\sb40\widctlpar\wrapdefault\nooverflow\faroman\rin0\lin1440\itap0 \rtlch\fcs1 \af45\afs20\alang1025 \ltrch\fcs0 \f45\fs20\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \sbasedon31 \snext93 ref list;}{\s94\ql \fi-2160\li3240\ri0\sb120\widctlpar\tx3240\wrapdefault\nooverflow\faroman\rin0\lin3240\itap0 \rtlch\fcs1 \af45\afs20\alang1025 \ltrch\fcs0 \f45\fs20\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \sbasedon43 \snext94 ref subhead first;}{\s95\ql \fi-2160\li3240\ri0\sb40\widctlpar\tx3240\wrapdefault\nooverflow\faroman\rin0\lin3240\itap0 \rtlch\fcs1 \af45\afs20\alang1025 \ltrch\fcs0 \f45\fs20\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \sbasedon0 \snext94 ref subhead last;}{\s96\ql \li1440\ri0\sb180\sa120\widctlpar\wrapdefault\nooverflow\faroman\rin0\lin1440\itap0 \rtlch\fcs1 \af45\afs20\alang1025 \ltrch\fcs0 \f45\fs20\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \sbasedon0 \snext96 \slink97 Body Text;}{\*\cs97 \additive \rtlch\fcs1 \af45\afs20 \ltrch\fcs0 \f45\fs20 \sbasedon10 \slink96 \slocked \ssemihidden Body Text Char;}{ \s98\ql \li1080\ri0\sb120\keepn\widctlpar\tqr\tldot\tx9893\wrapdefault\nooverflow\faroman\rin0\lin1080\itap0 \rtlch\fcs1 \ab\af1\afs20\alang1025 \ltrch\fcs0 \b\f1\fs20\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \sbasedon0 \snext0 \sautoupd \spriority39 toc 1;}{\s99\ql \li1440\ri1440\sb180\sa120\widctlpar\wrapdefault\nooverflow\faroman\rin1440\lin1440\itap0 \rtlch\fcs1 \af45\afs20\alang1025 \ltrch\fcs0 \f45\fs20\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \sbasedon0 \snext99 Block Text;}{\s100\ql \li360\ri0\sb180\sa120\widctlpar\wrapdefault\nooverflow\faroman\rin0\lin360\itap0 \rtlch\fcs1 \af45\afs20\alang1025 \ltrch\fcs0 \f45\fs20\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \sbasedon0 \snext100 \slink101 Body Text 2;}{\*\cs101 \additive \rtlch\fcs1 \af45\afs20 \ltrch\fcs0 \f45\fs20 \sbasedon10 \slink100 \slocked \ssemihidden Body Text 2 Char;}{ \s102\ql \li1440\ri0\sb180\sa120\widctlpar\wrapdefault\nooverflow\faroman\rin0\lin1440\itap0 \rtlch\fcs1 \af45\afs16\alang1025 \ltrch\fcs0 \f45\fs16\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \sbasedon0 \snext102 \slink103 Body Text 3;}{\*\cs103 \additive \rtlch\fcs1 \af45\afs16 \ltrch\fcs0 \f45\fs16 \sbasedon10 \slink102 \slocked \ssemihidden Body Text 3 Char;}{\s104\ql \fi210\li1440\ri0\sb180\sa120\widctlpar\wrapdefault\nooverflow\faroman\rin0\lin1440\itap0 \rtlch\fcs1 \af45\afs20\alang1025 \ltrch\fcs0 \f45\fs20\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \sbasedon96 \snext104 \slink105 Body Text First Indent;}{\*\cs105 \additive \rtlch\fcs1 \af45\afs20 \ltrch\fcs0 \f45\fs20 \sbasedon97 \slink104 \slocked \ssemihidden Body Text First Indent Char;}{\s106\ql \li283\ri0\sb180\sa120\widctlpar\wrapdefault\nooverflow\faroman\rin0\lin283\itap0 \rtlch\fcs1 \af45\afs20\alang1025 \ltrch\fcs0 \f45\fs20\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \sbasedon0 \snext106 \slink107 Body Text Indent;}{\*\cs107 \additive \rtlch\fcs1 \af45\afs20 \ltrch\fcs0 \f45\fs20 \sbasedon10 \slink106 \slocked \ssemihidden Body Text Indent Char;}{ \s108\ql \fi210\li360\ri0\sb180\sa120\widctlpar\wrapdefault\nooverflow\faroman\rin0\lin360\itap0 \rtlch\fcs1 \af45\afs20\alang1025 \ltrch\fcs0 \f45\fs20\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \sbasedon100 \snext108 \slink109 Body Text First Indent 2;}{\*\cs109 \additive \rtlch\fcs1 \af45\afs20 \ltrch\fcs0 \f45\fs20 \sbasedon107 \slink108 \slocked \ssemihidden Body Text First Indent 2 Char;}{\s110\ql \li360\ri0\sb180\sa120\sl480\slmult1 \widctlpar\wrapdefault\nooverflow\faroman\rin0\lin360\itap0 \rtlch\fcs1 \af45\afs20\alang1025 \ltrch\fcs0 \f45\fs20\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \sbasedon0 \snext110 \slink111 Body Text Indent 2;}{\*\cs111 \additive \rtlch\fcs1 \af45\afs20 \ltrch\fcs0 \f45\fs20 \sbasedon10 \slink110 \slocked \ssemihidden Body Text Indent 2 Char;}{\s112\ql \li360\ri0\sb180\sa120\widctlpar\wrapdefault\nooverflow\faroman\rin0\lin360\itap0 \rtlch\fcs1 \af45\afs16\alang1025 \ltrch\fcs0 \f45\fs16\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \sbasedon0 \snext112 \slink113 Body Text Indent 3;}{\*\cs113 \additive \rtlch\fcs1 \af45\afs16 \ltrch\fcs0 \f45\fs16 \sbasedon10 \slink112 \slocked \ssemihidden Body Text Indent 3 Char;}{ \s114\ql \li1440\ri0\sb120\sa120\widctlpar\wrapdefault\nooverflow\faroman\rin0\lin1440\itap0 \rtlch\fcs1 \ab\af45\afs20\alang1025 \ltrch\fcs0 \b\f45\fs20\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \sbasedon0 \snext0 \sqformat caption;}{ \s115\ql \li4320\ri0\sb180\widctlpar\wrapdefault\nooverflow\faroman\rin0\lin4320\itap0 \rtlch\fcs1 \af45\afs20\alang1025 \ltrch\fcs0 \f45\fs20\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \sbasedon0 \snext115 \slink116 Closing;}{\*\cs116 \additive \rtlch\fcs1 \af45\afs20 \ltrch\fcs0 \f45\fs20 \sbasedon10 \slink115 \slocked \ssemihidden Closing Char;}{\s117\ql \li1440\ri0\sb180\widctlpar\wrapdefault\nooverflow\faroman\rin0\lin1440\itap0 \rtlch\fcs1 \af45\afs20\alang1025 \ltrch\fcs0 \f45\fs20\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \sbasedon0 \snext117 \slink118 \ssemihidden annotation text;}{\*\cs118 \additive \rtlch\fcs1 \af45\afs20 \ltrch\fcs0 \f45\fs20 \sbasedon10 \slink117 \slocked \ssemihidden Comment Text Char;}{ \s119\ql \li1440\ri0\sb180\widctlpar\wrapdefault\nooverflow\faroman\rin0\lin1440\itap0 \rtlch\fcs1 \af45\afs20\alang1025 \ltrch\fcs0 \f45\fs20\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \sbasedon0 \snext0 \slink120 Date;}{\*\cs120 \additive \rtlch\fcs1 \af45\afs20 \ltrch\fcs0 \f45\fs20 \sbasedon10 \slink119 \slocked \ssemihidden Date Char;}{\s121\ql \li1440\ri0\sb180\widctlpar\wrapdefault\nooverflow\faroman\rin0\lin1440\itap0 \cbpat9 \rtlch\fcs1 \af44\afs20\alang1025 \ltrch\fcs0 \f44\fs20\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \sbasedon0 \snext121 \slink122 \ssemihidden Document Map;}{\*\cs122 \additive \rtlch\fcs1 \af44\afs16 \ltrch\fcs0 \f44\fs16 \sbasedon10 \slink121 \slocked \ssemihidden Document Map Char;}{ \s123\ql \li1440\ri0\sb180\widctlpar\wrapdefault\nooverflow\faroman\rin0\lin1440\itap0 \rtlch\fcs1 \af45\afs20\alang1025 \ltrch\fcs0 \f45\fs20\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \sbasedon0 \snext123 \slink124 \ssemihidden endnote text;}{\* \cs124 \additive \rtlch\fcs1 \af45\afs20 \ltrch\fcs0 \f45\fs20 \sbasedon10 \slink123 \slocked \ssemihidden Endnote Text Char;}{ \s125\ql \li2880\ri0\sb180\widctlpar\phpg\posxc\posyb\absh-1980\absw7920\dxfrtext180\dfrmtxtx180\dfrmtxty0\wrapdefault\nooverflow\faroman\rin0\lin2880\itap0 \rtlch\fcs1 \af1\afs24\alang1025 \ltrch\fcs0 \f1\fs24\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \sbasedon0 \snext125 envelope address;}{\s126\ql \li1440\ri0\sb180\widctlpar\wrapdefault\nooverflow\faroman\rin0\lin1440\itap0 \rtlch\fcs1 \af1\afs20\alang1025 \ltrch\fcs0 \f1\fs20\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \sbasedon0 \snext126 envelope return;}{\s127\ql \li1440\ri0\sb180\widctlpar\wrapdefault\nooverflow\faroman\rin0\lin1440\itap0 \rtlch\fcs1 \af45\afs20\alang1025 \ltrch\fcs0 \f45\fs20\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \sbasedon0 \snext127 \slink128 \ssemihidden footnote text;}{\*\cs128 \additive \rtlch\fcs1 \af45\afs20 \ltrch\fcs0 \f45\fs20 \sbasedon10 \slink127 \slocked \ssemihidden Footnote Text Char;}{ \s129\ql \fi-200\li200\ri0\sb180\widctlpar\wrapdefault\nooverflow\faroman\rin0\lin200\itap0 \rtlch\fcs1 \af45\afs20\alang1025 \ltrch\fcs0 \f45\fs20\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \sbasedon0 \snext0 \sautoupd \ssemihidden index 1;}{ \s130\ql \fi-200\li400\ri0\sb180\widctlpar\wrapdefault\nooverflow\faroman\rin0\lin400\itap0 \rtlch\fcs1 \af45\afs20\alang1025 \ltrch\fcs0 \f45\fs20\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \sbasedon0 \snext0 \sautoupd \ssemihidden index 2;}{ \s131\ql \fi-200\li600\ri0\sb180\widctlpar\wrapdefault\nooverflow\faroman\rin0\lin600\itap0 \rtlch\fcs1 \af45\afs20\alang1025 \ltrch\fcs0 \f45\fs20\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \sbasedon0 \snext0 \sautoupd \ssemihidden index 3;}{ \s132\ql \fi-200\li800\ri0\sb180\widctlpar\wrapdefault\nooverflow\faroman\rin0\lin800\itap0 \rtlch\fcs1 \af45\afs20\alang1025 \ltrch\fcs0 \f45\fs20\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \sbasedon0 \snext0 \sautoupd \ssemihidden index 4;}{ \s133\ql \fi-200\li1000\ri0\sb180\widctlpar\wrapdefault\nooverflow\faroman\rin0\lin1000\itap0 \rtlch\fcs1 \af45\afs20\alang1025 \ltrch\fcs0 \f45\fs20\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \sbasedon0 \snext0 \sautoupd \ssemihidden index 5;}{ \s134\ql \fi-200\li1200\ri0\sb180\widctlpar\wrapdefault\nooverflow\faroman\rin0\lin1200\itap0 \rtlch\fcs1 \af45\afs20\alang1025 \ltrch\fcs0 \f45\fs20\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \sbasedon0 \snext0 \sautoupd \ssemihidden index 6;}{ \s135\ql \fi-200\li1400\ri0\sb180\widctlpar\wrapdefault\nooverflow\faroman\rin0\lin1400\itap0 \rtlch\fcs1 \af45\afs20\alang1025 \ltrch\fcs0 \f45\fs20\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \sbasedon0 \snext0 \sautoupd \ssemihidden index 7;}{ \s136\ql \fi-200\li1600\ri0\sb180\widctlpar\wrapdefault\nooverflow\faroman\rin0\lin1600\itap0 \rtlch\fcs1 \af45\afs20\alang1025 \ltrch\fcs0 \f45\fs20\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \sbasedon0 \snext0 \sautoupd \ssemihidden index 8;}{ \s137\ql \fi-200\li1800\ri0\sb180\widctlpar\wrapdefault\nooverflow\faroman\rin0\lin1800\itap0 \rtlch\fcs1 \af45\afs20\alang1025 \ltrch\fcs0 \f45\fs20\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \sbasedon0 \snext0 \sautoupd \ssemihidden index 9;}{ \s138\ql \li1440\ri0\sb180\widctlpar\wrapdefault\nooverflow\faroman\rin0\lin1440\itap0 \rtlch\fcs1 \ab\af1\afs20\alang1025 \ltrch\fcs0 \b\f1\fs20\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \sbasedon0 \snext129 \ssemihidden index heading;}{ \s139\ql \fi-360\li720\ri0\sb180\widctlpar\wrapdefault\nooverflow\faroman\rin0\lin720\itap0 \rtlch\fcs1 \af45\afs20\alang1025 \ltrch\fcs0 \f45\fs20\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \sbasedon0 \snext139 List 2;}{ \s140\ql \fi-360\li1080\ri0\sb180\widctlpar\wrapdefault\nooverflow\faroman\rin0\lin1080\itap0 \rtlch\fcs1 \af45\afs20\alang1025 \ltrch\fcs0 \f45\fs20\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \sbasedon0 \snext140 List 3;}{ \s141\ql \fi-360\li1440\ri0\sb180\widctlpar\wrapdefault\nooverflow\faroman\rin0\lin1440\itap0 \rtlch\fcs1 \af45\afs20\alang1025 \ltrch\fcs0 \f45\fs20\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \sbasedon0 \snext141 List 4;}{ \s142\ql \fi-360\li1800\ri0\sb180\widctlpar\wrapdefault\nooverflow\faroman\rin0\lin1800\itap0 \rtlch\fcs1 \af45\afs20\alang1025 \ltrch\fcs0 \f45\fs20\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \sbasedon0 \snext142 List 5;}{ \s143\ql \fi-360\li360\ri0\sb180\widctlpar\jclisttab\tx360\wrapdefault{\*\pn \pnlvlbody\ilvl0\ls1\pnrnot0\pndec }\nooverflow\faroman\ls1\rin0\lin360\itap0 \rtlch\fcs1 \af45\afs20\alang1025 \ltrch\fcs0 \f45\fs20\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \sbasedon0 \snext143 \sautoupd List Bullet;}{\s144\ql \fi-360\li720\ri0\sb180\widctlpar\jclisttab\tx720\wrapdefault{\*\pn \pnlvlbody\ilvl0\ls2\pnrnot0\pndec } \nooverflow\faroman\ls2\rin0\lin720\itap0 \rtlch\fcs1 \af45\afs20\alang1025 \ltrch\fcs0 \f45\fs20\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \sbasedon0 \snext144 \sautoupd List Bullet 2;}{\s145\ql \fi-360\li1080\ri0\sb180\widctlpar \jclisttab\tx1080\wrapdefault{\*\pn \pnlvlbody\ilvl0\ls3\pnrnot0\pndec }\nooverflow\faroman\ls3\rin0\lin1080\itap0 \rtlch\fcs1 \af45\afs20\alang1025 \ltrch\fcs0 \f45\fs20\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \sbasedon0 \snext145 \sautoupd List Bullet 3;}{\s146\ql \fi-360\li1440\ri0\sb180\widctlpar\jclisttab\tx1440\wrapdefault{\*\pn \pnlvlbody\ilvl0\ls4\pnrnot0\pndec }\nooverflow\faroman\ls4\rin0\lin1440\itap0 \rtlch\fcs1 \af45\afs20\alang1025 \ltrch\fcs0 \f45\fs20\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \sbasedon0 \snext146 \sautoupd List Bullet 4;}{\s147\ql \fi-360\li1800\ri0\sb180\widctlpar\jclisttab\tx1800\wrapdefault{\*\pn \pnlvlbody\ilvl0\ls5\pnrnot0\pndec } \nooverflow\faroman\ls5\rin0\lin1800\itap0 \rtlch\fcs1 \af45\afs20\alang1025 \ltrch\fcs0 \f45\fs20\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \sbasedon0 \snext147 \sautoupd List Bullet 5;}{ \s148\ql \li360\ri0\sb180\sa120\widctlpar\wrapdefault\nooverflow\faroman\rin0\lin360\itap0 \rtlch\fcs1 \af45\afs20\alang1025 \ltrch\fcs0 \f45\fs20\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \sbasedon0 \snext148 List Continue;}{ \s149\ql \li720\ri0\sb180\sa120\widctlpar\wrapdefault\nooverflow\faroman\rin0\lin720\itap0 \rtlch\fcs1 \af45\afs20\alang1025 \ltrch\fcs0 \f45\fs20\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \sbasedon0 \snext149 List Continue 2;}{ \s150\ql \li1080\ri0\sb180\sa120\widctlpar\wrapdefault\nooverflow\faroman\rin0\lin1080\itap0 \rtlch\fcs1 \af45\afs20\alang1025 \ltrch\fcs0 \f45\fs20\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \sbasedon0 \snext150 List Continue 3;}{ \s151\ql \li1440\ri0\sb180\sa120\widctlpar\wrapdefault\nooverflow\faroman\rin0\lin1440\itap0 \rtlch\fcs1 \af45\afs20\alang1025 \ltrch\fcs0 \f45\fs20\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \sbasedon0 \snext151 List Continue 4;}{ \s152\ql \li1800\ri0\sb180\sa120\widctlpar\wrapdefault\nooverflow\faroman\rin0\lin1800\itap0 \rtlch\fcs1 \af45\afs20\alang1025 \ltrch\fcs0 \f45\fs20\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \sbasedon0 \snext152 List Continue 5;}{ \s153\ql \fi-360\li720\ri0\sb180\widctlpar\jclisttab\tx720\wrapdefault{\*\pn \pnlvlbody\ilvl0\ls6\pnrnot0\pndec }\nooverflow\faroman\ls6\rin0\lin720\itap0 \rtlch\fcs1 \af45\afs20\alang1025 \ltrch\fcs0 \f45\fs20\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \sbasedon0 \snext153 List Number 2;}{\s154\ql \fi-360\li1080\ri0\sb180\widctlpar\jclisttab\tx1080\wrapdefault{\*\pn \pnlvlbody\ilvl0\ls7\pnrnot0\pndec }\nooverflow\faroman\ls7\rin0\lin1080\itap0 \rtlch\fcs1 \af45\afs20\alang1025 \ltrch\fcs0 \f45\fs20\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \sbasedon0 \snext154 List Number 3;}{\s155\ql \fi-360\li1440\ri0\sb180\widctlpar\jclisttab\tx1440\wrapdefault{\*\pn \pnlvlbody\ilvl0\ls8\pnrnot0 \pndec }\nooverflow\faroman\ls8\rin0\lin1440\itap0 \rtlch\fcs1 \af45\afs20\alang1025 \ltrch\fcs0 \f45\fs20\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \sbasedon0 \snext155 List Number 4;}{\s156\ql \fi-360\li1800\ri0\sb180\widctlpar \jclisttab\tx1800\wrapdefault{\*\pn \pnlvlbody\ilvl0\ls9\pnrnot0\pndec }\nooverflow\faroman\ls9\rin0\lin1800\itap0 \rtlch\fcs1 \af45\afs20\alang1025 \ltrch\fcs0 \f45\fs20\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \sbasedon0 \snext156 List Number 5;}{\s157\ql \li1440\ri0\sb180\widctlpar\tx480\tx960\tx1440\tx1920\tx2400\tx2880\tx3360\tx3840\tx4320\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin1440\itap0 \rtlch\fcs1 \af2\afs20\alang1025 \ltrch\fcs0 \f2\fs20\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \snext157 \slink158 \ssemihidden macro;}{\*\cs158 \additive \rtlch\fcs1 \af2\afs20 \ltrch\fcs0 \f2\fs20 \sbasedon10 \slink157 \slocked \ssemihidden Macro Text Char;}{ \s159\ql \fi-1080\li1080\ri0\sb180\widctlpar\brdrt\brdrs\brdrw15\brsp20 \brdrl\brdrs\brdrw15\brsp20 \brdrb\brdrs\brdrw15\brsp20 \brdrr\brdrs\brdrw15\brsp20 \wrapdefault\nooverflow\faroman\rin0\lin1080\itap0 \shading2000 \rtlch\fcs1 \af1\afs24\alang1025 \ltrch\fcs0 \f1\fs24\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \sbasedon0 \snext159 \slink160 Message Header;}{\*\cs160 \additive \rtlch\fcs1 \af0\afs24 \ltrch\fcs0 \f43\fs24\chshdng2000\chcfpat0\chcbpat0 \sbasedon10 \slink159 \slocked \ssemihidden Message Header Char;}{\s161\ql \li1440\ri0\sb180\widctlpar\wrapdefault\nooverflow\faroman\rin0\lin1440\itap0 \rtlch\fcs1 \af45\afs20\alang1025 \ltrch\fcs0 \f45\fs20\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \sbasedon0 \snext0 \slink162 Note Heading;}{\*\cs162 \additive \rtlch\fcs1 \af45\afs20 \ltrch\fcs0 \f45\fs20 \sbasedon10 \slink161 \slocked \ssemihidden Note Heading Char;}{ \s163\ql \li1440\ri0\sb180\widctlpar\wrapdefault\nooverflow\faroman\rin0\lin1440\itap0 \rtlch\fcs1 \af2\afs20\alang1025 \ltrch\fcs0 \f2\fs20\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \sbasedon0 \snext163 \slink164 Plain Text;}{\*\cs164 \additive \rtlch\fcs1 \af2\afs20 \ltrch\fcs0 \f2\fs20 \sbasedon10 \slink163 \slocked \ssemihidden Plain Text Char;}{\s165\ql \li1440\ri0\sb180\widctlpar\wrapdefault\nooverflow\faroman\rin0\lin1440\itap0 \rtlch\fcs1 \af45\afs20\alang1025 \ltrch\fcs0 \f45\fs20\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \sbasedon0 \snext0 \slink166 Salutation;}{\*\cs166 \additive \rtlch\fcs1 \af45\afs20 \ltrch\fcs0 \f45\fs20 \sbasedon10 \slink165 \slocked \ssemihidden Salutation Char;}{ \s167\ql \li4320\ri0\sb180\widctlpar\wrapdefault\nooverflow\faroman\rin0\lin4320\itap0 \rtlch\fcs1 \af45\afs20\alang1025 \ltrch\fcs0 \f45\fs20\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \sbasedon0 \snext167 \slink168 Signature;}{\*\cs168 \additive \rtlch\fcs1 \af45\afs20 \ltrch\fcs0 \f45\fs20 \sbasedon10 \slink167 \slocked \ssemihidden Signature Char;}{\s169\qc \li1440\ri0\sb180\sa60\widctlpar\wrapdefault\nooverflow\faroman\outlinelevel1\rin0\lin1440\itap0 \rtlch\fcs1 \af1\afs24\alang1025 \ltrch\fcs0 \f1\fs24\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \sbasedon0 \snext169 \slink170 \sqformat Subtitle;}{\*\cs170 \additive \rtlch\fcs1 \af0\afs24 \ltrch\fcs0 \f43\fs24 \sbasedon10 \slink169 \slocked Subtitle Char;}{ \s171\ql \fi-200\li200\ri0\sb180\widctlpar\wrapdefault\nooverflow\faroman\rin0\lin200\itap0 \rtlch\fcs1 \af45\afs20\alang1025 \ltrch\fcs0 \f45\fs20\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \sbasedon0 \snext0 \ssemihidden table of authorities;}{ \s172\ql \fi-400\li400\ri0\sb180\widctlpar\wrapdefault\nooverflow\faroman\rin0\lin400\itap0 \rtlch\fcs1 \af45\afs20\alang1025 \ltrch\fcs0 \f45\fs20\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \sbasedon0 \snext0 \ssemihidden table of figures;}{ \s173\qc \li1440\ri0\sb240\sa60\widctlpar\wrapdefault\nooverflow\faroman\outlinelevel0\rin0\lin1440\itap0 \rtlch\fcs1 \ab\af1\afs32\alang1025 \ltrch\fcs0 \b\f1\fs32\lang1033\langfe1033\kerning28\cgrid\langnp1033\langfenp1033 \sbasedon0 \snext173 \slink174 \sqformat Title;}{\*\cs174 \additive \rtlch\fcs1 \ab\af0\afs32 \ltrch\fcs0 \b\f43\fs32\kerning28 \sbasedon10 \slink173 \slocked Title Char;}{ \s175\ql \li1440\ri0\sb120\widctlpar\wrapdefault\nooverflow\faroman\rin0\lin1440\itap0 \rtlch\fcs1 \ab\af1\afs24\alang1025 \ltrch\fcs0 \b\f1\fs24\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \sbasedon0 \snext0 \ssemihidden toa heading;}{ \s176\ql \li1440\ri0\sb180\widctlpar\tqr\tldot\tx9883\wrapdefault\nooverflow\faroman\rin0\lin1440\itap0 \rtlch\fcs1 \af45\afs20\alang1025 \ltrch\fcs0 \f45\fs20\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \sbasedon0 \snext0 \sautoupd \spriority39 toc 2;}{\s177\ql \li400\ri0\sb180\widctlpar\wrapdefault\nooverflow\faroman\rin0\lin400\itap0 \rtlch\fcs1 \af45\afs20\alang1025 \ltrch\fcs0 \f45\fs20\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \sbasedon0 \snext0 \sautoupd \ssemihidden toc 3;}{ \s178\ql \li600\ri0\sb180\widctlpar\wrapdefault\nooverflow\faroman\rin0\lin600\itap0 \rtlch\fcs1 \af45\afs20\alang1025 \ltrch\fcs0 \f45\fs20\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \sbasedon0 \snext0 \sautoupd \ssemihidden toc 4;}{ \s179\ql \li800\ri0\sb180\widctlpar\wrapdefault\nooverflow\faroman\rin0\lin800\itap0 \rtlch\fcs1 \af45\afs20\alang1025 \ltrch\fcs0 \f45\fs20\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \sbasedon0 \snext0 \sautoupd \ssemihidden toc 5;}{ \s180\ql \li1000\ri0\sb180\widctlpar\wrapdefault\nooverflow\faroman\rin0\lin1000\itap0 \rtlch\fcs1 \af45\afs20\alang1025 \ltrch\fcs0 \f45\fs20\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \sbasedon0 \snext0 \sautoupd \ssemihidden toc 6;}{ \s181\ql \li1200\ri0\sb180\widctlpar\wrapdefault\nooverflow\faroman\rin0\lin1200\itap0 \rtlch\fcs1 \af45\afs20\alang1025 \ltrch\fcs0 \f45\fs20\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \sbasedon0 \snext0 \sautoupd \ssemihidden toc 7;}{ \s182\ql \li1400\ri0\sb180\widctlpar\wrapdefault\nooverflow\faroman\rin0\lin1400\itap0 \rtlch\fcs1 \af45\afs20\alang1025 \ltrch\fcs0 \f45\fs20\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \sbasedon0 \snext0 \sautoupd \ssemihidden toc 8;}{ \s183\ql \li1600\ri0\sb180\widctlpar\wrapdefault\nooverflow\faroman\rin0\lin1600\itap0 \rtlch\fcs1 \af45\afs20\alang1025 \ltrch\fcs0 \f45\fs20\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \sbasedon0 \snext0 \sautoupd \ssemihidden toc 9;}{ \s184\ql \li1440\ri0\sb180\widctlpar\wrapdefault\nooverflow\faroman\rin0\lin1440\itap0 \rtlch\fcs1 \af44\afs16\alang1025 \ltrch\fcs0 \f44\fs16\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \sbasedon0 \snext184 \slink185 \ssemihidden Balloon Text;}{\* \cs185 \additive \rtlch\fcs1 \af44\afs16 \ltrch\fcs0 \f44\fs16 \sbasedon10 \slink184 \slocked \ssemihidden Balloon Text Char;}{\*\ts186\tsrowd\trbrdrt\brdrs\brdrw10 \trbrdrl\brdrs\brdrw10 \trbrdrb\brdrs\brdrw10 \trbrdrr\brdrs\brdrw10 \trbrdrh \brdrs\brdrw10 \trbrdrv\brdrs\brdrw10 \trftsWidthB3\trpaddl108\trpaddr108\trpaddfl3\trpaddft3\trpaddfb3\trpaddfr3\trcbpat1\trcfpat1\tblind0\tblindtype3\tsvertalt\tsbrdrt\tsbrdrl\tsbrdrb\tsbrdrr\tsbrdrdgl\tsbrdrdgr\tsbrdrh\tsbrdrv \ql \li1440\ri0\sb180\widctlpar\wrapdefault\nooverflow\faroman\rin0\lin1440\itap0 \rtlch\fcs1 \af0\afs20\alang1025 \ltrch\fcs0 \fs20\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \sbasedon11 \snext186 Table Grid;}{\*\cs187 \additive \rtlch\fcs1 \af0 \ltrch\fcs0 \ul\cf2 \sbasedon10 Hyperlink;}{\*\cs188 \additive \rtlch\fcs1 \af0\afs19 \ltrch\fcs0 \fs19 \sbasedon10 postbody1;}{\s189\ql \li0\ri0\keepn\pagebb\widctlpar\brdrt\brdrs\brdrw30\brsp120 \wrapdefault\nooverflow\faroman\outlinelevel0\rin0\lin0\itap0 \rtlch\fcs1 \ab\af1\afs24\alang1025 \ltrch\fcs0 \b\f1\fs24\cf9\lang1024\langfe1024\cgrid\noproof\langnp1033\langfenp1033 \sbasedon1 \snext189 \slink190 TWAIN Header;}{\*\cs190 \additive \rtlch\fcs1 \ab\af1\afs24 \ltrch\fcs0 \b\f1\fs24\cf9\lang1024\langfe1024\kerning32\noproof \sbasedon15 \slink189 \slocked TWAIN Header Char;}{\s191\ql \li720\ri0\sb360\sl240\slmult0\widctlpar\tx720\wrapdefault\hyphpar0\faauto\rin0\lin720\itap0 \rtlch\fcs1 \af45\afs20\alang1025 \ltrch\fcs0 \f45\fs20\cf1\lang1033\langfe1033\charscalex0\cgrid\langnp1033\langfenp1033 \snext191 body;}{\s192\ql \li1440\ri0\sb120\sl240\slmult0\widctlpar \tx720\tx1080\tx1440\tx1800\tx2160\tx2520\tx2880\tx3240\tx3600\tx3960\tx4320\tx4680\tx5040\tx5400\tx5760\tx6120\tx6480\tx6840\tx7200\tx7560\tx7920\tx8280\tx8640\tx9000\wrapdefault\hyphpar0\faauto\rin0\lin1440\itap0 \rtlch\fcs1 \af49\afs20\alang1025 \ltrch\fcs0 \f49\fs20\cf1\lang1033\langfe1033\charscalex0\cgrid\langnp1033\langfenp1033 \snext0 Code;}{\s193\ql \fi-3240\li4680\ri0\sb120\sl240\slmult0\widctlpar\tx4680\tx7400\wrapdefault\hyphpar0\faauto\rin0\lin4680\itap0 \rtlch\fcs1 \af45\afs20\alang1025 \ltrch\fcs0 \f45\fs20\cf1\lang1033\langfe1033\charscalex0\cgrid\langnp1033\langfenp1033 \snext31 twocol;}{\*\cs194 \additive \f2 Code2;}{\s195\ql \li0\ri0\widctlpar\wrapdefault\faauto\adjustright\rin0\lin0\itap0 \rtlch\fcs1 \af0\afs24\alang1025 \ltrch\fcs0 \fs24\cf1\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \sbasedon0 \snext195 Default;}{\*\cs196 \additive \rtlch\fcs1 \af0 \ltrch\fcs0 \sbasedon10 \spriority0 postbody;}{\*\cs197 \additive \rtlch\fcs1 \af0 \ltrch\fcs0 \ul\cf19 \sbasedon10 \slocked \ssemihidden \sunhideused FollowedHyperlink;}{\s198\ql \li60\ri60\sb80\sa80\sl240\slmult0\widctlpar\tx720\tx2520\wrapdefault\hyphpar0\faauto\rin60\lin60\itap0 \rtlch\fcs1 \af2\afs20\alang1025 \ltrch\fcs0 \fs20\cf1\lang1033\langfe2052\loch\f2\hich\af2\dbch\af31505\charscalex0\cgrid\langnp1033\langfenp2052 \snext198 table_code;}{\s199\ql \li720\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin720\itap0 \rtlch\fcs1 \af37\afs22\alang1025 \ltrch\fcs0 \f37\fs22\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \sbasedon0 \snext199 \sqformat \spriority34 List Paragraph;}{\*\cs200 \additive \rtlch\fcs1 \af0 \ltrch\fcs0 \cf20\chshdng0\chcfpat0\chcbpat21 \sbasedon10 \ssemihidden \sunhideused Unresolved Mention;}}{\*\listtable{\list\listtemplateid-537102814\listsimple{\listlevel\levelnfc0\levelnfcn0\leveljc0\leveljcn0\levelfollow0\levelstartat1\levelspace0\levelindent0{\leveltext\'02\'00.;}{\levelnumbers\'01;}\rtlch\fcs1 \af0 \ltrch\fcs0 \fi-360\li1440\jclisttab\tx1440\lin1440 }{\listname ;}\listid-131}{\list\listtemplateid-241933882\listsimple{\listlevel\levelnfc0\levelnfcn0\leveljc0\leveljcn0\levelfollow0\levelstartat1\levelspace0\levelindent0{\leveltext\'02\'00.;}{\levelnumbers\'01;} \rtlch\fcs1 \af0 \ltrch\fcs0 \fi-360\li1080\jclisttab\tx1080\lin1080 }{\listname ;}\listid-130}{\list\listtemplateid894471834\listsimple{\listlevel\levelnfc0\levelnfcn0\leveljc0\leveljcn0\levelfollow0\levelstartat1\levelspace0\levelindent0{\leveltext \'02\'00.;}{\levelnumbers\'01;}\rtlch\fcs1 \af0 \ltrch\fcs0 \fi-360\li720\jclisttab\tx720\lin720 }{\listname ;}\listid-129}{\list\listtemplateid-1633241602\listsimple{\listlevel\levelnfc23\levelnfcn23\leveljc0\leveljcn0\levelfollow0\levelstartat1 \levelspace0\levelindent0{\leveltext\'01\u-3913 ?;}{\levelnumbers;}\f3\fbias0 \fi-360\li1800\jclisttab\tx1800\lin1800 }{\listname ;}\listid-128}{\list\listtemplateid-203631750\listsimple{\listlevel\levelnfc23\levelnfcn23\leveljc0\leveljcn0\levelfollow0 \levelstartat1\levelspace0\levelindent0{\leveltext\'01\u-3913 ?;}{\levelnumbers;}\f3\fbias0 \fi-360\li1440\jclisttab\tx1440\lin1440 }{\listname ;}\listid-127}{\list\listtemplateid360335964\listsimple{\listlevel\levelnfc23\levelnfcn23\leveljc0\leveljcn0 \levelfollow0\levelstartat1\levelspace0\levelindent0{\leveltext\'01\u-3913 ?;}{\levelnumbers;}\f3\fbias0 \fi-360\li1080\jclisttab\tx1080\lin1080 }{\listname ;}\listid-126}{\list\listtemplateid627448582\listsimple{\listlevel\levelnfc23\levelnfcn23\leveljc0 \leveljcn0\levelfollow0\levelstartat1\levelspace0\levelindent0{\leveltext\'01\u-3913 ?;}{\levelnumbers;}\f3\fbias0 \fi-360\li720\jclisttab\tx720\lin720 }{\listname ;}\listid-125}{\list\listtemplateid507960418\listsimple{\listlevel\levelnfc0\levelnfcn0 \leveljc0\leveljcn0\levelfollow0\levelstartat1\levelspace0\levelindent0{\leveltext\'02\'00.;}{\levelnumbers\'01;}\rtlch\fcs1 \af0 \ltrch\fcs0 \fi-360\li360\jclisttab\tx360\lin360 }{\listname ;}\listid-120}{\list\listtemplateid-1407048446\listsimple {\listlevel\levelnfc23\levelnfcn23\leveljc0\leveljcn0\levelfollow0\levelstartat1\levelspace0\levelindent0{\leveltext\'01\u-3913 ?;}{\levelnumbers;}\f3\fbias0 \fi-360\li360\jclisttab\tx360\lin360 }{\listname ;}\listid-119}{\list\listtemplateid-950138062 \listhybrid{\listlevel\levelnfc23\levelnfcn23\leveljc0\leveljcn0\levelfollow0\levelstartat0\levelspace0\levelindent0{\leveltext\leveltemplateid-129700622\'01-;}{\levelnumbers;}\loch\af37\hich\af37\dbch\af0\fbias0 \fi-360\li720\lin720 }{\listlevel \levelnfc23\levelnfcn23\leveljc0\leveljcn0\levelfollow0\levelstartat1\lvltentative\levelspace0\levelindent0{\leveltext\leveltemplateid67698691\'01o;}{\levelnumbers;}\f2\fbias0 \fi-360\li1440\lin1440 }{\listlevel\levelnfc23\levelnfcn23\leveljc0\leveljcn0 \levelfollow0\levelstartat1\lvltentative\levelspace0\levelindent0{\leveltext\leveltemplateid67698693\'01\u-3929 ?;}{\levelnumbers;}\f10\fbias0 \fi-360\li2160\lin2160 }{\listlevel\levelnfc23\levelnfcn23\leveljc0\leveljcn0\levelfollow0\levelstartat1 \lvltentative\levelspace0\levelindent0{\leveltext\leveltemplateid67698689\'01\u-3913 ?;}{\levelnumbers;}\f3\fbias0 \fi-360\li2880\lin2880 }{\listlevel\levelnfc23\levelnfcn23\leveljc0\leveljcn0\levelfollow0\levelstartat1\lvltentative\levelspace0 \levelindent0{\leveltext\leveltemplateid67698691\'01o;}{\levelnumbers;}\f2\fbias0 \fi-360\li3600\lin3600 }{\listlevel\levelnfc23\levelnfcn23\leveljc0\leveljcn0\levelfollow0\levelstartat1\lvltentative\levelspace0\levelindent0{\leveltext \leveltemplateid67698693\'01\u-3929 ?;}{\levelnumbers;}\f10\fbias0 \fi-360\li4320\lin4320 }{\listlevel\levelnfc23\levelnfcn23\leveljc0\leveljcn0\levelfollow0\levelstartat1\lvltentative\levelspace0\levelindent0{\leveltext\leveltemplateid67698689 \'01\u-3913 ?;}{\levelnumbers;}\f3\fbias0 \fi-360\li5040\lin5040 }{\listlevel\levelnfc23\levelnfcn23\leveljc0\leveljcn0\levelfollow0\levelstartat1\lvltentative\levelspace0\levelindent0{\leveltext\leveltemplateid67698691\'01o;}{\levelnumbers;}\f2\fbias0 \fi-360\li5760\lin5760 }{\listlevel\levelnfc23\levelnfcn23\leveljc0\leveljcn0\levelfollow0\levelstartat1\lvltentative\levelspace0\levelindent0{\leveltext\leveltemplateid67698693\'01\u-3929 ?;}{\levelnumbers;}\f10\fbias0 \fi-360\li6480\lin6480 }{\listname ;}\listid162478944}{\list\listtemplateid181715488\listhybrid{\listlevel\levelnfc23\levelnfcn23\leveljc0\leveljcn0\levelfollow0\levelstartat0\levelspace0\levelindent0{\leveltext\leveltemplateid1324631620\'01-;}{\levelnumbers;} \loch\af0\hich\af0\dbch\af0\fbias0 \fi-360\li720\lin720 }{\listlevel\levelnfc23\levelnfcn23\leveljc0\leveljcn0\levelfollow0\levelstartat1\lvltentative\levelspace0\levelindent0{\leveltext\leveltemplateid67698691\'01o;}{\levelnumbers;}\f2\fbias0 \fi-360\li1440\lin1440 }{\listlevel\levelnfc23\levelnfcn23\leveljc0\leveljcn0\levelfollow0\levelstartat1\lvltentative\levelspace0\levelindent0{\leveltext\leveltemplateid67698693\'01\u-3929 ?;}{\levelnumbers;}\f10\fbias0 \fi-360\li2160\lin2160 }{\listlevel \levelnfc23\levelnfcn23\leveljc0\leveljcn0\levelfollow0\levelstartat1\lvltentative\levelspace0\levelindent0{\leveltext\leveltemplateid67698689\'01\u-3913 ?;}{\levelnumbers;}\f3\fbias0 \fi-360\li2880\lin2880 }{\listlevel\levelnfc23\levelnfcn23\leveljc0 \leveljcn0\levelfollow0\levelstartat1\lvltentative\levelspace0\levelindent0{\leveltext\leveltemplateid67698691\'01o;}{\levelnumbers;}\f2\fbias0 \fi-360\li3600\lin3600 }{\listlevel\levelnfc23\levelnfcn23\leveljc0\leveljcn0\levelfollow0\levelstartat1 \lvltentative\levelspace0\levelindent0{\leveltext\leveltemplateid67698693\'01\u-3929 ?;}{\levelnumbers;}\f10\fbias0 \fi-360\li4320\lin4320 }{\listlevel\levelnfc23\levelnfcn23\leveljc0\leveljcn0\levelfollow0\levelstartat1\lvltentative\levelspace0 \levelindent0{\leveltext\leveltemplateid67698689\'01\u-3913 ?;}{\levelnumbers;}\f3\fbias0 \fi-360\li5040\lin5040 }{\listlevel\levelnfc23\levelnfcn23\leveljc0\leveljcn0\levelfollow0\levelstartat1\lvltentative\levelspace0\levelindent0{\leveltext \leveltemplateid67698691\'01o;}{\levelnumbers;}\f2\fbias0 \fi-360\li5760\lin5760 }{\listlevel\levelnfc23\levelnfcn23\leveljc0\leveljcn0\levelfollow0\levelstartat1\lvltentative\levelspace0\levelindent0{\leveltext\leveltemplateid67698693 \'01\u-3929 ?;}{\levelnumbers;}\f10\fbias0 \fi-360\li6480\lin6480 }{\listname ;}\listid984241419}{\list\listtemplateid81190112\listhybrid{\listlevel\levelnfc0\levelnfcn0\leveljc0\leveljcn0\levelfollow0\levelstartat1\levelspace0\levelindent0{\leveltext \leveltemplateid1970803460\'02\'00);}{\levelnumbers\'01;}\rtlch\fcs1 \af0 \ltrch\fcs0 \fs22\cf22\loch\af37\hich\af37\dbch\af0\fbias0 \fi-360\li720\lin720 }{\listlevel\levelnfc4\levelnfcn4\leveljc0\leveljcn0\levelfollow0\levelstartat1\levelspace0 \levelindent0{\leveltext\leveltemplateid67698713\'02\'01.;}{\levelnumbers\'01;}\rtlch\fcs1 \af0 \ltrch\fcs0 \fi-360\li1440\lin1440 }{\listlevel\levelnfc2\levelnfcn2\leveljc2\leveljcn2\levelfollow0\levelstartat1\levelspace0\levelindent0{\leveltext \leveltemplateid67698715\'02\'02.;}{\levelnumbers\'01;}\rtlch\fcs1 \af0 \ltrch\fcs0 \fi-180\li2160\lin2160 }{\listlevel\levelnfc0\levelnfcn0\leveljc0\leveljcn0\levelfollow0\levelstartat1\levelspace0\levelindent0{\leveltext\leveltemplateid67698703 \'02\'03.;}{\levelnumbers\'01;}\rtlch\fcs1 \af0 \ltrch\fcs0 \fi-360\li2880\lin2880 }{\listlevel\levelnfc4\levelnfcn4\leveljc0\leveljcn0\levelfollow0\levelstartat1\levelspace0\levelindent0{\leveltext\leveltemplateid67698713\'02\'04.;}{\levelnumbers\'01;} \rtlch\fcs1 \af0 \ltrch\fcs0 \fi-360\li3600\lin3600 }{\listlevel\levelnfc2\levelnfcn2\leveljc2\leveljcn2\levelfollow0\levelstartat1\levelspace0\levelindent0{\leveltext\leveltemplateid67698715\'02\'05.;}{\levelnumbers\'01;}\rtlch\fcs1 \af0 \ltrch\fcs0 \fi-180\li4320\lin4320 }{\listlevel\levelnfc0\levelnfcn0\leveljc0\leveljcn0\levelfollow0\levelstartat1\levelspace0\levelindent0{\leveltext\leveltemplateid67698703\'02\'06.;}{\levelnumbers\'01;}\rtlch\fcs1 \af0 \ltrch\fcs0 \fi-360\li5040\lin5040 } {\listlevel\levelnfc4\levelnfcn4\leveljc0\leveljcn0\levelfollow0\levelstartat1\levelspace0\levelindent0{\leveltext\leveltemplateid67698713\'02\'07.;}{\levelnumbers\'01;}\rtlch\fcs1 \af0 \ltrch\fcs0 \fi-360\li5760\lin5760 }{\listlevel\levelnfc2\levelnfcn2 \leveljc2\leveljcn2\levelfollow0\levelstartat1\levelspace0\levelindent0{\leveltext\leveltemplateid67698715\'02\'08.;}{\levelnumbers\'01;}\rtlch\fcs1 \af0 \ltrch\fcs0 \fi-180\li6480\lin6480 }{\listname ;}\listid2094470365}}{\*\listoverridetable {\listoverride\listid-120\listoverridecount0\ls1}{\listoverride\listid-119\listoverridecount0\ls2}{\listoverride\listid-125\listoverridecount0\ls3}{\listoverride\listid-126\listoverridecount0\ls4}{\listoverride\listid-127\listoverridecount0\ls5} {\listoverride\listid-128\listoverridecount0\ls6}{\listoverride\listid-129\listoverridecount0\ls7}{\listoverride\listid-130\listoverridecount0\ls8}{\listoverride\listid-131\listoverridecount0\ls9}{\listoverride\listid2094470365 \listoverridecount9{\lfolevel\listoverridestartat\levelstartat1}{\lfolevel\listoverridestartat\levelstartat1}{\lfolevel\listoverridestartat\levelstartat1}{\lfolevel\listoverridestartat\levelstartat1}{\lfolevel\listoverridestartat\levelstartat1}{\lfolevel \listoverridestartat\levelstartat1}{\lfolevel\listoverridestartat\levelstartat1}{\lfolevel\listoverridestartat\levelstartat1}{\lfolevel\listoverridestartat\levelstartat1}\ls10}{\listoverride\listid984241419\listoverridecount0\ls11} {\listoverride\listid162478944\listoverridecount0\ls12}}{\*\pgptbl {\pgp\ipgp0\itap0\li0\ri0\sb0\sa0}{\pgp\ipgp0\itap0\li0\ri0\sb0\sa0}{\pgp\ipgp0\itap0\li0\ri0\sb0\sa0}{\pgp\ipgp0\itap0\li0\ri0\sb0\sa0}{\pgp\ipgp0\itap0\li0\ri0\sb0\sa0}{\pgp\ipgp0\itap0 \li0\ri0\sb0\sa0}{\pgp\ipgp0\itap0\li0\ri0\sb0\sa0}{\pgp\ipgp0\itap0\li0\ri0\sb0\sa0}{\pgp\ipgp0\itap0\li0\ri0\sb0\sa0}{\pgp\ipgp0\itap0\li0\ri0\sb0\sa0}{\pgp\ipgp0\itap0\li0\ri0\sb0\sa0}{\pgp\ipgp0\itap0\li0\ri0\sb0\sa0}{\pgp\ipgp0\itap0\li0\ri0\sb0\sa0} {\pgp\ipgp0\itap0\li0\ri0\sb0\sa0}{\pgp\ipgp0\itap0\li0\ri0\sb0\sa0}}{\*\rsidtbl \rsid472724\rsid1196296\rsid6441407\rsid6555766\rsid6896082\rsid8668465}{\mmathPr\mmathFont34\mbrkBin0\mbrkBinSub0\msmallFrac0\mdispDef1\mlMargin0\mrMargin0\mdefJc1 \mwrapIndent1440\mintLim0\mnaryLim1}{\info{\title Spec 1.9a - Title page}{\author The TWAIN Working Group}{\operator l252353}{\creatim\yr2013\mo11\dy4\hr16\min24}{\revtim\yr2021\mo11\dy8\hr7\min25}{\printim\yr2010\mo7\dy28\hr8\min8}{\version45} {\edmins182}{\nofpages15}{\nofwords5071}{\nofchars28907}{\*\company JFL Peripheral Solutions Inc.}{\nofcharsws33911}{\vern21}}{\*\xmlnstbl {\xmlns1 http://schemas.microsoft.com/office/word/2003/wordml}} \paperw12240\paperh15840\margl1260\margr1080\margt1440\margb1080\gutter0\ltrsect\rtlgutter \widowctrl\ftnbj\aenddoc\trackmoves0\trackformatting1\donotembedsysfont0\relyonvml0\donotembedlingdata1\grfdocevents0\validatexml0\showplaceholdtext0\ignoremixedcontent0\saveinvalidxml0\showxmlerrors0\margmirror \noextrasprl\cvmme\sprsspbf\brkfrm\swpbdr\noxlattoyen\expshrtn\noultrlspc\dntblnsbdb\nospaceforul\lytprtmet\hyphcaps0\horzdoc\fracwidth\dghspace180\dgvspace180\dghorigin1701\dgvorigin1984\dghshow0\dgvshow0 \jexpand\viewkind1\viewscale100\pgbrdrhead\pgbrdrfoot\bdrrlswsix\nolnhtadjtbl\rsidroot8668465 \fet0{\*\wgrffmtfilter 013f}\ilfomacatclnup12{\*\ftnsep \ltrpar \pard\plain \ltrpar \ql \li1440\ri0\sb180\widctlpar\wrapdefault\nooverflow\faroman\rin0\lin1440\itap0 \rtlch\fcs1 \af45\afs20\alang1025 \ltrch\fcs0 \f45\fs20\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 {\rtlch\fcs1 \af45 \ltrch\fcs0 \insrsid6555766 \chftnsep \par }}{\*\ftnsepc \ltrpar \pard\plain \ltrpar\ql \li1440\ri0\sb180\widctlpar\wrapdefault\nooverflow\faroman\rin0\lin1440\itap0 \rtlch\fcs1 \af45\afs20\alang1025 \ltrch\fcs0 \f45\fs20\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 {\rtlch\fcs1 \af45 \ltrch\fcs0 \insrsid6555766 \chftnsepc \par }}{\*\aftnsep \ltrpar \pard\plain \ltrpar\ql \li1440\ri0\sb180\widctlpar\wrapdefault\nooverflow\faroman\rin0\lin1440\itap0 \rtlch\fcs1 \af45\afs20\alang1025 \ltrch\fcs0 \f45\fs20\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 {\rtlch\fcs1 \af45 \ltrch\fcs0 \insrsid6555766 \chftnsep \par }}{\*\aftnsepc \ltrpar \pard\plain \ltrpar\ql \li1440\ri0\sb180\widctlpar\wrapdefault\nooverflow\faroman\rin0\lin1440\itap0 \rtlch\fcs1 \af45\afs20\alang1025 \ltrch\fcs0 \f45\fs20\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 {\rtlch\fcs1 \af45 \ltrch\fcs0 \insrsid6555766 \chftnsepc \par }}\ltrpar \sectd \ltrsect\rtlgutter\psz1\linex0\endnhere\pgbrdropt32\sectdefaultcl\sectrsid6896082\sftnbj {\footerr \ltrpar \pard\plain \ltrpar\s25\ql \li0\ri0\widctlpar\tqr\tx9900\wrapdefault\nooverflow\faroman\rin0\lin0\itap0 \rtlch\fcs1 \ai\af1\afs16\alang1025 \ltrch\fcs0 \i\f1\fs16\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 {\rtlch\fcs1 \af1 \ltrch\fcs0 \insrsid6441407 TWAIN for C#\tab }{\field{\*\fldinst {\rtlch\fcs1 \af1 \ltrch\fcs0 \cs32\insrsid6441407 PAGE }}{\fldrslt { \rtlch\fcs1 \af1 \ltrch\fcs0 \cs32\lang1024\langfe1024\noproof\insrsid6441407 11}}}\sectd \ltrsect\linex0\endnhere\sectdefaultcl\sftnbj {\rtlch\fcs1 \af1 \ltrch\fcs0 \cs32\insrsid6441407 \par Kodak Alaris Inc.}{\rtlch\fcs1 \af1 \ltrch\fcs0 \insrsid6441407 \par }}{\*\pnseclvl1\pnucrm\pnstart1\pnindent720\pnhang {\pntxta .}}{\*\pnseclvl2\pnucltr\pnstart1\pnindent720\pnhang {\pntxta .}}{\*\pnseclvl3\pndec\pnstart1\pnindent720\pnhang {\pntxta .}}{\*\pnseclvl4\pnlcltr\pnstart1\pnindent720\pnhang {\pntxta )}} {\*\pnseclvl5\pndec\pnstart1\pnindent720\pnhang {\pntxtb (}{\pntxta )}}{\*\pnseclvl6\pnlcltr\pnstart1\pnindent720\pnhang {\pntxtb (}{\pntxta )}}{\*\pnseclvl7\pnlcrm\pnstart1\pnindent720\pnhang {\pntxtb (}{\pntxta )}}{\*\pnseclvl8 \pnlcltr\pnstart1\pnindent720\pnhang {\pntxtb (}{\pntxta )}}{\*\pnseclvl9\pnlcrm\pnstart1\pnindent720\pnhang {\pntxtb (}{\pntxta )}}\pard\plain \ltrpar\ql \li0\ri0\sb1440\widctlpar\brdrt\brdrs\brdrw60\brsp20\brdrcf13 \wrapdefault\nooverflow\faroman\rin0\lin0\itap0 \rtlch\fcs1 \af45\afs20\alang1025 \ltrch\fcs0 \f45\fs20\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 {\rtlch\fcs1 \af45 \ltrch\fcs0 \f31506\insrsid6441407 \par }\pard \ltrpar\ql \li1440\ri0\sb180\widctlpar\wrapdefault\nooverflow\faroman\rin0\lin1440\itap0 {\rtlch\fcs1 \af1\afs56 \ltrch\fcs0 \b\f31506\fs56\cf9\insrsid6441407 TWAIN for C# \par }\pard \ltrpar\ql \li1440\ri0\sb120\widctlpar\wrapdefault\nooverflow\faroman\rin0\lin1440\itap0 {\rtlch\fcs1 \ab\af1\afs28 \ltrch\fcs0 \b\f31506\fs28\cf13\insrsid6441407 For Version 2.}{\rtlch\fcs1 \ab\af1\afs28 \ltrch\fcs0 \b\f31506\fs28\cf13\insrsid8668465 5}{\rtlch\fcs1 \ab\af1\afs28 \ltrch\fcs0 \b\f31506\fs28\cf13\insrsid6441407 .}{\rtlch\fcs1 \ab\af1\afs28 \ltrch\fcs0 \b\f31506\fs28\cf13\insrsid8668465 0}{\rtlch\fcs1 \ab\af1\afs28 \ltrch\fcs0 \b\f31506\fs28\cf13\insrsid6441407 .0 \par }\pard \ltrpar\ql \li1440\ri0\sb180\widctlpar\wrapdefault\nooverflow\faroman\rin0\lin1440\itap0 {\rtlch\fcs1 \ab\af1\afs28 \ltrch\fcs0 \b\f31506\fs28\insrsid8668465 November}{\rtlch\fcs1 \ab\af1\afs28 \ltrch\fcs0 \b\f31506\fs28\insrsid6441407 8}{ \rtlch\fcs1 \ab\af1\afs28 \ltrch\fcs0 \b\f31506\fs28\super\insrsid6441407 th}{\rtlch\fcs1 \ab\af1\afs28 \ltrch\fcs0 \b\f31506\fs28\insrsid6441407 , 202}{\rtlch\fcs1 \ab\af1\afs28 \ltrch\fcs0 \b\f31506\fs28\insrsid8668465 1}{\rtlch\fcs1 \ab\af1\afs28 \ltrch\fcs0 \b\f31506\fs28\insrsid6441407 \par }\pard \ltrpar\ql \li1440\ri0\sb360\widctlpar\wrapdefault\nooverflow\faroman\rin0\lin1440\itap0 {\rtlch\fcs1 \af1\afs28 \ltrch\fcs0 \f31506\fs28\insrsid6441407 \par }\pard \ltrpar\ql \li0\ri0\sb120\widctlpar\brdrt\brdrs\brdrw60\brsp20\brdrcf13 \wrapdefault\nooverflow\faroman\rin0\lin0\itap0 {\rtlch\fcs1 \af45 \ltrch\fcs0 \f31506\insrsid6441407 \par }\pard \ltrpar\ql \li1440\ri0\sb240\widctlpar\wrapdefault\nooverflow\faroman\rin0\lin1440\itap0 {\rtlch\fcs1 \af45 \ltrch\fcs0 \f31506\insrsid6441407 \par }\pard \ltrpar\ql \li1440\ri0\sb360\widctlpar\wrapdefault\nooverflow\faroman\rin0\lin1440\itap0 {\rtlch\fcs1 \af45 \ltrch\fcs0 \f31506\insrsid6441407 \par \par }\pard \ltrpar\qc \li0\ri0\sb180\widctlpar\wrapdefault\nooverflow\faroman\rin0\lin0\itap0 {\rtlch\fcs1 \af45 \ltrch\fcs0 \f31506\insrsid6441407 \par }\pard \ltrpar\ql \li720\ri0\sb180\widctlpar\wrapdefault\nooverflow\faroman\rin0\lin720\itap0 {\rtlch\fcs1 \af45\afs40 \ltrch\fcs0 \f31506\fs40\insrsid6441407 \page }{\rtlch\fcs1 \af1\afs36 \ltrch\fcs0 \b\f31506\fs36\cf9\insrsid6441407 \par }\pard \ltrpar\ql \li720\ri0\sb180\keep\keepn\widctlpar\wrapdefault\nooverflow\faroman\rin0\lin720\itap0 {\rtlch\fcs1 \af1\afs36 \ltrch\fcs0 \b\f31506\fs36\cf9\insrsid6441407 Contents \par }\pard\plain \ltrpar\s98\ql \li1080\ri0\sb120\keepn\widctlpar\tqr\tldot\tx9893\wrapdefault\nooverflow\faroman\rin0\lin1080\itap0 \rtlch\fcs1 \ab\af1\afs20\alang1025 \ltrch\fcs0 \b\f1\fs20\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 {\field\fldedit{\*\fldinst {\rtlch\fcs1 \af1 \ltrch\fcs0 \b0\f31506\insrsid6441407 TOC \\o "1-3" \\h \\z \\u }}{\fldrslt {\field\fldedit{\*\fldinst {\rtlch\fcs1 \af0 \ltrch\fcs0 \cs187\ul\cf2\lang1024\langfe1024\noproof\insrsid1196296\charrsid12086908 } {\rtlch\fcs1 \af1 \ltrch\fcs0 \lang1024\langfe1024\noproof\insrsid1196296 HYPERLINK \\l "_Toc87248710"}{\rtlch\fcs1 \af0 \ltrch\fcs0 \cs187\ul\cf2\lang1024\langfe1024\noproof\insrsid1196296\charrsid12086908 }{\rtlch\fcs1 \af0 \ltrch\fcs0 \cs187\ul\cf2\lang1024\langfe1024\noproof\insrsid1196296\charrsid12086908 {\*\datafield 08d0c9ea79f9bace118c8200aa004ba90b02000000080000000d0000005f0054006f006300380037003200340038003700310030000000}}}{\fldrslt {\rtlch\fcs1 \af0 \ltrch\fcs0 \cs187\f37\ul\cf2\lang1024\langfe1024\noproof\insrsid1196296\charrsid12086908 Purpose}{\rtlch\fcs1 \af1 \ltrch\fcs0 \lang1024\langfe1024\noproof\webhidden\insrsid1196296 \tab }{\field{\*\fldinst {\rtlch\fcs1 \af1 \ltrch\fcs0 \lang1024\langfe1024\noproof\webhidden\insrsid1196296 PAGEREF _Toc87248710 \\h }{\rtlch\fcs1 \af1 \ltrch\fcs0 \lang1024\langfe1024\noproof\webhidden\insrsid1196296 {\*\datafield 08d0c9ea79f9bace118c8200aa004ba90b02000000080000000d0000005f0054006f006300380037003200340038003700310030000000}}}{\fldrslt {\rtlch\fcs1 \af1 \ltrch\fcs0 \lang1024\langfe1024\noproof\webhidden\insrsid1196296 4}}}\sectd \ltrsect\rtlgutter \psz1\linex0\endnhere\pgbrdropt32\sectdefaultcl\sectrsid6896082\sftnbj }}\sectd \ltrsect\rtlgutter\psz1\linex0\endnhere\pgbrdropt32\sectdefaultcl\sectrsid6896082\sftnbj {\rtlch\fcs1 \ab0\af31507\afs22 \ltrch\fcs0 \b0\fs22\lang1024\langfe1024\loch\af31506\hich\af31506\dbch\af31505\noproof\insrsid1196296 \par }{\field\fldedit{\*\fldinst {\rtlch\fcs1 \af0 \ltrch\fcs0 \cs187\ul\cf2\lang1024\langfe1024\noproof\insrsid1196296\charrsid12086908 }{\rtlch\fcs1 \af1 \ltrch\fcs0 \lang1024\langfe1024\noproof\insrsid1196296 HYPERLINK \\l "_Toc87248711"}{\rtlch\fcs1 \af0 \ltrch\fcs0 \cs187\ul\cf2\lang1024\langfe1024\noproof\insrsid1196296\charrsid12086908 }{\rtlch\fcs1 \af0 \ltrch\fcs0 \cs187\ul\cf2\lang1024\langfe1024\noproof\insrsid1196296\charrsid12086908 {\*\datafield 08d0c9ea79f9bace118c8200aa004ba90b02000000080000000d0000005f0054006f006300380037003200340038003700310031000000}}}{\fldrslt {\rtlch\fcs1 \af0 \ltrch\fcs0 \cs187\f37\ul\cf2\lang1024\langfe1024\noproof\insrsid1196296\charrsid12086908 License}{\rtlch\fcs1 \af1 \ltrch\fcs0 \lang1024\langfe1024\noproof\webhidden\insrsid1196296 \tab }{\field{\*\fldinst {\rtlch\fcs1 \af1 \ltrch\fcs0 \lang1024\langfe1024\noproof\webhidden\insrsid1196296 PAGEREF _Toc87248711 \\h }{\rtlch\fcs1 \af1 \ltrch\fcs0 \lang1024\langfe1024\noproof\webhidden\insrsid1196296 {\*\datafield 08d0c9ea79f9bace118c8200aa004ba90b02000000080000000d0000005f0054006f006300380037003200340038003700310031000000}}}{\fldrslt {\rtlch\fcs1 \af1 \ltrch\fcs0 \lang1024\langfe1024\noproof\webhidden\insrsid1196296 4}}}\sectd \ltrsect\rtlgutter\psz1\linex0\endnhere\pgbrdropt32\sectdefaultcl\sectrsid6896082\sftnbj }}\sectd \ltrsect\rtlgutter\psz1\linex0\endnhere\pgbrdropt32\sectdefaultcl\sectrsid6896082\sftnbj { \rtlch\fcs1 \ab0\af31507\afs22 \ltrch\fcs0 \b0\fs22\lang1024\langfe1024\loch\af31506\hich\af31506\dbch\af31505\noproof\insrsid1196296 \par }{\field\fldedit{\*\fldinst {\rtlch\fcs1 \af0 \ltrch\fcs0 \cs187\ul\cf2\lang1024\langfe1024\noproof\insrsid1196296\charrsid12086908 }{\rtlch\fcs1 \af1 \ltrch\fcs0 \lang1024\langfe1024\noproof\insrsid1196296 HYPERLINK \\l "_Toc87248712"}{\rtlch\fcs1 \af0 \ltrch\fcs0 \cs187\ul\cf2\lang1024\langfe1024\noproof\insrsid1196296\charrsid12086908 }{\rtlch\fcs1 \af0 \ltrch\fcs0 \cs187\ul\cf2\lang1024\langfe1024\noproof\insrsid1196296\charrsid12086908 {\*\datafield 08d0c9ea79f9bace118c8200aa004ba90b02000000080000000d0000005f0054006f006300380037003200340038003700310032000000}}}{\fldrslt {\rtlch\fcs1 \af0 \ltrch\fcs0 \cs187\ul\cf2\lang1024\langfe1024\noproof\insrsid1196296\charrsid12086908 Project Repository}{ \rtlch\fcs1 \af1 \ltrch\fcs0 \lang1024\langfe1024\noproof\webhidden\insrsid1196296 \tab }{\field{\*\fldinst {\rtlch\fcs1 \af1 \ltrch\fcs0 \lang1024\langfe1024\noproof\webhidden\insrsid1196296 PAGEREF _Toc87248712 \\h }{\rtlch\fcs1 \af1 \ltrch\fcs0 \lang1024\langfe1024\noproof\webhidden\insrsid1196296 {\*\datafield 08d0c9ea79f9bace118c8200aa004ba90b02000000080000000d0000005f0054006f006300380037003200340038003700310032000000}}}{\fldrslt {\rtlch\fcs1 \af1 \ltrch\fcs0 \lang1024\langfe1024\noproof\webhidden\insrsid1196296 5}}}\sectd \ltrsect\rtlgutter\psz1\linex0\endnhere\pgbrdropt32\sectdefaultcl\sectrsid6896082\sftnbj }}\sectd \ltrsect\rtlgutter\psz1\linex0\endnhere\pgbrdropt32\sectdefaultcl\sectrsid6896082\sftnbj { \rtlch\fcs1 \ab0\af31507\afs22 \ltrch\fcs0 \b0\fs22\lang1024\langfe1024\loch\af31506\hich\af31506\dbch\af31505\noproof\insrsid1196296 \par }\pard\plain \ltrpar\s176\ql \li1440\ri0\sb180\widctlpar\tqr\tldot\tx9883\wrapdefault\nooverflow\faroman\rin0\lin1440\itap0 \rtlch\fcs1 \af45\afs20\alang1025 \ltrch\fcs0 \f45\fs20\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 {\field\fldedit{\*\fldinst {\rtlch\fcs1 \af0 \ltrch\fcs0 \cs187\ul\cf2\lang1024\langfe1024\noproof\insrsid1196296\charrsid12086908 }{\rtlch\fcs1 \af45 \ltrch\fcs0 \lang1024\langfe1024\noproof\insrsid1196296 HYPERLINK \\l "_Toc87248713"}{\rtlch\fcs1 \af0 \ltrch\fcs0 \cs187\ul\cf2\lang1024\langfe1024\noproof\insrsid1196296\charrsid12086908 }{\rtlch\fcs1 \af0 \ltrch\fcs0 \cs187\ul\cf2\lang1024\langfe1024\noproof\insrsid1196296\charrsid12086908 {\*\datafield 08d0c9ea79f9bace118c8200aa004ba90b02000000080000000d0000005f0054006f006300380037003200340038003700310033000000}}}{\fldrslt {\rtlch\fcs1 \af0 \ltrch\fcs0 \cs187\b\ul\cf2\lang1024\langfe1024\noproof\insrsid1196296\charrsid12086908 Installation}{\rtlch\fcs1 \af45 \ltrch\fcs0 \lang1024\langfe1024\noproof\webhidden\insrsid1196296 \tab }{\field{\*\fldinst {\rtlch\fcs1 \af45 \ltrch\fcs0 \lang1024\langfe1024\noproof\webhidden\insrsid1196296 PAGEREF _Toc87248713 \\h }{\rtlch\fcs1 \af45 \ltrch\fcs0 \lang1024\langfe1024\noproof\webhidden\insrsid1196296 {\*\datafield 08d0c9ea79f9bace118c8200aa004ba90b02000000080000000d0000005f0054006f006300380037003200340038003700310033000000}}}{\fldrslt {\rtlch\fcs1 \af45 \ltrch\fcs0 \lang1024\langfe1024\noproof\webhidden\insrsid1196296 5}}}\sectd \ltrsect\rtlgutter\psz1\linex0\endnhere\pgbrdropt32\sectdefaultcl\sectrsid6896082\sftnbj }}\sectd \ltrsect\rtlgutter\psz1\linex0\endnhere\pgbrdropt32\sectdefaultcl\sectrsid6896082\sftnbj { \rtlch\fcs1 \af31507\afs22 \ltrch\fcs0 \fs22\lang1024\langfe1024\loch\af31506\hich\af31506\dbch\af31505\noproof\insrsid1196296 \par }{\field\fldedit{\*\fldinst {\rtlch\fcs1 \af0 \ltrch\fcs0 \cs187\ul\cf2\lang1024\langfe1024\noproof\insrsid1196296\charrsid12086908 }{\rtlch\fcs1 \af45 \ltrch\fcs0 \lang1024\langfe1024\noproof\insrsid1196296 HYPERLINK \\l "_Toc87248714"}{\rtlch\fcs1 \af0 \ltrch\fcs0 \cs187\ul\cf2\lang1024\langfe1024\noproof\insrsid1196296\charrsid12086908 }{\rtlch\fcs1 \af0 \ltrch\fcs0 \cs187\ul\cf2\lang1024\langfe1024\noproof\insrsid1196296\charrsid12086908 {\*\datafield 08d0c9ea79f9bace118c8200aa004ba90b02000000080000000d0000005f0054006f006300380037003200340038003700310034000000}}}{\fldrslt {\rtlch\fcs1 \af0 \ltrch\fcs0 \cs187\b\ul\cf2\lang1024\langfe1024\noproof\insrsid1196296\charrsid12086908 Versioning}{\rtlch\fcs1 \af45 \ltrch\fcs0 \lang1024\langfe1024\noproof\webhidden\insrsid1196296 \tab }{\field{\*\fldinst {\rtlch\fcs1 \af45 \ltrch\fcs0 \lang1024\langfe1024\noproof\webhidden\insrsid1196296 PAGEREF _Toc87248714 \\h }{\rtlch\fcs1 \af45 \ltrch\fcs0 \lang1024\langfe1024\noproof\webhidden\insrsid1196296 {\*\datafield 08d0c9ea79f9bace118c8200aa004ba90b02000000080000000d0000005f0054006f006300380037003200340038003700310034000000}}}{\fldrslt {\rtlch\fcs1 \af45 \ltrch\fcs0 \lang1024\langfe1024\noproof\webhidden\insrsid1196296 5}}}\sectd \ltrsect\rtlgutter\psz1\linex0\endnhere\pgbrdropt32\sectdefaultcl\sectrsid6896082\sftnbj }}\sectd \ltrsect\rtlgutter\psz1\linex0\endnhere\pgbrdropt32\sectdefaultcl\sectrsid6896082\sftnbj { \rtlch\fcs1 \af31507\afs22 \ltrch\fcs0 \fs22\lang1024\langfe1024\loch\af31506\hich\af31506\dbch\af31505\noproof\insrsid1196296 \par }\pard\plain \ltrpar\s98\ql \li1080\ri0\sb120\keepn\widctlpar\tqr\tldot\tx9893\wrapdefault\nooverflow\faroman\rin0\lin1080\itap0 \rtlch\fcs1 \ab\af1\afs20\alang1025 \ltrch\fcs0 \b\f1\fs20\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 {\field\fldedit{\*\fldinst {\rtlch\fcs1 \af0 \ltrch\fcs0 \cs187\ul\cf2\lang1024\langfe1024\noproof\insrsid1196296\charrsid12086908 }{\rtlch\fcs1 \af1 \ltrch\fcs0 \lang1024\langfe1024\noproof\insrsid1196296 HYPERLINK \\l "_Toc87248715"}{\rtlch\fcs1 \af0 \ltrch\fcs0 \cs187\ul\cf2\lang1024\langfe1024\noproof\insrsid1196296\charrsid12086908 }{\rtlch\fcs1 \af0 \ltrch\fcs0 \cs187\ul\cf2\lang1024\langfe1024\noproof\insrsid1196296\charrsid12086908 {\*\datafield 08d0c9ea79f9bace118c8200aa004ba90b02000000080000000d0000005f0054006f006300380037003200340038003700310035000000}}}{\fldrslt {\rtlch\fcs1 \af0 \ltrch\fcs0 \cs187\ul\cf2\lang1024\langfe1024\noproof\insrsid1196296\charrsid12086908 Project Layout}{\rtlch\fcs1 \af1 \ltrch\fcs0 \lang1024\langfe1024\noproof\webhidden\insrsid1196296 \tab }{\field{\*\fldinst {\rtlch\fcs1 \af1 \ltrch\fcs0 \lang1024\langfe1024\noproof\webhidden\insrsid1196296 PAGEREF _Toc87248715 \\h }{\rtlch\fcs1 \af1 \ltrch\fcs0 \lang1024\langfe1024\noproof\webhidden\insrsid1196296 {\*\datafield 08d0c9ea79f9bace118c8200aa004ba90b02000000080000000d0000005f0054006f006300380037003200340038003700310035000000}}}{\fldrslt {\rtlch\fcs1 \af1 \ltrch\fcs0 \lang1024\langfe1024\noproof\webhidden\insrsid1196296 6}}}\sectd \ltrsect\rtlgutter\psz1\linex0\endnhere\pgbrdropt32\sectdefaultcl\sectrsid6896082\sftnbj }}\sectd \ltrsect\rtlgutter\psz1\linex0\endnhere\pgbrdropt32\sectdefaultcl\sectrsid6896082\sftnbj { \rtlch\fcs1 \ab0\af31507\afs22 \ltrch\fcs0 \b0\fs22\lang1024\langfe1024\loch\af31506\hich\af31506\dbch\af31505\noproof\insrsid1196296 \par }\pard\plain \ltrpar\s176\ql \li1440\ri0\sb180\widctlpar\tqr\tldot\tx9883\wrapdefault\nooverflow\faroman\rin0\lin1440\itap0 \rtlch\fcs1 \af45\afs20\alang1025 \ltrch\fcs0 \f45\fs20\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 {\field\fldedit{\*\fldinst {\rtlch\fcs1 \af0 \ltrch\fcs0 \cs187\ul\cf2\lang1024\langfe1024\noproof\insrsid1196296\charrsid12086908 }{\rtlch\fcs1 \af45 \ltrch\fcs0 \lang1024\langfe1024\noproof\insrsid1196296 HYPERLINK \\l "_Toc87248716"}{\rtlch\fcs1 \af0 \ltrch\fcs0 \cs187\ul\cf2\lang1024\langfe1024\noproof\insrsid1196296\charrsid12086908 }{\rtlch\fcs1 \af0 \ltrch\fcs0 \cs187\ul\cf2\lang1024\langfe1024\noproof\insrsid1196296\charrsid12086908 {\*\datafield 08d0c9ea79f9bace118c8200aa004ba90b02000000080000000d0000005f0054006f006300380037003200340038003700310036000000}}}{\fldrslt {\rtlch\fcs1 \af0 \ltrch\fcs0 \cs187\b\ul\cf2\lang1024\langfe1024\noproof\insrsid1196296\charrsid12086908 Basic TWAIN C# Definitions and Helper Functions}{\rtlch\fcs1 \af45 \ltrch\fcs0 \lang1024\langfe1024\noproof\webhidden\insrsid1196296 \tab }{\field{\*\fldinst {\rtlch\fcs1 \af45 \ltrch\fcs0 \lang1024\langfe1024\noproof\webhidden\insrsid1196296 PAGEREF _Toc87248716 \\h }{\rtlch\fcs1 \af45 \ltrch\fcs0 \lang1024\langfe1024\noproof\webhidden\insrsid1196296 {\*\datafield 08d0c9ea79f9bace118c8200aa004ba90b02000000080000000d0000005f0054006f006300380037003200340038003700310036000000}}}{\fldrslt {\rtlch\fcs1 \af45 \ltrch\fcs0 \lang1024\langfe1024\noproof\webhidden\insrsid1196296 6}}}\sectd \ltrsect\rtlgutter\psz1\linex0\endnhere\pgbrdropt32\sectdefaultcl\sectrsid6896082\sftnbj }}\sectd \ltrsect\rtlgutter \psz1\linex0\endnhere\pgbrdropt32\sectdefaultcl\sectrsid6896082\sftnbj {\rtlch\fcs1 \af31507\afs22 \ltrch\fcs0 \fs22\lang1024\langfe1024\loch\af31506\hich\af31506\dbch\af31505\noproof\insrsid1196296 \par }{\field\fldedit{\*\fldinst {\rtlch\fcs1 \af0 \ltrch\fcs0 \cs187\ul\cf2\lang1024\langfe1024\noproof\insrsid1196296\charrsid12086908 }{\rtlch\fcs1 \af45 \ltrch\fcs0 \lang1024\langfe1024\noproof\insrsid1196296 HYPERLINK \\l "_Toc87248717"}{\rtlch\fcs1 \af0 \ltrch\fcs0 \cs187\ul\cf2\lang1024\langfe1024\noproof\insrsid1196296\charrsid12086908 }{\rtlch\fcs1 \af0 \ltrch\fcs0 \cs187\ul\cf2\lang1024\langfe1024\noproof\insrsid1196296\charrsid12086908 {\*\datafield 08d0c9ea79f9bace118c8200aa004ba90b02000000080000000d0000005f0054006f006300380037003200340038003700310037000000}}}{\fldrslt {\rtlch\fcs1 \af0 \ltrch\fcs0 \cs187\b\ul\cf2\lang1024\langfe1024\noproof\insrsid1196296\charrsid12086908 A TWAIN C# Diagnostic Application}{\rtlch\fcs1 \af45 \ltrch\fcs0 \lang1024\langfe1024\noproof\webhidden\insrsid1196296 \tab }{\field{\*\fldinst {\rtlch\fcs1 \af45 \ltrch\fcs0 \lang1024\langfe1024\noproof\webhidden\insrsid1196296 PAGEREF _Toc87248717 \\h }{\rtlch\fcs1 \af45 \ltrch\fcs0 \lang1024\langfe1024\noproof\webhidden\insrsid1196296 {\*\datafield 08d0c9ea79f9bace118c8200aa004ba90b02000000080000000d0000005f0054006f006300380037003200340038003700310037000000}}}{\fldrslt {\rtlch\fcs1 \af45 \ltrch\fcs0 \lang1024\langfe1024\noproof\webhidden\insrsid1196296 6}}}\sectd \ltrsect\rtlgutter\psz1\linex0\endnhere\pgbrdropt32\sectdefaultcl\sectrsid6896082\sftnbj }}\sectd \ltrsect\rtlgutter\psz1\linex0\endnhere\pgbrdropt32\sectdefaultcl\sectrsid6896082\sftnbj { \rtlch\fcs1 \af31507\afs22 \ltrch\fcs0 \fs22\lang1024\langfe1024\loch\af31506\hich\af31506\dbch\af31505\noproof\insrsid1196296 \par }{\field\fldedit{\*\fldinst {\rtlch\fcs1 \af0 \ltrch\fcs0 \cs187\ul\cf2\lang1024\langfe1024\noproof\insrsid1196296\charrsid12086908 }{\rtlch\fcs1 \af45 \ltrch\fcs0 \lang1024\langfe1024\noproof\insrsid1196296 HYPERLINK \\l "_Toc87248718"}{\rtlch\fcs1 \af0 \ltrch\fcs0 \cs187\ul\cf2\lang1024\langfe1024\noproof\insrsid1196296\charrsid12086908 }{\rtlch\fcs1 \af0 \ltrch\fcs0 \cs187\ul\cf2\lang1024\langfe1024\noproof\insrsid1196296\charrsid12086908 {\*\datafield 08d0c9ea79f9bace118c8200aa004ba90b02000000080000000d0000005f0054006f006300380037003200340038003700310038000000}}}{\fldrslt {\rtlch\fcs1 \af0 \ltrch\fcs0 \cs187\b\ul\cf2\lang1024\langfe1024\noproof\insrsid1196296\charrsid12086908 A TWAIN C# Sample Application}{\rtlch\fcs1 \af45 \ltrch\fcs0 \lang1024\langfe1024\noproof\webhidden\insrsid1196296 \tab }{\field{\*\fldinst {\rtlch\fcs1 \af45 \ltrch\fcs0 \lang1024\langfe1024\noproof\webhidden\insrsid1196296 PAGEREF _Toc87248718 \\h }{ \rtlch\fcs1 \af45 \ltrch\fcs0 \lang1024\langfe1024\noproof\webhidden\insrsid1196296 {\*\datafield 08d0c9ea79f9bace118c8200aa004ba90b02000000080000000d0000005f0054006f006300380037003200340038003700310038000000}}}{\fldrslt {\rtlch\fcs1 \af45 \ltrch\fcs0 \lang1024\langfe1024\noproof\webhidden\insrsid1196296 7}}}\sectd \ltrsect\rtlgutter\psz1\linex0\endnhere\pgbrdropt32\sectdefaultcl\sectrsid6896082\sftnbj }}\sectd \ltrsect\rtlgutter\psz1\linex0\endnhere\pgbrdropt32\sectdefaultcl\sectrsid6896082\sftnbj { \rtlch\fcs1 \af31507\afs22 \ltrch\fcs0 \fs22\lang1024\langfe1024\loch\af31506\hich\af31506\dbch\af31505\noproof\insrsid1196296 \par }{\field\fldedit{\*\fldinst {\rtlch\fcs1 \af0 \ltrch\fcs0 \cs187\ul\cf2\lang1024\langfe1024\noproof\insrsid1196296\charrsid12086908 }{\rtlch\fcs1 \af45 \ltrch\fcs0 \lang1024\langfe1024\noproof\insrsid1196296 HYPERLINK \\l "_Toc87248719"}{\rtlch\fcs1 \af0 \ltrch\fcs0 \cs187\ul\cf2\lang1024\langfe1024\noproof\insrsid1196296\charrsid12086908 }{\rtlch\fcs1 \af0 \ltrch\fcs0 \cs187\ul\cf2\lang1024\langfe1024\noproof\insrsid1196296\charrsid12086908 {\*\datafield 08d0c9ea79f9bace118c8200aa004ba90b02000000080000000d0000005f0054006f006300380037003200340038003700310039000000}}}{\fldrslt {\rtlch\fcs1 \af0 \ltrch\fcs0 \cs187\b\ul\cf2\lang1024\langfe1024\noproof\insrsid1196296\charrsid12086908 A TWAIN C# Self Certification Application}{\rtlch\fcs1 \af45 \ltrch\fcs0 \lang1024\langfe1024\noproof\webhidden\insrsid1196296 \tab }{\field{\*\fldinst {\rtlch\fcs1 \af45 \ltrch\fcs0 \lang1024\langfe1024\noproof\webhidden\insrsid1196296 PAGEREF _Toc87248719 \\h }{\rtlch\fcs1 \af45 \ltrch\fcs0 \lang1024\langfe1024\noproof\webhidden\insrsid1196296 {\*\datafield 08d0c9ea79f9bace118c8200aa004ba90b02000000080000000d0000005f0054006f006300380037003200340038003700310039000000}}}{\fldrslt {\rtlch\fcs1 \af45 \ltrch\fcs0 \lang1024\langfe1024\noproof\webhidden\insrsid1196296 7}}}\sectd \ltrsect\rtlgutter\psz1\linex0\endnhere\pgbrdropt32\sectdefaultcl\sectrsid6896082\sftnbj }}\sectd \ltrsect\rtlgutter \psz1\linex0\endnhere\pgbrdropt32\sectdefaultcl\sectrsid6896082\sftnbj {\rtlch\fcs1 \af31507\afs22 \ltrch\fcs0 \fs22\lang1024\langfe1024\loch\af31506\hich\af31506\dbch\af31505\noproof\insrsid1196296 \par }\pard\plain \ltrpar\s98\ql \li1080\ri0\sb120\keepn\widctlpar\tqr\tldot\tx9893\wrapdefault\nooverflow\faroman\rin0\lin1080\itap0 \rtlch\fcs1 \ab\af1\afs20\alang1025 \ltrch\fcs0 \b\f1\fs20\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 {\field\fldedit{\*\fldinst {\rtlch\fcs1 \af0 \ltrch\fcs0 \cs187\ul\cf2\lang1024\langfe1024\noproof\insrsid1196296\charrsid12086908 }{\rtlch\fcs1 \af1 \ltrch\fcs0 \lang1024\langfe1024\noproof\insrsid1196296 HYPERLINK \\l "_Toc87248720"}{\rtlch\fcs1 \af0 \ltrch\fcs0 \cs187\ul\cf2\lang1024\langfe1024\noproof\insrsid1196296\charrsid12086908 }{\rtlch\fcs1 \af0 \ltrch\fcs0 \cs187\ul\cf2\lang1024\langfe1024\noproof\insrsid1196296\charrsid12086908 {\*\datafield 08d0c9ea79f9bace118c8200aa004ba90b02000000080000000d0000005f0054006f006300380037003200340038003700320030000000}}}{\fldrslt {\rtlch\fcs1 \af0 \ltrch\fcs0 \cs187\ul\cf2\lang1024\langfe1024\noproof\insrsid1196296\charrsid12086908 Release Notes}{\rtlch\fcs1 \af1 \ltrch\fcs0 \lang1024\langfe1024\noproof\webhidden\insrsid1196296 \tab }{\field{\*\fldinst {\rtlch\fcs1 \af1 \ltrch\fcs0 \lang1024\langfe1024\noproof\webhidden\insrsid1196296 PAGEREF _Toc87248720 \\h }{\rtlch\fcs1 \af1 \ltrch\fcs0 \lang1024\langfe1024\noproof\webhidden\insrsid1196296 {\*\datafield 08d0c9ea79f9bace118c8200aa004ba90b02000000080000000d0000005f0054006f006300380037003200340038003700320030000000}}}{\fldrslt {\rtlch\fcs1 \af1 \ltrch\fcs0 \lang1024\langfe1024\noproof\webhidden\insrsid1196296 8}}}\sectd \ltrsect\rtlgutter\psz1\linex0\endnhere\pgbrdropt32\sectdefaultcl\sectrsid6896082\sftnbj }}\sectd \ltrsect\rtlgutter\psz1\linex0\endnhere\pgbrdropt32\sectdefaultcl\sectrsid6896082\sftnbj { \rtlch\fcs1 \ab0\af31507\afs22 \ltrch\fcs0 \b0\fs22\lang1024\langfe1024\loch\af31506\hich\af31506\dbch\af31505\noproof\insrsid1196296 \par }\pard\plain \ltrpar\s176\ql \li1440\ri0\sb180\widctlpar\tqr\tldot\tx9883\wrapdefault\nooverflow\faroman\rin0\lin1440\itap0 \rtlch\fcs1 \af45\afs20\alang1025 \ltrch\fcs0 \f45\fs20\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 {\field\fldedit{\*\fldinst {\rtlch\fcs1 \af0 \ltrch\fcs0 \cs187\ul\cf2\lang1024\langfe1024\noproof\insrsid1196296\charrsid12086908 }{\rtlch\fcs1 \af45 \ltrch\fcs0 \lang1024\langfe1024\noproof\insrsid1196296 HYPERLINK \\l "_Toc87248721"}{\rtlch\fcs1 \af0 \ltrch\fcs0 \cs187\ul\cf2\lang1024\langfe1024\noproof\insrsid1196296\charrsid12086908 }{\rtlch\fcs1 \af0 \ltrch\fcs0 \cs187\ul\cf2\lang1024\langfe1024\noproof\insrsid1196296\charrsid12086908 {\*\datafield 08d0c9ea79f9bace118c8200aa004ba90b02000000080000000d0000005f0054006f006300380037003200340038003700320031000000}}}{\fldrslt {\rtlch\fcs1 \af0 \ltrch\fcs0 \cs187\b\ul\cf2\lang1024\langfe1024\noproof\insrsid1196296\charrsid12086908 V2.5.0.0 (08-Nov-2021)}{ \rtlch\fcs1 \af45 \ltrch\fcs0 \lang1024\langfe1024\noproof\webhidden\insrsid1196296 \tab }{\field{\*\fldinst {\rtlch\fcs1 \af45 \ltrch\fcs0 \lang1024\langfe1024\noproof\webhidden\insrsid1196296 PAGEREF _Toc87248721 \\h }{\rtlch\fcs1 \af45 \ltrch\fcs0 \lang1024\langfe1024\noproof\webhidden\insrsid1196296 {\*\datafield 08d0c9ea79f9bace118c8200aa004ba90b02000000080000000d0000005f0054006f006300380037003200340038003700320031000000}}}{\fldrslt {\rtlch\fcs1 \af45 \ltrch\fcs0 \lang1024\langfe1024\noproof\webhidden\insrsid1196296 8}}}\sectd \ltrsect\rtlgutter\psz1\linex0\endnhere\pgbrdropt32\sectdefaultcl\sectrsid6896082\sftnbj }}\sectd \ltrsect\rtlgutter\psz1\linex0\endnhere\pgbrdropt32\sectdefaultcl\sectrsid6896082\sftnbj { \rtlch\fcs1 \af31507\afs22 \ltrch\fcs0 \fs22\lang1024\langfe1024\loch\af31506\hich\af31506\dbch\af31505\noproof\insrsid1196296 \par }{\field\fldedit{\*\fldinst {\rtlch\fcs1 \af0 \ltrch\fcs0 \cs187\ul\cf2\lang1024\langfe1024\noproof\insrsid1196296\charrsid12086908 }{\rtlch\fcs1 \af45 \ltrch\fcs0 \lang1024\langfe1024\noproof\insrsid1196296 HYPERLINK \\l "_Toc87248722"}{\rtlch\fcs1 \af0 \ltrch\fcs0 \cs187\ul\cf2\lang1024\langfe1024\noproof\insrsid1196296\charrsid12086908 }{\rtlch\fcs1 \af0 \ltrch\fcs0 \cs187\ul\cf2\lang1024\langfe1024\noproof\insrsid1196296\charrsid12086908 {\*\datafield 08d0c9ea79f9bace118c8200aa004ba90b02000000080000000d0000005f0054006f006300380037003200340038003700320032000000}}}{\fldrslt {\rtlch\fcs1 \af0 \ltrch\fcs0 \cs187\b\ul\cf2\lang1024\langfe1024\noproof\insrsid1196296\charrsid12086908 V2.4.11.0 (08-Jul-2020)}{ \rtlch\fcs1 \af45 \ltrch\fcs0 \lang1024\langfe1024\noproof\webhidden\insrsid1196296 \tab }{\field{\*\fldinst {\rtlch\fcs1 \af45 \ltrch\fcs0 \lang1024\langfe1024\noproof\webhidden\insrsid1196296 PAGEREF _Toc87248722 \\h }{\rtlch\fcs1 \af45 \ltrch\fcs0 \lang1024\langfe1024\noproof\webhidden\insrsid1196296 {\*\datafield 08d0c9ea79f9bace118c8200aa004ba90b02000000080000000d0000005f0054006f006300380037003200340038003700320032000000}}}{\fldrslt {\rtlch\fcs1 \af45 \ltrch\fcs0 \lang1024\langfe1024\noproof\webhidden\insrsid1196296 8}}}\sectd \ltrsect\rtlgutter\psz1\linex0\endnhere\pgbrdropt32\sectdefaultcl\sectrsid6896082\sftnbj }}\sectd \ltrsect\rtlgutter\psz1\linex0\endnhere\pgbrdropt32\sectdefaultcl\sectrsid6896082\sftnbj { \rtlch\fcs1 \af31507\afs22 \ltrch\fcs0 \fs22\lang1024\langfe1024\loch\af31506\hich\af31506\dbch\af31505\noproof\insrsid1196296 \par }{\field\fldedit{\*\fldinst {\rtlch\fcs1 \af0 \ltrch\fcs0 \cs187\ul\cf2\lang1024\langfe1024\noproof\insrsid1196296\charrsid12086908 }{\rtlch\fcs1 \af45 \ltrch\fcs0 \lang1024\langfe1024\noproof\insrsid1196296 HYPERLINK \\l "_Toc87248723"}{\rtlch\fcs1 \af0 \ltrch\fcs0 \cs187\ul\cf2\lang1024\langfe1024\noproof\insrsid1196296\charrsid12086908 }{\rtlch\fcs1 \af0 \ltrch\fcs0 \cs187\ul\cf2\lang1024\langfe1024\noproof\insrsid1196296\charrsid12086908 {\*\datafield 08d0c9ea79f9bace118c8200aa004ba90b02000000080000000d0000005f0054006f006300380037003200340038003700320033000000}}}{\fldrslt {\rtlch\fcs1 \af0 \ltrch\fcs0 \cs187\b\ul\cf2\lang1024\langfe1024\noproof\insrsid1196296\charrsid12086908 V2.4.10.0 (06-Jun-2020)}{ \rtlch\fcs1 \af45 \ltrch\fcs0 \lang1024\langfe1024\noproof\webhidden\insrsid1196296 \tab }{\field{\*\fldinst {\rtlch\fcs1 \af45 \ltrch\fcs0 \lang1024\langfe1024\noproof\webhidden\insrsid1196296 PAGEREF _Toc87248723 \\h }{\rtlch\fcs1 \af45 \ltrch\fcs0 \lang1024\langfe1024\noproof\webhidden\insrsid1196296 {\*\datafield 08d0c9ea79f9bace118c8200aa004ba90b02000000080000000d0000005f0054006f006300380037003200340038003700320033000000}}}{\fldrslt {\rtlch\fcs1 \af45 \ltrch\fcs0 \lang1024\langfe1024\noproof\webhidden\insrsid1196296 8}}}\sectd \ltrsect\rtlgutter\psz1\linex0\endnhere\pgbrdropt32\sectdefaultcl\sectrsid6896082\sftnbj }}\sectd \ltrsect\rtlgutter\psz1\linex0\endnhere\pgbrdropt32\sectdefaultcl\sectrsid6896082\sftnbj { \rtlch\fcs1 \af31507\afs22 \ltrch\fcs0 \fs22\lang1024\langfe1024\loch\af31506\hich\af31506\dbch\af31505\noproof\insrsid1196296 \par }{\field\fldedit{\*\fldinst {\rtlch\fcs1 \af0 \ltrch\fcs0 \cs187\ul\cf2\lang1024\langfe1024\noproof\insrsid1196296\charrsid12086908 }{\rtlch\fcs1 \af45 \ltrch\fcs0 \lang1024\langfe1024\noproof\insrsid1196296 HYPERLINK \\l "_Toc87248724"}{\rtlch\fcs1 \af0 \ltrch\fcs0 \cs187\ul\cf2\lang1024\langfe1024\noproof\insrsid1196296\charrsid12086908 }{\rtlch\fcs1 \af0 \ltrch\fcs0 \cs187\ul\cf2\lang1024\langfe1024\noproof\insrsid1196296\charrsid12086908 {\*\datafield 08d0c9ea79f9bace118c8200aa004ba90b02000000080000000d0000005f0054006f006300380037003200340038003700320034000000}}}{\fldrslt {\rtlch\fcs1 \af0 \ltrch\fcs0 \cs187\b\ul\cf2\lang1024\langfe1024\noproof\insrsid1196296\charrsid12086908 V2.4.9.0 (30-Apr-2020)}{ \rtlch\fcs1 \af45 \ltrch\fcs0 \lang1024\langfe1024\noproof\webhidden\insrsid1196296 \tab }{\field{\*\fldinst {\rtlch\fcs1 \af45 \ltrch\fcs0 \lang1024\langfe1024\noproof\webhidden\insrsid1196296 PAGEREF _Toc87248724 \\h }{\rtlch\fcs1 \af45 \ltrch\fcs0 \lang1024\langfe1024\noproof\webhidden\insrsid1196296 {\*\datafield 08d0c9ea79f9bace118c8200aa004ba90b02000000080000000d0000005f0054006f006300380037003200340038003700320034000000}}}{\fldrslt {\rtlch\fcs1 \af45 \ltrch\fcs0 \lang1024\langfe1024\noproof\webhidden\insrsid1196296 8}}}\sectd \ltrsect\rtlgutter\psz1\linex0\endnhere\pgbrdropt32\sectdefaultcl\sectrsid6896082\sftnbj }}\sectd \ltrsect\rtlgutter\psz1\linex0\endnhere\pgbrdropt32\sectdefaultcl\sectrsid6896082\sftnbj { \rtlch\fcs1 \af31507\afs22 \ltrch\fcs0 \fs22\lang1024\langfe1024\loch\af31506\hich\af31506\dbch\af31505\noproof\insrsid1196296 \par }{\field\fldedit{\*\fldinst {\rtlch\fcs1 \af0 \ltrch\fcs0 \cs187\ul\cf2\lang1024\langfe1024\noproof\insrsid1196296\charrsid12086908 }{\rtlch\fcs1 \af45 \ltrch\fcs0 \lang1024\langfe1024\noproof\insrsid1196296 HYPERLINK \\l "_Toc87248725"}{\rtlch\fcs1 \af0 \ltrch\fcs0 \cs187\ul\cf2\lang1024\langfe1024\noproof\insrsid1196296\charrsid12086908 }{\rtlch\fcs1 \af0 \ltrch\fcs0 \cs187\ul\cf2\lang1024\langfe1024\noproof\insrsid1196296\charrsid12086908 {\*\datafield 08d0c9ea79f9bace118c8200aa004ba90b02000000080000000d0000005f0054006f006300380037003200340038003700320035000000}}}{\fldrslt {\rtlch\fcs1 \af0 \ltrch\fcs0 \cs187\b\ul\cf2\lang1024\langfe1024\noproof\insrsid1196296\charrsid12086908 V2.4.8.0 (30-Mar-2020)}{ \rtlch\fcs1 \af45 \ltrch\fcs0 \lang1024\langfe1024\noproof\webhidden\insrsid1196296 \tab }{\field{\*\fldinst {\rtlch\fcs1 \af45 \ltrch\fcs0 \lang1024\langfe1024\noproof\webhidden\insrsid1196296 PAGEREF _Toc87248725 \\h }{\rtlch\fcs1 \af45 \ltrch\fcs0 \lang1024\langfe1024\noproof\webhidden\insrsid1196296 {\*\datafield 08d0c9ea79f9bace118c8200aa004ba90b02000000080000000d0000005f0054006f006300380037003200340038003700320035000000}}}{\fldrslt {\rtlch\fcs1 \af45 \ltrch\fcs0 \lang1024\langfe1024\noproof\webhidden\insrsid1196296 9}}}\sectd \ltrsect\rtlgutter\psz1\linex0\endnhere\pgbrdropt32\sectdefaultcl\sectrsid6896082\sftnbj }}\sectd \ltrsect\rtlgutter\psz1\linex0\endnhere\pgbrdropt32\sectdefaultcl\sectrsid6896082\sftnbj { \rtlch\fcs1 \af31507\afs22 \ltrch\fcs0 \fs22\lang1024\langfe1024\loch\af31506\hich\af31506\dbch\af31505\noproof\insrsid1196296 \par }{\field\fldedit{\*\fldinst {\rtlch\fcs1 \af0 \ltrch\fcs0 \cs187\ul\cf2\lang1024\langfe1024\noproof\insrsid1196296\charrsid12086908 }{\rtlch\fcs1 \af45 \ltrch\fcs0 \lang1024\langfe1024\noproof\insrsid1196296 HYPERLINK \\l "_Toc87248726"}{\rtlch\fcs1 \af0 \ltrch\fcs0 \cs187\ul\cf2\lang1024\langfe1024\noproof\insrsid1196296\charrsid12086908 }{\rtlch\fcs1 \af0 \ltrch\fcs0 \cs187\ul\cf2\lang1024\langfe1024\noproof\insrsid1196296\charrsid12086908 {\*\datafield 08d0c9ea79f9bace118c8200aa004ba90b02000000080000000d0000005f0054006f006300380037003200340038003700320036000000}}}{\fldrslt {\rtlch\fcs1 \af0 \ltrch\fcs0 \cs187\b\ul\cf2\lang1024\langfe1024\noproof\insrsid1196296\charrsid12086908 V2.4.6.0 (26-Mar-2020)}{ \rtlch\fcs1 \af45 \ltrch\fcs0 \lang1024\langfe1024\noproof\webhidden\insrsid1196296 \tab }{\field{\*\fldinst {\rtlch\fcs1 \af45 \ltrch\fcs0 \lang1024\langfe1024\noproof\webhidden\insrsid1196296 PAGEREF _Toc87248726 \\h }{\rtlch\fcs1 \af45 \ltrch\fcs0 \lang1024\langfe1024\noproof\webhidden\insrsid1196296 {\*\datafield 08d0c9ea79f9bace118c8200aa004ba90b02000000080000000d0000005f0054006f006300380037003200340038003700320036000000}}}{\fldrslt {\rtlch\fcs1 \af45 \ltrch\fcs0 \lang1024\langfe1024\noproof\webhidden\insrsid1196296 9}}}\sectd \ltrsect\rtlgutter\psz1\linex0\endnhere\pgbrdropt32\sectdefaultcl\sectrsid6896082\sftnbj }}\sectd \ltrsect\rtlgutter\psz1\linex0\endnhere\pgbrdropt32\sectdefaultcl\sectrsid6896082\sftnbj { \rtlch\fcs1 \af31507\afs22 \ltrch\fcs0 \fs22\lang1024\langfe1024\loch\af31506\hich\af31506\dbch\af31505\noproof\insrsid1196296 \par }{\field\fldedit{\*\fldinst {\rtlch\fcs1 \af0 \ltrch\fcs0 \cs187\ul\cf2\lang1024\langfe1024\noproof\insrsid1196296\charrsid12086908 }{\rtlch\fcs1 \af45 \ltrch\fcs0 \lang1024\langfe1024\noproof\insrsid1196296 HYPERLINK \\l "_Toc87248727"}{\rtlch\fcs1 \af0 \ltrch\fcs0 \cs187\ul\cf2\lang1024\langfe1024\noproof\insrsid1196296\charrsid12086908 }{\rtlch\fcs1 \af0 \ltrch\fcs0 \cs187\ul\cf2\lang1024\langfe1024\noproof\insrsid1196296\charrsid12086908 {\*\datafield 08d0c9ea79f9bace118c8200aa004ba90b02000000080000000d0000005f0054006f006300380037003200340038003700320037000000}}}{\fldrslt {\rtlch\fcs1 \af0 \ltrch\fcs0 \cs187\b\ul\cf2\lang1024\langfe1024\noproof\insrsid1196296\charrsid12086908 V2.4.5.0 (24-Mar-2020)}{ \rtlch\fcs1 \af45 \ltrch\fcs0 \lang1024\langfe1024\noproof\webhidden\insrsid1196296 \tab }{\field{\*\fldinst {\rtlch\fcs1 \af45 \ltrch\fcs0 \lang1024\langfe1024\noproof\webhidden\insrsid1196296 PAGEREF _Toc87248727 \\h }{\rtlch\fcs1 \af45 \ltrch\fcs0 \lang1024\langfe1024\noproof\webhidden\insrsid1196296 {\*\datafield 08d0c9ea79f9bace118c8200aa004ba90b02000000080000000d0000005f0054006f006300380037003200340038003700320037000000}}}{\fldrslt {\rtlch\fcs1 \af45 \ltrch\fcs0 \lang1024\langfe1024\noproof\webhidden\insrsid1196296 9}}}\sectd \ltrsect\rtlgutter\psz1\linex0\endnhere\pgbrdropt32\sectdefaultcl\sectrsid6896082\sftnbj }}\sectd \ltrsect\rtlgutter\psz1\linex0\endnhere\pgbrdropt32\sectdefaultcl\sectrsid6896082\sftnbj { \rtlch\fcs1 \af31507\afs22 \ltrch\fcs0 \fs22\lang1024\langfe1024\loch\af31506\hich\af31506\dbch\af31505\noproof\insrsid1196296 \par }{\field\fldedit{\*\fldinst {\rtlch\fcs1 \af0 \ltrch\fcs0 \cs187\ul\cf2\lang1024\langfe1024\noproof\insrsid1196296\charrsid12086908 }{\rtlch\fcs1 \af45 \ltrch\fcs0 \lang1024\langfe1024\noproof\insrsid1196296 HYPERLINK \\l "_Toc87248728"}{\rtlch\fcs1 \af0 \ltrch\fcs0 \cs187\ul\cf2\lang1024\langfe1024\noproof\insrsid1196296\charrsid12086908 }{\rtlch\fcs1 \af0 \ltrch\fcs0 \cs187\ul\cf2\lang1024\langfe1024\noproof\insrsid1196296\charrsid12086908 {\*\datafield 08d0c9ea79f9bace118c8200aa004ba90b02000000080000000d0000005f0054006f006300380037003200340038003700320038000000}}}{\fldrslt {\rtlch\fcs1 \af0 \ltrch\fcs0 \cs187\b\ul\cf2\lang1024\langfe1024\noproof\insrsid1196296\charrsid12086908 V2.4.4.0 (24-Mar-2020)}{ \rtlch\fcs1 \af45 \ltrch\fcs0 \lang1024\langfe1024\noproof\webhidden\insrsid1196296 \tab }{\field{\*\fldinst {\rtlch\fcs1 \af45 \ltrch\fcs0 \lang1024\langfe1024\noproof\webhidden\insrsid1196296 PAGEREF _Toc87248728 \\h }{\rtlch\fcs1 \af45 \ltrch\fcs0 \lang1024\langfe1024\noproof\webhidden\insrsid1196296 {\*\datafield 08d0c9ea79f9bace118c8200aa004ba90b02000000080000000d0000005f0054006f006300380037003200340038003700320038000000}}}{\fldrslt {\rtlch\fcs1 \af45 \ltrch\fcs0 \lang1024\langfe1024\noproof\webhidden\insrsid1196296 9}}}\sectd \ltrsect\rtlgutter\psz1\linex0\endnhere\pgbrdropt32\sectdefaultcl\sectrsid6896082\sftnbj }}\sectd \ltrsect\rtlgutter\psz1\linex0\endnhere\pgbrdropt32\sectdefaultcl\sectrsid6896082\sftnbj { \rtlch\fcs1 \af31507\afs22 \ltrch\fcs0 \fs22\lang1024\langfe1024\loch\af31506\hich\af31506\dbch\af31505\noproof\insrsid1196296 \par }{\field\fldedit{\*\fldinst {\rtlch\fcs1 \af0 \ltrch\fcs0 \cs187\ul\cf2\lang1024\langfe1024\noproof\insrsid1196296\charrsid12086908 }{\rtlch\fcs1 \af45 \ltrch\fcs0 \lang1024\langfe1024\noproof\insrsid1196296 HYPERLINK \\l "_Toc87248729"}{\rtlch\fcs1 \af0 \ltrch\fcs0 \cs187\ul\cf2\lang1024\langfe1024\noproof\insrsid1196296\charrsid12086908 }{\rtlch\fcs1 \af0 \ltrch\fcs0 \cs187\ul\cf2\lang1024\langfe1024\noproof\insrsid1196296\charrsid12086908 {\*\datafield 08d0c9ea79f9bace118c8200aa004ba90b02000000080000000d0000005f0054006f006300380037003200340038003700320039000000}}}{\fldrslt {\rtlch\fcs1 \af0 \ltrch\fcs0 \cs187\b\ul\cf2\lang1024\langfe1024\noproof\insrsid1196296\charrsid12086908 V2.4.3.0 (20-Mar-2020)}{ \rtlch\fcs1 \af45 \ltrch\fcs0 \lang1024\langfe1024\noproof\webhidden\insrsid1196296 \tab }{\field{\*\fldinst {\rtlch\fcs1 \af45 \ltrch\fcs0 \lang1024\langfe1024\noproof\webhidden\insrsid1196296 PAGEREF _Toc87248729 \\h }{\rtlch\fcs1 \af45 \ltrch\fcs0 \lang1024\langfe1024\noproof\webhidden\insrsid1196296 {\*\datafield 08d0c9ea79f9bace118c8200aa004ba90b02000000080000000d0000005f0054006f006300380037003200340038003700320039000000}}}{\fldrslt {\rtlch\fcs1 \af45 \ltrch\fcs0 \lang1024\langfe1024\noproof\webhidden\insrsid1196296 10}}}\sectd \ltrsect\rtlgutter\psz1\linex0\endnhere\pgbrdropt32\sectdefaultcl\sectrsid6896082\sftnbj }}\sectd \ltrsect\rtlgutter\psz1\linex0\endnhere\pgbrdropt32\sectdefaultcl\sectrsid6896082\sftnbj { \rtlch\fcs1 \af31507\afs22 \ltrch\fcs0 \fs22\lang1024\langfe1024\loch\af31506\hich\af31506\dbch\af31505\noproof\insrsid1196296 \par }{\field\fldedit{\*\fldinst {\rtlch\fcs1 \af0 \ltrch\fcs0 \cs187\ul\cf2\lang1024\langfe1024\noproof\insrsid1196296\charrsid12086908 }{\rtlch\fcs1 \af45 \ltrch\fcs0 \lang1024\langfe1024\noproof\insrsid1196296 HYPERLINK \\l "_Toc87248730"}{\rtlch\fcs1 \af0 \ltrch\fcs0 \cs187\ul\cf2\lang1024\langfe1024\noproof\insrsid1196296\charrsid12086908 }{\rtlch\fcs1 \af0 \ltrch\fcs0 \cs187\ul\cf2\lang1024\langfe1024\noproof\insrsid1196296\charrsid12086908 {\*\datafield 08d0c9ea79f9bace118c8200aa004ba90b02000000080000000d0000005f0054006f006300380037003200340038003700330030000000}}}{\fldrslt {\rtlch\fcs1 \af0 \ltrch\fcs0 \cs187\b\ul\cf2\lang1024\langfe1024\noproof\insrsid1196296\charrsid12086908 V2.4.2.0 (13-Mar-2020)}{ \rtlch\fcs1 \af45 \ltrch\fcs0 \lang1024\langfe1024\noproof\webhidden\insrsid1196296 \tab }{\field{\*\fldinst {\rtlch\fcs1 \af45 \ltrch\fcs0 \lang1024\langfe1024\noproof\webhidden\insrsid1196296 PAGEREF _Toc87248730 \\h }{\rtlch\fcs1 \af45 \ltrch\fcs0 \lang1024\langfe1024\noproof\webhidden\insrsid1196296 {\*\datafield 08d0c9ea79f9bace118c8200aa004ba90b02000000080000000d0000005f0054006f006300380037003200340038003700330030000000}}}{\fldrslt {\rtlch\fcs1 \af45 \ltrch\fcs0 \lang1024\langfe1024\noproof\webhidden\insrsid1196296 10}}}\sectd \ltrsect\rtlgutter\psz1\linex0\endnhere\pgbrdropt32\sectdefaultcl\sectrsid6896082\sftnbj }}\sectd \ltrsect\rtlgutter\psz1\linex0\endnhere\pgbrdropt32\sectdefaultcl\sectrsid6896082\sftnbj { \rtlch\fcs1 \af31507\afs22 \ltrch\fcs0 \fs22\lang1024\langfe1024\loch\af31506\hich\af31506\dbch\af31505\noproof\insrsid1196296 \par }{\field\fldedit{\*\fldinst {\rtlch\fcs1 \af0 \ltrch\fcs0 \cs187\ul\cf2\lang1024\langfe1024\noproof\insrsid1196296\charrsid12086908 }{\rtlch\fcs1 \af45 \ltrch\fcs0 \lang1024\langfe1024\noproof\insrsid1196296 HYPERLINK \\l "_Toc87248731"}{\rtlch\fcs1 \af0 \ltrch\fcs0 \cs187\ul\cf2\lang1024\langfe1024\noproof\insrsid1196296\charrsid12086908 }{\rtlch\fcs1 \af0 \ltrch\fcs0 \cs187\ul\cf2\lang1024\langfe1024\noproof\insrsid1196296\charrsid12086908 {\*\datafield 08d0c9ea79f9bace118c8200aa004ba90b02000000080000000d0000005f0054006f006300380037003200340038003700330031000000}}}{\fldrslt {\rtlch\fcs1 \af0 \ltrch\fcs0 \cs187\b\ul\cf2\lang1024\langfe1024\noproof\insrsid1196296\charrsid12086908 V2.4.1.0 (30-Jan-2020)}{ \rtlch\fcs1 \af45 \ltrch\fcs0 \lang1024\langfe1024\noproof\webhidden\insrsid1196296 \tab }{\field{\*\fldinst {\rtlch\fcs1 \af45 \ltrch\fcs0 \lang1024\langfe1024\noproof\webhidden\insrsid1196296 PAGEREF _Toc87248731 \\h }{\rtlch\fcs1 \af45 \ltrch\fcs0 \lang1024\langfe1024\noproof\webhidden\insrsid1196296 {\*\datafield 08d0c9ea79f9bace118c8200aa004ba90b02000000080000000d0000005f0054006f006300380037003200340038003700330031000000}}}{\fldrslt {\rtlch\fcs1 \af45 \ltrch\fcs0 \lang1024\langfe1024\noproof\webhidden\insrsid1196296 10}}}\sectd \ltrsect\rtlgutter\psz1\linex0\endnhere\pgbrdropt32\sectdefaultcl\sectrsid6896082\sftnbj }}\sectd \ltrsect\rtlgutter\psz1\linex0\endnhere\pgbrdropt32\sectdefaultcl\sectrsid6896082\sftnbj { \rtlch\fcs1 \af31507\afs22 \ltrch\fcs0 \fs22\lang1024\langfe1024\loch\af31506\hich\af31506\dbch\af31505\noproof\insrsid1196296 \par }{\field\fldedit{\*\fldinst {\rtlch\fcs1 \af0 \ltrch\fcs0 \cs187\ul\cf2\lang1024\langfe1024\noproof\insrsid1196296\charrsid12086908 }{\rtlch\fcs1 \af45 \ltrch\fcs0 \lang1024\langfe1024\noproof\insrsid1196296 HYPERLINK \\l "_Toc87248732"}{\rtlch\fcs1 \af0 \ltrch\fcs0 \cs187\ul\cf2\lang1024\langfe1024\noproof\insrsid1196296\charrsid12086908 }{\rtlch\fcs1 \af0 \ltrch\fcs0 \cs187\ul\cf2\lang1024\langfe1024\noproof\insrsid1196296\charrsid12086908 {\*\datafield 08d0c9ea79f9bace118c8200aa004ba90b02000000080000000d0000005f0054006f006300380037003200340038003700330032000000}}}{\fldrslt {\rtlch\fcs1 \af0 \ltrch\fcs0 \cs187\b\ul\cf2\lang1024\langfe1024\noproof\insrsid1196296\charrsid12086908 V2.4.0.3 (13-Mar-2019)}{ \rtlch\fcs1 \af45 \ltrch\fcs0 \lang1024\langfe1024\noproof\webhidden\insrsid1196296 \tab }{\field{\*\fldinst {\rtlch\fcs1 \af45 \ltrch\fcs0 \lang1024\langfe1024\noproof\webhidden\insrsid1196296 PAGEREF _Toc87248732 \\h }{\rtlch\fcs1 \af45 \ltrch\fcs0 \lang1024\langfe1024\noproof\webhidden\insrsid1196296 {\*\datafield 08d0c9ea79f9bace118c8200aa004ba90b02000000080000000d0000005f0054006f006300380037003200340038003700330032000000}}}{\fldrslt {\rtlch\fcs1 \af45 \ltrch\fcs0 \lang1024\langfe1024\noproof\webhidden\insrsid1196296 10}}}\sectd \ltrsect\rtlgutter\psz1\linex0\endnhere\pgbrdropt32\sectdefaultcl\sectrsid6896082\sftnbj }}\sectd \ltrsect\rtlgutter\psz1\linex0\endnhere\pgbrdropt32\sectdefaultcl\sectrsid6896082\sftnbj { \rtlch\fcs1 \af31507\afs22 \ltrch\fcs0 \fs22\lang1024\langfe1024\loch\af31506\hich\af31506\dbch\af31505\noproof\insrsid1196296 \par }{\field\fldedit{\*\fldinst {\rtlch\fcs1 \af0 \ltrch\fcs0 \cs187\ul\cf2\lang1024\langfe1024\noproof\insrsid1196296\charrsid12086908 }{\rtlch\fcs1 \af45 \ltrch\fcs0 \lang1024\langfe1024\noproof\insrsid1196296 HYPERLINK \\l "_Toc87248733"}{\rtlch\fcs1 \af0 \ltrch\fcs0 \cs187\ul\cf2\lang1024\langfe1024\noproof\insrsid1196296\charrsid12086908 }{\rtlch\fcs1 \af0 \ltrch\fcs0 \cs187\ul\cf2\lang1024\langfe1024\noproof\insrsid1196296\charrsid12086908 {\*\datafield 08d0c9ea79f9bace118c8200aa004ba90b02000000080000000d0000005f0054006f006300380037003200340038003700330033000000}}}{\fldrslt {\rtlch\fcs1 \af0 \ltrch\fcs0 \cs187\b\ul\cf2\lang1024\langfe1024\noproof\insrsid1196296\charrsid12086908 V2.4.0.2 (25-Jan-2019)}{ \rtlch\fcs1 \af45 \ltrch\fcs0 \lang1024\langfe1024\noproof\webhidden\insrsid1196296 \tab }{\field{\*\fldinst {\rtlch\fcs1 \af45 \ltrch\fcs0 \lang1024\langfe1024\noproof\webhidden\insrsid1196296 PAGEREF _Toc87248733 \\h }{\rtlch\fcs1 \af45 \ltrch\fcs0 \lang1024\langfe1024\noproof\webhidden\insrsid1196296 {\*\datafield 08d0c9ea79f9bace118c8200aa004ba90b02000000080000000d0000005f0054006f006300380037003200340038003700330033000000}}}{\fldrslt {\rtlch\fcs1 \af45 \ltrch\fcs0 \lang1024\langfe1024\noproof\webhidden\insrsid1196296 11}}}\sectd \ltrsect\rtlgutter\psz1\linex0\endnhere\pgbrdropt32\sectdefaultcl\sectrsid6896082\sftnbj }}\sectd \ltrsect\rtlgutter\psz1\linex0\endnhere\pgbrdropt32\sectdefaultcl\sectrsid6896082\sftnbj { \rtlch\fcs1 \af31507\afs22 \ltrch\fcs0 \fs22\lang1024\langfe1024\loch\af31506\hich\af31506\dbch\af31505\noproof\insrsid1196296 \par }{\field\fldedit{\*\fldinst {\rtlch\fcs1 \af0 \ltrch\fcs0 \cs187\ul\cf2\lang1024\langfe1024\noproof\insrsid1196296\charrsid12086908 }{\rtlch\fcs1 \af45 \ltrch\fcs0 \lang1024\langfe1024\noproof\insrsid1196296 HYPERLINK \\l "_Toc87248734"}{\rtlch\fcs1 \af0 \ltrch\fcs0 \cs187\ul\cf2\lang1024\langfe1024\noproof\insrsid1196296\charrsid12086908 }{\rtlch\fcs1 \af0 \ltrch\fcs0 \cs187\ul\cf2\lang1024\langfe1024\noproof\insrsid1196296\charrsid12086908 {\*\datafield 08d0c9ea79f9bace118c8200aa004ba90b02000000080000000d0000005f0054006f006300380037003200340038003700330034000000}}}{\fldrslt {\rtlch\fcs1 \af0 \ltrch\fcs0 \cs187\b\ul\cf2\lang1024\langfe1024\noproof\insrsid1196296\charrsid12086908 V2.4.0.1 (19-Apr-2018)}{ \rtlch\fcs1 \af45 \ltrch\fcs0 \lang1024\langfe1024\noproof\webhidden\insrsid1196296 \tab }{\field{\*\fldinst {\rtlch\fcs1 \af45 \ltrch\fcs0 \lang1024\langfe1024\noproof\webhidden\insrsid1196296 PAGEREF _Toc87248734 \\h }{\rtlch\fcs1 \af45 \ltrch\fcs0 \lang1024\langfe1024\noproof\webhidden\insrsid1196296 {\*\datafield 08d0c9ea79f9bace118c8200aa004ba90b02000000080000000d0000005f0054006f006300380037003200340038003700330034000000}}}{\fldrslt {\rtlch\fcs1 \af45 \ltrch\fcs0 \lang1024\langfe1024\noproof\webhidden\insrsid1196296 11}}}\sectd \ltrsect\rtlgutter\psz1\linex0\endnhere\pgbrdropt32\sectdefaultcl\sectrsid6896082\sftnbj }}\sectd \ltrsect\rtlgutter\psz1\linex0\endnhere\pgbrdropt32\sectdefaultcl\sectrsid6896082\sftnbj { \rtlch\fcs1 \af31507\afs22 \ltrch\fcs0 \fs22\lang1024\langfe1024\loch\af31506\hich\af31506\dbch\af31505\noproof\insrsid1196296 \par }{\field\fldedit{\*\fldinst {\rtlch\fcs1 \af0 \ltrch\fcs0 \cs187\ul\cf2\lang1024\langfe1024\noproof\insrsid1196296\charrsid12086908 }{\rtlch\fcs1 \af45 \ltrch\fcs0 \lang1024\langfe1024\noproof\insrsid1196296 HYPERLINK \\l "_Toc87248735"}{\rtlch\fcs1 \af0 \ltrch\fcs0 \cs187\ul\cf2\lang1024\langfe1024\noproof\insrsid1196296\charrsid12086908 }{\rtlch\fcs1 \af0 \ltrch\fcs0 \cs187\ul\cf2\lang1024\langfe1024\noproof\insrsid1196296\charrsid12086908 {\*\datafield 08d0c9ea79f9bace118c8200aa004ba90b02000000080000000d0000005f0054006f006300380037003200340038003700330035000000}}}{\fldrslt {\rtlch\fcs1 \af0 \ltrch\fcs0 \cs187\b\ul\cf2\lang1024\langfe1024\noproof\insrsid1196296\charrsid12086908 V2.4.0.0 (darned if I know, 2017)}{\rtlch\fcs1 \af45 \ltrch\fcs0 \lang1024\langfe1024\noproof\webhidden\insrsid1196296 \tab }{\field{\*\fldinst {\rtlch\fcs1 \af45 \ltrch\fcs0 \lang1024\langfe1024\noproof\webhidden\insrsid1196296 PAGEREF _Toc87248735 \\h }{\rtlch\fcs1 \af45 \ltrch\fcs0 \lang1024\langfe1024\noproof\webhidden\insrsid1196296 {\*\datafield 08d0c9ea79f9bace118c8200aa004ba90b02000000080000000d0000005f0054006f006300380037003200340038003700330035000000}}}{\fldrslt {\rtlch\fcs1 \af45 \ltrch\fcs0 \lang1024\langfe1024\noproof\webhidden\insrsid1196296 11}}}\sectd \ltrsect\rtlgutter\psz1\linex0\endnhere\pgbrdropt32\sectdefaultcl\sectrsid6896082\sftnbj }}\sectd \ltrsect\rtlgutter\psz1\linex0\endnhere\pgbrdropt32\sectdefaultcl\sectrsid6896082\sftnbj { \rtlch\fcs1 \af31507\afs22 \ltrch\fcs0 \fs22\lang1024\langfe1024\loch\af31506\hich\af31506\dbch\af31505\noproof\insrsid1196296 \par }{\field\fldedit{\*\fldinst {\rtlch\fcs1 \af0 \ltrch\fcs0 \cs187\ul\cf2\lang1024\langfe1024\noproof\insrsid1196296\charrsid12086908 }{\rtlch\fcs1 \af45 \ltrch\fcs0 \lang1024\langfe1024\noproof\insrsid1196296 HYPERLINK \\l "_Toc87248736"}{\rtlch\fcs1 \af0 \ltrch\fcs0 \cs187\ul\cf2\lang1024\langfe1024\noproof\insrsid1196296\charrsid12086908 }{\rtlch\fcs1 \af0 \ltrch\fcs0 \cs187\ul\cf2\lang1024\langfe1024\noproof\insrsid1196296\charrsid12086908 {\*\datafield 08d0c9ea79f9bace118c8200aa004ba90b02000000080000000d0000005f0054006f006300380037003200340038003700330036000000}}}{\fldrslt {\rtlch\fcs1 \af0 \ltrch\fcs0 \cs187\b\ul\cf2\lang1024\langfe1024\noproof\insrsid1196296\charrsid12086908 V2.3.2.0 (18-Oct-2015)}{ \rtlch\fcs1 \af45 \ltrch\fcs0 \lang1024\langfe1024\noproof\webhidden\insrsid1196296 \tab }{\field{\*\fldinst {\rtlch\fcs1 \af45 \ltrch\fcs0 \lang1024\langfe1024\noproof\webhidden\insrsid1196296 PAGEREF _Toc87248736 \\h }{\rtlch\fcs1 \af45 \ltrch\fcs0 \lang1024\langfe1024\noproof\webhidden\insrsid1196296 {\*\datafield 08d0c9ea79f9bace118c8200aa004ba90b02000000080000000d0000005f0054006f006300380037003200340038003700330036000000}}}{\fldrslt {\rtlch\fcs1 \af45 \ltrch\fcs0 \lang1024\langfe1024\noproof\webhidden\insrsid1196296 11}}}\sectd \ltrsect\rtlgutter\psz1\linex0\endnhere\pgbrdropt32\sectdefaultcl\sectrsid6896082\sftnbj }}\sectd \ltrsect\rtlgutter\psz1\linex0\endnhere\pgbrdropt32\sectdefaultcl\sectrsid6896082\sftnbj { \rtlch\fcs1 \af31507\afs22 \ltrch\fcs0 \fs22\lang1024\langfe1024\loch\af31506\hich\af31506\dbch\af31505\noproof\insrsid1196296 \par }{\field\fldedit{\*\fldinst {\rtlch\fcs1 \af0 \ltrch\fcs0 \cs187\ul\cf2\lang1024\langfe1024\noproof\insrsid1196296\charrsid12086908 }{\rtlch\fcs1 \af45 \ltrch\fcs0 \lang1024\langfe1024\noproof\insrsid1196296 HYPERLINK \\l "_Toc87248737"}{\rtlch\fcs1 \af0 \ltrch\fcs0 \cs187\ul\cf2\lang1024\langfe1024\noproof\insrsid1196296\charrsid12086908 }{\rtlch\fcs1 \af0 \ltrch\fcs0 \cs187\ul\cf2\lang1024\langfe1024\noproof\insrsid1196296\charrsid12086908 {\*\datafield 08d0c9ea79f9bace118c8200aa004ba90b02000000080000000d0000005f0054006f006300380037003200340038003700330037000000}}}{\fldrslt {\rtlch\fcs1 \af0 \ltrch\fcs0 \cs187\b\ul\cf2\lang1024\langfe1024\noproof\insrsid1196296\charrsid12086908 V2.3.1.2 (13-Sep-2015)}{ \rtlch\fcs1 \af45 \ltrch\fcs0 \lang1024\langfe1024\noproof\webhidden\insrsid1196296 \tab }{\field{\*\fldinst {\rtlch\fcs1 \af45 \ltrch\fcs0 \lang1024\langfe1024\noproof\webhidden\insrsid1196296 PAGEREF _Toc87248737 \\h }{\rtlch\fcs1 \af45 \ltrch\fcs0 \lang1024\langfe1024\noproof\webhidden\insrsid1196296 {\*\datafield 08d0c9ea79f9bace118c8200aa004ba90b02000000080000000d0000005f0054006f006300380037003200340038003700330037000000}}}{\fldrslt {\rtlch\fcs1 \af45 \ltrch\fcs0 \lang1024\langfe1024\noproof\webhidden\insrsid1196296 12}}}\sectd \ltrsect\rtlgutter\psz1\linex0\endnhere\pgbrdropt32\sectdefaultcl\sectrsid6896082\sftnbj }}\sectd \ltrsect\rtlgutter\psz1\linex0\endnhere\pgbrdropt32\sectdefaultcl\sectrsid6896082\sftnbj { \rtlch\fcs1 \af31507\afs22 \ltrch\fcs0 \fs22\lang1024\langfe1024\loch\af31506\hich\af31506\dbch\af31505\noproof\insrsid1196296 \par }{\field\fldedit{\*\fldinst {\rtlch\fcs1 \af0 \ltrch\fcs0 \cs187\ul\cf2\lang1024\langfe1024\noproof\insrsid1196296\charrsid12086908 }{\rtlch\fcs1 \af45 \ltrch\fcs0 \lang1024\langfe1024\noproof\insrsid1196296 HYPERLINK \\l "_Toc87248738"}{\rtlch\fcs1 \af0 \ltrch\fcs0 \cs187\ul\cf2\lang1024\langfe1024\noproof\insrsid1196296\charrsid12086908 }{\rtlch\fcs1 \af0 \ltrch\fcs0 \cs187\ul\cf2\lang1024\langfe1024\noproof\insrsid1196296\charrsid12086908 {\*\datafield 08d0c9ea79f9bace118c8200aa004ba90b02000000080000000d0000005f0054006f006300380037003200340038003700330038000000}}}{\fldrslt {\rtlch\fcs1 \af0 \ltrch\fcs0 \cs187\b\ul\cf2\lang1024\langfe1024\noproof\insrsid1196296\charrsid12086908 V2.3.1.1 (27-Aug-2015)}{ \rtlch\fcs1 \af45 \ltrch\fcs0 \lang1024\langfe1024\noproof\webhidden\insrsid1196296 \tab }{\field{\*\fldinst {\rtlch\fcs1 \af45 \ltrch\fcs0 \lang1024\langfe1024\noproof\webhidden\insrsid1196296 PAGEREF _Toc87248738 \\h }{\rtlch\fcs1 \af45 \ltrch\fcs0 \lang1024\langfe1024\noproof\webhidden\insrsid1196296 {\*\datafield 08d0c9ea79f9bace118c8200aa004ba90b02000000080000000d0000005f0054006f006300380037003200340038003700330038000000}}}{\fldrslt {\rtlch\fcs1 \af45 \ltrch\fcs0 \lang1024\langfe1024\noproof\webhidden\insrsid1196296 12}}}\sectd \ltrsect\rtlgutter\psz1\linex0\endnhere\pgbrdropt32\sectdefaultcl\sectrsid6896082\sftnbj }}\sectd \ltrsect\rtlgutter\psz1\linex0\endnhere\pgbrdropt32\sectdefaultcl\sectrsid6896082\sftnbj { \rtlch\fcs1 \af31507\afs22 \ltrch\fcs0 \fs22\lang1024\langfe1024\loch\af31506\hich\af31506\dbch\af31505\noproof\insrsid1196296 \par }{\field\fldedit{\*\fldinst {\rtlch\fcs1 \af0 \ltrch\fcs0 \cs187\ul\cf2\lang1024\langfe1024\noproof\insrsid1196296\charrsid12086908 }{\rtlch\fcs1 \af45 \ltrch\fcs0 \lang1024\langfe1024\noproof\insrsid1196296 HYPERLINK \\l "_Toc87248739"}{\rtlch\fcs1 \af0 \ltrch\fcs0 \cs187\ul\cf2\lang1024\langfe1024\noproof\insrsid1196296\charrsid12086908 }{\rtlch\fcs1 \af0 \ltrch\fcs0 \cs187\ul\cf2\lang1024\langfe1024\noproof\insrsid1196296\charrsid12086908 {\*\datafield 08d0c9ea79f9bace118c8200aa004ba90b02000000080000000d0000005f0054006f006300380037003200340038003700330039000000}}}{\fldrslt {\rtlch\fcs1 \af0 \ltrch\fcs0 \cs187\b\ul\cf2\lang1024\langfe1024\noproof\insrsid1196296\charrsid12086908 V2.3.1.0 (13-Mar-2015)}{ \rtlch\fcs1 \af45 \ltrch\fcs0 \lang1024\langfe1024\noproof\webhidden\insrsid1196296 \tab }{\field{\*\fldinst {\rtlch\fcs1 \af45 \ltrch\fcs0 \lang1024\langfe1024\noproof\webhidden\insrsid1196296 PAGEREF _Toc87248739 \\h }{\rtlch\fcs1 \af45 \ltrch\fcs0 \lang1024\langfe1024\noproof\webhidden\insrsid1196296 {\*\datafield 08d0c9ea79f9bace118c8200aa004ba90b02000000080000000d0000005f0054006f006300380037003200340038003700330039000000}}}{\fldrslt {\rtlch\fcs1 \af45 \ltrch\fcs0 \lang1024\langfe1024\noproof\webhidden\insrsid1196296 12}}}\sectd \ltrsect\rtlgutter\psz1\linex0\endnhere\pgbrdropt32\sectdefaultcl\sectrsid6896082\sftnbj }}\sectd \ltrsect\rtlgutter\psz1\linex0\endnhere\pgbrdropt32\sectdefaultcl\sectrsid6896082\sftnbj { \rtlch\fcs1 \af31507\afs22 \ltrch\fcs0 \fs22\lang1024\langfe1024\loch\af31506\hich\af31506\dbch\af31505\noproof\insrsid1196296 \par }{\field\fldedit{\*\fldinst {\rtlch\fcs1 \af0 \ltrch\fcs0 \cs187\ul\cf2\lang1024\langfe1024\noproof\insrsid1196296\charrsid12086908 }{\rtlch\fcs1 \af45 \ltrch\fcs0 \lang1024\langfe1024\noproof\insrsid1196296 HYPERLINK \\l "_Toc87248740"}{\rtlch\fcs1 \af0 \ltrch\fcs0 \cs187\ul\cf2\lang1024\langfe1024\noproof\insrsid1196296\charrsid12086908 }{\rtlch\fcs1 \af0 \ltrch\fcs0 \cs187\ul\cf2\lang1024\langfe1024\noproof\insrsid1196296\charrsid12086908 {\*\datafield 08d0c9ea79f9bace118c8200aa004ba90b02000000080000000d0000005f0054006f006300380037003200340038003700340030000000}}}{\fldrslt {\rtlch\fcs1 \af0 \ltrch\fcs0 \cs187\b\ul\cf2\lang1024\langfe1024\noproof\insrsid1196296\charrsid12086908 V2.3.0.6 (30-Oct-2014)}{ \rtlch\fcs1 \af45 \ltrch\fcs0 \lang1024\langfe1024\noproof\webhidden\insrsid1196296 \tab }{\field{\*\fldinst {\rtlch\fcs1 \af45 \ltrch\fcs0 \lang1024\langfe1024\noproof\webhidden\insrsid1196296 PAGEREF _Toc87248740 \\h }{\rtlch\fcs1 \af45 \ltrch\fcs0 \lang1024\langfe1024\noproof\webhidden\insrsid1196296 {\*\datafield 08d0c9ea79f9bace118c8200aa004ba90b02000000080000000d0000005f0054006f006300380037003200340038003700340030000000}}}{\fldrslt {\rtlch\fcs1 \af45 \ltrch\fcs0 \lang1024\langfe1024\noproof\webhidden\insrsid1196296 12}}}\sectd \ltrsect\rtlgutter\psz1\linex0\endnhere\pgbrdropt32\sectdefaultcl\sectrsid6896082\sftnbj }}\sectd \ltrsect\rtlgutter\psz1\linex0\endnhere\pgbrdropt32\sectdefaultcl\sectrsid6896082\sftnbj { \rtlch\fcs1 \af31507\afs22 \ltrch\fcs0 \fs22\lang1024\langfe1024\loch\af31506\hich\af31506\dbch\af31505\noproof\insrsid1196296 \par }{\field\fldedit{\*\fldinst {\rtlch\fcs1 \af0 \ltrch\fcs0 \cs187\ul\cf2\lang1024\langfe1024\noproof\insrsid1196296\charrsid12086908 }{\rtlch\fcs1 \af45 \ltrch\fcs0 \lang1024\langfe1024\noproof\insrsid1196296 HYPERLINK \\l "_Toc87248741"}{\rtlch\fcs1 \af0 \ltrch\fcs0 \cs187\ul\cf2\lang1024\langfe1024\noproof\insrsid1196296\charrsid12086908 }{\rtlch\fcs1 \af0 \ltrch\fcs0 \cs187\ul\cf2\lang1024\langfe1024\noproof\insrsid1196296\charrsid12086908 {\*\datafield 08d0c9ea79f9bace118c8200aa004ba90b02000000080000000d0000005f0054006f006300380037003200340038003700340031000000}}}{\fldrslt {\rtlch\fcs1 \af0 \ltrch\fcs0 \cs187\b\ul\cf2\lang1024\langfe1024\noproof\insrsid1196296\charrsid12086908 V2.3.0.5 (19-Oct-2014)}{ \rtlch\fcs1 \af45 \ltrch\fcs0 \lang1024\langfe1024\noproof\webhidden\insrsid1196296 \tab }{\field{\*\fldinst {\rtlch\fcs1 \af45 \ltrch\fcs0 \lang1024\langfe1024\noproof\webhidden\insrsid1196296 PAGEREF _Toc87248741 \\h }{\rtlch\fcs1 \af45 \ltrch\fcs0 \lang1024\langfe1024\noproof\webhidden\insrsid1196296 {\*\datafield 08d0c9ea79f9bace118c8200aa004ba90b02000000080000000d0000005f0054006f006300380037003200340038003700340031000000}}}{\fldrslt {\rtlch\fcs1 \af45 \ltrch\fcs0 \lang1024\langfe1024\noproof\webhidden\insrsid1196296 13}}}\sectd \ltrsect\rtlgutter\psz1\linex0\endnhere\pgbrdropt32\sectdefaultcl\sectrsid6896082\sftnbj }}\sectd \ltrsect\rtlgutter\psz1\linex0\endnhere\pgbrdropt32\sectdefaultcl\sectrsid6896082\sftnbj { \rtlch\fcs1 \af31507\afs22 \ltrch\fcs0 \fs22\lang1024\langfe1024\loch\af31506\hich\af31506\dbch\af31505\noproof\insrsid1196296 \par }{\field\fldedit{\*\fldinst {\rtlch\fcs1 \af0 \ltrch\fcs0 \cs187\ul\cf2\lang1024\langfe1024\noproof\insrsid1196296\charrsid12086908 }{\rtlch\fcs1 \af45 \ltrch\fcs0 \lang1024\langfe1024\noproof\insrsid1196296 HYPERLINK \\l "_Toc87248742"}{\rtlch\fcs1 \af0 \ltrch\fcs0 \cs187\ul\cf2\lang1024\langfe1024\noproof\insrsid1196296\charrsid12086908 }{\rtlch\fcs1 \af0 \ltrch\fcs0 \cs187\ul\cf2\lang1024\langfe1024\noproof\insrsid1196296\charrsid12086908 {\*\datafield 08d0c9ea79f9bace118c8200aa004ba90b02000000080000000d0000005f0054006f006300380037003200340038003700340032000000}}}{\fldrslt {\rtlch\fcs1 \af0 \ltrch\fcs0 \cs187\b\ul\cf2\lang1024\langfe1024\noproof\insrsid1196296\charrsid12086908 V2.3.0.4 (13-Oct-2014)}{ \rtlch\fcs1 \af45 \ltrch\fcs0 \lang1024\langfe1024\noproof\webhidden\insrsid1196296 \tab }{\field{\*\fldinst {\rtlch\fcs1 \af45 \ltrch\fcs0 \lang1024\langfe1024\noproof\webhidden\insrsid1196296 PAGEREF _Toc87248742 \\h }{\rtlch\fcs1 \af45 \ltrch\fcs0 \lang1024\langfe1024\noproof\webhidden\insrsid1196296 {\*\datafield 08d0c9ea79f9bace118c8200aa004ba90b02000000080000000d0000005f0054006f006300380037003200340038003700340032000000}}}{\fldrslt {\rtlch\fcs1 \af45 \ltrch\fcs0 \lang1024\langfe1024\noproof\webhidden\insrsid1196296 13}}}\sectd \ltrsect\rtlgutter\psz1\linex0\endnhere\pgbrdropt32\sectdefaultcl\sectrsid6896082\sftnbj }}\sectd \ltrsect\rtlgutter\psz1\linex0\endnhere\pgbrdropt32\sectdefaultcl\sectrsid6896082\sftnbj { \rtlch\fcs1 \af31507\afs22 \ltrch\fcs0 \fs22\lang1024\langfe1024\loch\af31506\hich\af31506\dbch\af31505\noproof\insrsid1196296 \par }{\field\fldedit{\*\fldinst {\rtlch\fcs1 \af0 \ltrch\fcs0 \cs187\ul\cf2\lang1024\langfe1024\noproof\insrsid1196296\charrsid12086908 }{\rtlch\fcs1 \af45 \ltrch\fcs0 \lang1024\langfe1024\noproof\insrsid1196296 HYPERLINK \\l "_Toc87248743"}{\rtlch\fcs1 \af0 \ltrch\fcs0 \cs187\ul\cf2\lang1024\langfe1024\noproof\insrsid1196296\charrsid12086908 }{\rtlch\fcs1 \af0 \ltrch\fcs0 \cs187\ul\cf2\lang1024\langfe1024\noproof\insrsid1196296\charrsid12086908 {\*\datafield 08d0c9ea79f9bace118c8200aa004ba90b02000000080000000d0000005f0054006f006300380037003200340038003700340033000000}}}{\fldrslt {\rtlch\fcs1 \af0 \ltrch\fcs0 \cs187\b\ul\cf2\lang1024\langfe1024\noproof\insrsid1196296\charrsid12086908 V2.2.0 (11-Jul-2014)}{ \rtlch\fcs1 \af45 \ltrch\fcs0 \lang1024\langfe1024\noproof\webhidden\insrsid1196296 \tab }{\field{\*\fldinst {\rtlch\fcs1 \af45 \ltrch\fcs0 \lang1024\langfe1024\noproof\webhidden\insrsid1196296 PAGEREF _Toc87248743 \\h }{\rtlch\fcs1 \af45 \ltrch\fcs0 \lang1024\langfe1024\noproof\webhidden\insrsid1196296 {\*\datafield 08d0c9ea79f9bace118c8200aa004ba90b02000000080000000d0000005f0054006f006300380037003200340038003700340033000000}}}{\fldrslt {\rtlch\fcs1 \af45 \ltrch\fcs0 \lang1024\langfe1024\noproof\webhidden\insrsid1196296 13}}}\sectd \ltrsect\rtlgutter\psz1\linex0\endnhere\pgbrdropt32\sectdefaultcl\sectrsid6896082\sftnbj }}\sectd \ltrsect\rtlgutter\psz1\linex0\endnhere\pgbrdropt32\sectdefaultcl\sectrsid6896082\sftnbj { \rtlch\fcs1 \af31507\afs22 \ltrch\fcs0 \fs22\lang1024\langfe1024\loch\af31506\hich\af31506\dbch\af31505\noproof\insrsid1196296 \par }{\field\fldedit{\*\fldinst {\rtlch\fcs1 \af0 \ltrch\fcs0 \cs187\ul\cf2\lang1024\langfe1024\noproof\insrsid1196296\charrsid12086908 }{\rtlch\fcs1 \af45 \ltrch\fcs0 \lang1024\langfe1024\noproof\insrsid1196296 HYPERLINK \\l "_Toc87248744"}{\rtlch\fcs1 \af0 \ltrch\fcs0 \cs187\ul\cf2\lang1024\langfe1024\noproof\insrsid1196296\charrsid12086908 }{\rtlch\fcs1 \af0 \ltrch\fcs0 \cs187\ul\cf2\lang1024\langfe1024\noproof\insrsid1196296\charrsid12086908 {\*\datafield 08d0c9ea79f9bace118c8200aa004ba90b02000000080000000d0000005f0054006f006300380037003200340038003700340034000000}}}{\fldrslt {\rtlch\fcs1 \af0 \ltrch\fcs0 \cs187\b\ul\cf2\lang1024\langfe1024\noproof\insrsid1196296\charrsid12086908 V2.1.0 (09-Jul-2014)}{ \rtlch\fcs1 \af45 \ltrch\fcs0 \lang1024\langfe1024\noproof\webhidden\insrsid1196296 \tab }{\field{\*\fldinst {\rtlch\fcs1 \af45 \ltrch\fcs0 \lang1024\langfe1024\noproof\webhidden\insrsid1196296 PAGEREF _Toc87248744 \\h }{\rtlch\fcs1 \af45 \ltrch\fcs0 \lang1024\langfe1024\noproof\webhidden\insrsid1196296 {\*\datafield 08d0c9ea79f9bace118c8200aa004ba90b02000000080000000d0000005f0054006f006300380037003200340038003700340034000000}}}{\fldrslt {\rtlch\fcs1 \af45 \ltrch\fcs0 \lang1024\langfe1024\noproof\webhidden\insrsid1196296 14}}}\sectd \ltrsect\rtlgutter\psz1\linex0\endnhere\pgbrdropt32\sectdefaultcl\sectrsid6896082\sftnbj }}\sectd \ltrsect\rtlgutter\psz1\linex0\endnhere\pgbrdropt32\sectdefaultcl\sectrsid6896082\sftnbj { \rtlch\fcs1 \af31507\afs22 \ltrch\fcs0 \fs22\lang1024\langfe1024\loch\af31506\hich\af31506\dbch\af31505\noproof\insrsid1196296 \par }{\field\fldedit{\*\fldinst {\rtlch\fcs1 \af0 \ltrch\fcs0 \cs187\ul\cf2\lang1024\langfe1024\noproof\insrsid1196296\charrsid12086908 }{\rtlch\fcs1 \af45 \ltrch\fcs0 \lang1024\langfe1024\noproof\insrsid1196296 HYPERLINK \\l "_Toc87248745"}{\rtlch\fcs1 \af0 \ltrch\fcs0 \cs187\ul\cf2\lang1024\langfe1024\noproof\insrsid1196296\charrsid12086908 }{\rtlch\fcs1 \af0 \ltrch\fcs0 \cs187\ul\cf2\lang1024\langfe1024\noproof\insrsid1196296\charrsid12086908 {\*\datafield 08d0c9ea79f9bace118c8200aa004ba90b02000000080000000d0000005f0054006f006300380037003200340038003700340035000000}}}{\fldrslt {\rtlch\fcs1 \af0 \ltrch\fcs0 \cs187\b\ul\cf2\lang1024\langfe1024\noproof\insrsid1196296\charrsid12086908 V2.0.0 (21-May-2014)}{ \rtlch\fcs1 \af45 \ltrch\fcs0 \lang1024\langfe1024\noproof\webhidden\insrsid1196296 \tab }{\field{\*\fldinst {\rtlch\fcs1 \af45 \ltrch\fcs0 \lang1024\langfe1024\noproof\webhidden\insrsid1196296 PAGEREF _Toc87248745 \\h }{\rtlch\fcs1 \af45 \ltrch\fcs0 \lang1024\langfe1024\noproof\webhidden\insrsid1196296 {\*\datafield 08d0c9ea79f9bace118c8200aa004ba90b02000000080000000d0000005f0054006f006300380037003200340038003700340035000000}}}{\fldrslt {\rtlch\fcs1 \af45 \ltrch\fcs0 \lang1024\langfe1024\noproof\webhidden\insrsid1196296 14}}}\sectd \ltrsect\rtlgutter\psz1\linex0\endnhere\pgbrdropt32\sectdefaultcl\sectrsid6896082\sftnbj }}\sectd \ltrsect\rtlgutter\psz1\linex0\endnhere\pgbrdropt32\sectdefaultcl\sectrsid6896082\sftnbj { \rtlch\fcs1 \af31507\afs22 \ltrch\fcs0 \fs22\lang1024\langfe1024\loch\af31506\hich\af31506\dbch\af31505\noproof\insrsid1196296 \par }{\field\fldedit{\*\fldinst {\rtlch\fcs1 \af0 \ltrch\fcs0 \cs187\ul\cf2\lang1024\langfe1024\noproof\insrsid1196296\charrsid12086908 }{\rtlch\fcs1 \af45 \ltrch\fcs0 \lang1024\langfe1024\noproof\insrsid1196296 HYPERLINK \\l "_Toc87248746"}{\rtlch\fcs1 \af0 \ltrch\fcs0 \cs187\ul\cf2\lang1024\langfe1024\noproof\insrsid1196296\charrsid12086908 }{\rtlch\fcs1 \af0 \ltrch\fcs0 \cs187\ul\cf2\lang1024\langfe1024\noproof\insrsid1196296\charrsid12086908 {\*\datafield 08d0c9ea79f9bace118c8200aa004ba90b02000000080000000d0000005f0054006f006300380037003200340038003700340036000000}}}{\fldrslt {\rtlch\fcs1 \af0 \ltrch\fcs0 \cs187\b\ul\cf2\lang1024\langfe1024\noproof\insrsid1196296\charrsid12086908 V1.1.0 (27-Feb-2014)}{ \rtlch\fcs1 \af45 \ltrch\fcs0 \lang1024\langfe1024\noproof\webhidden\insrsid1196296 \tab }{\field{\*\fldinst {\rtlch\fcs1 \af45 \ltrch\fcs0 \lang1024\langfe1024\noproof\webhidden\insrsid1196296 PAGEREF _Toc87248746 \\h }{\rtlch\fcs1 \af45 \ltrch\fcs0 \lang1024\langfe1024\noproof\webhidden\insrsid1196296 {\*\datafield 08d0c9ea79f9bace118c8200aa004ba90b02000000080000000d0000005f0054006f006300380037003200340038003700340036000000}}}{\fldrslt {\rtlch\fcs1 \af45 \ltrch\fcs0 \lang1024\langfe1024\noproof\webhidden\insrsid1196296 14}}}\sectd \ltrsect\rtlgutter\psz1\linex0\endnhere\pgbrdropt32\sectdefaultcl\sectrsid6896082\sftnbj }}\sectd \ltrsect\rtlgutter\psz1\linex0\endnhere\pgbrdropt32\sectdefaultcl\sectrsid6896082\sftnbj { \rtlch\fcs1 \af31507\afs22 \ltrch\fcs0 \fs22\lang1024\langfe1024\loch\af31506\hich\af31506\dbch\af31505\noproof\insrsid1196296 \par }{\field\fldedit{\*\fldinst {\rtlch\fcs1 \af0 \ltrch\fcs0 \cs187\ul\cf2\lang1024\langfe1024\noproof\insrsid1196296\charrsid12086908 }{\rtlch\fcs1 \af45 \ltrch\fcs0 \lang1024\langfe1024\noproof\insrsid1196296 HYPERLINK \\l "_Toc87248747"}{\rtlch\fcs1 \af0 \ltrch\fcs0 \cs187\ul\cf2\lang1024\langfe1024\noproof\insrsid1196296\charrsid12086908 }{\rtlch\fcs1 \af0 \ltrch\fcs0 \cs187\ul\cf2\lang1024\langfe1024\noproof\insrsid1196296\charrsid12086908 {\*\datafield 08d0c9ea79f9bace118c8200aa004ba90b02000000080000000d0000005f0054006f006300380037003200340038003700340037000000}}}{\fldrslt {\rtlch\fcs1 \af0 \ltrch\fcs0 \cs187\b\ul\cf2\lang1024\langfe1024\noproof\insrsid1196296\charrsid12086908 V1.0.0 (05-Nov-2013)}{ \rtlch\fcs1 \af45 \ltrch\fcs0 \lang1024\langfe1024\noproof\webhidden\insrsid1196296 \tab }{\field{\*\fldinst {\rtlch\fcs1 \af45 \ltrch\fcs0 \lang1024\langfe1024\noproof\webhidden\insrsid1196296 PAGEREF _Toc87248747 \\h }{\rtlch\fcs1 \af45 \ltrch\fcs0 \lang1024\langfe1024\noproof\webhidden\insrsid1196296 {\*\datafield 08d0c9ea79f9bace118c8200aa004ba90b02000000080000000d0000005f0054006f006300380037003200340038003700340037000000}}}{\fldrslt {\rtlch\fcs1 \af45 \ltrch\fcs0 \lang1024\langfe1024\noproof\webhidden\insrsid1196296 15}}}\sectd \ltrsect\rtlgutter\psz1\linex0\endnhere\pgbrdropt32\sectdefaultcl\sectrsid6896082\sftnbj }}\sectd \ltrsect\rtlgutter\psz1\linex0\endnhere\pgbrdropt32\sectdefaultcl\sectrsid6896082\sftnbj { \rtlch\fcs1 \af31507\afs22 \ltrch\fcs0 \fs22\lang1024\langfe1024\loch\af31506\hich\af31506\dbch\af31505\noproof\insrsid1196296 \par }\pard\plain \ltrpar\s98\ql \li1440\ri0\sb120\keep\keepn\widctlpar\tqr\tldot\tx9893\wrapdefault\nooverflow\faroman\rin0\lin1440\itap0 \rtlch\fcs1 \ab\af1\afs20\alang1025 \ltrch\fcs0 \b\f1\fs20\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 }} \pard\plain \ltrpar\s98\ql \li1440\ri0\sb120\keep\keepn\widctlpar\tqr\tldot\tx9893\wrapdefault\nooverflow\faroman\rin0\lin1440\itap0 \rtlch\fcs1 \ab\af1\afs20\alang1025 \ltrch\fcs0 \b\f1\fs20\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \sectd \ltrsect\rtlgutter\psz1\linex0\endnhere\pgbrdropt32\sectdefaultcl\sectrsid6896082\sftnbj {\rtlch\fcs1 \af1 \ltrch\fcs0 \f31506\cf9\insrsid6441407 {\*\bkmkstart _Toc234021027} \par }\pard\plain \ltrpar\ql \li720\ri0\sb180\widctlpar\wrapdefault\nooverflow\faroman\rin0\lin720\itap0 \rtlch\fcs1 \af45\afs20\alang1025 \ltrch\fcs0 \f45\fs20\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 {\rtlch\fcs1 \af45 \ltrch\fcs0 \f31506\insrsid6441407 \par }\pard \ltrpar\ql \li0\ri0\widctlpar\wrapdefault\nooverflow\faroman\rin0\lin0\itap0 {\rtlch\fcs1 \af51 \ltrch\fcs0 \f31506\insrsid6441407 \par }\pard \ltrpar\ql \li720\ri0\sb180\widctlpar\wrapdefault\nooverflow\faroman\rin0\lin720\itap0 {\rtlch\fcs1 \af1\afs36 \ltrch\fcs0 \b\f37\fs36\cf9\insrsid6441407 \par }\pard\plain \ltrpar\s1\ql \li90\ri0\sb720\keepn\widctlpar\brdrt\brdrs\brdrw30\brsp120 \wrapdefault\nooverflow\faroman\outlinelevel0\rin0\lin90\itap0 \rtlch\fcs1 \ab\af1\afs36\alang1025 \ltrch\fcs0 \b\f1\fs36\cf9\lang1024\langfe1024\cgrid\noproof\langnp1033\langfenp1033 {\rtlch\fcs1 \af1 \ltrch\fcs0 \b0\f37\insrsid6441407 \page }{\rtlch\fcs1 \af1 \ltrch\fcs0 \f37\noproof0\insrsid6441407 {\*\bkmkstart _Toc87248710}Purpose{\*\bkmkend _Toc87248710} \par }\pard\plain \ltrpar\ql \li1440\ri0\sb180\widctlpar\wrapdefault\nooverflow\faroman\rin0\lin1440\itap0 \rtlch\fcs1 \af45\afs20\alang1025 \ltrch\fcs0 \f45\fs20\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 {\rtlch\fcs1 \af45\afs22 \ltrch\fcs0 \f37\fs22\insrsid6441407 This document serves as a brief introduction to the TWAIN CS projects. It assumes familiarity with the C# programming language, and a basic understanding of the TWAIN Specification. \par The version number supplied in the title is a guide to when the document was last modified. TWAIN supports feature negotiated interoperability between all versions of TWAIN enabled applications, TWAIN drivers (data sources), and the TWAIN Data Source Manager. \par }{\rtlch\fcs1 \af45 \ltrch\fcs0 \f37\insrsid6441407 \par }\pard\plain \ltrpar\s1\ql \li0\ri0\sb720\keepn\widctlpar\brdrt\brdrs\brdrw30\brsp120 \wrapdefault\nooverflow\faroman\outlinelevel0\rin0\lin0\itap0 \rtlch\fcs1 \ab\af1\afs36\alang1025 \ltrch\fcs0 \b\f1\fs36\cf9\lang1024\langfe1024\cgrid\noproof\langnp1033\langfenp1033 {\rtlch\fcs1 \af1 \ltrch\fcs0 \f37\insrsid6441407 {\*\bkmkstart _Toc87248711}License{\*\bkmkend _Toc87248711} \par }\pard\plain \ltrpar\ql \li1440\ri0\widctlpar\wrapdefault\faauto\rin0\lin1440\itap0 \rtlch\fcs1 \af45\afs20\alang1025 \ltrch\fcs0 \f45\fs20\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 {\rtlch\fcs1 \af50 \ltrch\fcs0 \f37\insrsid6441407 \par }{\rtlch\fcs1 \af50\afs22 \ltrch\fcs0 \f37\fs22\insrsid6441407 Copyright (C) 2013-202}{\rtlch\fcs1 \af50\afs22 \ltrch\fcs0 \f37\fs22\insrsid8668465 1}{\rtlch\fcs1 \af50\afs22 \ltrch\fcs0 \f37\fs22\insrsid6441407 Kodak Alaris Inc. \par \par Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to u se, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: \par \par The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. \par \par THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND N ONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALIN GS IN THE SOFTWARE. \par }\pard \ltrpar\ql \li720\ri0\sb180\keep\keepn\widctlpar\wrapdefault\nooverflow\faroman\rin0\lin720\itap0 {\rtlch\fcs1 \af1\afs36 \ltrch\fcs0 \b\f37\fs36\cf9\insrsid6441407 \par }\pard \ltrpar\ql \li720\ri0\widctlpar\wrapdefault\nooverflow\faroman\rin0\lin720\itap0 {\rtlch\fcs1 \af51 \ltrch\fcs0 \f31506\insrsid6441407 \par }\pard\plain \ltrpar\s189\ql \li0\ri0\keepn\pagebb\widctlpar\brdrt\brdrs\brdrw30\brsp120 \wrapdefault\nooverflow\faroman\outlinelevel0\rin0\lin0\itap0 \rtlch\fcs1 \ab\af1\afs24\alang1025 \ltrch\fcs0 \b\f1\fs24\cf9\lang1024\langfe1024\cgrid\noproof\langnp1033\langfenp1033 {\rtlch\fcs1 \af1\afs36 \ltrch\fcs0 \f31506\fs36\noproof0\insrsid6441407 {\*\bkmkstart _Toc87248712}Project Repository{\*\bkmkend _Toc87248712} \par }\pard\plain \ltrpar\ql \li0\ri0\widctlpar\wrapdefault\nooverflow\faroman\rin0\lin0\itap0 \rtlch\fcs1 \af45\afs20\alang1025 \ltrch\fcs0 \f45\fs20\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 {\rtlch\fcs1 \af0 \ltrch\fcs0 \v\f31506\cf6\insrsid6441407 \par }\pard\plain \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 \rtlch\fcs1 \af37\afs22\alang1025 \ltrch\fcs0 \f37\fs22\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 {\rtlch\fcs1 \af0 \ltrch\fcs0 \v\f31506\cf6\insrsid6441407 [Technical Notes]}{\rtlch\fcs1 \af0\afs20 \ltrch\fcs0 \i\v\f31506\fs20\cf6\insrsid6441407 \par }{\rtlch\fcs1 \af37 \ltrch\fcs0 \i\v\f31506\cf6\insrsid6441407 I think we made a mistake here. All of the capabilities that use TW_ARRAY containers only show TW_ONEVALUE as the valid container for MSG_SET. It should be TW_ONEVALUE and TW_ARRAY. \par }{\rtlch\fcs1 \af37 \ltrch\fcs0 \i\f31506\cf6\insrsid6441407 \par }{\rtlch\fcs1 \af37 \ltrch\fcs0 \f31506\insrsid6441407 TWAIN for C-Sharp (C#) resides on GitHub at }{\field{\*\fldinst {\rtlch\fcs1 \af37 \ltrch\fcs0 \insrsid6441407 HYPERLINK "https://github.com/twain/twain-cs" }{\rtlch\fcs1 \af37 \ltrch\fcs0 \insrsid6441407 {\*\datafield 00d0c9ea79f9bace118c8200aa004ba90b0200000003000000e0c9ea79f9bace118c8200aa004ba90b5c000000680074007400700073003a002f002f006700690074006800750062002e0063006f006d002f0074007700610069006e002f0074007700610069006e002d00630073000000795881f43b1d7f48af2c825dc485 276300000000a5ab00030000001500ef000000ff}}}{\fldrslt {\rtlch\fcs1 \af37 \ltrch\fcs0 \cs187\ul\cf2\insrsid6441407 https://github.com/twain/twain-cs}}}\sectd \ltrsect\rtlgutter\psz1\linex0\endnhere\pgbrdropt32\sectdefaultcl\sectrsid6896082\sftnbj { \rtlch\fcs1 \af37 \ltrch\fcs0 \f31506\insrsid6441407 . \par }{\rtlch\fcs1 \af37 \ltrch\fcs0 \insrsid6441407 \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\outlinelevel1\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 \b\ul\insrsid6441407 {\*\bkmkstart _Toc87248713}Installation{\*\bkmkend _Toc87248713} \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 \insrsid6441407 \par There is a releases folder that contains release and debug copies of the binaries. There is no installation kit, just run them as-is. If running on Linux or macOS it may be necessary to install or upgrade Mono to v4.8 or higher. The certification tool automatically creates a \lquote TWAIN Self Certification\rquote folder on the user\rquote s desktop, which contains all the stuff needed for certification. \par \par \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\outlinelevel1\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 \b\ul\insrsid6441407 {\*\bkmkstart _Toc87248714}Versioning{\*\bkmkend _Toc87248714} \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 \f31506\insrsid6441407 \par The versioning scheme takes the form: TWAIN-ProtocolMajor.TWAIN-ProtocolMinor.Interface.Build \par \par If the TWAIN Specification is at 2.3 then the version will be 2.3.i.b. This is for notational purposes only, TWAIN interoperates at all versions of the protocol, so there is no requirement that a developer has to use any specific version, or i mmediately upgrade if there is a change to the TWAIN Specification. \par \par The interface number rises if there is a modification to the TWAINCS that requires a code change in TWAINCSTest or TWAINCSScan. This lets a developer know that downloading the new versio n will most likely require some work in their code before they can use it. This assumption always applies when the TWAIN Specification changes, so the interface number resets to 0 when they are modified. \par \par The build number tracks releases for a given version of the TWAIN Specification, and always rises until a new version of the spec is adopted. \par \par So, for example (fictitious sequence, just to show how it works): \par \par 2.3.0.0 \endash initial release to go with TWAIN 2.3 \par 2.3.0.1 \endash bug fix \par 2.3.0.2 \endash bug fix \par 2.3.1.3 \endash interface change \par 2.3.1.4 \endash bug fix \par 2.4.0.0 \endash initial release to go with TWAIN 2.4 \par \par }\pard\plain \ltrpar\s189\ql \li0\ri0\keepn\pagebb\widctlpar\brdrt\brdrs\brdrw30\brsp120 \wrapdefault\nooverflow\faroman\outlinelevel0\rin0\lin0\itap0 \rtlch\fcs1 \ab\af1\afs24\alang1025 \ltrch\fcs0 \b\f1\fs24\cf9\lang1024\langfe1024\cgrid\noproof\langnp1033\langfenp1033 {\rtlch\fcs1 \af1\afs36 \ltrch\fcs0 \f31506\fs36\noproof0\insrsid6441407 {\*\bkmkstart _Toc87248715}Project Layout{\*\bkmkend _Toc87248715} \par }\pard\plain \ltrpar\ql \li0\ri0\widctlpar\wrapdefault\nooverflow\faroman\rin0\lin0\itap0 \rtlch\fcs1 \af45\afs20\alang1025 \ltrch\fcs0 \f45\fs20\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 {\rtlch\fcs1 \af0 \ltrch\fcs0 \v\f31506\cf6\insrsid6441407 \par }\pard\plain \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 \rtlch\fcs1 \af37\afs22\alang1025 \ltrch\fcs0 \f37\fs22\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 {\rtlch\fcs1 \af0 \ltrch\fcs0 \v\f31506\cf6\insrsid6441407 [Technical Notes]}{\rtlch\fcs1 \af0\afs20 \ltrch\fcs0 \i\v\f31506\fs20\cf6\insrsid6441407 \par }{\rtlch\fcs1 \af37 \ltrch\fcs0 \i\v\f31506\cf6\insrsid6441407 I think we made a mistake here. All of the capabilities that use TW_ARRAY containers only show TW_ONEVALUE as the valid container for MSG_SET. It should be TW_ONEVALUE and TW_ARRAY. \par }{\rtlch\fcs1 \af37 \ltrch\fcs0 \i\f31506\cf6\insrsid6441407 \par }\pard \ltrpar\s199\ql \li360\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin360\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 \f31506\insrsid6441407 There are five projects in the TWAIN CS repository, with a single solution file to access them all: \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22\insrsid6441407 \hich\af37\dbch\af0\loch\f37 -\tab}}\pard \ltrpar \s199\ql \fi-360\li720\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\ls12\adjustright\rin0\lin720\itap0\pararsid6555766 {\rtlch\fcs1 \af37 \ltrch\fcs0 \f31506\insrsid6441407 Basic TWAIN C# Definitions and Helper Functions \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22\insrsid6441407 \hich\af37\dbch\af0\loch\f37 -\tab}A TWAIN C# Diagnostic Application \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22\insrsid6441407 \hich\af37\dbch\af0\loch\f37 -\tab}A TWAIN C# Sample Application \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22\insrsid6441407 \hich\af37\dbch\af0\loch\f37 -\tab}}{\rtlch\fcs1 \af37 \ltrch\fcs0 \insrsid6441407 A TWAIN C# Self Certification Application \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 \f31506\insrsid6441407 \par }\pard \ltrpar\s199\ql \li360\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin360\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 \f31506\insrsid8668465 The}{\rtlch\fcs1 \af37 \ltrch\fcs0 \f31506\insrsid6441407 }{\rtlch\fcs1 \af37 \ltrch\fcs0 \f31506\insrsid8668465 a}{\rtlch\fcs1 \af37 \ltrch\fcs0 \f31506\insrsid6441407 pplications reference the }{\rtlch\fcs1 \af37 \ltrch\fcs0 \f31506\insrsid8668465 basic definitions and helper function}{\rtlch\fcs1 \af37 \ltrch\fcs0 \f31506\insrsid6441407 . }{\rtlch\fcs1 \af37 \ltrch\fcs0 \f31506\insrsid8668465 Previous versions used a toolkit layer, but this introduced more complexity than it removed}{\rtlch\fcs1 \af37 \ltrch\fcs0 \f31506\insrsid1196296 , so it was deleted}{\rtlch\fcs1 \af37 \ltrch\fcs0 \f31506\insrsid6441407 . \par \par It\rquote s assumed that application writers will opt t o pull this source code into a single assembly, the most common selection being the basic definitions and the sample application. Updates will be accomplished by pulling in newer versions of these files. Updates will typically come from the basic defini tions. \par \par If you decide to keep the items as separate projects, then make a note of the inside of each of the .csproj files. Replacing the platform\\configuration folder names with }{\rtlch\fcs1 \af37 \ltrch\fcs0 \insrsid6441407 $(Platform)\\ $(Configuration) makes for a much better build experience, since the references correctly track to the current settings. \par }{\rtlch\fcs1 \af37 \ltrch\fcs0 \f31506\insrsid6441407 \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 \f31506\insrsid6441407 \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\outlinelevel1\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 \b\f31506\ul\insrsid6441407 {\*\bkmkstart _Toc87248716}Basic TWAIN C# Definitions and Helper Functions {\*\bkmkend _Toc87248716} \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af0 \ltrch\fcs0 \f31506\insrsid6441407 \par }\pard \ltrpar\s199\ql \li360\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin360\itap0 {\rtlch\fcs1 \af0 \ltrch\fcs0 \f31506\insrsid6441407 TWAINH.CS contains all of the C/C++ TWAIN.H definitions for the version of TWAIN referenced on the title page of this document. \par \par TWAIN.CS contains helper functions designed to hide platform specific details, and to promote best practices when interfacing with the TWAIN Data Source Manager and TWAIN drivers. Best practices cover a few areas: \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af0\afs22 \ltrch\fcs0 \f37\fs22\insrsid6441407 \hich\af37\dbch\af0\loch\f37 -\tab}}\pard \ltrpar \s199\ql \fi-360\li720\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\ls12\adjustright\rin0\lin720\itap0\pararsid6555766 {\rtlch\fcs1 \af0 \ltrch\fcs0 \f31506\insrsid6441407 Funnel all commands through a single thread \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af0\afs22 \ltrch\fcs0 \f37\fs22\insrsid6441407 \hich\af37\dbch\af0\loch\f37 -\tab}Automatically collect the condition code when TWRC.Failure is detected \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af0\afs22 \ltrch\fcs0 \f37\fs22\insrsid6441407 \hich\af37\dbch\af0\loch\f37 -\tab}Automatically resynchronize the TWAIN state if a sequence error is detected \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af0\afs22 \ltrch\fcs0 \f37\fs22\insrsid8668465 \hich\af37\dbch\af0\loch\f37 -\tab}}{\rtlch\fcs1 \af0 \ltrch\fcs0 \f31506\insrsid8668465 Access}{\rtlch\fcs1 \af0 \ltrch\fcs0 \f31506\insrsid6441407 the data through CSV strings \par }\pard \ltrpar\s199\ql \li360\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin360\itap0 {\rtlch\fcs1 \af0 \ltrch\fcs0 \f31506\insrsid6441407 \par Both files expose their functionality through the TWAIN class in the TWAINWorkingGroup namespace. \par \par \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 \f31506\insrsid6441407 \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\outlinelevel1\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 \b\f31506\ul\insrsid6441407 {\*\bkmkstart _Toc87248717}A TWAIN C# Diagnostic Application {\*\bkmkend _Toc87248717} \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af0 \ltrch\fcs0 \f31506\insrsid6441407 \par }\pard \ltrpar\s199\ql \li360\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin360\itap0 {\rtlch\fcs1 \af0 \ltrch\fcs0 \f31506\insrsid6441407 The code is not intended as seed code for applications. It is a comprehens ive frontend to the TWAIN API. It allows the selection of any combination of TWAIN triplets, including ones that are illegal or are out of sequence with the current TWAIN state. It is best compared to the TWACKER application, which has long been the mai n way to exercise TWAIN drivers on Microsoft Windows systems. \par \par Data is presented and consumed in the form of CSV strings. Familiarity with the various TWAIN structures is essential, since these strings do not include self-referential metadata, aside from t he content described by the TWAIN Specification. As mentioned above, }{\rtlch\fcs1 \af0 \ltrch\fcs0 \insrsid6441407 it helps to have access to a copy of TWAINH.CS handy when looking at the CSV data.}{\rtlch\fcs1 \af0 \ltrch\fcs0 \f31506\insrsid6441407 \par \par The application tries to reduce mouse clicks for some common operations. For instance, upon successfu l completion of the DG_CONTROL / DAT_PARENT / MSG_OPENDSM operation, the dropdown values are set to DG_CONTROL / DAT_IDENTITY / MSG_GETFIRST, to enumerate the first TWAIN driver in the list of drivers. After a few uses it\rquote ll be apparent when the application is trying to help. \par \par A @-command system has been added. It doesn\rquote t do much at the moment, but it could be expanded to allow for more complex behavior. For instance, some kind of scripting system that would allow the diagnostic tool to help with automat ed tests. It becomes available after opening a DSM. Type @help in the text box and press the Send button to get the list of supported commands. \par \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0\pararsid8668465 {\rtlch\fcs1 \af0 \ltrch\fcs0 \f31506\insrsid6441407 \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 \f31506\insrsid6441407 \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\outlinelevel1\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 \b\f31506\ul\insrsid6441407 {\*\bkmkstart _Toc87248718}A TWAIN C# Sample Application {\*\bkmkend _Toc87248718} \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af0 \ltrch\fcs0 \f31506\insrsid6441407 \par }\pard \ltrpar\s199\ql \li360\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin360\itap0 {\rtlch\fcs1 \af0 \ltrch\fcs0 \f31506\insrsid6441407 The code is intended as seed code for applications, and demonstrates the easiest way to access the full range of functionality present in TWAIN. \par \par For TWAIN drivers that support DG_CONTROL / DAT_USERINTERFACE / MSG_ENABLEDSUIONLY and DG_CONTROL / DAT_CUSTOMDSDATA / MSG_*, the application supports a \'93snapshot\'94 system. This allows a user to configure a TWAIN driver and save its setting under a descriptive name that can be used to restore those settings prior to scanning. \par \par For drivers that don\rquote t support these operations the application defaults to the older }{\rtlch\fcs1 \af0 \ltrch\fcs0 \insrsid6441407 DG_CONTROL / DAT_USERINTERFACE / MSG_ENABLEDS system, with TW_USERINTERFACE.ShowUI set to TRUE. \par \par }\pard \ltrpar\s199\ql \li360\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin360\itap0\pararsid8668465 {\rtlch\fcs1 \af0 \ltrch\fcs0 \insrsid6441407 An application writer also has the option to programmatically negotiate capabilities. The sample app doesn\rquote t show this path, but it\rquote s relatively easy to add for a small number of configurable items.}{\rtlch\fcs1 \af0 \ltrch\fcs0 \f31506\insrsid6441407\charrsid8668465 \par }\pard \ltrpar\s199\ql \li360\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin360\itap0 {\rtlch\fcs1 \af0 \ltrch\fcs0 \insrsid6441407 \par \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 \insrsid6441407 \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\outlinelevel1\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 \b\ul\insrsid6441407 {\*\bkmkstart _Toc87248719}A TWAIN C# Self Certification Application {\*\bkmkend _Toc87248719} \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af0 \ltrch\fcs0 \insrsid6441407 \par }\pard \ltrpar\s199\ql \li360\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin360\itap0 {\rtlch\fcs1 \af0 \ltrch\fcs0 \insrsid6441407 This application serves three purposes. I t shows a reasonably good way of interfacing with TWAIN from C#. It allows a user to interact directly with a TWAIN driver (with the aid of scripts). And it offers a way to certify that a TWAIN driver is compliant with the specification. \par \par Note that the correct binary must be run to interface with 32-bit or 64-bit drivers. This code has been tested on Windows, Linux, and Mac (the last two using Mono 4.8 or later). \par \par The tool has help built into it. It also comes with a large collection of scripts. If you use the \lquote runv\rquote command with the script, you\rquote ll get some insight into what arguments are needed for the \lquote dsmentry\rquote command. \par \par It should be a good tool for developers, allowing them to explore the kind of commands they\rquote ll need to issue from other languages, like C++. \par \par }\pard \ltrpar\s199\ql \li360\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin360\itap0\pararsid8668465 {\rtlch\fcs1 \af0 \ltrch\fcs0 \insrsid6441407 If developing with the tool, it\rquote ll use the data folder located with the binary. The release version normally defaults to the \'93TWAIN Self Certification/data\'94 folder on the desktop.}{\rtlch\fcs1 \af0 \ltrch\fcs0 \insrsid6441407\charrsid8668465 \par }\pard\plain \ltrpar\s189\ql \li0\ri0\keepn\pagebb\widctlpar\brdrt\brdrs\brdrw30\brsp120 \wrapdefault\nooverflow\faroman\outlinelevel0\rin0\lin0\itap0 \rtlch\fcs1 \ab\af1\afs24\alang1025 \ltrch\fcs0 \b\f1\fs24\cf9\lang1024\langfe1024\cgrid\noproof\langnp1033\langfenp1033 {\rtlch\fcs1 \af1\afs36 \ltrch\fcs0 \f31506\fs36\noproof0\insrsid6441407 {\*\bkmkstart _Toc87248720}Release Notes{\*\bkmkend _Toc87248720} \par }\pard\plain \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 \rtlch\fcs1 \af37\afs22\alang1025 \ltrch\fcs0 \f37\fs22\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 {\rtlch\fcs1 \af37 \ltrch\fcs0 \i\cf6\insrsid6441407 \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\outlinelevel1\adjustright\rin0\lin0\itap0\pararsid8668465 {\rtlch\fcs1 \af37 \ltrch\fcs0 \b\ul\insrsid8668465 {\*\bkmkstart _Toc87248721}V2.5.0.0 (}{\rtlch\fcs1 \af37 \ltrch\fcs0 \b\ul\insrsid472724 08}{\rtlch\fcs1 \af37 \ltrch\fcs0 \b\ul\insrsid8668465 -Nov-2021)}{\rtlch\fcs1 \af37 \ltrch\fcs0 \insrsid8668465 {\*\bkmkend _Toc87248721} \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0\pararsid8668465 {\rtlch\fcs1 \af37 \ltrch\fcs0 \insrsid8668465 New Features: \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22\insrsid8668465 \hich\af37\dbch\af0\loch\f37 -\tab}}\pard \ltrpar \s199\ql \fi-360\li720\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\ls12\adjustright\rin0\lin720\itap0\pararsid6555766 {\rtlch\fcs1 \af37 \ltrch\fcs0 \insrsid8668465 Updated to version 2.5 of the TWAIN Specification \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22\insrsid472724 \hich\af37\dbch\af0\loch\f37 -\tab}}{\rtlch\fcs1 \af37 \ltrch\fcs0 \insrsid472724 Certification tests for barcode, image address, patch code, printer}{ \rtlch\fcs1 \af37 \ltrch\fcs0 \insrsid8668465 \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22\insrsid472724 \hich\af37\dbch\af0\loch\f37 -\tab}}{\rtlch\fcs1 \af37 \ltrch\fcs0 \insrsid472724 Obsolete toolkit code removed \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0\pararsid8668465 {\rtlch\fcs1 \af37 \ltrch\fcs0 \insrsid8668465 Bug Fixes: \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22\insrsid8668465 \hich\af37\dbch\af0\loch\f37 -\tab}}\pard \ltrpar \s199\ql \fi-360\li720\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\ls12\adjustright\rin0\lin720\itap0\pararsid6555766 {\rtlch\fcs1 \af37 \ltrch\fcs0 \insrsid8668465 (none) \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0\pararsid8668465 {\rtlch\fcs1 \af37 \ltrch\fcs0 \insrsid8668465 Known Issues: \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22\insrsid8668465 \hich\af37\dbch\af0\loch\f37 -\tab}}\pard \ltrpar \s199\ql \fi-360\li720\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\ls12\adjustright\rin0\lin720\itap0\pararsid6555766 {\rtlch\fcs1 \af37 \ltrch\fcs0 \insrsid8668465 (none) \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0\pararsid8668465 {\rtlch\fcs1 \af37 \ltrch\fcs0 \insrsid8668465 Wish List: \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22\insrsid472724 \hich\af37\dbch\af0\loch\f37 -\tab}}\pard \ltrpar \s199\ql \fi-360\li720\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\ls12\adjustright\rin0\lin720\itap0\pararsid6555766 {\rtlch\fcs1 \af37 \ltrch\fcs0 \insrsid472724 Switch}{\rtlch\fcs1 \af37 \ltrch\fcs0 \insrsid8668465 to something other than WinForms \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\outlinelevel1\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 \b\ul\insrsid8668465 \par }{\rtlch\fcs1 \af37 \ltrch\fcs0 \b\ul\insrsid6441407 {\*\bkmkstart _Toc87248722}V2.4.11.0 (08-Jul-2020)}{\rtlch\fcs1 \af37 \ltrch\fcs0 \insrsid6441407 {\*\bkmkend _Toc87248722} \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 \insrsid6441407 New Features: \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22\insrsid6441407 \hich\af37\dbch\af0\loch\f37 -\tab}}\pard \ltrpar \s199\ql \fi-360\li720\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\ls12\adjustright\rin0\lin720\itap0\pararsid6555766 {\rtlch\fcs1 \af37 \ltrch\fcs0 \insrsid6441407 (none) \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 \insrsid6441407 Bug Fixes: \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22\insrsid6441407 \hich\af37\dbch\af0\loch\f37 -\tab}}\pard \ltrpar \s199\ql \fi-360\li720\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\ls12\adjustright\rin0\lin720\itap0\pararsid6555766 {\rtlch\fcs1 \af37 \ltrch\fcs0 \insrsid6441407 Added deprecated }{\rtlch\fcs1 \af37 \ltrch\fcs0 \insrsid472724 capabilities}{ \rtlch\fcs1 \af37 \ltrch\fcs0 \insrsid6441407 to LookupTable.tc \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22\insrsid6441407 \hich\af37\dbch\af0\loch\f37 -\tab}Fixed cert to skip deprecated }{\rtlch\fcs1 \af37 \ltrch\fcs0 \insrsid472724 capabilities}{\rtlch\fcs1 \af37 \ltrch\fcs0 \insrsid6441407 \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22\insrsid6441407 \hich\af37\dbch\af0\loch\f37 -\tab}Fixed to better handle when a driver isn\rquote t successfully opened (skip the tests) \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 \insrsid6441407 Known Issues: \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22\insrsid6441407 \hich\af37\dbch\af0\loch\f37 -\tab}}\pard \ltrpar \s199\ql \fi-360\li720\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\ls12\adjustright\rin0\lin720\itap0\pararsid6555766 {\rtlch\fcs1 \af37 \ltrch\fcs0 \insrsid6441407 (none) \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 \insrsid6441407 Wish List: \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22\insrsid6441407 \hich\af37\dbch\af0\loch\f37 -\tab}}\pard \ltrpar \s199\ql \fi-360\li720\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\ls12\adjustright\rin0\lin720\itap0\pararsid6555766 {\rtlch\fcs1 \af37 \ltrch\fcs0 \insrsid6441407 Want to switch to something other than WinForms, especially for macOS \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22\insrsid6441407 \hich\af37\dbch\af0\loch\f37 -\tab}Need to add some more certification tests, especially for things like printer, barcode, patch \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 \i\cf6\insrsid6441407 \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\outlinelevel1\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 \b\ul\insrsid6441407 {\*\bkmkstart _Toc87248723}V2.4.10.0 (06-Jun-2020)}{\rtlch\fcs1 \af37 \ltrch\fcs0 \insrsid6441407 {\*\bkmkend _Toc87248723} \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 \insrsid6441407 New Features: \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22\insrsid6441407 \hich\af37\dbch\af0\loch\f37 -\tab}}\pard \ltrpar \s199\ql \fi-360\li720\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\ls12\adjustright\rin0\lin720\itap0\pararsid6555766 {\rtlch\fcs1 \af37 \ltrch\fcs0 \insrsid6441407 (none) \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 \insrsid6441407 Bug Fixes: \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22\insrsid6441407 \hich\af37\dbch\af0\loch\f37 -\tab}}\pard \ltrpar \s199\ql \fi-360\li720\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\ls12\adjustright\rin0\lin720\itap0\pararsid6555766 {\rtlch\fcs1 \af37 \ltrch\fcs0 \insrsid6441407 Fixed twaincert.exe to run from the releases folder without thinking it\rquote s a development path, so it correctly creates the \lquote data\rquote folder in the \lquote TWAIN Self Certification\rquote folder on the desktop. \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 \insrsid6441407 Known Issues: \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22\insrsid6441407 \hich\af37\dbch\af0\loch\f37 -\tab}}\pard \ltrpar \s199\ql \fi-360\li720\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\ls12\adjustright\rin0\lin720\itap0\pararsid6555766 {\rtlch\fcs1 \af37 \ltrch\fcs0 \insrsid6441407 (none) \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 \insrsid6441407 Wish List: \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22\insrsid6441407 \hich\af37\dbch\af0\loch\f37 -\tab}}\pard \ltrpar \s199\ql \fi-360\li720\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\ls12\adjustright\rin0\lin720\itap0\pararsid6555766 {\rtlch\fcs1 \af37 \ltrch\fcs0 \insrsid6441407 Want to switch to something other than WinForms, especially for macOS \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22\insrsid6441407 \hich\af37\dbch\af0\loch\f37 -\tab}Need to add some more certification tests, especially for things like printer, barcode, patch \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 \i\cf6\insrsid6441407 \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\outlinelevel1\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 \b\ul\insrsid6441407 {\*\bkmkstart _Toc87248724}V2.4.9.0 (30-Apr-2020)}{\rtlch\fcs1 \af37 \ltrch\fcs0 \insrsid6441407 {\*\bkmkend _Toc87248724} \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 \insrsid6441407 New Features: \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22\insrsid6441407 \hich\af37\dbch\af0\loch\f37 -\tab}}\pard \ltrpar \s199\ql \fi-360\li720\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\ls12\adjustright\rin0\lin720\itap0\pararsid6555766 {\rtlch\fcs1 \af37 \ltrch\fcs0 \insrsid6441407 (none) \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 \insrsid6441407 Bug Fixes: \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22\insrsid6441407 \hich\af37\dbch\af0\loch\f37 -\tab}}\pard \ltrpar \s199\ql \fi-360\li720\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\ls12\adjustright\rin0\lin720\itap0\pararsid6555766 {\rtlch\fcs1 \af37 \ltrch\fcs0 \insrsid6441407 The MSG_SET certification test was using the MSG_GET container, when the 2.4 spec states that it should only use TW_ONEVALUE or TW_ARRAY (the others being for MSG_SETCONTAINER), so that\rquote s fixed now \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22\insrsid6441407 \hich\af37\dbch\af0\loch\f37 -\tab}Fixed TWBP_* values to not return symbolic names, the support for symbolic names with TW_RANGE gets too weird too fast, staying with numbers offers fewer problems \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 \insrsid6441407 Known Issues: \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22\insrsid6441407 \hich\af37\dbch\af0\loch\f37 -\tab}}\pard \ltrpar \s199\ql \fi-360\li720\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\ls12\adjustright\rin0\lin720\itap0\pararsid6555766 {\rtlch\fcs1 \af37 \ltrch\fcs0 \insrsid6441407 (none) \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 \insrsid6441407 Wish List: \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22\insrsid6441407 \hich\af37\dbch\af0\loch\f37 -\tab}}\pard \ltrpar \s199\ql \fi-360\li720\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\ls12\adjustright\rin0\lin720\itap0\pararsid6555766 {\rtlch\fcs1 \af37 \ltrch\fcs0 \insrsid6441407 Want to switch to something other than WinForms, especially for macOS \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22\insrsid6441407 \hich\af37\dbch\af0\loch\f37 -\tab}Need to add some more certification tests, especially for things like printer, barcode, patch \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 \i\cf6\insrsid6441407 \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\outlinelevel1\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 \b\ul\insrsid6441407 {\*\bkmkstart _Toc87248725}V2.4.8.0 (30-Mar-2020)}{\rtlch\fcs1 \af37 \ltrch\fcs0 \insrsid6441407 {\*\bkmkend _Toc87248725} \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 \insrsid6441407 New Features: \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22\insrsid6441407 \hich\af37\dbch\af0\loch\f37 -\tab}}\pard \ltrpar \s199\ql \fi-360\li720\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\ls12\adjustright\rin0\lin720\itap0\pararsid6555766 {\rtlch\fcs1 \af37 \ltrch\fcs0 \insrsid6441407 Switched almost all of the csv functions to static \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22\insrsid6441407 \hich\af37\dbch\af0\loch\f37 -\tab}(yah, skipped 2.4.7, kinda) \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 \insrsid6441407 Bug Fixes: \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22\insrsid6441407 \hich\af37\dbch\af0\loch\f37 -\tab}}\pard \ltrpar \s199\ql \fi-360\li720\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\ls12\adjustright\rin0\lin720\itap0\pararsid6555766 {\rtlch\fcs1 \af37 \ltrch\fcs0 \insrsid6441407 (none) \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 \insrsid6441407 Known Issues: \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22\insrsid6441407 \hich\af37\dbch\af0\loch\f37 -\tab}}\pard \ltrpar \s199\ql \fi-360\li720\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\ls12\adjustright\rin0\lin720\itap0\pararsid6555766 {\rtlch\fcs1 \af37 \ltrch\fcs0 \insrsid6441407 (none) \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 \insrsid6441407 Wish List: \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22\insrsid6441407 \hich\af37\dbch\af0\loch\f37 -\tab}}\pard \ltrpar \s199\ql \fi-360\li720\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\ls12\adjustright\rin0\lin720\itap0\pararsid6555766 {\rtlch\fcs1 \af37 \ltrch\fcs0 \insrsid6441407 Want to switch to something other than WinForms, especially for macOS \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22\insrsid6441407 \hich\af37\dbch\af0\loch\f37 -\tab}Need to add some more certification tests, especially for things like printer, barcode, patch \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 \i\cf6\insrsid6441407 \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\outlinelevel1\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 \b\ul\insrsid6441407 {\*\bkmkstart _Toc87248726}V2.4.6.0 (26-Mar-2020)}{\rtlch\fcs1 \af37 \ltrch\fcs0 \insrsid6441407 {\*\bkmkend _Toc87248726} \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 \insrsid6441407 New Features: \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22\insrsid6441407 \hich\af37\dbch\af0\loch\f37 -\tab}}\pard \ltrpar \s199\ql \fi-360\li720\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\ls12\adjustright\rin0\lin720\itap0\pararsid6555766 {\rtlch\fcs1 \af37 \ltrch\fcs0 \insrsid6441407 (none) \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 \insrsid6441407 Bug Fixes: \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22\insrsid6441407 \hich\af37\dbch\af0\loch\f37 -\tab}}\pard \ltrpar \s199\ql \fi-360\li720\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\ls12\adjustright\rin0\lin720\itap0\pararsid6555766 {\rtlch\fcs1 \af37 \ltrch\fcs0 \insrsid6441407 MSG_XFERREADY wasn\rquote t being handled properly if ShowUI was TRUE \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 \insrsid6441407 Known Issues: \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22\insrsid6441407 \hich\af37\dbch\af0\loch\f37 -\tab}}\pard \ltrpar \s199\ql \fi-360\li720\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\ls12\adjustright\rin0\lin720\itap0\pararsid6555766 {\rtlch\fcs1 \af37 \ltrch\fcs0 \insrsid6441407 (none) \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 \insrsid6441407 Wish List: \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22\insrsid6441407 \hich\af37\dbch\af0\loch\f37 -\tab}}\pard \ltrpar \s199\ql \fi-360\li720\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\ls12\adjustright\rin0\lin720\itap0\pararsid6555766 {\rtlch\fcs1 \af37 \ltrch\fcs0 \insrsid6441407 Want to switch to something other than WinForms, especially for macOS \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22\insrsid6441407 \hich\af37\dbch\af0\loch\f37 -\tab}Need to add some more certification tests, especially for things like printer, barcode, patch \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 \insrsid6441407 \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\outlinelevel1\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 \b\ul\insrsid6441407 {\*\bkmkstart _Toc87248727}V2.4.5.0 (24-Mar-2020)}{\rtlch\fcs1 \af37 \ltrch\fcs0 \insrsid6441407 {\*\bkmkend _Toc87248727} \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 \insrsid6441407 New Features: \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22\insrsid6441407 \hich\af37\dbch\af0\loch\f37 -\tab}}\pard \ltrpar \s199\ql \fi-360\li720\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\ls12\adjustright\rin0\lin720\itap0\pararsid6555766 {\rtlch\fcs1 \af37 \ltrch\fcs0 \insrsid6441407 (none) \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 \insrsid6441407 Bug Fixes: \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22\insrsid6441407 \hich\af37\dbch\af0\loch\f37 -\tab}}\pard \ltrpar \s199\ql \fi-360\li720\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\ls12\adjustright\rin0\lin720\itap0\pararsid6555766 {\rtlch\fcs1 \af37 \ltrch\fcs0 \insrsid6441407 Stupid data folder wasn\rquote t being properly created (grrr) \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 \insrsid6441407 Known Issues: \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22\insrsid6441407 \hich\af37\dbch\af0\loch\f37 -\tab}}\pard \ltrpar \s199\ql \fi-360\li720\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\ls12\adjustright\rin0\lin720\itap0\pararsid6555766 {\rtlch\fcs1 \af37 \ltrch\fcs0 \insrsid6441407 (none) \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 \insrsid6441407 Wish List: \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22\insrsid6441407 \hich\af37\dbch\af0\loch\f37 -\tab}}\pard \ltrpar \s199\ql \fi-360\li720\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\ls12\adjustright\rin0\lin720\itap0\pararsid6555766 {\rtlch\fcs1 \af37 \ltrch\fcs0 \insrsid6441407 Want to switch to something other than WinForms, especially for macOS \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22\insrsid6441407 \hich\af37\dbch\af0\loch\f37 -\tab}Need to add some more certification tests, especially for things like printer, barcode, patch \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 \i\cf6\insrsid6441407 \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\outlinelevel1\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 \b\ul\insrsid6441407 {\*\bkmkstart _Toc87248728}V2.4.4.0 (24-Mar-2020)}{\rtlch\fcs1 \af37 \ltrch\fcs0 \insrsid6441407 {\*\bkmkend _Toc87248728} \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 \insrsid6441407 New Features: \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22\insrsid6441407 \hich\af37\dbch\af0\loch\f37 -\tab}}\pard \ltrpar \s199\ql \fi-360\li720\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\ls12\adjustright\rin0\lin720\itap0\pararsid6555766 {\rtlch\fcs1 \af37 \ltrch\fcs0 \insrsid6441407 Fixed issues related to TWAIN Direct support, and added it to certification \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22\insrsid6441407 \hich\af37\dbch\af0\loch\f37 -\tab}Added makerelease.bat file \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 \insrsid6441407 Bug Fixes: \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22\insrsid6441407 \hich\af37\dbch\af0\loch\f37 -\tab}}\pard \ltrpar \s199\ql \fi-360\li720\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\ls12\adjustright\rin0\lin720\itap0\pararsid6555766 {\rtlch\fcs1 \af37 \ltrch\fcs0 \insrsid6441407 (none) \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 \insrsid6441407 Known Issues: \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22\insrsid6441407 \hich\af37\dbch\af0\loch\f37 -\tab}}\pard \ltrpar \s199\ql \fi-360\li720\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\ls12\adjustright\rin0\lin720\itap0\pararsid6555766 {\rtlch\fcs1 \af37 \ltrch\fcs0 \insrsid6441407 (none) \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 \insrsid6441407 Wish List: \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22\insrsid6441407 \hich\af37\dbch\af0\loch\f37 -\tab}}\pard \ltrpar \s199\ql \fi-360\li720\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\ls12\adjustright\rin0\lin720\itap0\pararsid6555766 {\rtlch\fcs1 \af37 \ltrch\fcs0 \insrsid6441407 Want to switch to something other than WinForms, especially for macOS \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22\insrsid6441407 \hich\af37\dbch\af0\loch\f37 -\tab}Need to add some more certification tests, especially for things like printer, barcode, patch \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 \i\cf6\insrsid6441407 \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\outlinelevel1\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 \b\ul\insrsid6441407 {\*\bkmkstart _Toc87248729}V2.4.3.0 (20-Mar-2020)}{\rtlch\fcs1 \af37 \ltrch\fcs0 \insrsid6441407 {\*\bkmkend _Toc87248729} \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 \insrsid6441407 New Features: \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22\insrsid6441407 \hich\af37\dbch\af0\loch\f37 -\tab}}\pard \ltrpar \s199\ql \fi-360\li720\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\ls12\adjustright\rin0\lin720\itap0\pararsid6555766 {\rtlch\fcs1 \af37 \ltrch\fcs0 \insrsid6441407 Switched twaincsscan and twaincstst to directly access TWAIN.CS \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22\insrsid6441407 \hich\af37\dbch\af0\loch\f37 -\tab}The toolkit is officially deprecated now, don\rquote t use it \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 \insrsid6441407 Bug Fixes: \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22\insrsid6441407 \hich\af37\dbch\af0\loch\f37 -\tab}}\pard \ltrpar \s199\ql \fi-360\li720\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\ls12\adjustright\rin0\lin720\itap0\pararsid6555766 {\rtlch\fcs1 \af37 \ltrch\fcs0 \insrsid6441407 Fixed an issue where xferready during enableds could be missed \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 \insrsid6441407 Known Issues: \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22\insrsid6441407 \hich\af37\dbch\af0\loch\f37 -\tab}}\pard \ltrpar \s199\ql \fi-360\li720\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\ls12\adjustright\rin0\lin720\itap0\pararsid6555766 {\rtlch\fcs1 \af37 \ltrch\fcs0 \insrsid6441407 (none) \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 \insrsid6441407 Wish List: \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22\insrsid6441407 \hich\af37\dbch\af0\loch\f37 -\tab}}\pard \ltrpar \s199\ql \fi-360\li720\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\ls12\adjustright\rin0\lin720\itap0\pararsid6555766 {\rtlch\fcs1 \af37 \ltrch\fcs0 \insrsid6441407 Want to switch to something other than WinForms, especially for macOS \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22\insrsid6441407 \hich\af37\dbch\af0\loch\f37 -\tab}Need to add some more certification tests, especially for things like printer, barcode, patch \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 \i\cf6\insrsid6441407 \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\outlinelevel1\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 \b\ul\insrsid6441407 {\*\bkmkstart _Toc87248730}V2.4.2.0 (13-Mar-2020)}{\rtlch\fcs1 \af37 \ltrch\fcs0 \insrsid6441407 {\*\bkmkend _Toc87248730} \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 \insrsid6441407 New Features: \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22\insrsid6441407 \hich\af37\dbch\af0\loch\f37 -\tab}}\pard \ltrpar \s199\ql \fi-360\li720\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\ls12\adjustright\rin0\lin720\itap0\pararsid6555766 {\rtlch\fcs1 \af37 \ltrch\fcs0 \insrsid6441407 Massive update to TWAIN.CS \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22\insrsid6441407 \hich\af37\dbch\af0\loch\f37 -\tab}twaincscert is pretty much done \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 \insrsid6441407 Bug Fixes: \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22\insrsid6441407 \hich\af37\dbch\af0\loch\f37 -\tab}}\pard \ltrpar \s199\ql \fi-360\li720\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\ls12\adjustright\rin0\lin720\itap0\pararsid6555766 {\rtlch\fcs1 \af37 \ltrch\fcs0 \insrsid6441407 Too many to count, twaincscert helped scrub the code \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 \insrsid6441407 Known Issues: \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22\insrsid6441407 \hich\af37\dbch\af0\loch\f37 -\tab}}\pard \ltrpar \s199\ql \fi-360\li720\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\ls12\adjustright\rin0\lin720\itap0\pararsid6555766 {\rtlch\fcs1 \af37 \ltrch\fcs0 \insrsid6441407 (none) \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 \insrsid6441407 Wish List: \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22\insrsid6441407 \hich\af37\dbch\af0\loch\f37 -\tab}}\pard \ltrpar \s199\ql \fi-360\li720\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\ls12\adjustright\rin0\lin720\itap0\pararsid6555766 {\rtlch\fcs1 \af37 \ltrch\fcs0 \insrsid6441407 Want to switch to something other than WinForms, especially for macOS \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22\insrsid6441407 \hich\af37\dbch\af0\loch\f37 -\tab}Need to add some more certification tests, especially for things like printer, barcode, patch \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 \i\cf6\insrsid6441407 \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\outlinelevel1\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 \b\ul\insrsid6441407 {\*\bkmkstart _Toc87248731}V2.4.1.0 (30-Jan-2020)}{\rtlch\fcs1 \af37 \ltrch\fcs0 \insrsid6441407 {\*\bkmkend _Toc87248731} \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 \insrsid6441407 New Features: \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22\insrsid6441407 \hich\af37\dbch\af0\loch\f37 -\tab}}\pard \ltrpar \s199\ql \fi-360\li720\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\ls12\adjustright\rin0\lin720\itap0\pararsid6555766 {\rtlch\fcs1 \af37 \ltrch\fcs0 \insrsid6441407 Added twaincscert project (it\rquote s not done yet, but it is useable) \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22\insrsid6441407 \hich\af37\dbch\af0\loch\f37 -\tab}Fixed reflection to allow use of capability enumerations in the CSV (ex: TWPT_RGB) \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22\insrsid6441407 \hich\af37\dbch\af0\loch\f37 -\tab}Expanded ability to use TWAIN.CS without the toolkit (needed for cert) \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 \insrsid6441407 Bug Fixes: \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22\insrsid6441407 \hich\af37\dbch\af0\loch\f37 -\tab}}\pard \ltrpar \s199\ql \fi-360\li720\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\ls12\adjustright\rin0\lin720\itap0\pararsid6555766 {\rtlch\fcs1 \af37 \ltrch\fcs0 \insrsid6441407 (none) \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 \insrsid6441407 Known Issues: \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22\insrsid6441407 \hich\af37\dbch\af0\loch\f37 -\tab}}\pard \ltrpar \s199\ql \fi-360\li720\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\ls12\adjustright\rin0\lin720\itap0\pararsid6555766 {\rtlch\fcs1 \af37 \ltrch\fcs0 \insrsid6441407 Runs rather slowly on Mac OS X \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22\insrsid6441407 \hich\af37\dbch\af0\loch\f37 -\tab}Setup Dialog sometimes freaks out on Mac OS X (appears to be a WinForms bug) \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 \insrsid6441407 Wish List: \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22\insrsid6441407 \hich\af37\dbch\af0\loch\f37 -\tab}}\pard \ltrpar \s199\ql \fi-360\li720\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\ls12\adjustright\rin0\lin720\itap0\pararsid6555766 {\rtlch\fcs1 \af37 \ltrch\fcs0 \insrsid6441407 64-bit Mono support on Mac OS X (should just work, but needs building / testing) \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22\insrsid6441407 \hich\af37\dbch\af0\loch\f37 -\tab}Want to switch to Xamarin \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 \i\cf6\insrsid6441407 \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\outlinelevel1\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 \b\ul\insrsid6441407 {\*\bkmkstart _Toc87248732}V2.4.0.3 (13-Mar-2019)}{\rtlch\fcs1 \af37 \ltrch\fcs0 \insrsid6441407 {\*\bkmkend _Toc87248732} \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 \insrsid6441407 New Features: \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22\insrsid6441407 \hich\af37\dbch\af0\loch\f37 -\tab}}\pard \ltrpar \s199\ql \fi-360\li720\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\ls12\adjustright\rin0\lin720\itap0\pararsid6555766 {\rtlch\fcs1 \af37 \ltrch\fcs0 \insrsid6441407 (none) \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 \insrsid6441407 Bug Fixes: \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22\insrsid6441407 \hich\af37\dbch\af0\loch\f37 -\tab}}\pard \ltrpar \s199\ql \fi-360\li720\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\ls12\adjustright\rin0\lin720\itap0\pararsid6555766 {\rtlch\fcs1 \af37 \ltrch\fcs0 \insrsid6441407 Fixed an encoding problem, TWAIN on Windows requires strings in the encoding specified by the driver (either through it\rquote s TW_IDENTITY.Version.Language or the last successful set of CAP_LANGUAGE). Until this fix TWAIN CS was sending strings as UTF-8. Note that on Linux and macOS UTF-8 is the encoding, that hasn\rquote t changed. \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 \insrsid6441407 Known Issues: \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22\insrsid6441407 \hich\af37\dbch\af0\loch\f37 -\tab}}\pard \ltrpar \s199\ql \fi-360\li720\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\ls12\adjustright\rin0\lin720\itap0\pararsid6555766 {\rtlch\fcs1 \af37 \ltrch\fcs0 \insrsid6441407 Runs rather slowly on Mac OS X \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22\insrsid6441407 \hich\af37\dbch\af0\loch\f37 -\tab}Setup Dialog sometimes freaks out on Mac OS X (appears to be a WinForms bug) \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 \insrsid6441407 Wish List: \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22\insrsid6441407 \hich\af37\dbch\af0\loch\f37 -\tab}}\pard \ltrpar \s199\ql \fi-360\li720\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\ls12\adjustright\rin0\lin720\itap0\pararsid6555766 {\rtlch\fcs1 \af37 \ltrch\fcs0 \insrsid6441407 64-bit Mono support on Mac OS X (should just work, but needs building / testing) \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22\insrsid6441407 \hich\af37\dbch\af0\loch\f37 -\tab}Want to switch to Xamarin \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 \insrsid6441407 \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\outlinelevel1\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 \b\ul\insrsid6441407 {\*\bkmkstart _Toc87248733}V2.4.0.2 (25-Jan-2019)}{\rtlch\fcs1 \af37 \ltrch\fcs0 \insrsid6441407 {\*\bkmkend _Toc87248733} \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 \insrsid6441407 New Features: \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22\insrsid6441407 \hich\af37\dbch\af0\loch\f37 -\tab}}\pard \ltrpar \s199\ql \fi-360\li720\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\ls12\adjustright\rin0\lin720\itap0\pararsid6555766 {\rtlch\fcs1 \af37 \ltrch\fcs0 \insrsid6441407 In sync with TWAIN Direct \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22\insrsid6441407 \hich\af37\dbch\af0\loch\f37 -\tab}Updated to VS2017 \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 \insrsid6441407 Bug Fixes: \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22\insrsid6441407 \hich\af37\dbch\af0\loch\f37 -\tab}}\pard \ltrpar \s199\ql \fi-360\li720\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\ls12\adjustright\rin0\lin720\itap0\pararsid6555766 {\rtlch\fcs1 \af37 \ltrch\fcs0 \insrsid6441407 Fixed problem with FIX32 in TW_RANGE \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22\insrsid6441407 \hich\af37\dbch\af0\loch\f37 -\tab}Fixed problems with SendDat for custom DAT support \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 \insrsid6441407 Known Issues: \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22\insrsid6441407 \hich\af37\dbch\af0\loch\f37 -\tab}}\pard \ltrpar \s199\ql \fi-360\li720\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\ls12\adjustright\rin0\lin720\itap0\pararsid6555766 {\rtlch\fcs1 \af37 \ltrch\fcs0 \insrsid6441407 Runs rather slowly on Mac OS X \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22\insrsid6441407 \hich\af37\dbch\af0\loch\f37 -\tab}Setup Dialog sometimes freaks out on Mac OS X (appears to be a WinForms bug) \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 \insrsid6441407 Wish List: \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22\insrsid6441407 \hich\af37\dbch\af0\loch\f37 -\tab}}\pard \ltrpar \s199\ql \fi-360\li720\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\ls12\adjustright\rin0\lin720\itap0\pararsid6555766 {\rtlch\fcs1 \af37 \ltrch\fcs0 \insrsid6441407 64-bit Mono support on Mac OS X (should just work, but needs building / testing) \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22\insrsid6441407 \hich\af37\dbch\af0\loch\f37 -\tab}Want to switch to Xamarin \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 \i\cf6\insrsid6441407 \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\outlinelevel1\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 \b\ul\insrsid6441407 {\*\bkmkstart _Toc87248734}V2.4.0.1 (19-Apr-2018)}{\rtlch\fcs1 \af37 \ltrch\fcs0 \insrsid6441407 {\*\bkmkend _Toc87248734} \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 \insrsid6441407 New Features: \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22\insrsid6441407 \hich\af37\dbch\af0\loch\f37 -\tab}}\pard \ltrpar \s199\ql \fi-360\li720\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\ls12\adjustright\rin0\lin720\itap0\pararsid6555766 {\rtlch\fcs1 \af37 \ltrch\fcs0 \insrsid6441407 In sync with TWAIN Direct \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 \insrsid6441407 Bug Fixes: \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22\insrsid6441407 \hich\af37\dbch\af0\loch\f37 -\tab}}\pard \ltrpar \s199\ql \fi-360\li720\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\ls12\adjustright\rin0\lin720\itap0\pararsid6555766 {\rtlch\fcs1 \af37 \ltrch\fcs0 \insrsid6441407 Code analysis with VS2015, fixed up everything, supressed some stuff \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22\insrsid6441407 \hich\af37\dbch\af0\loch\f37 -\tab}Finally got the Linux 64-bit thing right (lots of edge cases) \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 \insrsid6441407 Known Issues: \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22\insrsid6441407 \hich\af37\dbch\af0\loch\f37 -\tab}}\pard \ltrpar \s199\ql \fi-360\li720\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\ls12\adjustright\rin0\lin720\itap0\pararsid6555766 {\rtlch\fcs1 \af37 \ltrch\fcs0 \insrsid6441407 Runs rather slowly on Mac OS X \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22\insrsid6441407 \hich\af37\dbch\af0\loch\f37 -\tab}Setup Dialog sometimes freaks out on Mac OS X (appears to be a WinForms bug) \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 \insrsid6441407 Wish List: \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22\insrsid6441407 \hich\af37\dbch\af0\loch\f37 -\tab}}\pard \ltrpar \s199\ql \fi-360\li720\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\ls12\adjustright\rin0\lin720\itap0\pararsid6555766 {\rtlch\fcs1 \af37 \ltrch\fcs0 \insrsid6441407 64-bit Mono support on Mac OS X (should just work, but needs building / testing) \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22\insrsid6441407 \hich\af37\dbch\af0\loch\f37 -\tab}Want to switch to Xamarin, and VS2017 \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 \i\cf6\insrsid6441407 \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\outlinelevel1\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 \b\ul\insrsid6441407 {\*\bkmkstart _Toc87248735}V2.4.0.0 (darned if I know, 2017)}{\rtlch\fcs1 \af37 \ltrch\fcs0 \insrsid6441407 {\*\bkmkend _Toc87248735} \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 \insrsid6441407 New Features: \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22\insrsid6441407 \hich\af37\dbch\af0\loch\f37 -\tab}}\pard \ltrpar \s199\ql \fi-360\li720\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\ls12\adjustright\rin0\lin720\itap0\pararsid6555766 {\rtlch\fcs1 \af37 \ltrch\fcs0 \insrsid6441407 Linux 64-bit support, despite the TW_INT32/TW_UINT32 fiasco \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22\insrsid6441407 \hich\af37\dbch\af0\loch\f37 -\tab}Switched to log file backup scheme \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22\insrsid6441407 \hich\af37\dbch\af0\loch\f37 -\tab}In sync with TWAIN Direct \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 \insrsid6441407 Known Issues: \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22\insrsid6441407 \hich\af37\dbch\af0\loch\f37 -\tab}}\pard \ltrpar \s199\ql \fi-360\li720\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\ls12\adjustright\rin0\lin720\itap0\pararsid6555766 {\rtlch\fcs1 \af37 \ltrch\fcs0 \insrsid6441407 Runs rather slowly on Mac OS X \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22\insrsid6441407 \hich\af37\dbch\af0\loch\f37 -\tab}Setup Dialog sometimes freaks out on Mac OS X (appears to be a WinForms bug) \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 \insrsid6441407 Wish List: \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22\insrsid6441407 \hich\af37\dbch\af0\loch\f37 -\tab}}\pard \ltrpar \s199\ql \fi-360\li720\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\ls12\adjustright\rin0\lin720\itap0\pararsid6555766 {\rtlch\fcs1 \af37 \ltrch\fcs0 \insrsid6441407 64-bit Mono support on Mac OS X (should just work, but needs building / testing) \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 \i\cf6\insrsid6441407 \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\outlinelevel1\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 \b\ul\insrsid6441407 {\*\bkmkstart _Toc87248736}V2.3.2.0 (18-Oct-2015)}{\rtlch\fcs1 \af37 \ltrch\fcs0 \insrsid6441407 {\*\bkmkend _Toc87248736} \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 \insrsid6441407 New Features: \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22\insrsid6441407 \hich\af37\dbch\af0\loch\f37 -\tab}}\pard \ltrpar \s199\ql \fi-360\li720\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\ls12\adjustright\rin0\lin720\itap0\pararsid6555766 {\rtlch\fcs1 \af37 \ltrch\fcs0 \insrsid6441407 Override capability for logging \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22\insrsid6441407 \hich\af37\dbch\af0\loch\f37 -\tab}Log files are now read shared, so they can be viewed while the code is running \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22\insrsid6441407 \hich\af37\dbch\af0\loch\f37 -\tab}RunInGuiThread scheme added to support Windows for bug listed below \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22\insrsid6441407 \hich\af37\dbch\af0\loch\f37 -\tab}Added thread and state to the log lines, added OS to the title line \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 \insrsid6441407 Bug Fixes: \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22\insrsid6441407 \hich\af37\dbch\af0\loch\f37 -\tab}}\pard \ltrpar \s199\ql \fi-360\li720\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\ls12\adjustright\rin0\lin720\itap0\pararsid6555766 {\rtlch\fcs1 \af37 \ltrch\fcs0 \insrsid6441407 DAT_USERINTERFACE and DAT_IMAGE*XFER run on the HWND thread on Windows, this fixes problems with a number of drivers that run their code in the message loop (addresses Ticket #11 and Ticket #14) \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22\insrsid6441407 \hich\af37\dbch\af0\loch\f37 -\tab}DsmMemLock on the native transfer handle (addresses Ticket #15) \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22\insrsid6441407 \hich\af37\dbch\af0\loch\f37 -\tab}I\rquote m not closing the tickets until I get feedback, or if I hear nothing for a month or two \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 \insrsid6441407 Known Issues: \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22\insrsid6441407 \hich\af37\dbch\af0\loch\f37 -\tab}}\pard \ltrpar \s199\ql \fi-360\li720\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\ls12\adjustright\rin0\lin720\itap0\pararsid6555766 {\rtlch\fcs1 \af37 \ltrch\fcs0 \insrsid6441407 Runs rather slowly on Mac OS X \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22\insrsid6441407 \hich\af37\dbch\af0\loch\f37 -\tab}Setup Dialog sometimes freaks out on Mac OS X (appears to be a WinForms bug) \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 \insrsid6441407 Wish List: \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22\insrsid6441407 \hich\af37\dbch\af0\loch\f37 -\tab}}\pard \ltrpar \s199\ql \fi-360\li720\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\ls12\adjustright\rin0\lin720\itap0\pararsid6555766 {\rtlch\fcs1 \af37 \ltrch\fcs0 \insrsid6441407 64-bit Mono support on Mac OS X (should just work, but needs building / testing) \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 \i\cf6\insrsid6441407 \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\outlinelevel1\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 \b\ul\insrsid6441407 {\*\bkmkstart _Toc87248737}V2.3.1.2 (13-Sep-2015)}{\rtlch\fcs1 \af37 \ltrch\fcs0 \insrsid6441407 {\*\bkmkend _Toc87248737} \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 \insrsid6441407 New Features: \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22\insrsid6441407 \hich\af37\dbch\af0\loch\f37 -\tab}}\pard \ltrpar \s199\ql \fi-360\li720\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\ls12\adjustright\rin0\lin720\itap0\pararsid6555766 {\rtlch\fcs1 \af37 \ltrch\fcs0 \insrsid6441407 (none) \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 \insrsid6441407 Bug Fixes: \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22\insrsid6441407 \hich\af37\dbch\af0\loch\f37 -\tab}}\pard \ltrpar \s199\ql \fi-360\li720\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\ls12\adjustright\rin0\lin720\itap0\pararsid6555766 {\rtlch\fcs1 \af37 \ltrch\fcs0 \insrsid6441407 Solved issues with the DsmMem* functions \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 \insrsid6441407 Known Issues: \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22\insrsid6441407 \hich\af37\dbch\af0\loch\f37 -\tab}}\pard \ltrpar \s199\ql \fi-360\li720\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\ls12\adjustright\rin0\lin720\itap0\pararsid6555766 {\rtlch\fcs1 \af37 \ltrch\fcs0 \insrsid6441407 Runs rather slowly on Mac OS X \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22\insrsid6441407 \hich\af37\dbch\af0\loch\f37 -\tab}Setup Dialog sometimes freaks out on Mac OS X (appears to be a WinForms bug) \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 \insrsid6441407 Wish List: \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22\insrsid6441407 \hich\af37\dbch\af0\loch\f37 -\tab}}\pard \ltrpar \s199\ql \fi-360\li720\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\ls12\adjustright\rin0\lin720\itap0\pararsid6555766 {\rtlch\fcs1 \af37 \ltrch\fcs0 \insrsid6441407 64-bit Mono support on Mac OS X (should just work, but needs building / testing) \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 \insrsid6441407 \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\outlinelevel1\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 \b\ul\insrsid6441407 {\*\bkmkstart _Toc87248738}V2.3.1.1 (27-Aug-2015)}{\rtlch\fcs1 \af37 \ltrch\fcs0 \insrsid6441407 {\*\bkmkend _Toc87248738} \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 \insrsid6441407 New Features: \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22\insrsid6441407 \hich\af37\dbch\af0\loch\f37 -\tab}}\pard \ltrpar \s199\ql \fi-360\li720\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\ls12\adjustright\rin0\lin720\itap0\pararsid6555766 {\rtlch\fcs1 \af37 \ltrch\fcs0 \insrsid6441407 (none) \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 \insrsid6441407 Bug Fixes: \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22\insrsid6441407 \hich\af37\dbch\af0\loch\f37 -\tab}}\pard \ltrpar \s199\ql \fi-360\li720\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\ls12\adjustright\rin0\lin720\itap0\pararsid6555766 {\rtlch\fcs1 \af37 \ltrch\fcs0 \insrsid6441407 Log fix and sync with TWAIN Direct \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 \insrsid6441407 Known Issues: \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22\insrsid6441407 \hich\af37\dbch\af0\loch\f37 -\tab}}\pard \ltrpar \s199\ql \fi-360\li720\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\ls12\adjustright\rin0\lin720\itap0\pararsid6555766 {\rtlch\fcs1 \af37 \ltrch\fcs0 \insrsid6441407 Runs rather slowly on Mac OS X \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22\insrsid6441407 \hich\af37\dbch\af0\loch\f37 -\tab}Setup Dialog sometimes freaks out on Mac OS X (appears to be a WinForms bug) \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 \insrsid6441407 Wish List: \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22\insrsid6441407 \hich\af37\dbch\af0\loch\f37 -\tab}}\pard \ltrpar \s199\ql \fi-360\li720\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\ls12\adjustright\rin0\lin720\itap0\pararsid6555766 {\rtlch\fcs1 \af37 \ltrch\fcs0 \insrsid6441407 64-bit Mono support on Mac OS X (should just work, but needs building / testing) \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 \insrsid6441407 \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\outlinelevel1\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 \b\ul\insrsid6441407 {\*\bkmkstart _Toc87248739}V2.3.1.0 (13-Mar-2015)}{\rtlch\fcs1 \af37 \ltrch\fcs0 \insrsid6441407 {\*\bkmkend _Toc87248739} \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 \insrsid6441407 New Features: \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22\insrsid6441407 \hich\af37\dbch\af0\loch\f37 -\tab}}\pard \ltrpar \s199\ql \fi-360\li720\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\ls12\adjustright\rin0\lin720\itap0\pararsid6555766 {\rtlch\fcs1 \af37 \ltrch\fcs0 \insrsid6441407 Additional arguments to the ReportImage callback \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 \insrsid6441407 Bug Fixes: \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22\insrsid6441407 \hich\af37\dbch\af0\loch\f37 -\tab}}\pard \ltrpar \s199\ql \fi-360\li720\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\ls12\adjustright\rin0\lin720\itap0\pararsid6555766 {\rtlch\fcs1 \af37 \ltrch\fcs0 \insrsid6441407 Tested building using MonoDevelop on Ubuntu 14.04 (32-bit) using Mono 3.12.1, fixed two problems \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 \insrsid6441407 Known Issues: \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22\insrsid6441407 \hich\af37\dbch\af0\loch\f37 -\tab}}\pard \ltrpar \s199\ql \fi-360\li720\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\ls12\adjustright\rin0\lin720\itap0\pararsid6555766 {\rtlch\fcs1 \af37 \ltrch\fcs0 \insrsid6441407 Runs rather slowly on Mac OS X \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22\insrsid6441407 \hich\af37\dbch\af0\loch\f37 -\tab}Setup Dialog sometimes freaks out on Mac OS X (appears to be a WinForms bug) \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 \insrsid6441407 Wish List: \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22\insrsid6441407 \hich\af37\dbch\af0\loch\f37 -\tab}}\pard \ltrpar \s199\ql \fi-360\li720\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\ls12\adjustright\rin0\lin720\itap0\pararsid6555766 {\rtlch\fcs1 \af37 \ltrch\fcs0 \insrsid6441407 64-bit Mono support on Mac OS X (should just work, but needs building / testing) \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 \insrsid6441407 \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\outlinelevel1\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 \b\ul\insrsid6441407 {\*\bkmkstart _Toc87248740}V2.3.0.6 (30-Oct-2014)}{\rtlch\fcs1 \af37 \ltrch\fcs0 \insrsid6441407 {\*\bkmkend _Toc87248740} \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 \insrsid6441407 New Features: \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22\insrsid6441407 \hich\af37\dbch\af0\loch\f37 -\tab}}\pard \ltrpar \s199\ql \fi-360\li720\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\ls12\adjustright\rin0\lin720\itap0\pararsid6555766 {\rtlch\fcs1 \af37 \ltrch\fcs0 \insrsid6441407 (none) \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 \insrsid6441407 Bug Fixes: \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22\insrsid6441407 \hich\af37\dbch\af0\loch\f37 -\tab}}\pard \ltrpar \s199\ql \fi-360\li720\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\ls12\adjustright\rin0\lin720\itap0\pararsid6555766 {\rtlch\fcs1 \af37 \ltrch\fcs0 \insrsid6441407 Closed Ticket #6: DsmMemFree - Validate \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22\insrsid6441407 \hich\af37\dbch\af0\loch\f37 -\tab}Ticket #5 has been resisting, this time I got it right\'85 \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22\insrsid6441407 \hich\af37\dbch\af0\loch\f37 -\tab}Removed embedded tabs \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22\insrsid6441407 \hich\af37\dbch\af0\loch\f37 -\tab}Confirmed successful tests with other vendors \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22\insrsid6441407 \hich\af37\dbch\af0\loch\f37 -\tab}Fixed code to better handle when TWAIN DSM isn\rquote t installed \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 \insrsid6441407 Known Issues: \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22\insrsid6441407 \hich\af37\dbch\af0\loch\f37 -\tab}}\pard \ltrpar \s199\ql \fi-360\li720\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\ls12\adjustright\rin0\lin720\itap0\pararsid6555766 {\rtlch\fcs1 \af37 \ltrch\fcs0 \insrsid6441407 Runs rather slowly on Mac OS X \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22\insrsid6441407 \hich\af37\dbch\af0\loch\f37 -\tab}Setup Dialog sometimes freaks out on Mac OS X (appears to be a WinForms bug) \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 \insrsid6441407 Wish List: \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22\insrsid6441407 \hich\af37\dbch\af0\loch\f37 -\tab}}\pard \ltrpar \s199\ql \fi-360\li720\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\ls12\adjustright\rin0\lin720\itap0\pararsid6555766 {\rtlch\fcs1 \af37 \ltrch\fcs0 \insrsid6441407 64-bit Mono support on Mac OS X (should just work, but needs building / testing) \par }\pard\plain \ltrpar\ql \li0\ri0\widctlpar\wrapdefault\nooverflow\faroman\rin0\lin0\itap0 \rtlch\fcs1 \af45\afs20\alang1025 \ltrch\fcs0 \f45\fs20\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 {\rtlch\fcs1 \af0 \ltrch\fcs0 \v\f37\cf6\insrsid6441407 \par }\pard\plain \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 \rtlch\fcs1 \af37\afs22\alang1025 \ltrch\fcs0 \f37\fs22\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 {\rtlch\fcs1 \af0 \ltrch\fcs0 \v\cf6\insrsid6441407 [Technical Notes]}{\rtlch\fcs1 \af0\afs20 \ltrch\fcs0 \i\v\fs20\cf6\insrsid6441407 \par }{\rtlch\fcs1 \af37 \ltrch\fcs0 \i\v\cf6\insrsid6441407 I think we made a mistake here. All of the capabilities that use TW_ARRAY containers only show TW_ONEVALUE as the valid container for MSG_SET. It should be TW_ONEVALUE and TW_ARRAY. \par }\pard\plain \ltrpar\ql \li0\ri0\widctlpar\wrapdefault\nooverflow\faroman\rin0\lin0\itap0 \rtlch\fcs1 \af45\afs20\alang1025 \ltrch\fcs0 \f45\fs20\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 {\rtlch\fcs1 \af0 \ltrch\fcs0 \v\f37\cf6\insrsid6441407 \par }\pard\plain \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 \rtlch\fcs1 \af37\afs22\alang1025 \ltrch\fcs0 \f37\fs22\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 {\rtlch\fcs1 \af0 \ltrch\fcs0 \v\cf6\insrsid6441407 [Technical Notes]}{\rtlch\fcs1 \af0\afs20 \ltrch\fcs0 \i\v\fs20\cf6\insrsid6441407 \par }{\rtlch\fcs1 \af37 \ltrch\fcs0 \i\v\cf6\insrsid6441407 I think we made a mistake here. All of the capabilities that use TW_ARRAY containers only show TW_ONEVALUE as the valid container for MSG_SET. It should be TW_ONEVALUE and TW_ARRAY. \par }{\rtlch\fcs1 \af37 \ltrch\fcs0 \i\cf6\insrsid6441407 \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\outlinelevel1\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 \b\ul\insrsid6441407 {\*\bkmkstart _Toc87248741}V2.3.0.5 (19-Oct-2014)}{\rtlch\fcs1 \af37 \ltrch\fcs0 \insrsid6441407 {\*\bkmkend _Toc87248741} \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 \insrsid6441407 New Features: \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22\insrsid6441407 \hich\af37\dbch\af0\loch\f37 -\tab}}\pard \ltrpar \s199\ql \fi-360\li720\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\ls12\adjustright\rin0\lin720\itap0\pararsid6555766 {\rtlch\fcs1 \af37 \ltrch\fcs0 \insrsid6441407 (none) \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 \insrsid6441407 Bug Fixes: \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22\insrsid6441407 \hich\af37\dbch\af0\loch\f37 -\tab}}\pard \ltrpar \s199\ql \fi-360\li720\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\ls12\adjustright\rin0\lin720\itap0\pararsid6555766 {\rtlch\fcs1 \af37 \ltrch\fcs0 \insrsid6441407 Closed Ticket #3: can\'b4t get capabilities; what can i get out of a_szMemref? \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22\insrsid6441407 \hich\af37\dbch\af0\loch\f37 -\tab}Closed Ticket #4: Setup Scanner does not work in twancsscan (dialog freezes) \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22\insrsid6441407 \hich\af37\dbch\af0\loch\f37 -\tab}Closed Ticket #5: Twain.DatParent - CloseDs should be CloseDsm \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22\insrsid6441407 \hich\af37\dbch\af0\loch\f37 -\tab}Figured out the message pump issue \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22\insrsid6441407 \hich\af37\dbch\af0\loch\f37 -\tab}Fixed SetImagePath to impact file transfers \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 \insrsid6441407 Known Issues: \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22\insrsid6441407 \hich\af37\dbch\af0\loch\f37 -\tab}}\pard \ltrpar \s199\ql \fi-360\li720\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\ls12\adjustright\rin0\lin720\itap0\pararsid6555766 {\rtlch\fcs1 \af37 \ltrch\fcs0 \insrsid6441407 Runs rather slowly on Mac OS X \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22\insrsid6441407 \hich\af37\dbch\af0\loch\f37 -\tab}Setup Dialog sometimes freaks out on Mac OS X (looks like a race condition) \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22\insrsid6441407 \hich\af37\dbch\af0\loch\f37 -\tab}Only tested on Kodak Alaris products and the TWAIN Sample Data Source \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 \insrsid6441407 Wish List: \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22\insrsid6441407 \hich\af37\dbch\af0\loch\f37 -\tab}}\pard \ltrpar \s199\ql \fi-360\li720\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\ls12\adjustright\rin0\lin720\itap0\pararsid6555766 {\rtlch\fcs1 \af37 \ltrch\fcs0 \insrsid6441407 Test with other vendors \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22\insrsid6441407 \hich\af37\dbch\af0\loch\f37 -\tab}64-bit Mono support on Mac OS X (should just work, but needs building / testing) \par }\pard\plain \ltrpar\ql \li0\ri0\widctlpar\wrapdefault\nooverflow\faroman\rin0\lin0\itap0 \rtlch\fcs1 \af45\afs20\alang1025 \ltrch\fcs0 \f45\fs20\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 {\rtlch\fcs1 \af0 \ltrch\fcs0 \v\f37\cf6\insrsid6441407 \par }\pard\plain \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 \rtlch\fcs1 \af37\afs22\alang1025 \ltrch\fcs0 \f37\fs22\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 {\rtlch\fcs1 \af0 \ltrch\fcs0 \v\cf6\insrsid6441407 [Technical Notes]}{\rtlch\fcs1 \af0\afs20 \ltrch\fcs0 \i\v\fs20\cf6\insrsid6441407 \par }{\rtlch\fcs1 \af37 \ltrch\fcs0 \i\v\cf6\insrsid6441407 I think we made a mistake here. All of the capabilities that use TW_ARRAY containers only show TW_ONEVALUE as the valid container for MSG_SET. It should be TW_ONEVALUE and TW_ARRAY. \par }{\rtlch\fcs1 \af37 \ltrch\fcs0 \i\cf6\insrsid6441407 \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\outlinelevel1\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 \b\ul\insrsid6441407 {\*\bkmkstart _Toc87248742}V2.3.0.4 (13-Oct-2014)}{\rtlch\fcs1 \af37 \ltrch\fcs0 \insrsid6441407 {\*\bkmkend _Toc87248742} \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 \insrsid6441407 New Features: \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22\insrsid6441407 \hich\af37\dbch\af0\loch\f37 -\tab}}\pard \ltrpar \s199\ql \fi-360\li720\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\ls12\adjustright\rin0\lin720\itap0\pararsid6555766 {\rtlch\fcs1 \af37 \ltrch\fcs0 \insrsid6441407 Trackin g the version number to the TWAIN Specification, so the major and minor will be the protocol value, the third number will call out major changes in the API within a version, and the fourth number will count minor changes to the API (like bug fixes) \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22\insrsid6441407 \hich\af37\dbch\af0\loch\f37 -\tab}Added logging (still some work to do on this) \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22\insrsid6441407 \hich\af37\dbch\af0\loch\f37 -\tab}Added auto JPEG/TIFF option for file transfers \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 \insrsid6441407 Bug Fixes: \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22\insrsid6441407 \hich\af37\dbch\af0\loch\f37 -\tab}}\pard \ltrpar \s199\ql \fi-360\li720\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\ls12\adjustright\rin0\lin720\itap0\pararsid6555766 {\rtlch\fcs1 \af37 \ltrch\fcs0 \insrsid6441407 Fixed DAT_IMAGEMEMFILEXFER for Mac OS X \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 \insrsid6441407 Known Issues: \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22\insrsid6441407 \hich\af37\dbch\af0\loch\f37 -\tab}}\pard \ltrpar \s199\ql \fi-360\li720\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\ls12\adjustright\rin0\lin720\itap0\pararsid6555766 {\rtlch\fcs1 \af37 \ltrch\fcs0 \insrsid6441407 Runs rather slowly on Mac OS X \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22\insrsid6441407 \hich\af37\dbch\af0\loch\f37 -\tab}Setup Dialog sometimes freaks out on Mac OS X (looks like a race condition) \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22\insrsid6441407 \hich\af37\dbch\af0\loch\f37 -\tab}Only tested on Kodak Alaris products and the TWAIN Sample Data Source \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 \insrsid6441407 Wish List: \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22\insrsid6441407 \hich\af37\dbch\af0\loch\f37 -\tab}}\pard \ltrpar \s199\ql \fi-360\li720\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\ls12\adjustright\rin0\lin720\itap0\pararsid6555766 {\rtlch\fcs1 \af37 \ltrch\fcs0 \insrsid6441407 Test with other vendors \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22\insrsid6441407 \hich\af37\dbch\af0\loch\f37 -\tab}64-bit Mono support on Mac OS X (should just work, but needs testing) \par }\pard\plain \ltrpar\ql \li0\ri0\widctlpar\wrapdefault\nooverflow\faroman\rin0\lin0\itap0 \rtlch\fcs1 \af45\afs20\alang1025 \ltrch\fcs0 \f45\fs20\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 {\rtlch\fcs1 \af0 \ltrch\fcs0 \v\f37\cf6\insrsid6441407 \par }\pard\plain \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 \rtlch\fcs1 \af37\afs22\alang1025 \ltrch\fcs0 \f37\fs22\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 {\rtlch\fcs1 \af0 \ltrch\fcs0 \v\cf6\insrsid6441407 [Technical Notes]}{\rtlch\fcs1 \af0\afs20 \ltrch\fcs0 \i\v\fs20\cf6\insrsid6441407 \par }{\rtlch\fcs1 \af37 \ltrch\fcs0 \i\v\cf6\insrsid6441407 I think we made a mistake here. All of the capabilities that use TW_ARRAY containers only show TW_ONEVALUE as the valid container for MSG_SET. It should be TW_ONEVALUE and TW_ARRAY. \par }{\rtlch\fcs1 \af37 \ltrch\fcs0 \i\cf6\insrsid6441407 \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\outlinelevel1\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 \b\ul\insrsid6441407 {\*\bkmkstart _Toc87248743}V2.2.0 (11-Jul-2014)}{\rtlch\fcs1 \af37 \ltrch\fcs0 \insrsid6441407 {\*\bkmkend _Toc87248743} \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 \insrsid6441407 New Features: \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22\insrsid6441407 \hich\af37\dbch\af0\loch\f37 -\tab}}\pard \ltrpar \s199\ql \fi-360\li720\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\ls12\adjustright\rin0\lin720\itap0\pararsid6555766 {\rtlch\fcs1 \af37 \ltrch\fcs0 \insrsid6441407 (none) \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 \insrsid6441407 Bug Fixes: \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22\insrsid6441407 \hich\af37\dbch\af0\loch\f37 -\tab}}\pard \ltrpar \s199\ql \fi-360\li720\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\ls12\adjustright\rin0\lin720\itap0\pararsid6555766 {\rtlch\fcs1 \af37 \ltrch\fcs0 \insrsid6441407 Fixed DAT_IMAGEMEMFILEXFER \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 \insrsid6441407 Known Issues: \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22\insrsid6441407 \hich\af37\dbch\af0\loch\f37 -\tab}}\pard \ltrpar \s199\ql \fi-360\li720\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\ls12\adjustright\rin0\lin720\itap0\pararsid6555766 {\rtlch\fcs1 \af37 \ltrch\fcs0 \insrsid6441407 Runs rather slowly on Mac OS X \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22\insrsid6441407 \hich\af37\dbch\af0\loch\f37 -\tab}Setup Dialog sometimes freaks out on Mac OS X (looks like a race condition) \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22\insrsid6441407 \hich\af37\dbch\af0\loch\f37 -\tab}Only tested on Kodak Alaris products and the TWAIN Sample Data Source \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 \insrsid6441407 Wish List: \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22\insrsid6441407 \hich\af37\dbch\af0\loch\f37 -\tab}}\pard \ltrpar \s199\ql \fi-360\li720\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\ls12\adjustright\rin0\lin720\itap0\pararsid6555766 {\rtlch\fcs1 \af37 \ltrch\fcs0 \insrsid6441407 Test with other vendors \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22\insrsid6441407 \hich\af37\dbch\af0\loch\f37 -\tab}64-bit Mono support on Mac OS X (should just work, but needs testing) \par }\pard\plain \ltrpar\ql \li0\ri0\widctlpar\wrapdefault\nooverflow\faroman\rin0\lin0\itap0 \rtlch\fcs1 \af45\afs20\alang1025 \ltrch\fcs0 \f45\fs20\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 {\rtlch\fcs1 \af0 \ltrch\fcs0 \v\f31506\cf6\insrsid6441407 \par }\pard\plain \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 \rtlch\fcs1 \af37\afs22\alang1025 \ltrch\fcs0 \f37\fs22\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 {\rtlch\fcs1 \af0 \ltrch\fcs0 \v\f31506\cf6\insrsid6441407 [Technical Notes]}{\rtlch\fcs1 \af0\afs20 \ltrch\fcs0 \i\v\f31506\fs20\cf6\insrsid6441407 \par }{\rtlch\fcs1 \af37 \ltrch\fcs0 \i\v\f31506\cf6\insrsid6441407 I think we made a mistake here. All of the capabilities that use TW_ARRAY containers only show TW_ONEVALUE as the valid container for MSG_SET. It should be TW_ONEVALUE and TW_ARRAY. \par }{\rtlch\fcs1 \af37 \ltrch\fcs0 \i\f31506\cf6\insrsid6441407 \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\outlinelevel1\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 \b\ul\insrsid6441407 {\*\bkmkstart _Toc87248744}V2.1.0 (09-Jul-2014)}{\rtlch\fcs1 \af37 \ltrch\fcs0 \insrsid6441407 {\*\bkmkend _Toc87248744} \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 \insrsid6441407 New Features: \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22\insrsid6441407 \hich\af37\dbch\af0\loch\f37 -\tab}}\pard \ltrpar \s199\ql \fi-360\li720\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\ls12\adjustright\rin0\lin720\itap0\pararsid6555766 {\rtlch\fcs1 \af37 \ltrch\fcs0 \insrsid6441407 ReportImage\rquote s bitmap no long locks access to the file \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 \insrsid6441407 Bug Fixes: \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22\insrsid6441407 \hich\af37\dbch\af0\loch\f37 -\tab}}\pard \ltrpar \s199\ql \fi-360\li720\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\ls12\adjustright\rin0\lin720\itap0\pararsid6555766 {\rtlch\fcs1 \af37 \ltrch\fcs0 \insrsid6441407 Handles MSG_XFERREADY when issued from MSG_ENABLEDS \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 \insrsid6441407 Known Issues: \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22\insrsid6441407 \hich\af37\dbch\af0\loch\f37 -\tab}}\pard \ltrpar \s199\ql \fi-360\li720\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\ls12\adjustright\rin0\lin720\itap0\pararsid6555766 {\rtlch\fcs1 \af37 \ltrch\fcs0 \insrsid6441407 Runs rather slowly on Mac OS X \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22\insrsid6441407 \hich\af37\dbch\af0\loch\f37 -\tab}Setup Dialog sometimes freaks out on Mac OS X (looks like a race condition) \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22\insrsid6441407 \hich\af37\dbch\af0\loch\f37 -\tab}Only tested on Kodak Alaris products and the TWAIN Sample Data Source \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 \insrsid6441407 Wish List: \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22\insrsid6441407 \hich\af37\dbch\af0\loch\f37 -\tab}}\pard \ltrpar \s199\ql \fi-360\li720\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\ls12\adjustright\rin0\lin720\itap0\pararsid6555766 {\rtlch\fcs1 \af37 \ltrch\fcs0 \insrsid6441407 Test with other vendors \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22\insrsid6441407 \hich\af37\dbch\af0\loch\f37 -\tab}64-bit Mono support on Mac OS X (should just work, but needs testing) \par }\pard \ltrpar\s199\ql \li720\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin720\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 \insrsid6441407 \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\outlinelevel1\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 \b\f31506\ul\insrsid6441407 {\*\bkmkstart _Toc87248745}V2.0.0 (21-May-2014)}{\rtlch\fcs1 \af37 \ltrch\fcs0 \f31506\insrsid6441407 {\*\bkmkend _Toc87248745} \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 \f31506\insrsid6441407 New Features: \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22\insrsid6441407 \hich\af37\dbch\af0\loch\f37 -\tab}}\pard \ltrpar \s199\ql \fi-360\li720\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\ls12\adjustright\rin0\lin720\itap0\pararsid6555766 {\rtlch\fcs1 \af37 \ltrch\fcs0 \f31506\insrsid6441407 Support for 64-bit Linux (native only, 32-bit on 64-bit is too nasty) \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22\insrsid6441407 \hich\af37\dbch\af0\loch\f37 -\tab}ShowImage renamed to ReportImage \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 \f31506\insrsid6441407 Known Issues: \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22\insrsid6441407 \hich\af37\dbch\af0\loch\f37 -\tab}}\pard \ltrpar \s199\ql \fi-360\li720\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\ls12\adjustright\rin0\lin720\itap0\pararsid6555766 {\rtlch\fcs1 \af37 \ltrch\fcs0 \f31506\insrsid6441407 Runs rather slowly on Mac OS X \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22\insrsid6441407 \hich\af37\dbch\af0\loch\f37 -\tab}Setup Dialog sometimes freaks out on Mac OS X (looks like a race condition) \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22\insrsid6441407 \hich\af37\dbch\af0\loch\f37 -\tab}Only tested on Kodak Alaris products \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 \f31506\insrsid6441407 Wish List: \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22\insrsid6441407 \hich\af37\dbch\af0\loch\f37 -\tab}}\pard \ltrpar \s199\ql \fi-360\li720\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\ls12\adjustright\rin0\lin720\itap0\pararsid6555766 {\rtlch\fcs1 \af37 \ltrch\fcs0 \f31506\insrsid6441407 Test with other vendors \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22\insrsid6441407 \hich\af37\dbch\af0\loch\f37 -\tab}64-bit Mono support on Mac OS X (should just work, but needs testing) \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 \i\cf6\insrsid6441407 \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\outlinelevel1\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 \b\ul\insrsid6441407 {\*\bkmkstart _Toc87248746}V1.1.0 (27-Feb-2014)}{\rtlch\fcs1 \af37 \ltrch\fcs0 \insrsid6441407 {\*\bkmkend _Toc87248746} \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 \insrsid6441407 New Features: \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22\insrsid6441407 \hich\af37\dbch\af0\loch\f37 -\tab}}\pard \ltrpar \s199\ql \fi-360\li720\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\ls12\adjustright\rin0\lin720\itap0\pararsid6555766 {\rtlch\fcs1 \af37 \ltrch\fcs0 \insrsid6441407 Additional arguments in ShowImage \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22\insrsid6441407 \hich\af37\dbch\af0\loch\f37 -\tab}Code example of CAP_INDICATORS in TWAINCSScan \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22\insrsid6441407 \hich\af37\dbch\af0\loch\f37 -\tab}Fixed projects to handle conditional references \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22\insrsid6441407 \hich\af37\dbch\af0\loch\f37 -\tab}Added AnyCPU support \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 \insrsid6441407 Known Issues: \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22\insrsid6441407 \hich\af37\dbch\af0\loch\f37 -\tab}}\pard \ltrpar \s199\ql \fi-360\li720\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\ls12\adjustright\rin0\lin720\itap0\pararsid6555766 {\rtlch\fcs1 \af37 \ltrch\fcs0 \insrsid6441407 Runs rather slowly on Mac OS X \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22\insrsid6441407 \hich\af37\dbch\af0\loch\f37 -\tab}Setup Dialog sometimes freaks out on Mac OS X (looks like a race condition) \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22\insrsid6441407 \hich\af37\dbch\af0\loch\f37 -\tab}Only tested on Kodak Alaris products \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 \insrsid6441407 Wish List: \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22\insrsid6441407 \hich\af37\dbch\af0\loch\f37 -\tab}}\pard \ltrpar \s199\ql \fi-360\li720\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\ls12\adjustright\rin0\lin720\itap0\pararsid6555766 {\rtlch\fcs1 \af37 \ltrch\fcs0 \insrsid6441407 Test with other vendors \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22\insrsid6441407 \hich\af37\dbch\af0\loch\f37 -\tab}64-bit Mono support on Linux and Mac OS X \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 \i\cf6\insrsid6441407 \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\outlinelevel1\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 \b\ul\insrsid6441407 {\*\bkmkstart _Toc87248747}V1.0.0 (05-Nov-2013)}{\rtlch\fcs1 \af37 \ltrch\fcs0 \insrsid6441407 {\*\bkmkend _Toc87248747} \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 \insrsid6441407 New Features: \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22\insrsid6441407 \hich\af37\dbch\af0\loch\f37 -\tab}}\pard \ltrpar \s199\ql \fi-360\li720\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\ls12\adjustright\rin0\lin720\itap0\pararsid6555766 {\rtlch\fcs1 \af37 \ltrch\fcs0 \insrsid6441407 Initial release \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 \insrsid6441407 Known Issues: \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22\insrsid6441407 \hich\af37\dbch\af0\loch\f37 -\tab}}\pard \ltrpar \s199\ql \fi-360\li720\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\ls12\adjustright\rin0\lin720\itap0\pararsid6555766 {\rtlch\fcs1 \af37 \ltrch\fcs0 \insrsid6441407 Runs rather slowly on Mac OS X \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22\insrsid6441407 \hich\af37\dbch\af0\loch\f37 -\tab}Setup Dialog sometimes freaks out on Mac OS X (looks like a race condition) \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22\insrsid6441407 \hich\af37\dbch\af0\loch\f37 -\tab}Only tested on Kodak Alaris products \par }\pard \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 \insrsid6441407 Wish List: \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22\insrsid6441407 \hich\af37\dbch\af0\loch\f37 -\tab}}\pard \ltrpar \s199\ql \fi-360\li720\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\ls12\adjustright\rin0\lin720\itap0\pararsid6555766 {\rtlch\fcs1 \af37 \ltrch\fcs0 \insrsid6441407 Test with other vendors \par {\listtext\pard\plain\ltrpar \s199 \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \f37\fs22\insrsid6441407 \hich\af37\dbch\af0\loch\f37 -\tab}64-bit Mono support on Linux and Mac OS X}{\rtlch\fcs1 \af46 \ltrch\fcs0 \f31506\insrsid6441407 \par }\pard\plain \ltrpar\s189\ql \li0\ri0\keepn\widctlpar\brdrt\brdrs\brdrw30\brsp120 \wrapdefault\nooverflow\faroman\outlinelevel0\rin0\lin0\itap0 \rtlch\fcs1 \ab\af1\afs24\alang1025 \ltrch\fcs0 \b\f1\fs24\cf9\lang1024\langfe1024\cgrid\noproof\langnp1033\langfenp1033 {\rtlch\fcs1 \af1 \ltrch\fcs0 \v\f31506\noproof0\insrsid6441407 {\*\bkmkend _Toc234021027}General Comments }{\rtlch\fcs1 \af1 \ltrch\fcs0 \v\f31506\cf6\noproof0\insrsid6441407 [DONE] }{\rtlch\fcs1 \af1 \ltrch\fcs0 \v\f31506\noproof0\insrsid6441407 \par }\pard\plain \ltrpar\ql \li0\ri0\widctlpar\wrapdefault\nooverflow\faroman\rin0\lin0\itap0 \rtlch\fcs1 \af45\afs20\alang1025 \ltrch\fcs0 \f45\fs20\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 {\rtlch\fcs1 \af0 \ltrch\fcs0 \v\f31506\cf6\insrsid6441407 \par }\pard\plain \ltrpar\s199\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 \rtlch\fcs1 \af37\afs22\alang1025 \ltrch\fcs0 \f37\fs22\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 {\rtlch\fcs1 \af0 \ltrch\fcs0 \v\f31506\cf6\insrsid6441407 [Technical Notes]}{\rtlch\fcs1 \af0\afs20 \ltrch\fcs0 \i\v\f31506\fs20\cf6\insrsid6441407 \par These are areas of discussion which may or may not lead to changes in the TWAIN Specification. If changes do result, they\rquote ll be moved into their own area. There are no Update Instructions in this section. When we\rquote re done with it, it \rquote ll be moved to the end of the document and given a status of \'93DONE\'94\'85 \par }\pard\plain \ltrpar\ql \li0\ri0\widctlpar\wrapdefault\nooverflow\faroman\rin0\lin0\itap0 \rtlch\fcs1 \af45\afs20\alang1025 \ltrch\fcs0 \f45\fs20\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 {\rtlch\fcs1 \af0 \ltrch\fcs0 \v\f31506\insrsid6441407 \par \par }{\rtlch\fcs1 \af0 \ltrch\fcs0 \v\f31506\cf6\insrsid6441407 [Note] \endash DONE \par }\pard \ltrpar\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af0\afs22 \ltrch\fcs0 \i\v\f31506\fs22\insrsid6441407 Does a Boolean enumeration have an expected order to the TRUE/FALSE values in the list? \par 8-22 (hunt this down and fix it) \par We don\rquote t want the values ordered, except in the context where the order impacts the UI, but there is no way to know if this is happening or not\'85 \par }\pard \ltrpar\ql \li0\ri0\widctlpar\wrapdefault\faauto\rin0\lin0\itap0 {\rtlch\fcs1 \af46 \ltrch\fcs0 \v\f31506\insrsid6441407 Stores a group of individual values describing a capability. The values are ordered from lowest to \par highest values, but the step size between each value is probably not uniform. Such a list would be \par useful to describe the discreet resolutions of a capture device supporting, say, 75, 150, 300, 400, \par }\pard \ltrpar\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af46 \ltrch\fcs0 \v\f31506\insrsid6441407 and 800 dots per inch.}{\rtlch\fcs1 \af0\afs22 \ltrch\fcs0 \i\v\f31506\fs22\insrsid6441407 \par \par {\listtext\pard\plain\ltrpar \rtlch\fcs1 \af0\afs22 \ltrch\fcs0 \v\fs22\insrsid6441407 \hich\af0\dbch\af0\loch\f0 -\tab}}\pard \ltrpar\ql \fi-360\li720\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\ls11\adjustright\rin0\lin720\itap0\pararsid6555766 { \rtlch\fcs1 \af0\afs22 \ltrch\fcs0 \i\v\f31506\fs22\insrsid6441407 No, there is no required order for items in an enumeration or an array. Ideally the Data Source would maintain t he order of items send to it, and display the items in that order in the GUI, but I don\rquote t believe there is anything in the Specification that even suggests that much. \par }\pard \ltrpar\ql \li0\ri0\widctlpar\wrapdefault\nooverflow\faroman\rin0\lin0\itap0 {\rtlch\fcs1 \af0 \ltrch\fcs0 \v\f31506\insrsid6441407 \par \par }{\rtlch\fcs1 \af0 \ltrch\fcs0 \v\f31506\cf6\insrsid6441407 [Note] \endash DONE \par }\pard \ltrpar\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af0\afs22 \ltrch\fcs0 \i\v\f31506\fs22\insrsid6441407 In particular, I was working on ICAP_BITDEPTH. If a Data Source only supp orts a single bitdepth for each specific pixeltype, wouldn\rquote t it make sense to respond that SET and RESET are not supported? There would be no reason to do a set of Bitdepth, since only a single value is supported at a time. \par \par {\listtext\pard\plain\ltrpar \rtlch\fcs1 \af0\afs22 \ltrch\fcs0 \v\fs22\insrsid6441407 \hich\af0\dbch\af0\loch\f0 -\tab}}\pard \ltrpar\ql \fi-360\li720\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\ls11\adjustright\rin0\lin720\itap0\pararsid6555766 { \rtlch\fcs1 \af0\afs22 \ltrch\fcs0 \i\v\f31506\fs22\insrsid6441407 I wonder if there should be a paragraph on this matter. Here\rquote s my take on it. Applications tend to do one of two things when confronted by an error: they ignore it or they fail (sometimes they crash). With that in mind a driver should always avoid returning an error if it has a val id alternative that allows it to return success instead. Therefore, MSG_RESET and MSG_SET should always be allowed for capabilities that support a single value, except in those cases where the Specification makes it clear that the value is read only (li ke CAP_DEVICEONLINE). \par }\pard \ltrpar\ql \li0\ri0\widctlpar\wrapdefault\nooverflow\faroman\rin0\lin0\itap0 {\rtlch\fcs1 \af0 \ltrch\fcs0 \v\f31506\insrsid6441407 \par \par }{\rtlch\fcs1 \af0 \ltrch\fcs0 \v\f31506\cf6\insrsid6441407 [Note] \endash DONE \par }\pard \ltrpar\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af0\afs22 \ltrch\fcs0 \i\v\f31506\fs22\insrsid6441407 Also regarding ICAP_BITDEPTH, am I correct in understanding that a MSG_GET for this capability should only report the available values based on the current setting for PIXELTYPE? Ie. Don\rquote t report all the bitdepths supported, only those supported for the current pixel type? \par \par {\listtext\pard\plain\ltrpar \rtlch\fcs1 \af0\afs22 \ltrch\fcs0 \v\fs22\insrsid6441407 \hich\af0\dbch\af0\loch\f0 -\tab}}\pard \ltrpar\ql \fi-360\li720\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\ls11\adjustright\rin0\lin720\itap0\pararsid6555766 { \rtlch\fcs1 \af0\afs22 \ltrch\fcs0 \i\v\f31506\fs22\insrsid6441407 This is correct. We know that some drivers show all of the bitdepth values for all of the supported pixeltypes. It doesn\rquote t look like we have a comment on this in the Legacy Issues section (3-39, PDF 71). \par {\listtext\pard\plain\ltrpar \rtlch\fcs1 \af0\afs22 \ltrch\fcs0 \v\fs22\insrsid6441407 \hich\af0\dbch\af0\loch\f0 -\tab}Add a test to the self cert to watch out for this\'85 (this has been added to the Proposed Changes doc) \par }\pard \ltrpar\ql \li0\ri0\widctlpar\wrapdefault\nooverflow\faroman\rin0\lin0\itap0 {\rtlch\fcs1 \af0 \ltrch\fcs0 \v\f31506\insrsid6441407 \par \par }{\rtlch\fcs1 \af0 \ltrch\fcs0 \v\f31506\cf6\insrsid6441407 \page [Note] \endash DONE \par }\pard \ltrpar\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af0\afs22 \ltrch\fcs0 \i\v\f31506\fs22\insrsid6441407 I have a question regarding the filename extension used in a File Transfer. The filename is provided in the DG_CONTROL/DAT_SETUPFILEXFER/MSG_SET message. Do I need to make sure the requested filename extension matches the type of the file I end up creating? \par }{\rtlch\fcs1 \af0\afs22 \ltrch\fcs0 \v\f31506\fs22\insrsid6441407 \par A couple of examples: \par {\listtext\pard\plain\ltrpar \rtlch\fcs1 \af0\afs22 \ltrch\fcs0 \v\f37\fs22\cf22\insrsid6441407 \hich\af37\dbch\af0\loch\f37 1)\tab}}\pard \ltrpar \ql \fi-360\li720\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\ls10\adjustright\rin0\lin720\itap0\pararsid6555766 {\rtlch\fcs1 \af0\afs22 \ltrch\fcs0 \v\f31506\fs22\insrsid6441407 Simple case: if \'93filexfer.tmp\'94 is requested, I\rquote m guessing I should use the file extension as requested regardless of file type that I create. (ie. Even though I save a tiff/jpg/bmp etc. file, continue using the .tmp extention) Is this correct? \par {\listtext\pard\plain\ltrpar \rtlch\fcs1 \af0\afs22 \ltrch\fcs0 \v\f37\fs22\cf22\insrsid6441407 \hich\af37\dbch\af0\loch\f37 2)\tab}More complex case: Assume I\rquote m doing auto color detect, and my non-color will be mapped to BW. If \'93filexfer.jpg \'94 is requested and I detect a non-color image, this will be an *}{\rtlch\fcs1 \ab\af0\afs22 \ltrch\fcs0 \b\v\f31506\fs22\insrsid6441407 incorrect}{\rtlch\fcs1 \af0\afs22 \ltrch\fcs0 \v\f31506\fs22\insrsid6441407 * name in the end since I cannot save a BW image as a JPG file. I will create a BMP file instead. Should I change the requested filename to \'93filexfer.bmp\'94 in this c ase? Or still use the filename as requested even though it gives the wrong impression of filetype? \par }\pard \ltrpar\ql \li360\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin360\itap0 {\rtlch\fcs1 \af0\afs22 \ltrch\fcs0 \v\f31506\fs22\insrsid6441407 \par }\pard \ltrpar\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af0\afs22 \ltrch\fcs0 \v\f31506\fs22\insrsid6441407 If I don\rquote t use the filename exactly as requested, does the TWAIN app think the transfer failed? They really have no way to know what I saved it as if I make a change, so it seems the filename better not change, even in the case that it is incorrect. \par \par Do you know of some TWAIN apps that use FileXfer that I could try this with? \par \par {\listtext\pard\plain\ltrpar \rtlch\fcs1 \af0\afs22 \ltrch\fcs0 \v\fs22\insrsid6441407 \hich\af0\dbch\af0\loch\f0 -\tab}}\pard \ltrpar\ql \fi-360\li720\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\ls11\adjustright\rin0\lin720\itap0\pararsid6555766 { \rtlch\fcs1 \af0\afs22 \ltrch\fcs0 \v\f31506\fs22\insrsid6441407 TWAIN doesn\rquote t recommend or enforce filename extensions for TWFF_* file formats. This means that someone could produce a ridiculous result (like image.bmp for a JPEG image), but that \rquote s okay, because application writers are free to use whatever naming system they need. \par }\pard \ltrpar\ql \li720\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin720\itap0 {\rtlch\fcs1 \af0\afs22 \ltrch\fcs0 \v\f31506\fs22\insrsid6441407 \par {\listtext\pard\plain\ltrpar \rtlch\fcs1 \af0\afs22 \ltrch\fcs0 \v\fs22\insrsid6441407 \hich\af0\dbch\af0\loch\f0 -\tab}}\pard \ltrpar\ql \fi-360\li720\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\ls11\adjustright\rin0\lin720\itap0\pararsid6555766 { \rtlch\fcs1 \af0\afs22 \ltrch\fcs0 \v\f31506\fs22\insrsid6441407 The only time a file transfer should fail is in situations where the application\rquote s request can\rquote t be met. For example, if TWFF_JFIF is requested for a TWPT_BW TWCP_GROUP4 compressed image. \par }\pard\plain \ltrpar\s199\ql \li720\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin720\itap0 \rtlch\fcs1 \af37\afs22\alang1025 \ltrch\fcs0 \f37\fs22\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 {\rtlch\fcs1 \af0 \ltrch\fcs0 \v\f31506\insrsid6441407 \par {\listtext\pard\plain\ltrpar \rtlch\fcs1 \af0\afs22 \ltrch\fcs0 \v\fs22\insrsid6441407 \hich\af0\dbch\af0\loch\f0 -\tab}}\pard\plain \ltrpar \ql \fi-360\li720\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\ls11\adjustright\rin0\lin720\itap0\pararsid6555766 \rtlch\fcs1 \af45\afs20\alang1025 \ltrch\fcs0 \f45\fs20\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 {\rtlch\fcs1 \af0\afs22 \ltrch\fcs0 \v\f31506\fs22\insrsid6441407 Note that DAT_IMAGEFILEXFER is still considered optional, so few drivers support it. It was designed as a low memory transfer option, since the driver is able to transfer the image directly to disk. Most application choose to do this themselves, and using DAT_IMAGEMEMXFER can achieve results that require little memo ry, though an extra step is often needed to create the finished file, since the metadata that describes the image isn\rquote t available until state 7. \par }\pard\plain \ltrpar\s199\ql \li720\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin720\itap0 \rtlch\fcs1 \af37\afs22\alang1025 \ltrch\fcs0 \f37\fs22\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 {\rtlch\fcs1 \af0 \ltrch\fcs0 \v\f31506\insrsid6441407 \par {\listtext\pard\plain\ltrpar \rtlch\fcs1 \af0\afs22 \ltrch\fcs0 \v\fs22\insrsid6441407 \hich\af0\dbch\af0\loch\f0 -\tab}}\pard\plain \ltrpar \ql \fi-360\li720\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\ls11\adjustright\rin0\lin720\itap0\pararsid6555766 \rtlch\fcs1 \af45\afs20\alang1025 \ltrch\fcs0 \f45\fs20\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 {\rtlch\fcs1 \af0\afs22 \ltrch\fcs0 \v\f31506\fs22\insrsid6441407 I don\rquote t know of any commonly used TWAIN applications that use DAT_IMAGEFILEXFER. \par }\pard \ltrpar\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \v\f31506\fs22\cf22\insrsid6441407 \par }\pard \ltrpar\ql \li0\ri0\sb180\widctlpar\wrapdefault\nooverflow\faroman\rin0\lin0\itap0 {\rtlch\fcs1 \af0 \ltrch\fcs0 \v\f31506\insrsid6441407 \page \par }\pard \ltrpar\ql \li0\ri0\widctlpar\wrapdefault\nooverflow\faroman\rin0\lin0\itap0 {\rtlch\fcs1 \af0 \ltrch\fcs0 \v\f31506\cf6\insrsid6441407 [Note] \endash DONE \par }\pard \ltrpar\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af0\afs22 \ltrch\fcs0 \v\f31506\fs22\insrsid6441407 For capabil ities (ch.10 pages), if MSG_GET supports both TW_ONEVALUE and TW_ENUMERATION; should MSG_SET support both as well? Nowhere does the spec include TW_ ENUMERATION as a valid set container, but I think this is allowed. \par \par Oh....ICAP_HALFTONETYPES is the only cap I found that lists TW_ENUMERATION as a SET Container type. \par \par Do I correctly understand that you could replace MSG_SET with MSG_SETCONSTRAINT, and never use MSG_SET anymore? Ie. If sending a TW_ONEVALUE or TW_ARRAY via the MSG_SETCONSTRAINT, this is equivalent to the MSG_SET functionality. \par \par {\listtext\pard\plain\ltrpar \rtlch\fcs1 \af0\afs22 \ltrch\fcs0 \v\fs22\insrsid6441407 \hich\af0\dbch\af0\loch\f0 -\tab}}\pard \ltrpar\ql \fi-360\li720\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\ls11\adjustright\rin0\lin720\itap0\pararsid6555766 { \rtlch\fcs1 \af0\afs22 \ltrch\fcs0 \v\f31506\fs22\insrsid6441407 I can say with confidence that this part of the Spec hasn\rquote t exactly turned out as planned. The intention was to separate setting values from setting constraints. However, I would always expect that one can call MSG_G ET, MSG_GETCURRENT and take the result and pass it into MSG_SET. The difference is that if both the application and the driver report themselves as 2.2 or higher the driver only takes the value from MSG_SET. \par }\pard \ltrpar\ql \li360\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin360\itap0 {\rtlch\fcs1 \af0\afs22 \ltrch\fcs0 \v\f31506\fs22\insrsid6441407 \par {\listtext\pard\plain\ltrpar \rtlch\fcs1 \af0\afs22 \ltrch\fcs0 \v\fs22\insrsid6441407 \hich\af0\dbch\af0\loch\f0 -\tab}}\pard \ltrpar\ql \fi-360\li720\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\ls11\adjustright\rin0\lin720\itap0\pararsid6555766 { \rtlch\fcs1 \af0\afs22 \ltrch\fcs0 \v\f31506\fs22\insrsid6441407 The situation as described means that MSG_GE T cannot be used as the input to MSG_SET. I think that results in too much work for applications and drivers, given the radical departure from previous behavior. \par }\pard\plain \ltrpar\s199\ql \li720\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin720\itap0 \rtlch\fcs1 \af37\afs22\alang1025 \ltrch\fcs0 \f37\fs22\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 {\rtlch\fcs1 \af0 \ltrch\fcs0 \v\f31506\insrsid6441407 \par {\listtext\pard\plain\ltrpar \rtlch\fcs1 \af0\afs22 \ltrch\fcs0 \v\fs22\insrsid6441407 \hich\af0\dbch\af0\loch\f0 -\tab}}\pard\plain \ltrpar \ql \fi-360\li720\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\ls11\adjustright\rin0\lin720\itap0\pararsid6555766 \rtlch\fcs1 \af45\afs20\alang1025 \ltrch\fcs0 \f45\fs20\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 {\rtlch\fcs1 \af0\afs22 \ltrch\fcs0 \v\f31506\fs22\insrsid6441407 Using TW_ONEVALUE with MSG_SETCONTRAINT should constrain the capability to that one value. Also, the value is always set with MSG_SETCONTRAINT. \par }\pard \ltrpar\ql \li720\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin720\itap0 {\rtlch\fcs1 \af0\afs22 \ltrch\fcs0 \v\f31506\fs22\insrsid6441407 \par {\listtext\pard\plain\ltrpar \rtlch\fcs1 \af0\afs22 \ltrch\fcs0 \v\fs22\insrsid6441407 \hich\af0\dbch\af0\loch\f0 -\tab}}\pard \ltrpar\ql \fi-360\li720\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\ls11\adjustright\rin0\lin720\itap0\pararsid6555766 { \rtlch\fcs1 \af0\afs22 \ltrch\fcs0 \v\f31506\fs22\insrsid6441407 Therefore, we need to make sure that t he Spec clearly explains the difference between MSG_SET and MSG_SETCONTRAINT, and then make sure that for all capabilities the allowed containers for both MSG_SET and MSG_SETCONSTRAINT are identical. \par }\pard\plain \ltrpar\s199\ql \li720\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin720\itap0 \rtlch\fcs1 \af37\afs22\alang1025 \ltrch\fcs0 \f37\fs22\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 {\rtlch\fcs1 \af0 \ltrch\fcs0 \v\f31506\insrsid6441407 \par {\listtext\pard\plain\ltrpar \rtlch\fcs1 \af0\afs22 \ltrch\fcs0 \v\fs22\insrsid6441407 \hich\af0\dbch\af0\loch\f0 -\tab}}\pard\plain \ltrpar \ql \fi-360\li720\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\ls11\adjustright\rin0\lin720\itap0\pararsid6555766 \rtlch\fcs1 \af45\afs20\alang1025 \ltrch\fcs0 \f45\fs20\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 {\rtlch\fcs1 \af0\afs22 \ltrch\fcs0 \v\f31506\fs22\insrsid6441407 I\rquote m pretty sure that Self-Cert will support this change (meaning that it assumes that a MSG_GET can always be followed by a MSG_SET). I\rquote d be very surprised if anybody changed the behavior of MSG_SET without asking us what we\rquote re thinking... \par }\pard\plain \ltrpar\s199\ql \li720\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin720\itap0 \rtlch\fcs1 \af37\afs22\alang1025 \ltrch\fcs0 \f37\fs22\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 {\rtlch\fcs1 \af0 \ltrch\fcs0 \v\f31506\insrsid6441407 \par {\listtext\pard\plain\ltrpar \rtlch\fcs1 \af0\afs22 \ltrch\fcs0 \v\fs22\insrsid6441407 \hich\af0\dbch\af0\loch\f0 -\tab}}\pard\plain \ltrpar \ql \fi-360\li720\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\ls11\adjustright\rin0\lin720\itap0\pararsid6555766 \rtlch\fcs1 \af45\afs20\alang1025 \ltrch\fcs0 \f45\fs20\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 {\rtlch\fcs1 \af0\afs22 \ltrch\fcs0 \v\f31506\fs22\insrsid6441407 MSG_SET will only impact the current value\'85 \par }\pard \ltrpar\ql \li0\ri0\sb180\widctlpar\wrapdefault\nooverflow\faroman\rin0\lin0\itap0 {\rtlch\fcs1 \af0 \ltrch\fcs0 \v\f31506\insrsid6441407 \par }\pard \ltrpar\ql \li0\ri0\widctlpar\wrapdefault\nooverflow\faroman\rin0\lin0\itap0 {\rtlch\fcs1 \af0 \ltrch\fcs0 \v\f31506\cf6\insrsid6441407 \page [Note] \endash DONE \par }\pard \ltrpar\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af0\afs22 \ltrch\fcs0 \v\f31506\fs22\insrsid6441407 ICAP_XFERMECH (ch. 10, pg. 10-197): under Application section it reads, \'93 The current value of ICAP_XFERMECH must match the data argument type when starting the transfer using the triplet: DG_IMAGE / DAT_IMAGExxxxXFER / MSG_GET.\'94 If it does not match, what should happen? \par (NOTE: already discussed in the working group meeting on 17 July 2012) \par \par {\listtext\pard\plain\ltrpar \rtlch\fcs1 \af0\afs22 \ltrch\fcs0 \v\fs22\insrsid6441407 \hich\af0\dbch\af0\loch\f0 -\tab}}\pard \ltrpar\ql \fi-360\li720\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\ls11\adjustright\rin0\lin720\itap0\pararsid6555766 { \rtlch\fcs1 \af0\afs22 \ltrch\fcs0 \v\f31506\fs22\insrsid6441407 My recollection from the meeting is as follows: \par }\pard \ltrpar\ql \li720\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin720\itap0 {\rtlch\fcs1 \af0\afs22 \ltrch\fcs0 \v\f31506\fs22\insrsid6441407 \par {\listtext\pard\plain\ltrpar \rtlch\fcs1 \af0\afs22 \ltrch\fcs0 \v\fs22\insrsid6441407 \hich\af0\dbch\af0\loch\f0 -\tab}}\pard \ltrpar\ql \fi-360\li720\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\ls11\adjustright\rin0\lin720\itap0\pararsid6555766 { \rtlch\fcs1 \af0\afs22 \ltrch\fcs0 \v\f31506\fs22\insrsid6441407 The TWAIN Spec says that apps need to set ICAP_XFERMECH in state 4 to the transfer mechanism that\rquote ll be used in state 6 and 7. However, some apps don\rquote t bother to do this. \par }\pard\plain \ltrpar\s199\ql \li720\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin720\itap0 \rtlch\fcs1 \af37\afs22\alang1025 \ltrch\fcs0 \f37\fs22\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 {\rtlch\fcs1 \af0 \ltrch\fcs0 \v\f31506\insrsid6441407 \par {\listtext\pard\plain\ltrpar \rtlch\fcs1 \af0\afs22 \ltrch\fcs0 \v\fs22\insrsid6441407 \hich\af0\dbch\af0\loch\f0 -\tab}}\pard\plain \ltrpar \ql \fi-360\li720\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\ls11\adjustright\rin0\lin720\itap0\pararsid6555766 \rtlch\fcs1 \af45\afs20\alang1025 \ltrch\fcs0 \f45\fs20\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 {\rtlch\fcs1 \af0\afs22 \ltrch\fcs0 \v\f31506\fs22\insrsid6441407 The thought is to leave the requirement intact, but add a bit to the Legacy Issues section warning driver writers not to assume this will happen. \par }\pard \ltrpar\ql \li0\ri0\sb180\widctlpar\wrapdefault\nooverflow\faroman\rin0\lin0\itap0 {\rtlch\fcs1 \af0 \ltrch\fcs0 \v\f31506\insrsid6441407 \par }\pard \ltrpar\ql \li0\ri0\widctlpar\wrapdefault\nooverflow\faroman\rin0\lin0\itap0 {\rtlch\fcs1 \af0 \ltrch\fcs0 \v\f31506\cf6\insrsid6441407 [Note] \endash DONE \par }\pard \ltrpar\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af0\afs22 \ltrch\fcs0 \v\f31506\fs22\insrsid6441407 (ch. 2, pg. 2-16) I think a couple of string types are missing. It says: \'93There are }{ \rtlch\fcs1 \af0\afs22 \ltrch\fcs0 \v\f31506\fs22\ul\insrsid6441407 four}{\rtlch\fcs1 \af0\afs22 \ltrch\fcs0 \v\f31506\fs22\insrsid6441407 types of TWAIN strings defined for developer use:\'94 , and then lists TW_STR32, TW_STR64, TW_STR128, and TW_STR256. But in twain.h, there are now TW_STR1024 and a TW_UNI512 types defined. Should these be added, for a total of 6? \par {\listtext\pard\plain\ltrpar \rtlch\fcs1 \af0\afs20 \ltrch\fcs0 \v\fs20\insrsid6441407 \hich\af0\dbch\af0\loch\f0 -\tab}}\pard \ltrpar\ql \fi-360\li720\ri0\sb180\widctlpar\wrapdefault\nooverflow\faroman\ls11\rin0\lin720\itap0\pararsid6555766 {\rtlch\fcs1 \af0 \ltrch\fcs0 \v\f31506\insrsid6441407 TW_STR1024 and TW_UNI512 have been deprecated, so the number \lquote four\rquote is right.}{\rtlch\fcs1 \ab\af0\afs22 \ltrch\fcs0 \b\v\f31506\fs22\insrsid6441407 \par }\pard \ltrpar\ql \li0\ri0\sb180\widctlpar\wrapdefault\nooverflow\faroman\rin0\lin0\itap0 {\rtlch\fcs1 \af0 \ltrch\fcs0 \v\f31506\insrsid6441407 \par }\pard \ltrpar\ql \li0\ri0\widctlpar\wrapdefault\nooverflow\faroman\rin0\lin0\itap0 {\rtlch\fcs1 \af0 \ltrch\fcs0 \v\f31506\cf6\insrsid6441407 [Note] \endash DONE \par }\pard \ltrpar\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \v\f31506\fs22\insrsid6441407 Do I understand correctly that MSG_GETDEFAULT should return the Source\rquote s *}{ \rtlch\fcs1 \ab\af37\afs22 \ltrch\fcs0 \b\v\f31506\fs22\insrsid6441407 Preferred}{\rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \v\f31506\fs22\insrsid6441407 * default. But this may *}{\rtlch\fcs1 \ab\af37\afs22 \ltrch\fcs0 \b\v\f31506\fs22\insrsid6441407 not}{ \rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \v\f31506\fs22\insrsid6441407 * be the value set when calling MSG_RESET, since MSG_RESET resets to the TWAIN default? If there is a Mandatory default, does MSG_GETDEFAULT need to return the mandatory default? \par }\pard \ltrpar\ql \li0\ri0\sb180\widctlpar\wrapdefault\nooverflow\faroman\rin0\lin0\itap0 {\rtlch\fcs1 \af0 \ltrch\fcs0 \v\f31506\insrsid6441407 \par }\pard \ltrpar\ql \li0\ri0\widctlpar\wrapdefault\nooverflow\faroman\rin0\lin0\itap0 {\rtlch\fcs1 \af0 \ltrch\fcs0 \v\f31506\cf6\insrsid6441407 [Note] \endash DONE \par }\pard \ltrpar\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \v\f31506\fs22\insrsid6441407 So is MSG_RESET meant to reset to the value listed in Ch. 10 a lways? (whether or not this is a mandatory default) Only if Ch. 10 says \'93no default\'94 can the source reset it to a preferred or user value? \par }\pard\plain \ltrpar\s199\ql \li360\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin360\itap0 \rtlch\fcs1 \af37\afs22\alang1025 \ltrch\fcs0 \f37\fs22\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 {\rtlch\fcs1 \af37 \ltrch\fcs0 \i\v\f31506\cf6\insrsid6441407 \par }\pard\plain \ltrpar\ql \li720\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin720\itap0 \rtlch\fcs1 \af45\afs20\alang1025 \ltrch\fcs0 \f45\fs20\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 {\rtlch\fcs1 \af37\afs22 \ltrch\fcs0 \v\f31506\fs22\cf23\insrsid6441407 \par }{\*\themedata 504b030414000600080000002100e9de0fbfff0000001c020000130000005b436f6e74656e745f54797065735d2e786d6cac91cb4ec3301045f748fc83e52d4a 9cb2400825e982c78ec7a27cc0c8992416c9d8b2a755fbf74cd25442a820166c2cd933f79e3be372bd1f07b5c3989ca74aaff2422b24eb1b475da5df374fd9ad 5689811a183c61a50f98f4babebc2837878049899a52a57be670674cb23d8e90721f90a4d2fa3802cb35762680fd800ecd7551dc18eb899138e3c943d7e503b6 b01d583deee5f99824e290b4ba3f364eac4a430883b3c092d4eca8f946c916422ecab927f52ea42b89a1cd59c254f919b0e85e6535d135a8de20f20b8c12c3b0 0c895fcf6720192de6bf3b9e89ecdbd6596cbcdd8eb28e7c365ecc4ec1ff1460f53fe813d3cc7f5b7f020000ffff0300504b030414000600080000002100a5d6 a7e7c0000000360100000b0000005f72656c732f2e72656c73848fcf6ac3300c87ef85bd83d17d51d2c31825762fa590432fa37d00e1287f68221bdb1bebdb4f c7060abb0884a4eff7a93dfeae8bf9e194e720169aaa06c3e2433fcb68e1763dbf7f82c985a4a725085b787086a37bdbb55fbc50d1a33ccd311ba548b6309512 0f88d94fbc52ae4264d1c910d24a45db3462247fa791715fd71f989e19e0364cd3f51652d73760ae8fa8c9ffb3c330cc9e4fc17faf2ce545046e37944c69e462 a1a82fe353bd90a865aad41ed0b5b8f9d6fd010000ffff0300504b0304140006000800000021006b799616830000008a0000001c0000007468656d652f746865 6d652f7468656d654d616e616765722e786d6c0ccc4d0ac3201040e17da17790d93763bb284562b2cbaebbf600439c1a41c7a0d29fdbd7e5e38337cedf14d59b 4b0d592c9c070d8a65cd2e88b7f07c2ca71ba8da481cc52c6ce1c715e6e97818c9b48d13df49c873517d23d59085adb5dd20d6b52bd521ef2cdd5eb9246a3d8b 4757e8d3f729e245eb2b260a0238fd010000ffff0300504b03041400060008000000210096b5ade296060000501b0000160000007468656d652f7468656d652f 7468656d65312e786d6cec594f6fdb3614bf0fd87720746f6327761a07758ad8b19b2d4d1bc46e871e698996d850a240d2497d1bdae38001c3ba618715d86d87 615b8116d8a5fb34d93a6c1dd0afb0475292c5585e9236d88aad3e2412f9e3fbff1e1fa9abd7eec70c1d1221294fda5efd72cd4324f1794093b0eddd1ef62fad 79482a9c0498f184b4bd2991deb58df7dfbb8ad755446282607d22d771db8b944ad79796a40fc3585ee62949606ecc458c15bc8a702910f808e8c66c69b9565b 5d8a314d3c94e018c8de1a8fa94fd05093f43672e23d06af89927ac06762a049136785c10607758d9053d965021d62d6f6804fc08f86e4bef210c352c144dbab 999fb7b4717509af678b985ab0b6b4ae6f7ed9ba6c4170b06c788a705430adf71bad2b5b057d03606a1ed7ebf5babd7a41cf00b0ef83a6569632cd467faddec9 699640f6719e76b7d6ac355c7c89feca9cccad4ea7d36c65b258a206641f1b73f8b5da6a6373d9c11b90c537e7f08dce66b7bbeae00dc8e257e7f0fd2badd586 8b37a088d1e4600ead1ddaef67d40bc898b3ed4af81ac0d76a197c86826828a24bb318f3442d8ab518dfe3a20f000d6458d104a9694ac6d88728eee2782428d6 0cf03ac1a5193be4cbb921cd0b495fd054b5bd0f530c1931a3f7eaf9f7af9e3f45c70f9e1d3ff8e9f8e1c3e3073f5a42ceaa6d9c84e5552fbffdeccfc71fa33f 9e7ef3f2d117d57859c6fffac327bffcfc793510d26726ce8b2f9ffcf6ecc98baf3efdfdbb4715f04d814765f890c644a29be408edf3181433567125272371be 15c308d3f28acd249438c19a4b05fd9e8a1cf4cd296699771c393ac4b5e01d01e5a30a787d72cf1178108989a2159c77a2d801ee72ce3a5c545a6147f32a9979 3849c26ae66252c6ed637c58c5bb8b13c7bfbd490a75330f4b47f16e441c31f7184e140e494214d273fc80900aedee52ead87597fa824b3e56e82e451d4c2b4d 32a423279a668bb6690c7e9956e90cfe766cb37b077538abd27a8b1cba48c80acc2a841f12e698f13a9e281c57911ce298950d7e03aba84ac8c154f8655c4f2a f074481847bd804859b5e696007d4b4edfc150b12addbecba6b18b148a1e54d1bc81392f23b7f84137c2715a851dd0242a633f900710a218ed715505dfe56e86 e877f0034e16bafb0e258ebb4faf06b769e888340b103d3311da9750aa9d0a1cd3e4efca31a3508f6d0c5c5c398602f8e2ebc71591f5b616e24dd893aa3261fb 44f95d843b5974bb5c04f4edafb95b7892ec1108f3f98de75dc97d5772bdff7cc95d94cf672db4b3da0a6557f70db629362d72bcb0431e53c6066acac80d699a 6409fb44d08741bdce9c0e4971624a2378cceaba830b05366b90e0ea23aaa241845368b0eb9e2612ca8c742851ca251ceccc70256d8d87265dd96361531f186c 3d9058edf2c00eafe8e1fc5c509031bb4d680e9f39a3154de0accc56ae644441edd76156d7429d995bdd88664a9dc3ad50197c38af1a0c16d684060441db0256 5e85f3b9660d0713cc48a0ed6ef7dedc2dc60b17e92219e180643ed27acffba86e9c94c78ab90980d8a9f0913ee49d62b512b79626fb06dccee2a432bbc60276 b9f7dec44b7904cfbca4f3f6443ab2a49c9c2c41476dafd55c6e7ac8c769db1bc399161ee314bc2e75cf8759081743be1236ec4f4d6693e5336fb672c5dc24a8 c33585b5fb9cc24e1d4885545b58463634cc5416022cd19cacfccb4d30eb45296023fd35a458598360f8d7a4003bbaae25e331f155d9d9a5116d3bfb9a95523e 51440ca2e0088dd844ec6370bf0e55d027a012ae264c45d02f708fa6ad6da6dce29c255df9f6cae0ec38666984b372ab5334cf640b37795cc860de4ae2816e95 b21be5ceaf8a49f90b52a51cc6ff3355f47e0237052b81f6800fd7b802239daf6d8f0b1571a8426944fdbe80c6c1d40e8816b88b8569082ab84c36ff0539d4ff 6dce591a26ade1c0a7f669880485fd484582903d284b26fa4e2156cff62e4b9265844c4495c495a9157b440e091bea1ab8aaf7760f4510eaa69a6465c0e04ec6 9ffb9e65d028d44d4e39df9c1a52ecbd3607fee9cec7263328e5d661d3d0e4f62f44acd855ed7ab33cdf7bcb8ae889599bd5c8b3029895b6825696f6af29c239 b75a5bb1e6345e6ee6c28117e73586c1a2214ae1be07e93fb0ff51e133fb65426fa843be0fb515c187064d0cc206a2fa926d3c902e907670048d931db4c1a449 59d366ad93b65abe595f70a75bf03d616c2dd959fc7d4e6317cd99cbcec9c58b34766661c7d6766ca1a9c1b327531486c6f941c638c67cd22a7f75e2a37be0e8 2db8df9f30254d30c1372581a1f51c983c80e4b71ccdd28dbf000000ffff0300504b0304140006000800000021000dd1909fb60000001b010000270000007468 656d652f7468656d652f5f72656c732f7468656d654d616e616765722e786d6c2e72656c73848f4d0ac2301484f78277086f6fd3ba109126dd88d0add40384e4 350d363f2451eced0dae2c082e8761be9969bb979dc9136332de3168aa1a083ae995719ac16db8ec8e4052164e89d93b64b060828e6f37ed1567914b284d2624 52282e3198720e274a939cd08a54f980ae38a38f56e422a3a641c8bbd048f7757da0f19b017cc524bd62107bd5001996509affb3fd381a89672f1f165dfe5141 73d9850528a2c6cce0239baa4c04ca5bbabac4df000000ffff0300504b01022d0014000600080000002100e9de0fbfff0000001c020000130000000000000000 0000000000000000005b436f6e74656e745f54797065735d2e786d6c504b01022d0014000600080000002100a5d6a7e7c0000000360100000b00000000000000 000000000000300100005f72656c732f2e72656c73504b01022d00140006000800000021006b799616830000008a0000001c0000000000000000000000000019 0200007468656d652f7468656d652f7468656d654d616e616765722e786d6c504b01022d001400060008000000210096b5ade296060000501b00001600000000 000000000000000000d60200007468656d652f7468656d652f7468656d65312e786d6c504b01022d00140006000800000021000dd1909fb60000001b01000027 00000000000000000000000000a00900007468656d652f7468656d652f5f72656c732f7468656d654d616e616765722e786d6c2e72656c73504b050600000000050005005d0100009b0a00000000} {\*\colorschememapping 3c3f786d6c2076657273696f6e3d22312e302220656e636f64696e673d225554462d3822207374616e64616c6f6e653d22796573223f3e0d0a3c613a636c724d 617020786d6c6e733a613d22687474703a2f2f736368656d61732e6f70656e786d6c666f726d6174732e6f72672f64726177696e676d6c2f323030362f6d6169 6e22206267313d226c743122207478313d22646b3122206267323d226c743222207478323d22646b322220616363656e74313d22616363656e74312220616363 656e74323d22616363656e74322220616363656e74333d22616363656e74332220616363656e74343d22616363656e74342220616363656e74353d22616363656e74352220616363656e74363d22616363656e74362220686c696e6b3d22686c696e6b2220666f6c486c696e6b3d22666f6c486c696e6b222f3e} {\*\latentstyles\lsdstimax376\lsdlockeddef0\lsdsemihiddendef0\lsdunhideuseddef0\lsdqformatdef0\lsdprioritydef99{\lsdlockedexcept \lsdqformat1 \lsdpriority0 \lsdlocked0 Normal;\lsdqformat1 \lsdpriority0 \lsdlocked0 heading 1; \lsdqformat1 \lsdpriority0 \lsdlocked0 heading 2;\lsdqformat1 \lsdpriority0 \lsdlocked0 heading 3;\lsdqformat1 \lsdpriority0 \lsdlocked0 heading 4;\lsdqformat1 \lsdpriority0 \lsdlocked0 heading 5;\lsdqformat1 \lsdpriority0 \lsdlocked0 heading 6; \lsdqformat1 \lsdpriority0 \lsdlocked0 heading 7;\lsdqformat1 \lsdpriority0 \lsdlocked0 heading 8;\lsdqformat1 \lsdpriority0 \lsdlocked0 heading 9;\lsdsemihidden1 \lsdunhideused1 index 1;\lsdsemihidden1 \lsdunhideused1 index 2; \lsdsemihidden1 \lsdunhideused1 index 3;\lsdsemihidden1 \lsdunhideused1 index 4;\lsdsemihidden1 \lsdunhideused1 index 5;\lsdsemihidden1 \lsdunhideused1 index 6;\lsdsemihidden1 \lsdunhideused1 index 7;\lsdsemihidden1 \lsdunhideused1 index 8; \lsdsemihidden1 \lsdunhideused1 index 9;\lsdpriority39 \lsdlocked0 toc 1;\lsdpriority39 \lsdlocked0 toc 2;\lsdpriority0 \lsdlocked0 toc 3;\lsdpriority0 \lsdlocked0 toc 4;\lsdpriority0 \lsdlocked0 toc 5;\lsdpriority0 \lsdlocked0 toc 6; \lsdpriority0 \lsdlocked0 toc 7;\lsdpriority0 \lsdlocked0 toc 8;\lsdpriority0 \lsdlocked0 toc 9;\lsdsemihidden1 \lsdunhideused1 Normal Indent;\lsdsemihidden1 \lsdunhideused1 footnote text;\lsdsemihidden1 \lsdunhideused1 annotation text; \lsdsemihidden1 \lsdunhideused1 header;\lsdsemihidden1 \lsdunhideused1 footer;\lsdsemihidden1 \lsdunhideused1 index heading;\lsdqformat1 \lsdpriority0 \lsdlocked0 caption;\lsdsemihidden1 \lsdunhideused1 table of figures; \lsdsemihidden1 \lsdunhideused1 envelope address;\lsdsemihidden1 \lsdunhideused1 envelope return;\lsdsemihidden1 \lsdunhideused1 footnote reference;\lsdsemihidden1 \lsdunhideused1 annotation reference;\lsdsemihidden1 \lsdunhideused1 line number; \lsdsemihidden1 \lsdunhideused1 page number;\lsdsemihidden1 \lsdunhideused1 endnote reference;\lsdsemihidden1 \lsdunhideused1 endnote text;\lsdsemihidden1 \lsdunhideused1 table of authorities;\lsdsemihidden1 \lsdunhideused1 macro; \lsdsemihidden1 \lsdunhideused1 toa heading;\lsdsemihidden1 \lsdunhideused1 List;\lsdsemihidden1 \lsdunhideused1 List Bullet;\lsdsemihidden1 \lsdunhideused1 List Number;\lsdsemihidden1 \lsdunhideused1 List 2;\lsdsemihidden1 \lsdunhideused1 List 3; \lsdsemihidden1 \lsdunhideused1 List 4;\lsdsemihidden1 \lsdunhideused1 List 5;\lsdsemihidden1 \lsdunhideused1 List Bullet 2;\lsdsemihidden1 \lsdunhideused1 List Bullet 3;\lsdsemihidden1 \lsdunhideused1 List Bullet 4; \lsdsemihidden1 \lsdunhideused1 List Bullet 5;\lsdsemihidden1 \lsdunhideused1 List Number 2;\lsdsemihidden1 \lsdunhideused1 List Number 3;\lsdsemihidden1 \lsdunhideused1 List Number 4;\lsdsemihidden1 \lsdunhideused1 List Number 5; \lsdqformat1 \lsdpriority0 \lsdlocked0 Title;\lsdsemihidden1 \lsdunhideused1 Closing;\lsdsemihidden1 \lsdunhideused1 Signature;\lsdpriority0 \lsdlocked0 Default Paragraph Font;\lsdsemihidden1 \lsdunhideused1 Body Text; \lsdsemihidden1 \lsdunhideused1 Body Text Indent;\lsdsemihidden1 \lsdunhideused1 List Continue;\lsdsemihidden1 \lsdunhideused1 List Continue 2;\lsdsemihidden1 \lsdunhideused1 List Continue 3;\lsdsemihidden1 \lsdunhideused1 List Continue 4; \lsdsemihidden1 \lsdunhideused1 List Continue 5;\lsdsemihidden1 \lsdunhideused1 Message Header;\lsdqformat1 \lsdpriority0 \lsdlocked0 Subtitle;\lsdsemihidden1 \lsdunhideused1 Salutation;\lsdsemihidden1 \lsdunhideused1 Date; \lsdsemihidden1 \lsdunhideused1 Body Text First Indent;\lsdsemihidden1 \lsdunhideused1 Body Text First Indent 2;\lsdsemihidden1 \lsdunhideused1 Note Heading;\lsdsemihidden1 \lsdunhideused1 Body Text 2;\lsdsemihidden1 \lsdunhideused1 Body Text 3; \lsdsemihidden1 \lsdunhideused1 Body Text Indent 2;\lsdsemihidden1 \lsdunhideused1 Body Text Indent 3;\lsdsemihidden1 \lsdunhideused1 Block Text;\lsdsemihidden1 \lsdunhideused1 Hyperlink;\lsdsemihidden1 \lsdunhideused1 FollowedHyperlink; \lsdqformat1 \lsdpriority0 \lsdlocked0 Strong;\lsdqformat1 \lsdpriority0 \lsdlocked0 Emphasis;\lsdsemihidden1 \lsdunhideused1 Document Map;\lsdsemihidden1 \lsdunhideused1 Plain Text;\lsdsemihidden1 \lsdunhideused1 E-mail Signature; \lsdsemihidden1 \lsdunhideused1 HTML Top of Form;\lsdsemihidden1 \lsdunhideused1 HTML Bottom of Form;\lsdsemihidden1 \lsdunhideused1 Normal (Web);\lsdsemihidden1 \lsdunhideused1 HTML Acronym;\lsdsemihidden1 \lsdunhideused1 HTML Address; \lsdsemihidden1 \lsdunhideused1 HTML Cite;\lsdsemihidden1 \lsdunhideused1 HTML Code;\lsdsemihidden1 \lsdunhideused1 HTML Definition;\lsdsemihidden1 \lsdunhideused1 HTML Keyboard;\lsdsemihidden1 \lsdunhideused1 HTML Preformatted; \lsdsemihidden1 \lsdunhideused1 HTML Sample;\lsdsemihidden1 \lsdunhideused1 HTML Typewriter;\lsdsemihidden1 \lsdunhideused1 HTML Variable;Normal Table;\lsdsemihidden1 \lsdunhideused1 annotation subject;\lsdsemihidden1 \lsdunhideused1 No List; \lsdsemihidden1 \lsdunhideused1 Outline List 1;\lsdsemihidden1 \lsdunhideused1 Outline List 2;\lsdsemihidden1 \lsdunhideused1 Outline List 3;Table Simple 1;Table Simple 2;Table Simple 3;Table Classic 1;Table Classic 2;Table Classic 3;Table Classic 4; Table Colorful 1;Table Colorful 2;Table Colorful 3;Table Columns 1;Table Columns 2;Table Columns 3;Table Columns 4;Table Columns 5;Table Grid 1;Table Grid 2;Table Grid 3;Table Grid 4;Table Grid 5;Table Grid 6;Table Grid 7;Table Grid 8;Table List 1; Table List 2;Table List 3;Table List 4;Table List 5;Table List 6;Table List 7;Table List 8;Table 3D effects 1;Table 3D effects 2;Table 3D effects 3;Table Contemporary;Table Elegant;Table Professional;Table Subtle 1;Table Subtle 2;Table Web 1;Table Web 2; Table Web 3;\lsdsemihidden1 \lsdunhideused1 Balloon Text;\lsdpriority0 \lsdlocked0 Table Grid;Table Theme;\lsdsemihidden1 \lsdlocked0 Placeholder Text;\lsdqformat1 \lsdpriority1 \lsdlocked0 No Spacing;\lsdpriority60 \lsdlocked0 Light Shading; \lsdpriority61 \lsdlocked0 Light List;\lsdpriority62 \lsdlocked0 Light Grid;\lsdpriority63 \lsdlocked0 Medium Shading 1;\lsdpriority64 \lsdlocked0 Medium Shading 2;\lsdpriority65 \lsdlocked0 Medium List 1;\lsdpriority66 \lsdlocked0 Medium List 2; \lsdpriority67 \lsdlocked0 Medium Grid 1;\lsdpriority68 \lsdlocked0 Medium Grid 2;\lsdpriority69 \lsdlocked0 Medium Grid 3;\lsdpriority70 \lsdlocked0 Dark List;\lsdpriority71 \lsdlocked0 Colorful Shading;\lsdpriority72 \lsdlocked0 Colorful List; \lsdpriority73 \lsdlocked0 Colorful Grid;\lsdpriority60 \lsdlocked0 Light Shading Accent 1;\lsdpriority61 \lsdlocked0 Light List Accent 1;\lsdpriority62 \lsdlocked0 Light Grid Accent 1;\lsdpriority63 \lsdlocked0 Medium Shading 1 Accent 1; \lsdpriority64 \lsdlocked0 Medium Shading 2 Accent 1;\lsdpriority65 \lsdlocked0 Medium List 1 Accent 1;\lsdqformat1 \lsdpriority34 \lsdlocked0 List Paragraph;\lsdqformat1 \lsdpriority29 \lsdlocked0 Quote; \lsdqformat1 \lsdpriority30 \lsdlocked0 Intense Quote;\lsdpriority66 \lsdlocked0 Medium List 2 Accent 1;\lsdpriority67 \lsdlocked0 Medium Grid 1 Accent 1;\lsdpriority68 \lsdlocked0 Medium Grid 2 Accent 1;\lsdpriority69 \lsdlocked0 Medium Grid 3 Accent 1; \lsdpriority70 \lsdlocked0 Dark List Accent 1;\lsdpriority71 \lsdlocked0 Colorful Shading Accent 1;\lsdpriority72 \lsdlocked0 Colorful List Accent 1;\lsdpriority73 \lsdlocked0 Colorful Grid Accent 1;\lsdpriority60 \lsdlocked0 Light Shading Accent 2; \lsdpriority61 \lsdlocked0 Light List Accent 2;\lsdpriority62 \lsdlocked0 Light Grid Accent 2;\lsdpriority63 \lsdlocked0 Medium Shading 1 Accent 2;\lsdpriority64 \lsdlocked0 Medium Shading 2 Accent 2;\lsdpriority65 \lsdlocked0 Medium List 1 Accent 2; \lsdpriority66 \lsdlocked0 Medium List 2 Accent 2;\lsdpriority67 \lsdlocked0 Medium Grid 1 Accent 2;\lsdpriority68 \lsdlocked0 Medium Grid 2 Accent 2;\lsdpriority69 \lsdlocked0 Medium Grid 3 Accent 2;\lsdpriority70 \lsdlocked0 Dark List Accent 2; \lsdpriority71 \lsdlocked0 Colorful Shading Accent 2;\lsdpriority72 \lsdlocked0 Colorful List Accent 2;\lsdpriority73 \lsdlocked0 Colorful Grid Accent 2;\lsdpriority60 \lsdlocked0 Light Shading Accent 3;\lsdpriority61 \lsdlocked0 Light List Accent 3; \lsdpriority62 \lsdlocked0 Light Grid Accent 3;\lsdpriority63 \lsdlocked0 Medium Shading 1 Accent 3;\lsdpriority64 \lsdlocked0 Medium Shading 2 Accent 3;\lsdpriority65 \lsdlocked0 Medium List 1 Accent 3;\lsdpriority66 \lsdlocked0 Medium List 2 Accent 3; \lsdpriority67 \lsdlocked0 Medium Grid 1 Accent 3;\lsdpriority68 \lsdlocked0 Medium Grid 2 Accent 3;\lsdpriority69 \lsdlocked0 Medium Grid 3 Accent 3;\lsdpriority70 \lsdlocked0 Dark List Accent 3;\lsdpriority71 \lsdlocked0 Colorful Shading Accent 3; \lsdpriority72 \lsdlocked0 Colorful List Accent 3;\lsdpriority73 \lsdlocked0 Colorful Grid Accent 3;\lsdpriority60 \lsdlocked0 Light Shading Accent 4;\lsdpriority61 \lsdlocked0 Light List Accent 4;\lsdpriority62 \lsdlocked0 Light Grid Accent 4; \lsdpriority63 \lsdlocked0 Medium Shading 1 Accent 4;\lsdpriority64 \lsdlocked0 Medium Shading 2 Accent 4;\lsdpriority65 \lsdlocked0 Medium List 1 Accent 4;\lsdpriority66 \lsdlocked0 Medium List 2 Accent 4; \lsdpriority67 \lsdlocked0 Medium Grid 1 Accent 4;\lsdpriority68 \lsdlocked0 Medium Grid 2 Accent 4;\lsdpriority69 \lsdlocked0 Medium Grid 3 Accent 4;\lsdpriority70 \lsdlocked0 Dark List Accent 4;\lsdpriority71 \lsdlocked0 Colorful Shading Accent 4; \lsdpriority72 \lsdlocked0 Colorful List Accent 4;\lsdpriority73 \lsdlocked0 Colorful Grid Accent 4;\lsdpriority60 \lsdlocked0 Light Shading Accent 5;\lsdpriority61 \lsdlocked0 Light List Accent 5;\lsdpriority62 \lsdlocked0 Light Grid Accent 5; \lsdpriority63 \lsdlocked0 Medium Shading 1 Accent 5;\lsdpriority64 \lsdlocked0 Medium Shading 2 Accent 5;\lsdpriority65 \lsdlocked0 Medium List 1 Accent 5;\lsdpriority66 \lsdlocked0 Medium List 2 Accent 5; \lsdpriority67 \lsdlocked0 Medium Grid 1 Accent 5;\lsdpriority68 \lsdlocked0 Medium Grid 2 Accent 5;\lsdpriority69 \lsdlocked0 Medium Grid 3 Accent 5;\lsdpriority70 \lsdlocked0 Dark List Accent 5;\lsdpriority71 \lsdlocked0 Colorful Shading Accent 5; \lsdpriority72 \lsdlocked0 Colorful List Accent 5;\lsdpriority73 \lsdlocked0 Colorful Grid Accent 5;\lsdpriority60 \lsdlocked0 Light Shading Accent 6;\lsdpriority61 \lsdlocked0 Light List Accent 6;\lsdpriority62 \lsdlocked0 Light Grid Accent 6; \lsdpriority63 \lsdlocked0 Medium Shading 1 Accent 6;\lsdpriority64 \lsdlocked0 Medium Shading 2 Accent 6;\lsdpriority65 \lsdlocked0 Medium List 1 Accent 6;\lsdpriority66 \lsdlocked0 Medium List 2 Accent 6; \lsdpriority67 \lsdlocked0 Medium Grid 1 Accent 6;\lsdpriority68 \lsdlocked0 Medium Grid 2 Accent 6;\lsdpriority69 \lsdlocked0 Medium Grid 3 Accent 6;\lsdpriority70 \lsdlocked0 Dark List Accent 6;\lsdpriority71 \lsdlocked0 Colorful Shading Accent 6; \lsdpriority72 \lsdlocked0 Colorful List Accent 6;\lsdpriority73 \lsdlocked0 Colorful Grid Accent 6;\lsdqformat1 \lsdpriority19 \lsdlocked0 Subtle Emphasis;\lsdqformat1 \lsdpriority21 \lsdlocked0 Intense Emphasis; \lsdqformat1 \lsdpriority31 \lsdlocked0 Subtle Reference;\lsdqformat1 \lsdpriority32 \lsdlocked0 Intense Reference;\lsdqformat1 \lsdpriority33 \lsdlocked0 Book Title;\lsdsemihidden1 \lsdunhideused1 \lsdpriority37 \lsdlocked0 Bibliography; \lsdsemihidden1 \lsdunhideused1 \lsdqformat1 \lsdpriority39 \lsdlocked0 TOC Heading;\lsdpriority41 \lsdlocked0 Plain Table 1;\lsdpriority42 \lsdlocked0 Plain Table 2;\lsdpriority43 \lsdlocked0 Plain Table 3;\lsdpriority44 \lsdlocked0 Plain Table 4; \lsdpriority45 \lsdlocked0 Plain Table 5;\lsdpriority40 \lsdlocked0 Grid Table Light;\lsdpriority46 \lsdlocked0 Grid Table 1 Light;\lsdpriority47 \lsdlocked0 Grid Table 2;\lsdpriority48 \lsdlocked0 Grid Table 3;\lsdpriority49 \lsdlocked0 Grid Table 4; \lsdpriority50 \lsdlocked0 Grid Table 5 Dark;\lsdpriority51 \lsdlocked0 Grid Table 6 Colorful;\lsdpriority52 \lsdlocked0 Grid Table 7 Colorful;\lsdpriority46 \lsdlocked0 Grid Table 1 Light Accent 1;\lsdpriority47 \lsdlocked0 Grid Table 2 Accent 1; \lsdpriority48 \lsdlocked0 Grid Table 3 Accent 1;\lsdpriority49 \lsdlocked0 Grid Table 4 Accent 1;\lsdpriority50 \lsdlocked0 Grid Table 5 Dark Accent 1;\lsdpriority51 \lsdlocked0 Grid Table 6 Colorful Accent 1; \lsdpriority52 \lsdlocked0 Grid Table 7 Colorful Accent 1;\lsdpriority46 \lsdlocked0 Grid Table 1 Light Accent 2;\lsdpriority47 \lsdlocked0 Grid Table 2 Accent 2;\lsdpriority48 \lsdlocked0 Grid Table 3 Accent 2; \lsdpriority49 \lsdlocked0 Grid Table 4 Accent 2;\lsdpriority50 \lsdlocked0 Grid Table 5 Dark Accent 2;\lsdpriority51 \lsdlocked0 Grid Table 6 Colorful Accent 2;\lsdpriority52 \lsdlocked0 Grid Table 7 Colorful Accent 2; \lsdpriority46 \lsdlocked0 Grid Table 1 Light Accent 3;\lsdpriority47 \lsdlocked0 Grid Table 2 Accent 3;\lsdpriority48 \lsdlocked0 Grid Table 3 Accent 3;\lsdpriority49 \lsdlocked0 Grid Table 4 Accent 3; \lsdpriority50 \lsdlocked0 Grid Table 5 Dark Accent 3;\lsdpriority51 \lsdlocked0 Grid Table 6 Colorful Accent 3;\lsdpriority52 \lsdlocked0 Grid Table 7 Colorful Accent 3;\lsdpriority46 \lsdlocked0 Grid Table 1 Light Accent 4; \lsdpriority47 \lsdlocked0 Grid Table 2 Accent 4;\lsdpriority48 \lsdlocked0 Grid Table 3 Accent 4;\lsdpriority49 \lsdlocked0 Grid Table 4 Accent 4;\lsdpriority50 \lsdlocked0 Grid Table 5 Dark Accent 4; \lsdpriority51 \lsdlocked0 Grid Table 6 Colorful Accent 4;\lsdpriority52 \lsdlocked0 Grid Table 7 Colorful Accent 4;\lsdpriority46 \lsdlocked0 Grid Table 1 Light Accent 5;\lsdpriority47 \lsdlocked0 Grid Table 2 Accent 5; \lsdpriority48 \lsdlocked0 Grid Table 3 Accent 5;\lsdpriority49 \lsdlocked0 Grid Table 4 Accent 5;\lsdpriority50 \lsdlocked0 Grid Table 5 Dark Accent 5;\lsdpriority51 \lsdlocked0 Grid Table 6 Colorful Accent 5; \lsdpriority52 \lsdlocked0 Grid Table 7 Colorful Accent 5;\lsdpriority46 \lsdlocked0 Grid Table 1 Light Accent 6;\lsdpriority47 \lsdlocked0 Grid Table 2 Accent 6;\lsdpriority48 \lsdlocked0 Grid Table 3 Accent 6; \lsdpriority49 \lsdlocked0 Grid Table 4 Accent 6;\lsdpriority50 \lsdlocked0 Grid Table 5 Dark Accent 6;\lsdpriority51 \lsdlocked0 Grid Table 6 Colorful Accent 6;\lsdpriority52 \lsdlocked0 Grid Table 7 Colorful Accent 6; \lsdpriority46 \lsdlocked0 List Table 1 Light;\lsdpriority47 \lsdlocked0 List Table 2;\lsdpriority48 \lsdlocked0 List Table 3;\lsdpriority49 \lsdlocked0 List Table 4;\lsdpriority50 \lsdlocked0 List Table 5 Dark; \lsdpriority51 \lsdlocked0 List Table 6 Colorful;\lsdpriority52 \lsdlocked0 List Table 7 Colorful;\lsdpriority46 \lsdlocked0 List Table 1 Light Accent 1;\lsdpriority47 \lsdlocked0 List Table 2 Accent 1;\lsdpriority48 \lsdlocked0 List Table 3 Accent 1; \lsdpriority49 \lsdlocked0 List Table 4 Accent 1;\lsdpriority50 \lsdlocked0 List Table 5 Dark Accent 1;\lsdpriority51 \lsdlocked0 List Table 6 Colorful Accent 1;\lsdpriority52 \lsdlocked0 List Table 7 Colorful Accent 1; \lsdpriority46 \lsdlocked0 List Table 1 Light Accent 2;\lsdpriority47 \lsdlocked0 List Table 2 Accent 2;\lsdpriority48 \lsdlocked0 List Table 3 Accent 2;\lsdpriority49 \lsdlocked0 List Table 4 Accent 2; \lsdpriority50 \lsdlocked0 List Table 5 Dark Accent 2;\lsdpriority51 \lsdlocked0 List Table 6 Colorful Accent 2;\lsdpriority52 \lsdlocked0 List Table 7 Colorful Accent 2;\lsdpriority46 \lsdlocked0 List Table 1 Light Accent 3; \lsdpriority47 \lsdlocked0 List Table 2 Accent 3;\lsdpriority48 \lsdlocked0 List Table 3 Accent 3;\lsdpriority49 \lsdlocked0 List Table 4 Accent 3;\lsdpriority50 \lsdlocked0 List Table 5 Dark Accent 3; \lsdpriority51 \lsdlocked0 List Table 6 Colorful Accent 3;\lsdpriority52 \lsdlocked0 List Table 7 Colorful Accent 3;\lsdpriority46 \lsdlocked0 List Table 1 Light Accent 4;\lsdpriority47 \lsdlocked0 List Table 2 Accent 4; \lsdpriority48 \lsdlocked0 List Table 3 Accent 4;\lsdpriority49 \lsdlocked0 List Table 4 Accent 4;\lsdpriority50 \lsdlocked0 List Table 5 Dark Accent 4;\lsdpriority51 \lsdlocked0 List Table 6 Colorful Accent 4; \lsdpriority52 \lsdlocked0 List Table 7 Colorful Accent 4;\lsdpriority46 \lsdlocked0 List Table 1 Light Accent 5;\lsdpriority47 \lsdlocked0 List Table 2 Accent 5;\lsdpriority48 \lsdlocked0 List Table 3 Accent 5; \lsdpriority49 \lsdlocked0 List Table 4 Accent 5;\lsdpriority50 \lsdlocked0 List Table 5 Dark Accent 5;\lsdpriority51 \lsdlocked0 List Table 6 Colorful Accent 5;\lsdpriority52 \lsdlocked0 List Table 7 Colorful Accent 5; \lsdpriority46 \lsdlocked0 List Table 1 Light Accent 6;\lsdpriority47 \lsdlocked0 List Table 2 Accent 6;\lsdpriority48 \lsdlocked0 List Table 3 Accent 6;\lsdpriority49 \lsdlocked0 List Table 4 Accent 6; \lsdpriority50 \lsdlocked0 List Table 5 Dark Accent 6;\lsdpriority51 \lsdlocked0 List Table 6 Colorful Accent 6;\lsdpriority52 \lsdlocked0 List Table 7 Colorful Accent 6;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Mention; \lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Smart Hyperlink;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Hashtag;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Unresolved Mention;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Smart Link;}}{\*\datastore 01050000 02000000180000004d73786d6c322e534158584d4c5265616465722e362e30000000000000000000000e0000 d0cf11e0a1b11ae1000000000000000000000000000000003e000300feff0900060000000000000000000000010000000100000000000000001000000200000001000000feffffff0000000000000000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff fffffffffffffffffdffffff04000000feffffff05000000fefffffffeffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffff52006f006f007400200045006e00740072007900000000000000000000000000000000000000000000000000000000000000000000000000000000000000000016000500ffffffffffffffff010000000c6ad98892f1d411a65f0040963251e500000000000000000000000010b7 95c29bd4d70103000000c0020000000000004d0073006f004400610074006100530074006f0072006500000000000000000000000000000000000000000000000000000000000000000000000000000000001a000101ffffffffffffffff02000000000000000000000000000000000000000000000010b795c29bd4d701 10b795c29bd4d70100000000000000000000000056003500d00049004400d00043003000ce00c400da0045004f004b0057004c004f0051004400d7003300c0003d003d000000000000000000000000000000000032000101ffffffffffffffff03000000000000000000000000000000000000000000000010b795c29bd4 d70110b795c29bd4d7010000000000000000000000004900740065006d0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000a000201ffffffff04000000ffffffff000000000000000000000000000000000000000000000000 000000000000000000000000000000000e0100000000000001000000020000000300000004000000feffffff060000000700000008000000090000000a000000feffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff3c3f786d6c2076657273696f6e3d22312e302220656e636f64696e673d225554462d3822207374616e64616c6f6e653d226e6f223f3e3c623a536f75726365732053656c65637465645374796c653d225c4150412e58534c22205374796c 654e616d653d224150412220786d6c6e733a623d22687474703a2f2f736368656d61732e6f70656e786d6c666f726d6174732e6f72672f6f6666696365446f63756d656e742f323030362f6269626c696f6772617068792220786d6c6e733d22687474703a2f2f736368656d61732e6f70656e786d6c666f726d6174732e 6f72672f6f6666696365446f63756d656e742f323030362f6269626c696f677261706879223e3c2f623a536f75726365733e00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003c3f786d6c2076657273696f6e3d22312e302220656e636f6469 6e673d225554462d3822207374616e64616c6f6e653d226e6f223f3e0d0a3c64733a6461746173746f72654974656d2064733a6974656d49443d227b30463038464335352d394130302d344542412d383433382d4135384233393030463737367d2220786d6c6e733a64733d22687474703a2f2f736368656d61732e6f70 656e786d6c666f726d6174732e6f72672f6f6666696365446f63756d656e742f323030362f637573500072006f007000650072007400690065007300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000016000200ffffffffffffffffffffffff000000000000 0000000000000000000000000000000000000000000000000000000000000500000055010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ffffffffffffffffffffffff00000000 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ffffffffffffffffffffffff0000 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ffffffffffffffffffffffff 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000746f6d586d6c223e3c64733a736368656d61526566733e3c64733a736368656d615265662064733a7572693d22687474703a2f2f736368656d61732e6f70656e786d6c666f726d6174732e6f7267 2f6f6666696365446f63756d656e742f323030362f6269626c696f677261706879222f3e3c2f64733a736368656d61526566733e3c2f64733a6461746173746f72654974656d3e00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000105000000000000}} ================================================ FILE: twaincs/source/TWAIN.cs ================================================ /////////////////////////////////////////////////////////////////////////////////////// // // TwainWorkingGroup.TWAIN // // This is a wrapper class for basic TWAIN functionality. It establishes // behavior that every application should adhere to. It also hides OS // specific details, so that toolkits or applications can use one unified // interface to TWAIN. // /////////////////////////////////////////////////////////////////////////////////////// // Author Date TWAIN Comment // M.McLaughlin 17-May-2021 2.5.0.0 Updated to latest spec // M.McLaughlin 13-Mar-2019 2.4.0.3 Add language code page support for strings // M.McLaughlin 13-Nov-2015 2.4.0.0 Updated to latest spec // M.McLaughlin 13-Sep-2015 2.3.1.2 DsmMem bug fixes // M.McLaughlin 26-Aug-2015 2.3.1.1 Log fix and sync with TWAIN Direct // M.McLaughlin 13-Mar-2015 2.3.1.0 Numerous fixes // M.McLaughlin 13-Oct-2014 2.3.0.4 Added logging // M.McLaughlin 24-Jun-2014 2.3.0.3 Stability fixes // M.McLaughlin 21-May-2014 2.3.0.2 64-Bit Linux // M.McLaughlin 27-Feb-2014 2.3.0.1 AnyCPU support // M.McLaughlin 21-Oct-2013 2.3.0.0 Initial Release /////////////////////////////////////////////////////////////////////////////////////// // Copyright (C) 2013-2021 Kodak Alaris Inc. // // Permission is hereby granted, free of charge, to any person obtaining a // copy of this software and associated documentation files (the "Software"), // to deal in the Software without restriction, including without limitation // the rights to use, copy, modify, merge, publish, distribute, sublicense, // and/or sell copies of the Software, and to permit persons to whom the // Software is furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL // THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER // DEALINGS IN THE SOFTWARE. /////////////////////////////////////////////////////////////////////////////////////// using System; using System.Diagnostics; using System.Diagnostics.CodeAnalysis; using System.Drawing; using System.Globalization; using System.IO; using System.Runtime.InteropServices; using System.Security.Permissions; using System.Threading; namespace TWAINWorkingGroup { /// /// This is the base TWAIN class. It's versioned so that developers can /// safely make a reference to it, if they don't want to actually include /// the TWAIN modules in their project. /// /// Here are the goals of this class: /// /// - Make the interface better than raw TWAIN (like with C/C++), but don't /// go as far as making a toolkit. Expose as much of TWAIN as possible. /// Part of this involves making a CSV interface to abstract away some of /// the pain of the C/C++ structures, especially TW_CAPABILITY. /// /// - Use type checking wherever possible. This is why the TWAIN contants /// tend to be enumerations and why there are multiple entry points into /// the DSM_Entry function. /// /// - Avoid unsafe code. We use marshalling, and we're forced to use some /// unmanaged memory, but that's it. /// /// - Run thread safe. Force as many TWAIN calls into a single thread as /// possible. The main exceptions are MSG_PROCESSEVENT and any of the /// calls that unwind the state machine (ex: MSG_DISABLEDS). Otherwise /// all of the calls are serialized through a single thread. /// /// - Avoid use of System.Windows content, so that the TWAIN assembly can be /// used as broadly as possible (specifically with Mono). /// /// - Support all platforms. The code currently works on 32-bit and 64-bit /// Windows. It's been tested on 32-bit Linux and Mac OS X (using Mono). /// It should work as 64-bit on those platforms. We're also supporting /// both TWAIN_32.DLL and TWAINDSM.DLL on Windows, and we'll support both /// TWAIN.framework and a TWAINDSM.framework (whenever it gets created). /// /// - Virtualiaze all public functions so that developers can extended the /// class with a minimum of fuss. /// public partial class TWAIN : IDisposable { /////////////////////////////////////////////////////////////////////////////// // Public Functions, these are the essentials... /////////////////////////////////////////////////////////////////////////////// #region Public Functions... /// /// Our constructor... /// /// Application manufacturer /// Application product family /// Name of the application /// TWAIN protocol major (doesn't have to match TWAINH.CS) /// TWAIN protocol minor (doesn't have to match TWAINH.CS) /// Bitmask of DG_ flags /// Country code for the application /// Info about the application /// Language code for the application /// Application's major version /// Application's minor version /// Use the legacy DSM (like TWAIN_32.DLL) /// Use callbacks instead of Windows post message /// Function to receive device events /// Function to handle scanning /// Help us run in the GUI thread on Windows /// window handle [PermissionSet(SecurityAction.LinkDemand, Name = "FullTrust", Unrestricted = false)] public TWAIN ( string a_szManufacturer, string a_szProductFamily, string a_szProductName, ushort a_u16ProtocolMajor, ushort a_u16ProtocolMinor, uint a_u32SupportedGroups, TWCY a_twcy, string a_szInfo, TWLG a_twlg, ushort a_u16MajorNum, ushort a_u16MinorNum, bool a_blUseLegacyDSM, bool a_blUseCallbacks, DeviceEventCallback a_deviceeventback, ScanCallback a_scancallback, RunInUiThreadDelegate a_runinuithreaddelegate, IntPtr a_intptrHwnd ) { TW_IDENTITY twidentity; // Since we're using P/Invoke in this sample, the DLL // is implicitly loaded as we access it, so we can // never go lower than state 2... m_state = STATE.S2; // Register the caller's info... twidentity = default(TW_IDENTITY); twidentity.Manufacturer.Set(a_szManufacturer); twidentity.ProductFamily.Set(a_szProductFamily); twidentity.ProductName.Set(a_szProductName); twidentity.ProtocolMajor = a_u16ProtocolMajor; twidentity.ProtocolMinor = a_u16ProtocolMinor; twidentity.SupportedGroups = a_u32SupportedGroups; twidentity.Version.Country = a_twcy; twidentity.Version.Info.Set(a_szInfo); twidentity.Version.Language = a_twlg; twidentity.Version.MajorNum = a_u16MajorNum; twidentity.Version.MinorNum = a_u16MinorNum; m_twidentityApp = twidentity; m_twidentitylegacyApp = TwidentityToTwidentitylegacy(twidentity); m_twidentitymacosxApp = TwidentityToTwidentitymacosx(twidentity); m_deviceeventcallback = a_deviceeventback; m_scancallback = a_scancallback; m_runinuithreaddelegate = a_runinuithreaddelegate; m_intptrHwnd = a_intptrHwnd; // Help for RunInUiThread... m_threaddataDatAudiofilexfer = default(ThreadData); m_threaddataDatAudionativexfer = default(ThreadData); m_threaddataDatCapability = default(ThreadData); m_threaddataDatEvent = default(ThreadData); m_threaddataDatExtimageinfo = default(ThreadData); m_threaddataDatIdentity = default(ThreadData); m_threaddataDatImagefilexfer = default(ThreadData); m_threaddataDatImageinfo = default(ThreadData); m_threaddataDatImagelayout = default(ThreadData); m_threaddataDatImagememfilexfer = default(ThreadData); m_threaddataDatImagememxfer = default(ThreadData); m_threaddataDatImagenativexfer = default(ThreadData); m_threaddataDatParent = default(ThreadData); m_threaddataDatPendingxfers = default(ThreadData); m_threaddataDatSetupfilexfer = default(ThreadData); m_threaddataDatSetupmemxfer = default(ThreadData); m_threaddataDatStatus = default(ThreadData); m_threaddataDatUserinterface = default(ThreadData); // We always go through a discovery process, even on 32-bit... m_linuxdsm = LinuxDsm.Unknown; // Placeholder for our DS identity... m_twidentityDs = default(TW_IDENTITY); m_twidentitylegacyDs = default(TW_IDENTITY_LEGACY); m_twidentitymacosxDs = default(TW_IDENTITY_MACOSX); // We'll normally do an automatic get of DAT.STATUS, but if we'd // like to turn it off, this is the variable to hit... m_blAutoDatStatus = true; // Our helper functions from the DSM... m_twentrypointdelegates = default(TW_ENTRYPOINT_DELEGATES); // Our events... m_autoreseteventCaller = new AutoResetEvent(false); m_autoreseteventThread = new AutoResetEvent(false); m_autoreseteventRollback = new AutoResetEvent(false); m_autoreseteventThreadStarted = new AutoResetEvent(false); m_lockTwain = new Object(); // Windows only... if (ms_platform == Platform.WINDOWS) { m_blUseLegacyDSM = a_blUseLegacyDSM; m_blUseCallbacks = a_blUseCallbacks; m_windowsdsmentrycontrolcallbackdelegate = WindowsDsmEntryCallbackProxy; } // Linux only... else if (ms_platform == Platform.LINUX) { // The user can't set these value, we have to decide automatically // which DSM to use, and only callbacks are supported... m_blUseLegacyDSM = false; m_blUseCallbacks = true; m_linuxdsmentrycontrolcallbackdelegate = LinuxDsmEntryCallbackProxy; // We assume the new DSM for 32-bit systems... if (GetMachineWordBitSize() == 32) { m_blFound020302Dsm64bit = false; if (File.Exists("/usr/local/lib64/libtwaindsm.so")) { m_blFoundLatestDsm64 = true; } if (File.Exists("/usr/local/lib/libtwaindsm.so")) { m_blFoundLatestDsm = true; } } // Check for the old DSM, but only on 64-bit systems... if ((GetMachineWordBitSize() == 64) && File.Exists("/usr/local/lib/libtwaindsm.so.2.3.2")) { m_blFound020302Dsm64bit = true; } // Check for any newer DSM, but only on 64-bit systems... if ((GetMachineWordBitSize() == 64) && (File.Exists("/usr/local/lib/libtwaindsm.so") || File.Exists("/usr/local/lib64/libtwaindsm.so"))) { bool blCheckForNewDsm = true; // Get the DSMs by their fully decorated names... string[] aszDsm = Directory.GetFiles("/usr/local/lib64", "libtwaindsm.so.*.*.*"); if (aszDsm.Length == 0) { aszDsm = Directory.GetFiles("/usr/local/lib", "libtwaindsm.so.*.*.*"); } if ((aszDsm != null) && (aszDsm.Length > 0)) { // Check each name, we only want to launch the process if // we find an old DSM... foreach (string szDsm in aszDsm) { if ( szDsm.EndsWith("so.2.0") || szDsm.Contains(".so.2.0.") || szDsm.EndsWith("so.2.1") || szDsm.Contains(".so.2.1.") || szDsm.EndsWith("so.2.2") || szDsm.Contains(".so.2.2.") || szDsm.EndsWith("so.2.3") || szDsm.Contains(".so.2.3.")) { // If we get a match, see if the symbolic link is // pointing to old junk... Process p = new Process(); p.StartInfo.UseShellExecute = false; p.StartInfo.RedirectStandardOutput = true; p.StartInfo.FileName = "readlink"; p.StartInfo.Arguments = "-e /usr/local/lib/libtwaindsm.so"; p.Start(); string szOutput = p.StandardOutput.ReadToEnd(); p.WaitForExit(); p.Dispose(); // We never did any 1.x stuff... if ( (szOutput != null) && (szOutput.EndsWith(".so.2.0") || szOutput.Contains(".so.2.0.") || szOutput.EndsWith(".so.2.1") || szOutput.Contains(".so.2.1.") || szOutput.EndsWith(".so.2.2") || szOutput.Contains(".so.2.2.") || szOutput.EndsWith(".so.2.3") || szOutput.Contains(".so.2.3."))) { // libtwaindsm.so is pointing to an old DSM... blCheckForNewDsm = false; } break; } } } // Is the symbolic link pointing to a new DSM? if (blCheckForNewDsm && (aszDsm != null) && (aszDsm.Length > 0)) { foreach (string szDsm in aszDsm) { // I guess this is reasonably future-proof... if ( szDsm.Contains("so.2.4") || szDsm.Contains("so.2.5") || szDsm.Contains("so.2.6") || szDsm.Contains("so.2.7") || szDsm.Contains("so.2.8") || szDsm.Contains("so.2.9") || szDsm.Contains("so.2.10") || szDsm.Contains("so.2.11") || szDsm.Contains("so.2.12") || szDsm.Contains("so.2.13") || szDsm.Contains("so.2.14") || szDsm.Contains("so.3") || szDsm.Contains("so.4")) { // libtwaindsm.so is pointing to a new DSM... if (szDsm.Contains("lib64")) { m_blFoundLatestDsm64 = true; } else { m_blFoundLatestDsm = true; } break; } } } } } // Mac OS X only... else if (ms_platform == Platform.MACOSX) { m_blUseLegacyDSM = a_blUseLegacyDSM; m_blUseCallbacks = true; m_macosxdsmentrycontrolcallbackdelegate = MacosxDsmEntryCallbackProxy; } // Uh-oh, Log will throw an exception for us... else { TWAINWorkingGroup.Log.Assert("Unsupported platform..." + ms_platform); } // Activate our thread... /* if (m_threadTwain == null) { m_twaincommand = new TwainCommand(); m_threadTwain = new Thread(Main); m_threadTwain.Start(); if (!m_autoreseteventThreadStarted.WaitOne(5000)) { try { m_threadTwain.Abort(); m_threadTwain = null; } catch (Exception exception) { // Log will throw an exception for us... TWAINWorkingGroup.Log.Assert("Failed to start the TWAIN background thread - " + exception.Message); } } } */ } /// /// Cleanup... /// [SuppressMessage("Microsoft.Security", "CA2123:OverrideLinkDemandsShouldBeIdenticalToBase")] [SecurityPermissionAttribute(SecurityAction.LinkDemand, Flags = SecurityPermissionFlag.UnmanagedCode)] public void Dispose() { Dispose(true); GC.SuppressFinalize(this); } /// /// Report the path to the DSM we're using... /// /// full path to the DSM public string GetDsmPath() { string szDsmPath = ""; // Windows... if (ms_platform == Platform.WINDOWS) { if (m_blUseLegacyDSM) { szDsmPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Windows), "twain_32.dll"); } else { szDsmPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.System), "twaindsm.dll"); } } // Linux... else if (ms_platform == Platform.LINUX) { if (m_blFoundLatestDsm64 && (m_linuxdsm == LinuxDsm.IsLatestDsm)) { szDsmPath = "/usr/local/lib64/libtwaindsm.so"; } else if (m_blFoundLatestDsm && (m_linuxdsm == LinuxDsm.IsLatestDsm)) { szDsmPath = "/usr/local/lib/libtwaindsm.so"; } else if (m_blFound020302Dsm64bit && (m_linuxdsm == LinuxDsm.Is020302Dsm64bit)) { szDsmPath = "/usr/local/lib/libtwaindsm.so.2.3.2"; } } // Mac OS X, which has to be different... else if (ms_platform == Platform.MACOSX) { if (m_blUseLegacyDSM) { szDsmPath = "/System/Library/Frameworks/TWAIN.framework/TWAIN"; } else { szDsmPath = "/Library/Frameworks/TWAIN.framework/TWAIN"; } } // If found... if (File.Exists(szDsmPath)) { return (szDsmPath); } // Ruh-roh... if (string.IsNullOrEmpty(szDsmPath)) { return ("(could not identify a DSM candidate for this platform - '" + ms_platform + "')"); } // Hmmm... return ("(could not find '" + szDsmPath + "')"); } /// /// Get the identity of the current application... /// /// public string GetAppIdentity() { return (IdentityToCsv(m_twidentityApp)); } /// /// Get the identity of the current driver, if we have one... /// /// public string GetDsIdentity() { if (m_state < STATE.S4) { return (IdentityToCsv(default(TW_IDENTITY))); } return (IdentityToCsv(m_twidentityDs)); } /// /// Alloc memory used with the data source. /// /// Number of bytes to allocate /// Point to memory [PermissionSet(SecurityAction.LinkDemand, Name = "FullTrust", Unrestricted = false)] public IntPtr DsmMemAlloc(uint a_u32Size, bool a_blForcePointer = false) { IntPtr intptr; // Use the DSM... if ((m_twentrypointdelegates.DSM_MemAllocate != null) && !a_blForcePointer) { intptr = m_twentrypointdelegates.DSM_MemAllocate(a_u32Size); if (intptr == IntPtr.Zero) { TWAINWorkingGroup.Log.Error("DSM_MemAllocate failed..."); } return (intptr); } // Do it ourselves, Windows... if (ms_platform == Platform.WINDOWS) { intptr = (IntPtr)NativeMethods.GlobalAlloc((uint)(a_blForcePointer ? 0x0040 /* GPTR */ : 0x0042 /* GHND */), (UIntPtr)a_u32Size); if (intptr == IntPtr.Zero) { TWAINWorkingGroup.Log.Error("GlobalAlloc failed..."); } return (intptr); } // Do it ourselves, Linux... if (ms_platform == Platform.LINUX) { intptr = Marshal.AllocHGlobal((int)a_u32Size); if (intptr == IntPtr.Zero) { TWAINWorkingGroup.Log.Error("AllocHGlobal failed..."); } return (intptr); } // Do it ourselves, Mac OS X... if (ms_platform == Platform.MACOSX) { IntPtr intptrIndirect = Marshal.AllocHGlobal((int)a_u32Size); if (intptrIndirect == IntPtr.Zero) { TWAINWorkingGroup.Log.Error("AllocHGlobal(indirect) failed..."); return (intptrIndirect); } IntPtr intptrDirect = Marshal.AllocHGlobal(Marshal.SizeOf(intptrIndirect)); if (intptrDirect == IntPtr.Zero) { TWAINWorkingGroup.Log.Error("AllocHGlobal(direct) failed..."); return (intptrDirect); } Marshal.StructureToPtr(intptrIndirect, intptrDirect, true); return (intptrDirect); } // Trouble, Log will throw an exception for us... TWAINWorkingGroup.Log.Assert("Unsupported platform..." + ms_platform); return (IntPtr.Zero); } /// /// Free memory used with the data source... /// /// Pointer to free [PermissionSet(SecurityAction.LinkDemand, Name = "FullTrust", Unrestricted = false)] public void DsmMemFree(ref IntPtr a_intptrHandle, bool a_blForcePointer = false) { // Validate... if (a_intptrHandle == IntPtr.Zero) { return; } // Use the DSM... if ((m_twentrypointdelegates.DSM_MemAllocate != null) && !a_blForcePointer) { m_twentrypointdelegates.DSM_MemFree(a_intptrHandle); } // Do it ourselves, Windows... else if (ms_platform == Platform.WINDOWS) { NativeMethods.GlobalFree(a_intptrHandle); } // Do it ourselves, Linux... else if (ms_platform == Platform.LINUX) { Marshal.FreeHGlobal(a_intptrHandle); } // Do it ourselves, Mac OS X... else if (ms_platform == Platform.MACOSX) { // Free the indirect pointer... IntPtr intptr = (IntPtr)Marshal.PtrToStructure(a_intptrHandle, typeof(IntPtr)); if (intptr != IntPtr.Zero) { Marshal.FreeHGlobal(intptr); } // If we free the direct pointer the CLR tells us that we're // freeing something that was never allocated. We're going // to believe it and not do a free. But I'm also leaving this // here as a record of the decision... //Marshal.FreeHGlobal(a_twcapability.hContainer); } // Make sure the variable is cleared... a_intptrHandle = IntPtr.Zero; } /// /// Lock memory used with the data source... /// /// Handle to lock /// Locked pointer [PermissionSet(SecurityAction.LinkDemand, Name = "FullTrust", Unrestricted = false)] public IntPtr DsmMemLock(IntPtr a_intptrHandle) { // Validate... if (a_intptrHandle == IntPtr.Zero) { return (a_intptrHandle); } // Use the DSM... if (m_twentrypointdelegates.DSM_MemLock != null) { return (m_twentrypointdelegates.DSM_MemLock(a_intptrHandle)); } // Do it ourselves, Windows... if (ms_platform == Platform.WINDOWS) { return (NativeMethods.GlobalLock(a_intptrHandle)); } // Do it ourselves, Linux... if (ms_platform == Platform.LINUX) { return (a_intptrHandle); } // Do it ourselves, Mac OS X... if (ms_platform == Platform.MACOSX) { IntPtr intptr = (IntPtr)Marshal.PtrToStructure(a_intptrHandle, typeof(IntPtr)); return (intptr); } // Trouble, Log will throw an exception for us... TWAINWorkingGroup.Log.Assert("Unsupported platform..." + ms_platform); return (IntPtr.Zero); } /// /// Unlock memory used with the data source... /// /// Handle to unlock [PermissionSet(SecurityAction.LinkDemand, Name = "FullTrust", Unrestricted = false)] public void DsmMemUnlock(IntPtr a_intptrHandle) { // Validate... if (a_intptrHandle == IntPtr.Zero) { return; } // Use the DSM... if (m_twentrypointdelegates.DSM_MemUnlock != null) { m_twentrypointdelegates.DSM_MemUnlock(a_intptrHandle); return; } // Do it ourselves, Windows... if (ms_platform == Platform.WINDOWS) { NativeMethods.GlobalUnlock(a_intptrHandle); return; } // Do it ourselves, Linux... if (ms_platform == Platform.LINUX) { return; } // Do it ourselves, Mac OS X... if (ms_platform == Platform.MACOSX) { return; } // Trouble, Log will throw an exception for us... TWAINWorkingGroup.Log.Assert("Unsupported platform..." + ms_platform); } /// /// Report the current TWAIN state as we understand it... /// /// The current TWAIN state for the application public STATE GetState() { return (m_state); } /// /// True if the DSM has the DSM2 flag set... /// /// True if we detect the TWAIN Working Group open source DSM public bool IsDsm2() { // Windows... if (ms_platform == Platform.WINDOWS) { return ((m_twidentitylegacyApp.SupportedGroups & (uint)DG.DSM2) != 0); } // Linux... if (ms_platform == Platform.LINUX) { return ((m_twidentitylegacyApp.SupportedGroups & (uint)DG.DSM2) != 0); } // Mac OS X... if (ms_platform == Platform.MACOSX) { return ((m_twidentitymacosxApp.SupportedGroups & (uint)DG.DSM2) != 0); } // Trouble, Log will throw an exception for us... TWAINWorkingGroup.Log.Assert("Unsupported platform..." + ms_platform); return (false); } /// /// Have we seen the first image since MSG.ENABLEDS? /// /// True if the driver is ready to transfer images public bool IsMsgXferReady() { return (m_blIsMsgxferready); } /// /// Has the cancel button been pressed since the last MSG.ENABLEDS? /// /// True if the cancel button was pressed public bool IsMsgCloseDsReq() { return (m_blIsMsgclosedsreq); } /// /// Has the OK button been pressed since the last MSG.ENABLEDS? /// /// True if the OK button was pressed public bool IsMsgCloseDsOk() { return (m_blIsMsgclosedsok); } /// /// Monitor for DAT.NULL / MSG.* stuff... /// /// Window handle that we're monitoring /// A message /// a parameter for the message /// another parameter for the message /// [PermissionSet(SecurityAction.LinkDemand, Name = "FullTrust", Unrestricted = false)] public bool PreFilterMessage ( IntPtr a_intptrHwnd, int a_iMsg, IntPtr a_intptrWparam, IntPtr a_intptrLparam ) { STS sts; MESSAGE msg; // This is only in effect after MSG.ENABLEDS*, or if we are in // the middle of processing DAT_USERINTERFACE. We don't want to // bump to state 5 before processing DAT_USERINTERFACE, but some // drivers are really eager to get going, and throw MSG_XFERREADY // before even get a chance to finish the command... if ((m_state < STATE.S5) && !m_blRunningDatUserinterface) { return (false); } // Convert the data... msg = new MESSAGE(); msg.hwnd = a_intptrHwnd; msg.message = (uint)a_iMsg; msg.wParam = a_intptrWparam; msg.lParam = a_intptrLparam; // Allocate memory that we can give to the driver... if (m_tweventPreFilterMessage.pEvent == IntPtr.Zero) { m_tweventPreFilterMessage.pEvent = Marshal.AllocHGlobal(Marshal.SizeOf(msg) + 65536); } Marshal.StructureToPtr(msg, m_tweventPreFilterMessage.pEvent, true); // See if the driver wants the event... m_tweventPreFilterMessage.TWMessage = 0; sts = DatEvent(DG.CONTROL, MSG.PROCESSEVENT, ref m_tweventPreFilterMessage, true); if ((sts != STS.DSEVENT) && (sts != STS.NOTDSEVENT)) { return (false); } // All done, tell the app we consumed the event if we // got back a status telling us that... return (sts == STS.DSEVENT); } /// /// Rollback the TWAIN state machine to the specified value, with an /// automatic resync if it detects a sequence error... /// /// The TWAIN state that we want to end up at /// Use the thread (most cases) static int s_iCloseDsmDelay = 0; [SecurityPermissionAttribute(SecurityAction.LinkDemand, Flags = SecurityPermissionFlag.UnmanagedCode)] public TWAIN.STATE Rollback(STATE a_stateTarget, bool a_blUseThread = true) { int iRetry; STS sts; STATE stateStart; // Nothing to do here... if (m_state <= STATE.S2) { return (m_state); } // Submit the work to the TWAIN thread... if (a_blUseThread) { if (m_runinuithreaddelegate != null) { lock (m_lockTwain) { // No point in continuing... if (m_twaincommand == null) { return (m_state); } // Set the command variables... ThreadData threaddata = default(ThreadData); threaddata.blExitThread = true; long lIndex = m_twaincommand.Submit(threaddata); // Submit the command and wait for the reply, the delay // is needed because Mac OS X doesn't gracefully handle // the loss of a mutex... s_iCloseDsmDelay = 0; CallerToThreadSet(); ThreadToRollbackWaitOne(); Thread.Sleep(s_iCloseDsmDelay); // Clear the command variables... m_twaincommand.Delete(lIndex); } } else if ((m_threadTwain != null) && (m_threadTwain.ManagedThreadId != Thread.CurrentThread.ManagedThreadId)) { lock (m_lockTwain) { // No point in continuing... if (m_twaincommand == null) { return (m_state); } // Set the command variables... ThreadData threaddata = default(ThreadData); threaddata.stateRollback = a_stateTarget; threaddata.blRollback = true; long lIndex = m_twaincommand.Submit(threaddata); // Submit the command and wait for the reply, the delay // is needed because Mac OS X doesn't gracefully handle // the loss of a mutex... s_iCloseDsmDelay = 0; CallerToThreadSet(); ThreadToRollbackWaitOne(); Thread.Sleep(s_iCloseDsmDelay); // Clear the command variables... m_twaincommand.Delete(lIndex); } return (m_state); } } // If we get a sequence error, then we'll repeat the loop from // the highest possible state to see if we can fix the problem... iRetry = 2; stateStart = GetState(); while (iRetry-- > 0) { // State 7 --> State 6... if ((stateStart >= STATE.S7) && (a_stateTarget < STATE.S7)) { TW_PENDINGXFERS twpendingxfers = default(TW_PENDINGXFERS); sts = DatPendingxfers(DG.CONTROL, MSG.ENDXFER, ref twpendingxfers); if (sts == STS.SEQERROR) { stateStart = STATE.S7; continue; } stateStart = STATE.S6; } // State 6 --> State 5... if ((stateStart >= STATE.S6) && (a_stateTarget < STATE.S6)) { TW_PENDINGXFERS twpendingxfers = default(TW_PENDINGXFERS); sts = DatPendingxfers(DG.CONTROL, MSG.RESET, ref twpendingxfers); if (sts == STS.SEQERROR) { stateStart = STATE.S7; continue; } stateStart = STATE.S5; } // State 5 --> State 4... if ((stateStart >= STATE.S5) && (a_stateTarget < STATE.S5)) { TW_USERINTERFACE twuserinterface = default(TW_USERINTERFACE); sts = DatUserinterface(DG.CONTROL, MSG.DISABLEDS, ref twuserinterface); if (sts == STS.SEQERROR) { stateStart = STATE.S7; continue; } if (m_tweventPreFilterMessage.pEvent != IntPtr.Zero) { Marshal.FreeHGlobal(m_tweventPreFilterMessage.pEvent); m_tweventPreFilterMessage.pEvent = IntPtr.Zero; } stateStart = STATE.S4; m_blAcceptXferReady = false; m_blIsMsgclosedsok = false; m_blIsMsgclosedsreq = false; m_blIsMsgxferready = false; } // State 4 --> State 3... if ((stateStart >= STATE.S4) && (a_stateTarget < STATE.S4)) { sts = DatIdentity(DG.CONTROL, MSG.CLOSEDS, ref m_twidentityDs); if (sts == STS.SEQERROR) { stateStart = STATE.S7; continue; } stateStart = STATE.S3; } // State 3 --> State 2... if ((stateStart >= STATE.S3) && (a_stateTarget < STATE.S3)) { // Do this to prevent a deadlock on Mac OS X, two seconds // better be enough to finish up... if (GetPlatform() == Platform.MACOSX) { ThreadToRollbackSet(); s_iCloseDsmDelay = 2000; } // Now do the rest of it... sts = DatParent(DG.CONTROL, MSG.CLOSEDSM, ref m_intptrHwnd); if (sts == STS.SEQERROR) { stateStart = STATE.S7; continue; } stateStart = STATE.S2; } // All done... break; } // How did we do? return (m_state); } /// /// Send a command to the currently loaded DSM... /// /// tokenized command and anything needed /// true to quit public TWAIN.STS Send(string a_szDg, string a_szDat, string a_szMsg, ref string a_szTwmemref, ref string a_szResult) { int iDg; int iDat; int iMsg; TWAIN.STS sts; TWAIN.DG dg = TWAIN.DG.MASK; TWAIN.DAT dat = TWAIN.DAT.NULL; TWAIN.MSG msg = TWAIN.MSG.NULL; // Init stuff... iDg = 0; iDat = 0; iMsg = 0; sts = TWAIN.STS.BADPROTOCOL; a_szResult = ""; // Look for DG... if (!a_szDg.ToLowerInvariant().StartsWith("dg_")) { TWAINWorkingGroup.Log.Error("Unrecognized dg - <" + a_szDg + ">"); return (TWAIN.STS.BADPROTOCOL); } else { // Look for hex number (take anything)... if (a_szDg.ToLowerInvariant().StartsWith("dg_0x")) { if (!int.TryParse(a_szDg.ToLowerInvariant().Substring(5), NumberStyles.HexNumber, CultureInfo.InvariantCulture, out iDg)) { TWAINWorkingGroup.Log.Error("Badly constructed dg - <" + a_szDg + ">"); return (TWAIN.STS.BADPROTOCOL); } } else { if (!TWAIN.Enum_TryParse(a_szDg.ToUpperInvariant().Substring(3), out dg)) { TWAINWorkingGroup.Log.Error("Unrecognized dg - <" + a_szDg + ">"); return (TWAIN.STS.BADPROTOCOL); } iDg = (int)dg; } } // Look for DAT... if (!a_szDat.ToLowerInvariant().StartsWith("dat_")) { TWAINWorkingGroup.Log.Error("Unrecognized dat - <" + a_szDat + ">"); return (TWAIN.STS.BADPROTOCOL); } else { // Look for hex number (take anything)... if (a_szDat.ToLowerInvariant().StartsWith("dat_0x")) { if (!int.TryParse(a_szDat.ToLowerInvariant().Substring(6), NumberStyles.HexNumber, CultureInfo.InvariantCulture, out iDat)) { TWAINWorkingGroup.Log.Error("Badly constructed dat - <" + a_szDat + ">"); return (TWAIN.STS.BADPROTOCOL); } } else { if (!TWAIN.Enum_TryParse(a_szDat.ToUpperInvariant().Substring(4), out dat)) { TWAINWorkingGroup.Log.Error("Unrecognized dat - <" + a_szDat + ">"); return (TWAIN.STS.BADPROTOCOL); } iDat = (int)dat; } } // Look for MSG... if (!a_szMsg.ToLowerInvariant().StartsWith("msg_")) { TWAINWorkingGroup.Log.Error("Unrecognized msg - <" + a_szMsg + ">"); return (TWAIN.STS.BADPROTOCOL); } else { // Look for hex number (take anything)... if (a_szMsg.ToLowerInvariant().StartsWith("msg_0x")) { if (!int.TryParse(a_szMsg.ToLowerInvariant().Substring(6), NumberStyles.HexNumber, CultureInfo.InvariantCulture, out iMsg)) { TWAINWorkingGroup.Log.Error("Badly constructed dat - <" + a_szMsg + ">"); return (TWAIN.STS.BADPROTOCOL); } } else { if (!TWAIN.Enum_TryParse(a_szMsg.ToUpperInvariant().Substring(4), out msg)) { TWAINWorkingGroup.Log.Error("Unrecognized msg - <" + a_szMsg + ">"); return (TWAIN.STS.BADPROTOCOL); } iMsg = (int)msg; } } // Send the command... switch (iDat) { // Ruh-roh, since we can't marshal it, we have to return an error, // it would be nice to have a solution for this, but that will need // a dynamic marshalling system... default: { Int64 i64Memref; if (!Int64.TryParse(a_szTwmemref, out i64Memref)) { sts = STS.BADPROTOCOL; } else { IntPtr intptrTwmemref = (IntPtr)i64Memref; sts = DsmEntry((DG)iDg, (DAT)iDat, (MSG)iMsg, intptrTwmemref); } } break; // DAT_AUDIOFILEXFER... case (int)TWAIN.DAT.AUDIOFILEXFER: { sts = DatAudiofilexfer((TWAIN.DG)iDg, (TWAIN.MSG)iMsg); a_szTwmemref = ""; } break; // DAT_AUDIOINFO.. case (int)TWAIN.DAT.AUDIOINFO: { TWAIN.TW_AUDIOINFO twaudioinfo = default(TWAIN.TW_AUDIOINFO); sts = DatAudioinfo((TWAIN.DG)iDg, (TWAIN.MSG)iMsg, ref twaudioinfo); a_szTwmemref = AudioinfoToCsv(twaudioinfo); } break; // DAT_AUDIONATIVEXFER.. case (int)TWAIN.DAT.AUDIONATIVEXFER: { IntPtr intptr = IntPtr.Zero; sts = DatAudionativexfer((TWAIN.DG)iDg, (TWAIN.MSG)iMsg, ref intptr); a_szTwmemref = intptr.ToString(); } break; // DAT_CALLBACK... case (int)TWAIN.DAT.CALLBACK: { TWAIN.TW_CALLBACK twcallback = default(TWAIN.TW_CALLBACK); CsvToCallback(ref twcallback, a_szTwmemref); sts = DatCallback((TWAIN.DG)iDg, (TWAIN.MSG)iMsg, ref twcallback); a_szTwmemref = CallbackToCsv(twcallback); } break; // DAT_CALLBACK2... case (int)TWAIN.DAT.CALLBACK2: { TWAIN.TW_CALLBACK2 twcallback2 = default(TWAIN.TW_CALLBACK2); CsvToCallback2(ref twcallback2, a_szTwmemref); sts = DatCallback2((TWAIN.DG)iDg, (TWAIN.MSG)iMsg, ref twcallback2); a_szTwmemref = Callback2ToCsv(twcallback2); } break; // DAT_CAPABILITY... case (int)TWAIN.DAT.CAPABILITY: { // Skip symbols for msg_querysupport, otherwise 0 gets turned into false, also // if the command fails the return value is whatever was sent into us, which // matches the experience one should get with C/C++... string szStatus = ""; TWAIN.TW_CAPABILITY twcapability = default(TWAIN.TW_CAPABILITY); CsvToCapability(ref twcapability, ref szStatus, a_szTwmemref); sts = DatCapability((TWAIN.DG)iDg, (TWAIN.MSG)iMsg, ref twcapability); if ((sts == TWAIN.STS.SUCCESS) || (sts == TWAIN.STS.CHECKSTATUS)) { // Convert the data to CSV... a_szTwmemref = CapabilityToCsv(twcapability, ((TWAIN.MSG)iMsg != TWAIN.MSG.QUERYSUPPORT)); // Free the handle if the driver created it... switch ((TWAIN.MSG)iMsg) { default: break; case TWAIN.MSG.GET: case TWAIN.MSG.GETCURRENT: case TWAIN.MSG.GETDEFAULT: case TWAIN.MSG.QUERYSUPPORT: case TWAIN.MSG.RESET: DsmMemFree(ref twcapability.hContainer); break; } } } break; // DAT_CIECOLOR.. case (int)TWAIN.DAT.CIECOLOR: { //TWAIN.TW_CIECOLOR twciecolor = default(TWAIN.TW_CIECOLOR); //sts = m_twain.DatCiecolor((TWAIN.DG)iDg, (TWAIN.MSG)iMsg, ref twciecolor); //a_szTwmemref = m_twain.CiecolorToCsv(twciecolor); } break; // DAT_CUSTOMDSDATA... case (int)TWAIN.DAT.CUSTOMDSDATA: { TWAIN.TW_CUSTOMDSDATA twcustomdsdata = default(TWAIN.TW_CUSTOMDSDATA); CsvToCustomdsdata(ref twcustomdsdata, a_szTwmemref); sts = DatCustomdsdata((TWAIN.DG)iDg, (TWAIN.MSG)iMsg, ref twcustomdsdata); a_szTwmemref = CustomdsdataToCsv(twcustomdsdata); } break; // DAT_DEVICEEVENT... case (int)TWAIN.DAT.DEVICEEVENT: { TWAIN.TW_DEVICEEVENT twdeviceevent = default(TWAIN.TW_DEVICEEVENT); sts = DatDeviceevent((TWAIN.DG)iDg, (TWAIN.MSG)iMsg, ref twdeviceevent); a_szTwmemref = DeviceeventToCsv(twdeviceevent); } break; // DAT_ENTRYPOINT... case (int)TWAIN.DAT.ENTRYPOINT: { TWAIN.TW_ENTRYPOINT twentrypoint = default(TWAIN.TW_ENTRYPOINT); twentrypoint.Size = (uint)Marshal.SizeOf(twentrypoint); sts = DatEntrypoint((TWAIN.DG)iDg, (TWAIN.MSG)iMsg, ref twentrypoint); a_szTwmemref = EntrypointToCsv(twentrypoint); } break; // DAT_EVENT... case (int)TWAIN.DAT.EVENT: { TWAIN.TW_EVENT twevent = default(TWAIN.TW_EVENT); sts = DatEvent((TWAIN.DG)iDg, (TWAIN.MSG)iMsg, ref twevent); a_szTwmemref = EventToCsv(twevent); } break; // DAT_EXTIMAGEINFO... case (int)TWAIN.DAT.EXTIMAGEINFO: { TWAIN.TW_EXTIMAGEINFO twextimageinfo = default(TWAIN.TW_EXTIMAGEINFO); CsvToExtimageinfo(ref twextimageinfo, a_szTwmemref); sts = DatExtimageinfo((TWAIN.DG)iDg, (TWAIN.MSG)iMsg, ref twextimageinfo); a_szTwmemref = ExtimageinfoToCsv(twextimageinfo); } break; // DAT_FILESYSTEM... case (int)TWAIN.DAT.FILESYSTEM: { TWAIN.TW_FILESYSTEM twfilesystem = default(TWAIN.TW_FILESYSTEM); CsvToFilesystem(ref twfilesystem, a_szTwmemref); sts = DatFilesystem((TWAIN.DG)iDg, (TWAIN.MSG)iMsg, ref twfilesystem); a_szTwmemref = FilesystemToCsv(twfilesystem); } break; // DAT_FILTER... case (int)TWAIN.DAT.FILTER: { //TWAIN.TW_FILTER twfilter = default(TWAIN.TW_FILTER); //m_twain.CsvToFilter(ref twfilter, a_szTwmemref); //sts = m_twain.DatFilter((TWAIN.DG)iDg, (TWAIN.MSG)iMsg, ref twfilter); //a_szTwmemref = m_twain.FilterToCsv(twfilter); } break; // DAT_GRAYRESPONSE... case (int)TWAIN.DAT.GRAYRESPONSE: { //TWAIN.TW_GRAYRESPONSE twgrayresponse = default(TWAIN.TW_GRAYRESPONSE); //m_twain.CsvToGrayresponse(ref twgrayresponse, a_szTwmemref); //sts = m_twain.DatGrayresponse((TWAIN.DG)iDg, (TWAIN.MSG)iMsg, ref twgrayresponse); //a_szTwmemref = m_twain.GrayresponseToCsv(twgrayresponse); } break; // DAT_ICCPROFILE... case (int)TWAIN.DAT.ICCPROFILE: { TWAIN.TW_MEMORY twmemory = default(TWAIN.TW_MEMORY); sts = DatIccprofile((TWAIN.DG)iDg, (TWAIN.MSG)iMsg, ref twmemory); a_szTwmemref = IccprofileToCsv(twmemory); } break; // DAT_IDENTITY... case (int)TWAIN.DAT.IDENTITY: { TWAIN.TW_IDENTITY twidentity = default(TWAIN.TW_IDENTITY); switch (iMsg) { default: break; case (int)TWAIN.MSG.SET: case (int)TWAIN.MSG.OPENDS: CsvToIdentity(ref twidentity, a_szTwmemref); break; } sts = DatIdentity((TWAIN.DG)iDg, (TWAIN.MSG)iMsg, ref twidentity); a_szTwmemref = IdentityToCsv(twidentity); } break; // DAT_IMAGEFILEXFER... case (int)TWAIN.DAT.IMAGEFILEXFER: { sts = DatImagefilexfer((TWAIN.DG)iDg, (TWAIN.MSG)iMsg); a_szTwmemref = ""; } break; // DAT_IMAGEINFO... case (int)TWAIN.DAT.IMAGEINFO: { TWAIN.TW_IMAGEINFO twimageinfo = default(TWAIN.TW_IMAGEINFO); CsvToImageinfo(ref twimageinfo, a_szTwmemref); sts = DatImageinfo((TWAIN.DG)iDg, (TWAIN.MSG)iMsg, ref twimageinfo); a_szTwmemref = ImageinfoToCsv(twimageinfo); } break; // DAT_IMAGELAYOUT... case (int)TWAIN.DAT.IMAGELAYOUT: { TWAIN.TW_IMAGELAYOUT twimagelayout = default(TWAIN.TW_IMAGELAYOUT); CsvToImagelayout(ref twimagelayout, a_szTwmemref); sts = DatImagelayout((TWAIN.DG)iDg, (TWAIN.MSG)iMsg, ref twimagelayout); a_szTwmemref = ImagelayoutToCsv(twimagelayout); } break; // DAT_IMAGEMEMFILEXFER... case (int)TWAIN.DAT.IMAGEMEMFILEXFER: { TWAIN.TW_IMAGEMEMXFER twimagememxfer = default(TWAIN.TW_IMAGEMEMXFER); CsvToImagememxfer(ref twimagememxfer, a_szTwmemref); sts = DatImagememfilexfer((TWAIN.DG)iDg, (TWAIN.MSG)iMsg, ref twimagememxfer); a_szTwmemref = ImagememxferToCsv(twimagememxfer); } break; // DAT_IMAGEMEMXFER... case (int)TWAIN.DAT.IMAGEMEMXFER: { TWAIN.TW_IMAGEMEMXFER twimagememxfer = default(TWAIN.TW_IMAGEMEMXFER); CsvToImagememxfer(ref twimagememxfer, a_szTwmemref); sts = DatImagememxfer((TWAIN.DG)iDg, (TWAIN.MSG)iMsg, ref twimagememxfer); a_szTwmemref = ImagememxferToCsv(twimagememxfer); } break; // DAT_IMAGENATIVEXFER... case (int)TWAIN.DAT.IMAGENATIVEXFER: { IntPtr intptrBitmapHandle = IntPtr.Zero; sts = DatImagenativexferHandle((TWAIN.DG)iDg, (TWAIN.MSG)iMsg, ref intptrBitmapHandle); a_szTwmemref = intptrBitmapHandle.ToString(); } break; // DAT_JPEGCOMPRESSION... case (int)TWAIN.DAT.JPEGCOMPRESSION: { //TWAIN.TW_JPEGCOMPRESSION twjpegcompression = default(TWAIN.TW_JPEGCOMPRESSION); //m_twain.CsvToJpegcompression(ref twjpegcompression, a_szTwmemref); //sts = m_twain.DatJpegcompression((TWAIN.DG)iDg, (TWAIN.MSG)iMsg, ref twjpegcompression); //a_szTwmemref = m_twain.JpegcompressionToCsv(twjpegcompression); } break; // DAT_METRICS... case (int)TWAIN.DAT.METRICS: { TWAIN.TW_METRICS twmetrics = default(TWAIN.TW_METRICS); twmetrics.SizeOf = (uint)Marshal.SizeOf(twmetrics); sts = DatMetrics((TWAIN.DG)iDg, (TWAIN.MSG)iMsg, ref twmetrics); a_szTwmemref = MetricsToCsv(twmetrics); } break; // DAT_PALETTE8... case (int)TWAIN.DAT.PALETTE8: { //TWAIN.TW_PALETTE8 twpalette8 = default(TWAIN.TW_PALETTE8); //m_twain.CsvToPalette8(ref twpalette8, a_szTwmemref); //sts = m_twain.DatPalette8((TWAIN.DG)iDg, (TWAIN.MSG)iMsg, ref twpalette8); //a_szTwmemref = m_twain.Palette8ToCsv(twpalette8); } break; // DAT_PARENT... case (int)TWAIN.DAT.PARENT: { sts = DatParent((TWAIN.DG)iDg, (TWAIN.MSG)iMsg, ref m_intptrHwnd); a_szTwmemref = ""; } break; // DAT_PASSTHRU... case (int)TWAIN.DAT.PASSTHRU: { TWAIN.TW_PASSTHRU twpassthru = default(TWAIN.TW_PASSTHRU); CsvToPassthru(ref twpassthru, a_szTwmemref); sts = DatPassthru((TWAIN.DG)iDg, (TWAIN.MSG)iMsg, ref twpassthru); a_szTwmemref = PassthruToCsv(twpassthru); } break; // DAT_PENDINGXFERS... case (int)TWAIN.DAT.PENDINGXFERS: { TWAIN.TW_PENDINGXFERS twpendingxfers = default(TWAIN.TW_PENDINGXFERS); sts = DatPendingxfers((TWAIN.DG)iDg, (TWAIN.MSG)iMsg, ref twpendingxfers); a_szTwmemref = PendingxfersToCsv(twpendingxfers); } break; // DAT_RGBRESPONSE... case (int)TWAIN.DAT.RGBRESPONSE: { //TWAIN.TW_RGBRESPONSE twrgbresponse = default(TWAIN.TW_RGBRESPONSE); //m_twain.CsvToRgbresponse(ref twrgbresponse, a_szTwmemref); //sts = m_twain.DatRgbresponse((TWAIN.DG)iDg, (TWAIN.MSG)iMsg, ref twrgbresponse); //a_szTwmemref = m_twain.RgbresponseToCsv(twrgbresponse); } break; // DAT_SETUPFILEXFER... case (int)TWAIN.DAT.SETUPFILEXFER: { TWAIN.TW_SETUPFILEXFER twsetupfilexfer = default(TWAIN.TW_SETUPFILEXFER); CsvToSetupfilexfer(ref twsetupfilexfer, a_szTwmemref); sts = DatSetupfilexfer((TWAIN.DG)iDg, (TWAIN.MSG)iMsg, ref twsetupfilexfer); a_szTwmemref = SetupfilexferToCsv(twsetupfilexfer); } break; // DAT_SETUPMEMXFER... case (int)TWAIN.DAT.SETUPMEMXFER: { TWAIN.TW_SETUPMEMXFER twsetupmemxfer = default(TWAIN.TW_SETUPMEMXFER); sts = DatSetupmemxfer((TWAIN.DG)iDg, (TWAIN.MSG)iMsg, ref twsetupmemxfer); a_szTwmemref = SetupmemxferToCsv(twsetupmemxfer); } break; // DAT_STATUS... case (int)TWAIN.DAT.STATUS: { TWAIN.TW_STATUS twstatus = default(TWAIN.TW_STATUS); sts = DatStatus((TWAIN.DG)iDg, (TWAIN.MSG)iMsg, ref twstatus); a_szTwmemref = StatusToCsv(twstatus); } break; // DAT_STATUSUTF8... case (int)TWAIN.DAT.STATUSUTF8: { TWAIN.TW_STATUSUTF8 twstatusutf8 = default(TWAIN.TW_STATUSUTF8); sts = DatStatusutf8((TWAIN.DG)iDg, (TWAIN.MSG)iMsg, ref twstatusutf8); a_szTwmemref = Statusutf8ToCsv(twstatusutf8); } break; // DAT_TWAINDIRECT... case (int)TWAIN.DAT.TWAINDIRECT: { TWAIN.TW_TWAINDIRECT twtwaindirect = default(TWAIN.TW_TWAINDIRECT); CsvToTwaindirect(ref twtwaindirect, a_szTwmemref); sts = DatTwaindirect((TWAIN.DG)iDg, (TWAIN.MSG)iMsg, ref twtwaindirect); a_szTwmemref = TwaindirectToCsv(twtwaindirect); } break; // DAT_USERINTERFACE... case (int)TWAIN.DAT.USERINTERFACE: { TWAIN.TW_USERINTERFACE twuserinterface = default(TWAIN.TW_USERINTERFACE); CsvToUserinterface(ref twuserinterface, a_szTwmemref); sts = DatUserinterface((TWAIN.DG)iDg, (TWAIN.MSG)iMsg, ref twuserinterface); a_szTwmemref = UserinterfaceToCsv(twuserinterface); } break; // DAT_XFERGROUP... case (int)TWAIN.DAT.XFERGROUP: { uint uXferGroup = 0; sts = DatXferGroup((TWAIN.DG)iDg, (TWAIN.MSG)iMsg, ref uXferGroup); a_szTwmemref = string.Format("0x{0:X}", uXferGroup); } break; } // All done... return (sts); } #endregion /////////////////////////////////////////////////////////////////////////////// // Public Helper Functions, we're mapping TWAIN structures to strings to // make it easier for the application to work with the data. All of the // functions that do that are located here... /////////////////////////////////////////////////////////////////////////////// #region Public Helper Functions... /// /// Copy intptr to intptr... /// /// /// /// public static void MemCpy(IntPtr dest, IntPtr src, int count) { if (TWAIN.GetPlatform() == TWAIN.Platform.WINDOWS) { NativeMethods.CopyMemory(dest, src, (uint)count); } else { NativeMethods.memcpy(dest, src, (IntPtr)count); } } /// /// Safely move intptr to intptr... /// /// /// /// public static void MemMove(IntPtr dest, IntPtr src, int count) { if (TWAIN.GetPlatform() == TWAIN.Platform.WINDOWS) { NativeMethods.MoveMemory(dest, src, (uint)count); } else { NativeMethods.memmove(dest, src, (IntPtr)count); } } /// /// Write stuff to a file without having to rebuffer it... /// /// /// /// /// public static int WriteImageFile(string a_szFilename, IntPtr a_intptrPtr, int a_iBytes, out string a_szFinalFilename) { // Init stuff... a_szFinalFilename = ""; // Try to write our file... try { // If we don't have an extension, try to add one... if (!Path.GetFileName(a_szFilename).Contains(".") && (a_iBytes >= 2)) { byte[] abData = new byte[2]; Marshal.Copy(a_intptrPtr, abData, 0, 2); // BMP if ((abData[0] == 0x42) && (abData[1] == 0x4D)) // BM { a_szFilename += ".bmp"; } else if ((abData[0] == 0x49) && (abData[1] == 0x49)) // II { a_szFilename += ".tif"; } else if ((abData[0] == 0xFF) && (abData[1] == 0xD8)) { a_szFilename += ".jpg"; } else if ((abData[0] == 0x25) && (abData[1] == 0x50)) // %P { a_szFilename += ".pdf"; } } // For the caller... a_szFinalFilename = a_szFilename; // Handle Windows... if (TWAIN.GetPlatform() == TWAIN.Platform.WINDOWS) { IntPtr intptrFile; IntPtr intptrBytes = (IntPtr)a_iBytes; IntPtr intptrCount = (IntPtr)1; if (NativeMethods._wfopen_s(out intptrFile, a_szFilename, "wb") != 0) { return (-1); } intptrBytes = NativeMethods.fwriteWin(a_intptrPtr, intptrCount, intptrBytes, intptrFile); NativeMethods.fcloseWin(intptrFile); return ((int)intptrBytes); } // Handle everybody else... else { IntPtr intptrFile; IntPtr intptrBytes; intptrFile = NativeMethods.fopen(a_szFilename, "w"); if (intptrFile == IntPtr.Zero) { return (-1); } intptrBytes = NativeMethods.fwrite(a_intptrPtr, (IntPtr)1, (IntPtr)a_iBytes, intptrFile); NativeMethods.fclose(intptrFile); return ((int)intptrBytes); } } catch (Exception exception) { Log.Error("Write file failed <" + a_szFilename + "> - " + exception.Message); return (-1); } } /// /// Convert the contents of an audio info to a string that we can show in /// our simple GUI... /// /// A TWAIN structure /// A CSV string of the TWAIN structure public static string AudioinfoToCsv(TW_AUDIOINFO a_twaudioinfo) { try { CSV csv = new CSV(); csv.Add(a_twaudioinfo.Name.Get()); csv.Add(a_twaudioinfo.Reserved.ToString()); return (csv.Get()); } catch (Exception exception) { Log.Error("***error*** - " + exception.Message); return ("***error***"); } } /// /// Convert the contents of a callback to a string that we can show in /// our simple GUI... /// /// A TWAIN structure /// A CSV string of the TWAIN structure public static string CallbackToCsv(TW_CALLBACK a_twcallback) { try { CSV csv = new CSV(); csv.Add(a_twcallback.CallBackProc.ToString()); csv.Add(a_twcallback.RefCon.ToString()); csv.Add(a_twcallback.Message.ToString()); return (csv.Get()); } catch (Exception exception) { Log.Error("***error*** - " + exception.Message); return ("***error***"); } } /// /// Convert the contents of a string to an callback structure... /// /// A TWAIN structure /// A CSV string of the TWAIN structure /// True if the conversion is successful public static bool CsvToCallback(ref TW_CALLBACK a_twcallback, string a_szCallback) { // Init stuff... a_twcallback = default(TW_CALLBACK); // Build the string... try { string[] asz = CSV.Parse(a_szCallback); // Grab the values... a_twcallback.CallBackProc = (IntPtr)UInt64.Parse(asz[0]); a_twcallback.RefCon = uint.Parse(asz[1]); a_twcallback.Message = ushort.Parse(asz[2]); } catch (Exception exception) { Log.Error("***error*** - " + exception.Message); return (false); } // All done... return (true); } /// /// Convert the contents of a callback2 to a string that we can show in /// our simple GUI... /// /// A TWAIN structure /// A CSV string of the TWAIN structure public static string Callback2ToCsv(TW_CALLBACK2 a_twcallback2) { try { CSV csv = new CSV(); csv.Add(a_twcallback2.CallBackProc.ToString()); csv.Add(a_twcallback2.RefCon.ToString()); csv.Add(a_twcallback2.Message.ToString()); return (csv.Get()); } catch (Exception exception) { Log.Error("***error*** - " + exception.Message); return ("***error***"); } } /// /// Convert the contents of a string to an callback2 structure... /// /// A TWAIN structure /// A CSV string of the TWAIN structure /// True if the conversion is successful public static bool CsvToCallback2(ref TW_CALLBACK2 a_twcallback2, string a_szCallback2) { // Init stuff... a_twcallback2 = default(TW_CALLBACK2); // Build the string... try { string[] asz = CSV.Parse(a_szCallback2); // Grab the values... a_twcallback2.CallBackProc = (IntPtr)UInt64.Parse(asz[0]); a_twcallback2.RefCon = (UIntPtr)UInt64.Parse(asz[1]); a_twcallback2.Message = ushort.Parse(asz[2]); } catch (Exception exception) { Log.Error("***error*** - " + exception.Message); return (false); } // All done... return (true); } /// /// Convert the contents of a capability to a string that we can show in /// our simple GUI.... /// /// A TWAIN structure /// A CSV string of the TWAIN structure [PermissionSet(SecurityAction.LinkDemand, Name = "FullTrust", Unrestricted = false)] public string CapabilityToCsv(TW_CAPABILITY a_twcapability, bool a_blUseSymbols) { IntPtr intptr; IntPtr intptrLocked; TWTY ItemType; uint NumItems; // Handle the container... switch (a_twcapability.ConType) { default: return ("(unrecognized container)"); case TWON.ARRAY: { uint uu; CSV csvArray; // Mac has a level of indirection and a different structure (ick)... if (ms_platform == Platform.MACOSX) { // Crack the container... TW_ARRAY_MACOSX twarraymacosx = default(TW_ARRAY_MACOSX); intptrLocked = DsmMemLock(a_twcapability.hContainer); twarraymacosx = (TW_ARRAY_MACOSX)Marshal.PtrToStructure(intptrLocked, typeof(TW_ARRAY_MACOSX)); ItemType = (TWTY)twarraymacosx.ItemType; NumItems = twarraymacosx.NumItems; intptr = (IntPtr)((UInt64)intptrLocked + (UInt64)Marshal.SizeOf(twarraymacosx)); } else { // Crack the container... TW_ARRAY twarray = default(TW_ARRAY); intptrLocked = DsmMemLock(a_twcapability.hContainer); twarray = (TW_ARRAY)Marshal.PtrToStructure(intptrLocked, typeof(TW_ARRAY)); ItemType = twarray.ItemType; NumItems = twarray.NumItems; intptr = (IntPtr)((UInt64)intptrLocked + (UInt64)Marshal.SizeOf(twarray)); } // Start building the string... csvArray = Common(a_twcapability.Cap, a_twcapability.ConType, ItemType); csvArray.Add(NumItems.ToString()); // Tack on the stuff from the ItemList... if (a_blUseSymbols) { string szValue; for (uu = 0; uu < NumItems; uu++) { string szItem = GetIndexedItem(a_twcapability, ItemType, intptr, (int)uu); szValue = CvtCapValueToEnum(a_twcapability.Cap, szItem); csvArray.Add(szValue); } } else { for (uu = 0; uu < NumItems; uu++) { csvArray.Add(GetIndexedItem(a_twcapability, ItemType, intptr, (int)uu)); } } // All done... DsmMemUnlock(a_twcapability.hContainer); return (csvArray.Get()); } case TWON.ENUMERATION: { uint uu; CSV csvEnum; // Mac has a level of indirection and a different structure (ick)... if (ms_platform == Platform.MACOSX) { // Crack the container... TW_ENUMERATION_MACOSX twenumerationmacosx = default(TW_ENUMERATION_MACOSX); intptrLocked = DsmMemLock(a_twcapability.hContainer); twenumerationmacosx = (TW_ENUMERATION_MACOSX)Marshal.PtrToStructure(intptrLocked, typeof(TW_ENUMERATION_MACOSX)); ItemType = (TWTY)twenumerationmacosx.ItemType; NumItems = twenumerationmacosx.NumItems; intptr = (IntPtr)((UInt64)intptrLocked + (UInt64)Marshal.SizeOf(twenumerationmacosx)); // Start building the string... csvEnum = Common(a_twcapability.Cap, a_twcapability.ConType, ItemType); csvEnum.Add(NumItems.ToString()); csvEnum.Add(twenumerationmacosx.CurrentIndex.ToString()); csvEnum.Add(twenumerationmacosx.DefaultIndex.ToString()); } // Windows or the 2.4+ Linux DSM... else if ((ms_platform == Platform.WINDOWS) || ((m_blFoundLatestDsm || m_blFoundLatestDsm64) && (m_linuxdsm == LinuxDsm.IsLatestDsm))) { // Crack the container... TW_ENUMERATION twenumeration = default(TW_ENUMERATION); intptrLocked = DsmMemLock(a_twcapability.hContainer); twenumeration = (TW_ENUMERATION)Marshal.PtrToStructure(intptrLocked, typeof(TW_ENUMERATION)); ItemType = twenumeration.ItemType; NumItems = twenumeration.NumItems; intptr = (IntPtr)((UInt64)intptrLocked + (UInt64)Marshal.SizeOf(twenumeration)); // Start building the string... csvEnum = Common(a_twcapability.Cap, a_twcapability.ConType, ItemType); csvEnum.Add(NumItems.ToString()); csvEnum.Add(twenumeration.CurrentIndex.ToString()); csvEnum.Add(twenumeration.DefaultIndex.ToString()); } // The -2.3 Linux DSM... else if (m_blFound020302Dsm64bit && (m_linuxdsm == LinuxDsm.Is020302Dsm64bit)) { // Crack the container... TW_ENUMERATION_LINUX64 twenumerationlinux64 = default(TW_ENUMERATION_LINUX64); intptrLocked = DsmMemLock(a_twcapability.hContainer); twenumerationlinux64 = (TW_ENUMERATION_LINUX64)Marshal.PtrToStructure(intptrLocked, typeof(TW_ENUMERATION_LINUX64)); ItemType = twenumerationlinux64.ItemType; NumItems = (uint)twenumerationlinux64.NumItems; intptr = (IntPtr)((UInt64)intptrLocked + (UInt64)Marshal.SizeOf(twenumerationlinux64)); // Start building the string... csvEnum = Common(a_twcapability.Cap, a_twcapability.ConType, ItemType); csvEnum.Add(NumItems.ToString()); csvEnum.Add(twenumerationlinux64.CurrentIndex.ToString()); csvEnum.Add(twenumerationlinux64.DefaultIndex.ToString()); } // This shouldn't be possible, but what the hey... else { Log.Error("This is serious, you win a cookie for getting here..."); DsmMemUnlock(a_twcapability.hContainer); return (""); } // Tack on the stuff from the ItemList... if (a_blUseSymbols) { string szValue; for (uu = 0; uu < NumItems; uu++) { string szItem = GetIndexedItem(a_twcapability, ItemType, intptr, (int)uu); szValue = CvtCapValueToEnum(a_twcapability.Cap, szItem); csvEnum.Add(szValue); } } else { for (uu = 0; uu < NumItems; uu++) { csvEnum.Add(GetIndexedItem(a_twcapability, ItemType, intptr, (int)uu)); } } // All done... DsmMemUnlock(a_twcapability.hContainer); return (csvEnum.Get()); } case TWON.ONEVALUE: { CSV csvOnevalue; // Mac has a level of indirection and a different structure (ick)... if (ms_platform == Platform.MACOSX) { // Crack the container... TW_ONEVALUE_MACOSX twonevaluemacosx = default(TW_ONEVALUE_MACOSX); intptrLocked = DsmMemLock(a_twcapability.hContainer); twonevaluemacosx = (TW_ONEVALUE_MACOSX)Marshal.PtrToStructure(intptrLocked, typeof(TW_ONEVALUE_MACOSX)); ItemType = (TWTY)twonevaluemacosx.ItemType; intptr = (IntPtr)((UInt64)intptrLocked + (UInt64)Marshal.SizeOf(twonevaluemacosx)); } else { // Crack the container... TW_ONEVALUE twonevalue = default(TW_ONEVALUE); intptrLocked = DsmMemLock(a_twcapability.hContainer); twonevalue = (TW_ONEVALUE)Marshal.PtrToStructure(intptrLocked, typeof(TW_ONEVALUE)); ItemType = (TWTY)twonevalue.ItemType; intptr = (IntPtr)((UInt64)intptrLocked + (UInt64)Marshal.SizeOf(twonevalue)); } // Start building the string... csvOnevalue = Common(a_twcapability.Cap, a_twcapability.ConType, ItemType); // Tack on the stuff from the Item... if (a_blUseSymbols) { string szValue; string szItem = GetIndexedItem(a_twcapability, ItemType, intptr, 0); szValue = CvtCapValueToEnum(a_twcapability.Cap, szItem); csvOnevalue.Add(szValue); } else { csvOnevalue.Add(GetIndexedItem(a_twcapability, ItemType, intptr, 0)); } // All done... DsmMemUnlock(a_twcapability.hContainer); return (csvOnevalue.Get()); } case TWON.RANGE: { CSV csvRange; string szTmp; TW_RANGE twrange; TW_RANGE_LINUX64 twrangelinux64; TW_RANGE_MACOSX twrangemacosx; TW_RANGE_FIX32 twrangefix32; TW_RANGE_FIX32_MACOSX twrangefix32macosx; // Mac has a level of indirection and a different structure (ick)... twrange = default(TW_RANGE); if (ms_platform == Platform.MACOSX) { intptrLocked = DsmMemLock(a_twcapability.hContainer); twrangemacosx = (TW_RANGE_MACOSX)Marshal.PtrToStructure(intptrLocked, typeof(TW_RANGE_MACOSX)); twrangefix32macosx = (TW_RANGE_FIX32_MACOSX)Marshal.PtrToStructure(intptrLocked, typeof(TW_RANGE_FIX32_MACOSX)); twrange.ItemType = (TWTY)twrangemacosx.ItemType; twrange.MinValue = twrangemacosx.MinValue; twrange.MaxValue = twrangemacosx.MaxValue; twrange.StepSize = twrangemacosx.StepSize; twrange.DefaultValue = twrangemacosx.DefaultValue; twrange.CurrentValue = twrangemacosx.CurrentValue; twrangefix32.ItemType = (TWTY)twrangefix32macosx.ItemType; twrangefix32.MinValue = twrangefix32macosx.MinValue; twrangefix32.MaxValue = twrangefix32macosx.MaxValue; twrangefix32.StepSize = twrangefix32macosx.StepSize; twrangefix32.DefaultValue = twrangefix32macosx.DefaultValue; twrangefix32.CurrentValue = twrangefix32macosx.CurrentValue; } // Windows or the 2.4+ Linux DSM... else if ((ms_platform == Platform.WINDOWS) || (m_linuxdsm == LinuxDsm.IsLatestDsm) || ((m_blFoundLatestDsm || m_blFoundLatestDsm64) && (m_linuxdsm == LinuxDsm.IsLatestDsm))) { intptrLocked = DsmMemLock(a_twcapability.hContainer); twrange = (TW_RANGE)Marshal.PtrToStructure(intptrLocked, typeof(TW_RANGE)); twrangefix32 = (TW_RANGE_FIX32)Marshal.PtrToStructure(intptrLocked, typeof(TW_RANGE_FIX32)); } // The -2.3 Linux DSM... else { intptrLocked = DsmMemLock(a_twcapability.hContainer); twrangelinux64 = (TW_RANGE_LINUX64)Marshal.PtrToStructure(intptrLocked, typeof(TW_RANGE_LINUX64)); twrangefix32macosx = (TW_RANGE_FIX32_MACOSX)Marshal.PtrToStructure(intptrLocked, typeof(TW_RANGE_FIX32_MACOSX)); twrange.ItemType = (TWTY)twrangelinux64.ItemType; twrange.MinValue = (uint)twrangelinux64.MinValue; twrange.MaxValue = (uint)twrangelinux64.MaxValue; twrange.StepSize = (uint)twrangelinux64.StepSize; twrange.DefaultValue = (uint)twrangelinux64.DefaultValue; twrange.CurrentValue = (uint)twrangelinux64.CurrentValue; twrangefix32.ItemType = (TWTY)twrangefix32macosx.ItemType; twrangefix32.MinValue = twrangefix32macosx.MinValue; twrangefix32.MaxValue = twrangefix32macosx.MaxValue; twrangefix32.StepSize = twrangefix32macosx.StepSize; twrangefix32.DefaultValue = twrangefix32macosx.DefaultValue; twrangefix32.CurrentValue = twrangefix32macosx.CurrentValue; } // Start the string... csvRange = Common(a_twcapability.Cap, a_twcapability.ConType, twrange.ItemType); // Tack on the data... switch ((TWTY)twrange.ItemType) { default: DsmMemUnlock(a_twcapability.hContainer); return ("(Get Capability: unrecognized data type)"); case TWTY.INT8: csvRange.Add(((char)(twrange.MinValue)).ToString()); csvRange.Add(((char)(twrange.MaxValue)).ToString()); csvRange.Add(((char)(twrange.StepSize)).ToString()); csvRange.Add(((char)(twrange.DefaultValue)).ToString()); csvRange.Add(((char)(twrange.CurrentValue)).ToString()); DsmMemUnlock(a_twcapability.hContainer); return (csvRange.Get()); case TWTY.INT16: csvRange.Add(((short)(twrange.MinValue)).ToString()); csvRange.Add(((short)(twrange.MaxValue)).ToString()); csvRange.Add(((short)(twrange.StepSize)).ToString()); csvRange.Add(((short)(twrange.DefaultValue)).ToString()); csvRange.Add(((short)(twrange.CurrentValue)).ToString()); DsmMemUnlock(a_twcapability.hContainer); return (csvRange.Get()); case TWTY.INT32: csvRange.Add(((int)(twrange.MinValue)).ToString()); csvRange.Add(((int)(twrange.MaxValue)).ToString()); csvRange.Add(((int)(twrange.StepSize)).ToString()); csvRange.Add(((int)(twrange.DefaultValue)).ToString()); csvRange.Add(((int)(twrange.CurrentValue)).ToString()); DsmMemUnlock(a_twcapability.hContainer); return (csvRange.Get()); case TWTY.UINT8: csvRange.Add(((byte)(twrange.MinValue)).ToString()); csvRange.Add(((byte)(twrange.MaxValue)).ToString()); csvRange.Add(((byte)(twrange.StepSize)).ToString()); csvRange.Add(((byte)(twrange.DefaultValue)).ToString()); csvRange.Add(((byte)(twrange.CurrentValue)).ToString()); DsmMemUnlock(a_twcapability.hContainer); return (csvRange.Get()); case TWTY.BOOL: case TWTY.UINT16: csvRange.Add(((ushort)(twrange.MinValue)).ToString()); csvRange.Add(((ushort)(twrange.MaxValue)).ToString()); csvRange.Add(((ushort)(twrange.StepSize)).ToString()); csvRange.Add(((ushort)(twrange.DefaultValue)).ToString()); csvRange.Add(((ushort)(twrange.CurrentValue)).ToString()); DsmMemUnlock(a_twcapability.hContainer); return (csvRange.Get()); case TWTY.UINT32: csvRange.Add(((uint)(twrange.MinValue)).ToString()); csvRange.Add(((uint)(twrange.MaxValue)).ToString()); csvRange.Add(((uint)(twrange.StepSize)).ToString()); csvRange.Add(((uint)(twrange.DefaultValue)).ToString()); csvRange.Add(((uint)(twrange.CurrentValue)).ToString()); DsmMemUnlock(a_twcapability.hContainer); return (csvRange.Get()); case TWTY.FIX32: szTmp = ((double)twrangefix32.MinValue.Whole + ((double)twrangefix32.MinValue.Frac / 65536.0)).ToString("0." + new string('#', 339)); csvRange.Add(szTmp); szTmp = ((double)twrangefix32.MaxValue.Whole + ((double)twrangefix32.MaxValue.Frac / 65536.0)).ToString("0." + new string('#', 339)); csvRange.Add(szTmp); szTmp = ((double)twrangefix32.StepSize.Whole + ((double)twrangefix32.StepSize.Frac / 65536.0)).ToString("0." + new string('#', 339)); csvRange.Add(szTmp); szTmp = ((double)twrangefix32.DefaultValue.Whole + ((double)twrangefix32.DefaultValue.Frac / 65536.0)).ToString("0." + new string('#', 339)); csvRange.Add(szTmp); szTmp = ((double)twrangefix32.CurrentValue.Whole + ((double)twrangefix32.CurrentValue.Frac / 65536.0)).ToString("0." + new string('#', 339)); csvRange.Add(szTmp); DsmMemUnlock(a_twcapability.hContainer); return (csvRange.Get()); } } } } /// /// Convert the contents of a string into something we can poke into a /// TW_CAPABILITY structure... /// /// A TWAIN structure /// A CSV string of the TWAIN structure /// The container for this capability /// True if the conversion is successful [PermissionSet(SecurityAction.LinkDemand, Name = "FullTrust", Unrestricted = false)] public bool CsvToCapability(ref TW_CAPABILITY a_twcapability, ref string a_szSetting, string a_szValue) { int ii = 0; TWTY twty = TWTY.BOOL; uint u32NumItems = 0; IntPtr intptr = IntPtr.Zero; string szResult; string[] asz; // We need some protection for this one... try { // Tokenize our values... asz = CSV.Parse(a_szValue); if (asz.GetLength(0) < 1) { a_szSetting = "Set Capability: (insufficient number of arguments)"; return (false); } // Set the capability from text or hex... try { // see if it is a custom cap if ((asz[0][0] == '8') || asz[0].StartsWith("0x8")) { a_twcapability.Cap = (CAP)0xFFFF; } else if (asz[0].StartsWith("0x")) { int iNum = 0; int.TryParse(asz[0].Substring(2), NumberStyles.AllowHexSpecifier | NumberStyles.HexNumber, CultureInfo.InvariantCulture, out iNum); a_twcapability.Cap = (CAP)iNum; } else { a_twcapability.Cap = (CAP)Enum.Parse(typeof(CAP), asz[0], true); } } catch { // don't log this exception... a_twcapability.Cap = (CAP)0xFFFF; } if ((a_twcapability.Cap == (CAP)0xFFFF) || !asz[0].Contains("_")) { a_twcapability.Cap = (CAP)Convert.ToUInt16(asz[0], 16); } // Set the container from text or decimal... if (asz.GetLength(0) >= 2) { try { a_twcapability.ConType = (TWON)Enum.Parse(typeof(TWON), asz[1].Replace("TWON_", "").Replace("twon_", ""), true); } catch { // don't log this exception... a_twcapability.ConType = (TWON)ushort.Parse(asz[1]); } } // Set the item type from text or decimal... if (asz.GetLength(0) >= 3) { try { twty = (TWTY)Enum.Parse(typeof(TWTY), asz[2].Replace("TWTY_", "").Replace("twty_", ""), true); } catch { // don't log this exception... twty = (TWTY)ushort.Parse(asz[2]); } } // Assign the new value... if (asz.GetLength(0) >= 4) { switch (a_twcapability.ConType) { default: a_szSetting = "(unrecognized container)"; return (false); case TWON.ARRAY: // Validate... if (asz.GetLength(0) < 4) { a_szSetting = "Set Capability: (insufficient number of arguments)"; return (false); } // Get the values... u32NumItems = uint.Parse(asz[3]); // Allocate the container (go for worst case, which is TW_STR255)... if (ms_platform == Platform.MACOSX) { // Allocate... a_twcapability.hContainer = DsmMemAlloc((uint)(Marshal.SizeOf(default(TW_ARRAY_MACOSX)) + (((int)u32NumItems + 1) * Marshal.SizeOf(default(TW_STR255))))); intptr = DsmMemLock(a_twcapability.hContainer); // Set the meta data... TW_ARRAY_MACOSX twarraymacosx = default(TW_ARRAY_MACOSX); twarraymacosx.ItemType = (uint)twty; twarraymacosx.NumItems = u32NumItems; Marshal.StructureToPtr(twarraymacosx, intptr, true); // Get the pointer to the ItemList... intptr = (IntPtr)((UInt64)intptr + (UInt64)Marshal.SizeOf(twarraymacosx)); } else { // Allocate... a_twcapability.hContainer = DsmMemAlloc((uint)(Marshal.SizeOf(default(TW_ARRAY)) + (((int)u32NumItems + 1) * Marshal.SizeOf(default(TW_STR255))))); intptr = DsmMemLock(a_twcapability.hContainer); // Set the meta data... TW_ARRAY twarray = default(TW_ARRAY); twarray.ItemType = twty; twarray.NumItems = u32NumItems; Marshal.StructureToPtr(twarray, intptr, true); // Get the pointer to the ItemList... intptr = (IntPtr)((UInt64)intptr + (UInt64)Marshal.SizeOf(twarray)); } // Set the ItemList... for (ii = 0; (ii < u32NumItems) && ((ii + 4) < asz.Length); ii++) { szResult = SetIndexedItem(a_twcapability, twty, intptr, ii, asz[ii + 4]); if (szResult != "") { return (false); } } // All done... DsmMemUnlock(a_twcapability.hContainer); return (true); case TWON.ENUMERATION: // Validate... if (asz.GetLength(0) < 6) { a_szSetting = "Set Capability: (insufficient number of arguments)"; return (false); } // Get the values... u32NumItems = uint.Parse(asz[3]); // Allocate the container (go for worst case, which is TW_STR255)... if (ms_platform == Platform.MACOSX) { // Allocate... a_twcapability.hContainer = DsmMemAlloc((uint)(Marshal.SizeOf(default(TW_ENUMERATION_MACOSX)) + (((int)u32NumItems + 1) * Marshal.SizeOf(default(TW_STR255))))); intptr = DsmMemLock(a_twcapability.hContainer); // Set the meta data... TW_ENUMERATION_MACOSX twenumerationmacosx = default(TW_ENUMERATION_MACOSX); twenumerationmacosx.ItemType = (uint)twty; twenumerationmacosx.NumItems = u32NumItems; twenumerationmacosx.CurrentIndex = uint.Parse(asz[4]); twenumerationmacosx.DefaultIndex = uint.Parse(asz[5]); Marshal.StructureToPtr(twenumerationmacosx, intptr, true); // Get the pointer to the ItemList... intptr = (IntPtr)((UInt64)intptr + (UInt64)Marshal.SizeOf(twenumerationmacosx)); } // Windows or the 2.4+ Linux DSM... else if ((ms_platform == Platform.WINDOWS) || ((m_linuxdsm == LinuxDsm.IsLatestDsm) || ((m_blFoundLatestDsm || m_blFoundLatestDsm64) && (m_linuxdsm == LinuxDsm.IsLatestDsm)))) { // Allocate... a_twcapability.hContainer = DsmMemAlloc((uint)(Marshal.SizeOf(default(TW_ENUMERATION)) + (((int)u32NumItems + 1) * Marshal.SizeOf(default(TW_STR255))))); intptr = DsmMemLock(a_twcapability.hContainer); // Set the meta data... TW_ENUMERATION twenumeration = default(TW_ENUMERATION); twenumeration.ItemType = twty; twenumeration.NumItems = u32NumItems; twenumeration.CurrentIndex = uint.Parse(asz[4]); twenumeration.DefaultIndex = uint.Parse(asz[5]); Marshal.StructureToPtr(twenumeration, intptr, true); // Get the pointer to the ItemList... intptr = (IntPtr)((UInt64)intptr + (UInt64)Marshal.SizeOf(twenumeration)); } // The -2.3 Linux DSM... else { // Allocate... a_twcapability.hContainer = DsmMemAlloc((uint)(Marshal.SizeOf(default(TW_ENUMERATION_LINUX64)) + (((int)u32NumItems + 1) * Marshal.SizeOf(default(TW_STR255))))); intptr = DsmMemLock(a_twcapability.hContainer); // Set the meta data... TW_ENUMERATION_LINUX64 twenumerationlinux64 = default(TW_ENUMERATION_LINUX64); twenumerationlinux64.ItemType = twty; twenumerationlinux64.NumItems = u32NumItems; twenumerationlinux64.CurrentIndex = uint.Parse(asz[4]); twenumerationlinux64.DefaultIndex = uint.Parse(asz[5]); Marshal.StructureToPtr(twenumerationlinux64, intptr, true); // Get the pointer to the ItemList... intptr = (IntPtr)((UInt64)intptr + (UInt64)Marshal.SizeOf(twenumerationlinux64)); } // Set the ItemList... for (ii = 0; ii < u32NumItems; ii++) { szResult = SetIndexedItem(a_twcapability, twty, intptr, ii, asz[ii + 6]); if (szResult != "") { return (false); } } // All done... DsmMemUnlock(a_twcapability.hContainer); return (true); case TWON.ONEVALUE: // Validate... if (asz.GetLength(0) < 4) { a_szSetting = "Set Capability: (insufficient number of arguments)"; return (false); } // Allocate the container (go for worst case, which is TW_STR255)... if (ms_platform == Platform.MACOSX) { // Allocate... a_twcapability.hContainer = DsmMemAlloc((uint)(Marshal.SizeOf(default(TW_ONEVALUE_MACOSX)) + Marshal.SizeOf(default(TW_STR255)))); intptr = DsmMemLock(a_twcapability.hContainer); // Set the meta data... TW_ONEVALUE_MACOSX twonevaluemacosx = default(TW_ONEVALUE_MACOSX); twonevaluemacosx.ItemType = (uint)twty; Marshal.StructureToPtr(twonevaluemacosx, intptr, true); // Get the pointer to the ItemList... intptr = (IntPtr)((UInt64)intptr + (UInt64)Marshal.SizeOf(twonevaluemacosx)); } else { // Allocate... a_twcapability.hContainer = DsmMemAlloc((uint)(Marshal.SizeOf(default(TW_ONEVALUE)) + Marshal.SizeOf(default(TW_STR255)))); intptr = DsmMemLock(a_twcapability.hContainer); // Set the meta data... TW_ONEVALUE twonevalue = default(TW_ONEVALUE); twonevalue.ItemType = twty; Marshal.StructureToPtr(twonevalue, intptr, true); // Get the pointer to the ItemList... intptr = (IntPtr)((UInt64)intptr + (UInt64)Marshal.SizeOf(twonevalue)); } // Set the Item... szResult = SetIndexedItem(a_twcapability, twty, intptr, 0, asz[3]); if (szResult != "") { return (false); } // All done... DsmMemUnlock(a_twcapability.hContainer); return (true); case TWON.RANGE: // Validate... if (asz.GetLength(0) < 8) { a_szSetting = "Set Capability: (insufficient number of arguments)"; return (false); } // Allocate the container (go for worst case, which is TW_STR255)... if (ms_platform == Platform.MACOSX) { // Allocate... a_twcapability.hContainer = DsmMemAlloc((uint)(Marshal.SizeOf(default(TW_RANGE_MACOSX)))); intptr = DsmMemLock(a_twcapability.hContainer); } // Windows or the 2.4+ Linux DSM... else if ((ms_platform == Platform.WINDOWS) || ((m_linuxdsm == LinuxDsm.IsLatestDsm) || ((m_blFoundLatestDsm || m_blFoundLatestDsm64) && (m_linuxdsm == LinuxDsm.IsLatestDsm)))) { // Allocate... a_twcapability.hContainer = DsmMemAlloc((uint)(Marshal.SizeOf(default(TW_RANGE)))); intptr = DsmMemLock(a_twcapability.hContainer); } // The -2.3 Linux DSM... else { // Allocate... a_twcapability.hContainer = DsmMemAlloc((uint)(Marshal.SizeOf(default(TW_RANGE_LINUX64)))); intptr = DsmMemLock(a_twcapability.hContainer); } // Set the Item... szResult = SetRangeItem(twty, intptr, asz); if (szResult != "") { return (false); } // All done... DsmMemUnlock(a_twcapability.hContainer); return (true); } } // All done (this is good for a get where only the cap was specified)... return (true); } catch (Exception exception) { Log.Error("CsvToCapability exception - " + exception.Message); Log.Error("setting=<" + a_szSetting + ">"); a_szValue = "(data error)"; return (false); } } /// /// Convert the contents of a custom DS data to a string that we can show in /// our simple GUI... /// /// A TWAIN structure /// A CSV string of the TWAIN structure [PermissionSet(SecurityAction.LinkDemand, Name = "FullTrust", Unrestricted = false)] public string CustomdsdataToCsv(TW_CUSTOMDSDATA a_twcustomdsdata) { try { CSV csv = new CSV(); csv.Add(a_twcustomdsdata.InfoLength.ToString()); IntPtr intptr = DsmMemLock(a_twcustomdsdata.hData); csv.Add(intptr.ToString()); DsmMemUnlock(a_twcustomdsdata.hData); return (csv.Get()); } catch (Exception exception) { Log.Error("***error*** - " + exception.Message); return ("***error***"); } } /// /// Convert the contents of a string to a custom DS data structure... /// /// A TWAIN structure /// A CSV string of the TWAIN structure /// True if the conversion is successful [PermissionSet(SecurityAction.LinkDemand, Name = "FullTrust", Unrestricted = false)] public bool CsvToCustomdsdata(ref TW_CUSTOMDSDATA a_twcustomdsdata, string a_szCustomdsdata) { // Init stuff... a_twcustomdsdata = default(TW_CUSTOMDSDATA); // Build the string... try { string[] asz = CSV.Parse(a_szCustomdsdata); // Grab the values... a_twcustomdsdata.InfoLength = uint.Parse(asz[0]); a_twcustomdsdata.hData = DsmMemAlloc(a_twcustomdsdata.InfoLength); IntPtr intptr = DsmMemLock(a_twcustomdsdata.hData); byte[] bProfile = new byte[a_twcustomdsdata.InfoLength]; Marshal.Copy((IntPtr)UInt64.Parse(asz[1]), bProfile, 0, (int)a_twcustomdsdata.InfoLength); Marshal.Copy(bProfile, 0, intptr, (int)a_twcustomdsdata.InfoLength); DsmMemUnlock(a_twcustomdsdata.hData); } catch (Exception exception) { Log.Error("***error*** - " + exception.Message); return (false); } // All done... return (true); } /// /// Convert the contents of a device event to a string that we can show in /// our simple GUI... /// /// A TWAIN structure /// A CSV string of the TWAIN structure public static string DeviceeventToCsv(TW_DEVICEEVENT a_twdeviceevent) { try { CSV csv = new CSV(); csv.Add(((TWDE)a_twdeviceevent.Event).ToString()); csv.Add(a_twdeviceevent.DeviceName.Get()); csv.Add(a_twdeviceevent.BatteryMinutes.ToString()); csv.Add(a_twdeviceevent.BatteryPercentage.ToString()); csv.Add(a_twdeviceevent.PowerSupply.ToString()); csv.Add(((double)a_twdeviceevent.XResolution.Whole + ((double)a_twdeviceevent.XResolution.Frac / 65536.0)).ToString()); csv.Add(((double)a_twdeviceevent.YResolution.Whole + ((double)a_twdeviceevent.YResolution.Frac / 65536.0)).ToString()); csv.Add(a_twdeviceevent.FlashUsed2.ToString()); csv.Add(a_twdeviceevent.AutomaticCapture.ToString()); csv.Add(a_twdeviceevent.TimeBeforeFirstCapture.ToString()); csv.Add(a_twdeviceevent.TimeBetweenCaptures.ToString()); return (csv.Get()); } catch (Exception exception) { Log.Error("***error*** - " + exception.Message); return ("***error***"); } } /// /// Convert the contents of an entry point to a string that /// we can show in our simple GUI... /// /// A TWAIN structure /// A CSV string of the TWAIN structure public static string EntrypointToCsv(TW_ENTRYPOINT a_twentrypoint) { try { CSV csv = new CSV(); csv.Add(a_twentrypoint.Size.ToString()); csv.Add("0x" + ((a_twentrypoint.DSM_Entry == null)?"0":a_twentrypoint.DSM_Entry.ToString("X"))); csv.Add("0x" + ((a_twentrypoint.DSM_MemAllocate == null) ? "0" : a_twentrypoint.DSM_MemAllocate.ToString("X"))); csv.Add("0x" + ((a_twentrypoint.DSM_MemFree == null) ? "0" : a_twentrypoint.DSM_MemFree.ToString("X"))); csv.Add("0x" + ((a_twentrypoint.DSM_MemLock == null) ? "0" : a_twentrypoint.DSM_MemLock.ToString("X"))); csv.Add("0x" + ((a_twentrypoint.DSM_MemUnlock == null) ? "0" : a_twentrypoint.DSM_MemUnlock.ToString("X"))); return (csv.Get()); } catch (Exception exception) { Log.Error("***error*** - " + exception.Message); return ("***error***"); } } /// /// Convert the contents of an event to a string that /// we can show in our simple GUI... /// /// A TWAIN structure /// A CSV string of the TWAIN structure public static string EventToCsv(TW_EVENT a_twevent) { try { CSV csv = new CSV(); csv.Add(a_twevent.pEvent.ToString()); csv.Add(a_twevent.TWMessage.ToString()); return (csv.Get()); } catch (Exception exception) { Log.Error("***error*** - " + exception.Message); return ("***error***"); } } /// /// Convert the contents of an extimageinfo to a string that we can show in /// our simple GUI... /// /// A TWAIN structure /// A CSV string of the TWAIN structure public static string ExtimageinfoToCsv(TW_EXTIMAGEINFO a_twextimageinfo) { try { uint uTwinfo = 0; CSV csv = new CSV(); csv.Add(a_twextimageinfo.NumInfos.ToString()); for (int ii = 0; (ii < a_twextimageinfo.NumInfos) && (ii < 200); ii++) { TWEI twei; TWTY twty; STS sts; TW_INFO twinfo = default(TW_INFO); a_twextimageinfo.Get(uTwinfo, ref twinfo); twei = (TWEI)twinfo.InfoId; if (twei.ToString() != twinfo.InfoId.ToString()) { csv.Add("TWEI_" + twei.ToString()); } else { csv.Add(string.Format("0x{0:X}", twinfo.InfoId)); } twty = (TWTY)twinfo.ItemType; if (twty.ToString() != twinfo.ItemType.ToString()) { csv.Add("TWTY_" + twty.ToString()); } else { csv.Add(string.Format("0x{0:X}", twinfo.ItemType)); } csv.Add(twinfo.NumItems.ToString()); sts = (STS)twinfo.ReturnCode; if (sts.ToString() != twinfo.ReturnCode.ToString()) { csv.Add("TWRC_" + sts.ToString()); } else { csv.Add(string.Format("0x{0:X}", twinfo.ReturnCode)); } csv.Add(twinfo.Item.ToString()); uTwinfo += 1; } return (csv.Get()); } catch (Exception exception) { Log.Error("***error*** - " + exception.Message); return ("***error***"); } } /// /// Convert the contents of a string to an extimageinfo structure, /// note that we don't have to worry about containers going in this /// direction... /// /// A TWAIN structure /// A CSV string of the TWAIN structure /// True if the conversion is successful public static bool CsvToExtimageinfo(ref TW_EXTIMAGEINFO a_twextimageinfo, string a_szExtimageinfo) { // Init stuff... a_twextimageinfo = default(TW_EXTIMAGEINFO); // Build the string... try { int iField; uint uTwinfo; string[] asz = CSV.Parse(a_szExtimageinfo); // Set the number of entries (this is the easy bit)... uint.TryParse(asz[0], out a_twextimageinfo.NumInfos); if (a_twextimageinfo.NumInfos > 200) { Log.Error("***error*** - we're limited to 200 entries, if this is a problem, just add more, and fix this code..."); return (false); } // Okay, walk all the entries in steps of TW_INFO... uTwinfo = 0; for (iField = 1; iField < asz.Length; iField += 5) { UInt64 u64; TWEI twei; TW_INFO twinfo = default(TW_INFO); if ((iField + 5) > asz.Length) { Log.Error("***error*** - badly constructed list, should be: num,(twinfo),(twinfo)..."); return (false); } if (TWEI.TryParse(asz[iField + 0].Replace("TWEI_", ""), out twei)) { twinfo.InfoId = (ushort)twei; } else { if (asz[iField + 0].ToLowerInvariant().StartsWith("0x")) { ushort.TryParse(asz[iField + 0].Substring(2), NumberStyles.HexNumber, CultureInfo.InvariantCulture, out twinfo.InfoId); } else { ushort.TryParse(asz[iField + 0], out twinfo.InfoId); } } // We really don't care about these... ushort.TryParse(asz[iField + 1], out twinfo.ItemType); ushort.TryParse(asz[iField + 2], out twinfo.NumItems); ushort.TryParse(asz[iField + 3], out twinfo.ReturnCode); UInt64.TryParse(asz[iField + 4], out u64); twinfo.Item = (UIntPtr)u64; a_twextimageinfo.Set(uTwinfo, ref twinfo); uTwinfo += 1; } } catch (Exception exception) { Log.Error("***error*** - " + exception.Message); return (false); } // All done... return (true); } /// /// Convert the contents of a filesystem to a string that we can show in /// our simple GUI... /// /// A TWAIN structure /// A CSV string of the TWAIN structure public static string FilesystemToCsv(TW_FILESYSTEM a_twfilesystem) { try { CSV csv = new CSV(); csv.Add(a_twfilesystem.InputName.Get()); csv.Add(a_twfilesystem.OutputName.Get()); csv.Add(a_twfilesystem.Context.ToString()); csv.Add(a_twfilesystem.Recursive.ToString()); csv.Add(a_twfilesystem.FileType.ToString()); csv.Add(a_twfilesystem.Size.ToString()); csv.Add(a_twfilesystem.CreateTimeDate.Get()); csv.Add(a_twfilesystem.ModifiedTimeDate.Get()); csv.Add(a_twfilesystem.FreeSpace.ToString()); csv.Add(a_twfilesystem.NewImageSize.ToString()); csv.Add(a_twfilesystem.NumberOfFiles.ToString()); csv.Add(a_twfilesystem.NumberOfSnippets.ToString()); csv.Add(a_twfilesystem.DeviceGroupMask.ToString()); return (csv.Get()); } catch (Exception exception) { Log.Error("***error*** - " + exception.Message); return ("***error***"); } } /// /// Convert the contents of a string to a filesystem structure... /// /// A TWAIN structure /// A CSV string of the TWAIN structure /// True if the conversion is successful public static bool CsvToFilesystem(ref TW_FILESYSTEM a_twfilesystem, string a_szFilesystem) { // Init stuff... a_twfilesystem = default(TW_FILESYSTEM); // Build the string... try { string[] asz = CSV.Parse(a_szFilesystem); // Grab the values... a_twfilesystem.InputName.Set(asz[0]); a_twfilesystem.OutputName.Set(asz[1]); a_twfilesystem.Context = (IntPtr)UInt64.Parse(asz[2]); a_twfilesystem.Recursive = int.Parse(asz[3]); a_twfilesystem.FileType = int.Parse(asz[4]); a_twfilesystem.Size = uint.Parse(asz[5]); a_twfilesystem.CreateTimeDate.Set(asz[6]); a_twfilesystem.ModifiedTimeDate.Set(asz[7]); a_twfilesystem.FreeSpace = (uint)UInt64.Parse(asz[8]); a_twfilesystem.NewImageSize = (uint)UInt64.Parse(asz[9]); a_twfilesystem.NumberOfFiles = (uint)UInt64.Parse(asz[10]); a_twfilesystem.NumberOfSnippets = (uint)UInt64.Parse(asz[11]); a_twfilesystem.DeviceGroupMask = (uint)UInt64.Parse(asz[12]); } catch (Exception exception) { Log.Error("***error*** - " + exception.Message); return (false); } // All done... return (true); } /// /// Convert the contents of an iccprofile to a string that we can /// show in our simple GUI... /// /// A TWAIN structure /// A CSV string of the TWAIN structure public static string IccprofileToCsv(TW_MEMORY a_twmemory) { try { CSV csv = new CSV(); csv.Add(a_twmemory.Flags.ToString()); csv.Add(a_twmemory.Length.ToString()); csv.Add(a_twmemory.TheMem.ToString()); return (csv.Get()); } catch (Exception exception) { Log.Error("***error*** - " + exception.Message); return ("***error***"); } } /// /// Convert the contents of an identity to a string that we can show in /// our simple GUI... /// /// A TWAIN structure /// A CSV string of the TWAIN structure public static string IdentityToCsv(TW_IDENTITY a_twidentity) { try { CSV csv = new CSV(); csv.Add(a_twidentity.Id.ToString()); csv.Add(a_twidentity.Version.MajorNum.ToString()); csv.Add(a_twidentity.Version.MinorNum.ToString()); csv.Add(a_twidentity.Version.Language.ToString()); csv.Add(a_twidentity.Version.Country.ToString()); csv.Add(a_twidentity.Version.Info.Get()); csv.Add(a_twidentity.ProtocolMajor.ToString()); csv.Add(a_twidentity.ProtocolMinor.ToString()); csv.Add("0x" + a_twidentity.SupportedGroups.ToString("X")); csv.Add(a_twidentity.Manufacturer.Get()); csv.Add(a_twidentity.ProductFamily.Get()); csv.Add(a_twidentity.ProductName.Get()); return (csv.Get()); } catch (Exception exception) { Log.Error("***error*** - " + exception.Message); return ("***error***"); } } /// /// Convert the contents of a string to an identity structure... /// /// A TWAIN structure /// A CSV string of the TWAIN structure /// True if the conversion is successful public static bool CsvToIdentity(ref TW_IDENTITY a_twidentity, string a_szIdentity) { // Init stuff... a_twidentity = default(TW_IDENTITY); // Build the string... try { string[] asz = CSV.Parse(a_szIdentity); // Grab the values... a_twidentity.Id = ulong.Parse(asz[0]); a_twidentity.Version.MajorNum = ushort.Parse(asz[1]); a_twidentity.Version.MinorNum = ushort.Parse(asz[2]); if (asz[3] != "0") a_twidentity.Version.Language = (TWLG)Enum.Parse(typeof(TWLG), asz[3]); if (asz[4] != "0") a_twidentity.Version.Country = (TWCY)Enum.Parse(typeof(TWCY), asz[4]); a_twidentity.Version.Info.Set(asz[5]); a_twidentity.ProtocolMajor = ushort.Parse(asz[6]); a_twidentity.ProtocolMinor = ushort.Parse(asz[7]); a_twidentity.SupportedGroups = asz[8].ToLower().StartsWith("0x") ? Convert.ToUInt32(asz[8].Remove(0, 2), 16) : Convert.ToUInt32(asz[8], 16); a_twidentity.Manufacturer.Set(asz[9]); a_twidentity.ProductFamily.Set(asz[10]); a_twidentity.ProductName.Set(asz[11]); } catch (Exception exception) { Log.Error("***error*** - " + exception.Message); return (false); } // All done... return (true); } /// /// Convert the contents of a image info to a string that we can show in /// our simple GUI... /// /// A TWAIN structure /// A CSV string of the TWAIN structure public static string ImageinfoToCsv(TW_IMAGEINFO a_twimageinfo) { try { CSV csv = new CSV(); csv.Add(((double)a_twimageinfo.XResolution.Whole + ((double)a_twimageinfo.XResolution.Frac / 65536.0)).ToString()); csv.Add(((double)a_twimageinfo.YResolution.Whole + ((double)a_twimageinfo.YResolution.Frac / 65536.0)).ToString()); csv.Add(a_twimageinfo.ImageWidth.ToString()); csv.Add(a_twimageinfo.ImageLength.ToString()); csv.Add(a_twimageinfo.SamplesPerPixel.ToString()); csv.Add(a_twimageinfo.BitsPerSample_0.ToString()); csv.Add(a_twimageinfo.BitsPerSample_1.ToString()); csv.Add(a_twimageinfo.BitsPerSample_2.ToString()); csv.Add(a_twimageinfo.BitsPerSample_3.ToString()); csv.Add(a_twimageinfo.BitsPerSample_4.ToString()); csv.Add(a_twimageinfo.BitsPerSample_5.ToString()); csv.Add(a_twimageinfo.BitsPerSample_6.ToString()); csv.Add(a_twimageinfo.BitsPerSample_7.ToString()); csv.Add(a_twimageinfo.Planar.ToString()); csv.Add("TWPT_" + (TWPT)a_twimageinfo.PixelType); csv.Add("TWCP_" + (TWCP)a_twimageinfo.Compression); return (csv.Get()); } catch (Exception exception) { Log.Error("***error*** - " + exception.Message); return ("***error***"); } } /// /// Convert the contents of a string to an callback structure... /// /// A TWAIN structure /// A CSV string of the TWAIN structure /// True if the conversion is successful public static bool CsvToImageinfo(ref TW_IMAGEINFO a_twimageinfo, string a_szImageinfo) { // Init stuff... a_twimageinfo = default(TW_IMAGEINFO); // Build the string... try { string[] asz = CSV.Parse(a_szImageinfo); // Grab the values... a_twimageinfo.XResolution.Whole = (short)double.Parse(asz[0]); a_twimageinfo.XResolution.Frac = (ushort)((double.Parse(asz[0]) - (double)a_twimageinfo.XResolution.Whole) * 65536.0); a_twimageinfo.YResolution.Whole = (short)double.Parse(asz[1]); a_twimageinfo.YResolution.Frac = (ushort)((double.Parse(asz[1]) - (double)a_twimageinfo.YResolution.Whole) * 65536.0); a_twimageinfo.ImageWidth = (short)double.Parse(asz[2]); a_twimageinfo.ImageLength = int.Parse(asz[3]); a_twimageinfo.SamplesPerPixel = short.Parse(asz[4]); a_twimageinfo.BitsPerSample_0 = short.Parse(asz[5]); a_twimageinfo.BitsPerSample_1 = short.Parse(asz[6]); a_twimageinfo.BitsPerSample_2 = short.Parse(asz[7]); a_twimageinfo.BitsPerSample_3 = short.Parse(asz[8]); a_twimageinfo.BitsPerSample_4 = short.Parse(asz[9]); a_twimageinfo.BitsPerSample_5 = short.Parse(asz[10]); a_twimageinfo.BitsPerSample_6 = short.Parse(asz[11]); a_twimageinfo.BitsPerSample_7 = short.Parse(asz[12]); a_twimageinfo.Planar = ushort.Parse(CvtCapValueFromEnum(CAP.ICAP_PLANARCHUNKY, asz[13])); a_twimageinfo.PixelType = short.Parse(CvtCapValueFromEnum(CAP.ICAP_PIXELTYPE, asz[14])); a_twimageinfo.Compression = ushort.Parse(CvtCapValueFromEnum(CAP.ICAP_COMPRESSION, asz[15])); } catch (Exception exception) { Log.Error("***error*** - " + exception.Message); return (false); } // All done... return (true); } /// /// Convert the contents of a image layout to a string that we can show in /// our simple GUI... /// /// A TWAIN structure /// A CSV string of the TWAIN structure public static string ImagelayoutToCsv(TW_IMAGELAYOUT a_twimagelayout) { try { CSV csv = new CSV(); csv.Add(((double)a_twimagelayout.Frame.Left.Whole + ((double)a_twimagelayout.Frame.Left.Frac / 65536.0)).ToString()); csv.Add(((double)a_twimagelayout.Frame.Top.Whole + ((double)a_twimagelayout.Frame.Top.Frac / 65536.0)).ToString()); csv.Add(((double)a_twimagelayout.Frame.Right.Whole + ((double)a_twimagelayout.Frame.Right.Frac / 65536.0)).ToString()); csv.Add(((double)a_twimagelayout.Frame.Bottom.Whole + ((double)a_twimagelayout.Frame.Bottom.Frac / 65536.0)).ToString()); csv.Add(a_twimagelayout.DocumentNumber.ToString()); csv.Add(a_twimagelayout.PageNumber.ToString()); csv.Add(a_twimagelayout.FrameNumber.ToString()); return (csv.Get()); } catch (Exception exception) { Log.Error("***error*** - " + exception.Message); return ("***error***"); } } /// /// Convert the contents of a string to an image layout structure... /// /// A TWAIN structure /// A CSV string of the TWAIN structure /// True if the conversion is successful public static bool CsvToImagelayout(ref TW_IMAGELAYOUT a_twimagelayout, string a_szImagelayout) { // Init stuff... a_twimagelayout = default(TW_IMAGELAYOUT); // Build the string... try { string[] asz = CSV.Parse(a_szImagelayout); // Sort out the frame... a_twimagelayout.Frame.Left.Whole = (short)double.Parse(asz[0]); a_twimagelayout.Frame.Left.Frac = (ushort)((double.Parse(asz[0]) - (double)a_twimagelayout.Frame.Left.Whole) * 65536.0); a_twimagelayout.Frame.Top.Whole = (short)double.Parse(asz[1]); a_twimagelayout.Frame.Top.Frac = (ushort)((double.Parse(asz[1]) - (double)a_twimagelayout.Frame.Top.Whole) * 65536.0); a_twimagelayout.Frame.Right.Whole = (short)double.Parse(asz[2]); a_twimagelayout.Frame.Right.Frac = (ushort)((double.Parse(asz[2]) - (double)a_twimagelayout.Frame.Right.Whole) * 65536.0); a_twimagelayout.Frame.Bottom.Whole = (short)double.Parse(asz[3]); a_twimagelayout.Frame.Bottom.Frac = (ushort)((double.Parse(asz[3]) - (double)a_twimagelayout.Frame.Bottom.Whole) * 65536.0); // And now the counters... a_twimagelayout.DocumentNumber = (uint)int.Parse(asz[4]); a_twimagelayout.PageNumber = (uint)int.Parse(asz[5]); a_twimagelayout.FrameNumber = (uint)int.Parse(asz[6]); } catch (Exception exception) { Log.Error("***error*** - " + exception.Message); return (false); } // All done... return (true); } /// /// Convert the contents of an image mem xfer structure to a string that /// we can show in our simple GUI... /// /// A TWAIN structure /// A CSV string of the TWAIN structure public static string ImagememxferToCsv(TW_IMAGEMEMXFER a_twimagememxfer) { try { CSV csv = new CSV(); csv.Add("TWCP_" + (TWCP)a_twimagememxfer.Compression); csv.Add(a_twimagememxfer.BytesPerRow.ToString()); csv.Add(a_twimagememxfer.Columns.ToString()); csv.Add(a_twimagememxfer.Rows.ToString()); csv.Add(a_twimagememxfer.XOffset.ToString()); csv.Add(a_twimagememxfer.YOffset.ToString()); csv.Add(a_twimagememxfer.BytesWritten.ToString()); csv.Add(a_twimagememxfer.Memory.Flags.ToString()); csv.Add(a_twimagememxfer.Memory.Length.ToString()); csv.Add(a_twimagememxfer.Memory.TheMem.ToString()); return (csv.Get()); } catch (Exception exception) { Log.Error("***error*** - " + exception.Message); return ("***error***"); } } /// /// Convert the contents of a string to an image mem xfer structure... /// /// A TWAIN structure /// A CSV string of the TWAIN structure /// True if the conversion is successful public static bool CsvToImagememxfer(ref TW_IMAGEMEMXFER a_twimagememxfer, string a_szImagememxfer) { // Init stuff... a_twimagememxfer = default(TW_IMAGEMEMXFER); // Build the string... try { string[] asz = CSV.Parse(a_szImagememxfer); // Sort out the structure... a_twimagememxfer.Compression = ushort.Parse(CvtCapValueFromEnum(CAP.ICAP_COMPRESSION, asz[0])); a_twimagememxfer.BytesPerRow = uint.Parse(asz[1]); a_twimagememxfer.Columns = uint.Parse(asz[2]); a_twimagememxfer.Rows = uint.Parse(asz[3]); a_twimagememxfer.XOffset = uint.Parse(asz[4]); a_twimagememxfer.YOffset = uint.Parse(asz[5]); a_twimagememxfer.BytesWritten = uint.Parse(asz[6]); a_twimagememxfer.Memory.Flags = ushort.Parse(asz[7]); a_twimagememxfer.Memory.Length = uint.Parse(asz[8]); a_twimagememxfer.Memory.TheMem = (IntPtr)ulong.Parse(asz[9]); } catch (Exception exception) { Log.Error("***error*** - " + exception.Message); return (false); } // All done... return (true); } /// /// Convert the contents of a metrics structure to a string that /// we can show in our simple GUI... /// /// A TWAIN structure /// A CSV string of the TWAIN structure public static string MetricsToCsv(TW_METRICS a_twmetrics) { try { CSV csv = new CSV(); csv.Add(a_twmetrics.SizeOf.ToString()); csv.Add(a_twmetrics.ImageCount.ToString()); csv.Add(a_twmetrics.SheetCount.ToString()); return (csv.Get()); } catch (Exception exception) { Log.Error("***error*** - " + exception.Message); return ("***error***"); } } /// /// Convert the contents of a patthru structure to a string that /// we can show in our simple GUI... /// /// A TWAIN structure /// A CSV string of the TWAIN structure public static string PassthruToCsv(TW_PASSTHRU a_twpassthru) { try { CSV csv = new CSV(); csv.Add(a_twpassthru.pCommand.ToString()); csv.Add(a_twpassthru.CommandBytes.ToString()); csv.Add(a_twpassthru.Direction.ToString()); csv.Add(a_twpassthru.pData.ToString()); csv.Add(a_twpassthru.DataBytes.ToString()); csv.Add(a_twpassthru.DataBytesXfered.ToString()); return (csv.Get()); } catch (Exception exception) { Log.Error("***error*** - " + exception.Message); return ("***error***"); } } /// /// Convert the contents of a string to a passthru structure... /// /// A TWAIN structure /// A CSV string of the TWAIN structure /// True if the conversion is successful public static bool CsvToPassthru(ref TW_PASSTHRU a_twpassthru, string a_szPassthru) { // Init stuff... a_twpassthru = default(TW_PASSTHRU); // Build the string... try { string[] asz = CSV.Parse(a_szPassthru); // Sort out the frame... a_twpassthru.pCommand = (IntPtr)UInt64.Parse(asz[0]); a_twpassthru.CommandBytes = uint.Parse(asz[1]); a_twpassthru.Direction = int.Parse(asz[2]); a_twpassthru.pData = (IntPtr)UInt64.Parse(asz[3]); a_twpassthru.DataBytes = uint.Parse(asz[4]); a_twpassthru.DataBytesXfered = uint.Parse(asz[5]); } catch (Exception exception) { Log.Error("***error*** - " + exception.Message); return (false); } // All done... return (true); } /// /// Convert the contents of a pending xfers structure to a string that /// we can show in our simple GUI... /// /// A TWAIN structure /// A CSV string of the TWAIN structure public static string PendingxfersToCsv(TW_PENDINGXFERS a_twpendingxfers) { try { CSV csv = new CSV(); csv.Add(a_twpendingxfers.Count.ToString()); csv.Add(a_twpendingxfers.EOJ.ToString()); return (csv.Get()); } catch (Exception exception) { Log.Error("***error*** - " + exception.Message); return ("***error***"); } } /// /// Convert the contents of a string to a pendingxfers structure... /// /// A TWAIN structure /// A CSV string of the TWAIN structure /// True if the conversion is successful public static bool CsvToPendingXfers(ref TW_PENDINGXFERS a_twpendingxfers, string a_szPendingxfers) { // Init stuff... a_twpendingxfers = default(TW_PENDINGXFERS); // Build the string... try { string[] asz = CSV.Parse(a_szPendingxfers); // Sort out the frame... a_twpendingxfers.Count = ushort.Parse(asz[0]); a_twpendingxfers.EOJ = uint.Parse(asz[1]); } catch (Exception exception) { Log.Error("***error*** - " + exception.Message); return (false); } // All done... return (true); } /// /// Convert the contents of a setup file xfer structure to a string that /// we can show in our simple GUI... /// /// A TWAIN structure /// A CSV string of the TWAIN structure public static string SetupfilexferToCsv(TW_SETUPFILEXFER a_twsetupfilexfer) { try { CSV csv = new CSV(); csv.Add(a_twsetupfilexfer.FileName.Get()); csv.Add("TWFF_" + a_twsetupfilexfer.Format); csv.Add(a_twsetupfilexfer.VRefNum.ToString()); return (csv.Get()); } catch (Exception exception) { Log.Error("***error*** - " + exception.Message); return ("***error***"); } } /// /// Convert a string to a setupfilexfer... /// /// A TWAIN structure /// A CSV string of the TWAIN structure /// True if the conversion is successful public static bool CsvToSetupfilexfer(ref TW_SETUPFILEXFER a_twsetupfilexfer, string a_szSetupfilexfer) { // Init stuff... a_twsetupfilexfer = default(TW_SETUPFILEXFER); // Build the string... try { string[] asz = CSV.Parse(a_szSetupfilexfer); // Sort out the values... a_twsetupfilexfer.FileName.Set(asz[0]); a_twsetupfilexfer.Format = (TWFF)ushort.Parse(CvtCapValueFromEnum(CAP.ICAP_IMAGEFILEFORMAT, asz[1])); a_twsetupfilexfer.VRefNum = short.Parse(asz[2]); } catch (Exception exception) { Log.Error("***error*** - " + exception.Message); return (false); } // All done... return (true); } /// /// Convert the contents of a setup mem xfer structure to a string that /// we can show in our simple GUI... /// /// A TWAIN structure /// A CSV string of the TWAIN structure public static string SetupmemxferToCsv(TW_SETUPMEMXFER a_twsetupmemxfer) { try { CSV csv = new CSV(); csv.Add(a_twsetupmemxfer.MinBufSize.ToString()); csv.Add(a_twsetupmemxfer.MaxBufSize.ToString()); csv.Add(a_twsetupmemxfer.Preferred.ToString()); return (csv.Get()); } catch (Exception exception) { Log.Error("***error*** - " + exception.Message); return ("***error***"); } } /// /// Convert a string to a setupmemxfer... /// /// A TWAIN structure /// A CSV string of the TWAIN structure /// True if the conversion is successful public static bool CsvToSetupmemxfer(ref TW_SETUPMEMXFER a_twsetupmemxfer, string a_szSetupmemxfer) { // Init stuff... a_twsetupmemxfer = default(TW_SETUPMEMXFER); // Build the string... try { string[] asz = CSV.Parse(a_szSetupmemxfer); // Sort out the values... a_twsetupmemxfer.MinBufSize = uint.Parse(asz[0]); a_twsetupmemxfer.MaxBufSize = uint.Parse(asz[1]); a_twsetupmemxfer.Preferred = uint.Parse(asz[2]); } catch (Exception exception) { Log.Error("***error*** - " + exception.Message); return (false); } // All done... return (true); } /// /// Convert the contents of a status structure to a string that /// we can show in our simple GUI... /// /// A TWAIN structure /// A CSV string of the TWAIN structure public static string StatusToCsv(TW_STATUS a_twstatus) { try { CSV csv = new CSV(); csv.Add(a_twstatus.ConditionCode.ToString()); csv.Add(a_twstatus.Data.ToString()); return (csv.Get()); } catch (Exception exception) { Log.Error("***error*** - " + exception.Message); return ("***error***"); } } /// /// Convert the contents of a statusutf8 structure to a string that /// we can show in our simple GUI... /// /// A TWAIN structure /// A CSV string of the TWAIN structure public string Statusutf8ToCsv(TW_STATUSUTF8 a_twstatusutf8) { try { CSV csv = new CSV(); csv.Add(a_twstatusutf8.Status.ConditionCode.ToString()); csv.Add(a_twstatusutf8.Status.Data.ToString()); IntPtr intptr = DsmMemLock(a_twstatusutf8.UTF8string); csv.Add(intptr.ToString()); DsmMemUnlock(a_twstatusutf8.UTF8string); return (csv.Get()); } catch (Exception exception) { Log.Error("***error*** - " + exception.Message); return ("***error***"); } } /// /// Convert a string to a twaindirect... /// /// A TWAIN structure /// A CSV string of the TWAIN structure /// True if the conversion is successful public static bool CsvToTwaindirect(ref TW_TWAINDIRECT a_twtwaindirect, string a_szTwaindirect) { // Init stuff... a_twtwaindirect = default(TW_TWAINDIRECT); // Build the string... try { long lTmp; string[] asz = CSV.Parse(a_szTwaindirect); // Sort out the values... if (!uint.TryParse(asz[0], out a_twtwaindirect.SizeOf)) { return (false); } if (!ushort.TryParse(asz[1], out a_twtwaindirect.CommunicationManager)) { return (false); } if (!long.TryParse(asz[2], out lTmp)) { return (false); } a_twtwaindirect.Send = new IntPtr(lTmp); if (!uint.TryParse(asz[3], out a_twtwaindirect.SendSize)) { return (false); } if (!long.TryParse(asz[4], out lTmp)) { return (false); } a_twtwaindirect.Receive = new IntPtr(lTmp); if (!uint.TryParse(asz[5], out a_twtwaindirect.ReceiveSize)) { return (false); } } catch (Exception exception) { Log.Error("***error*** - " + exception.Message); return (false); } // All done... return (true); } /// /// Convert the contents of a twaindirect structure to a string that /// we can show in our simple GUI... /// /// A TWAIN structure /// A CSV string of the TWAIN structure public static string TwaindirectToCsv(TW_TWAINDIRECT a_twtwaindirect) { try { CSV csv = new CSV(); csv.Add(a_twtwaindirect.SizeOf.ToString()); csv.Add(a_twtwaindirect.CommunicationManager.ToString()); csv.Add(a_twtwaindirect.Send.ToString()); csv.Add(a_twtwaindirect.SendSize.ToString()); csv.Add(a_twtwaindirect.Receive.ToString()); csv.Add(a_twtwaindirect.ReceiveSize.ToString()); return (csv.Get()); } catch (Exception exception) { Log.Error("***error*** - " + exception.Message); return ("***error***"); } } /// /// Convert the contents of a userinterface to a string that we can show in /// our simple GUI... /// /// A TWAIN structure /// A CSV string of the TWAIN structure public static string UserinterfaceToCsv(TW_USERINTERFACE a_twuserinterface) { try { CSV csv = new CSV(); csv.Add(CvtCapValueToEnumHelper(a_twuserinterface.ShowUI.ToString())); csv.Add(CvtCapValueToEnumHelper(a_twuserinterface.ModalUI.ToString())); csv.Add(a_twuserinterface.hParent.ToString()); return (csv.Get()); } catch (Exception exception) { Log.Error("***error*** - " + exception.Message); return ("***error***"); } } /// /// Convert a string to a userinterface... /// /// A TWAIN structure /// A CSV string of the TWAIN structure /// True if the conversion is successful public bool CsvToUserinterface(ref TW_USERINTERFACE a_twuserinterface, string a_szUserinterface) { // Init stuff... a_twuserinterface = default(TW_USERINTERFACE); // Build the string... try { string[] asz = CSV.Parse(a_szUserinterface); // Init stuff... a_twuserinterface.ShowUI = 0; a_twuserinterface.ModalUI = 0; a_twuserinterface.hParent = IntPtr.Zero; // Sort out the values... ushort.TryParse(CvtCapValueFromEnumHelper(asz[0]), out a_twuserinterface.ShowUI); ushort.TryParse(CvtCapValueFromEnumHelper(asz[1]), out a_twuserinterface.ModalUI); // Really shouldn't have this test, but I'll probably break things if I remove it... if (asz.Length >= 3) { if (asz[2].ToLowerInvariant() == "hwnd") { a_twuserinterface.hParent = m_intptrHwnd; } else { Int64 i64; if (Int64.TryParse(asz[2], out i64)) { a_twuserinterface.hParent = (IntPtr)i64; } } } } catch (Exception exception) { Log.Error("***error*** - " + exception.Message); return (false); } // All done... return (true); } /// /// Convert the contents of a transfer group to a string that we can show in /// our simple GUI... /// /// A TWAIN structure /// A CSV string of the TWAIN structure public static string XfergroupToCsv(UInt32 a_u32Xfergroup) { try { CSV csv = new CSV(); csv.Add("0x" + a_u32Xfergroup.ToString("X")); return (csv.Get()); } catch (Exception exception) { Log.Error("***error*** - " + exception.Message); return ("***error***"); } } /// /// Convert the contents of a string to a transfer group... /// /// A TWAIN structure /// A CSV string of the TWAIN structure /// True if the conversion is successful public static bool CsvToXfergroup(ref UInt32 a_u32Xfergroup, string a_szXfergroup) { // Init stuff... a_u32Xfergroup = 0; // Build the string... try { string[] asz = CSV.Parse(a_szXfergroup); // Grab the values... a_u32Xfergroup = asz[0].ToLower().StartsWith("0x") ? Convert.ToUInt32(asz[0].Remove(0, 2), 16) : Convert.ToUInt32(asz[0], 16); } catch (Exception exception) { Log.Error("***error*** - " + exception.Message); return (false); } // All done... return (true); } /// /// This mess is what tries to turn numeric constants into something /// a bit more readable... /// /// type for the conversion /// value to convert /// private static string CvtCapValueToEnumHelper(string a_szValue) { T t; Int32 i32 = 0; UInt32 u32 = 0; string szCvt = ""; // Adjust our value, as needed... if (a_szValue.StartsWith(typeof(T).Name + "_")) { a_szValue = a_szValue.Substring((typeof(T).Name + "_").Length); } // Handle enums with negative numbers... if (a_szValue.StartsWith("-")) { if (Int32.TryParse(a_szValue, out i32)) { t = (T)Enum.Parse(typeof(T), a_szValue, true); szCvt = t.ToString(); if (szCvt != i32.ToString()) { return (typeof(T).ToString().Replace("TWAINWorkingGroup.TWAIN+", "") + "_" + szCvt); } } } // Everybody else... else if (UInt32.TryParse(a_szValue, out u32)) { // Handle bool... if (typeof(T) == typeof(bool)) { if ((a_szValue == "1") || (a_szValue.ToLowerInvariant() == "true")) { return ("TRUE"); } return ("FALSE"); } // Handle DAT (which is a weird one).. else if (typeof(T) == typeof(DAT)) { UInt32 u32Dg = u32 >> 16; UInt32 u32Dat = u32 & 0xFFFF; string szDg = ((DG)u32Dg).ToString(); string szDat = ((DAT)u32Dat).ToString(); szDg = (szDg != u32Dg.ToString()) ? ("DG_" + szDg) : string.Format("0x{0:X}", u32Dg); szDat = (szDat != u32Dat.ToString()) ? ("DAT_" + szDat) : string.Format("0x{0:X}", u32Dat); return (szDg + "|" + szDat); } // Everybody else is on their own... else { // mono hurls on this, .net doesn't, so gonna help... switch (a_szValue) { default: break; case "65535": a_szValue = "-1"; break; case "65534": a_szValue = "-2"; break; case "65533": a_szValue = "-3"; break; case "65532": a_szValue = "-4"; break; } t = (T)Enum.Parse(typeof(T), a_szValue, true); } // Check to see if we changed anything... szCvt = t.ToString(); if (szCvt != u32.ToString()) { // CAP is in its final form... if (typeof(T) == typeof(CAP)) { return (szCvt); } // Everybody else needs the name decoration removed... else { return (typeof(T).ToString().Replace("TWAINWorkingGroup.TWAIN+", "") + "_" + szCvt); } } // We're probably a custom value... else { return (string.Format("0x{0:X}", u32)); } } // We're a string... return (a_szValue); } /// /// This mess is what tries to turn readable stuff into numeric constants... /// /// type for the conversion /// value to convert /// private static string CvtCapValueFromEnumHelper(string a_szValue) { // We can figure this one out on our own... if ((typeof(T).Name == "bool") || (typeof(T).Name == "Boolean")) { return (((a_szValue.ToLowerInvariant() == "true") || (a_szValue == "1")) ? "1" : "0"); } // Look for the enum prefix... if (a_szValue.ToLowerInvariant().StartsWith(typeof(T).Name.ToLowerInvariant() + "_")) { return (a_szValue.Substring((typeof(T).Name + "_").Length)); } // Er... return (a_szValue); } /// /// This mess is what tries to turn readable stuff into numeric constants... /// /// type for the conversion /// value to convert /// private static string CvtCapValueFromTwlg(string a_szValue) { // mono goes "hork", probably because the enum is wackadoodle, this // does work on .net, but what'cha gonna do? if (a_szValue.ToUpperInvariant().StartsWith("TWLG_")) { switch (a_szValue.ToUpperInvariant().Substring(5)) { default: break; case "USERLOCALE": return ("65535"); // -1, kinda... case "DAN": return ("0"); case "DUT": return ("1"); case "ENG": return ("2"); case "FCF": return ("3"); case "FIN": return ("4"); case "FRN": return ("5"); case "GER": return ("6"); case "ICE": return ("7"); case "ITN": return ("8"); case "NOR": return ("9"); case "POR": return ("10"); case "SPA": return ("11"); case "SWE": return ("12"); case "USA": return ("13"); case "AFRIKAANS": return ("14"); case "ALBANIA": return ("15"); case "ARABIC": return ("16"); case "ARABIC_ALGERIA": return ("17"); case "ARABIC_BAHRAIN": return ("18"); case "ARABIC_EGYPT": return ("19"); case "ARABIC_IRAQ": return ("20"); case "ARABIC_JORDAN": return ("21"); case "ARABIC_KUWAIT": return ("22"); case "ARABIC_LEBANON": return ("23"); case "ARABIC_LIBYA": return ("24"); case "ARABIC_MOROCCO": return ("25"); case "ARABIC_OMAN": return ("26"); case "ARABIC_QATAR": return ("27"); case "ARABIC_SAUDIARABIA": return ("28"); case "ARABIC_SYRIA": return ("29"); case "ARABIC_TUNISIA": return ("30"); case "ARABIC_UAE": return ("31"); case "ARABIC_YEMEN": return ("32"); case "BASQUE": return ("33"); case "BYELORUSSIAN": return ("34"); case "BULGARIAN": return ("35"); case "CATALAN": return ("36"); case "CHINESE": return ("37"); case "CHINESE_HONGKONG": return ("38"); case "CHINESE_PRC": return ("39"); case "CHINESE_SINGAPORE": return ("40"); case "CHINESE_SIMPLIFIED": return ("41"); case "CHINESE_TAIWAN": return ("42"); case "CHINESE_TRADITIONAL": return ("43"); case "CROATIA": return ("44"); case "CZECH": return ("45"); case "DANISH": return (((int)TWLG.DAN).ToString()); case "DUTCH": return (((int)TWLG.DUT).ToString()); case "DUTCH_BELGIAN": return ("46"); case "ENGLISH": return (((int)TWLG.ENG).ToString()); case "ENGLISH_AUSTRALIAN": return ("47"); case "ENGLISH_CANADIAN": return ("48"); case "ENGLISH_IRELAND": return ("49"); case "ENGLISH_NEWZEALAND": return ("50"); case "ENGLISH_SOUTHAFRICA": return ("51"); case "ENGLISH_UK": return ("52"); case "ENGLISH_USA": return (((int)TWLG.USA).ToString()); case "ESTONIAN": return ("53"); case "FAEROESE": return ("54"); case "FARSI": return ("55"); case "FINNISH": return (((int)TWLG.FIN).ToString()); case "FRENCH": return (((int)TWLG.FRN).ToString()); case "FRENCH_BELGIAN": return ("56"); case "FRENCH_CANADIAN": return (((int)TWLG.FCF).ToString()); case "FRENCH_LUXEMBOURG": return ("57"); case "FRENCH_SWISS": return ("58"); case "GERMAN": return (((int)TWLG.GER).ToString()); case "GERMAN_AUSTRIAN": return ("59"); case "GERMAN_LUXEMBOURG": return ("60"); case "GERMAN_LIECHTENSTEIN": return ("61"); case "GERMAN_SWISS": return ("62"); case "GREEK": return ("63"); case "HEBREW": return ("64"); case "HUNGARIAN": return ("65"); case "ICELANDIC": return (((int)TWLG.ICE).ToString()); case "INDONESIAN": return ("66"); case "ITALIAN": return (((int)TWLG.ITN).ToString()); case "ITALIAN_SWISS": return ("67"); case "JAPANESE": return ("68"); case "KOREAN": return ("69"); case "KOREAN_JOHAB": return ("70"); case "LATVIAN": return ("71"); case "LITHUANIAN": return ("72"); case "NORWEGIAN": return (((int)TWLG.NOR).ToString()); case "NORWEGIAN_BOKMAL": return ("73"); case "NORWEGIAN_NYNORSK": return ("74"); case "POLISH": return ("75"); case "PORTUGUESE": return (((int)TWLG.POR).ToString()); case "PORTUGUESE_BRAZIL": return ("76"); case "ROMANIAN": return ("77"); case "RUSSIAN": return ("78"); case "SERBIAN_LATIN": return ("79"); case "SLOVAK": return ("80"); case "SLOVENIAN": return ("81"); case "SPANISH": return (((int)TWLG.SPA).ToString()); case "SPANISH_MEXICAN": return ("82"); case "SPANISH_MODERN": return ("83"); case "SWEDISH": return (((int)TWLG.SWE).ToString()); case "THAI": return ("84"); case "TURKISH": return ("85"); case "UKRANIAN": return ("86"); case "ASSAMESE": return ("87"); case "BENGALI": return ("88"); case "BIHARI": return ("89"); case "BODO": return ("90"); case "DOGRI": return ("91"); case "GUJARATI": return ("92"); case "HARYANVI": return ("93"); case "HINDI": return ("94"); case "KANNADA": return ("95"); case "KASHMIRI": return ("96"); case "MALAYALAM": return ("97"); case "MARATHI": return ("98"); case "MARWARI": return ("99"); case "MEGHALAYAN": return ("100"); case "MIZO": return ("101"); case "NAGA": return ("102"); case "ORISSI": return ("103"); case "PUNJABI": return ("104"); case "PUSHTU": return ("105"); case "SERBIAN_CYRILLIC": return ("106"); case "SIKKIMI": return ("107"); case "SWEDISH_FINLAND": return ("108"); case "TAMIL": return ("109"); case "TELUGU": return ("110"); case "TRIPURI": return ("111"); case "URDU": return ("112"); case "VIETNAMESE": return ("113"); } } // Er... return (a_szValue); } /// /// Convert a value to the 'friendly' name, based on the capability... /// /// capability driving the conversion /// value to convert /// public static string CvtCapValueToEnum(CAP a_cap, string a_szValue) { switch (a_cap) { default: return (a_szValue); case CAP.ACAP_XFERMECH: return (CvtCapValueToEnumHelper(a_szValue)); case CAP.CAP_ALARMS: return (CvtCapValueToEnumHelper(a_szValue)); case CAP.CAP_ALARMVOLUME: return (a_szValue); case CAP.CAP_AUTHOR: return (a_szValue); case CAP.CAP_AUTOFEED: return (CvtCapValueToEnumHelper(a_szValue)); case CAP.CAP_AUTOMATICCAPTURE: return (CvtCapValueToEnumHelper(a_szValue)); case CAP.CAP_AUTOMATICSENSEMEDIUM: return (CvtCapValueToEnumHelper(a_szValue)); case CAP.CAP_AUTOSCAN: return (CvtCapValueToEnumHelper(a_szValue)); case CAP.CAP_BATTERYMINUTES: return (a_szValue); case CAP.CAP_BATTERYPERCENTAGE: return (a_szValue); case CAP.CAP_CAMERAENABLED: return (CvtCapValueToEnumHelper(a_szValue)); case CAP.CAP_CAMERAORDER: return (CvtCapValueToEnumHelper(a_szValue)); case CAP.CAP_CAMERAPREVIEWUI: return (CvtCapValueToEnumHelper(a_szValue)); case CAP.CAP_CAMERASIDE: return (CvtCapValueToEnumHelper(a_szValue)); case CAP.CAP_CAPTION: return (a_szValue); case CAP.CAP_CLEARPAGE: return (CvtCapValueToEnumHelper(a_szValue)); case CAP.CAP_CUSTOMDSDATA: return (CvtCapValueToEnumHelper(a_szValue)); case CAP.CAP_CUSTOMINTERFACEGUID: return (a_szValue); case CAP.CAP_DEVICEEVENT: return (CvtCapValueToEnumHelper(a_szValue)); case CAP.CAP_DEVICEONLINE: return (CvtCapValueToEnumHelper(a_szValue)); case CAP.CAP_DEVICETIMEDATE: return (a_szValue); case CAP.CAP_DOUBLEFEEDDETECTION: return (CvtCapValueToEnumHelper(a_szValue)); case CAP.CAP_DOUBLEFEEDDETECTIONLENGTH: return (a_szValue); case CAP.CAP_DOUBLEFEEDDETECTIONRESPONSE: return (CvtCapValueToEnumHelper(a_szValue)); case CAP.CAP_DOUBLEFEEDDETECTIONSENSITIVITY: return (CvtCapValueToEnumHelper(a_szValue)); case CAP.CAP_DUPLEX: return (CvtCapValueToEnumHelper(a_szValue)); case CAP.CAP_DUPLEXENABLED: return (CvtCapValueToEnumHelper(a_szValue)); case CAP.CAP_ENABLEDSUIONLY: return (CvtCapValueToEnumHelper(a_szValue)); case CAP.CAP_ENDORSER: return (a_szValue); case CAP.CAP_EXTENDEDCAPS: return (CvtCapValueToEnumHelper(a_szValue)); case CAP.CAP_FEEDERALIGNMENT: return (CvtCapValueToEnumHelper(a_szValue)); case CAP.CAP_FEEDERENABLED: return (CvtCapValueToEnumHelper(a_szValue)); case CAP.CAP_FEEDERLOADED: return (CvtCapValueToEnumHelper(a_szValue)); case CAP.CAP_FEEDERORDER: return (CvtCapValueToEnumHelper(a_szValue)); case CAP.CAP_FEEDERPOCKET: return (CvtCapValueToEnumHelper(a_szValue)); case CAP.CAP_FEEDERPREP: return (CvtCapValueToEnumHelper(a_szValue)); case CAP.CAP_FEEDPAGE: return (CvtCapValueToEnumHelper(a_szValue)); case CAP.CAP_IAFIELDA_LASTPAGE: return (a_szValue); case CAP.CAP_IAFIELDB_LASTPAGE: return (a_szValue); case CAP.CAP_IAFIELDC_LASTPAGE: return (a_szValue); case CAP.CAP_IAFIELDD_LASTPAGE: return (a_szValue); case CAP.CAP_IAFIELDA_LEVEL: return (CvtCapValueToEnumHelper(a_szValue)); case CAP.CAP_IAFIELDB_LEVEL: return (CvtCapValueToEnumHelper(a_szValue)); case CAP.CAP_IAFIELDC_LEVEL: return (CvtCapValueToEnumHelper(a_szValue)); case CAP.CAP_IAFIELDD_LEVEL: return (CvtCapValueToEnumHelper(a_szValue)); case CAP.CAP_IAFIELDA_PRINTFORMAT: return (a_szValue); case CAP.CAP_IAFIELDB_PRINTFORMAT: return (a_szValue); case CAP.CAP_IAFIELDC_PRINTFORMAT: return (a_szValue); case CAP.CAP_IAFIELDD_PRINTFORMAT: return (a_szValue); case CAP.CAP_IAFIELDA_VALUE: return (a_szValue); case CAP.CAP_IAFIELDB_VALUE: return (a_szValue); case CAP.CAP_IAFIELDC_VALUE: return (a_szValue); case CAP.CAP_IAFIELDD_VALUE: return (a_szValue); case CAP.CAP_IMAGEADDRESSENABLED: return (CvtCapValueToEnumHelper(a_szValue)); case CAP.CAP_INDICATORS: return (CvtCapValueToEnumHelper(a_szValue)); case CAP.CAP_INDICATORSMODE: return (CvtCapValueToEnumHelper(a_szValue)); case CAP.CAP_JOBCONTROL: return (CvtCapValueToEnumHelper(a_szValue)); case CAP.CAP_LANGUAGE: return (CvtCapValueToEnumHelper(a_szValue)); case CAP.CAP_MAXBATCHBUFFERS: return (a_szValue); case CAP.CAP_MICRENABLED: return (CvtCapValueToEnumHelper(a_szValue)); case CAP.CAP_PAPERDETECTABLE: return (CvtCapValueToEnumHelper(a_szValue)); case CAP.CAP_PAPERHANDLING: return (CvtCapValueToEnumHelper(a_szValue)); case CAP.CAP_POWERSAVETIME: return (a_szValue); case CAP.CAP_POWERSUPPLY: return (CvtCapValueToEnumHelper(a_szValue)); case CAP.CAP_PRINTER: return (CvtCapValueToEnumHelper(a_szValue)); case CAP.CAP_PRINTERCHARROTATION: return (a_szValue); case CAP.CAP_PRINTERENABLED: return (CvtCapValueToEnumHelper(a_szValue)); case CAP.CAP_PRINTERFONTSTYLE: return (CvtCapValueToEnumHelper(a_szValue)); case CAP.CAP_PRINTERINDEX: return (a_szValue); case CAP.CAP_PRINTERINDEXLEADCHAR: return (a_szValue); case CAP.CAP_PRINTERINDEXMAXVALUE: return (a_szValue); case CAP.CAP_PRINTERINDEXNUMDIGITS: return (a_szValue); case CAP.CAP_PRINTERINDEXSTEP: return (a_szValue); case CAP.CAP_PRINTERINDEXTRIGGER: return (CvtCapValueToEnumHelper(a_szValue)); case CAP.CAP_PRINTERMODE: return (CvtCapValueToEnumHelper(a_szValue)); case CAP.CAP_PRINTERSTRING: return (a_szValue); case CAP.CAP_PRINTERSTRINGPREVIEW: return (a_szValue); case CAP.CAP_PRINTERSUFFIX: return (a_szValue); case CAP.CAP_PRINTERVERTICALOFFSET: return (a_szValue); case CAP.CAP_REACQUIREALLOWED: return (CvtCapValueToEnumHelper(a_szValue)); case CAP.CAP_REWINDPAGE: return (CvtCapValueToEnumHelper(a_szValue)); case CAP.CAP_SEGMENTED: return (CvtCapValueToEnumHelper(a_szValue)); case CAP.CAP_SERIALNUMBER: return (a_szValue); case CAP.CAP_SHEETCOUNT: return (a_szValue); case CAP.CAP_SUPPORTEDCAPS: return (CvtCapValueToEnumHelper(a_szValue)); case CAP.CAP_SUPPORTEDCAPSSEGMENTUNIQUE: return (CvtCapValueToEnumHelper(a_szValue)); case CAP.CAP_SUPPORTEDDATS: return (CvtCapValueToEnumHelper(a_szValue)); case CAP.CAP_THUMBNAILSENABLED: return (CvtCapValueToEnumHelper(a_szValue)); case CAP.CAP_TIMEBEFOREFIRSTCAPTURE: return (a_szValue); case CAP.CAP_TIMEBETWEENCAPTURES: return (a_szValue); case CAP.CAP_TIMEDATE: return (a_szValue); case CAP.CAP_UICONTROLLABLE: return (CvtCapValueToEnumHelper(a_szValue)); case CAP.CAP_XFERCOUNT: return (a_szValue); case CAP.ICAP_AUTOBRIGHT: return (CvtCapValueToEnumHelper(a_szValue)); case CAP.ICAP_AUTODISCARDBLANKPAGES: return (a_szValue); case CAP.ICAP_AUTOMATICBORDERDETECTION: return (CvtCapValueToEnumHelper(a_szValue)); case CAP.ICAP_AUTOMATICCOLORENABLED: return (CvtCapValueToEnumHelper(a_szValue)); case CAP.ICAP_AUTOMATICCOLORNONCOLORPIXELTYPE: return (CvtCapValueToEnumHelper(a_szValue)); case CAP.ICAP_AUTOMATICCROPUSESFRAME: return (CvtCapValueToEnumHelper(a_szValue)); case CAP.ICAP_AUTOMATICDESKEW: return (CvtCapValueToEnumHelper(a_szValue)); case CAP.ICAP_AUTOMATICLENGTHDETECTION: return (CvtCapValueToEnumHelper(a_szValue)); case CAP.ICAP_AUTOMATICROTATE: return (CvtCapValueToEnumHelper(a_szValue)); case CAP.ICAP_AUTOSIZE: return (CvtCapValueToEnumHelper(a_szValue)); case CAP.ICAP_BARCODEDETECTIONENABLED: return (CvtCapValueToEnumHelper(a_szValue)); case CAP.ICAP_BARCODEMAXRETRIES: return (a_szValue); case CAP.ICAP_BARCODEMAXSEARCHPRIORITIES: return (a_szValue); case CAP.ICAP_BARCODESEARCHMODE: return (CvtCapValueToEnumHelper(a_szValue)); case CAP.ICAP_BARCODESEARCHPRIORITIES: return (CvtCapValueToEnumHelper(a_szValue)); case CAP.ICAP_BARCODETIMEOUT: return (a_szValue); case CAP.ICAP_BITDEPTH: return (a_szValue); case CAP.ICAP_BITDEPTHREDUCTION: return (CvtCapValueToEnumHelper(a_szValue)); case CAP.ICAP_BITORDER: return (CvtCapValueToEnumHelper(a_szValue)); case CAP.ICAP_BITORDERCODES: return (CvtCapValueToEnumHelper(a_szValue)); case CAP.ICAP_BRIGHTNESS: return (a_szValue); case CAP.ICAP_CCITTKFACTOR: return (a_szValue); case CAP.ICAP_COLORMANAGEMENTENABLED: return (CvtCapValueToEnumHelper(a_szValue)); case CAP.ICAP_COMPRESSION: return (CvtCapValueToEnumHelper(a_szValue)); case CAP.ICAP_CONTRAST: return (a_szValue); case CAP.ICAP_CUSTHALFTONE: return (a_szValue); case CAP.ICAP_EXPOSURETIME: return (a_szValue); case CAP.ICAP_EXTIMAGEINFO: return (CvtCapValueToEnumHelper(a_szValue)); case CAP.ICAP_FEEDERTYPE: return (CvtCapValueToEnumHelper(a_szValue)); case CAP.ICAP_FILMTYPE: return (CvtCapValueToEnumHelper(a_szValue)); case CAP.ICAP_FILTER: return (CvtCapValueToEnumHelper(a_szValue)); case CAP.ICAP_FLASHUSED: return (CvtCapValueToEnumHelper(a_szValue)); case CAP.ICAP_FLASHUSED2: return (CvtCapValueToEnumHelper(a_szValue)); case CAP.ICAP_FLIPROTATION: return (CvtCapValueToEnumHelper(a_szValue)); case CAP.ICAP_FRAMES: return (a_szValue); case CAP.ICAP_GAMMA: return (a_szValue); case CAP.ICAP_HALFTONES: return (a_szValue); case CAP.ICAP_HIGHLIGHT: return (a_szValue); case CAP.ICAP_ICCPROFILE: return (CvtCapValueToEnumHelper(a_szValue)); case CAP.ICAP_IMAGEDATASET: return (a_szValue); case CAP.ICAP_IMAGEFILEFORMAT: return (CvtCapValueToEnumHelper(a_szValue)); case CAP.ICAP_IMAGEFILTER: return (CvtCapValueToEnumHelper(a_szValue)); case CAP.ICAP_IMAGEMERGE: return (CvtCapValueToEnumHelper(a_szValue)); case CAP.ICAP_IMAGEMERGEHEIGHTTHRESHOLD: return (a_szValue); case CAP.ICAP_JPEGPIXELTYPE: return (CvtCapValueToEnumHelper(a_szValue)); case CAP.ICAP_JPEGQUALITY: return (CvtCapValueToEnumHelper(a_szValue)); case CAP.ICAP_JPEGSUBSAMPLING: return (CvtCapValueToEnumHelper(a_szValue)); case CAP.ICAP_LAMPSTATE: return (CvtCapValueToEnumHelper(a_szValue)); case CAP.ICAP_LIGHTPATH: return (CvtCapValueToEnumHelper(a_szValue)); case CAP.ICAP_LIGHTSOURCE: return (CvtCapValueToEnumHelper(a_szValue)); case CAP.ICAP_MAXFRAMES: return (a_szValue); case CAP.ICAP_MINIMUMHEIGHT: return (a_szValue); case CAP.ICAP_MINIMUMWIDTH: return (a_szValue); case CAP.ICAP_MIRROR: return (CvtCapValueToEnumHelper(a_szValue)); case CAP.ICAP_NOISEFILTER: return (CvtCapValueToEnumHelper(a_szValue)); case CAP.ICAP_ORIENTATION: return (CvtCapValueToEnumHelper(a_szValue)); case CAP.ICAP_OVERSCAN: return (CvtCapValueToEnumHelper(a_szValue)); case CAP.ICAP_PATCHCODEDETECTIONENABLED: return (CvtCapValueToEnumHelper(a_szValue)); case CAP.ICAP_PATCHCODEMAXRETRIES: return (a_szValue); case CAP.ICAP_PATCHCODEMAXSEARCHPRIORITIES: return (a_szValue); case CAP.ICAP_PATCHCODESEARCHMODE: return (CvtCapValueToEnumHelper(a_szValue)); case CAP.ICAP_PATCHCODESEARCHPRIORITIES: return (CvtCapValueToEnumHelper(a_szValue)); case CAP.ICAP_PATCHCODETIMEOUT: return (a_szValue); case CAP.ICAP_PHYSICALHEIGHT: return (a_szValue); case CAP.ICAP_PHYSICALWIDTH: return (a_szValue); case CAP.ICAP_PIXELFLAVOR: return (CvtCapValueToEnumHelper(a_szValue)); case CAP.ICAP_PIXELFLAVORCODES: return (CvtCapValueToEnumHelper(a_szValue)); case CAP.ICAP_PIXELTYPE: return (CvtCapValueToEnumHelper(a_szValue)); case CAP.ICAP_PLANARCHUNKY: return (CvtCapValueToEnumHelper(a_szValue)); case CAP.ICAP_ROTATION: return (a_szValue); case CAP.ICAP_SHADOW: return (a_szValue); case CAP.ICAP_SUPPORTEDBARCODETYPES: return (CvtCapValueToEnumHelper(a_szValue)); case CAP.ICAP_SUPPORTEDEXTIMAGEINFO: return (CvtCapValueToEnumHelper(a_szValue)); case CAP.ICAP_SUPPORTEDPATCHCODETYPES: return (CvtCapValueToEnumHelper(a_szValue)); case CAP.ICAP_SUPPORTEDSIZES: return (CvtCapValueToEnumHelper(a_szValue)); case CAP.ICAP_THRESHOLD: return (a_szValue); case CAP.ICAP_TILES: return (CvtCapValueToEnumHelper(a_szValue)); case CAP.ICAP_TIMEFILL: return (a_szValue); case CAP.ICAP_UNDEFINEDIMAGESIZE: return (CvtCapValueToEnumHelper(a_szValue)); case CAP.ICAP_UNITS: return (CvtCapValueToEnumHelper(a_szValue)); case CAP.ICAP_XFERMECH: return (CvtCapValueToEnumHelper(a_szValue)); case CAP.ICAP_XNATIVERESOLUTION: return (a_szValue); case CAP.ICAP_XRESOLUTION: return (a_szValue); case CAP.ICAP_XSCALING: return (a_szValue); case CAP.ICAP_YNATIVERESOLUTION: return (a_szValue); case CAP.ICAP_YRESOLUTION: return (a_szValue); case CAP.ICAP_YSCALING: return (a_szValue); case CAP.ICAP_ZOOMFACTOR: return (a_szValue); } } /// /// Convert a 'friendly' name to a numeric value... /// /// capability driving the conversion /// value to convert /// public static string CvtCapValueFromEnum(CAP a_cap, string a_szValue) { int ii; // Turn hex into a decimal... if (a_szValue.ToLowerInvariant().StartsWith("0x")) { return (int.Parse(a_szValue.Substring(2), NumberStyles.HexNumber).ToString()); } // Skip numbers... if (int.TryParse(a_szValue, out ii)) { return (a_szValue); } // Process text... switch (a_cap) { default: return (a_szValue); case CAP.ACAP_XFERMECH: { TWSX twsx; return (Enum.TryParse(CvtCapValueFromEnumHelper(a_szValue), out twsx) ? ((int)twsx).ToString() : a_szValue); }; case CAP.CAP_ALARMS: { TWAL twal; return (Enum.TryParse(CvtCapValueFromEnumHelper(a_szValue), out twal) ? ((int)twal).ToString() : a_szValue); }; case CAP.CAP_ALARMVOLUME: return (a_szValue); case CAP.CAP_AUTHOR: return (a_szValue); case CAP.CAP_AUTOFEED: return (CvtCapValueFromEnumHelper(a_szValue)); case CAP.CAP_AUTOMATICCAPTURE: return (CvtCapValueFromEnumHelper(a_szValue)); case CAP.CAP_AUTOMATICSENSEMEDIUM: return (CvtCapValueFromEnumHelper(a_szValue)); case CAP.CAP_AUTOSCAN: return (CvtCapValueFromEnumHelper(a_szValue)); case CAP.CAP_BATTERYMINUTES: return (a_szValue); case CAP.CAP_BATTERYPERCENTAGE: return (a_szValue); case CAP.CAP_CAMERAENABLED: return (CvtCapValueFromEnumHelper(a_szValue)); case CAP.CAP_CAMERAORDER: { TWPT twpt; return (Enum.TryParse(CvtCapValueFromEnumHelper(a_szValue), out twpt) ? ((int)twpt).ToString() : a_szValue); }; case CAP.CAP_CAMERAPREVIEWUI: return (CvtCapValueFromEnumHelper(a_szValue)); case CAP.CAP_CAMERASIDE: { TWCS twcs; return (Enum.TryParse(CvtCapValueFromEnumHelper(a_szValue), out twcs) ? ((int)twcs).ToString() : a_szValue); }; case CAP.CAP_CAPTION: return (a_szValue); case CAP.CAP_CLEARPAGE: return (CvtCapValueFromEnumHelper(a_szValue)); case CAP.CAP_CUSTOMDSDATA: return (CvtCapValueFromEnumHelper(a_szValue)); case CAP.CAP_CUSTOMINTERFACEGUID: return (a_szValue); case CAP.CAP_DEVICEEVENT: { TWDE twde; return (Enum.TryParse(CvtCapValueFromEnumHelper(a_szValue), out twde) ? ((int)twde).ToString() : a_szValue); }; case CAP.CAP_DEVICEONLINE: return (CvtCapValueFromEnumHelper(a_szValue)); case CAP.CAP_DEVICETIMEDATE: return (a_szValue); case CAP.CAP_DOUBLEFEEDDETECTION: { TWDF twdf; return (Enum.TryParse(CvtCapValueFromEnumHelper(a_szValue), out twdf) ? ((int)twdf).ToString() : a_szValue); }; case CAP.CAP_DOUBLEFEEDDETECTIONLENGTH: return (a_szValue); case CAP.CAP_DOUBLEFEEDDETECTIONRESPONSE: { TWDP twdp; return (Enum.TryParse(CvtCapValueFromEnumHelper(a_szValue), out twdp) ? ((int)twdp).ToString() : a_szValue); }; case CAP.CAP_DOUBLEFEEDDETECTIONSENSITIVITY: { TWUS twus; return (Enum.TryParse(CvtCapValueFromEnumHelper(a_szValue), out twus) ? ((int)twus).ToString() : a_szValue); }; case CAP.CAP_DUPLEX: { TWDX twdx; return (Enum.TryParse(CvtCapValueFromEnumHelper(a_szValue), out twdx) ? ((int)twdx).ToString() : a_szValue); }; case CAP.CAP_DUPLEXENABLED: return (CvtCapValueFromEnumHelper(a_szValue)); case CAP.CAP_ENABLEDSUIONLY: return (CvtCapValueFromEnumHelper(a_szValue)); case CAP.CAP_ENDORSER: return (a_szValue); case CAP.CAP_EXTENDEDCAPS: { CAP cap; return (Enum.TryParse(CvtCapValueFromEnumHelper(a_szValue), out cap) ? ((int)cap).ToString() : a_szValue); }; case CAP.CAP_FEEDERALIGNMENT: { TWFA twfa; return (Enum.TryParse(CvtCapValueFromEnumHelper(a_szValue), out twfa) ? ((int)twfa).ToString() : a_szValue); }; case CAP.CAP_FEEDERENABLED: return (CvtCapValueFromEnumHelper(a_szValue)); case CAP.CAP_FEEDERLOADED: return (CvtCapValueFromEnumHelper(a_szValue)); case CAP.CAP_FEEDERORDER: { TWFO twfo; return (Enum.TryParse(CvtCapValueFromEnumHelper(a_szValue), out twfo) ? ((int)twfo).ToString() : a_szValue); }; case CAP.CAP_FEEDERPOCKET: { TWFP twfp; return (Enum.TryParse(CvtCapValueFromEnumHelper(a_szValue), out twfp) ? ((int)twfp).ToString() : a_szValue); }; case CAP.CAP_FEEDERPREP: return (CvtCapValueFromEnumHelper(a_szValue)); case CAP.CAP_FEEDPAGE: return (CvtCapValueFromEnumHelper(a_szValue)); case CAP.CAP_IAFIELDA_LASTPAGE: return (a_szValue); case CAP.CAP_IAFIELDB_LASTPAGE: return (a_szValue); case CAP.CAP_IAFIELDC_LASTPAGE: return (a_szValue); case CAP.CAP_IAFIELDD_LASTPAGE: return (a_szValue); case CAP.CAP_IAFIELDA_LEVEL: { TWIA twia; return (Enum.TryParse(CvtCapValueFromEnumHelper(a_szValue), out twia) ? ((int)twia).ToString() : a_szValue); }; case CAP.CAP_IAFIELDB_LEVEL: { TWIA twia; return (Enum.TryParse(CvtCapValueFromEnumHelper(a_szValue), out twia) ? ((int)twia).ToString() : a_szValue); }; case CAP.CAP_IAFIELDC_LEVEL: { TWIA twia; return (Enum.TryParse(CvtCapValueFromEnumHelper(a_szValue), out twia) ? ((int)twia).ToString() : a_szValue); }; case CAP.CAP_IAFIELDD_LEVEL: { TWIA twia; return (Enum.TryParse(CvtCapValueFromEnumHelper(a_szValue), out twia) ? ((int)twia).ToString() : a_szValue); }; case CAP.CAP_IAFIELDA_PRINTFORMAT: return (a_szValue); case CAP.CAP_IAFIELDB_PRINTFORMAT: return (a_szValue); case CAP.CAP_IAFIELDC_PRINTFORMAT: return (a_szValue); case CAP.CAP_IAFIELDD_PRINTFORMAT: return (a_szValue); case CAP.CAP_IAFIELDA_VALUE: return (a_szValue); case CAP.CAP_IAFIELDB_VALUE: return (a_szValue); case CAP.CAP_IAFIELDC_VALUE: return (a_szValue); case CAP.CAP_IAFIELDD_VALUE: return (a_szValue); case CAP.CAP_IMAGEADDRESSENABLED: return (CvtCapValueFromEnumHelper(a_szValue)); case CAP.CAP_INDICATORS: return (CvtCapValueFromEnumHelper(a_szValue)); case CAP.CAP_INDICATORSMODE: { TWCI twci; return (Enum.TryParse(CvtCapValueFromEnumHelper(a_szValue), out twci) ? ((int)twci).ToString() : a_szValue); }; case CAP.CAP_JOBCONTROL: { TWJC twjc; return (Enum.TryParse(CvtCapValueFromEnumHelper(a_szValue), out twjc) ? ((int)twjc).ToString() : a_szValue); }; case CAP.CAP_LANGUAGE: return(CvtCapValueFromTwlg(a_szValue)); case CAP.CAP_MAXBATCHBUFFERS: return (a_szValue); case CAP.CAP_MICRENABLED: return (CvtCapValueFromEnumHelper(a_szValue)); case CAP.CAP_PAPERDETECTABLE: return (CvtCapValueFromEnumHelper(a_szValue)); case CAP.CAP_PAPERHANDLING: { TWPH twph; return (Enum.TryParse(CvtCapValueFromEnumHelper(a_szValue), out twph) ? ((int)twph).ToString() : a_szValue); }; case CAP.CAP_POWERSAVETIME: return (a_szValue); case CAP.CAP_POWERSUPPLY: { TWPS twps; return (Enum.TryParse(CvtCapValueFromEnumHelper(a_szValue), out twps) ? ((int)twps).ToString() : a_szValue); }; case CAP.CAP_PRINTER: { TWPR twpr; return (Enum.TryParse(CvtCapValueFromEnumHelper(a_szValue), out twpr) ? ((int)twpr).ToString() : a_szValue); }; case CAP.CAP_PRINTERCHARROTATION: return (a_szValue); case CAP.CAP_PRINTERENABLED: return (CvtCapValueFromEnumHelper(a_szValue)); case CAP.CAP_PRINTERFONTSTYLE: { TWPF twpf; return (Enum.TryParse(CvtCapValueFromEnumHelper(a_szValue), out twpf) ? ((int)twpf).ToString() : a_szValue); }; case CAP.CAP_PRINTERINDEX: return (a_szValue); case CAP.CAP_PRINTERINDEXLEADCHAR: return (a_szValue); case CAP.CAP_PRINTERINDEXMAXVALUE: return (a_szValue); case CAP.CAP_PRINTERINDEXNUMDIGITS: return (a_szValue); case CAP.CAP_PRINTERINDEXSTEP: return (a_szValue); case CAP.CAP_PRINTERINDEXTRIGGER: { TWCT twct; return (Enum.TryParse(CvtCapValueFromEnumHelper(a_szValue), out twct) ? ((int)twct).ToString() : a_szValue); }; case CAP.CAP_PRINTERMODE: { TWPM twpm; return (Enum.TryParse(CvtCapValueFromEnumHelper(a_szValue), out twpm) ? ((int)twpm).ToString() : a_szValue); }; case CAP.CAP_PRINTERSTRING: return (a_szValue); case CAP.CAP_PRINTERSTRINGPREVIEW: return (a_szValue); case CAP.CAP_PRINTERSUFFIX: return (a_szValue); case CAP.CAP_PRINTERVERTICALOFFSET: return (a_szValue); case CAP.CAP_REACQUIREALLOWED: return (CvtCapValueFromEnumHelper(a_szValue)); case CAP.CAP_REWINDPAGE: return (CvtCapValueFromEnumHelper(a_szValue)); case CAP.CAP_SEGMENTED: { TWSG twsg; return (Enum.TryParse(CvtCapValueFromEnumHelper(a_szValue), out twsg) ? ((int)twsg).ToString() : a_szValue); }; case CAP.CAP_SERIALNUMBER: return (a_szValue); case CAP.CAP_SHEETCOUNT: return (a_szValue); case CAP.CAP_SUPPORTEDCAPS: { CAP cap; return (Enum.TryParse(CvtCapValueFromEnumHelper(a_szValue), out cap) ? ((int)cap).ToString() : a_szValue); }; case CAP.CAP_SUPPORTEDCAPSSEGMENTUNIQUE: { CAP cap; return (Enum.TryParse(CvtCapValueFromEnumHelper(a_szValue), out cap) ? ((int)cap).ToString() : a_szValue); }; case CAP.CAP_SUPPORTEDDATS: { DAT dat; return (Enum.TryParse(CvtCapValueFromEnumHelper(a_szValue), out dat) ? ((int)dat).ToString() : a_szValue); }; case CAP.CAP_THUMBNAILSENABLED: return (CvtCapValueFromEnumHelper(a_szValue)); case CAP.CAP_TIMEBEFOREFIRSTCAPTURE: return (a_szValue); case CAP.CAP_TIMEBETWEENCAPTURES: return (a_szValue); case CAP.CAP_TIMEDATE: return (a_szValue); case CAP.CAP_UICONTROLLABLE: return (CvtCapValueFromEnumHelper(a_szValue)); case CAP.CAP_XFERCOUNT: return (a_szValue); case CAP.ICAP_AUTOBRIGHT: return (CvtCapValueFromEnumHelper(a_szValue)); case CAP.ICAP_AUTODISCARDBLANKPAGES: { TWBP twbp; return (Enum.TryParse(CvtCapValueFromEnumHelper(a_szValue), out twbp) ? ((int)twbp).ToString() : a_szValue); }; case CAP.ICAP_AUTOMATICBORDERDETECTION: return (CvtCapValueFromEnumHelper(a_szValue)); case CAP.ICAP_AUTOMATICCOLORENABLED: return (CvtCapValueFromEnumHelper(a_szValue)); case CAP.ICAP_AUTOMATICCOLORNONCOLORPIXELTYPE: { TWPT twpt; return (Enum.TryParse(CvtCapValueFromEnumHelper(a_szValue), out twpt) ? ((int)twpt).ToString() : a_szValue); }; case CAP.ICAP_AUTOMATICCROPUSESFRAME: return (CvtCapValueFromEnumHelper(a_szValue)); case CAP.ICAP_AUTOMATICDESKEW: return (CvtCapValueFromEnumHelper(a_szValue)); case CAP.ICAP_AUTOMATICLENGTHDETECTION: return (CvtCapValueFromEnumHelper(a_szValue)); case CAP.ICAP_AUTOMATICROTATE: return (CvtCapValueFromEnumHelper(a_szValue)); case CAP.ICAP_AUTOSIZE: { TWAS twas; return (Enum.TryParse(CvtCapValueFromEnumHelper(a_szValue), out twas) ? ((int)twas).ToString() : a_szValue); }; case CAP.ICAP_BARCODEDETECTIONENABLED: return (CvtCapValueFromEnumHelper(a_szValue)); case CAP.ICAP_BARCODEMAXRETRIES: return (a_szValue); case CAP.ICAP_BARCODEMAXSEARCHPRIORITIES: return (a_szValue); case CAP.ICAP_BARCODESEARCHMODE: { TWBD twbd; return (Enum.TryParse(CvtCapValueFromEnumHelper(a_szValue), out twbd) ? ((int)twbd).ToString() : a_szValue); }; case CAP.ICAP_BARCODESEARCHPRIORITIES: { TWBT twbt; return (Enum.TryParse(CvtCapValueFromEnumHelper(a_szValue), out twbt) ? ((int)twbt).ToString() : a_szValue); }; case CAP.ICAP_BARCODETIMEOUT: return (a_szValue); case CAP.ICAP_BITDEPTH: return (a_szValue); case CAP.ICAP_BITDEPTHREDUCTION: { TWBR twbr; return (Enum.TryParse(CvtCapValueFromEnumHelper(a_szValue), out twbr) ? ((int)twbr).ToString() : a_szValue); }; case CAP.ICAP_BITORDER: { TWBO twbo; return (Enum.TryParse(CvtCapValueFromEnumHelper(a_szValue), out twbo) ? ((int)twbo).ToString() : a_szValue); }; case CAP.ICAP_BITORDERCODES: { TWBO twbo; return (Enum.TryParse(CvtCapValueFromEnumHelper(a_szValue), out twbo) ? ((int)twbo).ToString() : a_szValue); }; case CAP.ICAP_BRIGHTNESS: return (a_szValue); case CAP.ICAP_CCITTKFACTOR: return (a_szValue); case CAP.ICAP_COLORMANAGEMENTENABLED: return (CvtCapValueFromEnumHelper(a_szValue)); case CAP.ICAP_COMPRESSION: { TWCP twcp; return (Enum.TryParse(CvtCapValueFromEnumHelper(a_szValue), out twcp) ? ((int)twcp).ToString() : a_szValue); }; case CAP.ICAP_CONTRAST: return (a_szValue); case CAP.ICAP_CUSTHALFTONE: return (a_szValue); case CAP.ICAP_EXPOSURETIME: return (a_szValue); case CAP.ICAP_EXTIMAGEINFO: return (CvtCapValueFromEnumHelper(a_szValue)); case CAP.ICAP_FEEDERTYPE: { TWFE twfe; return (Enum.TryParse(CvtCapValueFromEnumHelper(a_szValue), out twfe) ? ((int)twfe).ToString() : a_szValue); }; case CAP.ICAP_FILMTYPE: { TWFM twfm; return (Enum.TryParse(CvtCapValueFromEnumHelper(a_szValue), out twfm) ? ((int)twfm).ToString() : a_szValue); }; case CAP.ICAP_FILTER: { TWFT twft; return (Enum.TryParse(CvtCapValueFromEnumHelper(a_szValue), out twft) ? ((int)twft).ToString() : a_szValue); }; case CAP.ICAP_FLASHUSED: return (CvtCapValueFromEnumHelper(a_szValue)); case CAP.ICAP_FLASHUSED2: { TWFL twfl; return (Enum.TryParse(CvtCapValueFromEnumHelper(a_szValue), out twfl) ? ((int)twfl).ToString() : a_szValue); }; case CAP.ICAP_FLIPROTATION: { TWFR twfr; return (Enum.TryParse(CvtCapValueFromEnumHelper(a_szValue), out twfr) ? ((int)twfr).ToString() : a_szValue); }; case CAP.ICAP_FRAMES: return (a_szValue); case CAP.ICAP_GAMMA: return (a_szValue); case CAP.ICAP_HALFTONES: return (a_szValue); case CAP.ICAP_HIGHLIGHT: return (a_szValue); case CAP.ICAP_ICCPROFILE: { TWIC twic; return (Enum.TryParse(CvtCapValueFromEnumHelper(a_szValue), out twic) ? ((int)twic).ToString() : a_szValue); }; case CAP.ICAP_IMAGEDATASET: return (a_szValue); case CAP.ICAP_IMAGEFILEFORMAT: { TWFF twff; return (Enum.TryParse(CvtCapValueFromEnumHelper(a_szValue), out twff) ? ((int)twff).ToString() : a_szValue); }; case CAP.ICAP_IMAGEFILTER: { TWIF twif; return (Enum.TryParse(CvtCapValueFromEnumHelper(a_szValue), out twif) ? ((int)twif).ToString() : a_szValue); }; case CAP.ICAP_IMAGEMERGE: { TWIM twim; return (Enum.TryParse(CvtCapValueFromEnumHelper(a_szValue), out twim) ? ((int)twim).ToString() : a_szValue); }; case CAP.ICAP_IMAGEMERGEHEIGHTTHRESHOLD: return (a_szValue); case CAP.ICAP_JPEGPIXELTYPE: { TWPT twpt; return (Enum.TryParse(CvtCapValueFromEnumHelper(a_szValue), out twpt) ? ((int)twpt).ToString() : a_szValue); }; case CAP.ICAP_JPEGQUALITY: { TWJQ twjq; return (Enum.TryParse(CvtCapValueFromEnumHelper(a_szValue), out twjq) ? ((int)twjq).ToString() : a_szValue); }; case CAP.ICAP_JPEGSUBSAMPLING: { TWJS twjs; return (Enum.TryParse(CvtCapValueFromEnumHelper(a_szValue), out twjs) ? ((int)twjs).ToString() : a_szValue); }; case CAP.ICAP_LAMPSTATE: return (CvtCapValueFromEnumHelper(a_szValue)); case CAP.ICAP_LIGHTPATH: { TWLP twlp; return (Enum.TryParse(CvtCapValueFromEnumHelper(a_szValue), out twlp) ? ((int)twlp).ToString() : a_szValue); }; case CAP.ICAP_LIGHTSOURCE: { TWLS twls; return (Enum.TryParse(CvtCapValueFromEnumHelper(a_szValue), out twls) ? ((int)twls).ToString() : a_szValue); }; case CAP.ICAP_MAXFRAMES: return (a_szValue); case CAP.ICAP_MINIMUMHEIGHT: return (a_szValue); case CAP.ICAP_MINIMUMWIDTH: return (a_szValue); case CAP.ICAP_MIRROR: { TWMR twmr; return (Enum.TryParse(CvtCapValueFromEnumHelper(a_szValue), out twmr) ? ((int)twmr).ToString() : a_szValue); }; case CAP.ICAP_NOISEFILTER: { TWNF twnf; return (Enum.TryParse(CvtCapValueFromEnumHelper(a_szValue), out twnf) ? ((int)twnf).ToString() : a_szValue); }; case CAP.ICAP_ORIENTATION: { TWOR twor; return (Enum.TryParse(CvtCapValueFromEnumHelper(a_szValue), out twor) ? ((int)twor).ToString() : a_szValue); }; case CAP.ICAP_OVERSCAN: { TWOV twov; return (Enum.TryParse(CvtCapValueFromEnumHelper(a_szValue), out twov) ? ((int)twov).ToString() : a_szValue); }; case CAP.ICAP_PATCHCODEDETECTIONENABLED: return (CvtCapValueFromEnumHelper(a_szValue)); case CAP.ICAP_PATCHCODEMAXRETRIES: return (a_szValue); case CAP.ICAP_PATCHCODEMAXSEARCHPRIORITIES: return (a_szValue); case CAP.ICAP_PATCHCODESEARCHMODE: { TWBD twbd; return (Enum.TryParse(CvtCapValueFromEnumHelper(a_szValue), out twbd) ? ((int)twbd).ToString() : a_szValue); }; case CAP.ICAP_PATCHCODESEARCHPRIORITIES: { TWPCH twpch; return (Enum.TryParse(CvtCapValueFromEnumHelper(a_szValue), out twpch) ? ((int)twpch).ToString() : a_szValue); }; case CAP.ICAP_PATCHCODETIMEOUT: return (a_szValue); case CAP.ICAP_PHYSICALHEIGHT: return (a_szValue); case CAP.ICAP_PHYSICALWIDTH: return (a_szValue); case CAP.ICAP_PIXELFLAVOR: { TWPF twpf; return (Enum.TryParse(CvtCapValueFromEnumHelper(a_szValue), out twpf) ? ((int)twpf).ToString() : a_szValue); }; case CAP.ICAP_PIXELFLAVORCODES: { TWPF twpf; return (Enum.TryParse(CvtCapValueFromEnumHelper(a_szValue), out twpf) ? ((int)twpf).ToString() : a_szValue); }; case CAP.ICAP_PIXELTYPE: { TWPT twpt; return (Enum.TryParse(CvtCapValueFromEnumHelper(a_szValue), out twpt) ? ((int)twpt).ToString() : a_szValue); }; case CAP.ICAP_PLANARCHUNKY: { TWPC twpc; return (Enum.TryParse(CvtCapValueFromEnumHelper(a_szValue), out twpc) ? ((int)twpc).ToString() : a_szValue); }; case CAP.ICAP_ROTATION: return (a_szValue); case CAP.ICAP_SHADOW: return (a_szValue); case CAP.ICAP_SUPPORTEDBARCODETYPES: { TWBT twbt; return (Enum.TryParse(CvtCapValueFromEnumHelper(a_szValue), out twbt) ? ((int)twbt).ToString() : a_szValue); }; case CAP.ICAP_SUPPORTEDEXTIMAGEINFO: { TWEI twei; return (Enum.TryParse(CvtCapValueFromEnumHelper(a_szValue), out twei) ? ((int)twei).ToString() : a_szValue); }; case CAP.ICAP_SUPPORTEDPATCHCODETYPES: { TWPCH twpch; return (Enum.TryParse(CvtCapValueFromEnumHelper(a_szValue), out twpch) ? ((int)twpch).ToString() : a_szValue); }; case CAP.ICAP_SUPPORTEDSIZES: { TWSS twss; return (Enum.TryParse(CvtCapValueFromEnumHelper(a_szValue), out twss) ? ((int)twss).ToString() : a_szValue); }; case CAP.ICAP_THRESHOLD: return (a_szValue); case CAP.ICAP_TILES: return (CvtCapValueFromEnumHelper(a_szValue)); case CAP.ICAP_TIMEFILL: return (a_szValue); case CAP.ICAP_UNDEFINEDIMAGESIZE: return (CvtCapValueFromEnumHelper(a_szValue)); case CAP.ICAP_UNITS: { TWUN twun; return (Enum.TryParse(CvtCapValueFromEnumHelper(a_szValue), out twun) ? ((int)twun).ToString() : a_szValue); }; case CAP.ICAP_XFERMECH: { TWSX twsx; return (Enum.TryParse(CvtCapValueFromEnumHelper(a_szValue), out twsx) ? ((int)twsx).ToString() : a_szValue); }; case CAP.ICAP_XNATIVERESOLUTION: return (a_szValue); case CAP.ICAP_XRESOLUTION: return (a_szValue); case CAP.ICAP_XSCALING: return (a_szValue); case CAP.ICAP_YNATIVERESOLUTION: return (a_szValue); case CAP.ICAP_YRESOLUTION: return (a_szValue); case CAP.ICAP_YSCALING: return (a_szValue); case CAP.ICAP_ZOOMFACTOR: return (a_szValue); } } /// /// Convert a value to the 'friendly' name, based on the TWEI... /// /// TWEI driving the conversion /// value to convert /// public static string CvtTweiValueToEnum(TWEI a_twei, string a_szValue) { switch (a_twei) { default: return (a_szValue); case TWEI.BARCODECONFIDENCE: return (a_szValue); case TWEI.BARCODECOUNT: return (a_szValue); case TWEI.BARCODEROTATION: return (CvtCapValueToEnumHelper(a_szValue)); case TWEI.BARCODETEXT: return (a_szValue); case TWEI.BARCODETEXT2: return (a_szValue); case TWEI.BARCODETEXTLENGTH: return (a_szValue); case TWEI.BARCODETYPE: return (CvtCapValueToEnumHelper(a_szValue)); case TWEI.BARCODEX: return (a_szValue); case TWEI.BARCODEY: return (a_szValue); case TWEI.BLACKSPECKLESREMOVED: return (a_szValue); case TWEI.BOOKNAME: return (a_szValue); case TWEI.CAMERA: return (a_szValue); case TWEI.CHAPTERNUMBER: return (a_szValue); case TWEI.DESHADEBLACKCOUNTNEW: return (a_szValue); case TWEI.DESHADEBLACKCOUNTOLD: return (a_szValue); case TWEI.DESHADEBLACKRLMAX: return (a_szValue); case TWEI.DESHADEBLACKRLMIN: return (a_szValue); case TWEI.DESHADECOUNT: return (a_szValue); case TWEI.DESHADEHEIGHT: return (a_szValue); case TWEI.DESHADELEFT: return (a_szValue); case TWEI.DESHADESIZE: return (a_szValue); case TWEI.DESHADETOP: return (a_szValue); case TWEI.DESHADEWHITECOUNTNEW: return (a_szValue); case TWEI.DESHADEWHITECOUNTOLD: return (a_szValue); case TWEI.DESHADEWHITERLAVE: return (a_szValue); case TWEI.DESHADEWHITERLMAX: return (a_szValue); case TWEI.DESHADEWHITERLMIN: return (a_szValue); case TWEI.DESHADEWIDTH: return (a_szValue); case TWEI.DESKEWSTATUS: return (CvtCapValueToEnumHelper(a_szValue)); case TWEI.DOCUMENTNUMBER: return (a_szValue); case TWEI.ENDORSEDTEXT: return (a_szValue); case TWEI.FILESYSTEMSOURCE: return (a_szValue); case TWEI.FORMCONFIDENCE: return (a_szValue); case TWEI.FORMHORZDOCOFFSET: return (a_szValue); case TWEI.FORMTEMPLATEMATCH: return (a_szValue); case TWEI.FORMTEMPLATEPAGEMATCH: return (a_szValue); case TWEI.FORMVERTDOCOFFSET: return (a_szValue); case TWEI.FRAME: return (a_szValue); case TWEI.FRAMENUMBER: return (a_szValue); case TWEI.HORZLINECOUNT: return (a_szValue); case TWEI.HORZLINELENGTH: return (a_szValue); case TWEI.HORZLINETHICKNESS: return (a_szValue); case TWEI.HORZLINEXCOORD: return (a_szValue); case TWEI.HORZLINEYCOORD: return (a_szValue); case TWEI.IAFIELDA_VALUE: return (a_szValue); case TWEI.IAFIELDB_VALUE: return (a_szValue); case TWEI.IAFIELDC_VALUE: return (a_szValue); case TWEI.IAFIELDD_VALUE: return (a_szValue); case TWEI.IAFIELDE_VALUE: return (a_szValue); case TWEI.IALEVEL: return (CvtCapValueToEnumHelper(a_szValue)); case TWEI.ICCPROFILE: return (a_szValue); case TWEI.IMAGEMERGED: return (CvtCapValueToEnumHelper(a_szValue)); case TWEI.LASTSEGMENT: return (CvtCapValueToEnumHelper(a_szValue)); case TWEI.MAGDATA: return (a_szValue); case TWEI.MAGDATALENGTH: return (a_szValue); case TWEI.MAGTYPE: return (CvtCapValueToEnumHelper(a_szValue)); case TWEI.PAGENUMBER: return (a_szValue); case TWEI.PAGESIDE: return (a_szValue); case TWEI.PAPERCOUNT: return (a_szValue); case TWEI.PATCHCODE: return (CvtCapValueToEnumHelper(a_szValue)); case TWEI.PIXELFLAVOR: return (CvtCapValueToEnumHelper(a_szValue)); case TWEI.PRINTER: return (CvtCapValueToEnumHelper(a_szValue)); case TWEI.PRINTERTEXT: return (a_szValue); case TWEI.SEGMENTNUMBER: return (a_szValue); case TWEI.SKEWCONFIDENCE: return (a_szValue); case TWEI.SKEWFINALANGLE: return (a_szValue); case TWEI.SKEWORIGINALANGLE: return (a_szValue); case TWEI.SKEWWINDOWX1: return (a_szValue); case TWEI.SKEWWINDOWX2: return (a_szValue); case TWEI.SKEWWINDOWX3: return (a_szValue); case TWEI.SKEWWINDOWX4: return (a_szValue); case TWEI.SKEWWINDOWY1: return (a_szValue); case TWEI.SKEWWINDOWY2: return (a_szValue); case TWEI.SKEWWINDOWY3: return (a_szValue); case TWEI.SKEWWINDOWY4: return (a_szValue); case TWEI.SPECKLESREMOVED: return (a_szValue); case TWEI.TWAINDIRECTMETADATA: return (a_szValue); case TWEI.VERTLINECOUNT: return (a_szValue); case TWEI.VERTLINELENGTH: return (a_szValue); case TWEI.VERTLINETHICKNESS: return (a_szValue); case TWEI.VERTLINEXCOORD: return (a_szValue); case TWEI.VERTLINEYCOORD: return (a_szValue); case TWEI.WHITESPECKLESREMOVED: return (a_szValue); } } #endregion /////////////////////////////////////////////////////////////////////////////// // Public DSM_Entry calls, most of the DSM_Entry calls are in here. Their // main contribution is to make sure that they're running within the right // thread, but they also include the state transitions... /////////////////////////////////////////////////////////////////////////////// #region Public DSM_Entry calls... /// /// Generic DSM when the dest must be zero (null)... /// /// Data group /// Data argument type /// Operation /// Pointer to data /// TWAIN status public STS DsmEntryNullDest(DG a_dg, DAT a_dat, MSG a_msg, IntPtr a_twmemref) { STS sts; // Submit the work to the TWAIN thread... if ((m_threadTwain != null) && (m_threadTwain.ManagedThreadId != Thread.CurrentThread.ManagedThreadId)) { lock (m_lockTwain) { // Set our command variables... ThreadData threaddata = default(ThreadData); threaddata.twmemref = a_twmemref; threaddata.msg = a_msg; threaddata.dg = a_dg; threaddata.dat = a_dat; long lIndex = m_twaincommand.Submit(threaddata); // Submit the command and wait for the reply... CallerToThreadSet(); ThreadToCallerWaitOne(); // Return the result... a_twmemref = m_twaincommand.Get(lIndex).twmemref; sts = m_twaincommand.Get(lIndex).sts; // Clear the command variables... m_twaincommand.Delete(lIndex); } return (sts); } // Log it... if (Log.GetLevel() > 0) { Log.LogSendBefore(a_dg.ToString(), a_dat.ToString(), a_msg.ToString(), ""); } // Windows... if (ms_platform == Platform.WINDOWS) { // Issue the command... try { if (m_blUseLegacyDSM) { sts = (STS)NativeMethods.WindowsTwain32DsmEntryNullDest(ref m_twidentitylegacyApp, IntPtr.Zero, a_dg, a_dat, a_msg, a_twmemref); } else { sts = (STS)NativeMethods.WindowsTwaindsmDsmEntryNullDest(ref m_twidentitylegacyApp, IntPtr.Zero, a_dg, a_dat, a_msg, a_twmemref); } } catch (Exception exception) { // The driver crashed... Log.Error("crash - " + exception.Message); Log.LogSendAfter(STS.BUMMER, ""); return (STS.BUMMER); } } // Linux... else if (ms_platform == Platform.LINUX) { // Issue the command... try { if (m_blFoundLatestDsm64 && (m_linuxdsm == LinuxDsm.IsLatestDsm)) { sts = (STS)NativeMethods.Linux64DsmEntryNullDest(ref m_twidentitylegacyApp, IntPtr.Zero, a_dg, a_dat, a_msg, a_twmemref); } else if (m_blFoundLatestDsm && (m_linuxdsm == LinuxDsm.IsLatestDsm)) { sts = (STS)NativeMethods.LinuxDsmEntryNullDest(ref m_twidentitylegacyApp, IntPtr.Zero, a_dg, a_dat, a_msg, a_twmemref); } else if (m_blFound020302Dsm64bit && (m_linuxdsm == LinuxDsm.Is020302Dsm64bit)) { sts = (STS)NativeMethods.Linux020302Dsm64bitEntryNullDest(ref m_twidentityApp, IntPtr.Zero, a_dg, a_dat, a_msg, a_twmemref); } else { Log.Error("apparently we don't have a DSM..."); sts = STS.BUMMER; } } catch (Exception exception) { // The driver crashed... Log.Error("crash - " + exception.Message); Log.LogSendAfter(STS.BUMMER, ""); return (STS.BUMMER); } } // Mac OS X, which has to be different... else if (ms_platform == Platform.MACOSX) { // Issue the command... try { if (m_blUseLegacyDSM) { sts = (STS)NativeMethods.MacosxTwainDsmEntryNullDest(ref m_twidentitymacosxApp, IntPtr.Zero, a_dg, a_dat, a_msg, a_twmemref); } else { sts = (STS)NativeMethods.MacosxTwaindsmDsmEntryNullDest(ref m_twidentitymacosxApp, IntPtr.Zero, a_dg, a_dat, a_msg, a_twmemref); } } catch (Exception exception) { // The driver crashed... Log.Error("crash - " + exception.Message); Log.LogSendAfter(STS.BUMMER, ""); return (STS.BUMMER); } } // Uh-oh... else { TWAINWorkingGroup.Log.Assert("Unsupported platform..." + ms_platform); return (STS.BUMMER); } // Get DAT_STATUS, if needed... TWAIN.STS stsRcOrCc = AutoDatStatus(sts); // Log it... if (Log.GetLevel() > 0) { Log.LogSendAfter(stsRcOrCc, ""); } // All done... return (sts); } /// /// Generic DSM when the dest must be a data source... /// /// Data group /// Data argument type /// Operation /// Pointer to data /// TWAIN status public STS DsmEntry(DG a_dg, DAT a_dat, MSG a_msg, IntPtr a_twmemref) { STS sts; // Submit the work to the TWAIN thread... if ((m_threadTwain != null) && (m_threadTwain.ManagedThreadId != Thread.CurrentThread.ManagedThreadId)) { lock (m_lockTwain) { // Set our command variables... ThreadData threaddata = default(ThreadData); threaddata.twmemref = a_twmemref; threaddata.dg = a_dg; threaddata.msg = a_msg; threaddata.dat = a_dat; long lIndex = m_twaincommand.Submit(threaddata); // Submit the command and wait for the reply... CallerToThreadSet(); ThreadToCallerWaitOne(); // Return the result... a_twmemref = m_twaincommand.Get(lIndex).twmemref; sts = m_twaincommand.Get(lIndex).sts; // Clear the command variables... m_twaincommand.Delete(lIndex); } return (sts); } // Log it... if (Log.GetLevel() > 0) { Log.LogSendBefore(a_dg.ToString(), a_dat.ToString(), a_msg.ToString(), ""); } // Windows... if (ms_platform == Platform.WINDOWS) { // Issue the command... try { if (m_blUseLegacyDSM) { sts = (STS)NativeMethods.WindowsTwain32DsmEntry(ref m_twidentitylegacyApp, ref m_twidentitylegacyDs, a_dg, a_dat, a_msg, a_twmemref); } else { sts = (STS)NativeMethods.WindowsTwaindsmDsmEntry(ref m_twidentitylegacyApp, ref m_twidentitylegacyDs, a_dg, a_dat, a_msg, a_twmemref); } } catch (Exception exception) { // The driver crashed... Log.Error("crash - " + exception.Message); Log.LogSendAfter(STS.BUMMER, ""); return (STS.BUMMER); } } // Linux... else if (ms_platform == Platform.LINUX) { // Issue the command... try { if (m_blFoundLatestDsm64 && (m_linuxdsm == LinuxDsm.IsLatestDsm)) { sts = (STS)NativeMethods.Linux64DsmEntry(ref m_twidentitylegacyApp, ref m_twidentitylegacyDs, a_dg, a_dat, a_msg, a_twmemref); } else if (m_blFoundLatestDsm && (m_linuxdsm == LinuxDsm.IsLatestDsm)) { sts = (STS)NativeMethods.LinuxDsmEntry(ref m_twidentitylegacyApp, ref m_twidentitylegacyDs, a_dg, a_dat, a_msg, a_twmemref); } else if (m_blFound020302Dsm64bit && (m_linuxdsm == LinuxDsm.Is020302Dsm64bit)) { sts = (STS)NativeMethods.Linux020302Dsm64bitEntry(ref m_twidentityApp, ref m_twidentityDs, a_dg, a_dat, a_msg, a_twmemref); } else { Log.Error("apparently we don't have a DSM..."); sts = STS.BUMMER; } } catch (Exception exception) { // The driver crashed... Log.Error("crash - " + exception.Message); Log.LogSendAfter(STS.BUMMER, ""); return (STS.BUMMER); } } // Mac OS X, which has to be different... else if (ms_platform == Platform.MACOSX) { // Issue the command... try { if (m_blUseLegacyDSM) { sts = (STS)NativeMethods.MacosxTwainDsmEntry(ref m_twidentitymacosxApp, ref m_twidentitymacosxDs, a_dg, DAT.AUDIOINFO, a_msg, a_twmemref); } else { sts = (STS)NativeMethods.MacosxTwaindsmDsmEntry(ref m_twidentitymacosxApp, ref m_twidentitymacosxDs, a_dg, DAT.AUDIOINFO, a_msg, a_twmemref); } } catch (Exception exception) { // The driver crashed... Log.Error("crash - " + exception.Message); Log.LogSendAfter(STS.BUMMER, ""); return (STS.BUMMER); } } // Uh-oh... else { Log.LogSendAfter(STS.BUMMER, ""); return (STS.BUMMER); } // Get DAT_STATUS, if needed... TWAIN.STS stsRcOrCc = AutoDatStatus(sts); // Log it... if (Log.GetLevel() > 0) { Log.LogSendAfter(stsRcOrCc, ""); } // All done... return (stsRcOrCc); } /// /// Issue file audio transfer commands... /// /// Data group /// Operation /// TWAIN status private void DatAudiofilexferWindowsTwain32() { // If you get a first chance exception, be aware that some drivers // will do that to you, you can ignore it and they'll keep going... m_threaddataDatAudiofilexfer.sts = (STS)NativeMethods.WindowsTwain32DsmEntryAudiofilexfer ( ref m_twidentitylegacyApp, ref m_twidentitylegacyDs, m_threaddataDatAudiofilexfer.dg, m_threaddataDatAudiofilexfer.dat, m_threaddataDatAudiofilexfer.msg, IntPtr.Zero ); } private void DatAudiofilexferWindowsTwainDsm() { // If you get a first chance exception, be aware that some drivers // will do that to you, you can ignore it and they'll keep going... m_threaddataDatAudiofilexfer.sts = (STS)NativeMethods.WindowsTwaindsmDsmEntryAudiofilexfer ( ref m_twidentitylegacyApp, ref m_twidentitylegacyDs, m_threaddataDatAudiofilexfer.dg, m_threaddataDatAudiofilexfer.dat, m_threaddataDatAudiofilexfer.msg, IntPtr.Zero ); } public STS DatAudiofilexfer(DG a_dg, MSG a_msg) { STS sts; // Submit the work to the TWAIN thread... if (this.m_runinuithreaddelegate == null) { if ((m_threadTwain != null) && (m_threadTwain.ManagedThreadId != Thread.CurrentThread.ManagedThreadId)) { lock (m_lockTwain) { // Set our command variables... ThreadData threaddata = default(ThreadData); threaddata.dg = a_dg; threaddata.msg = a_msg; threaddata.dat = DAT.AUDIOFILEXFER; long lIndex = m_twaincommand.Submit(threaddata); // Submit the command and wait for the reply... CallerToThreadSet(); ThreadToCallerWaitOne(); // Return the result... sts = m_twaincommand.Get(lIndex).sts; // Clear the command variables... m_twaincommand.Delete(lIndex); } return (sts); } } // Log it... if (Log.GetLevel() > 0) { Log.LogSendBefore(a_dg.ToString(), DAT.AUDIOFILEXFER.ToString(), a_msg.ToString(), ""); } // Windows... if (ms_platform == Platform.WINDOWS) { // Issue the command... try { if (m_threaddataDatAudiofilexfer.blIsInuse || (this.m_runinuithreaddelegate == null)) { if (m_blUseLegacyDSM) { sts = (STS)NativeMethods.WindowsTwain32DsmEntryAudiofilexfer(ref m_twidentitylegacyApp, ref m_twidentitylegacyDs, a_dg, DAT.AUDIOFILEXFER, a_msg, IntPtr.Zero); } else { sts = (STS)NativeMethods.WindowsTwaindsmDsmEntryAudiofilexfer(ref m_twidentitylegacyApp, ref m_twidentitylegacyDs, a_dg, DAT.AUDIOFILEXFER, a_msg, IntPtr.Zero); } } else { if (m_blUseLegacyDSM) { lock (m_lockTwain) { m_threaddataDatAudiofilexfer = default(ThreadData); m_threaddataDatAudiofilexfer.blIsInuse = true; m_threaddataDatAudiofilexfer.dg = a_dg; m_threaddataDatAudiofilexfer.msg = a_msg; m_threaddataDatAudiofilexfer.dat = DAT.AUDIOFILEXFER; RunInUiThread(DatAudiofilexferWindowsTwain32); sts = m_threaddataDatAudiofilexfer.sts; m_threaddataDatAudiofilexfer = default(ThreadData); } } else { lock (m_lockTwain) { m_threaddataDatAudiofilexfer = default(ThreadData); m_threaddataDatAudiofilexfer.blIsInuse = true; m_threaddataDatAudiofilexfer.dg = a_dg; m_threaddataDatAudiofilexfer.msg = a_msg; m_threaddataDatAudiofilexfer.dat = DAT.AUDIOFILEXFER; RunInUiThread(DatAudiofilexferWindowsTwainDsm); sts = m_threaddataDatAudiofilexfer.sts; m_threaddataDatAudiofilexfer = default(ThreadData); } } } } catch (Exception exception) { // The driver crashed... Log.Error("crash - " + exception.Message); Log.LogSendAfter(STS.BUMMER, ""); return (STS.BUMMER); } } // Linux... else if (ms_platform == Platform.LINUX) { // Issue the command... try { if (m_blFoundLatestDsm64 && (m_linuxdsm == LinuxDsm.IsLatestDsm)) { sts = (STS)NativeMethods.Linux64DsmEntryAudiofilexfer(ref m_twidentitylegacyApp, ref m_twidentitylegacyDs, a_dg, DAT.AUDIOFILEXFER, a_msg, IntPtr.Zero); } else if (m_blFoundLatestDsm && (m_linuxdsm == LinuxDsm.IsLatestDsm)) { sts = (STS)NativeMethods.LinuxDsmEntryAudiofilexfer(ref m_twidentitylegacyApp, ref m_twidentitylegacyDs, a_dg, DAT.AUDIOFILEXFER, a_msg, IntPtr.Zero); } else if (m_blFound020302Dsm64bit && (m_linuxdsm == LinuxDsm.Is020302Dsm64bit)) { sts = (STS)NativeMethods.Linux020302Dsm64bitEntryAudiofilexfer(ref m_twidentityApp, ref m_twidentityDs, a_dg, DAT.AUDIOFILEXFER, a_msg, IntPtr.Zero); } else { Log.Error("apparently we don't have a DSM..."); sts = STS.BUMMER; } } catch (Exception exception) { // The driver crashed... Log.Error("crash - " + exception.Message); Log.LogSendAfter(STS.BUMMER, ""); return (STS.BUMMER); } } // Mac OS X, which has to be different... else if (ms_platform == Platform.MACOSX) { // Issue the command... try { if (m_blUseLegacyDSM) { sts = (STS)NativeMethods.MacosxTwainDsmEntryAudiofilexfer(ref m_twidentitymacosxApp, ref m_twidentitymacosxDs, a_dg, DAT.AUDIOFILEXFER, a_msg, IntPtr.Zero); } else { sts = (STS)NativeMethods.MacosxTwaindsmDsmEntryAudiofilexfer(ref m_twidentitymacosxApp, ref m_twidentitymacosxDs, a_dg, DAT.AUDIOFILEXFER, a_msg, IntPtr.Zero); } } catch (Exception exception) { // The driver crashed... Log.Error("crash - " + exception.Message); Log.LogSendAfter(STS.BUMMER, ""); return (STS.BUMMER); } } // Uh-oh... else { Log.LogSendAfter(STS.BUMMER, ""); return (STS.BUMMER); } // Get DAT_STATUS, if needed... TWAIN.STS stsRcOrCc = AutoDatStatus(sts); // Log it... if (Log.GetLevel() > 0) { Log.LogSendAfter(stsRcOrCc, ""); } // If we had a successful transfer, then change state... if (sts == STS.XFERDONE) { m_state = STATE.S7; } // All done... return (stsRcOrCc); } /// /// Get/Set audio info information... /// /// Data group /// Operation /// Audio structure /// TWAIN status public STS DatAudioinfo(DG a_dg, MSG a_msg, ref TW_AUDIOINFO a_twaudioinfo) { STS sts; // Submit the work to the TWAIN thread... if ((m_threadTwain != null) && (m_threadTwain.ManagedThreadId != Thread.CurrentThread.ManagedThreadId)) { lock (m_lockTwain) { // Set our command variables... ThreadData threaddata = default(ThreadData); threaddata.twaudioinfo = a_twaudioinfo; threaddata.dg = a_dg; threaddata.msg = a_msg; threaddata.dat = DAT.AUDIOINFO; long lIndex = m_twaincommand.Submit(threaddata); // Submit the command and wait for the reply... CallerToThreadSet(); ThreadToCallerWaitOne(); // Return the result... a_twaudioinfo = m_twaincommand.Get(lIndex).twaudioinfo; sts = m_twaincommand.Get(lIndex).sts; // Clear the command variables... m_twaincommand.Delete(lIndex); } return (sts); } // Log it... if (Log.GetLevel() > 0) { Log.LogSendBefore(a_dg.ToString(), DAT.AUDIOINFO.ToString(), a_msg.ToString(), ""); } // Windows... if (ms_platform == Platform.WINDOWS) { // Issue the command... try { if (m_blUseLegacyDSM) { sts = (STS)NativeMethods.WindowsTwain32DsmEntryAudioAudioinfo(ref m_twidentitylegacyApp, ref m_twidentitylegacyDs, a_dg, DAT.AUDIOINFO, a_msg, ref a_twaudioinfo); } else { sts = (STS)NativeMethods.WindowsTwaindsmDsmEntryAudioAudioinfo(ref m_twidentitylegacyApp, ref m_twidentitylegacyDs, a_dg, DAT.AUDIOINFO, a_msg, ref a_twaudioinfo); } } catch (Exception exception) { // The driver crashed... Log.Error("crash - " + exception.Message); Log.LogSendAfter(STS.BUMMER, ""); return (STS.BUMMER); } } // Linux... else if (ms_platform == Platform.LINUX) { // Issue the command... try { if (m_blFoundLatestDsm64 && (m_linuxdsm == LinuxDsm.IsLatestDsm)) { sts = (STS)NativeMethods.Linux64DsmEntryAudioAudioinfo(ref m_twidentitylegacyApp, ref m_twidentitylegacyDs, a_dg, DAT.AUDIOINFO, a_msg, ref a_twaudioinfo); } else if (m_blFoundLatestDsm && (m_linuxdsm == LinuxDsm.IsLatestDsm)) { sts = (STS)NativeMethods.LinuxDsmEntryAudioAudioinfo(ref m_twidentitylegacyApp, ref m_twidentitylegacyDs, a_dg, DAT.AUDIOINFO, a_msg, ref a_twaudioinfo); } else if (m_blFound020302Dsm64bit && (m_linuxdsm == LinuxDsm.Is020302Dsm64bit)) { sts = (STS)NativeMethods.Linux020302Dsm64bitEntryAudioAudioinfo(ref m_twidentityApp, ref m_twidentityDs, a_dg, DAT.AUDIOINFO, a_msg, ref a_twaudioinfo); } else { Log.Error("apparently we don't have a DSM..."); sts = STS.BUMMER; } } catch (Exception exception) { // The driver crashed... Log.Error("crash - " + exception.Message); Log.LogSendAfter(STS.BUMMER, ""); return (STS.BUMMER); } } // Mac OS X, which has to be different... else if (ms_platform == Platform.MACOSX) { // Issue the command... try { if (m_blUseLegacyDSM) { sts = (STS)NativeMethods.MacosxTwainDsmEntryAudioAudioinfo(ref m_twidentitymacosxApp, ref m_twidentitymacosxDs, a_dg, DAT.AUDIOINFO, a_msg, ref a_twaudioinfo); } else { sts = (STS)NativeMethods.MacosxTwaindsmDsmEntryAudioAudioinfo(ref m_twidentitymacosxApp, ref m_twidentitymacosxDs, a_dg, DAT.AUDIOINFO, a_msg, ref a_twaudioinfo); } } catch (Exception exception) { // The driver crashed... Log.Error("crash - " + exception.Message); Log.LogSendAfter(STS.BUMMER, ""); return (STS.BUMMER); } } // Uh-oh... else { Log.LogSendAfter(STS.BUMMER, ""); return (STS.BUMMER); } // Get DAT_STATUS, if needed... TWAIN.STS stsRcOrCc = AutoDatStatus(sts); // Log it... if (Log.GetLevel() > 0) { Log.LogSendAfter(stsRcOrCc, ""); } // All done... return (stsRcOrCc); } /// /// Issue native audio transfer commands... /// /// Data group /// Operation /// handle /// TWAIN status private void DatAudionativexferWindowsTwain32() { // If you get a first chance exception, be aware that some drivers // will do that to you, you can ignore it and they'll keep going... m_threaddataDatAudionativexfer.sts = (STS)NativeMethods.WindowsTwain32DsmEntryAudionativexfer ( ref m_twidentitylegacyApp, ref m_twidentitylegacyDs, m_threaddataDatAudionativexfer.dg, m_threaddataDatAudionativexfer.dat, m_threaddataDatAudionativexfer.msg, ref m_threaddataDatAudionativexfer.intptrAudio ); } private void DatAudionativexferWindowsTwainDsm() { // If you get a first chance exception, be aware that some drivers // will do that to you, you can ignore it and they'll keep going... m_threaddataDatAudionativexfer.sts = (STS)NativeMethods.WindowsTwaindsmDsmEntryAudionativexfer ( ref m_twidentitylegacyApp, ref m_twidentitylegacyDs, m_threaddataDatAudionativexfer.dg, m_threaddataDatAudionativexfer.dat, m_threaddataDatAudionativexfer.msg, ref m_threaddataDatAudionativexfer.intptrAudio ); } [PermissionSet(SecurityAction.LinkDemand, Name = "FullTrust", Unrestricted = false)] public STS DatAudionativexfer(DG a_dg, MSG a_msg, ref IntPtr a_intptrAudio) { STS sts; // Submit the work to the TWAIN thread... if (this.m_runinuithreaddelegate == null) { if ((m_threadTwain != null) && (m_threadTwain.ManagedThreadId != Thread.CurrentThread.ManagedThreadId)) { lock (m_lockTwain) { // Set our command variables... ThreadData threaddata = default(ThreadData); threaddata.intptrAudio = a_intptrAudio; threaddata.dg = a_dg; threaddata.msg = a_msg; threaddata.dat = DAT.AUDIONATIVEXFER; long lIndex = m_twaincommand.Submit(threaddata); // Submit the command and wait for the reply... CallerToThreadSet(); ThreadToCallerWaitOne(); // Return the result... a_intptrAudio = m_twaincommand.Get(lIndex).intptrAudio; sts = m_twaincommand.Get(lIndex).sts; // Clear the command variables... m_twaincommand.Delete(lIndex); } return (sts); } } // Log it... if (Log.GetLevel() > 0) { Log.LogSendBefore(a_dg.ToString(), DAT.AUDIONATIVEXFER.ToString(), a_msg.ToString(), ""); } // Windows... if (ms_platform == Platform.WINDOWS) { // Issue the command... try { if (m_threaddataDatAudionativexfer.blIsInuse || (this.m_runinuithreaddelegate == null)) { if (m_blUseLegacyDSM) { sts = (STS)NativeMethods.WindowsTwain32DsmEntryAudionativexfer(ref m_twidentitylegacyApp, ref m_twidentitylegacyDs, a_dg, DAT.AUDIONATIVEXFER, a_msg, ref a_intptrAudio); } else { sts = (STS)NativeMethods.WindowsTwaindsmDsmEntryAudionativexfer(ref m_twidentitylegacyApp, ref m_twidentitylegacyDs, a_dg, DAT.AUDIONATIVEXFER, a_msg, ref a_intptrAudio); } } else { if (m_blUseLegacyDSM) { lock (m_lockTwain) { m_threaddataDatAudionativexfer = default(ThreadData); m_threaddataDatAudionativexfer.blIsInuse = true; m_threaddataDatAudionativexfer.dg = a_dg; m_threaddataDatAudionativexfer.msg = a_msg; m_threaddataDatAudionativexfer.dat = DAT.AUDIONATIVEXFER; RunInUiThread(DatAudionativexferWindowsTwain32); a_intptrAudio = m_threaddataDatAudionativexfer.intptrAudio; sts = m_threaddataDatAudionativexfer.sts; m_threaddataDatAudionativexfer = default(ThreadData); } } else { lock (m_lockTwain) { m_threaddataDatAudionativexfer = default(ThreadData); m_threaddataDatAudionativexfer.blIsInuse = true; m_threaddataDatAudionativexfer.dg = a_dg; m_threaddataDatAudionativexfer.msg = a_msg; m_threaddataDatAudionativexfer.dat = DAT.AUDIONATIVEXFER; RunInUiThread(DatAudionativexferWindowsTwainDsm); a_intptrAudio = m_threaddataDatAudionativexfer.intptrAudio; sts = m_threaddataDatAudionativexfer.sts; m_threaddataDatAudionativexfer = default(ThreadData); } } } } catch (Exception exception) { // The driver crashed... Log.Error("crash - " + exception.Message); Log.LogSendAfter(STS.BUMMER, ""); return (STS.BUMMER); } } // Linux... else if (ms_platform == Platform.LINUX) { // Issue the command... try { a_intptrAudio = IntPtr.Zero; if (m_blFoundLatestDsm64 && (m_linuxdsm == LinuxDsm.IsLatestDsm)) { sts = (STS)NativeMethods.Linux64DsmEntryAudionativexfer(ref m_twidentitylegacyApp, ref m_twidentitylegacyDs, a_dg, DAT.AUDIONATIVEXFER, a_msg, ref a_intptrAudio); } else if (m_blFoundLatestDsm && (m_linuxdsm == LinuxDsm.IsLatestDsm)) { sts = (STS)NativeMethods.LinuxDsmEntryAudionativexfer(ref m_twidentitylegacyApp, ref m_twidentitylegacyDs, a_dg, DAT.AUDIONATIVEXFER, a_msg, ref a_intptrAudio); } else if (m_blFound020302Dsm64bit && (m_linuxdsm == LinuxDsm.Is020302Dsm64bit)) { sts = (STS)NativeMethods.Linux020302Dsm64bitEntryAudionativexfer(ref m_twidentityApp, ref m_twidentityDs, a_dg, DAT.IMAGENATIVEXFER, a_msg, ref a_intptrAudio); } else { Log.Error("apparently we don't have a DSM..."); sts = STS.BUMMER; } } catch (Exception exception) { // The driver crashed... Log.Error("crash - " + exception.Message); Log.LogSendAfter(STS.BUMMER, ""); return (STS.BUMMER); } } // Mac OS X, which has to be different... else if (ms_platform == Platform.MACOSX) { // Issue the command... try { a_intptrAudio = IntPtr.Zero; if (m_blUseLegacyDSM) { sts = (STS)NativeMethods.MacosxTwainDsmEntryAudionativexfer(ref m_twidentitymacosxApp, ref m_twidentitymacosxDs, a_dg, DAT.AUDIONATIVEXFER, a_msg, ref a_intptrAudio); } else { sts = (STS)NativeMethods.MacosxTwaindsmDsmEntryAudionativexfer(ref m_twidentitymacosxApp, ref m_twidentitymacosxDs, a_dg, DAT.AUDIONATIVEXFER, a_msg, ref a_intptrAudio); } } catch (Exception exception) { // The driver crashed... Log.Error("crash - " + exception.Message); Log.LogSendAfter(STS.BUMMER, ""); return (STS.BUMMER); } } // Uh-oh... else { Log.LogSendAfter(STS.BUMMER, ""); return (STS.BUMMER); } // Get DAT_STATUS, if needed... TWAIN.STS stsRcOrCc = AutoDatStatus(sts); // Log it... if (Log.GetLevel() > 0) { Log.LogSendAfter(stsRcOrCc, ""); } // If we had a successful transfer, then change state... if (sts == STS.XFERDONE) { // Bump our state... m_state = STATE.S7; } // All done... return (stsRcOrCc); } /// /// Issue callback commands... /// /// Data group /// Operation /// Callback structure /// TWAIN status public STS DatCallback(DG a_dg, MSG a_msg, ref TW_CALLBACK a_twcallback) { STS sts; // Submit the work to the TWAIN thread... if ((m_threadTwain != null) && (m_threadTwain.ManagedThreadId != Thread.CurrentThread.ManagedThreadId)) { lock (m_lockTwain) { // Set our command variables... ThreadData threaddata = default(ThreadData); threaddata.twcallback = a_twcallback; threaddata.dg = a_dg; threaddata.msg = a_msg; threaddata.dat = DAT.CALLBACK; long lIndex = m_twaincommand.Submit(threaddata); // Submit the command and wait for the reply... CallerToThreadSet(); ThreadToCallerWaitOne(); // Return the result... a_twcallback = m_twaincommand.Get(lIndex).twcallback; sts = m_twaincommand.Get(lIndex).sts; // Clear the command variables... m_twaincommand.Delete(lIndex); } return (sts); } // Log it... if (Log.GetLevel() > 0) { Log.LogSendBefore(a_dg.ToString(), DAT.CALLBACK.ToString(), a_msg.ToString(), CallbackToCsv(a_twcallback)); } // Windows... if (ms_platform == Platform.WINDOWS) { // Issue the command... try { if (m_blUseLegacyDSM) { sts = (STS)NativeMethods.WindowsTwain32DsmEntryCallback(ref m_twidentitylegacyApp, ref m_twidentitylegacyDs, a_dg, DAT.CALLBACK, a_msg, ref a_twcallback); } else { sts = (STS)NativeMethods.WindowsTwaindsmDsmEntryCallback(ref m_twidentitylegacyApp, ref m_twidentitylegacyDs, a_dg, DAT.CALLBACK, a_msg, ref a_twcallback); } } catch (Exception exception) { // The driver crashed... Log.Error("crash - " + exception.Message); Log.LogSendAfter(STS.BUMMER, ""); return (STS.BUMMER); } } // Linux... else if (ms_platform == Platform.LINUX) { // Issue the command... try { if (m_blFoundLatestDsm64 && (m_linuxdsm == LinuxDsm.IsLatestDsm)) { sts = (STS)NativeMethods.Linux64DsmEntryCallback(ref m_twidentitylegacyApp, ref m_twidentitylegacyDs, a_dg, DAT.CALLBACK, a_msg, ref a_twcallback); } else if (m_blFoundLatestDsm && (m_linuxdsm == LinuxDsm.IsLatestDsm)) { sts = (STS)NativeMethods.LinuxDsmEntryCallback(ref m_twidentitylegacyApp, ref m_twidentitylegacyDs, a_dg, DAT.CALLBACK, a_msg, ref a_twcallback); } else if (m_blFound020302Dsm64bit && (m_linuxdsm == LinuxDsm.Is020302Dsm64bit)) { sts = (STS)NativeMethods.Linux020302Dsm64bitEntryCallback(ref m_twidentityApp, ref m_twidentityDs, a_dg, DAT.CALLBACK, a_msg, ref a_twcallback); } else { Log.Error("apparently we don't have a DSM..."); sts = STS.BUMMER; } } catch (Exception exception) { // The driver crashed... Log.Error("crash - " + exception.Message); Log.LogSendAfter(STS.BUMMER, ""); return (STS.BUMMER); } } // Mac OS X, which has to be different... else if (ms_platform == Platform.MACOSX) { // Issue the command... try { if (m_blUseLegacyDSM) { sts = (STS)NativeMethods.MacosxTwainDsmEntryCallback(ref m_twidentitymacosxApp, IntPtr.Zero, a_dg, DAT.CALLBACK, a_msg, ref a_twcallback); } else { sts = (STS)NativeMethods.MacosxTwaindsmDsmEntryCallback(ref m_twidentitymacosxApp, ref m_twidentityDs, a_dg, DAT.CALLBACK, a_msg, ref a_twcallback); } } catch (Exception exception) { // The driver crashed... Log.Error("crash - " + exception.Message); Log.LogSendAfter(STS.BUMMER, ""); return (STS.BUMMER); } } // Uh-oh... else { Log.LogSendAfter(STS.BUMMER, ""); return (STS.BUMMER); } // Get DAT_STATUS, if needed... TWAIN.STS stsRcOrCc = AutoDatStatus(sts); // Log it... if (Log.GetLevel() > 0) { Log.LogSendAfter(stsRcOrCc, CallbackToCsv(a_twcallback)); } // All done... return (stsRcOrCc); } /// /// Issue callback2 commands... /// /// Data group /// Operation /// Callback2 structure /// TWAIN status public STS DatCallback2(DG a_dg, MSG a_msg, ref TW_CALLBACK2 a_twcallback2) { STS sts; // Submit the work to the TWAIN thread... if ((m_threadTwain != null) && (m_threadTwain.ManagedThreadId != Thread.CurrentThread.ManagedThreadId)) { lock (m_lockTwain) { // Set our command variables... ThreadData threaddata = default(ThreadData); threaddata.twcallback2 = a_twcallback2; threaddata.dg = a_dg; threaddata.msg = a_msg; threaddata.dat = DAT.CALLBACK; long lIndex = m_twaincommand.Submit(threaddata); // Submit the command and wait for the reply... CallerToThreadSet(); ThreadToCallerWaitOne(); // Return the result... a_twcallback2 = m_twaincommand.Get(lIndex).twcallback2; sts = m_twaincommand.Get(lIndex).sts; // Clear the command variables... m_twaincommand.Delete(lIndex); } return (sts); } // Log it... if (Log.GetLevel() > 0) { Log.LogSendBefore(a_dg.ToString(), DAT.CALLBACK2.ToString(), a_msg.ToString(), Callback2ToCsv(a_twcallback2)); } // Windows... if (ms_platform == Platform.WINDOWS) { // Issue the command... try { if (m_blUseLegacyDSM) { sts = (STS)NativeMethods.WindowsTwain32DsmEntryCallback2(ref m_twidentitylegacyApp, ref m_twidentitylegacyDs, a_dg, DAT.CALLBACK2, a_msg, ref a_twcallback2); } else { sts = (STS)NativeMethods.WindowsTwaindsmDsmEntryCallback2(ref m_twidentitylegacyApp, ref m_twidentitylegacyDs, a_dg, DAT.CALLBACK2, a_msg, ref a_twcallback2); } } catch (Exception exception) { // The driver crashed... Log.Error("crash - " + exception.Message); Log.LogSendAfter(STS.BUMMER, ""); return (STS.BUMMER); } } // Linux... else if (ms_platform == Platform.LINUX) { // Issue the command... try { if (m_blFoundLatestDsm64 && (m_linuxdsm == LinuxDsm.IsLatestDsm)) { sts = (STS)NativeMethods.Linux64DsmEntryCallback2(ref m_twidentitylegacyApp, ref m_twidentitylegacyDs, a_dg, DAT.CALLBACK2, a_msg, ref a_twcallback2); } else if (m_blFoundLatestDsm && (m_linuxdsm == LinuxDsm.IsLatestDsm)) { sts = (STS)NativeMethods.LinuxDsmEntryCallback2(ref m_twidentitylegacyApp, ref m_twidentitylegacyDs, a_dg, DAT.CALLBACK2, a_msg, ref a_twcallback2); } else if (m_blFound020302Dsm64bit && (m_linuxdsm == LinuxDsm.Is020302Dsm64bit)) { sts = (STS)NativeMethods.Linux020302Dsm64bitEntryCallback2(ref m_twidentityApp, ref m_twidentityDs, a_dg, DAT.CALLBACK2, a_msg, ref a_twcallback2); } else { Log.Error("apparently we don't have a DSM..."); sts = STS.BUMMER; } } catch (Exception exception) { // The driver crashed... Log.Error("crash - " + exception.Message); Log.LogSendAfter(STS.BUMMER, ""); return (STS.BUMMER); } } // Mac OS X, which has to be different... else if (ms_platform == Platform.MACOSX) { // Issue the command... try { if (m_blUseLegacyDSM) { sts = (STS)NativeMethods.MacosxTwainDsmEntryCallback2(ref m_twidentitymacosxApp, IntPtr.Zero, a_dg, DAT.CALLBACK2, a_msg, ref a_twcallback2); } else { sts = (STS)NativeMethods.MacosxTwaindsmDsmEntryCallback2(ref m_twidentitymacosxApp, ref m_twidentityDs, a_dg, DAT.CALLBACK2, a_msg, ref a_twcallback2); } } catch (Exception exception) { // The driver crashed... Log.Error("crash - " + exception.Message); Log.LogSendAfter(STS.BUMMER, ""); return (STS.BUMMER); } } // Uh-oh... else { Log.LogSendAfter(STS.BUMMER, ""); return (STS.BUMMER); } // Get DAT_STATUS, if needed... TWAIN.STS stsRcOrCc = AutoDatStatus(sts); // Log it... if (Log.GetLevel() > 0) { Log.LogSendAfter(stsRcOrCc, Callback2ToCsv(a_twcallback2)); } // All done... return (stsRcOrCc); } /// /// Issue capabilities commands... /// /// Data group /// Operation /// CAPABILITY structure /// TWAIN status [PermissionSet(SecurityAction.LinkDemand, Name = "FullTrust", Unrestricted = false)] private void DatCapabilityWindowsTwain32() { // If you get a first chance exception, be aware that some drivers // will do that to you, you can ignore it and they'll keep going... m_threaddataDatCapability.sts = (STS)NativeMethods.WindowsTwain32DsmEntryCapability ( ref m_twidentitylegacyApp, ref m_twidentitylegacyDs, m_threaddataDatCapability.dg, m_threaddataDatCapability.dat, m_threaddataDatCapability.msg, ref m_threaddataDatCapability.twcapability ); } private void DatCapabilityWindowsTwainDsm() { // If you get a first chance exception, be aware that some drivers // will do that to you, you can ignore it and they'll keep going... m_threaddataDatCapability.sts = (STS)NativeMethods.WindowsTwaindsmDsmEntryCapability ( ref m_twidentitylegacyApp, ref m_twidentitylegacyDs, m_threaddataDatCapability.dg, m_threaddataDatCapability.dat, m_threaddataDatCapability.msg, ref m_threaddataDatCapability.twcapability ); } public STS DatCapability(DG a_dg, MSG a_msg, ref TW_CAPABILITY a_twcapability) { STS sts; // Submit the work to the TWAIN thread... if (m_runinuithreaddelegate == null) { if ((m_threadTwain != null) && (m_threadTwain.ManagedThreadId != Thread.CurrentThread.ManagedThreadId)) { lock (m_lockTwain) { ThreadData threaddata = default(ThreadData); long lIndex = 0; // TBD: sometimes this doesn't work! Not sure why // yet, but a retry takes care of it. for (int ii = 0; ii < 5; ii++) { // Set our command variables... threaddata = default(ThreadData); threaddata.twcapability = a_twcapability; threaddata.dg = a_dg; threaddata.msg = a_msg; threaddata.dat = DAT.CAPABILITY; lIndex = m_twaincommand.Submit(threaddata); // Submit the command and wait for the reply... CallerToThreadSet(); ThreadToCallerWaitOne(); // Hmmm... if ( (a_msg == MSG.GETCURRENT) && (m_twaincommand.Get(lIndex).sts == STS.SUCCESS) && (m_twaincommand.Get(lIndex).twcapability.ConType == (TWON)0) && (m_twaincommand.Get(lIndex).twcapability.hContainer == IntPtr.Zero)) { Thread.Sleep(1000); continue; } // We're done... break; } // Return the result... a_twcapability = m_twaincommand.Get(lIndex).twcapability; sts = m_twaincommand.Get(lIndex).sts; // Clear the command variables... m_twaincommand.Delete(lIndex); } return (sts); } } // Log it... if (Log.GetLevel() > 0) { if ((a_msg == MSG.SET) || (a_msg == MSG.SETCONSTRAINT)) { Log.LogSendBefore(a_dg.ToString(), DAT.CAPABILITY.ToString(), a_msg.ToString(), CapabilityToCsv(a_twcapability, (a_msg != TWAIN.MSG.QUERYSUPPORT))); } else { string szCap = a_twcapability.Cap.ToString(); if (!szCap.Contains("_")) { szCap = "0x" + ((ushort)a_twcapability.Cap).ToString("X"); } Log.LogSendBefore(a_dg.ToString(), DAT.CAPABILITY.ToString(), a_msg.ToString(), szCap + ",0,0"); } } // Windows... if (ms_platform == Platform.WINDOWS) { // Issue the command... try { if (m_threaddataDatCapability.blIsInuse || (this.m_runinuithreaddelegate == null)) { if (m_blUseLegacyDSM) { sts = (STS)NativeMethods.WindowsTwain32DsmEntryCapability(ref m_twidentitylegacyApp, ref m_twidentitylegacyDs, a_dg, DAT.CAPABILITY, a_msg, ref a_twcapability); } else { sts = (STS)NativeMethods.WindowsTwaindsmDsmEntryCapability(ref m_twidentitylegacyApp, ref m_twidentitylegacyDs, a_dg, DAT.CAPABILITY, a_msg, ref a_twcapability); } } else { if (m_blUseLegacyDSM) { lock (m_lockTwain) { m_threaddataDatCapability = default(ThreadData); m_threaddataDatCapability.blIsInuse = true; m_threaddataDatCapability.dg = a_dg; m_threaddataDatCapability.msg = a_msg; m_threaddataDatCapability.dat = DAT.CAPABILITY; m_threaddataDatCapability.twcapability = a_twcapability; RunInUiThread(DatCapabilityWindowsTwain32); a_twcapability = m_threaddataDatCapability.twcapability; sts = m_threaddataDatCapability.sts; m_threaddataDatCapability = default(ThreadData); } } else { lock (m_lockTwain) { m_threaddataDatCapability = default(ThreadData); m_threaddataDatCapability.blIsInuse = true; m_threaddataDatCapability.dg = a_dg; m_threaddataDatCapability.msg = a_msg; m_threaddataDatCapability.dat = DAT.CAPABILITY; m_threaddataDatCapability.twcapability = a_twcapability; RunInUiThread(DatCapabilityWindowsTwainDsm); a_twcapability = m_threaddataDatCapability.twcapability; sts = m_threaddataDatCapability.sts; m_threaddataDatCapability = default(ThreadData); } } } } catch (Exception exception) { // The driver crashed... Log.Error("crash - " + exception.Message); Log.LogSendAfter(STS.BUMMER, ""); return (STS.BUMMER); } } // Linux... else if (ms_platform == Platform.LINUX) { // Issue the command... try { if (m_blFoundLatestDsm64 && (m_linuxdsm == LinuxDsm.IsLatestDsm)) { sts = (STS)NativeMethods.Linux64DsmEntryCapability(ref m_twidentitylegacyApp, ref m_twidentitylegacyDs, a_dg, DAT.CAPABILITY, a_msg, ref a_twcapability); } else if (m_blFoundLatestDsm && (m_linuxdsm == LinuxDsm.IsLatestDsm)) { sts = (STS)NativeMethods.LinuxDsmEntryCapability(ref m_twidentitylegacyApp, ref m_twidentitylegacyDs, a_dg, DAT.CAPABILITY, a_msg, ref a_twcapability); } else if (m_blFound020302Dsm64bit && (m_linuxdsm == LinuxDsm.Is020302Dsm64bit)) { sts = (STS)NativeMethods.Linux020302Dsm64bitEntryCapability(ref m_twidentityApp, ref m_twidentityDs, a_dg, DAT.CAPABILITY, a_msg, ref a_twcapability); } else { Log.Error("apparently we don't have a DSM..."); sts = STS.BUMMER; } } catch (Exception exception) { // The driver crashed... Log.Error("crash - " + exception.Message); Log.LogSendAfter(STS.BUMMER, ""); return (STS.BUMMER); } } // Mac OS X, which has to be different... else if (ms_platform == Platform.MACOSX) { // Issue the command... try { if (m_blUseLegacyDSM) { sts = (STS)NativeMethods.MacosxTwainDsmEntryCapability(ref m_twidentitymacosxApp, ref m_twidentitymacosxDs, a_dg, DAT.CAPABILITY, a_msg, ref a_twcapability); } else { sts = (STS)NativeMethods.MacosxTwaindsmDsmEntryCapability(ref m_twidentitymacosxApp, ref m_twidentitymacosxDs, a_dg, DAT.CAPABILITY, a_msg, ref a_twcapability); } } catch (Exception exception) { // The driver crashed... Log.Error("crash - " + exception.Message); Log.LogSendAfter(STS.BUMMER, ""); return (STS.BUMMER); } } // Uh-oh... else { Log.LogSendAfter(STS.BUMMER, ""); return (STS.BUMMER); } // Get DAT_STATUS, if needed... TWAIN.STS stsRcOrCc = AutoDatStatus(sts); // Log it... if (Log.GetLevel() > 0) { if ((a_msg == MSG.RESETALL) || ((sts != STS.SUCCESS) && (sts != STS.CHECKSTATUS))) { Log.LogSendAfter(stsRcOrCc, ""); } else { Log.LogSendAfter(stsRcOrCc, CapabilityToCsv(a_twcapability, (a_msg != TWAIN.MSG.QUERYSUPPORT))); } } // if MSG_SET/CAP_LANGUAGE, then we want to track it if ((a_twcapability.Cap == CAP.CAP_LANGUAGE) && (a_msg == MSG.SET) && (a_twcapability.ConType == TWON.ONEVALUE)) { string str; // if it was successful, then go with what was set. // otherwise ask the DS what it is currently set to if (sts == STS.SUCCESS) { str = CapabilityToCsv(a_twcapability, (a_msg != TWAIN.MSG.QUERYSUPPORT)); } else { TW_CAPABILITY twcapability = new TW_CAPABILITY(); twcapability.Cap = CAP.CAP_LANGUAGE; twcapability.ConType = TWON.ONEVALUE; sts = DatCapability(a_dg, MSG.GETCURRENT, ref twcapability); if (sts == STS.SUCCESS) { str = CapabilityToCsv(twcapability, (a_msg != TWAIN.MSG.QUERYSUPPORT)); } else { // couldn't get the value, so go with English str = "x," + ((int)TWLG.ENGLISH).ToString(); } } // get the value from the CSV string TWLG twlg = TWLG.ENGLISH; try { string[] astr = str.Split(new char[] { ',' }); int result; if (int.TryParse(astr[astr.Length - 1], out result)) { twlg = (TWLG)result; } } catch { twlg = TWLG.ENGLISH; } Language.Set(twlg); } // All done... return (stsRcOrCc); } /// /// Get/Set for CIE color... /// /// Data group /// Operation /// CIECOLOR structure /// TWAIN status public STS DatCiecolor(DG a_dg, MSG a_msg, ref TW_CIECOLOR a_twciecolor) { STS sts; // Submit the work to the TWAIN thread... if ((m_threadTwain != null) && (m_threadTwain.ManagedThreadId != Thread.CurrentThread.ManagedThreadId)) { lock (m_lockTwain) { // Set our command variables... ThreadData threaddata = default(ThreadData); threaddata.twciecolor = a_twciecolor; threaddata.dg = a_dg; threaddata.msg = a_msg; threaddata.dat = DAT.CIECOLOR; long lIndex = m_twaincommand.Submit(threaddata); // Submit the command and wait for the reply... CallerToThreadSet(); ThreadToCallerWaitOne(); // Return the result... a_twciecolor = m_twaincommand.Get(lIndex).twciecolor; sts = m_twaincommand.Get(lIndex).sts; // Clear the command variables... m_twaincommand.Delete(lIndex); } return (sts); } // Log it... if (Log.GetLevel() > 0) { Log.LogSendBefore(a_dg.ToString(), DAT.CIECOLOR.ToString(), a_msg.ToString(), ""); } // Windows... if (ms_platform == Platform.WINDOWS) { // Issue the command... try { if (m_blUseLegacyDSM) { sts = (STS)NativeMethods.WindowsTwain32DsmEntryCiecolor(ref m_twidentitylegacyApp, ref m_twidentitylegacyDs, a_dg, DAT.CIECOLOR, a_msg, ref a_twciecolor); } else { sts = (STS)NativeMethods.WindowsTwaindsmDsmEntryCiecolor(ref m_twidentitylegacyApp, ref m_twidentitylegacyDs, a_dg, DAT.CIECOLOR, a_msg, ref a_twciecolor); } } catch (Exception exception) { // The driver crashed... Log.Error("crash - " + exception.Message); Log.LogSendAfter(STS.BUMMER, ""); return (STS.BUMMER); } } // Linux... else if (ms_platform == Platform.LINUX) { // Issue the command... try { if (m_blFoundLatestDsm64 && (m_linuxdsm == LinuxDsm.IsLatestDsm)) { sts = (STS)NativeMethods.Linux64DsmEntryCiecolor(ref m_twidentitylegacyApp, ref m_twidentitylegacyDs, a_dg, DAT.CIECOLOR, a_msg, ref a_twciecolor); } else if (m_blFoundLatestDsm && (m_linuxdsm == LinuxDsm.IsLatestDsm)) { sts = (STS)NativeMethods.LinuxDsmEntryCiecolor(ref m_twidentitylegacyApp, ref m_twidentitylegacyDs, a_dg, DAT.CIECOLOR, a_msg, ref a_twciecolor); } else if (m_blFound020302Dsm64bit && (m_linuxdsm == LinuxDsm.Is020302Dsm64bit)) { sts = (STS)NativeMethods.Linux020302Dsm64bitEntryCiecolor(ref m_twidentityApp, ref m_twidentityDs, a_dg, DAT.CIECOLOR, a_msg, ref a_twciecolor); } else { Log.Error("apparently we don't have a DSM..."); sts = STS.BUMMER; } } catch (Exception exception) { // The driver crashed... Log.Error("crash - " + exception.Message); Log.LogSendAfter(STS.BUMMER, ""); return (STS.BUMMER); } } // Mac OS X, which has to be different... else if (ms_platform == Platform.MACOSX) { // Issue the command... try { if (m_blUseLegacyDSM) { sts = (STS)NativeMethods.MacosxTwainDsmEntryCiecolor(ref m_twidentitymacosxApp, ref m_twidentitymacosxDs, a_dg, DAT.CIECOLOR, a_msg, ref a_twciecolor); } else { sts = (STS)NativeMethods.MacosxTwaindsmDsmEntryCiecolor(ref m_twidentitymacosxApp, ref m_twidentitymacosxDs, a_dg, DAT.CIECOLOR, a_msg, ref a_twciecolor); } } catch (Exception exception) { // The driver crashed... Log.Error("crash - " + exception.Message); Log.LogSendAfter(STS.BUMMER, ""); return (STS.BUMMER); } } // Uh-oh... else { Log.LogSendAfter(STS.BUMMER, ""); return (STS.BUMMER); } // Get DAT_STATUS, if needed... TWAIN.STS stsRcOrCc = AutoDatStatus(sts); // Log it... if (Log.GetLevel() > 0) { Log.LogSendAfter(stsRcOrCc, ""); } // All done... return (stsRcOrCc); } /// /// Get/Set the custom DS data... /// /// Data group /// Operation /// CUSTOMDSDATA structure /// TWAIN status [PermissionSet(SecurityAction.LinkDemand, Name = "FullTrust", Unrestricted = false)] public STS DatCustomdsdata(DG a_dg, MSG a_msg, ref TW_CUSTOMDSDATA a_twcustomdsdata) { STS sts; // Submit the work to the TWAIN thread... if ((m_threadTwain != null) && (m_threadTwain.ManagedThreadId != Thread.CurrentThread.ManagedThreadId)) { lock (m_lockTwain) { // Set our command variables... ThreadData threaddata = default(ThreadData); threaddata.twcustomdsdata = a_twcustomdsdata; threaddata.dg = a_dg; threaddata.msg = a_msg; threaddata.dat = DAT.CUSTOMDSDATA; long lIndex = m_twaincommand.Submit(threaddata); // Submit the command and wait for the reply... CallerToThreadSet(); ThreadToCallerWaitOne(); // Return the result... a_twcustomdsdata = m_twaincommand.Get(lIndex).twcustomdsdata; sts = m_twaincommand.Get(lIndex).sts; // Clear the command variables... m_twaincommand.Delete(lIndex); } return (sts); } // Log it... if (Log.GetLevel() > 0) { Log.LogSendBefore(a_dg.ToString(), DAT.CUSTOMDSDATA.ToString(), a_msg.ToString(), CustomdsdataToCsv(a_twcustomdsdata)); } // Windows... if (ms_platform == Platform.WINDOWS) { // Issue the command... try { if (m_blUseLegacyDSM) { sts = (STS)NativeMethods.WindowsTwain32DsmEntryCustomdsdata(ref m_twidentitylegacyApp, ref m_twidentitylegacyDs, a_dg, DAT.CUSTOMDSDATA, a_msg, ref a_twcustomdsdata); } else { sts = (STS)NativeMethods.WindowsTwaindsmDsmEntryCustomdsdata(ref m_twidentitylegacyApp, ref m_twidentitylegacyDs, a_dg, DAT.CUSTOMDSDATA, a_msg, ref a_twcustomdsdata); } } catch (Exception exception) { // The driver crashed... Log.Error("crash - " + exception.Message); Log.LogSendAfter(STS.BUMMER, ""); return (STS.BUMMER); } } // Linux... else if (ms_platform == Platform.LINUX) { // Issue the command... try { if (m_blFoundLatestDsm64 && (m_linuxdsm == LinuxDsm.IsLatestDsm)) { sts = (STS)NativeMethods.Linux64DsmEntryCustomdsdata(ref m_twidentitylegacyApp, ref m_twidentitylegacyDs, a_dg, DAT.CUSTOMDSDATA, a_msg, ref a_twcustomdsdata); } else if (m_blFoundLatestDsm && (m_linuxdsm == LinuxDsm.IsLatestDsm)) { sts = (STS)NativeMethods.LinuxDsmEntryCustomdsdata(ref m_twidentitylegacyApp, ref m_twidentitylegacyDs, a_dg, DAT.CUSTOMDSDATA, a_msg, ref a_twcustomdsdata); } else if (m_blFound020302Dsm64bit && (m_linuxdsm == LinuxDsm.Is020302Dsm64bit)) { sts = (STS)NativeMethods.Linux020302Dsm64bitEntryCustomdsdata(ref m_twidentityApp, ref m_twidentityDs, a_dg, DAT.CUSTOMDSDATA, a_msg, ref a_twcustomdsdata); } else { Log.Error("apparently we don't have a DSM..."); sts = STS.BUMMER; } } catch (Exception exception) { // The driver crashed... Log.Error("crash - " + exception.Message); Log.LogSendAfter(STS.BUMMER, ""); return (STS.BUMMER); } } // Mac OS X, which has to be different... else if (ms_platform == Platform.MACOSX) { // Issue the command... try { if (m_blUseLegacyDSM) { sts = (STS)NativeMethods.MacosxTwainDsmEntryCustomdsdata(ref m_twidentitymacosxApp, ref m_twidentitymacosxDs, a_dg, DAT.CUSTOMDSDATA, a_msg, ref a_twcustomdsdata); } else { sts = (STS)NativeMethods.MacosxTwaindsmDsmEntryCustomdsdata(ref m_twidentitymacosxApp, ref m_twidentitymacosxDs, a_dg, DAT.CUSTOMDSDATA, a_msg, ref a_twcustomdsdata); } } catch (Exception exception) { // The driver crashed... Log.Error("crash - " + exception.Message); Log.LogSendAfter(STS.BUMMER, ""); return (STS.BUMMER); } } // Uh-oh... else { Log.LogSendAfter(STS.BUMMER, ""); return (STS.BUMMER); } // Get DAT_STATUS, if needed... TWAIN.STS stsRcOrCc = AutoDatStatus(sts); // Log it... if (Log.GetLevel() > 0) { Log.LogSendAfter(stsRcOrCc, CustomdsdataToCsv(a_twcustomdsdata)); } // All done... return (stsRcOrCc); } /// /// Get device events... /// /// Data group /// Operation /// DEVICEEVENT structure /// TWAIN status public STS DatDeviceevent(DG a_dg, MSG a_msg, ref TW_DEVICEEVENT a_twdeviceevent) { STS sts; // Submit the work to the TWAIN thread... if ((m_threadTwain != null) && (m_threadTwain.ManagedThreadId != Thread.CurrentThread.ManagedThreadId)) { lock (m_lockTwain) { // Set our command variables... ThreadData threaddata = default(ThreadData); threaddata.twdeviceevent = a_twdeviceevent; threaddata.dg = a_dg; threaddata.msg = a_msg; threaddata.dat = DAT.DEVICEEVENT; long lIndex = m_twaincommand.Submit(threaddata); // Submit the command and wait for the reply... CallerToThreadSet(); ThreadToCallerWaitOne(); // Return the result... a_twdeviceevent = m_twaincommand.Get(lIndex).twdeviceevent; sts = m_twaincommand.Get(lIndex).sts; // Clear the command variables... m_twaincommand.Delete(lIndex); } return (sts); } // Log it... if (Log.GetLevel() > 0) { Log.LogSendBefore(a_dg.ToString(), DAT.DEVICEEVENT.ToString(), a_msg.ToString(), ""); } // Windows... if (ms_platform == Platform.WINDOWS) { // Issue the command... try { if (m_blUseLegacyDSM) { sts = (STS)NativeMethods.WindowsTwain32DsmEntryDeviceevent(ref m_twidentitylegacyApp, ref m_twidentitylegacyDs, a_dg, DAT.DEVICEEVENT, a_msg, ref a_twdeviceevent); } else { sts = (STS)NativeMethods.WindowsTwaindsmDsmEntryDeviceevent(ref m_twidentitylegacyApp, ref m_twidentitylegacyDs, a_dg, DAT.DEVICEEVENT, a_msg, ref a_twdeviceevent); } } catch (Exception exception) { // The driver crashed... Log.Error("crash - " + exception.Message); Log.LogSendAfter(STS.BUMMER, ""); return (STS.BUMMER); } } // Linux... else if (ms_platform == Platform.LINUX) { // Issue the command... try { if (m_blFoundLatestDsm64 && (m_linuxdsm == LinuxDsm.IsLatestDsm)) { sts = (STS)NativeMethods.Linux64DsmEntryDeviceevent(ref m_twidentitylegacyApp, ref m_twidentitylegacyDs, a_dg, DAT.DEVICEEVENT, a_msg, ref a_twdeviceevent); } else if (m_blFoundLatestDsm && (m_linuxdsm == LinuxDsm.IsLatestDsm)) { sts = (STS)NativeMethods.LinuxDsmEntryDeviceevent(ref m_twidentitylegacyApp, ref m_twidentitylegacyDs, a_dg, DAT.DEVICEEVENT, a_msg, ref a_twdeviceevent); } else if (m_blFound020302Dsm64bit && (m_linuxdsm == LinuxDsm.Is020302Dsm64bit)) { sts = (STS)NativeMethods.Linux020302Dsm64bitEntryDeviceevent(ref m_twidentityApp, ref m_twidentityDs, a_dg, DAT.DEVICEEVENT, a_msg, ref a_twdeviceevent); } else { Log.Error("apparently we don't have a DSM..."); sts = STS.BUMMER; } } catch (Exception exception) { // The driver crashed... Log.Error("crash - " + exception.Message); Log.LogSendAfter(STS.BUMMER, ""); return (STS.BUMMER); } } // Mac OS X, which has to be different... else if (ms_platform == Platform.MACOSX) { // Issue the command... try { if (m_blUseLegacyDSM) { sts = (STS)NativeMethods.MacosxTwainDsmEntryDeviceevent(ref m_twidentitymacosxApp, ref m_twidentitymacosxDs, a_dg, DAT.DEVICEEVENT, a_msg, ref a_twdeviceevent); } else { sts = (STS)NativeMethods.MacosxTwaindsmDsmEntryDeviceevent(ref m_twidentitymacosxApp, ref m_twidentitymacosxDs, a_dg, DAT.DEVICEEVENT, a_msg, ref a_twdeviceevent); } } catch (Exception exception) { // The driver crashed... Log.Error("crash - " + exception.Message); Log.LogSendAfter(STS.BUMMER, ""); return (STS.BUMMER); } } // Uh-oh... else { Log.LogSendAfter(STS.BUMMER, ""); return (STS.BUMMER); } // Get DAT_STATUS, if needed... TWAIN.STS stsRcOrCc = AutoDatStatus(sts); // Log it... if (Log.GetLevel() > 0) { Log.LogSendAfter(stsRcOrCc, DeviceeventToCsv(a_twdeviceevent)); } // All done... return (stsRcOrCc); } /// /// Get the entrypoint data... /// /// Data group /// Operation /// ENTRYPOINT structure /// TWAIN status [PermissionSet(SecurityAction.LinkDemand, Name = "FullTrust", Unrestricted = false)] public STS DatEntrypoint(DG a_dg, MSG a_msg, ref TW_ENTRYPOINT a_twentrypoint) { STS sts; // Submit the work to the TWAIN thread... if ((m_threadTwain != null) && (m_threadTwain.ManagedThreadId != Thread.CurrentThread.ManagedThreadId)) { lock (m_lockTwain) { // Set our command variables... ThreadData threaddata = default(ThreadData); threaddata.twentrypoint = a_twentrypoint; threaddata.dg = a_dg; threaddata.msg = a_msg; threaddata.dat = DAT.ENTRYPOINT; long lIndex = m_twaincommand.Submit(threaddata); // Submit the command and wait for the reply... CallerToThreadSet(); ThreadToCallerWaitOne(); // Return the result... a_twentrypoint = m_twaincommand.Get(lIndex).twentrypoint; sts = m_twaincommand.Get(lIndex).sts; // Clear the command variables... m_twaincommand.Delete(lIndex); } return (sts); } // Log it... if (Log.GetLevel() > 0) { Log.LogSendBefore(a_dg.ToString(), DAT.ENTRYPOINT.ToString(), a_msg.ToString(), EntrypointToCsv(a_twentrypoint)); } // Windows... if (ms_platform == Platform.WINDOWS) { // Issue the command... try { if (m_blUseLegacyDSM) { sts = (STS)NativeMethods.WindowsTwain32DsmEntryEntrypoint(ref m_twidentitylegacyApp, ref m_twidentitylegacyDs, a_dg, DAT.ENTRYPOINT, a_msg, ref a_twentrypoint); } else { sts = (STS)NativeMethods.WindowsTwaindsmDsmEntryEntrypoint(ref m_twidentitylegacyApp, ref m_twidentitylegacyDs, a_dg, DAT.ENTRYPOINT, a_msg, ref a_twentrypoint); } } catch (Exception exception) { // The driver crashed... Log.Error("crash - " + exception.Message); Log.LogSendAfter(STS.BUMMER, ""); return (STS.BUMMER); } } // Linux... else if (ms_platform == Platform.LINUX) { // Issue the command... try { // Alright, this is super nasty. The application issues the call to // DAT_ENTRYPOINT before the call to MSG_OPENDS. We don't know which // driver they're going to use, so we don't know which DSM they're // going to end up with. This sucks in all kinds of ways. The only // reason we can hope for this to work is if all of the DSM's are in // agreement about the memory functions they're using. Lucky for us // on Linux it's always been calloc/free. So, we may be in the weird // situation of using a different DSM for the memory functions, but // it'l be okay. You can stop breathing in and out of that paper bag... sts = STS.BUMMER; if (m_blFoundLatestDsm64) { sts = (STS)NativeMethods.Linux64DsmEntryEntrypoint(ref m_twidentitylegacyApp, ref m_twidentitylegacyDs, a_dg, DAT.ENTRYPOINT, a_msg, ref a_twentrypoint); } else if (m_blFoundLatestDsm) { sts = (STS)NativeMethods.LinuxDsmEntryEntrypoint(ref m_twidentitylegacyApp, ref m_twidentitylegacyDs, a_dg, DAT.ENTRYPOINT, a_msg, ref a_twentrypoint); } else if (m_blFound020302Dsm64bit) { TW_ENTRYPOINT_LINUX64 twentrypointlinux64 = default(TW_ENTRYPOINT_LINUX64); twentrypointlinux64.Size = a_twentrypoint.Size; twentrypointlinux64.DSM_MemAllocate = a_twentrypoint.DSM_MemAllocate; twentrypointlinux64.DSM_MemFree = a_twentrypoint.DSM_MemFree; twentrypointlinux64.DSM_MemLock = a_twentrypoint.DSM_MemLock; twentrypointlinux64.DSM_MemUnlock = a_twentrypoint.DSM_MemUnlock; sts = (STS)NativeMethods.Linux020302Dsm64bitEntryEntrypoint(ref m_twidentityApp, ref m_twidentityDs, a_dg, DAT.ENTRYPOINT, a_msg, ref twentrypointlinux64); a_twentrypoint = default(TW_ENTRYPOINT); a_twentrypoint.Size = (uint)(twentrypointlinux64.Size & 0xFFFFFFFF); a_twentrypoint.DSM_MemAllocate = twentrypointlinux64.DSM_MemAllocate; a_twentrypoint.DSM_MemFree = twentrypointlinux64.DSM_MemFree; a_twentrypoint.DSM_MemLock = twentrypointlinux64.DSM_MemLock; a_twentrypoint.DSM_MemUnlock = twentrypointlinux64.DSM_MemUnlock; } else { Log.Error("apparently we don't have a DSM..."); sts = STS.BUMMER; } } catch (Exception exception) { // The driver crashed... Log.Error("crash - " + exception.Message); Log.LogSendAfter(STS.BUMMER, ""); return (STS.BUMMER); } } // Mac OS X, which has to be different... else if (ms_platform == Platform.MACOSX) { // Issue the command... try { if (m_blUseLegacyDSM) { sts = (STS)NativeMethods.MacosxTwainDsmEntryEntrypoint(ref m_twidentitymacosxApp, ref m_twidentitymacosxDs, a_dg, DAT.ENTRYPOINT, a_msg, ref a_twentrypoint); } else { sts = (STS)NativeMethods.MacosxTwaindsmDsmEntryEntrypoint(ref m_twidentitymacosxApp, ref m_twidentitymacosxDs, a_dg, DAT.ENTRYPOINT, a_msg, ref a_twentrypoint); } } catch (Exception exception) { // The driver crashed... Log.Error("crash - " + exception.Message); Log.LogSendAfter(STS.BUMMER, ""); return (STS.BUMMER); } } // Uh-oh... else { Log.LogSendAfter(STS.BUMMER, ""); return (STS.BUMMER); } // If we were successful, then squirrel away the data... if (sts == TWAIN.STS.SUCCESS) { m_twentrypointdelegates = default(TWAIN.TW_ENTRYPOINT_DELEGATES); m_twentrypointdelegates.Size = a_twentrypoint.Size; m_twentrypointdelegates.DSM_Entry = a_twentrypoint.DSM_Entry; if (a_twentrypoint.DSM_MemAllocate != null) { m_twentrypointdelegates.DSM_MemAllocate = (TWAIN.DSM_MEMALLOC)Marshal.GetDelegateForFunctionPointer(a_twentrypoint.DSM_MemAllocate,typeof(TWAIN.DSM_MEMALLOC)); } if (a_twentrypoint.DSM_MemFree != null) { m_twentrypointdelegates.DSM_MemFree = (TWAIN.DSM_MEMFREE)Marshal.GetDelegateForFunctionPointer(a_twentrypoint.DSM_MemFree, typeof(TWAIN.DSM_MEMFREE)); } if (a_twentrypoint.DSM_MemLock != null) { m_twentrypointdelegates.DSM_MemLock = (TWAIN.DSM_MEMLOCK)Marshal.GetDelegateForFunctionPointer(a_twentrypoint.DSM_MemLock, typeof(TWAIN.DSM_MEMLOCK)); } if (a_twentrypoint.DSM_MemUnlock != null) { m_twentrypointdelegates.DSM_MemUnlock = (TWAIN.DSM_MEMUNLOCK)Marshal.GetDelegateForFunctionPointer(a_twentrypoint.DSM_MemUnlock, typeof(TWAIN.DSM_MEMUNLOCK)); } } // Get DAT_STATUS, if needed... TWAIN.STS stsRcOrCc = AutoDatStatus(sts); // Log it... if (Log.GetLevel() > 0) { Log.LogSendAfter(stsRcOrCc, EntrypointToCsv(a_twentrypoint)); } // All done... return (stsRcOrCc); } /// /// Issue event commands... /// /// Data group /// Operation /// EVENT structure /// TWAIN status private void DatEventWindowsTwain32() { // If you get a first chance exception, be aware that some drivers // will do that to you, you can ignore it and they'll keep going... m_threaddataDatEvent.sts = (STS)NativeMethods.WindowsTwain32DsmEntryEvent ( ref m_twidentitylegacyApp, ref m_twidentitylegacyDs, m_threaddataDatEvent.dg, m_threaddataDatEvent.dat, m_threaddataDatEvent.msg, ref m_threaddataDatEvent.twevent ); } private void DatEventWindowsTwainDsm() { // If you get a first chance exception, be aware that some drivers // will do that to you, you can ignore it and they'll keep going... m_threaddataDatEvent.sts = (STS)NativeMethods.WindowsTwaindsmDsmEntryEvent ( ref m_twidentitylegacyApp, ref m_twidentitylegacyDs, m_threaddataDatEvent.dg, m_threaddataDatEvent.dat, m_threaddataDatEvent.msg, ref m_threaddataDatEvent.twevent ); } public STS DatEvent(DG a_dg, MSG a_msg, ref TW_EVENT a_twevent, bool a_blInPreFilter = false) { STS sts; // Log it... if (Log.GetLevel() > 1) { Log.LogSendBefore(a_dg.ToString(), DAT.EVENT.ToString(), a_msg.ToString(), ""); } // Windows... if (ms_platform == Platform.WINDOWS) { // Issue the command... try { if (a_blInPreFilter || m_threaddataDatEvent.blIsInuse || (this.m_runinuithreaddelegate == null)) { if (m_blUseLegacyDSM) { sts = (STS)NativeMethods.WindowsTwain32DsmEntryEvent(ref m_twidentitylegacyApp, ref m_twidentitylegacyDs, a_dg, DAT.EVENT, a_msg, ref a_twevent); } else { sts = (STS)NativeMethods.WindowsTwaindsmDsmEntryEvent(ref m_twidentitylegacyApp, ref m_twidentitylegacyDs, a_dg, DAT.EVENT, a_msg, ref a_twevent); } } else { if (m_blUseLegacyDSM) { lock (m_lockTwain) { m_threaddataDatEvent = default(ThreadData); m_threaddataDatEvent.blIsInuse = true; m_threaddataDatEvent.dg = a_dg; m_threaddataDatEvent.msg = a_msg; m_threaddataDatEvent.dat = DAT.EVENT; m_threaddataDatEvent.twevent = a_twevent; RunInUiThread(DatEventWindowsTwain32); a_twevent = m_threaddataDatEvent.twevent; sts = m_threaddataDatEvent.sts; m_threaddataDatEvent = default(ThreadData); } } else { lock (m_lockTwain) { m_threaddataDatEvent = default(ThreadData); m_threaddataDatEvent.blIsInuse = true; m_threaddataDatEvent.dg = a_dg; m_threaddataDatEvent.msg = a_msg; m_threaddataDatEvent.dat = DAT.EVENT; m_threaddataDatEvent.twevent = a_twevent; RunInUiThread(DatEventWindowsTwainDsm); a_twevent = m_threaddataDatEvent.twevent; sts = m_threaddataDatEvent.sts; m_threaddataDatEvent = default(ThreadData); } } } } catch (Exception exception) { // The driver crashed... Log.Error("crash - " + exception.Message); Log.LogSendAfter(STS.BUMMER, ""); return (STS.BUMMER); } } // Linux... else if (ms_platform == Platform.LINUX) { // Issue the command... try { if (m_blFoundLatestDsm64 && (m_linuxdsm == LinuxDsm.IsLatestDsm)) { sts = (STS)NativeMethods.Linux64DsmEntryEvent(ref m_twidentitylegacyApp, ref m_twidentitylegacyDs, a_dg, DAT.EVENT, a_msg, ref a_twevent); } else if (m_blFoundLatestDsm && (m_linuxdsm == LinuxDsm.IsLatestDsm)) { sts = (STS)NativeMethods.LinuxDsmEntryEvent(ref m_twidentitylegacyApp, ref m_twidentitylegacyDs, a_dg, DAT.EVENT, a_msg, ref a_twevent); } else if (m_blFound020302Dsm64bit && (m_linuxdsm == LinuxDsm.Is020302Dsm64bit)) { sts = (STS)NativeMethods.Linux020302Dsm64bitEntryEvent(ref m_twidentityApp, ref m_twidentityDs, a_dg, DAT.EVENT, a_msg, ref a_twevent); } else { Log.Error("apparently we don't have a DSM..."); sts = STS.BUMMER; } } catch (Exception exception) { // The driver crashed... Log.Error("crash - " + exception.Message); Log.LogSendAfter(STS.BUMMER, ""); return (STS.BUMMER); } } // Mac OS X, which has to be different... else if (ms_platform == Platform.MACOSX) { // Issue the command... try { if (m_blUseLegacyDSM) { sts = (STS)NativeMethods.MacosxTwainDsmEntryEvent(ref m_twidentitymacosxApp, ref m_twidentitymacosxDs, a_dg, DAT.EVENT, a_msg, ref a_twevent); } else { sts = (STS)NativeMethods.MacosxTwaindsmDsmEntryEvent(ref m_twidentitymacosxApp, ref m_twidentitymacosxDs, a_dg, DAT.EVENT, a_msg, ref a_twevent); } } catch (Exception exception) { // The driver crashed... Log.Error("crash - " + exception.Message); Log.LogSendAfter(STS.BUMMER, ""); return (STS.BUMMER); } } // Uh-oh... else { Log.LogSendAfter(STS.BUMMER, ""); return (STS.BUMMER); } // Get DAT_STATUS, if needed... TWAIN.STS stsRcOrCc = AutoDatStatus(sts); // Log it... if (Log.GetLevel() > 1) { Log.LogSendAfter(stsRcOrCc, ""); } // Check the event for anything interesting... if ((sts == STS.DSEVENT) || (sts == STS.NOTDSEVENT)) { ProcessEvent((MSG)a_twevent.TWMessage); } // All done... return (stsRcOrCc); } /// /// Get/Set extended image info information... /// /// Data group /// Operation /// EXTIMAGEINFO structure /// TWAIN status private void DatExtimageinfoWindowsTwain32() { // If you get a first chance exception, be aware that some drivers // will do that to you, you can ignore it and they'll keep going... m_threaddataDatExtimageinfo.sts = (STS)NativeMethods.WindowsTwain32DsmEntryExtimageinfo ( ref m_twidentitylegacyApp, ref m_twidentitylegacyDs, m_threaddataDatExtimageinfo.dg, m_threaddataDatExtimageinfo.dat, m_threaddataDatExtimageinfo.msg, ref m_threaddataDatExtimageinfo.twextimageinfo ); } private void DatExtimageinfoWindowsTwainDsm() { // If you get a first chance exception, be aware that some drivers // will do that to you, you can ignore it and they'll keep going... m_threaddataDatExtimageinfo.sts = (STS)NativeMethods.WindowsTwaindsmDsmEntryExtimageinfo ( ref m_twidentitylegacyApp, ref m_twidentitylegacyDs, m_threaddataDatExtimageinfo.dg, m_threaddataDatExtimageinfo.dat, m_threaddataDatExtimageinfo.msg, ref m_threaddataDatExtimageinfo.twextimageinfo ); } public STS DatExtimageinfo(DG a_dg, MSG a_msg, ref TW_EXTIMAGEINFO a_twextimageinfo) { STS sts; // Submit the work to the TWAIN thread... if (m_runinuithreaddelegate == null) { if ((m_threadTwain != null) && (m_threadTwain.ManagedThreadId != Thread.CurrentThread.ManagedThreadId)) { lock (m_lockTwain) { // Set our command variables... ThreadData threaddata = default(ThreadData); threaddata.twextimageinfo = a_twextimageinfo; threaddata.dg = a_dg; threaddata.msg = a_msg; threaddata.dat = DAT.EXTIMAGEINFO; long lIndex = m_twaincommand.Submit(threaddata); // Submit the command and wait for the reply... CallerToThreadSet(); ThreadToCallerWaitOne(); // Return the result... a_twextimageinfo = m_twaincommand.Get(lIndex).twextimageinfo; sts = m_twaincommand.Get(lIndex).sts; // Clear the command variables... m_twaincommand.Delete(lIndex); } return (sts); } } // Log it... if (Log.GetLevel() > 0) { Log.LogSendBefore(a_dg.ToString(), DAT.EXTIMAGEINFO.ToString(), a_msg.ToString(), ""); } // Windows... if (ms_platform == Platform.WINDOWS) { // Issue the command... try { if (m_threaddataDatExtimageinfo.blIsInuse || (this.m_runinuithreaddelegate == null)) { if (m_blUseLegacyDSM) { sts = (STS)NativeMethods.WindowsTwain32DsmEntryExtimageinfo(ref m_twidentitylegacyApp, ref m_twidentitylegacyDs, a_dg, DAT.EXTIMAGEINFO, a_msg, ref a_twextimageinfo); } else { sts = (STS)NativeMethods.WindowsTwaindsmDsmEntryExtimageinfo(ref m_twidentitylegacyApp, ref m_twidentitylegacyDs, a_dg, DAT.EXTIMAGEINFO, a_msg, ref a_twextimageinfo); } } else { if (m_blUseLegacyDSM) { lock (m_lockTwain) { m_threaddataDatExtimageinfo = default(ThreadData); m_threaddataDatExtimageinfo.blIsInuse = true; m_threaddataDatExtimageinfo.dg = a_dg; m_threaddataDatExtimageinfo.msg = a_msg; m_threaddataDatExtimageinfo.dat = DAT.EXTIMAGEINFO; m_threaddataDatExtimageinfo.twextimageinfo = a_twextimageinfo; RunInUiThread(DatExtimageinfoWindowsTwain32); a_twextimageinfo = m_threaddataDatExtimageinfo.twextimageinfo; sts = m_threaddataDatExtimageinfo.sts; m_threaddataDatExtimageinfo = default(ThreadData); } } else { lock (m_lockTwain) { m_threaddataDatExtimageinfo = default(ThreadData); m_threaddataDatExtimageinfo.blIsInuse = true; m_threaddataDatExtimageinfo.dg = a_dg; m_threaddataDatExtimageinfo.msg = a_msg; m_threaddataDatExtimageinfo.dat = DAT.EXTIMAGEINFO; m_threaddataDatExtimageinfo.twextimageinfo = a_twextimageinfo; RunInUiThread(DatExtimageinfoWindowsTwainDsm); a_twextimageinfo = m_threaddataDatExtimageinfo.twextimageinfo; sts = m_threaddataDatExtimageinfo.sts; m_threaddataDatExtimageinfo = default(ThreadData); } } } } catch (Exception exception) { // The driver crashed... Log.Error("crash - " + exception.Message); Log.LogSendAfter(STS.BUMMER, ""); return (STS.BUMMER); } } // Linux... else if (ms_platform == Platform.LINUX) { // Issue the command... try { if (m_blFoundLatestDsm64 && (m_linuxdsm == LinuxDsm.IsLatestDsm)) { sts = (STS)NativeMethods.Linux64DsmEntryExtimageinfo(ref m_twidentitylegacyApp, ref m_twidentitylegacyDs, a_dg, DAT.EXTIMAGEINFO, a_msg, ref a_twextimageinfo); } else if (m_blFoundLatestDsm && (m_linuxdsm == LinuxDsm.IsLatestDsm)) { sts = (STS)NativeMethods.LinuxDsmEntryExtimageinfo(ref m_twidentitylegacyApp, ref m_twidentitylegacyDs, a_dg, DAT.EXTIMAGEINFO, a_msg, ref a_twextimageinfo); } else if (m_blFound020302Dsm64bit && (m_linuxdsm == LinuxDsm.Is020302Dsm64bit)) { sts = (STS)NativeMethods.Linux020302Dsm64bitEntryExtimageinfo(ref m_twidentityApp, ref m_twidentityDs, a_dg, DAT.EXTIMAGEINFO, a_msg, ref a_twextimageinfo); } else { Log.Error("apparently we don't have a DSM..."); sts = STS.BUMMER; } } catch (Exception exception) { // The driver crashed... Log.Error("crash - " + exception.Message); Log.LogSendAfter(STS.BUMMER, ""); return (STS.BUMMER); } } // Mac OS X, which has to be different... else if (ms_platform == Platform.MACOSX) { // Issue the command... try { if (m_blUseLegacyDSM) { sts = (STS)NativeMethods.MacosxTwainDsmEntryExtimageinfo(ref m_twidentitymacosxApp, ref m_twidentitymacosxDs, a_dg, DAT.EXTIMAGEINFO, a_msg, ref a_twextimageinfo); } else { sts = (STS)NativeMethods.MacosxTwaindsmDsmEntryExtimageinfo(ref m_twidentitymacosxApp, ref m_twidentitymacosxDs, a_dg, DAT.EXTIMAGEINFO, a_msg, ref a_twextimageinfo); } } catch (Exception exception) { // The driver crashed... Log.Error("crash - " + exception.Message); Log.LogSendAfter(STS.BUMMER, ""); return (STS.BUMMER); } } // Uh-oh... else { Log.LogSendAfter(STS.BUMMER, ""); return (STS.BUMMER); } // Get DAT_STATUS, if needed... TWAIN.STS stsRcOrCc = AutoDatStatus(sts); // Log it... if (Log.GetLevel() > 0) { Log.LogSendAfter(stsRcOrCc, ""); } // All done... return (stsRcOrCc); } /// /// Get/Set the filesystem... /// /// Data group /// Operation /// FILESYSTEM structure /// TWAIN status public STS DatFilesystem(DG a_dg, MSG a_msg, ref TW_FILESYSTEM a_twfilesystem) { STS sts; // Submit the work to the TWAIN thread... if ((m_threadTwain != null) && (m_threadTwain.ManagedThreadId != Thread.CurrentThread.ManagedThreadId)) { lock (m_lockTwain) { // Set our command variables... ThreadData threaddata = default(ThreadData); threaddata.twfilesystem = a_twfilesystem; threaddata.dg = a_dg; threaddata.msg = a_msg; threaddata.dat = DAT.FILESYSTEM; long lIndex = m_twaincommand.Submit(threaddata); // Submit the command and wait for the reply... CallerToThreadSet(); ThreadToCallerWaitOne(); // Return the result... a_twfilesystem = m_twaincommand.Get(lIndex).twfilesystem; sts = m_twaincommand.Get(lIndex).sts; // Clear the command variables... m_twaincommand.Delete(lIndex); } return (sts); } // Log it... if (Log.GetLevel() > 0) { Log.LogSendBefore(a_dg.ToString(), DAT.FILESYSTEM.ToString(), a_msg.ToString(), FilesystemToCsv(a_twfilesystem)); } // Windows... if (ms_platform == Platform.WINDOWS) { // Issue the command... try { if (m_blUseLegacyDSM) { sts = (STS)NativeMethods.WindowsTwain32DsmEntryFilesystem(ref m_twidentitylegacyApp, ref m_twidentitylegacyDs, a_dg, DAT.FILESYSTEM, a_msg, ref a_twfilesystem); } else { sts = (STS)NativeMethods.WindowsTwaindsmDsmEntryFilesystem(ref m_twidentitylegacyApp, ref m_twidentitylegacyDs, a_dg, DAT.FILESYSTEM, a_msg, ref a_twfilesystem); } } catch (Exception exception) { // The driver crashed... Log.Error("crash - " + exception.Message); Log.LogSendAfter(STS.BUMMER, ""); return (STS.BUMMER); } } // Linux... else if (ms_platform == Platform.LINUX) { // Issue the command... try { if (m_blFoundLatestDsm64 && (m_linuxdsm == LinuxDsm.IsLatestDsm)) { sts = (STS)NativeMethods.Linux64DsmEntryFilesystem(ref m_twidentitylegacyApp, ref m_twidentitylegacyDs, a_dg, DAT.FILESYSTEM, a_msg, ref a_twfilesystem); } else if (m_blFoundLatestDsm && (m_linuxdsm == LinuxDsm.IsLatestDsm)) { sts = (STS)NativeMethods.LinuxDsmEntryFilesystem(ref m_twidentitylegacyApp, ref m_twidentitylegacyDs, a_dg, DAT.FILESYSTEM, a_msg, ref a_twfilesystem); } else if (m_blFound020302Dsm64bit && (m_linuxdsm == LinuxDsm.Is020302Dsm64bit)) { sts = (STS)NativeMethods.Linux020302Dsm64bitEntryFilesystem(ref m_twidentityApp, ref m_twidentityDs, a_dg, DAT.FILESYSTEM, a_msg, ref a_twfilesystem); } else { Log.Error("apparently we don't have a DSM..."); sts = STS.BUMMER; } } catch (Exception exception) { // The driver crashed... Log.Error("crash - " + exception.Message); Log.LogSendAfter(STS.BUMMER, ""); return (STS.BUMMER); } } // Mac OS X, which has to be different... else if (ms_platform == Platform.MACOSX) { // Issue the command... try { if (m_blUseLegacyDSM) { sts = (STS)NativeMethods.MacosxTwainDsmEntryFilesystem(ref m_twidentitymacosxApp, ref m_twidentitymacosxDs, a_dg, DAT.FILESYSTEM, a_msg, ref a_twfilesystem); } else { sts = (STS)NativeMethods.MacosxTwaindsmDsmEntryFilesystem(ref m_twidentitymacosxApp, ref m_twidentitymacosxDs, a_dg, DAT.FILESYSTEM, a_msg, ref a_twfilesystem); } } catch (Exception exception) { // The driver crashed... Log.Error("crash - " + exception.Message); Log.LogSendAfter(STS.BUMMER, ""); return (STS.BUMMER); } } // Uh-oh... else { Log.LogSendAfter(STS.BUMMER, ""); return (STS.BUMMER); } // Get DAT_STATUS, if needed... TWAIN.STS stsRcOrCc = AutoDatStatus(sts); // Log it... if (Log.GetLevel() > 0) { Log.LogSendAfter(stsRcOrCc, FilesystemToCsv(a_twfilesystem)); } // All done... return (stsRcOrCc); } /// /// Get/Set filter information... /// /// Data group /// Operation /// FILTER structure /// TWAIN status public STS DatFilter(DG a_dg, MSG a_msg, ref TW_FILTER a_twfilter) { STS sts; // Submit the work to the TWAIN thread... if ((m_threadTwain != null) && (m_threadTwain.ManagedThreadId != Thread.CurrentThread.ManagedThreadId)) { lock (m_lockTwain) { // Set our command variables... ThreadData threaddata = default(ThreadData); threaddata.twfilter = a_twfilter; threaddata.dg = a_dg; threaddata.msg = a_msg; threaddata.dat = DAT.FILTER; long lIndex = m_twaincommand.Submit(threaddata); // Submit the command and wait for the reply... CallerToThreadSet(); ThreadToCallerWaitOne(); // Return the result... a_twfilter = m_twaincommand.Get(lIndex).twfilter; sts = m_twaincommand.Get(lIndex).sts; // Clear the command variables... m_twaincommand.Delete(lIndex); } return (sts); } // Log it... if (Log.GetLevel() > 0) { Log.LogSendBefore(a_dg.ToString(), DAT.FILTER.ToString(), a_msg.ToString(), ""); } // Windows... if (ms_platform == Platform.WINDOWS) { // Issue the command... try { if (m_blUseLegacyDSM) { sts = (STS)NativeMethods.WindowsTwain32DsmEntryFilter(ref m_twidentitylegacyApp, ref m_twidentitylegacyDs, a_dg, DAT.FILTER, a_msg, ref a_twfilter); } else { sts = (STS)NativeMethods.WindowsTwaindsmDsmEntryFilter(ref m_twidentitylegacyApp, ref m_twidentitylegacyDs, a_dg, DAT.FILTER, a_msg, ref a_twfilter); } } catch (Exception exception) { // The driver crashed... Log.Error("crash - " + exception.Message); Log.LogSendAfter(STS.BUMMER, ""); return (STS.BUMMER); } } // Linux... else if (ms_platform == Platform.LINUX) { // Issue the command... try { if (m_blFoundLatestDsm64 && (m_linuxdsm == LinuxDsm.IsLatestDsm)) { sts = (STS)NativeMethods.Linux64DsmEntryFilter(ref m_twidentitylegacyApp, ref m_twidentitylegacyDs, a_dg, DAT.FILTER, a_msg, ref a_twfilter); } else if (m_blFoundLatestDsm && (m_linuxdsm == LinuxDsm.IsLatestDsm)) { sts = (STS)NativeMethods.LinuxDsmEntryFilter(ref m_twidentitylegacyApp, ref m_twidentitylegacyDs, a_dg, DAT.FILTER, a_msg, ref a_twfilter); } else if (m_blFound020302Dsm64bit && (m_linuxdsm == LinuxDsm.Is020302Dsm64bit)) { sts = (STS)NativeMethods.Linux020302Dsm64bitEntryFilter(ref m_twidentityApp, ref m_twidentityDs, a_dg, DAT.FILTER, a_msg, ref a_twfilter); } else { Log.Error("apparently we don't have a DSM..."); sts = STS.BUMMER; } } catch (Exception exception) { // The driver crashed... Log.Error("crash - " + exception.Message); Log.LogSendAfter(STS.BUMMER, ""); return (STS.BUMMER); } } // Mac OS X, which has to be different... else if (ms_platform == Platform.MACOSX) { // Issue the command... try { if (m_blUseLegacyDSM) { sts = (STS)NativeMethods.MacosxTwainDsmEntryFilter(ref m_twidentitymacosxApp, ref m_twidentitymacosxDs, a_dg, DAT.FILTER, a_msg, ref a_twfilter); } else { sts = (STS)NativeMethods.MacosxTwaindsmDsmEntryFilter(ref m_twidentitymacosxApp, ref m_twidentitymacosxDs, a_dg, DAT.FILTER, a_msg, ref a_twfilter); } } catch (Exception exception) { // The driver crashed... Log.Error("crash - " + exception.Message); Log.LogSendAfter(STS.BUMMER, ""); return (STS.BUMMER); } } // Uh-oh... else { Log.LogSendAfter(STS.BUMMER, ""); return (STS.BUMMER); } // Get DAT_STATUS, if needed... TWAIN.STS stsRcOrCc = AutoDatStatus(sts); // Log it... if (Log.GetLevel() > 0) { Log.LogSendAfter(stsRcOrCc, ""); } // All done... return (stsRcOrCc); } /// /// Get/Set for Gray response... /// /// Data group /// Operation /// GRAYRESPONSE structure /// TWAIN status public STS DatGrayresponse(DG a_dg, MSG a_msg, ref TW_GRAYRESPONSE a_twgrayresponse) { STS sts; // Submit the work to the TWAIN thread... if ((m_threadTwain != null) && (m_threadTwain.ManagedThreadId != Thread.CurrentThread.ManagedThreadId)) { lock (m_lockTwain) { // Set our command variables... ThreadData threaddata = default(ThreadData); threaddata.twgrayresponse = a_twgrayresponse; threaddata.dg = a_dg; threaddata.msg = a_msg; threaddata.dat = DAT.GRAYRESPONSE; long lIndex = m_twaincommand.Submit(threaddata); // Submit the command and wait for the reply... CallerToThreadSet(); ThreadToCallerWaitOne(); // Return the result... a_twgrayresponse = m_twaincommand.Get(lIndex).twgrayresponse; sts = m_twaincommand.Get(lIndex).sts; // Clear the command variables... m_twaincommand.Delete(lIndex); } return (sts); } // Log it... if (Log.GetLevel() > 0) { Log.LogSendBefore(a_dg.ToString(), DAT.GRAYRESPONSE.ToString(), a_msg.ToString(), ""); } // Windows... if (ms_platform == Platform.WINDOWS) { // Issue the command... try { if (m_blUseLegacyDSM) { sts = (STS)NativeMethods.WindowsTwain32DsmEntryGrayresponse(ref m_twidentitylegacyApp, ref m_twidentitylegacyDs, a_dg, DAT.GRAYRESPONSE, a_msg, ref a_twgrayresponse); } else { sts = (STS)NativeMethods.WindowsTwaindsmDsmEntryGrayresponse(ref m_twidentitylegacyApp, ref m_twidentitylegacyDs, a_dg, DAT.GRAYRESPONSE, a_msg, ref a_twgrayresponse); } } catch (Exception exception) { // The driver crashed... Log.Error("crash - " + exception.Message); Log.LogSendAfter(STS.BUMMER, ""); return (STS.BUMMER); } } // Linux... else if (ms_platform == Platform.LINUX) { // Issue the command... try { if (m_blFoundLatestDsm64 && (m_linuxdsm == LinuxDsm.IsLatestDsm)) { sts = (STS)NativeMethods.Linux64DsmEntryGrayresponse(ref m_twidentitylegacyApp, ref m_twidentitylegacyDs, a_dg, DAT.GRAYRESPONSE, a_msg, ref a_twgrayresponse); } else if (m_blFoundLatestDsm && (m_linuxdsm == LinuxDsm.IsLatestDsm)) { sts = (STS)NativeMethods.LinuxDsmEntryGrayresponse(ref m_twidentitylegacyApp, ref m_twidentitylegacyDs, a_dg, DAT.GRAYRESPONSE, a_msg, ref a_twgrayresponse); } else if (m_blFound020302Dsm64bit && (m_linuxdsm == LinuxDsm.Is020302Dsm64bit)) { sts = (STS)NativeMethods.Linux020302Dsm64bitEntryGrayresponse(ref m_twidentityApp, ref m_twidentityDs, a_dg, DAT.GRAYRESPONSE, a_msg, ref a_twgrayresponse); } else { Log.Error("apparently we don't have a DSM..."); sts = STS.BUMMER; } } catch (Exception exception) { // The driver crashed... Log.Error("crash - " + exception.Message); Log.LogSendAfter(STS.BUMMER, ""); return (STS.BUMMER); } } // Mac OS X, which has to be different... else if (ms_platform == Platform.MACOSX) { // Issue the command... try { if (m_blUseLegacyDSM) { sts = (STS)NativeMethods.MacosxTwainDsmEntryGrayresponse(ref m_twidentitymacosxApp, ref m_twidentitymacosxDs, a_dg, DAT.GRAYRESPONSE, a_msg, ref a_twgrayresponse); } else { sts = (STS)NativeMethods.MacosxTwaindsmDsmEntryGrayresponse(ref m_twidentitymacosxApp, ref m_twidentitymacosxDs, a_dg, DAT.GRAYRESPONSE, a_msg, ref a_twgrayresponse); } } catch (Exception exception) { // The driver crashed... Log.Error("crash - " + exception.Message); Log.LogSendAfter(STS.BUMMER, ""); return (STS.BUMMER); } } // Uh-oh... else { Log.LogSendAfter(STS.BUMMER, ""); return (STS.BUMMER); } // Get DAT_STATUS, if needed... TWAIN.STS stsRcOrCc = AutoDatStatus(sts); // Log it... if (Log.GetLevel() > 0) { Log.LogSendAfter(stsRcOrCc, ""); } // All done... return (stsRcOrCc); } /// /// Get/Set an ICC profile... /// /// Data group /// Operation /// ICCPROFILE structure /// TWAIN status public STS DatIccprofile(DG a_dg, MSG a_msg, ref TW_MEMORY a_twmemory) { STS sts; // Submit the work to the TWAIN thread... if ((m_threadTwain != null) && (m_threadTwain.ManagedThreadId != Thread.CurrentThread.ManagedThreadId)) { lock (m_lockTwain) { // Set our command variables... ThreadData threaddata = default(ThreadData); threaddata.twmemory = a_twmemory; threaddata.dg = a_dg; threaddata.msg = a_msg; threaddata.dat = DAT.ICCPROFILE; long lIndex = m_twaincommand.Submit(threaddata); // Submit the command and wait for the reply... CallerToThreadSet(); ThreadToCallerWaitOne(); // Return the result... a_twmemory = m_twaincommand.Get(lIndex).twmemory; sts = m_twaincommand.Get(lIndex).sts; // Clear the command variables... m_twaincommand.Delete(lIndex); } return (sts); } // Log it... if (Log.GetLevel() > 0) { Log.LogSendBefore(a_dg.ToString(), DAT.ICCPROFILE.ToString(), a_msg.ToString(), ""); } // Windows... if (ms_platform == Platform.WINDOWS) { // Issue the command... try { if (m_blUseLegacyDSM) { sts = (STS)NativeMethods.WindowsTwain32DsmEntryIccprofile(ref m_twidentitylegacyApp, ref m_twidentitylegacyDs, a_dg, DAT.ICCPROFILE, a_msg, ref a_twmemory); } else { sts = (STS)NativeMethods.WindowsTwaindsmDsmEntryIccprofile(ref m_twidentitylegacyApp, ref m_twidentitylegacyDs, a_dg, DAT.ICCPROFILE, a_msg, ref a_twmemory); } } catch (Exception exception) { // The driver crashed... Log.Error("crash - " + exception.Message); Log.LogSendAfter(STS.BUMMER, ""); return (STS.BUMMER); } } // Linux... else if (ms_platform == Platform.LINUX) { // Issue the command... try { if (m_blFoundLatestDsm64 && (m_linuxdsm == LinuxDsm.IsLatestDsm)) { sts = (STS)NativeMethods.Linux64DsmEntryIccprofile(ref m_twidentitylegacyApp, ref m_twidentitylegacyDs, a_dg, DAT.ICCPROFILE, a_msg, ref a_twmemory); } else if (m_blFoundLatestDsm && (m_linuxdsm == LinuxDsm.IsLatestDsm)) { sts = (STS)NativeMethods.LinuxDsmEntryIccprofile(ref m_twidentitylegacyApp, ref m_twidentitylegacyDs, a_dg, DAT.ICCPROFILE, a_msg, ref a_twmemory); } else if (m_blFound020302Dsm64bit && (m_linuxdsm == LinuxDsm.Is020302Dsm64bit)) { sts = (STS)NativeMethods.Linux020302Dsm64bitEntryIccprofile(ref m_twidentityApp, ref m_twidentityDs, a_dg, DAT.ICCPROFILE, a_msg, ref a_twmemory); } else { Log.Error("apparently we don't have a DSM..."); sts = STS.BUMMER; } } catch (Exception exception) { // The driver crashed... Log.Error("crash - " + exception.Message); Log.LogSendAfter(STS.BUMMER, ""); return (STS.BUMMER); } } // Mac OS X, which has to be different... else if (ms_platform == Platform.MACOSX) { // Issue the command... try { if (m_blUseLegacyDSM) { sts = (STS)NativeMethods.MacosxTwainDsmEntryIccprofile(ref m_twidentitymacosxApp, ref m_twidentitymacosxDs, a_dg, DAT.ICCPROFILE, a_msg, ref a_twmemory); } else { sts = (STS)NativeMethods.MacosxTwaindsmDsmEntryIccprofile(ref m_twidentitymacosxApp, ref m_twidentitymacosxDs, a_dg, DAT.ICCPROFILE, a_msg, ref a_twmemory); } } catch (Exception exception) { // The driver crashed... Log.Error("crash - " + exception.Message); Log.LogSendAfter(STS.BUMMER, ""); return (STS.BUMMER); } } // Uh-oh... else { Log.LogSendAfter(STS.BUMMER, ""); return (STS.BUMMER); } // Get DAT_STATUS, if needed... TWAIN.STS stsRcOrCc = AutoDatStatus(sts); // Log it... if (Log.GetLevel() > 0) { Log.LogSendAfter(stsRcOrCc, ""); } // All done... return (stsRcOrCc); } /// /// Issue identity commands... /// /// Data group /// Operation /// IDENTITY structure /// TWAIN status private void DatIdentityWindowsTwain32() { // If you get a first chance exception, be aware that some drivers // will do that to you, you can ignore it and they'll keep going... if (GetState() <= STATE.S3) { m_threaddataDatIdentity.sts = (STS)NativeMethods.WindowsTwain32DsmEntryIdentity ( ref m_twidentitylegacyApp, IntPtr.Zero, m_threaddataDatIdentity.dg, m_threaddataDatIdentity.dat, m_threaddataDatIdentity.msg, ref m_threaddataDatIdentity.twidentitylegacy ); } // Man, I'm learning stupid new stuff all the time, so the old DSM // had to have the destination. Argh... else { m_threaddataDatIdentity.sts = (STS)NativeMethods.WindowsTwain32DsmEntryIdentityState4 ( ref m_twidentitylegacyApp, ref m_twidentitylegacyDs, m_threaddataDatIdentity.dg, m_threaddataDatIdentity.dat, m_threaddataDatIdentity.msg, ref m_threaddataDatIdentity.twidentitylegacy ); } } private void DatIdentityWindowsTwainDsm() { // If you get a first chance exception, be aware that some drivers // will do that to you, you can ignore it and they'll keep going... m_threaddataDatIdentity.sts = (STS)NativeMethods.WindowsTwaindsmDsmEntryIdentity ( ref m_twidentitylegacyApp, IntPtr.Zero, m_threaddataDatIdentity.dg, m_threaddataDatIdentity.dat, m_threaddataDatIdentity.msg, ref m_threaddataDatIdentity.twidentitylegacy ); } [PermissionSet(SecurityAction.LinkDemand, Name = "FullTrust", Unrestricted = false)] public STS DatIdentity(DG a_dg, MSG a_msg, ref TW_IDENTITY a_twidentity) { STS sts; // Submit the work to the TWAIN thread... if (m_runinuithreaddelegate == null) { if ((m_threadTwain != null) && (m_threadTwain.ManagedThreadId != Thread.CurrentThread.ManagedThreadId)) { lock (m_lockTwain) { // Set our command variables... ThreadData threaddata = default(ThreadData); threaddata.twidentity = a_twidentity; threaddata.dg = a_dg; threaddata.msg = a_msg; threaddata.dat = DAT.IDENTITY; long lIndex = m_twaincommand.Submit(threaddata); // Submit the command and wait for the reply... CallerToThreadSet(); ThreadToCallerWaitOne(); // Return the result... a_twidentity = m_twaincommand.Get(lIndex).twidentity; sts = m_twaincommand.Get(lIndex).sts; // Clear the command variables... m_twaincommand.Delete(lIndex); } return (sts); } } // Log it... if (Log.GetLevel() > 0) { Log.LogSendBefore(a_dg.ToString(), DAT.IDENTITY.ToString(), a_msg.ToString(), ((a_msg == MSG.OPENDS) ? IdentityToCsv(a_twidentity) : "")); } // Windows... if (ms_platform == Platform.WINDOWS) { // Convert the identity structure... TW_IDENTITY_LEGACY twidentitylegacy = TwidentityToTwidentitylegacy(a_twidentity); // Issue the command... try { if (m_threaddataDatIdentity.blIsInuse || (this.m_runinuithreaddelegate == null)) { if (m_blUseLegacyDSM) { if (GetState() <= STATE.S3) { sts = (STS)NativeMethods.WindowsTwain32DsmEntryIdentity(ref m_twidentitylegacyApp, IntPtr.Zero, a_dg, DAT.IDENTITY, a_msg, ref twidentitylegacy); } else { sts = (STS)NativeMethods.WindowsTwain32DsmEntryIdentityState4(ref m_twidentitylegacyApp, ref m_twidentitylegacyDs, a_dg, DAT.IDENTITY, a_msg, ref twidentitylegacy); } } else { sts = (STS)NativeMethods.WindowsTwaindsmDsmEntryIdentity(ref m_twidentitylegacyApp, IntPtr.Zero, a_dg, DAT.IDENTITY, a_msg, ref twidentitylegacy); } } else { if (m_blUseLegacyDSM) { lock (m_lockTwain) { m_threaddataDatIdentity = default(ThreadData); m_threaddataDatIdentity.blIsInuse = true; m_threaddataDatIdentity.dg = a_dg; m_threaddataDatIdentity.msg = a_msg; m_threaddataDatIdentity.dat = DAT.IDENTITY; m_threaddataDatIdentity.twidentitylegacy = twidentitylegacy; RunInUiThread(DatIdentityWindowsTwain32); twidentitylegacy = m_threaddataDatIdentity.twidentitylegacy; sts = m_threaddataDatIdentity.sts; m_threaddataDatIdentity = default(ThreadData); } } else { lock (m_lockTwain) { m_threaddataDatIdentity = default(ThreadData); m_threaddataDatIdentity.blIsInuse = true; m_threaddataDatIdentity.dg = a_dg; m_threaddataDatIdentity.msg = a_msg; m_threaddataDatIdentity.dat = DAT.IDENTITY; m_threaddataDatIdentity.twidentitylegacy = twidentitylegacy; RunInUiThread(DatIdentityWindowsTwainDsm); twidentitylegacy = m_threaddataDatIdentity.twidentitylegacy; sts = m_threaddataDatIdentity.sts; m_threaddataDatIdentity = default(ThreadData); } } } } catch (Exception exception) { // The driver crashed... Log.Error("crash - " + exception.Message); Log.LogSendAfter(STS.BUMMER, ""); return (STS.BUMMER); } a_twidentity = TwidentitylegacyToTwidentity(twidentitylegacy); } // Linux... else if (ms_platform == Platform.LINUX) { // Issue the command, we have a serious problem with 64-bit stuff // because TW_INT32 and TW_UINT32 were defined using long, which // made them 64-bit values (not a good idea for 32-bit types). This // was fixed with TWAIN DSM 2.4, but it leaves us with a bit of a // mess. So, unlike all of the other calls, we're going to allow // ourselves to access both DSMs from here. This is only an issue // for 64-bit systems, and we're going to assume that the data source // is 2.4 or later, since that'll be the long term situation. Note // that we assume the DSMs are protecting us from talking to the // wrong data source... try { // Since life is complex, start by assuming failure... sts = STS.FAILURE; // Handle closeds... if (a_msg == MSG.CLOSEDS) { // We've opened this source, and we know it's the new style... if (m_blFoundLatestDsm64 && (m_linuxdsm == LinuxDsm.IsLatestDsm)) { TW_IDENTITY_LEGACY twidentitylegacy = TwidentityToTwidentitylegacy(a_twidentity); sts = (STS)NativeMethods.Linux64DsmEntryIdentity(ref m_twidentitylegacyApp, IntPtr.Zero, a_dg, DAT.IDENTITY, a_msg, ref twidentitylegacy); a_twidentity = TwidentitylegacyToTwidentity(twidentitylegacy); } // We've opened this source, and we know it's the new style... else if (m_blFoundLatestDsm && (m_linuxdsm == LinuxDsm.IsLatestDsm)) { TW_IDENTITY_LEGACY twidentitylegacy = TwidentityToTwidentitylegacy(a_twidentity); sts = (STS)NativeMethods.LinuxDsmEntryIdentity(ref m_twidentitylegacyApp, IntPtr.Zero, a_dg, DAT.IDENTITY, a_msg, ref twidentitylegacy); a_twidentity = TwidentitylegacyToTwidentity(twidentitylegacy); } // We've opened this source, and we know it's the old style... else if (m_blFound020302Dsm64bit && (m_linuxdsm == LinuxDsm.Is020302Dsm64bit)) { TW_IDENTITY_LINUX64 twidentitylinux64App = TwidentityToTwidentitylinux64(m_twidentityApp); TW_IDENTITY_LINUX64 twidentitylinux64 = TwidentityToTwidentitylinux64(a_twidentity); sts = (STS)NativeMethods.Linux020302Dsm64bitEntryIdentity(ref twidentitylinux64App, IntPtr.Zero, a_dg, DAT.IDENTITY, a_msg, ref twidentitylinux64); a_twidentity = Twidentitylinux64ToTwidentity(twidentitylinux64); } // We can't possibly have opened this source, so this had // better be a sequence error... else { sts = STS.SEQERROR; } } // Getfirst always starts with the latest DSM, if it can't find it, // or if it reports end of list, then go on to the old DSM, if we // have one. Note that it's up to the caller to handle any errors // and keep searching. We're not trying to figure out anything // about the driver at this level... else if (a_msg == MSG.GETFIRST) { m_linux64bitdsmDatIdentity = LinuxDsm.Unknown; // Assume end of list for the outcome... sts = STS.ENDOFLIST; // Try to start with the latest DSM... if (m_blFoundLatestDsm64) { m_linux64bitdsmDatIdentity = LinuxDsm.IsLatestDsm; TW_IDENTITY_LEGACY twidentitylegacy = TwidentityToTwidentitylegacy(a_twidentity); sts = (STS)NativeMethods.Linux64DsmEntryIdentity(ref m_twidentitylegacyApp, IntPtr.Zero, a_dg, DAT.IDENTITY, a_msg, ref twidentitylegacy); a_twidentity = TwidentitylegacyToTwidentity(twidentitylegacy); } // Try to start with the latest DSM... if (m_blFoundLatestDsm) { m_linux64bitdsmDatIdentity = LinuxDsm.IsLatestDsm; TW_IDENTITY_LEGACY twidentitylegacy = TwidentityToTwidentitylegacy(a_twidentity); sts = (STS)NativeMethods.LinuxDsmEntryIdentity(ref m_twidentitylegacyApp, IntPtr.Zero, a_dg, DAT.IDENTITY, a_msg, ref twidentitylegacy); a_twidentity = TwidentitylegacyToTwidentity(twidentitylegacy); } // If the lastest DSM didn't work, try the old stuff... if (m_blFound020302Dsm64bit && (sts == STS.ENDOFLIST)) { m_linux64bitdsmDatIdentity = LinuxDsm.Is020302Dsm64bit; TW_IDENTITY_LINUX64 twidentitylinux64App = TwidentityToTwidentitylinux64(m_twidentityApp); TW_IDENTITY_LINUX64 twidentitylinux64 = TwidentityToTwidentitylinux64(a_twidentity); sts = (STS)NativeMethods.Linux020302Dsm64bitEntryIdentity(ref twidentitylinux64App, IntPtr.Zero, a_dg, DAT.IDENTITY, a_msg, ref twidentitylinux64); a_twidentity = Twidentitylinux64ToTwidentity(twidentitylinux64); } } // Getnext gets its lead from getfirst, if we have a DSM // value, we try it out, if we don't have one, we must be // at the end of list. We'll do the new DSM and then the // old DSM (if we have one)... else if (a_msg == MSG.GETNEXT) { bool blChangeToGetFirst = false; // We're done, they'll have to use MSG_GETFIRST to start again... if (m_linux64bitdsmDatIdentity == LinuxDsm.Unknown) { sts = STS.ENDOFLIST; } // We're working the latest DSM, if we hit end of list, then we'll // try to switch over to the old DSM... if (m_blFoundLatestDsm64 && (m_linux64bitdsmDatIdentity == LinuxDsm.IsLatestDsm)) { TW_IDENTITY_LEGACY twidentitylegacy = TwidentityToTwidentitylegacy(a_twidentity); sts = (STS)NativeMethods.Linux64DsmEntryIdentity(ref m_twidentitylegacyApp, IntPtr.Zero, a_dg, DAT.IDENTITY, a_msg, ref twidentitylegacy); a_twidentity = TwidentitylegacyToTwidentity(twidentitylegacy); if (sts == STS.ENDOFLIST) { m_linux64bitdsmDatIdentity = m_blFound020302Dsm64bit ? LinuxDsm.Is020302Dsm64bit : LinuxDsm.Unknown; blChangeToGetFirst = true; } } // We're working the latest DSM, if we hit end of list, then we'll // try to switch over to the old DSM... if (m_blFoundLatestDsm && (m_linux64bitdsmDatIdentity == LinuxDsm.IsLatestDsm)) { TW_IDENTITY_LEGACY twidentitylegacy = TwidentityToTwidentitylegacy(a_twidentity); sts = (STS)NativeMethods.LinuxDsmEntryIdentity(ref m_twidentitylegacyApp, IntPtr.Zero, a_dg, DAT.IDENTITY, a_msg, ref twidentitylegacy); a_twidentity = TwidentitylegacyToTwidentity(twidentitylegacy); if (sts == STS.ENDOFLIST) { m_linux64bitdsmDatIdentity = m_blFound020302Dsm64bit ? LinuxDsm.Is020302Dsm64bit : LinuxDsm.Unknown; blChangeToGetFirst = true; } } // We're working the old DSM, if we hit the end of list, then we // clear the DSM indicator... if (m_blFound020302Dsm64bit && (m_linux64bitdsmDatIdentity == LinuxDsm.Is020302Dsm64bit)) { TW_IDENTITY_LINUX64 twidentitylinux64App = TwidentityToTwidentitylinux64(m_twidentityApp); TW_IDENTITY_LINUX64 twidentitylinux64 = blChangeToGetFirst ? default(TW_IDENTITY_LINUX64) : TwidentityToTwidentitylinux64(a_twidentity); sts = (STS)NativeMethods.Linux020302Dsm64bitEntryIdentity(ref twidentitylinux64App, IntPtr.Zero, a_dg, DAT.IDENTITY, blChangeToGetFirst ? MSG.GETFIRST : a_msg, ref twidentitylinux64); a_twidentity = Twidentitylinux64ToTwidentity(twidentitylinux64); if (sts == STS.ENDOFLIST) { m_linux64bitdsmDatIdentity = LinuxDsm.Unknown; } } } // Open always tries the current DSM, and then the older one, if needed... else if (a_msg == MSG.OPENDS) { TW_IDENTITY_LEGACY twidentitylegacy = default(TW_IDENTITY_LEGACY); // Prime the pump by assuming we didn't find anything... sts = STS.NODS; // Try with the latest DSM first, if we have one... if (m_blFoundLatestDsm64) { twidentitylegacy = TwidentityToTwidentitylegacy(a_twidentity); twidentitylegacy.Id = 0; try { sts = (STS)NativeMethods.Linux64DsmEntryIdentity(ref m_twidentitylegacyApp, IntPtr.Zero, a_dg, DAT.IDENTITY, a_msg, ref twidentitylegacy); } catch { sts = STS.NODS; } } // Try with the latest DSM first, if we have one... if (m_blFoundLatestDsm) { twidentitylegacy = TwidentityToTwidentitylegacy(a_twidentity); twidentitylegacy.Id = 0; try { sts = (STS)NativeMethods.LinuxDsmEntryIdentity(ref m_twidentitylegacyApp, IntPtr.Zero, a_dg, DAT.IDENTITY, a_msg, ref twidentitylegacy); } catch { sts = STS.NODS; } } // We got it... if (sts == STS.SUCCESS) { a_twidentity = TwidentitylegacyToTwidentity(twidentitylegacy); m_linuxdsm = LinuxDsm.IsLatestDsm; } // No joy, so try the old DSM... else if (m_blFound020302Dsm64bit) { TW_IDENTITY_LINUX64 twidentitylinux64App = TwidentityToTwidentitylinux64(m_twidentityApp); TW_IDENTITY_LINUX64 twidentitylinux64 = TwidentityToTwidentitylinux64(a_twidentity); twidentitylinux64.Id = 0; try { sts = (STS)NativeMethods.Linux020302Dsm64bitEntryIdentity(ref twidentitylinux64App, IntPtr.Zero, a_dg, DAT.IDENTITY, a_msg, ref twidentitylinux64); } catch { sts = STS.NODS; } // We got it... if (sts == STS.SUCCESS) { a_twidentity = Twidentitylinux64ToTwidentity(twidentitylinux64); m_linuxdsm = LinuxDsm.Is020302Dsm64bit; } } } // TBD: figure out how to safely do a set on Linux... else if (a_msg == MSG.SET) { // Just pretend we did it... } } catch (Exception exception) { // The driver crashed... Log.Error("crash - " + exception.Message); Log.LogSendAfter(STS.BUMMER, ""); return (STS.BUMMER); } } // Mac OS X, which has to be different... else if (ms_platform == Platform.MACOSX) { TW_IDENTITY_MACOSX twidentitymacosx = TwidentityToTwidentitymacosx(a_twidentity); // Issue the command... try { if (m_blUseLegacyDSM) { sts = (STS)NativeMethods.MacosxTwainDsmEntryIdentity(ref m_twidentitymacosxApp, IntPtr.Zero, a_dg, DAT.IDENTITY, a_msg, ref twidentitymacosx); } else { sts = (STS)NativeMethods.MacosxTwaindsmDsmEntryIdentity(ref m_twidentitymacosxApp, IntPtr.Zero, a_dg, DAT.IDENTITY, a_msg, ref twidentitymacosx); } } catch (Exception exception) { // The driver crashed... Log.Error("crash - " + exception.Message); Log.LogSendAfter(STS.BUMMER, ""); return (STS.BUMMER); } a_twidentity = TwidentitymacosxToTwidentity(twidentitymacosx); } // Uh-oh... else { Log.LogSendAfter(STS.BUMMER, ""); return (STS.BUMMER); } // Get DAT_STATUS, if needed... TWAIN.STS stsRcOrCc = AutoDatStatus(sts); // Log it... if (Log.GetLevel() > 0) { Log.LogSendAfter(stsRcOrCc, IdentityToCsv(a_twidentity)); } // If we opened, go to state 4... if (a_msg == MSG.OPENDS) { if (sts == STS.SUCCESS) { // Change our state, and record the identity we picked... m_state = STATE.S4; m_twidentityDs = a_twidentity; m_twidentitylegacyDs = TwidentityToTwidentitylegacy(m_twidentityDs); m_twidentitymacosxDs = TwidentityToTwidentitymacosx(m_twidentityDs); // update language Language.Set(m_twidentityDs.Version.Language); // Register for callbacks... // Windows... if (ms_platform == Platform.WINDOWS) { if (m_blUseCallbacks) { TW_CALLBACK twcallback = new TW_CALLBACK(); twcallback.CallBackProc = Marshal.GetFunctionPointerForDelegate(m_windowsdsmentrycontrolcallbackdelegate); // Log it... if (Log.GetLevel() > 0) { Log.LogSendBefore(a_dg.ToString(), DAT.CALLBACK.ToString(), a_msg.ToString(), CallbackToCsv(twcallback)); } // Issue the command... try { if (m_blUseLegacyDSM) { sts = (STS)NativeMethods.WindowsTwain32DsmEntryCallback(ref m_twidentitylegacyApp, ref m_twidentitylegacyDs, DG.CONTROL, DAT.CALLBACK, MSG.REGISTER_CALLBACK, ref twcallback); } else { sts = (STS)NativeMethods.WindowsTwaindsmDsmEntryCallback(ref m_twidentitylegacyApp, ref m_twidentitylegacyDs, DG.CONTROL, DAT.CALLBACK, MSG.REGISTER_CALLBACK, ref twcallback); } } catch (Exception exception) { // The driver crashed... Log.Error("crash - " + exception.Message); Log.LogSendAfter(STS.BUMMER, ""); return (STS.BUMMER); } // Log it... if (Log.GetLevel() > 0) { Log.LogSendAfter(sts, ""); } } } // Linux... else if (ms_platform == Platform.LINUX) { TW_CALLBACK twcallback = new TW_CALLBACK(); twcallback.CallBackProc = Marshal.GetFunctionPointerForDelegate(m_linuxdsmentrycontrolcallbackdelegate); // Log it... if (Log.GetLevel() > 0) { Log.LogSendBefore(a_dg.ToString(), DAT.CALLBACK.ToString(), MSG.REGISTER_CALLBACK.ToString(), CallbackToCsv(twcallback)); } // Issue the command... try { if (m_blFoundLatestDsm64 && (m_linuxdsm == LinuxDsm.IsLatestDsm)) { sts = (STS)NativeMethods.Linux64DsmEntryCallback(ref m_twidentitylegacyApp, ref m_twidentitylegacyDs, DG.CONTROL, DAT.CALLBACK, MSG.REGISTER_CALLBACK, ref twcallback); } else if (m_blFoundLatestDsm && (m_linuxdsm == LinuxDsm.IsLatestDsm)) { sts = (STS)NativeMethods.LinuxDsmEntryCallback(ref m_twidentitylegacyApp, ref m_twidentitylegacyDs, DG.CONTROL, DAT.CALLBACK, MSG.REGISTER_CALLBACK, ref twcallback); } else if (m_blFound020302Dsm64bit && (m_linuxdsm == LinuxDsm.Is020302Dsm64bit)) { sts = (STS)NativeMethods.Linux020302Dsm64bitEntryCallback(ref m_twidentityApp, ref m_twidentityDs, DG.CONTROL, DAT.CALLBACK, MSG.REGISTER_CALLBACK, ref twcallback); } else { Log.Error("apparently we don't have a DSM..."); sts = STS.BUMMER; } } catch (Exception exception) { // The driver crashed... Log.Error("crash - " + exception.Message); Log.LogSendAfter(STS.BUMMER, ""); return (STS.BUMMER); } // Log it... if (Log.GetLevel() > 0) { Log.LogSendAfter(sts, ""); } } // Mac OS X, which has to be different... else if (ms_platform == Platform.MACOSX) { IntPtr intptr = IntPtr.Zero; TW_CALLBACK twcallback = new TW_CALLBACK(); twcallback.CallBackProc = Marshal.GetFunctionPointerForDelegate(m_macosxdsmentrycontrolcallbackdelegate); // Log it... if (Log.GetLevel() > 0) { Log.LogSendBefore(a_dg.ToString(), DAT.CALLBACK.ToString(), a_msg.ToString(), CallbackToCsv(twcallback)); } // Issue the command... try { if (m_blUseLegacyDSM) { sts = (STS)NativeMethods.MacosxTwainDsmEntryCallback(ref m_twidentitymacosxApp, intptr, DG.CONTROL, DAT.CALLBACK, MSG.REGISTER_CALLBACK, ref twcallback); } else { sts = (STS)NativeMethods.MacosxTwaindsmDsmEntryCallback(ref m_twidentitymacosxApp, ref m_twidentityDs, DG.CONTROL, DAT.CALLBACK, MSG.REGISTER_CALLBACK, ref twcallback); } } catch (Exception exception) { // The driver crashed... Log.Error("crash - " + exception.Message); Log.LogSendAfter(STS.BUMMER, ""); return (STS.BUMMER); } // Log it... if (Log.GetLevel() > 0) { Log.LogSendAfter(sts, ""); } } } } // If we closed, go to state 3... else if (a_msg == MSG.CLOSEDS) { if (sts == STS.SUCCESS) { m_state = STATE.S3; } } // All done... return (stsRcOrCc); } /// /// Get/Set image info information... /// /// Data group /// Operation /// IMAGEINFO structure /// TWAIN status private void DatImageinfoWindowsTwain32() { // If you get a first chance exception, be aware that some drivers // will do that to you, you can ignore it and they'll keep going... m_threaddataDatImageinfo.sts = (STS)NativeMethods.WindowsTwain32DsmEntryImageinfo ( ref m_twidentitylegacyApp, ref m_twidentitylegacyDs, m_threaddataDatImageinfo.dg, m_threaddataDatImageinfo.dat, m_threaddataDatImageinfo.msg, ref m_threaddataDatImageinfo.twimageinfo ); } private void DatImageinfoWindowsTwainDsm() { // If you get a first chance exception, be aware that some drivers // will do that to you, you can ignore it and they'll keep going... m_threaddataDatImageinfo.sts = (STS)NativeMethods.WindowsTwaindsmDsmEntryImageinfo ( ref m_twidentitylegacyApp, ref m_twidentitylegacyDs, m_threaddataDatImageinfo.dg, m_threaddataDatImageinfo.dat, m_threaddataDatImageinfo.msg, ref m_threaddataDatImageinfo.twimageinfo ); } public STS DatImageinfo(DG a_dg, MSG a_msg, ref TW_IMAGEINFO a_twimageinfo) { STS sts; // Submit the work to the TWAIN thread... if (m_runinuithreaddelegate == null) { if ((m_threadTwain != null) && (m_threadTwain.ManagedThreadId != Thread.CurrentThread.ManagedThreadId)) { lock (m_lockTwain) { // Set our command variables... ThreadData threaddata = default(ThreadData); threaddata.twimageinfo = a_twimageinfo; threaddata.dg = a_dg; threaddata.msg = a_msg; threaddata.dat = DAT.IMAGEINFO; long lIndex = m_twaincommand.Submit(threaddata); // Submit the command and wait for the reply... CallerToThreadSet(); ThreadToCallerWaitOne(); // Return the result... a_twimageinfo = m_twaincommand.Get(lIndex).twimageinfo; sts = m_twaincommand.Get(lIndex).sts; // Clear the command variables... m_twaincommand.Delete(lIndex); } return (sts); } } // Log it... if (Log.GetLevel() > 0) { Log.LogSendBefore(a_dg.ToString(), DAT.IMAGEINFO.ToString(), a_msg.ToString(), ""); } // Windows... if (ms_platform == Platform.WINDOWS) { // Issue the command... try { if (m_threaddataDatImageinfo.blIsInuse || (this.m_runinuithreaddelegate == null)) { if (m_blUseLegacyDSM) { sts = (STS)NativeMethods.WindowsTwain32DsmEntryImageinfo(ref m_twidentitylegacyApp, ref m_twidentitylegacyDs, a_dg, DAT.IMAGEINFO, a_msg, ref a_twimageinfo); } else { sts = (STS)NativeMethods.WindowsTwaindsmDsmEntryImageinfo(ref m_twidentitylegacyApp, ref m_twidentitylegacyDs, a_dg, DAT.IMAGEINFO, a_msg, ref a_twimageinfo); } } else { if (m_blUseLegacyDSM) { lock (m_lockTwain) { m_threaddataDatImageinfo = default(ThreadData); m_threaddataDatImageinfo.blIsInuse = true; m_threaddataDatImageinfo.dg = a_dg; m_threaddataDatImageinfo.msg = a_msg; m_threaddataDatImageinfo.dat = DAT.IMAGEINFO; m_threaddataDatImageinfo.twimageinfo = a_twimageinfo; RunInUiThread(DatImageinfoWindowsTwain32); a_twimageinfo = m_threaddataDatImageinfo.twimageinfo; sts = m_threaddataDatImageinfo.sts; m_threaddataDatImageinfo = default(ThreadData); } } else { lock (m_lockTwain) { m_threaddataDatImageinfo = default(ThreadData); m_threaddataDatImageinfo.blIsInuse = true; m_threaddataDatImageinfo.dg = a_dg; m_threaddataDatImageinfo.msg = a_msg; m_threaddataDatImageinfo.dat = DAT.IMAGEINFO; m_threaddataDatImageinfo.twimageinfo = a_twimageinfo; RunInUiThread(DatImageinfoWindowsTwainDsm); a_twimageinfo = m_threaddataDatImageinfo.twimageinfo; sts = m_threaddataDatImageinfo.sts; m_threaddataDatImageinfo = default(ThreadData); } } } } catch (Exception exception) { // The driver crashed... Log.Error("crash - " + exception.Message); Log.LogSendAfter(STS.BUMMER, ""); return (STS.BUMMER); } } // Linux... else if (ms_platform == Platform.LINUX) { // Issue the command... try { if (m_blFoundLatestDsm64 && (m_linuxdsm == LinuxDsm.IsLatestDsm)) { sts = (STS)NativeMethods.Linux64DsmEntryImageinfo(ref m_twidentitylegacyApp, ref m_twidentitylegacyDs, a_dg, DAT.IMAGEINFO, a_msg, ref a_twimageinfo); } else if (m_blFoundLatestDsm && (m_linuxdsm == LinuxDsm.IsLatestDsm)) { sts = (STS)NativeMethods.LinuxDsmEntryImageinfo(ref m_twidentitylegacyApp, ref m_twidentitylegacyDs, a_dg, DAT.IMAGEINFO, a_msg, ref a_twimageinfo); } else if (m_blFound020302Dsm64bit && (m_linuxdsm == LinuxDsm.Is020302Dsm64bit)) { TW_IMAGEINFO_LINUX64 twimageinfolinux64 = default(TW_IMAGEINFO_LINUX64); sts = (STS)NativeMethods.Linux020302Dsm64bitEntryImageinfo(ref m_twidentityApp, ref m_twidentityDs, a_dg, DAT.IMAGEINFO, a_msg, ref twimageinfolinux64); a_twimageinfo.XResolution = twimageinfolinux64.XResolution; a_twimageinfo.YResolution = twimageinfolinux64.YResolution; a_twimageinfo.ImageWidth = (int)twimageinfolinux64.ImageWidth; a_twimageinfo.ImageLength = (int)twimageinfolinux64.ImageLength; a_twimageinfo.SamplesPerPixel = twimageinfolinux64.SamplesPerPixel; a_twimageinfo.BitsPerSample_0 = twimageinfolinux64.BitsPerSample_0; a_twimageinfo.BitsPerSample_1 = twimageinfolinux64.BitsPerSample_1; a_twimageinfo.BitsPerSample_2 = twimageinfolinux64.BitsPerSample_2; a_twimageinfo.BitsPerSample_3 = twimageinfolinux64.BitsPerSample_3; a_twimageinfo.BitsPerSample_4 = twimageinfolinux64.BitsPerSample_4; a_twimageinfo.BitsPerSample_5 = twimageinfolinux64.BitsPerSample_5; a_twimageinfo.BitsPerSample_6 = twimageinfolinux64.BitsPerSample_6; a_twimageinfo.BitsPerSample_7 = twimageinfolinux64.BitsPerSample_7; a_twimageinfo.BitsPerPixel = twimageinfolinux64.BitsPerPixel; a_twimageinfo.Planar = twimageinfolinux64.Planar; a_twimageinfo.PixelType = twimageinfolinux64.PixelType; a_twimageinfo.Compression = twimageinfolinux64.Compression; } else { Log.Error("apparently we don't have a DSM..."); sts = STS.BUMMER; } } catch (Exception exception) { // The driver crashed... Log.Error("crash - " + exception.Message); Log.LogSendAfter(STS.BUMMER, ""); return (STS.BUMMER); } } // Mac OS X, which has to be different... else if (ms_platform == Platform.MACOSX) { // Issue the command... try { if (m_blUseLegacyDSM) { sts = (STS)NativeMethods.MacosxTwainDsmEntryImageinfo(ref m_twidentitymacosxApp, ref m_twidentitymacosxDs, a_dg, DAT.IMAGEINFO, a_msg, ref a_twimageinfo); } else { sts = (STS)NativeMethods.MacosxTwaindsmDsmEntryImageinfo(ref m_twidentitymacosxApp, ref m_twidentitymacosxDs, a_dg, DAT.IMAGEINFO, a_msg, ref a_twimageinfo); } } catch (Exception exception) { // The driver crashed... Log.Error("crash - " + exception.Message); Log.LogSendAfter(STS.BUMMER, ""); return (STS.BUMMER); } } // Uh-oh... else { Log.LogSendAfter(STS.BUMMER, ""); return (STS.BUMMER); } // Get DAT_STATUS, if needed... TWAIN.STS stsRcOrCc = AutoDatStatus(sts); // Log it... if (Log.GetLevel() > 0) { Log.LogSendAfter(stsRcOrCc, ImageinfoToCsv(a_twimageinfo)); } // All done... return (stsRcOrCc); } /// /// Get/Set layout information... /// /// Data group /// Operation /// IMAGELAYOUT structure /// TWAIN status private void DatImagelayoutWindowsTwain32() { // If you get a first chance exception, be aware that some drivers // will do that to you, you can ignore it and they'll keep going... m_threaddataDatImagelayout.sts = (STS)NativeMethods.WindowsTwain32DsmEntryImagelayout ( ref m_twidentitylegacyApp, ref m_twidentitylegacyDs, m_threaddataDatImagelayout.dg, m_threaddataDatImagelayout.dat, m_threaddataDatImagelayout.msg, ref m_threaddataDatImagelayout.twimagelayout ); } private void DatImagelayoutWindowsTwainDsm() { // If you get a first chance exception, be aware that some drivers // will do that to you, you can ignore it and they'll keep going... m_threaddataDatImagelayout.sts = (STS)NativeMethods.WindowsTwaindsmDsmEntryImagelayout ( ref m_twidentitylegacyApp, ref m_twidentitylegacyDs, m_threaddataDatImagelayout.dg, m_threaddataDatImagelayout.dat, m_threaddataDatImagelayout.msg, ref m_threaddataDatImagelayout.twimagelayout ); } public STS DatImagelayout(DG a_dg, MSG a_msg, ref TW_IMAGELAYOUT a_twimagelayout) { STS sts; // Submit the work to the TWAIN thread... if (m_runinuithreaddelegate == null) { if ((m_threadTwain != null) && (m_threadTwain.ManagedThreadId != Thread.CurrentThread.ManagedThreadId)) { lock (m_lockTwain) { // Set our command variables... ThreadData threaddata = default(ThreadData); threaddata.twimagelayout = a_twimagelayout; threaddata.dg = a_dg; threaddata.msg = a_msg; threaddata.dat = DAT.IMAGELAYOUT; long lIndex = m_twaincommand.Submit(threaddata); // Submit the command and wait for the reply... CallerToThreadSet(); ThreadToCallerWaitOne(); // Return the result... a_twimagelayout = m_twaincommand.Get(lIndex).twimagelayout; sts = m_twaincommand.Get(lIndex).sts; // Clear the command variables... m_twaincommand.Delete(lIndex); } return (sts); } } // Log it... if (Log.GetLevel() > 0) { Log.LogSendBefore(a_dg.ToString(), DAT.IMAGELAYOUT.ToString(), a_msg.ToString(), ImagelayoutToCsv(a_twimagelayout)); } // Windows... if (ms_platform == Platform.WINDOWS) { // Issue the command... try { if (m_threaddataDatImagelayout.blIsInuse || (this.m_runinuithreaddelegate == null)) { if (m_blUseLegacyDSM) { sts = (STS)NativeMethods.WindowsTwain32DsmEntryImagelayout(ref m_twidentitylegacyApp, ref m_twidentitylegacyDs, a_dg, DAT.IMAGELAYOUT, a_msg, ref a_twimagelayout); } else { sts = (STS)NativeMethods.WindowsTwaindsmDsmEntryImagelayout(ref m_twidentitylegacyApp, ref m_twidentitylegacyDs, a_dg, DAT.IMAGELAYOUT, a_msg, ref a_twimagelayout); } } else { if (m_blUseLegacyDSM) { lock (m_lockTwain) { m_threaddataDatImagelayout = default(ThreadData); m_threaddataDatImagelayout.blIsInuse = true; m_threaddataDatImagelayout.dg = a_dg; m_threaddataDatImagelayout.msg = a_msg; m_threaddataDatImagelayout.dat = DAT.IMAGELAYOUT; m_threaddataDatImagelayout.twimagelayout = a_twimagelayout; RunInUiThread(DatImagelayoutWindowsTwain32); a_twimagelayout = m_threaddataDatImagelayout.twimagelayout; sts = m_threaddataDatImagelayout.sts; m_threaddataDatImagelayout = default(ThreadData); } } else { lock (m_lockTwain) { m_threaddataDatImagelayout = default(ThreadData); m_threaddataDatImagelayout.blIsInuse = true; m_threaddataDatImagelayout.dg = a_dg; m_threaddataDatImagelayout.msg = a_msg; m_threaddataDatImagelayout.dat = DAT.IMAGELAYOUT; m_threaddataDatImagelayout.twimagelayout = a_twimagelayout; RunInUiThread(DatImagelayoutWindowsTwainDsm); a_twimagelayout = m_threaddataDatImagelayout.twimagelayout; sts = m_threaddataDatImagelayout.sts; m_threaddataDatImagelayout = default(ThreadData); } } } } catch (Exception exception) { // The driver crashed... Log.Error("crash - " + exception.Message); Log.LogSendAfter(STS.BUMMER, ""); return (STS.BUMMER); } } // Linux... else if (ms_platform == Platform.LINUX) { // Issue the command... try { if (m_blFoundLatestDsm64 && (m_linuxdsm == LinuxDsm.IsLatestDsm)) { sts = (STS)NativeMethods.Linux64DsmEntryImagelayout(ref m_twidentitylegacyApp, ref m_twidentitylegacyDs, a_dg, DAT.IMAGELAYOUT, a_msg, ref a_twimagelayout); } else if (m_blFoundLatestDsm && (m_linuxdsm == LinuxDsm.IsLatestDsm)) { sts = (STS)NativeMethods.LinuxDsmEntryImagelayout(ref m_twidentitylegacyApp, ref m_twidentitylegacyDs, a_dg, DAT.IMAGELAYOUT, a_msg, ref a_twimagelayout); } else if (m_blFound020302Dsm64bit && (m_linuxdsm == LinuxDsm.Is020302Dsm64bit)) { sts = (STS)NativeMethods.Linux020302Dsm64bitEntryImagelayout(ref m_twidentityApp, ref m_twidentityDs, a_dg, DAT.IMAGELAYOUT, a_msg, ref a_twimagelayout); } else { Log.Error("apparently we don't have a DSM..."); sts = STS.BUMMER; } } catch (Exception exception) { // The driver crashed... Log.Error("crash - " + exception.Message); Log.LogSendAfter(STS.BUMMER, ""); return (STS.BUMMER); } } // Mac OS X, which has to be different... else if (ms_platform == Platform.MACOSX) { // Issue the command... try { if (m_blUseLegacyDSM) { sts = (STS)NativeMethods.MacosxTwainDsmEntryImagelayout(ref m_twidentitymacosxApp, ref m_twidentitymacosxDs, a_dg, DAT.IMAGELAYOUT, a_msg, ref a_twimagelayout); } else { sts = (STS)NativeMethods.MacosxTwaindsmDsmEntryImagelayout(ref m_twidentitymacosxApp, ref m_twidentitymacosxDs, a_dg, DAT.IMAGELAYOUT, a_msg, ref a_twimagelayout); } } catch (Exception exception) { // The driver crashed... Log.Error("crash - " + exception.Message); Log.LogSendAfter(STS.BUMMER, ""); return (STS.BUMMER); } } // Uh-oh... else { Log.LogSendAfter(STS.BUMMER, ""); return (STS.BUMMER); } // Get DAT_STATUS, if needed... TWAIN.STS stsRcOrCc = AutoDatStatus(sts); // Log it... if (Log.GetLevel() > 0) { Log.LogSendAfter(stsRcOrCc, ImagelayoutToCsv(a_twimagelayout)); } // All done... return (stsRcOrCc); } /// /// Issue file image transfer commands... /// /// Data group /// Operation /// TWAIN status private void DatImagefilexferWindowsTwain32() { // If you get a first chance exception, be aware that some drivers // will do that to you, you can ignore it and they'll keep going... m_threaddataDatImagefilexfer.sts = (STS)NativeMethods.WindowsTwain32DsmEntryImagefilexfer ( ref m_twidentitylegacyApp, ref m_twidentitylegacyDs, m_threaddataDatImagefilexfer.dg, m_threaddataDatImagefilexfer.dat, m_threaddataDatImagefilexfer.msg, IntPtr.Zero ); } private void DatImagefilexferWindowsTwainDsm() { // If you get a first chance exception, be aware that some drivers // will do that to you, you can ignore it and they'll keep going... m_threaddataDatImagefilexfer.sts = (STS)NativeMethods.WindowsTwaindsmDsmEntryImagefilexfer ( ref m_twidentitylegacyApp, ref m_twidentitylegacyDs, m_threaddataDatImagefilexfer.dg, m_threaddataDatImagefilexfer.dat, m_threaddataDatImagefilexfer.msg, IntPtr.Zero ); } public STS DatImagefilexfer(DG a_dg, MSG a_msg) { STS sts; // Submit the work to the TWAIN thread... if (this.m_runinuithreaddelegate == null) { if ((m_threadTwain != null) && (m_threadTwain.ManagedThreadId != Thread.CurrentThread.ManagedThreadId)) { lock (m_lockTwain) { // Set our command variables... ThreadData threaddata = default(ThreadData); threaddata.dg = a_dg; threaddata.msg = a_msg; threaddata.dat = DAT.IMAGEFILEXFER; long lIndex = m_twaincommand.Submit(threaddata); // Submit the command and wait for the reply... CallerToThreadSet(); ThreadToCallerWaitOne(); // Return the result... sts = m_twaincommand.Get(lIndex).sts; // Clear the command variables... m_twaincommand.Delete(lIndex); } return (sts); } } // Log it... if (Log.GetLevel() > 0) { Log.LogSendBefore(a_dg.ToString(), DAT.IMAGEFILEXFER.ToString(), a_msg.ToString(), ""); } // Windows... if (ms_platform == Platform.WINDOWS) { // Issue the command... try { if (m_threaddataDatImagefilexfer.blIsInuse || (this.m_runinuithreaddelegate == null)) { if (m_blUseLegacyDSM) { sts = (STS)NativeMethods.WindowsTwain32DsmEntryImagefilexfer(ref m_twidentitylegacyApp, ref m_twidentitylegacyDs, a_dg, DAT.IMAGEFILEXFER, a_msg, IntPtr.Zero); } else { sts = (STS)NativeMethods.WindowsTwaindsmDsmEntryImagefilexfer(ref m_twidentitylegacyApp, ref m_twidentitylegacyDs, a_dg, DAT.IMAGEFILEXFER, a_msg, IntPtr.Zero); } } else { if (m_blUseLegacyDSM) { lock (m_lockTwain) { m_threaddataDatImagefilexfer = default(ThreadData); m_threaddataDatImagefilexfer.blIsInuse = true; m_threaddataDatImagefilexfer.dg = a_dg; m_threaddataDatImagefilexfer.msg = a_msg; m_threaddataDatImagefilexfer.dat = DAT.IMAGEFILEXFER; RunInUiThread(DatImagefilexferWindowsTwain32); sts = m_threaddataDatImagefilexfer.sts; m_threaddataDatImagefilexfer = default(ThreadData); } } else { lock (m_lockTwain) { m_threaddataDatImagefilexfer = default(ThreadData); m_threaddataDatImagefilexfer.blIsInuse = true; m_threaddataDatImagefilexfer.dg = a_dg; m_threaddataDatImagefilexfer.msg = a_msg; m_threaddataDatImagefilexfer.dat = DAT.IMAGEFILEXFER; RunInUiThread(DatImagefilexferWindowsTwainDsm); sts = m_threaddataDatImagefilexfer.sts; m_threaddataDatImagefilexfer = default(ThreadData); } } } } catch (Exception exception) { // The driver crashed... Log.Error("crash - " + exception.Message); Log.LogSendAfter(STS.BUMMER, ""); return (STS.BUMMER); } } // Linux... else if (ms_platform == Platform.LINUX) { // Issue the command... try { if (m_blFoundLatestDsm64 && (m_linuxdsm == LinuxDsm.IsLatestDsm)) { sts = (STS)NativeMethods.Linux64DsmEntryImagefilexfer(ref m_twidentitylegacyApp, ref m_twidentitylegacyDs, a_dg, DAT.IMAGEFILEXFER, a_msg, IntPtr.Zero); } else if (m_blFoundLatestDsm && (m_linuxdsm == LinuxDsm.IsLatestDsm)) { sts = (STS)NativeMethods.LinuxDsmEntryImagefilexfer(ref m_twidentitylegacyApp, ref m_twidentitylegacyDs, a_dg, DAT.IMAGEFILEXFER, a_msg, IntPtr.Zero); } else if (m_blFound020302Dsm64bit && (m_linuxdsm == LinuxDsm.Is020302Dsm64bit)) { sts = (STS)NativeMethods.Linux020302Dsm64bitEntryImagefilexfer(ref m_twidentityApp, ref m_twidentityDs, a_dg, DAT.IMAGEFILEXFER, a_msg, IntPtr.Zero); } else { Log.Error("apparently we don't have a DSM..."); sts = STS.BUMMER; } } catch (Exception exception) { // The driver crashed... Log.Error("crash - " + exception.Message); Log.LogSendAfter(STS.BUMMER, ""); return (STS.BUMMER); } } // Mac OS X, which has to be different... else if (ms_platform == Platform.MACOSX) { // Issue the command... try { if (m_blUseLegacyDSM) { sts = (STS)NativeMethods.MacosxTwainDsmEntryImagefilexfer(ref m_twidentitymacosxApp, ref m_twidentitymacosxDs, a_dg, DAT.IMAGEFILEXFER, a_msg, IntPtr.Zero); } else { sts = (STS)NativeMethods.MacosxTwaindsmDsmEntryImagefilexfer(ref m_twidentitymacosxApp, ref m_twidentitymacosxDs, a_dg, DAT.IMAGEFILEXFER, a_msg, IntPtr.Zero); } } catch (Exception exception) { // The driver crashed... Log.Error("crash - " + exception.Message); Log.LogSendAfter(STS.BUMMER, ""); return (STS.BUMMER); } } // Uh-oh... else { Log.LogSendAfter(STS.BUMMER, ""); return (STS.BUMMER); } // Get DAT_STATUS, if needed... TWAIN.STS stsRcOrCc = AutoDatStatus(sts); // Log it... if (Log.GetLevel() > 0) { Log.LogSendAfter(stsRcOrCc, ""); } // If we had a successful transfer, then change state... if (sts == STS.XFERDONE) { m_state = STATE.S7; } // All done... return (stsRcOrCc); } /// /// Issue memory file image transfer commands... /// /// Data group /// Operation /// IMAGEMEMXFER structure /// TWAIN status private void DatImagememfilexferWindowsTwain32() { // If you get a first chance exception, be aware that some drivers // will do that to you, you can ignore it and they'll keep going... m_threaddataDatImagememfilexfer.sts = (STS)NativeMethods.WindowsTwain32DsmEntryImagememfilexfer ( ref m_twidentitylegacyApp, ref m_twidentitylegacyDs, m_threaddataDatImagememfilexfer.dg, m_threaddataDatImagememfilexfer.dat, m_threaddataDatImagememfilexfer.msg, ref m_threaddataDatImagememfilexfer.twimagememxfer ); } private void DatImagememfilexferWindowsTwainDsm() { // If you get a first chance exception, be aware that some drivers // will do that to you, you can ignore it and they'll keep going... m_threaddataDatImagememfilexfer.sts = (STS)NativeMethods.WindowsTwaindsmDsmEntryImagememfilexfer ( ref m_twidentitylegacyApp, ref m_twidentitylegacyDs, m_threaddataDatImagememfilexfer.dg, m_threaddataDatImagememfilexfer.dat, m_threaddataDatImagememfilexfer.msg, ref m_threaddataDatImagememfilexfer.twimagememxfer ); } public STS DatImagememfilexfer(DG a_dg, MSG a_msg, ref TW_IMAGEMEMXFER a_twimagememxfer) { STS sts; // Submit the work to the TWAIN thread... if (this.m_runinuithreaddelegate == null) { if ((m_threadTwain != null) && (m_threadTwain.ManagedThreadId != Thread.CurrentThread.ManagedThreadId)) { lock (m_lockTwain) { // Set our command variables... ThreadData threaddata = default(ThreadData); threaddata.twimagememxfer = a_twimagememxfer; threaddata.dg = a_dg; threaddata.msg = a_msg; threaddata.dat = DAT.IMAGEMEMFILEXFER; long lIndex = m_twaincommand.Submit(threaddata); // Submit the command and wait for the reply... CallerToThreadSet(); ThreadToCallerWaitOne(); // Return the result... a_twimagememxfer = m_twaincommand.Get(lIndex).twimagememxfer; sts = m_twaincommand.Get(lIndex).sts; // Clear the command variables... m_twaincommand.Delete(lIndex); } return (sts); } } // Log it... if (Log.GetLevel() > 0) { Log.LogSendBefore(a_dg.ToString(), DAT.IMAGEMEMFILEXFER.ToString(), a_msg.ToString(), ImagememxferToCsv(a_twimagememxfer)); } // Windows... if (ms_platform == Platform.WINDOWS) { // Issue the command... try { if (m_threaddataDatImagememfilexfer.blIsInuse || (this.m_runinuithreaddelegate == null)) { if (m_blUseLegacyDSM) { sts = (STS)NativeMethods.WindowsTwain32DsmEntryImagememfilexfer(ref m_twidentitylegacyApp, ref m_twidentitylegacyDs, a_dg, DAT.IMAGEMEMFILEXFER, a_msg, ref a_twimagememxfer); } else { sts = (STS)NativeMethods.WindowsTwaindsmDsmEntryImagememfilexfer(ref m_twidentitylegacyApp, ref m_twidentitylegacyDs, a_dg, DAT.IMAGEMEMFILEXFER, a_msg, ref a_twimagememxfer); } } else { if (m_blUseLegacyDSM) { lock (m_lockTwain) { m_threaddataDatImagememfilexfer = default(ThreadData); m_threaddataDatImagememfilexfer.blIsInuse = true; m_threaddataDatImagememfilexfer.dg = a_dg; m_threaddataDatImagememfilexfer.msg = a_msg; m_threaddataDatImagememfilexfer.dat = DAT.IMAGEMEMFILEXFER; m_threaddataDatImagememfilexfer.twimagememxfer = a_twimagememxfer; RunInUiThread(DatImagememfilexferWindowsTwain32); a_twimagememxfer = m_threaddataDatImagememfilexfer.twimagememxfer; sts = m_threaddataDatImagememfilexfer.sts; m_threaddataDatImagememfilexfer = default(ThreadData); } } else { lock (m_lockTwain) { m_threaddataDatImagememfilexfer = default(ThreadData); m_threaddataDatImagememfilexfer.blIsInuse = true; m_threaddataDatImagememfilexfer.dg = a_dg; m_threaddataDatImagememfilexfer.msg = a_msg; m_threaddataDatImagememfilexfer.dat = DAT.IMAGEMEMFILEXFER; m_threaddataDatImagememfilexfer.twimagememxfer = a_twimagememxfer; RunInUiThread(DatImagememfilexferWindowsTwainDsm); a_twimagememxfer = m_threaddataDatImagememfilexfer.twimagememxfer; sts = m_threaddataDatImagememfilexfer.sts; m_threaddataDatImagememfilexfer = default(ThreadData); } } } } catch (Exception exception) { // The driver crashed... Log.Error("crash - " + exception.Message); Log.LogSendAfter(STS.BUMMER, ""); return (STS.BUMMER); } } // Linux... else if (ms_platform == Platform.LINUX) { // Issue the command... try { if (m_blFoundLatestDsm64 && (m_linuxdsm == LinuxDsm.IsLatestDsm)) { sts = (STS)NativeMethods.Linux64DsmEntryImagememfilexfer(ref m_twidentitylegacyApp, ref m_twidentitylegacyDs, a_dg, DAT.IMAGEMEMFILEXFER, a_msg, ref a_twimagememxfer); } else if (m_blFoundLatestDsm && (m_linuxdsm == LinuxDsm.IsLatestDsm)) { sts = (STS)NativeMethods.LinuxDsmEntryImagememfilexfer(ref m_twidentitylegacyApp, ref m_twidentitylegacyDs, a_dg, DAT.IMAGEMEMFILEXFER, a_msg, ref a_twimagememxfer); } else if (m_blFound020302Dsm64bit && (m_linuxdsm == LinuxDsm.Is020302Dsm64bit)) { TW_IMAGEMEMXFER_LINUX64 twimagememxferlinux64 = default(TW_IMAGEMEMXFER_LINUX64); twimagememxferlinux64.BytesPerRow = a_twimagememxfer.BytesPerRow; twimagememxferlinux64.BytesWritten = a_twimagememxfer.BytesWritten; twimagememxferlinux64.Columns = a_twimagememxfer.Columns; twimagememxferlinux64.Compression = a_twimagememxfer.Compression; twimagememxferlinux64.MemoryFlags = a_twimagememxfer.Memory.Flags; twimagememxferlinux64.MemoryLength = a_twimagememxfer.Memory.Length; twimagememxferlinux64.MemoryTheMem = a_twimagememxfer.Memory.TheMem; twimagememxferlinux64.Rows = a_twimagememxfer.Rows; twimagememxferlinux64.XOffset = a_twimagememxfer.XOffset; twimagememxferlinux64.YOffset = a_twimagememxfer.YOffset; sts = (STS)NativeMethods.Linux020302Dsm64bitEntryImagememfilexfer(ref m_twidentityApp, ref m_twidentityDs, a_dg, DAT.IMAGEMEMFILEXFER, a_msg, ref twimagememxferlinux64); a_twimagememxfer.BytesPerRow = (uint)twimagememxferlinux64.BytesPerRow; a_twimagememxfer.BytesWritten = (uint)twimagememxferlinux64.BytesWritten; a_twimagememxfer.Columns = (uint)twimagememxferlinux64.Columns; a_twimagememxfer.Compression = (ushort)twimagememxferlinux64.Compression; a_twimagememxfer.Memory.Flags = (uint)twimagememxferlinux64.MemoryFlags; a_twimagememxfer.Memory.Length = (uint)twimagememxferlinux64.MemoryLength; a_twimagememxfer.Memory.TheMem = twimagememxferlinux64.MemoryTheMem; a_twimagememxfer.Rows = (uint)twimagememxferlinux64.Rows; a_twimagememxfer.XOffset = (uint)twimagememxferlinux64.XOffset; a_twimagememxfer.YOffset = (uint)twimagememxferlinux64.YOffset; } else { Log.Error("apparently we don't have a DSM..."); sts = STS.BUMMER; } } catch (Exception exception) { // The driver crashed... Log.Error("crash - " + exception.Message); Log.LogSendAfter(STS.BUMMER, ""); return (STS.BUMMER); } } // Mac OS X, which has to be different... else if (ms_platform == Platform.MACOSX) { // Issue the command... try { TW_IMAGEMEMXFER_MACOSX twimagememxfermacosx = default(TW_IMAGEMEMXFER_MACOSX); twimagememxfermacosx.BytesPerRow = a_twimagememxfer.BytesPerRow; twimagememxfermacosx.BytesWritten = a_twimagememxfer.BytesWritten; twimagememxfermacosx.Columns = a_twimagememxfer.Columns; twimagememxfermacosx.Compression = a_twimagememxfer.Compression; twimagememxfermacosx.Memory.Flags = a_twimagememxfer.Memory.Flags; twimagememxfermacosx.Memory.Length = a_twimagememxfer.Memory.Length; twimagememxfermacosx.Memory.TheMem = a_twimagememxfer.Memory.TheMem; twimagememxfermacosx.Rows = a_twimagememxfer.Rows; twimagememxfermacosx.XOffset = a_twimagememxfer.XOffset; twimagememxfermacosx.YOffset = a_twimagememxfer.YOffset; if (m_blUseLegacyDSM) { sts = (STS)NativeMethods.MacosxTwainDsmEntryImagememfilexfer(ref m_twidentitymacosxApp, ref m_twidentitymacosxDs, a_dg, DAT.IMAGEMEMFILEXFER, a_msg, ref twimagememxfermacosx); } else { sts = (STS)NativeMethods.MacosxTwaindsmDsmEntryImagememfilexfer(ref m_twidentitymacosxApp, ref m_twidentitymacosxDs, a_dg, DAT.IMAGEMEMFILEXFER, a_msg, ref twimagememxfermacosx); } a_twimagememxfer.BytesPerRow = twimagememxfermacosx.BytesPerRow; a_twimagememxfer.BytesWritten = twimagememxfermacosx.BytesWritten; a_twimagememxfer.Columns = twimagememxfermacosx.Columns; a_twimagememxfer.Compression = (ushort)twimagememxfermacosx.Compression; a_twimagememxfer.Memory.Flags = twimagememxfermacosx.Memory.Flags; a_twimagememxfer.Memory.Length = twimagememxfermacosx.Memory.Length; a_twimagememxfer.Memory.TheMem = twimagememxfermacosx.Memory.TheMem; a_twimagememxfer.Rows = twimagememxfermacosx.Rows; a_twimagememxfer.XOffset = twimagememxfermacosx.XOffset; a_twimagememxfer.YOffset = twimagememxfermacosx.YOffset; } catch (Exception exception) { // The driver crashed... Log.Error("crash - " + exception.Message); Log.LogSendAfter(STS.BUMMER, ""); return (STS.BUMMER); } } // Uh-oh... else { Log.LogSendAfter(STS.BUMMER, ""); return (STS.BUMMER); } // Get DAT_STATUS, if needed... TWAIN.STS stsRcOrCc = AutoDatStatus(sts); // Log it... if (Log.GetLevel() > 0) { Log.LogSendAfter(stsRcOrCc, ImagememxferToCsv(a_twimagememxfer)); } // If we had a successful transfer, then change state... if (sts == STS.XFERDONE) { m_state = STATE.S7; } // All done... return (stsRcOrCc); } /// /// Issue memory image transfer commands... /// /// Data group /// Operation /// IMAGEMEMXFER structure /// TWAIN status private void DatImagememxferWindowsTwain32() { // If you get a first chance exception, be aware that some drivers // will do that to you, you can ignore it and they'll keep going... m_threaddataDatImagememxfer.sts = (STS)NativeMethods.WindowsTwain32DsmEntryImagememxfer ( ref m_twidentitylegacyApp, ref m_twidentitylegacyDs, m_threaddataDatImagememxfer.dg, m_threaddataDatImagememxfer.dat, m_threaddataDatImagememxfer.msg, ref m_threaddataDatImagememxfer.twimagememxfer ); } private void DatImagememxferWindowsTwainDsm() { // If you get a first chance exception, be aware that some drivers // will do that to you, you can ignore it and they'll keep going... m_threaddataDatImagememxfer.sts = (STS)NativeMethods.WindowsTwaindsmDsmEntryImagememxfer ( ref m_twidentitylegacyApp, ref m_twidentitylegacyDs, m_threaddataDatImagememxfer.dg, m_threaddataDatImagememxfer.dat, m_threaddataDatImagememxfer.msg, ref m_threaddataDatImagememxfer.twimagememxfer ); } public STS DatImagememxfer(DG a_dg, MSG a_msg, ref TW_IMAGEMEMXFER a_twimagememxfer) { STS sts; // Submit the work to the TWAIN thread... if (this.m_runinuithreaddelegate == null) { if ((m_threadTwain != null) && (m_threadTwain.ManagedThreadId != Thread.CurrentThread.ManagedThreadId)) { lock (m_lockTwain) { // Set our command variables... ThreadData threaddata = default(ThreadData); threaddata.twimagememxfer = a_twimagememxfer; threaddata.dg = a_dg; threaddata.msg = a_msg; threaddata.dat = DAT.IMAGEMEMXFER; long lIndex = m_twaincommand.Submit(threaddata); // Submit the command and wait for the reply... CallerToThreadSet(); ThreadToCallerWaitOne(); // Return the result... a_twimagememxfer = m_twaincommand.Get(lIndex).twimagememxfer; sts = m_twaincommand.Get(lIndex).sts; // Clear the command variables... m_twaincommand.Delete(lIndex); } return (sts); } } // Log it... if (Log.GetLevel() > 0) { Log.LogSendBefore(a_dg.ToString(), DAT.IMAGEMEMXFER.ToString(), a_msg.ToString(), ImagememxferToCsv(a_twimagememxfer)); } // Windows... if (ms_platform == Platform.WINDOWS) { // Issue the command... try { if (m_threaddataDatImagememxfer.blIsInuse || (this.m_runinuithreaddelegate == null)) { if (m_blUseLegacyDSM) { sts = (STS)NativeMethods.WindowsTwain32DsmEntryImagememxfer(ref m_twidentitylegacyApp, ref m_twidentitylegacyDs, a_dg, DAT.IMAGEMEMXFER, a_msg, ref a_twimagememxfer); } else { sts = (STS)NativeMethods.WindowsTwaindsmDsmEntryImagememxfer(ref m_twidentitylegacyApp, ref m_twidentitylegacyDs, a_dg, DAT.IMAGEMEMXFER, a_msg, ref a_twimagememxfer); } } else { if (m_blUseLegacyDSM) { lock (m_lockTwain) { m_threaddataDatImagememxfer = default(ThreadData); m_threaddataDatImagememxfer.blIsInuse = true; m_threaddataDatImagememxfer.dg = a_dg; m_threaddataDatImagememxfer.msg = a_msg; m_threaddataDatImagememxfer.dat = DAT.IMAGEMEMXFER; m_threaddataDatImagememxfer.twimagememxfer = a_twimagememxfer; RunInUiThread(DatImagememxferWindowsTwain32); a_twimagememxfer = m_threaddataDatImagememxfer.twimagememxfer; sts = m_threaddataDatImagememxfer.sts; m_threaddataDatImagememxfer = default(ThreadData); } } else { lock (m_lockTwain) { m_threaddataDatImagememxfer = default(ThreadData); m_threaddataDatImagememxfer.blIsInuse = true; m_threaddataDatImagememxfer.dg = a_dg; m_threaddataDatImagememxfer.msg = a_msg; m_threaddataDatImagememxfer.dat = DAT.IMAGEMEMXFER; m_threaddataDatImagememxfer.twimagememxfer = a_twimagememxfer; RunInUiThread(DatImagememxferWindowsTwainDsm); a_twimagememxfer = m_threaddataDatImagememxfer.twimagememxfer; sts = m_threaddataDatImagememxfer.sts; m_threaddataDatImagememxfer = default(ThreadData); } } } } catch (Exception exception) { // The driver crashed... Log.Error("crash - " + exception.Message); Log.LogSendAfter(STS.BUMMER, ""); return (STS.BUMMER); } } // Linux... else if (ms_platform == Platform.LINUX) { // Issue the command... try { if (m_blFoundLatestDsm64 && (m_linuxdsm == LinuxDsm.IsLatestDsm)) { sts = (STS)NativeMethods.Linux64DsmEntryImagememxfer(ref m_twidentitylegacyApp, ref m_twidentitylegacyDs, a_dg, DAT.IMAGEMEMXFER, a_msg, ref a_twimagememxfer); } else if (m_blFoundLatestDsm && (m_linuxdsm == LinuxDsm.IsLatestDsm)) { sts = (STS)NativeMethods.LinuxDsmEntryImagememxfer(ref m_twidentitylegacyApp, ref m_twidentitylegacyDs, a_dg, DAT.IMAGEMEMXFER, a_msg, ref a_twimagememxfer); } else if (m_blFound020302Dsm64bit && (m_linuxdsm == LinuxDsm.Is020302Dsm64bit)) { TW_IMAGEMEMXFER_LINUX64 twimagememxferlinux64 = default(TW_IMAGEMEMXFER_LINUX64); twimagememxferlinux64.BytesPerRow = a_twimagememxfer.BytesPerRow; twimagememxferlinux64.BytesWritten = a_twimagememxfer.BytesWritten; twimagememxferlinux64.Columns = a_twimagememxfer.Columns; twimagememxferlinux64.Compression = a_twimagememxfer.Compression; twimagememxferlinux64.MemoryFlags = a_twimagememxfer.Memory.Flags; twimagememxferlinux64.MemoryLength = a_twimagememxfer.Memory.Length; twimagememxferlinux64.MemoryTheMem = a_twimagememxfer.Memory.TheMem; twimagememxferlinux64.Rows = a_twimagememxfer.Rows; twimagememxferlinux64.XOffset = a_twimagememxfer.XOffset; twimagememxferlinux64.YOffset = a_twimagememxfer.YOffset; sts = (STS)NativeMethods.Linux020302Dsm64bitEntryImagememxfer(ref m_twidentityApp, ref m_twidentityDs, a_dg, DAT.IMAGEMEMXFER, a_msg, ref twimagememxferlinux64); a_twimagememxfer.BytesPerRow = (uint)twimagememxferlinux64.BytesPerRow; a_twimagememxfer.BytesWritten = (uint)twimagememxferlinux64.BytesWritten; a_twimagememxfer.Columns = (uint)twimagememxferlinux64.Columns; a_twimagememxfer.Compression = (ushort)twimagememxferlinux64.Compression; a_twimagememxfer.Memory.Flags = (uint)twimagememxferlinux64.MemoryFlags; a_twimagememxfer.Memory.Length = (uint)twimagememxferlinux64.MemoryLength; a_twimagememxfer.Memory.TheMem = twimagememxferlinux64.MemoryTheMem; a_twimagememxfer.Rows = (uint)twimagememxferlinux64.Rows; a_twimagememxfer.XOffset = (uint)twimagememxferlinux64.XOffset; a_twimagememxfer.YOffset = (uint)twimagememxferlinux64.YOffset; } else { Log.Error("apparently we don't have a DSM..."); sts = STS.BUMMER; } } catch (Exception exception) { // The driver crashed... Log.Error("crash - " + exception.Message); Log.LogSendAfter(STS.BUMMER, ""); return (STS.BUMMER); } } // Mac OS X, which has to be different... else if (ms_platform == Platform.MACOSX) { // Issue the command... try { TW_IMAGEMEMXFER_MACOSX twimagememxfermacosx = default(TW_IMAGEMEMXFER_MACOSX); twimagememxfermacosx.BytesPerRow = a_twimagememxfer.BytesPerRow; twimagememxfermacosx.BytesWritten = a_twimagememxfer.BytesWritten; twimagememxfermacosx.Columns = a_twimagememxfer.Columns; twimagememxfermacosx.Compression = a_twimagememxfer.Compression; twimagememxfermacosx.Memory.Flags = a_twimagememxfer.Memory.Flags; twimagememxfermacosx.Memory.Length = a_twimagememxfer.Memory.Length; twimagememxfermacosx.Memory.TheMem = a_twimagememxfer.Memory.TheMem; twimagememxfermacosx.Rows = a_twimagememxfer.Rows; twimagememxfermacosx.XOffset = a_twimagememxfer.XOffset; twimagememxfermacosx.YOffset = a_twimagememxfer.YOffset; if (m_blUseLegacyDSM) { sts = (STS)NativeMethods.MacosxTwainDsmEntryImagememxfer(ref m_twidentitymacosxApp, ref m_twidentitymacosxDs, a_dg, DAT.IMAGEMEMXFER, a_msg, ref twimagememxfermacosx); } else { sts = (STS)NativeMethods.MacosxTwaindsmDsmEntryImagememxfer(ref m_twidentitymacosxApp, ref m_twidentitymacosxDs, a_dg, DAT.IMAGEMEMXFER, a_msg, ref twimagememxfermacosx); } a_twimagememxfer.BytesPerRow = twimagememxfermacosx.BytesPerRow; a_twimagememxfer.BytesWritten = twimagememxfermacosx.BytesWritten; a_twimagememxfer.Columns = twimagememxfermacosx.Columns; a_twimagememxfer.Compression = (ushort)twimagememxfermacosx.Compression; a_twimagememxfer.Memory.Flags = twimagememxfermacosx.Memory.Flags; a_twimagememxfer.Memory.Length = twimagememxfermacosx.Memory.Length; a_twimagememxfer.Memory.TheMem = twimagememxfermacosx.Memory.TheMem; a_twimagememxfer.Rows = twimagememxfermacosx.Rows; a_twimagememxfer.XOffset = twimagememxfermacosx.XOffset; a_twimagememxfer.YOffset = twimagememxfermacosx.YOffset; } catch (Exception exception) { // The driver crashed... Log.Error("crash - " + exception.Message); Log.LogSendAfter(STS.BUMMER, ""); return (STS.BUMMER); } } // Uh-oh... else { Log.LogSendAfter(STS.BUMMER, ""); return (STS.BUMMER); } // Get DAT_STATUS, if needed... TWAIN.STS stsRcOrCc = AutoDatStatus(sts); // Log it... if (Log.GetLevel() > 0) { Log.LogSendAfter(stsRcOrCc, ImagememxferToCsv(a_twimagememxfer)); } // If we had a successful transfer, then change state... if (sts == STS.XFERDONE) { m_state = STATE.S7; } // All done... return (stsRcOrCc); } /// /// Issue native image transfer commands... /// /// Data group /// Operation /// BITMAP structure /// TWAIN status private void DatImagenativexferWindowsTwain32() { // If you get a first chance exception, be aware that some drivers // will do that to you, you can ignore it and they'll keep going... m_threaddataDatImagenativexfer.sts = (STS)NativeMethods.WindowsTwain32DsmEntryImagenativexfer ( ref m_twidentitylegacyApp, ref m_twidentitylegacyDs, m_threaddataDatImagenativexfer.dg, m_threaddataDatImagenativexfer.dat, m_threaddataDatImagenativexfer.msg, ref m_threaddataDatImagenativexfer.intptrBitmap ); } private void DatImagenativexferWindowsTwainDsm() { // If you get a first chance exception, be aware that some drivers // will do that to you, you can ignore it and they'll keep going... m_threaddataDatImagenativexfer.sts = (STS)NativeMethods.WindowsTwaindsmDsmEntryImagenativexfer ( ref m_twidentitylegacyApp, ref m_twidentitylegacyDs, m_threaddataDatImagenativexfer.dg, m_threaddataDatImagenativexfer.dat, m_threaddataDatImagenativexfer.msg, ref m_threaddataDatImagenativexfer.intptrBitmap ); } [PermissionSet(SecurityAction.LinkDemand, Name = "FullTrust", Unrestricted = false)] public STS DatImagenativexfer(DG a_dg, MSG a_msg, ref Bitmap a_bitmap) { IntPtr intptrBitmapHandle = IntPtr.Zero; return (DatImagenativexferBitmap(a_dg, a_msg, ref a_bitmap, ref intptrBitmapHandle, false)); } [PermissionSet(SecurityAction.LinkDemand, Name = "FullTrust", Unrestricted = false)] public STS DatImagenativexferHandle(DG a_dg, MSG a_msg, ref IntPtr a_intptrBitmapHandle) { Bitmap bitmap = null; return (DatImagenativexferBitmap(a_dg, a_msg, ref bitmap, ref a_intptrBitmapHandle, true)); } [PermissionSet(SecurityAction.LinkDemand, Name = "FullTrust", Unrestricted = false)] public STS DatImagenativexferBitmap(DG a_dg, MSG a_msg, ref Bitmap a_bitmap, ref IntPtr a_intptrBitmapHandle, bool a_blUseBitmapHandle) { STS sts; IntPtr intptrBitmap = IntPtr.Zero; // Submit the work to the TWAIN thread... if (this.m_runinuithreaddelegate == null) { if ((m_threadTwain != null) && (m_threadTwain.ManagedThreadId != Thread.CurrentThread.ManagedThreadId)) { lock (m_lockTwain) { // Set our command variables... ThreadData threaddata = default(ThreadData); threaddata.bitmap = a_bitmap; threaddata.blUseBitmapHandle = a_blUseBitmapHandle; threaddata.dg = a_dg; threaddata.msg = a_msg; threaddata.dat = DAT.IMAGENATIVEXFER; long lIndex = m_twaincommand.Submit(threaddata); // Submit the command and wait for the reply... CallerToThreadSet(); ThreadToCallerWaitOne(); // Return the result... a_bitmap = m_twaincommand.Get(lIndex).bitmap; a_intptrBitmapHandle = m_twaincommand.Get(lIndex).intptrBitmap; sts = m_twaincommand.Get(lIndex).sts; // Clear the command variables... m_twaincommand.Delete(lIndex); } return (sts); } } // Log it... if (Log.GetLevel() > 0) { Log.LogSendBefore(a_dg.ToString(), DAT.IMAGENATIVEXFER.ToString(), a_msg.ToString(), ""); } // Windows... if (ms_platform == Platform.WINDOWS) { // Issue the command... try { if (m_threaddataDatImagenativexfer.blIsInuse || (this.m_runinuithreaddelegate == null)) { if (m_blUseLegacyDSM) { sts = (STS)NativeMethods.WindowsTwain32DsmEntryImagenativexfer(ref m_twidentitylegacyApp, ref m_twidentitylegacyDs, a_dg, DAT.IMAGENATIVEXFER, a_msg, ref intptrBitmap); } else { sts = (STS)NativeMethods.WindowsTwaindsmDsmEntryImagenativexfer(ref m_twidentitylegacyApp, ref m_twidentitylegacyDs, a_dg, DAT.IMAGENATIVEXFER, a_msg, ref intptrBitmap); } } else { if (m_blUseLegacyDSM) { lock (m_lockTwain) { m_threaddataDatImagenativexfer = default(ThreadData); m_threaddataDatImagenativexfer.blIsInuse = true; m_threaddataDatImagenativexfer.dg = a_dg; m_threaddataDatImagenativexfer.msg = a_msg; m_threaddataDatImagenativexfer.dat = DAT.IMAGENATIVEXFER; RunInUiThread(DatImagenativexferWindowsTwain32); intptrBitmap = a_intptrBitmapHandle = m_threaddataDatImagenativexfer.intptrBitmap; sts = m_threaddataDatImagenativexfer.sts; m_threaddataDatImagenativexfer = default(ThreadData); } } else { lock (m_lockTwain) { m_threaddataDatImagenativexfer = default(ThreadData); m_threaddataDatImagenativexfer.blIsInuse = true; m_threaddataDatImagenativexfer.dg = a_dg; m_threaddataDatImagenativexfer.msg = a_msg; m_threaddataDatImagenativexfer.dat = DAT.IMAGENATIVEXFER; RunInUiThread(DatImagenativexferWindowsTwainDsm); intptrBitmap = a_intptrBitmapHandle = m_threaddataDatImagenativexfer.intptrBitmap; sts = m_threaddataDatImagenativexfer.sts; m_threaddataDatImagenativexfer = default(ThreadData); } } } } catch (Exception exception) { // The driver crashed... Log.Error("crash - " + exception.Message); Log.LogSendAfter(STS.BUMMER, ""); return (STS.BUMMER); } } // Linux... else if (ms_platform == Platform.LINUX) { // Issue the command... try { if (m_blFoundLatestDsm64 && (m_linuxdsm == LinuxDsm.IsLatestDsm)) { sts = (STS)NativeMethods.Linux64DsmEntryImagenativexfer(ref m_twidentitylegacyApp, ref m_twidentitylegacyDs, a_dg, DAT.IMAGENATIVEXFER, a_msg, ref intptrBitmap); } else if (m_blFoundLatestDsm && (m_linuxdsm == LinuxDsm.IsLatestDsm)) { sts = (STS)NativeMethods.LinuxDsmEntryImagenativexfer(ref m_twidentitylegacyApp, ref m_twidentitylegacyDs, a_dg, DAT.IMAGENATIVEXFER, a_msg, ref intptrBitmap); } else if (m_blFound020302Dsm64bit && (m_linuxdsm == LinuxDsm.Is020302Dsm64bit)) { sts = (STS)NativeMethods.Linux020302Dsm64bitEntryImagenativexfer(ref m_twidentityApp, ref m_twidentityDs, a_dg, DAT.IMAGENATIVEXFER, a_msg, ref intptrBitmap); } else { Log.Error("apparently we don't have a DSM..."); sts = STS.BUMMER; } } catch (Exception exception) { // The driver crashed... Log.Error("crash - " + exception.Message); Log.LogSendAfter(STS.BUMMER, ""); return (STS.BUMMER); } } // Mac OS X, which has to be different... else if (ms_platform == Platform.MACOSX) { // Issue the command... try { intptrBitmap = IntPtr.Zero; if (m_blUseLegacyDSM) { sts = (STS)NativeMethods.MacosxTwainDsmEntryImagenativexfer(ref m_twidentitymacosxApp, ref m_twidentitymacosxDs, a_dg, DAT.IMAGENATIVEXFER, a_msg, ref intptrBitmap); } else { sts = (STS)NativeMethods.MacosxTwaindsmDsmEntryImagenativexfer(ref m_twidentitymacosxApp, ref m_twidentitymacosxDs, a_dg, DAT.IMAGENATIVEXFER, a_msg, ref intptrBitmap); } } catch (Exception exception) { // The driver crashed... Log.Error("crash - " + exception.Message); Log.LogSendAfter(STS.BUMMER, ""); return (STS.BUMMER); } } // Uh-oh... else { Log.LogSendAfter(STS.BUMMER, ""); return (STS.BUMMER); } // Get DAT_STATUS, if needed... TWAIN.STS stsRcOrCc = AutoDatStatus(sts); // Log it... if (Log.GetLevel() > 0) { Log.LogSendAfter(stsRcOrCc, ""); } // If we had a successful transfer, then convert the data... if (sts == STS.XFERDONE) { if (a_blUseBitmapHandle) { a_intptrBitmapHandle = intptrBitmap; } else { // Bump our state... m_state = STATE.S7; // Turn the DIB into a Bitmap object... a_bitmap = NativeToBitmap(ms_platform, intptrBitmap); // We're done with the data we got from the driver... Marshal.FreeHGlobal(intptrBitmap); intptrBitmap = IntPtr.Zero; } } // All done... return (stsRcOrCc); } /// /// Get/Set JPEG compression tables... /// /// Data group /// Operation /// JPEGCOMPRESSION structure /// TWAIN status public STS DatJpegcompression(DG a_dg, MSG a_msg, ref TW_JPEGCOMPRESSION a_twjpegcompression) { STS sts; // Submit the work to the TWAIN thread... if ((m_threadTwain != null) && (m_threadTwain.ManagedThreadId != Thread.CurrentThread.ManagedThreadId)) { lock (m_lockTwain) { // Set our command variables... ThreadData threaddata = default(ThreadData); threaddata.twjpegcompression = a_twjpegcompression; threaddata.dg = a_dg; threaddata.msg = a_msg; threaddata.dat = DAT.JPEGCOMPRESSION; long lIndex = m_twaincommand.Submit(threaddata); // Submit the command and wait for the reply... CallerToThreadSet(); ThreadToCallerWaitOne(); // Return the result... a_twjpegcompression = m_twaincommand.Get(lIndex).twjpegcompression; sts = m_twaincommand.Get(lIndex).sts; // Clear the command variables... m_twaincommand.Delete(lIndex); } return (sts); } // Log it... if (Log.GetLevel() > 0) { Log.LogSendBefore(a_dg.ToString(), DAT.JPEGCOMPRESSION.ToString(), a_msg.ToString(), ""); } // Windows... if (ms_platform == Platform.WINDOWS) { // Issue the command... try { if (m_blUseLegacyDSM) { sts = (STS)NativeMethods.WindowsTwain32DsmEntryJpegcompression(ref m_twidentitylegacyApp, ref m_twidentitylegacyDs, a_dg, DAT.JPEGCOMPRESSION, a_msg, ref a_twjpegcompression); } else { sts = (STS)NativeMethods.WindowsTwaindsmDsmEntryJpegcompression(ref m_twidentitylegacyApp, ref m_twidentitylegacyDs, a_dg, DAT.JPEGCOMPRESSION, a_msg, ref a_twjpegcompression); } } catch (Exception exception) { // The driver crashed... Log.Error("crash - " + exception.Message); Log.LogSendAfter(STS.BUMMER, ""); return (STS.BUMMER); } } // Linux... else if (ms_platform == Platform.LINUX) { // Issue the command... try { if (m_blFoundLatestDsm64 && (m_linuxdsm == LinuxDsm.IsLatestDsm)) { sts = (STS)NativeMethods.Linux64DsmEntryJpegcompression(ref m_twidentitylegacyApp, ref m_twidentitylegacyDs, a_dg, DAT.JPEGCOMPRESSION, a_msg, ref a_twjpegcompression); } else if (m_blFoundLatestDsm && (m_linuxdsm == LinuxDsm.IsLatestDsm)) { sts = (STS)NativeMethods.LinuxDsmEntryJpegcompression(ref m_twidentitylegacyApp, ref m_twidentitylegacyDs, a_dg, DAT.JPEGCOMPRESSION, a_msg, ref a_twjpegcompression); } else if (m_blFound020302Dsm64bit && (m_linuxdsm == LinuxDsm.Is020302Dsm64bit)) { sts = (STS)NativeMethods.Linux020302Dsm64bitEntryJpegcompression(ref m_twidentityApp, ref m_twidentityDs, a_dg, DAT.JPEGCOMPRESSION, a_msg, ref a_twjpegcompression); } else { Log.Error("apparently we don't have a DSM..."); sts = STS.BUMMER; } } catch (Exception exception) { // The driver crashed... Log.Error("crash - " + exception.Message); Log.LogSendAfter(STS.BUMMER, ""); return (STS.BUMMER); } } // Mac OS X, which has to be different... else if (ms_platform == Platform.MACOSX) { // Issue the command... try { if (m_blUseLegacyDSM) { sts = (STS)NativeMethods.MacosxTwainDsmEntryJpegcompression(ref m_twidentitymacosxApp, ref m_twidentitymacosxDs, a_dg, DAT.JPEGCOMPRESSION, a_msg, ref a_twjpegcompression); } else { sts = (STS)NativeMethods.MacosxTwaindsmDsmEntryJpegcompression(ref m_twidentitymacosxApp, ref m_twidentitymacosxDs, a_dg, DAT.JPEGCOMPRESSION, a_msg, ref a_twjpegcompression); } } catch (Exception exception) { // The driver crashed... Log.Error("crash - " + exception.Message); Log.LogSendAfter(STS.BUMMER, ""); return (STS.BUMMER); } } // Uh-oh... else { Log.LogSendAfter(STS.BUMMER, ""); return (STS.BUMMER); } // Get DAT_STATUS, if needed... TWAIN.STS stsRcOrCc = AutoDatStatus(sts); // Log it... if (Log.GetLevel() > 0) { Log.LogSendAfter(stsRcOrCc, ""); } // All done... return (stsRcOrCc); } /// /// Get/Set metrics... /// /// Data group /// Operation /// JPEGCOMPRESSION structure /// TWAIN status public STS DatMetrics(DG a_dg, MSG a_msg, ref TW_METRICS a_twmetrics) { STS sts; // Submit the work to the TWAIN thread... if ((m_threadTwain != null) && (m_threadTwain.ManagedThreadId != Thread.CurrentThread.ManagedThreadId)) { lock (m_lockTwain) { // Set our command variables... ThreadData threaddata = default(ThreadData); threaddata.twmetrics = a_twmetrics; threaddata.dg = a_dg; threaddata.msg = a_msg; threaddata.dat = DAT.METRICS; long lIndex = m_twaincommand.Submit(threaddata); // Submit the command and wait for the reply... CallerToThreadSet(); ThreadToCallerWaitOne(); // Return the result... a_twmetrics = m_twaincommand.Get(lIndex).twmetrics; sts = m_twaincommand.Get(lIndex).sts; // Clear the command variables... m_twaincommand.Delete(lIndex); } return (sts); } // Log it... if (Log.GetLevel() > 0) { Log.LogSendBefore(a_dg.ToString(), DAT.METRICS.ToString(), a_msg.ToString(), ""); } // Windows... if (ms_platform == Platform.WINDOWS) { // Issue the command... try { if (m_blUseLegacyDSM) { sts = (STS)NativeMethods.WindowsTwain32DsmEntryMetrics(ref m_twidentitylegacyApp, ref m_twidentitylegacyDs, a_dg, DAT.METRICS, a_msg, ref a_twmetrics); } else { sts = (STS)NativeMethods.WindowsTwaindsmDsmEntryMetrics(ref m_twidentitylegacyApp, ref m_twidentitylegacyDs, a_dg, DAT.METRICS, a_msg, ref a_twmetrics); } } catch (Exception exception) { // The driver crashed... Log.Error("crash - " + exception.Message); Log.LogSendAfter(STS.BUMMER, ""); return (STS.BUMMER); } } // Linux... else if (ms_platform == Platform.LINUX) { // Issue the command... try { if (m_blFoundLatestDsm64 && (m_linuxdsm == LinuxDsm.IsLatestDsm)) { sts = (STS)NativeMethods.Linux64DsmEntryMetrics(ref m_twidentitylegacyApp, ref m_twidentitylegacyDs, a_dg, DAT.METRICS, a_msg, ref a_twmetrics); } else if (m_blFoundLatestDsm && (m_linuxdsm == LinuxDsm.IsLatestDsm)) { sts = (STS)NativeMethods.LinuxDsmEntryMetrics(ref m_twidentitylegacyApp, ref m_twidentitylegacyDs, a_dg, DAT.METRICS, a_msg, ref a_twmetrics); } else if (m_blFound020302Dsm64bit && (m_linuxdsm == LinuxDsm.Is020302Dsm64bit)) { sts = (STS)NativeMethods.Linux020302Dsm64bitEntryMetrics(ref m_twidentityApp, ref m_twidentityDs, a_dg, DAT.METRICS, a_msg, ref a_twmetrics); } else { Log.Error("apparently we don't have a DSM..."); sts = STS.BUMMER; } } catch (Exception exception) { // The driver crashed... Log.Error("crash - " + exception.Message); Log.LogSendAfter(STS.BUMMER, ""); return (STS.BUMMER); } } // Mac OS X, which has to be different... else if (ms_platform == Platform.MACOSX) { // Issue the command... try { if (m_blUseLegacyDSM) { sts = (STS)NativeMethods.MacosxTwainDsmEntryMetrics(ref m_twidentitymacosxApp, ref m_twidentitymacosxDs, a_dg, DAT.METRICS, a_msg, ref a_twmetrics); } else { sts = (STS)NativeMethods.MacosxTwaindsmDsmEntryMetrics(ref m_twidentitymacosxApp, ref m_twidentitymacosxDs, a_dg, DAT.METRICS, a_msg, ref a_twmetrics); } } catch (Exception exception) { // The driver crashed... Log.Error("crash - " + exception.Message); Log.LogSendAfter(STS.BUMMER, ""); return (STS.BUMMER); } } // Uh-oh... else { Log.LogSendAfter(STS.BUMMER, ""); return (STS.BUMMER); } // Get DAT_STATUS, if needed... TWAIN.STS stsRcOrCc = AutoDatStatus(sts); // Log it... if (Log.GetLevel() > 0) { Log.LogSendAfter(stsRcOrCc, ""); } // All done... return (stsRcOrCc); } /// /// Get/Set for a Pallete8... /// /// Data group /// Operation /// PALETTE8 structure /// TWAIN status public STS DatPalette8(DG a_dg, MSG a_msg, ref TW_PALETTE8 a_twpalette8) { STS sts; // Submit the work to the TWAIN thread... if ((m_threadTwain != null) && (m_threadTwain.ManagedThreadId != Thread.CurrentThread.ManagedThreadId)) { lock (m_lockTwain) { // Set our command variables... ThreadData threaddata = default(ThreadData); threaddata.twpalette8 = a_twpalette8; threaddata.dg = a_dg; threaddata.msg = a_msg; threaddata.dat = DAT.PALETTE8; long lIndex = m_twaincommand.Submit(threaddata); // Submit the command and wait for the reply... CallerToThreadSet(); ThreadToCallerWaitOne(); // Return the result... a_twpalette8 = m_twaincommand.Get(lIndex).twpalette8; sts = m_twaincommand.Get(lIndex).sts; // Clear the command variables... m_twaincommand.Delete(lIndex); } return (sts); } // Log it... if (Log.GetLevel() > 0) { Log.LogSendBefore(a_dg.ToString(), DAT.PALETTE8.ToString(), a_msg.ToString(), ""); } // Windows... if (ms_platform == Platform.WINDOWS) { // Issue the command... try { if (m_blUseLegacyDSM) { sts = (STS)NativeMethods.WindowsTwain32DsmEntryPalette8(ref m_twidentitylegacyApp, ref m_twidentitylegacyDs, a_dg, DAT.PALETTE8, a_msg, ref a_twpalette8); } else { sts = (STS)NativeMethods.WindowsTwaindsmDsmEntryPalette8(ref m_twidentitylegacyApp, ref m_twidentitylegacyDs, a_dg, DAT.PALETTE8, a_msg, ref a_twpalette8); } } catch (Exception exception) { // The driver crashed... Log.Error("crash - " + exception.Message); Log.LogSendAfter(STS.BUMMER, ""); return (STS.BUMMER); } } // Linux... else if (ms_platform == Platform.LINUX) { // Issue the command... try { if (m_blFoundLatestDsm64 && (m_linuxdsm == LinuxDsm.IsLatestDsm)) { sts = (STS)NativeMethods.Linux64DsmEntryPalette8(ref m_twidentitylegacyApp, ref m_twidentitylegacyDs, a_dg, DAT.PALETTE8, a_msg, ref a_twpalette8); } else if (m_blFoundLatestDsm && (m_linuxdsm == LinuxDsm.IsLatestDsm)) { sts = (STS)NativeMethods.LinuxDsmEntryPalette8(ref m_twidentitylegacyApp, ref m_twidentitylegacyDs, a_dg, DAT.PALETTE8, a_msg, ref a_twpalette8); } else if (m_blFound020302Dsm64bit && (m_linuxdsm == LinuxDsm.Is020302Dsm64bit)) { sts = (STS)NativeMethods.Linux020302Dsm64bitEntryPalette8(ref m_twidentityApp, ref m_twidentityDs, a_dg, DAT.PALETTE8, a_msg, ref a_twpalette8); } else { Log.Error("apparently we don't have a DSM..."); sts = STS.BUMMER; } } catch (Exception exception) { // The driver crashed... Log.Error("crash - " + exception.Message); Log.LogSendAfter(STS.BUMMER, ""); return (STS.BUMMER); } } // Mac OS X, which has to be different... else if (ms_platform == Platform.MACOSX) { // Issue the command... try { if (m_blUseLegacyDSM) { sts = (STS)NativeMethods.MacosxTwainDsmEntryPalette8(ref m_twidentitymacosxApp, ref m_twidentitymacosxDs, a_dg, DAT.PALETTE8, a_msg, ref a_twpalette8); } else { sts = (STS)NativeMethods.MacosxTwaindsmDsmEntryPalette8(ref m_twidentitymacosxApp, ref m_twidentitymacosxDs, a_dg, DAT.PALETTE8, a_msg, ref a_twpalette8); } } catch (Exception exception) { // The driver crashed... Log.Error("crash - " + exception.Message); Log.LogSendAfter(STS.BUMMER, ""); return (STS.BUMMER); } } // Uh-oh... else { Log.LogSendAfter(STS.BUMMER, ""); return (STS.BUMMER); } // Get DAT_STATUS, if needed... TWAIN.STS stsRcOrCc = AutoDatStatus(sts); // Log it... if (Log.GetLevel() > 0) { Log.LogSendAfter(stsRcOrCc, ""); } // All done... return (stsRcOrCc); } /// /// Issue DSM commands... /// /// Data group /// Operation /// PARENT structure /// TWAIN status private void DatParentWindowsTwain32() { // If you get a first chance exception, be aware that some drivers // will do that to you, you can ignore it and they'll keep going... m_threaddataDatParent.sts = (STS)NativeMethods.WindowsTwain32DsmEntryParent ( ref m_twidentitylegacyApp, IntPtr.Zero, m_threaddataDatParent.dg, m_threaddataDatParent.dat, m_threaddataDatParent.msg, ref m_threaddataDatParent.intptrHwnd ); } private void DatParentWindowsTwainDsm() { // If you get a first chance exception, be aware that some drivers // will do that to you, you can ignore it and they'll keep going... m_threaddataDatParent.sts = (STS)NativeMethods.WindowsTwaindsmDsmEntryParent ( ref m_twidentitylegacyApp, IntPtr.Zero, m_threaddataDatParent.dg, m_threaddataDatParent.dat, m_threaddataDatParent.msg, ref m_threaddataDatParent.intptrHwnd ); } [PermissionSet(SecurityAction.LinkDemand, Name = "FullTrust", Unrestricted = false)] public STS DatParent(DG a_dg, MSG a_msg, ref IntPtr a_intptrHwnd) { STS sts; // Submit the work to the TWAIN thread... if (m_runinuithreaddelegate == null) { if ((m_threadTwain != null) && (m_threadTwain.ManagedThreadId != Thread.CurrentThread.ManagedThreadId)) { lock (m_lockTwain) { // Set our command variables... ThreadData threaddata = default(ThreadData); threaddata.intptrHwnd = a_intptrHwnd; threaddata.dg = a_dg; threaddata.msg = a_msg; threaddata.dat = DAT.PARENT; long lIndex = m_twaincommand.Submit(threaddata); // Submit the command and wait for the reply... CallerToThreadSet(); ThreadToCallerWaitOne(); // Return the result... a_intptrHwnd = m_twaincommand.Get(lIndex).intptrHwnd; sts = m_twaincommand.Get(lIndex).sts; // Clear the command variables... m_twaincommand.Delete(lIndex); } return (sts); } } // Log it... if (Log.GetLevel() > 0) { Log.LogSendBefore(a_dg.ToString(), DAT.PARENT.ToString(), a_msg.ToString(), ""); } // Windows... if (ms_platform == Platform.WINDOWS) { // Issue the command... try { if (m_threaddataDatParent.blIsInuse || (this.m_runinuithreaddelegate == null)) { if (m_blUseLegacyDSM) { sts = (STS)NativeMethods.WindowsTwain32DsmEntryParent(ref m_twidentitylegacyApp, IntPtr.Zero, a_dg, DAT.PARENT, a_msg, ref a_intptrHwnd); } else { sts = (STS)NativeMethods.WindowsTwaindsmDsmEntryParent(ref m_twidentitylegacyApp, IntPtr.Zero, a_dg, DAT.PARENT, a_msg, ref a_intptrHwnd); } } else { if (m_blUseLegacyDSM) { lock (m_lockTwain) { m_threaddataDatParent = default(ThreadData); m_threaddataDatParent.blIsInuse = true; m_threaddataDatParent.dg = a_dg; m_threaddataDatParent.msg = a_msg; m_threaddataDatParent.dat = DAT.PARENT; m_threaddataDatParent.intptrHwnd = a_intptrHwnd; RunInUiThread(DatParentWindowsTwain32); sts = m_threaddataDatParent.sts; m_threaddataDatParent = default(ThreadData); } } else { lock (m_lockTwain) { m_threaddataDatParent = default(ThreadData); m_threaddataDatParent.blIsInuse = true; m_threaddataDatParent.dg = a_dg; m_threaddataDatParent.msg = a_msg; m_threaddataDatParent.dat = DAT.PARENT; m_threaddataDatParent.intptrHwnd = a_intptrHwnd; RunInUiThread(DatParentWindowsTwainDsm); sts = m_threaddataDatParent.sts; m_threaddataDatParent = default(ThreadData); } } } // Needed for the DF_DSM2 flag... m_twidentityApp.SupportedGroups = m_twidentitylegacyApp.SupportedGroups; } catch (Exception exception) { // The driver crashed... Log.Error("crash - " + exception.Message); Log.LogSendAfter(STS.BUMMER, ""); return (STS.BUMMER); } } // Linux... else if (ms_platform == Platform.LINUX) { STS stsLatest = STS.BUMMER; STS sts020302Dsm64bit = STS.BUMMER; // We're trying both DSM's... sts = STS.BUMMER; // Load the new DSM, whatever it is, if we found one... if (m_blFoundLatestDsm64) { try { stsLatest = (STS)NativeMethods.Linux64DsmEntryParent(ref m_twidentitylegacyApp, IntPtr.Zero, a_dg, DAT.PARENT, a_msg, ref a_intptrHwnd); // Needed for the DF_DSM2 flag... m_twidentityApp.SupportedGroups = m_twidentitylegacyApp.SupportedGroups; } catch { // Forget this... m_blFoundLatestDsm64 = false; } } // Load the new DSM, whatever it is, if we found one... if (m_blFoundLatestDsm) { try { stsLatest = (STS)NativeMethods.LinuxDsmEntryParent(ref m_twidentitylegacyApp, IntPtr.Zero, a_dg, DAT.PARENT, a_msg, ref a_intptrHwnd); // Needed for the DF_DSM2 flag... m_twidentityApp.SupportedGroups = m_twidentitylegacyApp.SupportedGroups; } catch { // Forget this... m_blFoundLatestDsm = false; } } // Load libtwaindsm.so.2.3.2, if we found it... if (m_blFound020302Dsm64bit) { try { sts020302Dsm64bit = (STS)NativeMethods.Linux020302Dsm64bitEntryParent(ref m_twidentityApp, IntPtr.Zero, a_dg, DAT.PARENT, a_msg, ref a_intptrHwnd); } catch { // Forget this... m_blFound020302Dsm64bit = false; } } // We only need one success to get through this... sts = STS.BUMMER; if ((stsLatest == STS.SUCCESS) || (sts020302Dsm64bit == STS.SUCCESS)) { sts = STS.SUCCESS; } } // Mac OS X, which has to be different... else if (ms_platform == Platform.MACOSX) { // Issue the command... try { if (m_blUseLegacyDSM) { sts = (STS)NativeMethods.MacosxTwainDsmEntryParent(ref m_twidentitymacosxApp, IntPtr.Zero, a_dg, DAT.PARENT, a_msg, ref a_intptrHwnd); } else { sts = (STS)NativeMethods.MacosxTwaindsmDsmEntryParent(ref m_twidentitymacosxApp, IntPtr.Zero, a_dg, DAT.PARENT, a_msg, ref a_intptrHwnd); } // Needed for the DF_DSM2 flag... m_twidentityApp.SupportedGroups = m_twidentitymacosxApp.SupportedGroups; } catch (Exception exception) { // The driver crashed... Log.Error("crash - " + exception.Message); Log.LogSendAfter(STS.BUMMER, ""); return (STS.BUMMER); } } // Uh-oh... else { Log.LogSendAfter(STS.BUMMER, ""); return (STS.BUMMER); } // Get DAT_STATUS, if needed... TWAIN.STS stsRcOrCc = AutoDatStatus(sts); // Log it... if (Log.GetLevel() > 0) { Log.LogSendAfter(stsRcOrCc, ""); } // If we opened, go to state 3, and start tracking // TWAIN's state in the log file... if (a_msg == MSG.OPENDSM) { if (sts == STS.SUCCESS) { m_state = STATE.S3; Log.RegisterTwain(this); } } // If we closed, go to state 2, and stop tracking // TWAIN's state in the log file... else if (a_msg == MSG.CLOSEDSM) { if (sts == STS.SUCCESS) { m_state = STATE.S2; Log.RegisterTwain(null); } } // All done... return (stsRcOrCc); } /// /// Get/Set for a raw commands... /// /// Data group /// Operation /// PASSTHRU structure /// TWAIN status public STS DatPassthru(DG a_dg, MSG a_msg, ref TW_PASSTHRU a_twpassthru) { STS sts; // Submit the work to the TWAIN thread... if ((m_threadTwain != null) && (m_threadTwain.ManagedThreadId != Thread.CurrentThread.ManagedThreadId)) { lock (m_lockTwain) { // Set our command variables... ThreadData threaddata = default(ThreadData); threaddata.twpassthru = a_twpassthru; threaddata.dg = a_dg; threaddata.msg = a_msg; threaddata.dat = DAT.PASSTHRU; long lIndex = m_twaincommand.Submit(threaddata); // Submit the command and wait for the reply... CallerToThreadSet(); ThreadToCallerWaitOne(); // Return the result... a_twpassthru = m_twaincommand.Get(lIndex).twpassthru; sts = m_twaincommand.Get(lIndex).sts; // Clear the command variables... m_twaincommand.Delete(lIndex); } return (sts); } // Log it... if (Log.GetLevel() > 0) { Log.LogSendBefore(a_dg.ToString(), DAT.PASSTHRU.ToString(), a_msg.ToString(), ""); } // Windows... if (ms_platform == Platform.WINDOWS) { // Issue the command... try { if (m_blUseLegacyDSM) { sts = (STS)NativeMethods.WindowsTwain32DsmEntryPassthru(ref m_twidentitylegacyApp, ref m_twidentitylegacyDs, a_dg, DAT.PASSTHRU, a_msg, ref a_twpassthru); } else { sts = (STS)NativeMethods.WindowsTwaindsmDsmEntryPassthru(ref m_twidentitylegacyApp, ref m_twidentitylegacyDs, a_dg, DAT.PASSTHRU, a_msg, ref a_twpassthru); } } catch (Exception exception) { // The driver crashed... Log.Error("crash - " + exception.Message); Log.LogSendAfter(STS.BUMMER, ""); return (STS.BUMMER); } } // Linux... else if (ms_platform == Platform.LINUX) { // Issue the command... try { if (m_blFoundLatestDsm64 && (m_linuxdsm == LinuxDsm.IsLatestDsm)) { sts = (STS)NativeMethods.Linux64DsmEntryPassthru(ref m_twidentitylegacyApp, ref m_twidentitylegacyDs, a_dg, DAT.PASSTHRU, a_msg, ref a_twpassthru); } else if (m_blFoundLatestDsm && (m_linuxdsm == LinuxDsm.IsLatestDsm)) { sts = (STS)NativeMethods.LinuxDsmEntryPassthru(ref m_twidentitylegacyApp, ref m_twidentitylegacyDs, a_dg, DAT.PASSTHRU, a_msg, ref a_twpassthru); } else if (m_blFound020302Dsm64bit && (m_linuxdsm == LinuxDsm.Is020302Dsm64bit)) { sts = (STS)NativeMethods.Linux020302Dsm64bitEntryPassthru(ref m_twidentityApp, ref m_twidentityDs, a_dg, DAT.PASSTHRU, a_msg, ref a_twpassthru); } else { Log.Error("apparently we don't have a DSM..."); sts = STS.BUMMER; } } catch (Exception exception) { // The driver crashed... Log.Error("crash - " + exception.Message); Log.LogSendAfter(STS.BUMMER, ""); return (STS.BUMMER); } } // Mac OS X, which has to be different... else if (ms_platform == Platform.MACOSX) { // Issue the command... try { if (m_blUseLegacyDSM) { sts = (STS)NativeMethods.MacosxTwainDsmEntryPassthru(ref m_twidentitymacosxApp, ref m_twidentitymacosxDs, a_dg, DAT.PASSTHRU, a_msg, ref a_twpassthru); } else { sts = (STS)NativeMethods.MacosxTwaindsmDsmEntryPassthru(ref m_twidentitymacosxApp, ref m_twidentitymacosxDs, a_dg, DAT.PASSTHRU, a_msg, ref a_twpassthru); } } catch (Exception exception) { // The driver crashed... Log.Error("crash - " + exception.Message); Log.LogSendAfter(STS.BUMMER, ""); return (STS.BUMMER); } } // Uh-oh... else { Log.LogSendAfter(STS.BUMMER, ""); return (STS.BUMMER); } // Get DAT_STATUS, if needed... TWAIN.STS stsRcOrCc = AutoDatStatus(sts); // Log it... if (Log.GetLevel() > 0) { Log.LogSendAfter(stsRcOrCc, ""); } // All done... return (stsRcOrCc); } /// /// Issue pendingxfers commands... /// /// Data group /// Operation /// PENDINGXFERS structure /// TWAIN status private void DatPendingxfersWindowsTwain32() { // If you get a first chance exception, be aware that some drivers // will do that to you, you can ignore it and they'll keep going... m_threaddataDatPendingxfers.sts = (STS)NativeMethods.WindowsTwain32DsmEntryPendingxfers ( ref m_twidentitylegacyApp, ref m_twidentitylegacyDs, m_threaddataDatPendingxfers.dg, m_threaddataDatPendingxfers.dat, m_threaddataDatPendingxfers.msg, ref m_threaddataDatPendingxfers.twpendingxfers ); } private void DatPendingxfersWindowsTwainDsm() { // If you get a first chance exception, be aware that some drivers // will do that to you, you can ignore it and they'll keep going... m_threaddataDatPendingxfers.sts = (STS)NativeMethods.WindowsTwaindsmDsmEntryPendingxfers ( ref m_twidentitylegacyApp, ref m_twidentitylegacyDs, m_threaddataDatPendingxfers.dg, m_threaddataDatPendingxfers.dat, m_threaddataDatPendingxfers.msg, ref m_threaddataDatPendingxfers.twpendingxfers ); } public STS DatPendingxfers(DG a_dg, MSG a_msg, ref TW_PENDINGXFERS a_twpendingxfers) { STS sts; // Submit the work to the TWAIN thread... if (m_runinuithreaddelegate == null) { if ((m_threadTwain != null) && (m_threadTwain.ManagedThreadId != Thread.CurrentThread.ManagedThreadId)) { lock (m_lockTwain) { // Set our command variables... ThreadData threaddata = default(ThreadData); threaddata.twpendingxfers = a_twpendingxfers; threaddata.dg = a_dg; threaddata.msg = a_msg; threaddata.dat = DAT.PENDINGXFERS; long lIndex = m_twaincommand.Submit(threaddata); // Submit the command and wait for the reply... CallerToThreadSet(); ThreadToCallerWaitOne(); // Return the result... a_twpendingxfers = m_twaincommand.Get(lIndex).twpendingxfers; sts = m_twaincommand.Get(lIndex).sts; // Clear the command variables... m_twaincommand.Delete(lIndex); } return (sts); } } // Log it... if (Log.GetLevel() > 0) { Log.LogSendBefore(a_dg.ToString(), DAT.PENDINGXFERS.ToString(), a_msg.ToString(), ""); } // Windows... if (ms_platform == Platform.WINDOWS) { // Issue the command... try { if (m_threaddataDatPendingxfers.blIsInuse || (this.m_runinuithreaddelegate == null)) { if (m_blUseLegacyDSM) { sts = (STS)NativeMethods.WindowsTwain32DsmEntryPendingxfers(ref m_twidentitylegacyApp, ref m_twidentitylegacyDs, a_dg, DAT.PENDINGXFERS, a_msg, ref a_twpendingxfers); } else { sts = (STS)NativeMethods.WindowsTwaindsmDsmEntryPendingxfers(ref m_twidentitylegacyApp, ref m_twidentitylegacyDs, a_dg, DAT.PENDINGXFERS, a_msg, ref a_twpendingxfers); } } else { if (m_blUseLegacyDSM) { lock (m_lockTwain) { m_threaddataDatPendingxfers = default(ThreadData); m_threaddataDatPendingxfers.blIsInuse = true; m_threaddataDatPendingxfers.dg = a_dg; m_threaddataDatPendingxfers.msg = a_msg; m_threaddataDatPendingxfers.dat = DAT.PENDINGXFERS; m_threaddataDatPendingxfers.twpendingxfers = a_twpendingxfers; RunInUiThread(DatPendingxfersWindowsTwain32); a_twpendingxfers = m_threaddataDatPendingxfers.twpendingxfers; sts = m_threaddataDatPendingxfers.sts; m_threaddataDatPendingxfers = default(ThreadData); } } else { lock (m_lockTwain) { m_threaddataDatPendingxfers = default(ThreadData); m_threaddataDatPendingxfers.blIsInuse = true; m_threaddataDatPendingxfers.dg = a_dg; m_threaddataDatPendingxfers.msg = a_msg; m_threaddataDatPendingxfers.dat = DAT.PENDINGXFERS; m_threaddataDatPendingxfers.twpendingxfers = a_twpendingxfers; RunInUiThread(DatPendingxfersWindowsTwainDsm); a_twpendingxfers = m_threaddataDatPendingxfers.twpendingxfers; sts = m_threaddataDatPendingxfers.sts; m_threaddataDatPendingxfers = default(ThreadData); } } } } catch (Exception exception) { // The driver crashed... Log.Error("crash - " + exception.Message); Log.LogSendAfter(STS.BUMMER, ""); return (STS.BUMMER); } } // Linux... else if (ms_platform == Platform.LINUX) { // Issue the command... try { if (m_blFoundLatestDsm64 && (m_linuxdsm == LinuxDsm.IsLatestDsm)) { sts = (STS)NativeMethods.Linux64DsmEntryPendingxfers(ref m_twidentitylegacyApp, ref m_twidentitylegacyDs, a_dg, DAT.PENDINGXFERS, a_msg, ref a_twpendingxfers); } else if (m_blFoundLatestDsm && (m_linuxdsm == LinuxDsm.IsLatestDsm)) { sts = (STS)NativeMethods.LinuxDsmEntryPendingxfers(ref m_twidentitylegacyApp, ref m_twidentitylegacyDs, a_dg, DAT.PENDINGXFERS, a_msg, ref a_twpendingxfers); } else if (m_blFound020302Dsm64bit && (m_linuxdsm == LinuxDsm.Is020302Dsm64bit)) { sts = (STS)NativeMethods.Linux020302Dsm64bitEntryPendingxfers(ref m_twidentityApp, ref m_twidentityDs, a_dg, DAT.PENDINGXFERS, a_msg, ref a_twpendingxfers); } else { Log.Error("apparently we don't have a DSM..."); sts = STS.BUMMER; } } catch (Exception exception) { // The driver crashed... Log.Error("crash - " + exception.Message); Log.LogSendAfter(STS.BUMMER, ""); return (STS.BUMMER); } } // Mac OS X, which has to be different... else if (ms_platform == Platform.MACOSX) { // Issue the command... try { if (m_blUseLegacyDSM) { sts = (STS)NativeMethods.MacosxTwainDsmEntryPendingxfers(ref m_twidentitymacosxApp, ref m_twidentitymacosxDs, a_dg, DAT.PENDINGXFERS, a_msg, ref a_twpendingxfers); } else { sts = (STS)NativeMethods.MacosxTwaindsmDsmEntryPendingxfers(ref m_twidentitymacosxApp, ref m_twidentitymacosxDs, a_dg, DAT.PENDINGXFERS, a_msg, ref a_twpendingxfers); } } catch (Exception exception) { // The driver crashed... Log.Error("crash - " + exception.Message); Log.LogSendAfter(STS.BUMMER, ""); return (STS.BUMMER); } } // Uh-oh... else { Log.LogSendAfter(STS.BUMMER, ""); return (STS.BUMMER); } // Get DAT_STATUS, if needed... TWAIN.STS stsRcOrCc = AutoDatStatus(sts); // Log it... if (Log.GetLevel() > 0) { Log.LogSendAfter(stsRcOrCc, PendingxfersToCsv(a_twpendingxfers)); } // If we endxfer, go to state 5 or 6... if (a_msg == MSG.ENDXFER) { if (sts == STS.SUCCESS) { if (a_twpendingxfers.Count == 0) { m_blAcceptXferReady = true; m_blIsMsgxferready = false; m_state = STATE.S5; } else { m_state = STATE.S6; } } } // If we reset, go to state 5... else if (a_msg == MSG.RESET) { if (sts == STS.SUCCESS) { m_blAcceptXferReady = true; m_blIsMsgxferready = false; m_state = STATE.S5; } } // All done... return (stsRcOrCc); } /// /// Get/Set for RGB response... /// /// Data group /// Operation /// RGBRESPONSE structure /// TWAIN status public STS DatRgbresponse(DG a_dg, MSG a_msg, ref TW_RGBRESPONSE a_twrgbresponse) { STS sts; // Submit the work to the TWAIN thread... if ((m_threadTwain != null) && (m_threadTwain.ManagedThreadId != Thread.CurrentThread.ManagedThreadId)) { lock (m_lockTwain) { // Set our command variables... ThreadData threaddata = default(ThreadData); threaddata.twrgbresponse = a_twrgbresponse; threaddata.dg = a_dg; threaddata.msg = a_msg; threaddata.dat = DAT.RGBRESPONSE; long lIndex = m_twaincommand.Submit(threaddata); // Submit the command and wait for the reply... CallerToThreadSet(); ThreadToCallerWaitOne(); // Return the result... a_twrgbresponse = m_twaincommand.Get(lIndex).twrgbresponse; sts = m_twaincommand.Get(lIndex).sts; // Clear the command variables... m_twaincommand.Delete(lIndex); } return (sts); } // Log it... if (Log.GetLevel() > 0) { Log.LogSendBefore(a_dg.ToString(), DAT.RGBRESPONSE.ToString(), a_msg.ToString(), ""); } // Windows... if (ms_platform == Platform.WINDOWS) { // Issue the command... try { if (m_blUseLegacyDSM) { sts = (STS)NativeMethods.WindowsTwain32DsmEntryRgbresponse(ref m_twidentitylegacyApp, ref m_twidentitylegacyDs, a_dg, DAT.RGBRESPONSE, a_msg, ref a_twrgbresponse); } else { sts = (STS)NativeMethods.WindowsTwaindsmDsmEntryRgbresponse(ref m_twidentitylegacyApp, ref m_twidentitylegacyDs, a_dg, DAT.RGBRESPONSE, a_msg, ref a_twrgbresponse); } } catch (Exception exception) { // The driver crashed... Log.Error("crash - " + exception.Message); Log.LogSendAfter(STS.BUMMER, ""); return (STS.BUMMER); } } // Linux... else if (ms_platform == Platform.LINUX) { // Issue the command... try { if (m_blFoundLatestDsm64 && (m_linuxdsm == LinuxDsm.IsLatestDsm)) { sts = (STS)NativeMethods.Linux64DsmEntryRgbresponse(ref m_twidentitylegacyApp, ref m_twidentitylegacyDs, a_dg, DAT.RGBRESPONSE, a_msg, ref a_twrgbresponse); } else if (m_blFoundLatestDsm && (m_linuxdsm == LinuxDsm.IsLatestDsm)) { sts = (STS)NativeMethods.LinuxDsmEntryRgbresponse(ref m_twidentitylegacyApp, ref m_twidentitylegacyDs, a_dg, DAT.RGBRESPONSE, a_msg, ref a_twrgbresponse); } else if (m_blFound020302Dsm64bit && (m_linuxdsm == LinuxDsm.Is020302Dsm64bit)) { sts = (STS)NativeMethods.Linux020302Dsm64bitEntryRgbresponse(ref m_twidentityApp, ref m_twidentityDs, a_dg, DAT.RGBRESPONSE, a_msg, ref a_twrgbresponse); } else { Log.Error("apparently we don't have a DSM..."); sts = STS.BUMMER; } } catch (Exception exception) { // The driver crashed... Log.Error("crash - " + exception.Message); Log.LogSendAfter(STS.BUMMER, ""); return (STS.BUMMER); } } // Mac OS X, which has to be different... else if (ms_platform == Platform.MACOSX) { // Issue the command... try { if (m_blUseLegacyDSM) { sts = (STS)NativeMethods.MacosxTwainDsmEntryRgbresponse(ref m_twidentitymacosxApp, ref m_twidentitymacosxDs, a_dg, DAT.RGBRESPONSE, a_msg, ref a_twrgbresponse); } else { sts = (STS)NativeMethods.MacosxTwaindsmDsmEntryRgbresponse(ref m_twidentitymacosxApp, ref m_twidentitymacosxDs, a_dg, DAT.RGBRESPONSE, a_msg, ref a_twrgbresponse); } } catch (Exception exception) { // The driver crashed... Log.Error("crash - " + exception.Message); Log.LogSendAfter(STS.BUMMER, ""); return (STS.BUMMER); } } // Uh-oh... else { Log.LogSendAfter(STS.BUMMER, ""); return (STS.BUMMER); } // Get DAT_STATUS, if needed... TWAIN.STS stsRcOrCc = AutoDatStatus(sts); // Log it... if (Log.GetLevel() > 0) { Log.LogSendAfter(stsRcOrCc, ""); } // All done... return (stsRcOrCc); } /// /// Get/Set for a file xfer... /// /// Data group /// Operation /// SETUPFILEXFER structure /// TWAIN status private void DatSetupfilexferWindowsTwain32() { // If you get a first chance exception, be aware that some drivers // will do that to you, you can ignore it and they'll keep going... m_threaddataDatSetupfilexfer.sts = (STS)NativeMethods.WindowsTwain32DsmEntrySetupfilexfer ( ref m_twidentitylegacyApp, ref m_twidentitylegacyDs, m_threaddataDatSetupfilexfer.dg, m_threaddataDatSetupfilexfer.dat, m_threaddataDatSetupfilexfer.msg, ref m_threaddataDatSetupfilexfer.twsetupfilexfer ); } private void DatSetupfilexferWindowsTwainDsm() { // If you get a first chance exception, be aware that some drivers // will do that to you, you can ignore it and they'll keep going... m_threaddataDatSetupfilexfer.sts = (STS)NativeMethods.WindowsTwaindsmDsmEntrySetupfilexfer ( ref m_twidentitylegacyApp, ref m_twidentitylegacyDs, m_threaddataDatSetupfilexfer.dg, m_threaddataDatSetupfilexfer.dat, m_threaddataDatSetupfilexfer.msg, ref m_threaddataDatSetupfilexfer.twsetupfilexfer ); } public STS DatSetupfilexfer(DG a_dg, MSG a_msg, ref TW_SETUPFILEXFER a_twsetupfilexfer) { STS sts; // Submit the work to the TWAIN thread... if (m_runinuithreaddelegate == null) { if ((m_threadTwain != null) && (m_threadTwain.ManagedThreadId != Thread.CurrentThread.ManagedThreadId)) { lock (m_lockTwain) { // Set our command variables... ThreadData threaddata = default(ThreadData); threaddata.twsetupfilexfer = a_twsetupfilexfer; threaddata.dg = a_dg; threaddata.msg = a_msg; threaddata.dat = DAT.SETUPFILEXFER; long lIndex = m_twaincommand.Submit(threaddata); // Submit the command and wait for the reply... CallerToThreadSet(); ThreadToCallerWaitOne(); // Return the result... a_twsetupfilexfer = m_twaincommand.Get(lIndex).twsetupfilexfer; sts = m_twaincommand.Get(lIndex).sts; // Clear the command variables... m_twaincommand.Delete(lIndex); } return (sts); } } // Log it... if (Log.GetLevel() > 0) { Log.LogSendBefore(a_dg.ToString(), DAT.SETUPFILEXFER.ToString(), a_msg.ToString(), SetupfilexferToCsv(a_twsetupfilexfer)); } // Windows... if (ms_platform == Platform.WINDOWS) { // Issue the command... try { if (m_threaddataDatSetupfilexfer.blIsInuse || (this.m_runinuithreaddelegate == null)) { if (m_blUseLegacyDSM) { sts = (STS)NativeMethods.WindowsTwain32DsmEntrySetupfilexfer(ref m_twidentitylegacyApp, ref m_twidentitylegacyDs, a_dg, DAT.SETUPFILEXFER, a_msg, ref a_twsetupfilexfer); } else { sts = (STS)NativeMethods.WindowsTwaindsmDsmEntrySetupfilexfer(ref m_twidentitylegacyApp, ref m_twidentitylegacyDs, a_dg, DAT.SETUPFILEXFER, a_msg, ref a_twsetupfilexfer); } } else { if (m_blUseLegacyDSM) { lock (m_lockTwain) { m_threaddataDatSetupfilexfer = default(ThreadData); m_threaddataDatSetupfilexfer.blIsInuse = true; m_threaddataDatSetupfilexfer.dg = a_dg; m_threaddataDatSetupfilexfer.msg = a_msg; m_threaddataDatSetupfilexfer.dat = DAT.SETUPFILEXFER; m_threaddataDatSetupfilexfer.twsetupfilexfer = a_twsetupfilexfer; RunInUiThread(DatSetupfilexferWindowsTwain32); a_twsetupfilexfer = m_threaddataDatSetupfilexfer.twsetupfilexfer; sts = m_threaddataDatSetupfilexfer.sts; m_threaddataDatSetupfilexfer = default(ThreadData); } } else { lock (m_lockTwain) { m_threaddataDatSetupfilexfer = default(ThreadData); m_threaddataDatSetupfilexfer.blIsInuse = true; m_threaddataDatSetupfilexfer.dg = a_dg; m_threaddataDatSetupfilexfer.msg = a_msg; m_threaddataDatSetupfilexfer.dat = DAT.SETUPFILEXFER; m_threaddataDatSetupfilexfer.twsetupfilexfer = a_twsetupfilexfer; RunInUiThread(DatSetupfilexferWindowsTwainDsm); a_twsetupfilexfer = m_threaddataDatSetupfilexfer.twsetupfilexfer; sts = m_threaddataDatSetupfilexfer.sts; m_threaddataDatSetupfilexfer = default(ThreadData); } } } } catch (Exception exception) { // The driver crashed... Log.Error("crash - " + exception.Message); Log.LogSendAfter(STS.BUMMER, ""); return (STS.BUMMER); } } // Linux... else if (ms_platform == Platform.LINUX) { // Issue the command... try { if (m_blFoundLatestDsm64 && (m_linuxdsm == LinuxDsm.IsLatestDsm)) { sts = (STS)NativeMethods.Linux64DsmEntrySetupfilexfer(ref m_twidentitylegacyApp, ref m_twidentitylegacyDs, a_dg, DAT.SETUPFILEXFER, a_msg, ref a_twsetupfilexfer); } else if (m_blFoundLatestDsm && (m_linuxdsm == LinuxDsm.IsLatestDsm)) { sts = (STS)NativeMethods.LinuxDsmEntrySetupfilexfer(ref m_twidentitylegacyApp, ref m_twidentitylegacyDs, a_dg, DAT.SETUPFILEXFER, a_msg, ref a_twsetupfilexfer); } else if (m_blFound020302Dsm64bit && (m_linuxdsm == LinuxDsm.Is020302Dsm64bit)) { sts = (STS)NativeMethods.Linux020302Dsm64bitEntrySetupfilexfer(ref m_twidentityApp, ref m_twidentityDs, a_dg, DAT.SETUPFILEXFER, a_msg, ref a_twsetupfilexfer); } else { Log.Error("apparently we don't have a DSM..."); sts = STS.BUMMER; } } catch (Exception exception) { // The driver crashed... Log.Error("crash - " + exception.Message); Log.LogSendAfter(STS.BUMMER, ""); return (STS.BUMMER); } } // Mac OS X, which has to be different... else if (ms_platform == Platform.MACOSX) { // Issue the command... try { if (m_blUseLegacyDSM) { sts = (STS)NativeMethods.MacosxTwainDsmEntrySetupfilexfer(ref m_twidentitymacosxApp, ref m_twidentitymacosxDs, a_dg, DAT.SETUPFILEXFER, a_msg, ref a_twsetupfilexfer); } else { sts = (STS)NativeMethods.MacosxTwaindsmDsmEntrySetupfilexfer(ref m_twidentitymacosxApp, ref m_twidentitymacosxDs, a_dg, DAT.SETUPFILEXFER, a_msg, ref a_twsetupfilexfer); } } catch (Exception exception) { // The driver crashed... Log.Error("crash - " + exception.Message); Log.LogSendAfter(STS.BUMMER, ""); return (STS.BUMMER); } } // Uh-oh... else { Log.LogSendAfter(STS.BUMMER, ""); return (STS.BUMMER); } // Get DAT_STATUS, if needed... TWAIN.STS stsRcOrCc = AutoDatStatus(sts); // Log it... if (Log.GetLevel() > 0) { Log.LogSendAfter(stsRcOrCc, SetupfilexferToCsv(a_twsetupfilexfer)); } // All done... return (stsRcOrCc); } /// /// Get info about the memory xfer... /// /// Data group /// Operation /// SETUPMEMXFER structure /// TWAIN status private void DatSetupmemxferWindowsTwain32() { // If you get a first chance exception, be aware that some drivers // will do that to you, you can ignore it and they'll keep going... m_threaddataDatSetupmemxfer.sts = (STS)NativeMethods.WindowsTwain32DsmEntrySetupmemxfer ( ref m_twidentitylegacyApp, ref m_twidentitylegacyDs, m_threaddataDatSetupmemxfer.dg, m_threaddataDatSetupmemxfer.dat, m_threaddataDatSetupmemxfer.msg, ref m_threaddataDatSetupmemxfer.twsetupmemxfer ); } private void DatSetupmemxferWindowsTwainDsm() { // If you get a first chance exception, be aware that some drivers // will do that to you, you can ignore it and they'll keep going... m_threaddataDatSetupmemxfer.sts = (STS)NativeMethods.WindowsTwaindsmDsmEntrySetupmemxfer ( ref m_twidentitylegacyApp, ref m_twidentitylegacyDs, m_threaddataDatSetupmemxfer.dg, m_threaddataDatSetupmemxfer.dat, m_threaddataDatSetupmemxfer.msg, ref m_threaddataDatSetupmemxfer.twsetupmemxfer ); } public STS DatSetupmemxfer(DG a_dg, MSG a_msg, ref TW_SETUPMEMXFER a_twsetupmemxfer) { STS sts; // Submit the work to the TWAIN thread... if (m_runinuithreaddelegate == null) { if ((m_threadTwain != null) && (m_threadTwain.ManagedThreadId != Thread.CurrentThread.ManagedThreadId)) { lock (m_lockTwain) { // Set our command variables... ThreadData threaddata = default(ThreadData); threaddata.twsetupmemxfer = a_twsetupmemxfer; threaddata.dg = a_dg; threaddata.msg = a_msg; threaddata.dat = DAT.SETUPMEMXFER; long lIndex = m_twaincommand.Submit(threaddata); // Submit the command and wait for the reply... CallerToThreadSet(); ThreadToCallerWaitOne(); // Return the result... a_twsetupmemxfer = m_twaincommand.Get(lIndex).twsetupmemxfer; sts = m_twaincommand.Get(lIndex).sts; // Clear the command variables... m_twaincommand.Delete(lIndex); } return (sts); } } // Log it... if (Log.GetLevel() > 0) { Log.LogSendBefore(a_dg.ToString(), DAT.SETUPMEMXFER.ToString(), a_msg.ToString(), ""); } // Windows... if (ms_platform == Platform.WINDOWS) { // Issue the command... try { if (m_threaddataDatSetupmemxfer.blIsInuse || (this.m_runinuithreaddelegate == null)) { if (m_blUseLegacyDSM) { sts = (STS)NativeMethods.WindowsTwain32DsmEntrySetupmemxfer(ref m_twidentitylegacyApp, ref m_twidentitylegacyDs, a_dg, DAT.SETUPMEMXFER, a_msg, ref a_twsetupmemxfer); } else { sts = (STS)NativeMethods.WindowsTwaindsmDsmEntrySetupmemxfer(ref m_twidentitylegacyApp, ref m_twidentitylegacyDs, a_dg, DAT.SETUPMEMXFER, a_msg, ref a_twsetupmemxfer); } } else { if (m_blUseLegacyDSM) { lock (m_lockTwain) { m_threaddataDatSetupmemxfer = default(ThreadData); m_threaddataDatSetupmemxfer.blIsInuse = true; m_threaddataDatSetupmemxfer.dg = a_dg; m_threaddataDatSetupmemxfer.msg = a_msg; m_threaddataDatSetupmemxfer.dat = DAT.SETUPMEMXFER; m_threaddataDatSetupmemxfer.twsetupmemxfer = a_twsetupmemxfer; RunInUiThread(DatSetupmemxferWindowsTwain32); a_twsetupmemxfer = m_threaddataDatSetupmemxfer.twsetupmemxfer; sts = m_threaddataDatSetupmemxfer.sts; m_threaddataDatSetupmemxfer = default(ThreadData); } } else { lock (m_lockTwain) { m_threaddataDatSetupmemxfer = default(ThreadData); m_threaddataDatSetupmemxfer.blIsInuse = true; m_threaddataDatSetupmemxfer.dg = a_dg; m_threaddataDatSetupmemxfer.msg = a_msg; m_threaddataDatSetupmemxfer.dat = DAT.SETUPMEMXFER; m_threaddataDatSetupmemxfer.twsetupmemxfer = a_twsetupmemxfer; RunInUiThread(DatSetupmemxferWindowsTwainDsm); a_twsetupmemxfer = m_threaddataDatSetupmemxfer.twsetupmemxfer; sts = m_threaddataDatSetupmemxfer.sts; m_threaddataDatSetupmemxfer = default(ThreadData); } } } } catch (Exception exception) { // The driver crashed... Log.Error("crash - " + exception.Message); Log.LogSendAfter(STS.BUMMER, ""); return (STS.BUMMER); } } // Linux... else if (ms_platform == Platform.LINUX) { // Issue the command... try { if (m_blFoundLatestDsm64 && (m_linuxdsm == LinuxDsm.IsLatestDsm)) { sts = (STS)NativeMethods.Linux64DsmEntrySetupmemxfer(ref m_twidentitylegacyApp, ref m_twidentitylegacyDs, a_dg, DAT.SETUPMEMXFER, a_msg, ref a_twsetupmemxfer); } else if (m_blFoundLatestDsm && (m_linuxdsm == LinuxDsm.IsLatestDsm)) { sts = (STS)NativeMethods.LinuxDsmEntrySetupmemxfer(ref m_twidentitylegacyApp, ref m_twidentitylegacyDs, a_dg, DAT.SETUPMEMXFER, a_msg, ref a_twsetupmemxfer); } else if (m_blFound020302Dsm64bit && (m_linuxdsm == LinuxDsm.Is020302Dsm64bit)) { sts = (STS)NativeMethods.Linux020302Dsm64bitEntrySetupmemxfer(ref m_twidentityApp, ref m_twidentityDs, a_dg, DAT.SETUPMEMXFER, a_msg, ref a_twsetupmemxfer); } else { Log.Error("apparently we don't have a DSM..."); sts = STS.BUMMER; } } catch (Exception exception) { // The driver crashed... Log.Error("crash - " + exception.Message); Log.LogSendAfter(STS.BUMMER, ""); return (STS.BUMMER); } } // Mac OS X, which has to be different... else if (ms_platform == Platform.MACOSX) { // Issue the command... try { if (m_blUseLegacyDSM) { sts = (STS)NativeMethods.MacosxTwainDsmEntrySetupmemxfer(ref m_twidentitymacosxApp, ref m_twidentitymacosxDs, a_dg, DAT.SETUPMEMXFER, a_msg, ref a_twsetupmemxfer); } else { sts = (STS)NativeMethods.MacosxTwaindsmDsmEntrySetupmemxfer(ref m_twidentitymacosxApp, ref m_twidentitymacosxDs, a_dg, DAT.SETUPMEMXFER, a_msg, ref a_twsetupmemxfer); } } catch (Exception exception) { // The driver crashed... Log.Error("crash - " + exception.Message); Log.LogSendAfter(STS.BUMMER, ""); return (STS.BUMMER); } } // Uh-oh... else { Log.LogSendAfter(STS.BUMMER, ""); return (STS.BUMMER); } // Get DAT_STATUS, if needed... TWAIN.STS stsRcOrCc = AutoDatStatus(sts); // Log it... if (Log.GetLevel() > 0) { Log.LogSendAfter(stsRcOrCc, SetupmemxferToCsv(a_twsetupmemxfer)); } // All done... return (stsRcOrCc); } /// /// Get some text for an error... /// /// Data group /// Operation /// STATUS structure /// TWAIN status private void DatStatusWindowsTwain32() { // If you get a first chance exception, be aware that some drivers // will do that to you, you can ignore it and they'll keep going... m_threaddataDatStatus.sts = (STS)NativeMethods.WindowsTwain32DsmEntryStatus ( ref m_twidentitylegacyApp, ref m_twidentitylegacyDs, m_threaddataDatStatus.dg, m_threaddataDatStatus.dat, m_threaddataDatStatus.msg, ref m_threaddataDatStatus.twstatus ); } private void DatStatusWindowsTwainDsm() { // If you get a first chance exception, be aware that some drivers // will do that to you, you can ignore it and they'll keep going... m_threaddataDatStatus.sts = (STS)NativeMethods.WindowsTwaindsmDsmEntryStatus ( ref m_twidentitylegacyApp, ref m_twidentitylegacyDs, m_threaddataDatStatus.dg, m_threaddataDatStatus.dat, m_threaddataDatStatus.msg, ref m_threaddataDatStatus.twstatus ); } public STS DatStatus(DG a_dg, MSG a_msg, ref TW_STATUS a_twstatus) { STS sts; // Submit the work to the TWAIN thread... if (m_runinuithreaddelegate == null) { if ((m_threadTwain != null) && (m_threadTwain.ManagedThreadId != Thread.CurrentThread.ManagedThreadId)) { lock (m_lockTwain) { // Set our command variables... ThreadData threaddata = default(ThreadData); threaddata.twstatus = a_twstatus; threaddata.dg = a_dg; threaddata.msg = a_msg; threaddata.dat = DAT.STATUS; long lIndex = m_twaincommand.Submit(threaddata); // Submit the command and wait for the reply... CallerToThreadSet(); ThreadToCallerWaitOne(); // Return the result... a_twstatus = m_twaincommand.Get(lIndex).twstatus; sts = m_twaincommand.Get(lIndex).sts; // Clear the command variables... m_twaincommand.Delete(lIndex); } return (sts); } } // Log it... if (Log.GetLevel() > 0) { Log.LogSendBefore(a_dg.ToString(), DAT.STATUS.ToString(), a_msg.ToString(), ""); } // Windows... if (ms_platform == Platform.WINDOWS) { // Issue the command... try { if (m_threaddataDatStatus.blIsInuse || (this.m_runinuithreaddelegate == null)) { if (m_blUseLegacyDSM) { sts = (STS)NativeMethods.WindowsTwain32DsmEntryStatus(ref m_twidentitylegacyApp, ref m_twidentitylegacyDs, a_dg, DAT.STATUS, a_msg, ref a_twstatus); } else { sts = (STS)NativeMethods.WindowsTwaindsmDsmEntryStatus(ref m_twidentitylegacyApp, ref m_twidentitylegacyDs, a_dg, DAT.STATUS, a_msg, ref a_twstatus); } } else { if (m_blUseLegacyDSM) { lock (m_lockTwain) { m_threaddataDatStatus = default(ThreadData); m_threaddataDatStatus.blIsInuse = true; m_threaddataDatStatus.dg = a_dg; m_threaddataDatStatus.msg = a_msg; m_threaddataDatStatus.dat = DAT.STATUS; m_threaddataDatStatus.twstatus = a_twstatus; RunInUiThread(DatStatusWindowsTwain32); a_twstatus = m_threaddataDatStatus.twstatus; sts = m_threaddataDatStatus.sts; m_threaddataDatStatus = default(ThreadData); } } else { lock (m_lockTwain) { m_threaddataDatStatus = default(ThreadData); m_threaddataDatStatus.blIsInuse = true; m_threaddataDatStatus.dg = a_dg; m_threaddataDatStatus.msg = a_msg; m_threaddataDatStatus.dat = DAT.STATUS; m_threaddataDatStatus.twstatus = a_twstatus; RunInUiThread(DatStatusWindowsTwainDsm); a_twstatus = m_threaddataDatStatus.twstatus; sts = m_threaddataDatStatus.sts; m_threaddataDatStatus = default(ThreadData); } } } } catch (Exception exception) { // The driver crashed... Log.Error("crash - " + exception.Message); Log.LogSendAfter(STS.BUMMER, ""); return (STS.BUMMER); } } // Linux... else if (ms_platform == Platform.LINUX) { // Issue the command... try { if (m_blFoundLatestDsm64 && (m_linuxdsm == LinuxDsm.IsLatestDsm)) { sts = (STS)NativeMethods.Linux64DsmEntryStatus(ref m_twidentitylegacyApp, ref m_twidentitylegacyDs, a_dg, DAT.STATUS, a_msg, ref a_twstatus); } else if (m_blFoundLatestDsm && (m_linuxdsm == LinuxDsm.IsLatestDsm)) { sts = (STS)NativeMethods.LinuxDsmEntryStatus(ref m_twidentitylegacyApp, ref m_twidentitylegacyDs, a_dg, DAT.STATUS, a_msg, ref a_twstatus); } else if (m_blFound020302Dsm64bit && (m_linuxdsm == LinuxDsm.Is020302Dsm64bit)) { sts = (STS)NativeMethods.Linux020302Dsm64bitEntryStatus(ref m_twidentityApp, ref m_twidentityDs, a_dg, DAT.STATUS, a_msg, ref a_twstatus); } else { Log.Error("apparently we don't have a DSM..."); sts = STS.BUMMER; } } catch (Exception exception) { // The driver crashed... Log.Error("crash - " + exception.Message); Log.LogSendAfter(STS.BUMMER, ""); return (STS.BUMMER); } } // Mac OS X, which has to be different... else if (ms_platform == Platform.MACOSX) { // Issue the command... try { if (m_blUseLegacyDSM) { sts = (STS)NativeMethods.MacosxTwainDsmEntryStatus(ref m_twidentitymacosxApp, ref m_twidentitymacosxDs, a_dg, DAT.STATUS, a_msg, ref a_twstatus); } else { sts = (STS)NativeMethods.MacosxTwaindsmDsmEntryStatus(ref m_twidentitymacosxApp, ref m_twidentitymacosxDs, a_dg, DAT.STATUS, a_msg, ref a_twstatus); } } catch (Exception exception) { // The driver crashed... Log.Error("crash - " + exception.Message); Log.LogSendAfter(STS.BUMMER, ""); return (STS.BUMMER); } } // Uh-oh... else { Log.LogSendAfter(STS.BUMMER, ""); return (STS.BUMMER); } // Skip getting the status... :) TWAIN.STS stsRcOrCc = sts; // Log it... if (Log.GetLevel() > 0) { Log.LogSendAfter(stsRcOrCc, ""); } // All done... return (stsRcOrCc); } /// /// Get some text for an error... /// /// Data group /// Operation /// STATUSUTF8 structure /// TWAIN status public STS DatStatusutf8(DG a_dg, MSG a_msg, ref TW_STATUSUTF8 a_twstatusutf8) { STS sts; // Submit the work to the TWAIN thread... if ((m_threadTwain != null) && (m_threadTwain.ManagedThreadId != Thread.CurrentThread.ManagedThreadId)) { lock (m_lockTwain) { // Set our command variables... ThreadData threaddata = default(ThreadData); threaddata.twstatusutf8 = a_twstatusutf8; threaddata.dg = a_dg; threaddata.msg = a_msg; threaddata.dat = DAT.STATUSUTF8; long lIndex = m_twaincommand.Submit(threaddata); // Submit the command and wait for the reply... CallerToThreadSet(); ThreadToCallerWaitOne(); // Return the result... a_twstatusutf8 = m_twaincommand.Get(lIndex).twstatusutf8; sts = m_twaincommand.Get(lIndex).sts; // Clear the command variables... m_twaincommand.Delete(lIndex); } return (sts); } // Log it... if (Log.GetLevel() > 0) { Log.LogSendBefore(a_dg.ToString(), DAT.STATUSUTF8.ToString(), a_msg.ToString(), ""); } // Windows... if (ms_platform == Platform.WINDOWS) { // Issue the command... try { if (m_blUseLegacyDSM) { sts = (STS)NativeMethods.WindowsTwain32DsmEntryStatusutf8(ref m_twidentitylegacyApp, ref m_twidentitylegacyDs, a_dg, DAT.STATUSUTF8, a_msg, ref a_twstatusutf8); } else { sts = (STS)NativeMethods.WindowsTwaindsmDsmEntryStatusutf8(ref m_twidentitylegacyApp, ref m_twidentitylegacyDs, a_dg, DAT.STATUSUTF8, a_msg, ref a_twstatusutf8); } } catch (Exception exception) { // The driver crashed... Log.Error("crash - " + exception.Message); Log.LogSendAfter(STS.BUMMER, ""); return (STS.BUMMER); } } // Linux... else if (ms_platform == Platform.LINUX) { // Issue the command... try { if (m_blFoundLatestDsm64 && (m_linuxdsm == LinuxDsm.IsLatestDsm)) { sts = (STS)NativeMethods.Linux64DsmEntryStatusutf8(ref m_twidentitylegacyApp, ref m_twidentitylegacyDs, a_dg, DAT.STATUSUTF8, a_msg, ref a_twstatusutf8); } else if (m_blFoundLatestDsm && (m_linuxdsm == LinuxDsm.IsLatestDsm)) { sts = (STS)NativeMethods.LinuxDsmEntryStatusutf8(ref m_twidentitylegacyApp, ref m_twidentitylegacyDs, a_dg, DAT.STATUSUTF8, a_msg, ref a_twstatusutf8); } else if (m_blFound020302Dsm64bit && (m_linuxdsm == LinuxDsm.Is020302Dsm64bit)) { sts = (STS)NativeMethods.Linux020302Dsm64bitEntryStatusutf8(ref m_twidentityApp, ref m_twidentityDs, a_dg, DAT.STATUSUTF8, a_msg, ref a_twstatusutf8); } else { Log.Error("apparently we don't have a DSM..."); sts = STS.BUMMER; } } catch (Exception exception) { // The driver crashed... Log.Error("crash - " + exception.Message); Log.LogSendAfter(STS.BUMMER, ""); return (STS.BUMMER); } } // Mac OS X, which has to be different... else if (ms_platform == Platform.MACOSX) { // Issue the command... try { if (m_blUseLegacyDSM) { sts = (STS)NativeMethods.MacosxTwainDsmEntryStatusutf8(ref m_twidentitymacosxApp, ref m_twidentitymacosxDs, a_dg, DAT.STATUSUTF8, a_msg, ref a_twstatusutf8); } else { sts = (STS)NativeMethods.MacosxTwaindsmDsmEntryStatusutf8(ref m_twidentitymacosxApp, ref m_twidentitymacosxDs, a_dg, DAT.STATUSUTF8, a_msg, ref a_twstatusutf8); } } catch (Exception exception) { // The driver crashed... Log.Error("crash - " + exception.Message); Log.LogSendAfter(STS.BUMMER, ""); return (STS.BUMMER); } } // Uh-oh... else { Log.LogSendAfter(STS.BUMMER, ""); return (STS.BUMMER); } // Get DAT_STATUS, if needed... TWAIN.STS stsRcOrCc = AutoDatStatus(sts); // Log it... if (Log.GetLevel() > 0) { Log.LogSendAfter(stsRcOrCc, ""); } // All done... return (stsRcOrCc); } /// /// Get some text for an error... /// /// Data group /// Operation /// TWAINDIRECT structure /// TWAIN status public STS DatTwaindirect(DG a_dg, MSG a_msg, ref TW_TWAINDIRECT a_twtwaindirect) { STS sts; // Submit the work to the TWAIN thread... if ((m_threadTwain != null) && (m_threadTwain.ManagedThreadId != Thread.CurrentThread.ManagedThreadId)) { lock (m_lockTwain) { // Set our command variables... ThreadData threaddata = default(ThreadData); threaddata.twtwaindirect = a_twtwaindirect; threaddata.dg = a_dg; threaddata.msg = a_msg; threaddata.dat = DAT.TWAINDIRECT; long lIndex = m_twaincommand.Submit(threaddata); // Submit the command and wait for the reply... CallerToThreadSet(); ThreadToCallerWaitOne(); // Return the result... a_twtwaindirect = m_twaincommand.Get(lIndex).twtwaindirect; sts = m_twaincommand.Get(lIndex).sts; // Clear the command variables... m_twaincommand.Delete(lIndex); } return (sts); } // Log it... if (Log.GetLevel() > 0) { Log.LogSendBefore(a_dg.ToString(), DAT.TWAINDIRECT.ToString(), a_msg.ToString(), ""); } // Windows... if (ms_platform == Platform.WINDOWS) { // Issue the command... try { if (m_blUseLegacyDSM) { sts = (STS)NativeMethods.WindowsTwain32DsmEntryTwaindirect(ref m_twidentitylegacyApp, ref m_twidentitylegacyDs, a_dg, DAT.TWAINDIRECT, a_msg, ref a_twtwaindirect); } else { sts = (STS)NativeMethods.WindowsTwaindsmDsmEntryTwaindirect(ref m_twidentitylegacyApp, ref m_twidentitylegacyDs, a_dg, DAT.TWAINDIRECT, a_msg, ref a_twtwaindirect); } } catch (Exception exception) { // The driver crashed... Log.Error("crash - " + exception.Message); Log.LogSendAfter(STS.BUMMER, ""); return (STS.BUMMER); } } // Linux... else if (ms_platform == Platform.LINUX) { // Issue the command... try { if (m_blFoundLatestDsm64 && (m_linuxdsm == LinuxDsm.IsLatestDsm)) { sts = (STS)NativeMethods.Linux64DsmEntryTwaindirect(ref m_twidentitylegacyApp, ref m_twidentitylegacyDs, a_dg, DAT.TWAINDIRECT, a_msg, ref a_twtwaindirect); } else if (m_blFoundLatestDsm && (m_linuxdsm == LinuxDsm.IsLatestDsm)) { sts = (STS)NativeMethods.LinuxDsmEntryTwaindirect(ref m_twidentitylegacyApp, ref m_twidentitylegacyDs, a_dg, DAT.TWAINDIRECT, a_msg, ref a_twtwaindirect); } else if (m_blFound020302Dsm64bit && (m_linuxdsm == LinuxDsm.Is020302Dsm64bit)) { sts = (STS)NativeMethods.Linux020302Dsm64bitEntryTwaindirect(ref m_twidentityApp, ref m_twidentityDs, a_dg, DAT.TWAINDIRECT, a_msg, ref a_twtwaindirect); } else { Log.Error("apparently we don't have a DSM..."); sts = STS.BUMMER; } } catch (Exception exception) { // The driver crashed... Log.Error("crash - " + exception.Message); Log.LogSendAfter(STS.BUMMER, ""); return (STS.BUMMER); } } // Mac OS X, which has to be different... else if (ms_platform == Platform.MACOSX) { // Issue the command... try { if (m_blUseLegacyDSM) { sts = (STS)NativeMethods.MacosxTwainDsmEntryTwaindirect(ref m_twidentitymacosxApp, ref m_twidentitymacosxDs, a_dg, DAT.TWAINDIRECT, a_msg, ref a_twtwaindirect); } else { sts = (STS)NativeMethods.MacosxTwaindsmDsmEntryTwaindirect(ref m_twidentitymacosxApp, ref m_twidentitymacosxDs, a_dg, DAT.TWAINDIRECT, a_msg, ref a_twtwaindirect); } } catch (Exception exception) { // The driver crashed... Log.Error("crash - " + exception.Message); Log.LogSendAfter(STS.BUMMER, ""); return (STS.BUMMER); } } // Uh-oh... else { Log.LogSendAfter(STS.BUMMER, ""); return (STS.BUMMER); } // Get DAT_STATUS, if needed... TWAIN.STS stsRcOrCc = AutoDatStatus(sts); // Log it... if (Log.GetLevel() > 0) { Log.LogSendAfter(stsRcOrCc, ""); } // All done... return (stsRcOrCc); } /// /// Issue capabilities commands... /// /// Data group /// Operation /// USERINTERFACE structure /// TWAIN status private void DatUserinterfaceWindowsTwain32() { // If you get a first chance exception, be aware that some drivers // will do that to you, you can ignore it and they'll keep going... m_threaddataDatUserinterface.sts = (STS)NativeMethods.WindowsTwain32DsmEntryUserinterface ( ref m_twidentitylegacyApp, ref m_twidentitylegacyDs, m_threaddataDatUserinterface.dg, m_threaddataDatUserinterface.dat, m_threaddataDatUserinterface.msg, ref m_threaddataDatUserinterface.twuserinterface ); } private void DatUserinterfaceWindowsTwainDsm() { // If you get a first chance exception, be aware that some drivers // will do that to you, you can ignore it and they'll keep going... m_threaddataDatUserinterface.sts = (STS)NativeMethods.WindowsTwaindsmDsmEntryUserinterface ( ref m_twidentitylegacyApp, ref m_twidentitylegacyDs, m_threaddataDatUserinterface.dg, m_threaddataDatUserinterface.dat, m_threaddataDatUserinterface.msg, ref m_threaddataDatUserinterface.twuserinterface ); } public STS DatUserinterface(DG a_dg, MSG a_msg, ref TW_USERINTERFACE a_twuserinterface) { STS sts; // Submit the work to the TWAIN thread... if (this.m_runinuithreaddelegate == null) { if ((m_threadTwain != null) && (m_threadTwain.ManagedThreadId != Thread.CurrentThread.ManagedThreadId)) { lock (m_lockTwain) { // Set our command variables... ThreadData threaddata = default(ThreadData); threaddata.twuserinterface = a_twuserinterface; threaddata.twuserinterface.hParent = m_intptrHwnd; threaddata.dg = a_dg; threaddata.msg = a_msg; threaddata.dat = DAT.USERINTERFACE; long lIndex = m_twaincommand.Submit(threaddata); // Submit the command and wait for the reply... CallerToThreadSet(); ThreadToCallerWaitOne(); // Return the result... a_twuserinterface = m_twaincommand.Get(lIndex).twuserinterface; sts = m_twaincommand.Get(lIndex).sts; // Clear the command variables... m_twaincommand.Delete(lIndex); } return (sts); } } // Log it... if (Log.GetLevel() > 0) { Log.LogSendBefore(a_dg.ToString(), DAT.USERINTERFACE.ToString(), a_msg.ToString(), UserinterfaceToCsv(a_twuserinterface)); } // We need this to handle data sources that return MSG_XFERREADY in // the midst of processing MSG_ENABLEDS, otherwise we'll miss it... m_blAcceptXferReady = (a_msg == MSG.ENABLEDS); m_blRunningDatUserinterface = (a_msg == MSG.ENABLEDS); // Windows... if (ms_platform == Platform.WINDOWS) { // Issue the command... try { if (m_threaddataDatUserinterface.blIsInuse || (this.m_runinuithreaddelegate == null)) { if (m_blUseLegacyDSM) { sts = (STS)NativeMethods.WindowsTwain32DsmEntryUserinterface(ref m_twidentitylegacyApp, ref m_twidentitylegacyDs, a_dg, DAT.USERINTERFACE, a_msg, ref a_twuserinterface); } else { sts = (STS)NativeMethods.WindowsTwaindsmDsmEntryUserinterface(ref m_twidentitylegacyApp, ref m_twidentitylegacyDs, a_dg, DAT.USERINTERFACE, a_msg, ref a_twuserinterface); } } else { if (m_blUseLegacyDSM) { lock (m_lockTwain) { m_threaddataDatUserinterface = default(ThreadData); m_threaddataDatUserinterface.blIsInuse = true; m_threaddataDatUserinterface.dg = a_dg; m_threaddataDatUserinterface.msg = a_msg; m_threaddataDatUserinterface.dat = DAT.USERINTERFACE; m_threaddataDatUserinterface.twuserinterface = a_twuserinterface; RunInUiThread(DatUserinterfaceWindowsTwain32); a_twuserinterface = m_threaddataDatUserinterface.twuserinterface; sts = m_threaddataDatUserinterface.sts; m_threaddataDatUserinterface = default(ThreadData); } } else { lock (m_lockTwain) { m_threaddataDatUserinterface = default(ThreadData); m_threaddataDatUserinterface.blIsInuse = true; m_threaddataDatUserinterface.dg = a_dg; m_threaddataDatUserinterface.msg = a_msg; m_threaddataDatUserinterface.dat = DAT.USERINTERFACE; m_threaddataDatUserinterface.twuserinterface = a_twuserinterface; RunInUiThread(DatUserinterfaceWindowsTwainDsm); a_twuserinterface = m_threaddataDatUserinterface.twuserinterface; sts = m_threaddataDatUserinterface.sts; m_threaddataDatUserinterface = default(ThreadData); } } } } catch (Exception exception) { // The driver crashed... Log.Error("crash - " + exception.Message); Log.LogSendAfter(STS.BUMMER, ""); m_blRunningDatUserinterface = false; return (STS.BUMMER); } } // Linux... else if (ms_platform == Platform.LINUX) { // Issue the command... try { if (m_blFoundLatestDsm64 && (m_linuxdsm == LinuxDsm.IsLatestDsm)) { sts = (STS)NativeMethods.Linux64DsmEntryUserinterface(ref m_twidentitylegacyApp, ref m_twidentitylegacyDs, a_dg, DAT.USERINTERFACE, a_msg, ref a_twuserinterface); } else if (m_blFoundLatestDsm && (m_linuxdsm == LinuxDsm.IsLatestDsm)) { sts = (STS)NativeMethods.LinuxDsmEntryUserinterface(ref m_twidentitylegacyApp, ref m_twidentitylegacyDs, a_dg, DAT.USERINTERFACE, a_msg, ref a_twuserinterface); } else if (m_blFound020302Dsm64bit && (m_linuxdsm == LinuxDsm.Is020302Dsm64bit)) { sts = (STS)NativeMethods.Linux020302Dsm64bitEntryUserinterface(ref m_twidentityApp, ref m_twidentityDs, a_dg, DAT.USERINTERFACE, a_msg, ref a_twuserinterface); } else { Log.Error("apparently we don't have a DSM..."); sts = STS.BUMMER; } } catch (Exception exception) { // The driver crashed... Log.Error("crash - " + exception.Message); Log.LogSendAfter(STS.BUMMER, ""); m_blRunningDatUserinterface = false; return (STS.BUMMER); } } // Mac OS X, which has to be different... else if (ms_platform == Platform.MACOSX) { // Issue the command... try { if (m_blUseLegacyDSM) { sts = (STS)NativeMethods.MacosxTwainDsmEntryUserinterface(ref m_twidentitymacosxApp, ref m_twidentitymacosxDs, a_dg, DAT.USERINTERFACE, a_msg, ref a_twuserinterface); } else { sts = (STS)NativeMethods.MacosxTwaindsmDsmEntryUserinterface(ref m_twidentitymacosxApp, ref m_twidentitymacosxDs, a_dg, DAT.USERINTERFACE, a_msg, ref a_twuserinterface); } } catch (Exception exception) { // The driver crashed... Log.Error("crash - " + exception.Message); Log.LogSendAfter(STS.BUMMER, ""); m_blRunningDatUserinterface = false; return (STS.BUMMER); } } // Uh-oh... else { Log.LogSendAfter(STS.BUMMER, ""); m_blRunningDatUserinterface = false; return (STS.BUMMER); } // Get DAT_STATUS, if needed... TWAIN.STS stsRcOrCc = AutoDatStatus(sts); // Log it... if (Log.GetLevel() > 0) { Log.LogSendAfter(stsRcOrCc, ""); } // If successful, decide which way to jump... if (sts == STS.SUCCESS) { switch (a_msg) { // No clue... default: break; // Jump up... case MSG.ENABLEDS: case MSG.ENABLEDSUIONLY: m_state = STATE.S5; break; // Jump down... case MSG.DISABLEDS: m_blIsMsgclosedsreq = false; m_blIsMsgclosedsok = false; m_state = STATE.S4; break; } } // All done... m_blRunningDatUserinterface = false; return (stsRcOrCc); } /// /// Get/Set the Xfer Group... /// /// Data group /// Operation /// XFERGROUP structure /// TWAIN status public STS DatXferGroup(DG a_dg, MSG a_msg, ref UInt32 a_twuint32) { STS sts; // Submit the work to the TWAIN thread... if ((m_threadTwain != null) && (m_threadTwain.ManagedThreadId != Thread.CurrentThread.ManagedThreadId)) { lock (m_lockTwain) { // Set our command variables... ThreadData threaddata = default(ThreadData); threaddata.twuint32 = a_twuint32; threaddata.dg = a_dg; threaddata.msg = a_msg; threaddata.dat = DAT.XFERGROUP; long lIndex = m_twaincommand.Submit(threaddata); // Submit the command and wait for the reply... CallerToThreadSet(); ThreadToCallerWaitOne(); // Return the result... a_twuint32 = m_twaincommand.Get(lIndex).twuint32; sts = m_twaincommand.Get(lIndex).sts; // Clear the command variables... m_twaincommand.Delete(lIndex); } return (sts); } // Log it... if (Log.GetLevel() > 0) { Log.LogSendBefore(a_dg.ToString(), DAT.XFERGROUP.ToString(), a_msg.ToString(), XfergroupToCsv(a_twuint32)); } // Windows... if (ms_platform == Platform.WINDOWS) { // Issue the command... try { if (m_blUseLegacyDSM) { sts = (STS)NativeMethods.WindowsTwain32DsmEntryXfergroup(ref m_twidentitylegacyApp, ref m_twidentitylegacyDs, a_dg, DAT.XFERGROUP, a_msg, ref a_twuint32); } else { sts = (STS)NativeMethods.WindowsTwaindsmDsmEntryXfergroup(ref m_twidentitylegacyApp, ref m_twidentitylegacyDs, a_dg, DAT.XFERGROUP, a_msg, ref a_twuint32); } } catch (Exception exception) { // The driver crashed... Log.Error("crash - " + exception.Message); Log.LogSendAfter(STS.BUMMER, ""); return (STS.BUMMER); } } // Linux... else if (ms_platform == Platform.LINUX) { // Issue the command... try { if (m_blFoundLatestDsm64 && (m_linuxdsm == LinuxDsm.IsLatestDsm)) { sts = (STS)NativeMethods.Linux64DsmEntryXfergroup(ref m_twidentitylegacyApp, ref m_twidentitylegacyDs, a_dg, DAT.XFERGROUP, a_msg, ref a_twuint32); } else if (m_blFoundLatestDsm && (m_linuxdsm == LinuxDsm.IsLatestDsm)) { sts = (STS)NativeMethods.LinuxDsmEntryXfergroup(ref m_twidentitylegacyApp, ref m_twidentitylegacyDs, a_dg, DAT.XFERGROUP, a_msg, ref a_twuint32); } else if (m_blFound020302Dsm64bit && (m_linuxdsm == LinuxDsm.Is020302Dsm64bit)) { sts = (STS)NativeMethods.Linux020302Dsm64bitEntryXfergroup(ref m_twidentityApp, ref m_twidentityDs, a_dg, DAT.XFERGROUP, a_msg, ref a_twuint32); } else { Log.Error("apparently we don't have a DSM..."); sts = STS.BUMMER; } } catch (Exception exception) { // The driver crashed... Log.Error("crash - " + exception.Message); Log.LogSendAfter(STS.BUMMER, ""); return (STS.BUMMER); } } // Mac OS X, which has to be different... else if (ms_platform == Platform.MACOSX) { // Issue the command... try { if (m_blUseLegacyDSM) { sts = (STS)NativeMethods.MacosxTwainDsmEntryXfergroup(ref m_twidentitymacosxApp, ref m_twidentitymacosxDs, a_dg, DAT.XFERGROUP, a_msg, ref a_twuint32); } else { sts = (STS)NativeMethods.MacosxTwaindsmDsmEntryXfergroup(ref m_twidentitymacosxApp, ref m_twidentitymacosxDs, a_dg, DAT.XFERGROUP, a_msg, ref a_twuint32); } } catch (Exception exception) { // The driver crashed... Log.Error("crash - " + exception.Message); Log.LogSendAfter(STS.BUMMER, ""); return (STS.BUMMER); } } // Uh-oh... else { Log.LogSendAfter(STS.BUMMER, ""); return (STS.BUMMER); } // Get DAT_STATUS, if needed... TWAIN.STS stsRcOrCc = AutoDatStatus(sts); // Log it... if (Log.GetLevel() > 0) { Log.LogSendAfter(stsRcOrCc, XfergroupToCsv(a_twuint32)); } // All done... return (stsRcOrCc); } #endregion /////////////////////////////////////////////////////////////////////////////// // Public Definitions, this is where you get the callback definitions for // handling device events and scanning... /////////////////////////////////////////////////////////////////////////////// #region Public Definitions... /// /// The form of the device event callback used by the caller when they are /// running in states 4, 5, 6 and 7... /// /// public delegate STS DeviceEventCallback(); /// /// The form of the callback used by the caller when they are running /// in states 5, 6 and 7; anything after DG_CONTROL / DAT_USERINTERFACE / /// MSG_ENABLEDS* until DG_CONTROL / DAT_USERINTERFACE / MSG_DISABLEDS... /// /// public delegate STS ScanCallback(bool a_blClosing); /// /// We use this to run code in the context of the caller's UI thread... /// /// code to run public delegate void RunInUiThreadDelegate(Action a_action); /// /// Only one DSM can be installed on a Linux system, and it must match /// the architecture. To handle the legacy problem due to the bad /// definition of TW_INT32/TW_UINT32, we also support access to the /// 64-bit 2.3.2 DSM. This is only used if we see a driver that seems /// to be returning garbage for its TW_IDENTITY... /// public enum LinuxDsm { Unknown, IsLatestDsm, Is020302Dsm64bit } #endregion /////////////////////////////////////////////////////////////////////////////// // Private Definitions (TIFF): this stuff should have been here all along to // make it easier to share. It's only needed when writing out files from // DAT_IMAGEMEMXFER data. /////////////////////////////////////////////////////////////////////////////// #region Private Definitions (TIFF)... // A TIFF header is composed of tags... [StructLayout(LayoutKind.Sequential, Pack = 2)] public struct TiffTag { public TiffTag(ushort a_u16Tag, ushort a_u16Type, uint a_u32Count, uint a_u32Value) { u16Tag = a_u16Tag; u16Type = a_u16Type; u32Count = a_u32Count; u32Value = a_u32Value; } public ushort u16Tag; public ushort u16Type; public uint u32Count; public uint u32Value; } // TIFF header for Uncompressed BITONAL images... [StructLayout(LayoutKind.Sequential, Pack = 2)] public struct TiffBitonalUncompressed { // Constructor... public TiffBitonalUncompressed(uint a_u32Width, uint a_u32Height, uint a_u32Resolution, uint a_u32Size) { // Header... u16ByteOrder = 0x4949; u16Version = 42; u32OffsetFirstIFD = 8; // First IFD... u16IFD = 16; // Tags... tifftagNewSubFileType = new TiffTag(254, 4, 1, 0); tifftagSubFileType = new TiffTag(255, 3, 1, 1); tifftagImageWidth = new TiffTag(256, 4, 1, a_u32Width); tifftagImageLength = new TiffTag(257, 4, 1, a_u32Height); tifftagBitsPerSample = new TiffTag(258, 3, 1, 1); tifftagCompression = new TiffTag(259, 3, 1, 1); tifftagPhotometricInterpretation = new TiffTag(262, 3, 1, 1); tifftagFillOrder = new TiffTag(266, 3, 1, 1); tifftagStripOffsets = new TiffTag(273, 4, 1, 222); tifftagSamplesPerPixel = new TiffTag(277, 3, 1, 1); tifftagRowsPerStrip = new TiffTag(278, 4, 1, a_u32Height); tifftagStripByteCounts = new TiffTag(279, 4, 1, a_u32Size); tifftagXResolution = new TiffTag(282, 5, 1, 206); tifftagYResolution = new TiffTag(283, 5, 1, 214); tifftagT4T6Options = new TiffTag(292, 4, 1, 0); tifftagResolutionUnit = new TiffTag(296, 3, 1, 2); // Footer... u32NextIFD = 0; u64XResolution = (ulong)0x100000000 + (ulong)a_u32Resolution; u64YResolution = (ulong)0x100000000 + (ulong)a_u32Resolution; } // Header... public ushort u16ByteOrder; public ushort u16Version; public uint u32OffsetFirstIFD; // First IFD... public ushort u16IFD; // Tags... public TiffTag tifftagNewSubFileType; public TiffTag tifftagSubFileType; public TiffTag tifftagImageWidth; public TiffTag tifftagImageLength; public TiffTag tifftagBitsPerSample; public TiffTag tifftagCompression; public TiffTag tifftagPhotometricInterpretation; public TiffTag tifftagFillOrder; public TiffTag tifftagStripOffsets; public TiffTag tifftagSamplesPerPixel; public TiffTag tifftagRowsPerStrip; public TiffTag tifftagStripByteCounts; public TiffTag tifftagXResolution; public TiffTag tifftagYResolution; public TiffTag tifftagT4T6Options; public TiffTag tifftagResolutionUnit; // Footer... public uint u32NextIFD; public ulong u64XResolution; public ulong u64YResolution; } // TIFF header for Group4 BITONAL images... [StructLayout(LayoutKind.Sequential, Pack = 2)] public struct TiffBitonalG4 { // Constructor... public TiffBitonalG4(uint a_u32Width, uint a_u32Height, uint a_u32Resolution, uint a_u32Size) { // Header... u16ByteOrder = 0x4949; u16Version = 42; u32OffsetFirstIFD = 8; // First IFD... u16IFD = 16; // Tags... tifftagNewSubFileType = new TiffTag(254, 4, 1, 0); tifftagSubFileType = new TiffTag(255, 3, 1, 1); tifftagImageWidth = new TiffTag(256, 4, 1, a_u32Width); tifftagImageLength = new TiffTag(257, 4, 1, a_u32Height); tifftagBitsPerSample = new TiffTag(258, 3, 1, 1); tifftagCompression = new TiffTag(259, 3, 1, 4); tifftagPhotometricInterpretation = new TiffTag(262, 3, 1, 0); tifftagFillOrder = new TiffTag(266, 3, 1, 1); tifftagStripOffsets = new TiffTag(273, 4, 1, 222); tifftagSamplesPerPixel = new TiffTag(277, 3, 1, 1); tifftagRowsPerStrip = new TiffTag(278, 4, 1, a_u32Height); tifftagStripByteCounts = new TiffTag(279, 4, 1, a_u32Size); tifftagXResolution = new TiffTag(282, 5, 1, 206); tifftagYResolution = new TiffTag(283, 5, 1, 214); tifftagT4T6Options = new TiffTag(293, 4, 1, 0); tifftagResolutionUnit = new TiffTag(296, 3, 1, 2); // Footer... u32NextIFD = 0; u64XResolution = (ulong)0x100000000 + (ulong)a_u32Resolution; u64YResolution = (ulong)0x100000000 + (ulong)a_u32Resolution; } // Header... public ushort u16ByteOrder; public ushort u16Version; public uint u32OffsetFirstIFD; // First IFD... public ushort u16IFD; // Tags... public TiffTag tifftagNewSubFileType; public TiffTag tifftagSubFileType; public TiffTag tifftagImageWidth; public TiffTag tifftagImageLength; public TiffTag tifftagBitsPerSample; public TiffTag tifftagCompression; public TiffTag tifftagPhotometricInterpretation; public TiffTag tifftagFillOrder; public TiffTag tifftagStripOffsets; public TiffTag tifftagSamplesPerPixel; public TiffTag tifftagRowsPerStrip; public TiffTag tifftagStripByteCounts; public TiffTag tifftagXResolution; public TiffTag tifftagYResolution; public TiffTag tifftagT4T6Options; public TiffTag tifftagResolutionUnit; // Footer... public uint u32NextIFD; public ulong u64XResolution; public ulong u64YResolution; } // TIFF header for Uncompressed GRAYSCALE images... [StructLayout(LayoutKind.Sequential, Pack = 2)] public struct TiffGrayscaleUncompressed { // Constructor... public TiffGrayscaleUncompressed(uint a_u32Width, uint a_u32Height, uint a_u32Resolution, uint a_u32Size) { // Header... u16ByteOrder = 0x4949; u16Version = 42; u32OffsetFirstIFD = 8; // First IFD... u16IFD = 14; // Tags... tifftagNewSubFileType = new TiffTag(254, 4, 1, 0); tifftagSubFileType = new TiffTag(255, 3, 1, 1); tifftagImageWidth = new TiffTag(256, 4, 1, a_u32Width); tifftagImageLength = new TiffTag(257, 4, 1, a_u32Height); tifftagBitsPerSample = new TiffTag(258, 3, 1, 8); tifftagCompression = new TiffTag(259, 3, 1, 1); tifftagPhotometricInterpretation = new TiffTag(262, 3, 1, 1); tifftagStripOffsets = new TiffTag(273, 4, 1, 198); tifftagSamplesPerPixel = new TiffTag(277, 3, 1, 1); tifftagRowsPerStrip = new TiffTag(278, 4, 1, a_u32Height); tifftagStripByteCounts = new TiffTag(279, 4, 1, a_u32Size); tifftagXResolution = new TiffTag(282, 5, 1, 182); tifftagYResolution = new TiffTag(283, 5, 1, 190); tifftagResolutionUnit = new TiffTag(296, 3, 1, 2); // Footer... u32NextIFD = 0; u64XResolution = (ulong)0x100000000 + (ulong)a_u32Resolution; u64YResolution = (ulong)0x100000000 + (ulong)a_u32Resolution; } // Header... public ushort u16ByteOrder; public ushort u16Version; public uint u32OffsetFirstIFD; // First IFD... public ushort u16IFD; // Tags... public TiffTag tifftagNewSubFileType; public TiffTag tifftagSubFileType; public TiffTag tifftagImageWidth; public TiffTag tifftagImageLength; public TiffTag tifftagBitsPerSample; public TiffTag tifftagCompression; public TiffTag tifftagPhotometricInterpretation; public TiffTag tifftagStripOffsets; public TiffTag tifftagSamplesPerPixel; public TiffTag tifftagRowsPerStrip; public TiffTag tifftagStripByteCounts; public TiffTag tifftagXResolution; public TiffTag tifftagYResolution; public TiffTag tifftagResolutionUnit; // Footer... public uint u32NextIFD; public ulong u64XResolution; public ulong u64YResolution; } // TIFF header for Uncompressed COLOR images... [StructLayout(LayoutKind.Sequential, Pack = 2)] public struct TiffColorUncompressed { // Constructor... public TiffColorUncompressed(uint a_u32Width, uint a_u32Height, uint a_u32Resolution, uint a_u32Size) { // Header... u16ByteOrder = 0x4949; u16Version = 42; u32OffsetFirstIFD = 8; // First IFD... u16IFD = 14; // Tags... tifftagNewSubFileType = new TiffTag(254, 4, 1, 0); tifftagSubFileType = new TiffTag(255, 3, 1, 1); tifftagImageWidth = new TiffTag(256, 4, 1, a_u32Width); tifftagImageLength = new TiffTag(257, 4, 1, a_u32Height); tifftagBitsPerSample = new TiffTag(258, 3, 3, 182); tifftagCompression = new TiffTag(259, 3, 1, 1); tifftagPhotometricInterpretation = new TiffTag(262, 3, 1, 2); tifftagStripOffsets = new TiffTag(273, 4, 1, 204); tifftagSamplesPerPixel = new TiffTag(277, 3, 1, 3); tifftagRowsPerStrip = new TiffTag(278, 4, 1, a_u32Height); tifftagStripByteCounts = new TiffTag(279, 4, 1, a_u32Size); tifftagXResolution = new TiffTag(282, 5, 1, 188); tifftagYResolution = new TiffTag(283, 5, 1, 196); tifftagResolutionUnit = new TiffTag(296, 3, 1, 2); // Footer... u32NextIFD = 0; u16XBitsPerSample1 = 8; u16XBitsPerSample2 = 8; u16XBitsPerSample3 = 8; u64XResolution = (ulong)0x100000000 + (ulong)a_u32Resolution; u64YResolution = (ulong)0x100000000 + (ulong)a_u32Resolution; } // Header... public ushort u16ByteOrder; public ushort u16Version; public uint u32OffsetFirstIFD; // First IFD... public ushort u16IFD; // Tags... public TiffTag tifftagNewSubFileType; public TiffTag tifftagSubFileType; public TiffTag tifftagImageWidth; public TiffTag tifftagImageLength; public TiffTag tifftagBitsPerSample; public TiffTag tifftagCompression; public TiffTag tifftagPhotometricInterpretation; public TiffTag tifftagStripOffsets; public TiffTag tifftagSamplesPerPixel; public TiffTag tifftagRowsPerStrip; public TiffTag tifftagStripByteCounts; public TiffTag tifftagXResolution; public TiffTag tifftagYResolution; public TiffTag tifftagResolutionUnit; // Footer... public uint u32NextIFD; public ushort u16XBitsPerSample1; public ushort u16XBitsPerSample2; public ushort u16XBitsPerSample3; public ulong u64XResolution; public ulong u64YResolution; } #endregion /////////////////////////////////////////////////////////////////////////////// // Private Functions, the main thread is in here... /////////////////////////////////////////////////////////////////////////////// #region Private Functions... /// /// Cleanup... /// /// true if we need to clean up managed resources [SecurityPermissionAttribute(SecurityAction.LinkDemand, Flags = SecurityPermissionFlag.UnmanagedCode)] internal void Dispose(bool a_blDisposing) { // Free managed resources... if (a_blDisposing) { // Make sure we've closed any drivers... Rollback(TWAIN.STATE.S2); // Make sure that our thread is gone... if (m_threadTwain != null) { m_threadTwain.Join(); m_threadTwain = null; } // This one too... if (m_threadRunningDatUserinterface != null) { m_threadRunningDatUserinterface.Join(); m_threadRunningDatUserinterface = null; } // Clean up our communication thingy... m_twaincommand = null; // Cleanup... if (m_autoreseteventCaller != null) { m_autoreseteventCaller.Close(); m_autoreseteventCaller = null; } if (m_autoreseteventThread != null) { m_autoreseteventThread.Close(); m_autoreseteventThread = null; } if (m_autoreseteventRollback != null) { m_autoreseteventRollback.Close(); m_autoreseteventRollback = null; } if (m_autoreseteventThreadStarted != null) { m_autoreseteventThreadStarted.Close(); m_autoreseteventThreadStarted = null; } } } /// /// This is our main loop where we issue commands to the TWAIN /// object on behalf of the caller. This function runs in its /// own thread... /// private void Main() { bool blRunning; bool blScanning; long lIndex; ThreadData threaddata; // Okay, we're ready to run... m_autoreseteventThreadStarted.Set(); Log.Info("main>>> thread started..."); // // We have three different ways of driving the TWAIN driver... // // First, we can accept a direct command from the user for commands // that move from state 2 to state 4, and for any commands that are // issued in state 4. // // Second, we have a scanning callback function, that operates when // we are transferring images; this means that we don't want the // user making those calls directly. // // Third, we have a rollback function, that allows the calls to // move anywhere from state 7 to state 2; what this means is that we // don't want the user making those calls directly. // // The trick is to move smoothly between these three styles of // access, and what we find is that the first and second are pretty // easy to do, but the third one is tricky... // blRunning = true; blScanning = false; while (blRunning) { // Get the next item, if we don't have anything, then we may // need to wait... if (!m_twaincommand.GetNext(out lIndex, out threaddata)) { // If we're not scanning, then wait for a command to wake // us up... if (!blScanning) { CallerToThreadWaitOne(); m_twaincommand.GetNext(out lIndex, out threaddata); } } // Leave...now... if (threaddata.blExitThread) { m_twaincommand.Complete(lIndex, threaddata); m_scancallback(true); ThreadToCallerSet(); ThreadToRollbackSet(); return; } // Process device events... if (IsMsgDeviceEvent()) { m_deviceeventcallback(); } // We don't have a direct command, it's either a rollback request, // a request to run the scan callback, or its a false positive, // which we can safely ignore... if (threaddata.dat == default(DAT)) { // The caller has asked us to rollback the state machine... if (threaddata.blRollback) { threaddata.blRollback = false; Rollback(threaddata.stateRollback); blScanning = (threaddata.stateRollback >= STATE.S5); blRunning = (threaddata.stateRollback > STATE.S2); if (!blRunning) { m_scancallback(true); } ThreadToRollbackSet(); } // Callback stuff here between MSG_ENABLEDS* and MSG_DISABLEDS... else if (GetState() >= STATE.S5) { m_scancallback(false); blScanning = true; } // We're done scanning... else { blScanning = false; } // Tag the command as complete... m_twaincommand.Complete(lIndex, threaddata); // Go back to the top... continue; } // Otherwise, directly issue the command... switch (threaddata.dat) { // Unrecognized DAT... default: if (m_state < STATE.S4) { threaddata.sts = DsmEntryNullDest(threaddata.dg, threaddata.dat, threaddata.msg, threaddata.twmemref); } else { threaddata.sts = DsmEntry(threaddata.dg, threaddata.dat, threaddata.msg, threaddata.twmemref); } break; // Audio file xfer... case DAT.AUDIOFILEXFER: threaddata.sts = DatAudiofilexfer(threaddata.dg, threaddata.msg); break; // Audio info... case DAT.AUDIOINFO: threaddata.sts = DatAudioinfo(threaddata.dg, threaddata.msg, ref threaddata.twaudioinfo); break; // Audio native xfer... case DAT.AUDIONATIVEXFER: threaddata.sts = DatAudionativexfer(threaddata.dg, threaddata.msg, ref threaddata.intptrAudio); break; // Negotiation commands... case DAT.CAPABILITY: threaddata.sts = DatCapability(threaddata.dg, threaddata.msg, ref threaddata.twcapability); break; // CIE color... case DAT.CIECOLOR: threaddata.sts = DatCiecolor(threaddata.dg, threaddata.msg, ref threaddata.twciecolor); break; // Snapshots... case DAT.CUSTOMDSDATA: threaddata.sts = DatCustomdsdata(threaddata.dg, threaddata.msg, ref threaddata.twcustomdsdata); break; // Functions... case DAT.ENTRYPOINT: threaddata.sts = DatEntrypoint(threaddata.dg, threaddata.msg, ref threaddata.twentrypoint); break; // Image meta data... case DAT.EXTIMAGEINFO: threaddata.sts = DatExtimageinfo(threaddata.dg, threaddata.msg, ref threaddata.twextimageinfo); break; // Filesystem... case DAT.FILESYSTEM: threaddata.sts = DatFilesystem(threaddata.dg, threaddata.msg, ref threaddata.twfilesystem); break; // Filter... case DAT.FILTER: threaddata.sts = DatFilter(threaddata.dg, threaddata.msg, ref threaddata.twfilter); break; // Grayscale... case DAT.GRAYRESPONSE: threaddata.sts = DatGrayresponse(threaddata.dg, threaddata.msg, ref threaddata.twgrayresponse); break; // ICC color profiles... case DAT.ICCPROFILE: threaddata.sts = DatIccprofile(threaddata.dg, threaddata.msg, ref threaddata.twmemory); break; // Enumerate and Open commands... case DAT.IDENTITY: threaddata.sts = DatIdentity(threaddata.dg, threaddata.msg, ref threaddata.twidentity); break; // More meta data... case DAT.IMAGEINFO: threaddata.sts = DatImageinfo(threaddata.dg, threaddata.msg, ref threaddata.twimageinfo); break; // File xfer... case DAT.IMAGEFILEXFER: threaddata.sts = DatImagefilexfer(threaddata.dg, threaddata.msg); break; // Image layout commands... case DAT.IMAGELAYOUT: threaddata.sts = DatImagelayout(threaddata.dg, threaddata.msg, ref threaddata.twimagelayout); break; // Memory file transfer (yes, we're using TW_IMAGEMEMXFER, that's okay)... case DAT.IMAGEMEMFILEXFER: threaddata.sts = DatImagememfilexfer(threaddata.dg, threaddata.msg, ref threaddata.twimagememxfer); break; // Memory transfer... case DAT.IMAGEMEMXFER: threaddata.sts = DatImagememxfer(threaddata.dg, threaddata.msg, ref threaddata.twimagememxfer); break; // Native transfer... case DAT.IMAGENATIVEXFER: if (threaddata.blUseBitmapHandle) { threaddata.sts = DatImagenativexferHandle(threaddata.dg, threaddata.msg, ref threaddata.intptrBitmap); } else { threaddata.sts = DatImagenativexfer(threaddata.dg, threaddata.msg, ref threaddata.bitmap); } break; // JPEG compression... case DAT.JPEGCOMPRESSION: threaddata.sts = DatJpegcompression(threaddata.dg, threaddata.msg, ref threaddata.twjpegcompression); break; // Metrics... case DAT.METRICS: threaddata.sts = DatMetrics(threaddata.dg, threaddata.msg, ref threaddata.twmetrics); break; // Palette8... case DAT.PALETTE8: threaddata.sts = DatPalette8(threaddata.dg, threaddata.msg, ref threaddata.twpalette8); break; // DSM commands... case DAT.PARENT: threaddata.sts = DatParent(threaddata.dg, threaddata.msg, ref threaddata.intptrHwnd); break; // Raw commands... case DAT.PASSTHRU: threaddata.sts = DatPassthru(threaddata.dg, threaddata.msg, ref threaddata.twpassthru); break; // Pending transfers... case DAT.PENDINGXFERS: threaddata.sts = DatPendingxfers(threaddata.dg, threaddata.msg, ref threaddata.twpendingxfers); break; // RGB... case DAT.RGBRESPONSE: threaddata.sts = DatRgbresponse(threaddata.dg, threaddata.msg, ref threaddata.twrgbresponse); break; // Setup file transfer... case DAT.SETUPFILEXFER: threaddata.sts = DatSetupfilexfer(threaddata.dg, threaddata.msg, ref threaddata.twsetupfilexfer); break; // Get memory info... case DAT.SETUPMEMXFER: threaddata.sts = DatSetupmemxfer(threaddata.dg, threaddata.msg, ref threaddata.twsetupmemxfer); break; // Status... case DAT.STATUS: threaddata.sts = DatStatus(threaddata.dg, threaddata.msg, ref threaddata.twstatus); break; // Status text... case DAT.STATUSUTF8: threaddata.sts = DatStatusutf8(threaddata.dg, threaddata.msg, ref threaddata.twstatusutf8); break; // TWAIN Direct... case DAT.TWAINDIRECT: threaddata.sts = DatTwaindirect(threaddata.dg, threaddata.msg, ref threaddata.twtwaindirect); break; // Scan and GUI commands... case DAT.USERINTERFACE: threaddata.sts = DatUserinterface(threaddata.dg, threaddata.msg, ref threaddata.twuserinterface); if (threaddata.sts == STS.SUCCESS) { if ((threaddata.dg == DG.CONTROL) && (threaddata.dat == DAT.USERINTERFACE) && (threaddata.msg == MSG.DISABLEDS)) { blScanning = false; } else if ((threaddata.dg == DG.CONTROL) && (threaddata.dat == DAT.USERINTERFACE) && (threaddata.msg == MSG.DISABLEDS)) { if (threaddata.twuserinterface.ShowUI == 0) { blScanning = true; } } } break; // Transfer group... case DAT.XFERGROUP: threaddata.sts = DatXferGroup(threaddata.dg, threaddata.msg, ref threaddata.twuint32); break; } // Report to the caller that we're done, and loop back up for another... m_twaincommand.Complete(lIndex, threaddata); ThreadToCallerSet(); } // Some insurance to make sure we loosen up the caller... m_scancallback(true); ThreadToCallerSet(); return; } /// /// Use an event message to set the appropriate flags... /// /// Message to process private void ProcessEvent(MSG a_msg) { switch (a_msg) { // Do nothing... default: break; // If we're in state 5, then go to state 6... case MSG.XFERREADY: if (m_blAcceptXferReady) { // Protect us from driver's that spam this event... m_blAcceptXferReady = false; // We're still processing DAT_USERINTERFACE, that's a kick the // teeth. We can't wait for it here, so launch a thread to wait // for it to finish, so we can go to the next state as soon as // it's done... if (m_blRunningDatUserinterface) { m_threadRunningDatUserinterface = new Thread(RunningDatUserinterface); m_threadRunningDatUserinterface.Start(); return; } // Change our state... m_state = STATE.S6; m_blIsMsgxferready = true; CallerToThreadSet(); // Kick off the scan engine... if (m_scancallback != null) { m_scancallback(false); } } break; // The cancel button was pressed... case MSG.CLOSEDSREQ: m_blIsMsgclosedsreq = true; CallerToThreadSet(); if (m_scancallback != null) { m_scancallback(false); } break; // The OK button was pressed... case MSG.CLOSEDSOK: m_blIsMsgclosedsok = true; CallerToThreadSet(); if (m_scancallback != null) { m_scancallback(false); } break; // A device event arrived... case MSG.DEVICEEVENT: m_blIsMsgdeviceevent = true; CallerToThreadSet(); break; } } /// /// As long as DAT_USERINTERFACE is running we'll spin here... /// private void RunningDatUserinterface() { // Wait until something kicks us out... while ((m_state >= STATE.S4) && m_blRunningDatUserinterface) { Thread.Sleep(20); } // If we never made it to state 5, then bail... if (m_state < STATE.S5) { return; } // Bump up our state... m_state = STATE.S6; m_blIsMsgxferready = true; CallerToThreadSet(); // Kick off the scan engine... if (m_scancallback != null) { m_scancallback(false); } } /// /// TWAIN needs help, if we want it to run stuff in our main /// UI thread... /// /// the code to run private void RunInUiThread(Action a_action) { m_runinuithreaddelegate(a_action); } /// /// The caller is asking the thread to wake-up... /// private void CallerToThreadSet() { m_autoreseteventCaller.Set(); } /// /// The thread is waiting for the caller to wake it... /// private bool CallerToThreadWaitOne() { return (m_autoreseteventCaller.WaitOne()); } /// /// The common start to every capability csv... /// /// Capability number /// Container /// Data type /// private CSV Common(CAP a_cap, TWON a_twon, TWTY a_twty) { CSV csv = new CSV(); // Add the capability... string szCap = a_cap.ToString(); if (!szCap.Contains("_")) { szCap = "0x" + ((ushort)a_cap).ToString("X"); } // Build the CSV... csv.Add(szCap); csv.Add("TWON_" + a_twon); csv.Add("TWTY_" + a_twty); // And return it... return (csv); } /// /// Has a device event arrived? Make sure to clear it, because /// we can get many of these. We don't have to worry about a /// race condition, because the caller is expected to drain the /// driver of all events. /// /// True if a device event is pending private bool IsMsgDeviceEvent() { if (m_blIsMsgdeviceevent) { m_blIsMsgdeviceevent = false; return (true); } return (false); } /// /// The thread is asking the caller to wake-up... /// private void ThreadToCallerSet() { m_autoreseteventThread.Set(); } /// /// The caller is waiting for the thread to wake it... /// /// Result of the wait private bool ThreadToCallerWaitOne() { return (m_autoreseteventThread.WaitOne()); } /// /// The thread is asking the rollback to wake-up... /// private void ThreadToRollbackSet() { m_autoreseteventRollback.Set(); } /// /// The rollback is waiting for the thread to wake it... /// /// Result of the wait private bool ThreadToRollbackWaitOne() { return (m_autoreseteventRollback.WaitOne()); } /// /// Automatically collect the condition code for TWRC_FAILURE's... /// /// The return code from the last operation /// The return code from the last operation /// The final statue return private STS AutoDatStatus(STS a_sts) { STS sts; TW_STATUS twstatus = new TW_STATUS(); // Automatic system is off, or the status is not TWRC_FAILURE, so just return the status we got... if (!m_blAutoDatStatus || (a_sts != STS.FAILURE)) { return (a_sts); } // Windows... if (ms_platform == Platform.WINDOWS) { // Issue the command... try { if (m_blUseLegacyDSM) { if (GetState() <= STATE.S3) { sts = (STS)NativeMethods.WindowsTwain32DsmEntryStatusState3(ref m_twidentitylegacyApp, IntPtr.Zero, DG.CONTROL, DAT.STATUS, MSG.GET, ref twstatus); } else { sts = (STS)NativeMethods.WindowsTwain32DsmEntryStatus(ref m_twidentitylegacyApp, ref m_twidentitylegacyDs, DG.CONTROL, DAT.STATUS, MSG.GET, ref twstatus); } } else { if (GetState() <= STATE.S3) { sts = (STS)NativeMethods.WindowsTwaindsmDsmEntryStatusState3(ref m_twidentitylegacyApp, IntPtr.Zero, DG.CONTROL, DAT.STATUS, MSG.GET, ref twstatus); } else { sts = (STS)NativeMethods.WindowsTwaindsmDsmEntryStatus(ref m_twidentitylegacyApp, ref m_twidentitylegacyDs, DG.CONTROL, DAT.STATUS, MSG.GET, ref twstatus); } } } catch (Exception exception) { // The driver crashed... Log.Error("crash - " + exception.Message); TWAINWorkingGroup.Log.Error("Driver crash..."); return (STS.BUMMER); } } // Linux... else if (ms_platform == Platform.LINUX) { // Issue the command... try { if (m_blFoundLatestDsm64 && (m_linuxdsm == LinuxDsm.IsLatestDsm)) { if (GetState() <= STATE.S3) { sts = (STS)NativeMethods.Linux64DsmEntryStatusState3(ref m_twidentitylegacyApp, IntPtr.Zero, DG.CONTROL, DAT.STATUS, MSG.GET, ref twstatus); } else { sts = (STS)NativeMethods.Linux64DsmEntryStatus(ref m_twidentitylegacyApp, ref m_twidentitylegacyDs, DG.CONTROL, DAT.STATUS, MSG.GET, ref twstatus); } } else if (m_blFoundLatestDsm && (m_linuxdsm == LinuxDsm.IsLatestDsm)) { if (GetState() <= STATE.S3) { sts = (STS)NativeMethods.LinuxDsmEntryStatusState3(ref m_twidentitylegacyApp, IntPtr.Zero, DG.CONTROL, DAT.STATUS, MSG.GET, ref twstatus); } else { sts = (STS)NativeMethods.LinuxDsmEntryStatus(ref m_twidentitylegacyApp, ref m_twidentitylegacyDs, DG.CONTROL, DAT.STATUS, MSG.GET, ref twstatus); } } else if (m_blFound020302Dsm64bit && (m_linuxdsm == LinuxDsm.Is020302Dsm64bit)) { if (GetState() <= STATE.S3) { sts = (STS)NativeMethods.Linux020302Dsm64bitEntryStatusState3(ref m_twidentityApp, IntPtr.Zero, DG.CONTROL, DAT.STATUS, MSG.GET, ref twstatus); } else { sts = (STS)NativeMethods.Linux020302Dsm64bitEntryStatus(ref m_twidentityApp, ref m_twidentityDs, DG.CONTROL, DAT.STATUS, MSG.GET, ref twstatus); } } else { Log.Error("apparently we don't have a DSM..."); sts = STS.BUMMER; } } catch (Exception exception) { // The driver crashed... Log.Error("crash - " + exception.Message); TWAINWorkingGroup.Log.Error("Driver crash..."); return (STS.BUMMER); } } // Mac OS X, which has to be different... else if (ms_platform == Platform.MACOSX) { // Issue the command... try { if (GetState() <= STATE.S3) { sts = (STS)NativeMethods.MacosxTwainDsmEntryStatusState3(ref m_twidentitymacosxApp, IntPtr.Zero, DG.CONTROL, DAT.STATUS, MSG.GET, ref twstatus); } else { sts = (STS)NativeMethods.MacosxTwainDsmEntryStatus(ref m_twidentitymacosxApp, ref m_twidentitymacosxDs, DG.CONTROL, DAT.STATUS, MSG.GET, ref twstatus); } } catch (Exception exception) { // The driver crashed... Log.Error("crash - " + exception.Message); TWAINWorkingGroup.Log.Error("Driver crash..."); return (STS.BUMMER); } } // Uh-oh... else { TWAINWorkingGroup.Log.Assert("Unsupported platform..." + ms_platform); return (STS.BUMMER); } // Uh-oh, the status call failed... if (sts != STS.SUCCESS) { return (a_sts); } // All done... return ((STS)(STSCC + twstatus.ConditionCode)); } /// /// 32-bit or 64-bit... /// /// Number of bits in the machine word for this process public static int GetMachineWordBitSize() { return ((IntPtr.Size == 4) ? 32 : 64); } /// /// Quick access to our platform id... /// /// public static Platform GetPlatform() { // First pass... if (ms_blFirstPassGetPlatform) { // Dont'c come in here again... ms_blFirstPassGetPlatform = false; // We're Windows... if (Environment.OSVersion.ToString().Contains("Microsoft Windows")) { ms_platform = Platform.WINDOWS; ms_processor = (GetMachineWordBitSize() == 64) ? Processor.X86_64 : Processor.X86; } // We're Mac OS X (this has to come before LINUX!!!)... else if (Directory.Exists("/Library/Application Support")) { ms_platform = Platform.MACOSX; ms_processor = (GetMachineWordBitSize() == 64) ? Processor.X86_64 : Processor.X86; } // We're Linux... else if (Environment.OSVersion.ToString().Contains("Unix")) { string szProcessor = ""; ms_platform = Platform.LINUX; try { Process process = new Process() { StartInfo = new ProcessStartInfo() { FileName = "uname", Arguments = "-m", UseShellExecute = false, RedirectStandardOutput = true, CreateNoWindow = true } }; process.Start(); process.WaitForExit(); szProcessor = process.StandardOutput.ReadToEnd(); process.Close(); } catch { Console.Out.WriteLine("Oh dear, this isn't good...where's uname?"); } if (szProcessor.Contains("mips64")) { ms_processor = Processor.MIPS64EL; } else { ms_processor = (GetMachineWordBitSize() == 64) ? Processor.X86_64 : Processor.X86; } } // We have a problem, Log will throw for us... else { ms_platform = Platform.UNKNOWN; ms_processor = Processor.UNKNOWN; TWAINWorkingGroup.Log.Assert("Unsupported platform..." + ms_platform); } } // All done... return (ms_platform); } /// /// Quick access to our processor id... /// /// public static Processor GetProcessor() { // First pass... if (ms_blFirstPassGetPlatform) { GetPlatform(); } // All done... return (ms_processor); } /// /// Convert the contents of a capability to a string that we can show in /// our simple GUI... /// /// Data type /// Pointer to the data /// Index of the item in the data /// Data in CSV form [PermissionSet(SecurityAction.LinkDemand, Name = "FullTrust", Unrestricted = false)] public string GetIndexedItem(TW_CAPABILITY a_twcapability, TWTY a_twty, IntPtr a_intptr, int a_iIndex) { IntPtr intptr; // Index by type... switch (a_twty) { default: return ("Get Capability: (unrecognized item type)..." + a_twty); case TWTY.INT8: { intptr = (IntPtr)((ulong)a_intptr + (ulong)(1 * a_iIndex)); sbyte i8Value = (sbyte)Marshal.PtrToStructure(intptr, typeof(sbyte)); return (i8Value.ToString()); } case TWTY.INT16: { intptr = (IntPtr)((ulong)a_intptr + (ulong)(2 * a_iIndex)); short i16Value = (short)Marshal.PtrToStructure(intptr, typeof(short)); return (i16Value.ToString()); } case TWTY.INT32: { intptr = (IntPtr)((ulong)a_intptr + (ulong)(4 * a_iIndex)); int i32Value = (int)Marshal.PtrToStructure(intptr, typeof(int)); return (i32Value.ToString()); } case TWTY.UINT8: { intptr = (IntPtr)((ulong)a_intptr + (ulong)(1 * a_iIndex)); byte u8Value = (byte)Marshal.PtrToStructure(intptr, typeof(byte)); return (u8Value.ToString()); } case TWTY.BOOL: case TWTY.UINT16: { intptr = (IntPtr)((ulong)a_intptr + (ulong)(2 * a_iIndex)); ushort u16Value = (ushort)Marshal.PtrToStructure(intptr, typeof(ushort)); return (u16Value.ToString()); } case TWTY.UINT32: { intptr = (IntPtr)((ulong)a_intptr + (ulong)(4 * a_iIndex)); uint u32Value = (uint)Marshal.PtrToStructure(intptr, typeof(uint)); return (u32Value.ToString()); } case TWTY.FIX32: { intptr = (IntPtr)((ulong)a_intptr + (ulong)(4 * a_iIndex)); TW_FIX32 twfix32 = (TW_FIX32)Marshal.PtrToStructure(intptr, typeof(TW_FIX32)); return (((double)twfix32.Whole + ((double)twfix32.Frac / 65536.0)).ToString()); } case TWTY.FRAME: { CSV csv = new CSV(); intptr = (IntPtr)((ulong)a_intptr + (ulong)(16 * a_iIndex)); TW_FRAME twframe = (TW_FRAME)Marshal.PtrToStructure(intptr, typeof(TW_FRAME)); csv.Add(((double)twframe.Left.Whole + ((double)twframe.Left.Frac / 65536.0)).ToString()); csv.Add(((double)twframe.Top.Whole + ((double)twframe.Top.Frac / 65536.0)).ToString()); csv.Add(((double)twframe.Right.Whole + ((double)twframe.Right.Frac / 65536.0)).ToString()); csv.Add(((double)twframe.Bottom.Whole + ((double)twframe.Bottom.Frac / 65536.0)).ToString()); return (csv.Get()); } case TWTY.STR32: { intptr = (IntPtr)((ulong)a_intptr + (ulong)(34 * a_iIndex)); TW_STR32 twstr32 = (TW_STR32)Marshal.PtrToStructure(intptr, typeof(TW_STR32)); return (twstr32.Get()); } case TWTY.STR64: { intptr = (IntPtr)((ulong)a_intptr + (ulong)(66 * a_iIndex)); TW_STR64 twstr64 = (TW_STR64)Marshal.PtrToStructure(intptr, typeof(TW_STR64)); return (twstr64.Get()); } case TWTY.STR128: { intptr = (IntPtr)((ulong)a_intptr + (ulong)(130 * a_iIndex)); TW_STR128 twstr128 = (TW_STR128)Marshal.PtrToStructure(intptr, typeof(TW_STR128)); return (twstr128.Get()); } case TWTY.STR255: { intptr = (IntPtr)((ulong)a_intptr + (ulong)(256 * a_iIndex)); TW_STR255 twstr255 = (TW_STR255)Marshal.PtrToStructure(intptr, typeof(TW_STR255)); return (twstr255.Get()); } } } /// /// Convert the value of a string into a capability... /// /// All info on the capability /// Data type /// Point to the data /// Index for item in the data /// CSV value to be used to set the data /// Empty string or an error string [PermissionSet(SecurityAction.LinkDemand, Name = "FullTrust", Unrestricted = false)] public string SetIndexedItem(TW_CAPABILITY a_twcapability, TWTY a_twty, IntPtr a_intptr, int a_iIndex, string a_szValue) { IntPtr intptr; // Index by type... switch (a_twty) { default: return ("Set Capability: (unrecognized item type)..." + a_twty); case TWTY.INT8: { // We do this to make sure the entire Item value is overwritten... if (a_twcapability.ConType == TWON.ONEVALUE) { int i32Value = sbyte.Parse(CvtCapValueFromEnum(a_twcapability.Cap, a_szValue)); Marshal.StructureToPtr(i32Value, a_intptr, true); return (""); } // These items have to be packed on the type sizes... else { sbyte i8Value = sbyte.Parse(CvtCapValueFromEnum(a_twcapability.Cap, a_szValue)); intptr = (IntPtr)((ulong)a_intptr + (ulong)(1 * a_iIndex)); Marshal.StructureToPtr(i8Value, intptr, true); return (""); } } case TWTY.INT16: { // We use i32Value to make sure the entire Item value is overwritten... if (a_twcapability.ConType == TWON.ONEVALUE) { int i32Value = short.Parse(CvtCapValueFromEnum(a_twcapability.Cap, a_szValue)); Marshal.StructureToPtr(i32Value, a_intptr, true); return (""); } // These items have to be packed on the type sizes... else { short i16Value = short.Parse(CvtCapValueFromEnum(a_twcapability.Cap, a_szValue)); intptr = (IntPtr)((ulong)a_intptr + (ulong)(2 * a_iIndex)); Marshal.StructureToPtr(i16Value, intptr, true); return (""); } } case TWTY.INT32: { // Entire value will always be overwritten, so we don't have to get fancy... int i32Value = int.Parse(CvtCapValueFromEnum(a_twcapability.Cap, a_szValue)); intptr = (IntPtr)((ulong)a_intptr + (ulong)(4 * a_iIndex)); Marshal.StructureToPtr(i32Value, intptr, true); return (""); } case TWTY.UINT8: { // We use u32Value to make sure the entire Item value is overwritten... if (a_twcapability.ConType == TWON.ONEVALUE) { uint u32Value = byte.Parse(CvtCapValueFromEnum(a_twcapability.Cap, a_szValue)); Marshal.StructureToPtr(u32Value, a_intptr, true); return (""); } // These items have to be packed on the type sizes... else { byte u8Value = byte.Parse(CvtCapValueFromEnum(a_twcapability.Cap, a_szValue)); intptr = (IntPtr)((ulong)a_intptr + (ulong)(1 * a_iIndex)); Marshal.StructureToPtr(u8Value, intptr, true); return (""); } } case TWTY.BOOL: case TWTY.UINT16: { // We use u32Value to make sure the entire Item value is overwritten... if (a_twcapability.ConType == TWON.ONEVALUE) { uint u32Value = ushort.Parse(CvtCapValueFromEnum(a_twcapability.Cap, a_szValue)); Marshal.StructureToPtr(u32Value, a_intptr, true); return (""); } else { ushort u16Value = ushort.Parse(CvtCapValueFromEnum(a_twcapability.Cap, a_szValue)); intptr = (IntPtr)((ulong)a_intptr + (ulong)(2 * a_iIndex)); Marshal.StructureToPtr(u16Value, intptr, true); return (""); } } case TWTY.UINT32: { // Entire value will always be overwritten, so we don't have to get fancy... uint u32Value = uint.Parse(CvtCapValueFromEnum(a_twcapability.Cap, a_szValue)); intptr = (IntPtr)((ulong)a_intptr + (ulong)(4 * a_iIndex)); Marshal.StructureToPtr(u32Value, intptr, true); return (""); } case TWTY.FIX32: { // Entire value will always be overwritten, so we don't have to get fancy... TW_FIX32 twfix32 = default(TW_FIX32); twfix32.Whole = (short)Convert.ToDouble(a_szValue); twfix32.Frac = (ushort)((Convert.ToDouble(a_szValue) - (double)twfix32.Whole) * 65536.0); intptr = (IntPtr)((ulong)a_intptr + (ulong)(4 * a_iIndex)); Marshal.StructureToPtr(twfix32, intptr, true); return (""); } case TWTY.FRAME: { TW_FRAME twframe = default(TW_FRAME); string[] asz = CSV.Parse(a_szValue); twframe.Left.Whole = (short)Convert.ToDouble(asz[0]); twframe.Left.Frac = (ushort)((Convert.ToDouble(asz[0]) - (double)twframe.Left.Whole) * 65536.0); twframe.Top.Whole = (short)Convert.ToDouble(asz[1]); twframe.Top.Frac = (ushort)((Convert.ToDouble(asz[1]) - (double)twframe.Top.Whole) * 65536.0); twframe.Right.Whole = (short)Convert.ToDouble(asz[2]); twframe.Right.Frac = (ushort)((Convert.ToDouble(asz[2]) - (double)twframe.Right.Whole) * 65536.0); twframe.Bottom.Whole = (short)Convert.ToDouble(asz[3]); twframe.Bottom.Frac = (ushort)((Convert.ToDouble(asz[3]) - (double)twframe.Bottom.Whole) * 65536.0); intptr = (IntPtr)((ulong)a_intptr + (ulong)(16 * a_iIndex)); Marshal.StructureToPtr(twframe, intptr, true); return (""); } case TWTY.STR32: { TW_STR32 twstr32 = default(TW_STR32); twstr32.Set(a_szValue); intptr = (IntPtr)((ulong)a_intptr + (ulong)(34 * a_iIndex)); Marshal.StructureToPtr(twstr32, intptr, true); return (""); } case TWTY.STR64: { TW_STR64 twstr64 = default(TW_STR64); twstr64.Set(a_szValue); intptr = (IntPtr)((ulong)a_intptr + (ulong)(66 * a_iIndex)); Marshal.StructureToPtr(twstr64, intptr, true); return (""); } case TWTY.STR128: { TW_STR128 twstr128 = default(TW_STR128); twstr128.Set(a_szValue); intptr = (IntPtr)((ulong)a_intptr + (ulong)(130 * a_iIndex)); Marshal.StructureToPtr(twstr128, intptr, true); return (""); } case TWTY.STR255: { TW_STR255 twstr255 = default(TW_STR255); twstr255.Set(a_szValue); intptr = (IntPtr)((ulong)a_intptr + (ulong)(256 * a_iIndex)); Marshal.StructureToPtr(twstr255, intptr, true); return (""); } } } /// /// Convert strings into a range... /// /// Data type /// Pointer to the data /// List of strings /// Empty string or an error string [PermissionSet(SecurityAction.LinkDemand, Name = "FullTrust", Unrestricted = false)] public string SetRangeItem(TWTY a_twty, IntPtr a_intptr, string[] a_asz) { TW_RANGE twrange = default(TW_RANGE); TW_RANGE_MACOSX twrangemacosx = default(TW_RANGE_MACOSX); TW_RANGE_LINUX64 twrangelinux64 = default(TW_RANGE_LINUX64); TW_RANGE_FIX32 twrangefix32 = default(TW_RANGE_FIX32); TW_RANGE_FIX32_MACOSX twrangefix32macosx = default(TW_RANGE_FIX32_MACOSX); // Index by type... switch (a_twty) { default: return ("Set Capability: (unrecognized item type)..." + a_twty); case TWTY.INT8: { if (ms_platform == Platform.MACOSX) { twrangemacosx.ItemType = (uint)a_twty; twrangemacosx.MinValue = (uint)sbyte.Parse(a_asz[3]); twrangemacosx.MaxValue = (uint)sbyte.Parse(a_asz[4]); twrangemacosx.StepSize = (uint)sbyte.Parse(a_asz[5]); twrangemacosx.DefaultValue = (uint)sbyte.Parse(a_asz[6]); twrangemacosx.CurrentValue = (uint)sbyte.Parse(a_asz[7]); Marshal.StructureToPtr(twrangemacosx, a_intptr, true); } else if ((m_linuxdsm == LinuxDsm.Unknown) || (m_linuxdsm == LinuxDsm.IsLatestDsm)) { twrange.ItemType = a_twty; twrange.MinValue = (uint)sbyte.Parse(a_asz[3]); twrange.MaxValue = (uint)sbyte.Parse(a_asz[4]); twrange.StepSize = (uint)sbyte.Parse(a_asz[5]); twrange.DefaultValue = (uint)sbyte.Parse(a_asz[6]); twrange.CurrentValue = (uint)sbyte.Parse(a_asz[7]); Marshal.StructureToPtr(twrange, a_intptr, true); } else { twrangelinux64.ItemType = a_twty; twrangelinux64.MinValue = (uint)sbyte.Parse(a_asz[3]); twrangelinux64.MaxValue = (uint)sbyte.Parse(a_asz[4]); twrangelinux64.StepSize = (uint)sbyte.Parse(a_asz[5]); twrangelinux64.DefaultValue = (uint)sbyte.Parse(a_asz[6]); twrangelinux64.CurrentValue = (uint)sbyte.Parse(a_asz[7]); Marshal.StructureToPtr(twrangelinux64, a_intptr, true); } return (""); } case TWTY.INT16: { if (ms_platform == Platform.MACOSX) { twrangemacosx.ItemType = (uint)a_twty; twrangemacosx.MinValue = (uint)short.Parse(a_asz[3]); twrangemacosx.MaxValue = (uint)short.Parse(a_asz[4]); twrangemacosx.StepSize = (uint)short.Parse(a_asz[5]); twrangemacosx.DefaultValue = (uint)short.Parse(a_asz[6]); twrangemacosx.CurrentValue = (uint)short.Parse(a_asz[7]); Marshal.StructureToPtr(twrangemacosx, a_intptr, true); } else if ((m_linuxdsm == LinuxDsm.Unknown) || (m_linuxdsm == LinuxDsm.IsLatestDsm)) { twrange.ItemType = a_twty; twrange.MinValue = (uint)short.Parse(a_asz[3]); twrange.MaxValue = (uint)short.Parse(a_asz[4]); twrange.StepSize = (uint)short.Parse(a_asz[5]); twrange.DefaultValue = (uint)short.Parse(a_asz[6]); twrange.CurrentValue = (uint)short.Parse(a_asz[7]); Marshal.StructureToPtr(twrange, a_intptr, true); } else { twrangelinux64.ItemType = a_twty; twrangelinux64.MinValue = (uint)short.Parse(a_asz[3]); twrangelinux64.MaxValue = (uint)short.Parse(a_asz[4]); twrangelinux64.StepSize = (uint)short.Parse(a_asz[5]); twrangelinux64.DefaultValue = (uint)short.Parse(a_asz[6]); twrangelinux64.CurrentValue = (uint)short.Parse(a_asz[7]); Marshal.StructureToPtr(twrangelinux64, a_intptr, true); } return (""); } case TWTY.INT32: { if (ms_platform == Platform.MACOSX) { twrangemacosx.ItemType = (uint)a_twty; twrangemacosx.MinValue = (uint)int.Parse(a_asz[3]); twrangemacosx.MaxValue = (uint)int.Parse(a_asz[4]); twrangemacosx.StepSize = (uint)int.Parse(a_asz[5]); twrangemacosx.DefaultValue = (uint)int.Parse(a_asz[6]); twrangemacosx.CurrentValue = (uint)int.Parse(a_asz[7]); Marshal.StructureToPtr(twrangemacosx, a_intptr, true); } else if ((m_linuxdsm == LinuxDsm.Unknown) || (m_linuxdsm == LinuxDsm.IsLatestDsm)) { twrange.ItemType = a_twty; twrange.MinValue = (uint)int.Parse(a_asz[3]); twrange.MaxValue = (uint)int.Parse(a_asz[4]); twrange.StepSize = (uint)int.Parse(a_asz[5]); twrange.DefaultValue = (uint)int.Parse(a_asz[6]); twrange.CurrentValue = (uint)int.Parse(a_asz[7]); Marshal.StructureToPtr(twrange, a_intptr, true); } else { twrangelinux64.ItemType = a_twty; twrangelinux64.MinValue = (uint)int.Parse(a_asz[3]); twrangelinux64.MaxValue = (uint)int.Parse(a_asz[4]); twrangelinux64.StepSize = (uint)int.Parse(a_asz[5]); twrangelinux64.DefaultValue = (uint)int.Parse(a_asz[6]); twrangelinux64.CurrentValue = (uint)int.Parse(a_asz[7]); Marshal.StructureToPtr(twrangelinux64, a_intptr, true); } return (""); } case TWTY.UINT8: { if (ms_platform == Platform.MACOSX) { twrangemacosx.ItemType = (uint)a_twty; twrangemacosx.MinValue = (uint)byte.Parse(a_asz[3]); twrangemacosx.MaxValue = (uint)byte.Parse(a_asz[4]); twrangemacosx.StepSize = (uint)byte.Parse(a_asz[5]); twrangemacosx.DefaultValue = (uint)byte.Parse(a_asz[6]); twrangemacosx.CurrentValue = (uint)byte.Parse(a_asz[7]); Marshal.StructureToPtr(twrangemacosx, a_intptr, true); } else if ((m_linuxdsm == LinuxDsm.Unknown) || (m_linuxdsm == LinuxDsm.IsLatestDsm)) { twrange.ItemType = a_twty; twrange.MinValue = (uint)byte.Parse(a_asz[3]); twrange.MaxValue = (uint)byte.Parse(a_asz[4]); twrange.StepSize = (uint)byte.Parse(a_asz[5]); twrange.DefaultValue = (uint)byte.Parse(a_asz[6]); twrange.CurrentValue = (uint)byte.Parse(a_asz[7]); Marshal.StructureToPtr(twrange, a_intptr, true); } else { twrangelinux64.ItemType = a_twty; twrangelinux64.MinValue = (uint)byte.Parse(a_asz[3]); twrangelinux64.MaxValue = (uint)byte.Parse(a_asz[4]); twrangelinux64.StepSize = (uint)byte.Parse(a_asz[5]); twrangelinux64.DefaultValue = (uint)byte.Parse(a_asz[6]); twrangelinux64.CurrentValue = (uint)byte.Parse(a_asz[7]); Marshal.StructureToPtr(twrangelinux64, a_intptr, true); } return (""); } case TWTY.BOOL: case TWTY.UINT16: { if (ms_platform == Platform.MACOSX) { twrangemacosx.ItemType = (uint)a_twty; twrangemacosx.MinValue = (uint)ushort.Parse(a_asz[3]); twrangemacosx.MaxValue = (uint)ushort.Parse(a_asz[4]); twrangemacosx.StepSize = (uint)ushort.Parse(a_asz[5]); twrangemacosx.DefaultValue = (uint)ushort.Parse(a_asz[6]); twrangemacosx.CurrentValue = (uint)ushort.Parse(a_asz[7]); Marshal.StructureToPtr(twrangemacosx, a_intptr, true); } else if ((m_linuxdsm == LinuxDsm.Unknown) || (m_linuxdsm == LinuxDsm.IsLatestDsm)) { twrange.ItemType = a_twty; twrange.MinValue = (uint)ushort.Parse(a_asz[3]); twrange.MaxValue = (uint)ushort.Parse(a_asz[4]); twrange.StepSize = (uint)ushort.Parse(a_asz[5]); twrange.DefaultValue = (uint)ushort.Parse(a_asz[6]); twrange.CurrentValue = (uint)ushort.Parse(a_asz[7]); Marshal.StructureToPtr(twrange, a_intptr, true); } else { twrangelinux64.ItemType = a_twty; twrangelinux64.MinValue = (uint)ushort.Parse(a_asz[3]); twrangelinux64.MaxValue = (uint)ushort.Parse(a_asz[4]); twrangelinux64.StepSize = (uint)ushort.Parse(a_asz[5]); twrangelinux64.DefaultValue = (uint)ushort.Parse(a_asz[6]); twrangelinux64.CurrentValue = (uint)ushort.Parse(a_asz[7]); Marshal.StructureToPtr(twrangelinux64, a_intptr, true); } return (""); } case TWTY.UINT32: { if (ms_platform == Platform.MACOSX) { twrangemacosx.ItemType = (uint)a_twty; twrangemacosx.MinValue = uint.Parse(a_asz[3]); twrangemacosx.MaxValue = uint.Parse(a_asz[4]); twrangemacosx.StepSize = uint.Parse(a_asz[5]); twrangemacosx.DefaultValue = uint.Parse(a_asz[6]); twrangemacosx.CurrentValue = uint.Parse(a_asz[7]); Marshal.StructureToPtr(twrangemacosx, a_intptr, true); } else if ((m_linuxdsm == LinuxDsm.Unknown) || (m_linuxdsm == LinuxDsm.IsLatestDsm)) { twrange.ItemType = a_twty; twrange.MinValue = uint.Parse(a_asz[3]); twrange.MaxValue = uint.Parse(a_asz[4]); twrange.StepSize = uint.Parse(a_asz[5]); twrange.DefaultValue = uint.Parse(a_asz[6]); twrange.CurrentValue = uint.Parse(a_asz[7]); Marshal.StructureToPtr(twrange, a_intptr, true); } else { twrangelinux64.ItemType = a_twty; twrangelinux64.MinValue = uint.Parse(a_asz[3]); twrangelinux64.MaxValue = uint.Parse(a_asz[4]); twrangelinux64.StepSize = uint.Parse(a_asz[5]); twrangelinux64.DefaultValue = uint.Parse(a_asz[6]); twrangelinux64.CurrentValue = uint.Parse(a_asz[7]); Marshal.StructureToPtr(twrangelinux64, a_intptr, true); } return (""); } case TWTY.FIX32: { double dMinValue = Convert.ToDouble(a_asz[3]); double dMaxValue = Convert.ToDouble(a_asz[4]); double dStepSize = Convert.ToDouble(a_asz[5]); double dDefaultValue = Convert.ToDouble(a_asz[6]); double dCurrentValue = Convert.ToDouble(a_asz[7]); if (ms_platform == Platform.MACOSX) { twrangefix32macosx.ItemType = (uint)a_twty; twrangefix32macosx.MinValue.Whole = (short)dMinValue; twrangefix32macosx.MinValue.Frac = (ushort)((dMinValue - (double)twrangefix32macosx.MinValue.Whole) * 65536.0); twrangefix32macosx.MaxValue.Whole = (short)dMaxValue; twrangefix32macosx.MaxValue.Frac = (ushort)((dMaxValue - (double)twrangefix32macosx.MaxValue.Whole) * 65536.0); twrangefix32macosx.StepSize.Whole = (short)dStepSize; twrangefix32macosx.StepSize.Frac = (ushort)((dStepSize - (double)twrangefix32macosx.StepSize.Whole) * 65536.0); twrangefix32macosx.DefaultValue.Whole = (short)dDefaultValue; twrangefix32macosx.DefaultValue.Frac = (ushort)((dDefaultValue - (double)twrangefix32macosx.DefaultValue.Whole) * 65536.0); twrangefix32macosx.CurrentValue.Whole = (short)dCurrentValue; twrangefix32macosx.CurrentValue.Frac = (ushort)((dCurrentValue - (double)twrangefix32macosx.CurrentValue.Whole) * 65536.0); Marshal.StructureToPtr(twrangefix32macosx, a_intptr, true); } else { twrangefix32.ItemType = a_twty; twrangefix32.MinValue.Whole = (short)dMinValue; twrangefix32.MinValue.Frac = (ushort)((dMinValue - (double)twrangefix32.MinValue.Whole) * 65536.0); twrangefix32.MaxValue.Whole = (short)dMaxValue; twrangefix32.MaxValue.Frac = (ushort)((dMaxValue - (double)twrangefix32.MaxValue.Whole) * 65536.0); twrangefix32.StepSize.Whole = (short)dStepSize; twrangefix32.StepSize.Frac = (ushort)((dStepSize - (double)twrangefix32.StepSize.Whole) * 65536.0); twrangefix32.DefaultValue.Whole = (short)dDefaultValue; twrangefix32.DefaultValue.Frac = (ushort)((dDefaultValue - (double)twrangefix32.DefaultValue.Whole) * 65536.0); twrangefix32.CurrentValue.Whole = (short)dCurrentValue; twrangefix32.CurrentValue.Frac = (ushort)((dCurrentValue - (double)twrangefix32.CurrentValue.Whole) * 65536.0); Marshal.StructureToPtr(twrangefix32, a_intptr, true); } return (""); } } } /// /// Our callback delegate for Windows... /// /// Origin of message /// Message target /// Data group /// Data argument type /// Operation /// NULL pointer /// TWAIN status private UInt16 WindowsDsmEntryCallbackProxy ( ref TW_IDENTITY_LEGACY origin, ref TW_IDENTITY_LEGACY dest, DG dg, DAT dat, MSG msg, IntPtr twnull ) { ProcessEvent(msg); return ((UInt16)STS.SUCCESS); } /// /// Our callback delegate for Linux... /// /// Origin of message /// Message target /// Data group /// Data argument type /// Operation /// NULL pointer /// TWAIN status private UInt16 LinuxDsmEntryCallbackProxy ( ref TW_IDENTITY_LEGACY origin, ref TW_IDENTITY_LEGACY dest, DG dg, DAT dat, MSG msg, IntPtr twnull ) { ProcessEvent(msg); return ((UInt16)STS.SUCCESS); } /// /// Our callback delegate for Mac OS X... /// /// Origin of message /// Message target /// Data group /// Data argument type /// Operation /// NULL pointer /// TWAIN status private UInt16 MacosxDsmEntryCallbackProxy ( ref TW_IDENTITY_MACOSX origin, ref TW_IDENTITY_MACOSX dest, DG dg, DAT dat, MSG msg, IntPtr twnull ) { ProcessEvent(msg); return ((UInt16)STS.SUCCESS); } /// /// Get .NET 'Bitmap' object from memory DIB via stream constructor. /// This should work for most DIBs. /// /// Our operating system /// The pointer to something (presumably a BITMAP or a TIFF image) /// C# Bitmap of image private Bitmap NativeToBitmap(Platform a_platform, IntPtr a_intptrNative) { ushort u16Magic; IntPtr intptrNative; // We need the first two bytes to decide if we have a DIB or a TIFF. Don't // forget to lock the silly thing... intptrNative = DsmMemLock(a_intptrNative); u16Magic = (ushort)Marshal.PtrToStructure(intptrNative, typeof(ushort)); // Windows uses a DIB, the first usigned short is 40... if (u16Magic == 40) { byte[] bBitmap; BITMAPFILEHEADER bitmapfileheader; BITMAPINFOHEADER bitmapinfoheader; // Our incoming DIB is a bitmap info header... bitmapinfoheader = (BITMAPINFOHEADER)Marshal.PtrToStructure(intptrNative, typeof(BITMAPINFOHEADER)); // Build our file header... bitmapfileheader = new BITMAPFILEHEADER(); bitmapfileheader.bfType = 0x4D42; // "BM" bitmapfileheader.bfSize = (uint)Marshal.SizeOf(typeof(BITMAPFILEHEADER)) + bitmapinfoheader.biSize + (bitmapinfoheader.biClrUsed * 4) + bitmapinfoheader.biSizeImage; bitmapfileheader.bfOffBits = (uint)Marshal.SizeOf(typeof(BITMAPFILEHEADER)) + bitmapinfoheader.biSize + (bitmapinfoheader.biClrUsed * 4); // Copy the file header into our byte array... IntPtr intptr = Marshal.AllocHGlobal(Marshal.SizeOf(bitmapfileheader)); Marshal.StructureToPtr(bitmapfileheader, intptr, true); bBitmap = new byte[bitmapfileheader.bfSize]; Marshal.Copy(intptr, bBitmap, 0, Marshal.SizeOf(bitmapfileheader)); Marshal.FreeHGlobal(intptr); intptr = IntPtr.Zero; // Copy the rest of the DIB into our byte array...... Marshal.Copy(intptrNative, bBitmap, Marshal.SizeOf(typeof(BITMAPFILEHEADER)), (int)bitmapfileheader.bfSize - Marshal.SizeOf(typeof(BITMAPFILEHEADER))); // Now we can turn the in-memory bitmap file into a Bitmap object... MemoryStream memorystream = new MemoryStream(bBitmap); // Unfortunately the stream has to be kept with the bitmap... Bitmap bitmapStream = new Bitmap(memorystream); // So we make a copy (ick)... Bitmap bitmap; switch (bitmapinfoheader.biBitCount) { default: case 24: bitmap = bitmapStream.Clone(new Rectangle(0, 0, bitmapStream.Width, bitmapStream.Height), System.Drawing.Imaging.PixelFormat.Format24bppRgb); break; case 8: bitmap = bitmapStream.Clone(new Rectangle(0, 0, bitmapStream.Width, bitmapStream.Height), System.Drawing.Imaging.PixelFormat.Format8bppIndexed); break; case 1: bitmap = bitmapStream.Clone(new Rectangle(0, 0, bitmapStream.Width, bitmapStream.Height), System.Drawing.Imaging.PixelFormat.Format1bppIndexed); break; } // Fix the resolution... bitmap.SetResolution((int)(bitmap.HorizontalResolution + 0.5), (int)(bitmap.VerticalResolution + 0.5)); // Cleanup... //bitmapStream.Dispose(); //memorystream.Close(); bitmapStream = null; memorystream = null; bBitmap = null; // Return our bitmap... DsmMemUnlock(a_intptrNative); return (bitmap); } // Linux and Mac OS X use TIFF. We'll handle a simple Intel TIFF ("II")... else if (u16Magic == 0x4949) { int iTiffSize; ulong u64; ulong u64Pointer; ulong u64TiffHeaderSize; ulong u64TiffTagSize; byte[] abTiff; TIFFHEADER tiffheader; TIFFTAG tifftag; // Init stuff... tiffheader = new TIFFHEADER(); tifftag = new TIFFTAG(); u64TiffHeaderSize = (ulong)Marshal.SizeOf(tiffheader); u64TiffTagSize = (ulong)Marshal.SizeOf(tifftag); // Find the size of the image so we can turn it into a memory stream... iTiffSize = 0; tiffheader = (TIFFHEADER)Marshal.PtrToStructure(intptrNative, typeof(TIFFHEADER)); for (u64 = 0; u64 < 999; u64++) { u64Pointer = (ulong)intptrNative + u64TiffHeaderSize + (u64TiffTagSize * u64); tifftag = (TIFFTAG)Marshal.PtrToStructure((IntPtr)u64Pointer, typeof(TIFFTAG)); // StripOffsets... if (tifftag.u16Tag == 273) { iTiffSize += (int)tifftag.u32Value; } // StripByteCounts... if (tifftag.u16Tag == 279) { iTiffSize += (int)tifftag.u32Value; } } // No joy... if (iTiffSize == 0) { DsmMemUnlock(a_intptrNative); return (null); } // Copy the data to our byte array... abTiff = new byte[iTiffSize]; Marshal.Copy(intptrNative, abTiff, 0, iTiffSize); // Move the image into a memory stream... MemoryStream memorystream = new MemoryStream(abTiff); // Turn the memory stream into an in-memory TIFF image... Image imageTiff = Image.FromStream(memorystream); // Convert the in-memory tiff to a Bitmap object... Bitmap bitmap = new Bitmap(imageTiff); // Cleanup... abTiff = null; memorystream = null; imageTiff = null; // Return our bitmap... DsmMemUnlock(a_intptrNative); return (bitmap); } // Uh-oh... DsmMemUnlock(a_intptrNative); return (null); } /// /// Get .NET 'Bitmap' object from memory DIB via stream constructor. /// This should work for most DIBs. /// /// The pointer to something (presumably a BITMAP or a TIFF image) /// C# Bitmap of image public byte[] NativeToByteArray(IntPtr a_intptrNative, bool a_blIsHandle, out int a_iHeaderBytes) { ushort u16Magic; UIntPtr uintptrBytes; IntPtr intptrNative; // Init stuff... a_iHeaderBytes = 0; // Give ourselves what protection we can... try { // We need the first two bytes to decide if we have a DIB or a TIFF. Don't // forget to lock the silly thing... intptrNative = a_blIsHandle ? DsmMemLock(a_intptrNative) : a_intptrNative; u16Magic = (ushort)Marshal.PtrToStructure(intptrNative, typeof(ushort)); // Windows uses a DIB, the first unsigned short is 40... if (u16Magic == 40) { byte[] abBitmap; BITMAPFILEHEADER bitmapfileheader; BITMAPINFOHEADER bitmapinfoheader; // Our incoming DIB is a bitmap info header... bitmapinfoheader = (BITMAPINFOHEADER)Marshal.PtrToStructure(intptrNative, typeof(BITMAPINFOHEADER)); // Build our file header... bitmapfileheader = new BITMAPFILEHEADER(); bitmapfileheader.bfType = 0x4D42; // "BM" bitmapfileheader.bfSize = (uint)Marshal.SizeOf(typeof(BITMAPFILEHEADER)) + bitmapinfoheader.biSize + (bitmapinfoheader.biClrUsed * 4) + bitmapinfoheader.biSizeImage; bitmapfileheader.bfOffBits = (uint)Marshal.SizeOf(typeof(BITMAPFILEHEADER)) + bitmapinfoheader.biSize + (bitmapinfoheader.biClrUsed * 4); // Copy the file header into our byte array... IntPtr intptr = Marshal.AllocHGlobal(Marshal.SizeOf(bitmapfileheader)); Marshal.StructureToPtr(bitmapfileheader, intptr, true); abBitmap = new byte[bitmapfileheader.bfSize]; Marshal.Copy(intptr, abBitmap, 0, Marshal.SizeOf(bitmapfileheader)); Marshal.FreeHGlobal(intptr); intptr = IntPtr.Zero; // Copy the rest of the DIB into our byte array... a_iHeaderBytes = (int)bitmapfileheader.bfOffBits; Marshal.Copy(intptrNative, abBitmap, Marshal.SizeOf(typeof(BITMAPFILEHEADER)), (int)bitmapfileheader.bfSize - Marshal.SizeOf(typeof(BITMAPFILEHEADER))); // Unlock the handle, and return our byte array... if (a_blIsHandle) { DsmMemUnlock(a_intptrNative); } return (abBitmap); } // Linux and Mac OS X use TIFF. We'll handle a simple Intel TIFF ("II")... else if (u16Magic == 0x4949) { int iTiffSize; ulong u64; ulong u64Pointer; ulong u64TiffHeaderSize; ulong u64TiffTagSize; byte[] abTiff; TIFFHEADER tiffheader; TIFFTAG tifftag; // Init stuff... tiffheader = new TIFFHEADER(); tifftag = new TIFFTAG(); u64TiffHeaderSize = (ulong)Marshal.SizeOf(tiffheader); u64TiffTagSize = (ulong)Marshal.SizeOf(tifftag); // Find the size of the image so we can turn it into a byte array... iTiffSize = 0; tiffheader = (TIFFHEADER)Marshal.PtrToStructure(intptrNative, typeof(TIFFHEADER)); for (u64 = 0; u64 < 999; u64++) { u64Pointer = (ulong)intptrNative + u64TiffHeaderSize + (u64TiffTagSize * u64); tifftag = (TIFFTAG)Marshal.PtrToStructure((IntPtr)u64Pointer, typeof(TIFFTAG)); // StripOffsets... if (tifftag.u16Tag == 273) { iTiffSize += (int)tifftag.u32Value; a_iHeaderBytes = (int)tifftag.u32Value; } // StripByteCounts... if (tifftag.u16Tag == 279) { iTiffSize += (int)tifftag.u32Value; } } // No joy... if (iTiffSize == 0) { if (a_blIsHandle) { DsmMemUnlock(a_intptrNative); } return (null); } // Copy the data to our byte array... abTiff = new byte[iTiffSize]; Marshal.Copy(intptrNative, abTiff, 0, iTiffSize); // Unlock the handle, and return our byte array... if (a_blIsHandle) { DsmMemUnlock(a_intptrNative); } return (abTiff); } // As long as we're here, let's handle JFIF (JPEG) too, // this can never be a handle... else if (u16Magic == 0xFFD8) { byte[] abJfif; // We need the size of this memory block... switch (GetPlatform()) { default: Log.Error("Really? <" + GetPlatform() + ">"); return (null); case Platform.WINDOWS: uintptrBytes = NativeMethods._msize(a_intptrNative); break; case Platform.LINUX: uintptrBytes = NativeMethods.malloc_usable_size(a_intptrNative); break; case Platform.MACOSX: uintptrBytes = NativeMethods.malloc_size(a_intptrNative); break; } abJfif = new byte[(int)uintptrBytes]; Marshal.Copy(a_intptrNative, abJfif, 0, (int)(int)uintptrBytes); return (abJfif); } } catch (Exception exception) { Log.Error("NativeToByteArray threw an exceptions - " + exception.Message); } // Byte-bye... DsmMemUnlock(a_intptrNative); return (null); } /// /// Convert a public identity to a legacy identity... /// /// Identity to convert /// Legacy form of identity private TW_IDENTITY_LEGACY TwidentityToTwidentitylegacy(TW_IDENTITY a_twidentity) { TW_IDENTITY_LEGACY twidentitylegacy = new TW_IDENTITY_LEGACY(); twidentitylegacy.Id = (uint)a_twidentity.Id; twidentitylegacy.Manufacturer = a_twidentity.Manufacturer; twidentitylegacy.ProductFamily = a_twidentity.ProductFamily; twidentitylegacy.ProductName = a_twidentity.ProductName; twidentitylegacy.ProtocolMajor = a_twidentity.ProtocolMajor; twidentitylegacy.ProtocolMinor = a_twidentity.ProtocolMinor; twidentitylegacy.SupportedGroups = a_twidentity.SupportedGroups; twidentitylegacy.Version.Country = a_twidentity.Version.Country; twidentitylegacy.Version.Info = a_twidentity.Version.Info; twidentitylegacy.Version.Language = a_twidentity.Version.Language; twidentitylegacy.Version.MajorNum = a_twidentity.Version.MajorNum; twidentitylegacy.Version.MinorNum = a_twidentity.Version.MinorNum; return (twidentitylegacy); } /// /// Convert a public identity to a linux64 identity... /// /// Identity to convert /// Linux64 form of identity private TW_IDENTITY_LINUX64 TwidentityToTwidentitylinux64(TW_IDENTITY a_twidentity) { TW_IDENTITY_LINUX64 twidentitylinux64 = new TW_IDENTITY_LINUX64(); twidentitylinux64.Id = a_twidentity.Id; twidentitylinux64.Manufacturer = a_twidentity.Manufacturer; twidentitylinux64.ProductFamily = a_twidentity.ProductFamily; twidentitylinux64.ProductName = a_twidentity.ProductName; twidentitylinux64.ProtocolMajor = a_twidentity.ProtocolMajor; twidentitylinux64.ProtocolMinor = a_twidentity.ProtocolMinor; twidentitylinux64.SupportedGroups = a_twidentity.SupportedGroups; twidentitylinux64.Version.Country = a_twidentity.Version.Country; twidentitylinux64.Version.Info = a_twidentity.Version.Info; twidentitylinux64.Version.Language = a_twidentity.Version.Language; twidentitylinux64.Version.MajorNum = a_twidentity.Version.MajorNum; twidentitylinux64.Version.MinorNum = a_twidentity.Version.MinorNum; return (twidentitylinux64); } /// /// Convert a public identity to a macosx identity... /// /// Identity to convert /// Mac OS X form of identity public static TW_IDENTITY_MACOSX TwidentityToTwidentitymacosx(TW_IDENTITY a_twidentity) { TW_IDENTITY_MACOSX twidentitymacosx = new TW_IDENTITY_MACOSX(); twidentitymacosx.Id = (uint)a_twidentity.Id; twidentitymacosx.Manufacturer = a_twidentity.Manufacturer; twidentitymacosx.ProductFamily = a_twidentity.ProductFamily; twidentitymacosx.ProductName = a_twidentity.ProductName; twidentitymacosx.ProtocolMajor = a_twidentity.ProtocolMajor; twidentitymacosx.ProtocolMinor = a_twidentity.ProtocolMinor; twidentitymacosx.SupportedGroups = a_twidentity.SupportedGroups; twidentitymacosx.Version.Country = a_twidentity.Version.Country; twidentitymacosx.Version.Info = a_twidentity.Version.Info; twidentitymacosx.Version.Language = a_twidentity.Version.Language; twidentitymacosx.Version.MajorNum = a_twidentity.Version.MajorNum; twidentitymacosx.Version.MinorNum = a_twidentity.Version.MinorNum; return (twidentitymacosx); } /// /// Convert a legacy identity to a public identity... /// /// Legacy identity to convert /// Regular form of identity private TW_IDENTITY TwidentitylegacyToTwidentity(TW_IDENTITY_LEGACY a_twidentitylegacy) { TW_IDENTITY twidentity = new TW_IDENTITY(); twidentity.Id = a_twidentitylegacy.Id; twidentity.Manufacturer = a_twidentitylegacy.Manufacturer; twidentity.ProductFamily = a_twidentitylegacy.ProductFamily; twidentity.ProductName = a_twidentitylegacy.ProductName; twidentity.ProtocolMajor = a_twidentitylegacy.ProtocolMajor; twidentity.ProtocolMinor = a_twidentitylegacy.ProtocolMinor; twidentity.SupportedGroups = a_twidentitylegacy.SupportedGroups; twidentity.Version.Country = a_twidentitylegacy.Version.Country; twidentity.Version.Info = a_twidentitylegacy.Version.Info; twidentity.Version.Language = a_twidentitylegacy.Version.Language; twidentity.Version.MajorNum = a_twidentitylegacy.Version.MajorNum; twidentity.Version.MinorNum = a_twidentitylegacy.Version.MinorNum; return (twidentity); } /// /// Convert a linux64 identity to a public identity... /// /// Legacy identity to convert /// Regular form of identity private TW_IDENTITY Twidentitylinux64ToTwidentity(TW_IDENTITY_LINUX64 a_twidentitylinux64) { TW_IDENTITY twidentity = new TW_IDENTITY(); twidentity.Id = a_twidentitylinux64.Id; twidentity.Manufacturer = a_twidentitylinux64.Manufacturer; twidentity.ProductFamily = a_twidentitylinux64.ProductFamily; twidentity.ProductName = a_twidentitylinux64.ProductName; twidentity.ProtocolMajor = a_twidentitylinux64.ProtocolMajor; twidentity.ProtocolMinor = a_twidentitylinux64.ProtocolMinor; twidentity.SupportedGroups = (uint)a_twidentitylinux64.SupportedGroups; twidentity.Version.Country = a_twidentitylinux64.Version.Country; twidentity.Version.Info = a_twidentitylinux64.Version.Info; twidentity.Version.Language = a_twidentitylinux64.Version.Language; twidentity.Version.MajorNum = a_twidentitylinux64.Version.MajorNum; twidentity.Version.MinorNum = a_twidentitylinux64.Version.MinorNum; return (twidentity); } /// /// Convert a macosx identity to a public identity... /// /// Mac OS X identity to convert /// Regular identity private TW_IDENTITY TwidentitymacosxToTwidentity(TW_IDENTITY_MACOSX a_twidentitymacosx) { TW_IDENTITY twidentity = new TW_IDENTITY(); twidentity.Id = a_twidentitymacosx.Id; twidentity.Manufacturer = a_twidentitymacosx.Manufacturer; twidentity.ProductFamily = a_twidentitymacosx.ProductFamily; twidentity.ProductName = a_twidentitymacosx.ProductName; twidentity.ProtocolMajor = a_twidentitymacosx.ProtocolMajor; twidentity.ProtocolMinor = a_twidentitymacosx.ProtocolMinor; twidentity.SupportedGroups = a_twidentitymacosx.SupportedGroups; twidentity.Version.Country = a_twidentitymacosx.Version.Country; twidentity.Version.Info = a_twidentitymacosx.Version.Info; twidentity.Version.Language = a_twidentitymacosx.Version.Language; twidentity.Version.MajorNum = a_twidentitymacosx.Version.MajorNum; twidentity.Version.MinorNum = a_twidentitymacosx.Version.MinorNum; return (twidentity); } #endregion /////////////////////////////////////////////////////////////////////////////// // Private Structures, things we need for the thread, and to support stuff // like DAT_IMAGENATIVEXFER... /////////////////////////////////////////////////////////////////////////////// #region Private Structures... /// /// The data we share with the thread... /// [SuppressMessage("Microsoft.Design", "CA1049:TypesThatOwnNativeResourcesShouldBeDisposable")] private struct ThreadData { // The state of the structure... public bool blIsInuse; public bool blIsComplete; public bool blExitThread; // Command... public DG dg; public DAT dat; public MSG msg; public STATE stateRollback; public bool blRollback; // Payload... public IntPtr intptrHwnd; public IntPtr intptrBitmap; public IntPtr intptrAudio; public IntPtr twmemref; public Bitmap bitmap; public bool blUseBitmapHandle; public UInt32 twuint32; public TW_AUDIOINFO twaudioinfo; public TW_CALLBACK twcallback; public TW_CALLBACK2 twcallback2; public TW_CAPABILITY twcapability; public TW_CIECOLOR twciecolor; public TW_CUSTOMDSDATA twcustomdsdata; public TW_DEVICEEVENT twdeviceevent; public TW_ENTRYPOINT twentrypoint; public TW_EVENT twevent; public TW_EXTIMAGEINFO twextimageinfo; public TW_FILESYSTEM twfilesystem; public TW_FILTER twfilter; public TW_GRAYRESPONSE twgrayresponse; public TW_IDENTITY twidentity; public TW_IDENTITY_LEGACY twidentitylegacy; public TW_IMAGEINFO twimageinfo; public TW_IMAGELAYOUT twimagelayout; public TW_IMAGEMEMXFER twimagememxfer; public TW_JPEGCOMPRESSION twjpegcompression; public TW_METRICS twmetrics; public TW_MEMORY twmemory; public TW_PALETTE8 twpalette8; public TW_PASSTHRU twpassthru; public TW_PENDINGXFERS twpendingxfers; public TW_RGBRESPONSE twrgbresponse; public TW_SETUPFILEXFER twsetupfilexfer; public TW_SETUPMEMXFER twsetupmemxfer; public TW_STATUS twstatus; public TW_STATUSUTF8 twstatusutf8; public TW_TWAINDIRECT twtwaindirect; public TW_USERINTERFACE twuserinterface; // Result... public STS sts; } /// /// The Windows Point structure. /// Needed for the PreFilterMessage function when we're /// handling DAT_EVENT... /// [StructLayout(LayoutKind.Sequential, Pack = 1)] private struct POINT { public int X; public int Y; } /// /// The Windows MSG structure. /// Needed for the PreFilterMessage function when we're /// handling DAT_EVENT... /// [StructLayout(LayoutKind.Sequential)] private struct MESSAGE { public IntPtr hwnd; public UInt32 message; public IntPtr wParam; public IntPtr lParam; public UInt32 time; public POINT pt; } /// /// The header for a Bitmap file. /// Needed for supporting DAT.IMAGENATIVEXFER... /// [StructLayout(LayoutKind.Sequential, Pack = 1)] private struct BITMAPFILEHEADER { public ushort bfType; public uint bfSize; public ushort bfReserved1; public ushort bfReserved2; public uint bfOffBits; } /// /// The header for a Device Independent Bitmap (DIB). /// Needed for supporting DAT.IMAGENATIVEXFER... /// [StructLayout(LayoutKind.Sequential, Pack = 1)] private struct BITMAPINFOHEADER { public uint biSize; public int biWidth; public int biHeight; public ushort biPlanes; public ushort biBitCount; public uint biCompression; public uint biSizeImage; public int biXPelsPerMeter; public int biYPelsPerMeter; public uint biClrUsed; public uint biClrImportant; public void Init() { biSize = (uint)Marshal.SizeOf(this); } } /// /// The TIFF file header. /// Needed for supporting DAT.IMAGENATIVEXFER... /// [StructLayout(LayoutKind.Sequential, Pack = 1)] private struct TIFFHEADER { public ushort u8ByteOrder; public ushort u16Version; public uint u32OffsetFirstIFD; public ushort u16u16IFD; } /// /// An individual TIFF Tag. /// Needed for supporting DAT.IMAGENATIVEXFER... /// [StructLayout(LayoutKind.Sequential, Pack = 1)] private struct TIFFTAG { public ushort u16Tag; public ushort u16Type; public uint u32Count; public uint u32Value; } #endregion /////////////////////////////////////////////////////////////////////////////// // Private Attributes... /////////////////////////////////////////////////////////////////////////////// #region Private Attributes... /// /// Our application identity... /// private TW_IDENTITY m_twidentityApp; private TW_IDENTITY_LEGACY m_twidentitylegacyApp; private TW_IDENTITY_MACOSX m_twidentitymacosxApp; /// /// Our Data Source identity... /// private TW_IDENTITY m_twidentityDs; private TW_IDENTITY_LEGACY m_twidentitylegacyDs; private TW_IDENTITY_MACOSX m_twidentitymacosxDs; /// /// Our current TWAIN state... /// private STATE m_state; private bool m_blAcceptXferReady; /// /// DAT_NULL flags that we've seen after entering into /// state 5 through MSG_ENABLEDS or MSG_ENABLEDSUIONLY, /// or coming down from DAT_PENDINGXFERS, either /// MSG_ENDXFER or MSG_RESET... /// private bool m_blIsMsgxferready; private bool m_blIsMsgclosedsreq; private bool m_blIsMsgclosedsok; private bool m_blIsMsgdeviceevent; private bool m_blRunningDatUserinterface; private Thread m_threadRunningDatUserinterface; /// /// Automatically issue DAT.STATUS on TWRC_FAILURE... /// private bool m_blAutoDatStatus; /// /// Windows, pick between TWAIN_32.DLL and TWAINDSM.DLL... /// Mac OS X, pick between /System/Library/Frameworks/TWAIN.framework and /Library/Frameworks/TWAINDSM.framework /// private bool m_blUseLegacyDSM; /// /// Help us pick the right DSM for the current data source, /// the first one is for the session, the second one is for /// getfirst/getnext, and allows us to check for drivers /// using either one or both DSMs, depending on what is /// available... /// private LinuxDsm m_linuxdsm; private LinuxDsm m_linux64bitdsmDatIdentity; private bool m_blFoundLatestDsm; private bool m_blFoundLatestDsm64; private bool m_blFound020302Dsm64bit; /// /// Use the callback system (TWAINDSM.DLL only)... /// private bool m_blUseCallbacks; /// /// The platform we're running on... /// private static Platform ms_platform; private static Processor ms_processor; private static bool ms_blFirstPassGetPlatform = true; /// /// Delegates for DAT_CALLBACK... /// private NativeMethods.WindowsDsmEntryCallbackDelegate m_windowsdsmentrycontrolcallbackdelegate; private NativeMethods.LinuxDsmEntryCallbackDelegate m_linuxdsmentrycontrolcallbackdelegate; private NativeMethods.MacosxDsmEntryCallbackDelegate m_macosxdsmentrycontrolcallbackdelegate; /// /// We only allow one thread at a time to talk to the TWAIN driver... /// private Object m_lockTwain; /// /// Use this to wait for commands from the caller... /// private AutoResetEvent m_autoreseteventCaller; /// /// Use this to force the user's command to block until TWAIN has /// a response... /// private AutoResetEvent m_autoreseteventThread; /// /// Use this to force the user's rollback to block until TWAIN has /// a response... /// private AutoResetEvent m_autoreseteventRollback; /// /// One can get into a race condition with the thread, so we use /// this event to confirm that it's started and ready for use... /// private AutoResetEvent m_autoreseteventThreadStarted; /// /// The data we share with the thread... /// //private ThreadData m_threaddata; /// /// Our callback for device events... /// private DeviceEventCallback m_deviceeventcallback; /// /// Our callback function for scanning... /// private ScanCallback m_scancallback; /// /// Run stuff in a caller's UI thread... /// private RunInUiThreadDelegate m_runinuithreaddelegate; /// /// The event calls don't go through the thread... /// private TW_EVENT m_tweventPreFilterMessage; // Remember the window handle, so we can reuse it... private IntPtr m_intptrHwnd; /// /// Our thread... /// private Thread m_threadTwain; /// /// How we talk to our thread... /// private TwainCommand m_twaincommand; /// /// Indecies for commands that have to do something a /// bit more fancy, such as running the command in the /// context of a GUI thread. And flags to help know /// when we are doing this... /// private ThreadData m_threaddataDatAudiofilexfer; private ThreadData m_threaddataDatAudionativexfer; private ThreadData m_threaddataDatCapability; private ThreadData m_threaddataDatEvent; private ThreadData m_threaddataDatExtimageinfo; private ThreadData m_threaddataDatIdentity; private ThreadData m_threaddataDatImagefilexfer; private ThreadData m_threaddataDatImageinfo; private ThreadData m_threaddataDatImagelayout; private ThreadData m_threaddataDatImagememfilexfer; private ThreadData m_threaddataDatImagememxfer; private ThreadData m_threaddataDatImagenativexfer; private ThreadData m_threaddataDatParent; private ThreadData m_threaddataDatPendingxfers; private ThreadData m_threaddataDatSetupfilexfer; private ThreadData m_threaddataDatSetupmemxfer; private ThreadData m_threaddataDatStatus; private ThreadData m_threaddataDatUserinterface; /// /// Our helper functions from the DSM... /// private TW_ENTRYPOINT_DELEGATES m_twentrypointdelegates; #endregion /////////////////////////////////////////////////////////////////////////////// // TwainCommand... /////////////////////////////////////////////////////////////////////////////// #region TwainCommand... /// /// We have TWAIN commands that can be called by the application from any /// thread they want. We do a lock, and then build a command and submit /// it to the Main thread. The Main thread runs without locks, so all it /// is allowed to do is examine TwainCommands to see if it has work. If /// it finds an item, it takes care of it, and changes it to complete. /// private sealed class TwainCommand { /////////////////////////////////////////////////////////////////////////// // Public Functions... /////////////////////////////////////////////////////////////////////////// #region Public Functions... /// /// Initialize an array that we'll be sharing between the TWAIN operations /// and the Main thread... /// public TwainCommand() { m_athreaddata = new ThreadData[8]; } /// /// Complete a command /// /// index to update /// data to use public void Complete(long a_lIndex, ThreadData a_threaddata) { // If we're out of bounds, return an empty structure... if ((a_lIndex < 0) || (a_lIndex >= m_athreaddata.Length)) { return; } // We're not really a command... if (!m_athreaddata[a_lIndex].blIsInuse) { return; } // Do the update and tag it complete... m_athreaddata[a_lIndex] = a_threaddata; m_athreaddata[a_lIndex].blIsComplete = true; } /// /// Delete a command... /// /// the requested command public void Delete(long a_lIndex) { // If we're out of bounds, return an empty structure... if ((a_lIndex < 0) || (a_lIndex >= m_athreaddata.Length)) { return; } // Clear the record... m_athreaddata[a_lIndex] = default(ThreadData); } /// /// Get a command... /// /// the requested command public ThreadData Get(long a_lIndex) { // If we're out of bounds, return an empty structure... if ((a_lIndex < 0) || (a_lIndex >= m_athreaddata.Length)) { return (new ThreadData()); } // Return what we found... return (m_athreaddata[a_lIndex]); } /// /// Get the next command in the list... /// /// the index of the data /// the command we'll return /// true if we found something public bool GetNext(out long a_lIndex, out ThreadData a_threaddata) { long lIndex; // Init stuff... lIndex = m_lIndex; a_lIndex = 0; a_threaddata = default(ThreadData); // Cycle once through the commands to see if we have any... for (;;) { // We found something, copy it out, point to the next // item (so we know we're looking at the whole list) // and return... if (m_athreaddata[lIndex].blIsInuse && !m_athreaddata[lIndex].blIsComplete) { a_threaddata = m_athreaddata[lIndex]; a_lIndex = lIndex; m_lIndex = lIndex + 1; if (m_lIndex >= m_athreaddata.Length) { m_lIndex = 0; } return (true); } // Next item... lIndex += 1; if (lIndex >= m_athreaddata.Length) { lIndex = 0; } // We've cycled, and we didn't find anything... if (lIndex == m_lIndex) { a_lIndex = lIndex; return (false); } } } /// /// Submit a new command... /// /// public long Submit(ThreadData a_threadata) { long ll; // We won't leave until we've submitted the beastie... for (;;) { // Look for a free slot... for (ll = 0; ll < m_athreaddata.Length; ll++) { if (!m_athreaddata[ll].blIsInuse) { m_athreaddata[ll] = a_threadata; m_athreaddata[ll].blIsInuse = true; return (ll); } } // Wait a little... Thread.Sleep(0); } } /// /// Update a command /// /// index to update /// data to use public void Update(long a_lIndex, ThreadData a_threaddata) { // If we're out of bounds, return an empty structure... if ((a_lIndex < 0) || (a_lIndex >= m_athreaddata.Length)) { return; } // We're not really a command... if (!m_athreaddata[a_lIndex].blIsInuse) { return; } // Do the update... m_athreaddata[a_lIndex] = a_threaddata; } #endregion /////////////////////////////////////////////////////////////////////////// // Private Attributes... /////////////////////////////////////////////////////////////////////////// #region Private Attributes... /// /// The data we're sharing. A null in a position means its available for /// use. The Main thread only consumes items, it never creates or /// destroys them, that's done by the various commands. /// private ThreadData[] m_athreaddata; /// /// Index for browsing m_athreaddata for work... /// private long m_lIndex; #endregion } #endregion } /// /// A quick and dirty CSV reader/writer... /// public class CSV { /////////////////////////////////////////////////////////////////////////////// // Public Functions... /////////////////////////////////////////////////////////////////////////////// #region Public Functions... /// /// Start with an empty string... /// public CSV() { m_szCsv = ""; } /// /// Add an item to a CSV string... /// /// Something to add to the CSV string public void Add(string a_szItem) { // If the item has commas, we need to do work... if (a_szItem.Contains(",")) { // If the item has quotes, replace them with paired quotes, then // quote it and add it... if (a_szItem.Contains("\"")) { m_szCsv += ((m_szCsv != "") ? "," : "") + "\"" + a_szItem.Replace("\"", "\"\"") + "\""; } // Otherwise, just quote it and add it... else { m_szCsv += ((m_szCsv != "") ? "," : "") + "\"" + a_szItem + "\""; } } // If the item has quotes, replace them with escaped quotes, then // quote it and add it... else if (a_szItem.Contains("\"")) { m_szCsv += ((m_szCsv != "") ? "," : "") + "\"" + a_szItem.Replace("\"", "\"\"") + "\""; } // Otherwise, just add it... else { m_szCsv += ((m_szCsv != "") ? "," : "") + a_szItem; } } /// /// Clear the record... /// public void Clear() { m_szCsv = ""; } /// /// Get the current CSV string... /// /// The current value of the CSV string public string Get() { return (m_szCsv); } /// /// Parse a CSV string... /// /// A CSV string to parse /// An array if items (some can be CSV themselves) public static string[] Parse(string a_szCsv) { int ii; bool blEnd; string[] aszCsv; string[] aszLeft; string[] aszRight; // Validate... if ((a_szCsv == null) || (a_szCsv == "")) { return (new string[] { "" }); } // If there are no quotes, then parse it fast... if (!a_szCsv.Contains("\"")) { return (a_szCsv.Split(new char[] { ',' })); } // There's no opening quote, so split and recurse... if (a_szCsv[0] != '"') { aszLeft = new string[] { a_szCsv.Substring(0, a_szCsv.IndexOf(',')) }; aszRight = Parse(a_szCsv.Remove(0, a_szCsv.IndexOf(',') + 1)); aszCsv = new string[aszLeft.Length + aszRight.Length]; aszLeft.CopyTo(aszCsv, 0); aszRight.CopyTo(aszCsv, aszLeft.Length); return (aszCsv); } // Handle the quoted string... else { // Find the terminating quote... blEnd = true; for (ii = 0; ii < a_szCsv.Length; ii++) { if (a_szCsv[ii] == '"') { blEnd = !blEnd; } else if (blEnd && (a_szCsv[ii] == ',')) { break; } } ii -= 1; // We have a problem... if (!blEnd) { throw new Exception("Error in CSV string..."); } // This is the last item, remove any escaped quotes and return it... if (((ii + 1) >= a_szCsv.Length)) { return (new string[] { a_szCsv.Substring(1, a_szCsv.Length - 2).Replace("\"\"", "\"") }); } // We have more data... if (a_szCsv[ii + 1] == ',') { aszLeft = new string[] { a_szCsv.Substring(1, ii - 1).Replace("\"\"", "\"") }; aszRight = Parse(a_szCsv.Remove(0, ii + 2)); aszCsv = new string[aszLeft.Length + aszRight.Length]; aszLeft.CopyTo(aszCsv, 0); aszRight.CopyTo(aszCsv, aszLeft.Length); return (aszCsv); } // We have a problem... throw new Exception("Error in CSV string..."); } } #endregion /////////////////////////////////////////////////////////////////////////////// // Private Attributes... /////////////////////////////////////////////////////////////////////////////// #region Private Attributes... /// /// Our working string for creating or parsing... /// private string m_szCsv; #endregion } /// /// Our logger. If we bump up to 4.5 (and if mono supports it at compile /// time), then we'll be able to add the following to our traces, which /// seems like it should be more than enough to locate log messages. For /// now we'll leave the log messages undecorated: /// [CallerFilePath] string file = "", /// [CallerMemberName] string member = "", /// [CallerLineNumber] int line = 0 /// public static class Log { // Public Methods... #region Public Methods... /// /// Initialize our delegates... /// static Log() { Close = CloseLocal; GetLevel = GetLevelLocal; Open = OpenLocal; RegisterTwain = RegisterTwainLocal; SetFlush = SetFlushLocal; SetLevel = SetLevelLocal; WriteEntry = WriteEntryLocal; } /// /// Let the caller override our delegates with their own functions... /// /// use this to close the logging session /// get the current log level /// open the logging session /// not needed at this time /// turn flushing on and off /// set the new log level /// the function that actually writes to the log /// returns a way to get the current TWAIN state public static void Override ( CloseDelegate a_closedelegate, GetLevelDelegate a_getleveldelegate, OpenDelegate a_opendelegate, RegisterTwainDelegate a_registertwaindelegate, SetFlushDelegate a_setflushdelegate, SetLevelDelegate a_setleveldelegate, WriteEntryDelegate a_writeentrydelegate, out GetStateDelegate a_getstatedelegate ) { Close = (a_closedelegate != null) ? a_closedelegate : CloseLocal; GetLevel = (a_getleveldelegate != null) ? a_getleveldelegate : GetLevelLocal; Open = (a_opendelegate != null) ? a_opendelegate : OpenLocal; RegisterTwain = (a_registertwaindelegate != null) ? a_registertwaindelegate : RegisterTwainLocal; SetFlush = (a_setflushdelegate != null) ? a_setflushdelegate : SetFlushLocal; SetLevel = (a_setleveldelegate != null) ? a_setleveldelegate : SetLevelLocal; WriteEntry = (a_writeentrydelegate != null) ? a_writeentrydelegate : WriteEntryLocal; a_getstatedelegate = GetStateLocal; } /// /// Write an assert message, but only throw with a debug build... /// /// message to log public static void Assert(string a_szMessage) { WriteEntry("A", a_szMessage, true); #if DEBUG throw new Exception(a_szMessage); #endif } /// /// Write an error message... /// /// message to log public static void Error(string a_szMessage) { WriteEntry("E", a_szMessage, true); } /// /// Write an informational message... /// /// message to log public static void Info(string a_szMessage) { WriteEntry(".", a_szMessage, ms_blFlush); } /// /// Log after sending to the TWAIN driver... /// /// status /// data public static void LogSendAfter(TWAIN.STS a_sts, string a_szMemref) { // The data argument type (DAT) stuff... if ((a_szMemref != null) && (a_szMemref != "") && (a_szMemref[0] != '(')) { Log.Info("twn> " + a_szMemref); } // TWRC... if ((int)a_sts < TWAIN.STSCC) { Log.Info("twn> " + a_sts); } // TWCC... else { Log.Info("twn> FAILURE/" + a_sts); } } /// /// Log before sending to the TWAIN driver... /// /// data group /// data argument type /// message /// data public static void LogSendBefore(string a_szDg, string a_szDat, string a_szMsg, string a_szMemref) { Log.Info(""); Log.Info("twn> DG_" + a_szDg + "/DAT_" + a_szDat + "/MSG_" + a_szMsg); if ((a_szMemref != null) && (a_szMemref != "") && (a_szMemref[0] != '(')) { Log.Info("twn> " + a_szMemref); } } /// /// Write a verbose message, this is extra info that isn't normally /// needed to diagnose problems, but may provide insight into what /// the code is doing... /// /// message to log public static void Verbose(string a_szMessage) { WriteEntry("V", a_szMessage, ms_blFlush); } /// /// Write a verbose data message, this is extra info, specifically /// data transfers, that isn't normally needed to diagnose problems. /// Turning this one can really bloat the logs... /// /// message to log public static void VerboseData(string a_szMessage) { WriteEntry("D", a_szMessage, ms_blFlush); } /// /// Write an warning message... /// /// message to log public static void Warn(string a_szMessage) { WriteEntry("W", a_szMessage, ms_blFlush); } #endregion // Public Definitions... #region Public Definitions... // The public methods that need attributes, here offered // as delegates, so that a caller will be able to override // them... public delegate void CloseDelegate(); public delegate int GetLevelDelegate(); public delegate string GetStateDelegate(); public delegate void OpenDelegate(string a_szName, string a_szPath, int a_iLevel); public delegate void RegisterTwainDelegate(TWAIN a_twain); public delegate void SetFlushDelegate(bool a_blFlush); public delegate void SetLevelDelegate(int a_iLevel); public delegate void WriteEntryDelegate(string a_szSeverity, string a_szMessage, bool a_blFlush); #endregion // Public Attributes... #region Public Attributes... // The public methods that need attributes, here offered // as delegates, so that a caller will be able to override // them... public static CloseDelegate Close; public static GetLevelDelegate GetLevel; public static OpenDelegate Open; public static RegisterTwainDelegate RegisterTwain; public static SetFlushDelegate SetFlush; public static SetLevelDelegate SetLevel; public static WriteEntryDelegate WriteEntry; #endregion // Private Methods... #region Private Methods... /// /// Close tracing... /// private static void CloseLocal() { if (!ms_blFirstPass) { Trace.Close(); ms_filestream.Close(); ms_filestream = null; } ms_blFirstPass = true; ms_blOpened = false; ms_blFlush = false; ms_iMessageNumber = 0; } /// /// Get the debugging level... /// /// the level private static int GetLevelLocal() { return (ms_iLevel); } /// /// Get the state... /// /// the level private static string GetStateLocal() { return ((ms_twain == null) ? "S1" : ms_twain.GetState().ToString()); } /// /// Turn on the listener for our log file... /// /// the name of our log /// the path where we want our log to go /// debug level private static void OpenLocal(string a_szName, string a_szPath, int a_iLevel) { string szLogFile; // Init stuff... ms_blFirstPass = true; ms_blOpened = true; ms_blFlush = false; ms_iMessageNumber = 0; ms_iLevel = a_iLevel; // Ask for a TWAINDSM log... if (a_iLevel > 0) { Environment.SetEnvironmentVariable("TWAINDSM_LOG", Path.Combine(a_szPath, "twaindsm.log")); Environment.SetEnvironmentVariable("TWAINDSM_MODE", "w"); } // Backup old stuff... szLogFile = Path.Combine(a_szPath, a_szName); try { if (File.Exists(szLogFile + "_backup_2.log")) { File.Delete(szLogFile + "_backup_2.log"); } if (File.Exists(szLogFile + "_backup_1.log")) { File.Move(szLogFile + "_backup_1.log", szLogFile + "_backup_2.log"); } if (File.Exists(szLogFile + ".log")) { File.Move(szLogFile + ".log", szLogFile + "_backup_1.log"); } } catch { // Don't care, keep going... } // Turn on the listener, if we're reentering, we maybe have to retry a bit until the // previous one is gone... for (int iRetry = 0; iRetry < 5000; iRetry += 1000) { try { ms_filestream = File.Open(szLogFile + ".log", FileMode.Append, FileAccess.Write, FileShare.Read); Trace.Listeners.Add(new TextWriterTraceListener(ms_filestream, a_szName + "Listener")); break; } catch { // Just keep retrying... } Thread.Sleep(1000); } } /// /// Register the TWAIN object so we can get some extra info... /// /// twain object or null private static void RegisterTwainLocal(TWAIN a_twain) { ms_twain = a_twain; } /// /// Flush data to the file... /// private static void SetFlushLocal(bool a_blFlush) { ms_blFlush = a_blFlush; if (a_blFlush) { Trace.Flush(); } } /// /// Set the debugging level /// /// private static void SetLevelLocal(int a_iLevel) { // Squirrel this value away... ms_iLevel = a_iLevel; // One has to opt out of flushing, since the consequence // of turning it off often involves losing log data... if ((a_iLevel & c_iDebugNoFlush) == c_iDebugNoFlush) { SetFlush(false); } else { SetFlush(true); } } /// /// Do this for all of them... /// /// The message /// Message severity /// Flush it to disk private static void WriteEntryLocal(string a_szSeverity, string a_szMessage, bool a_blFlush) { long lThreadId; // Filter... switch (a_szSeverity) { // Always log these, and always flush them to disk... case "A": case "E": case "W": a_blFlush = true; break; // Log informationals when bit-0 is set... case ".": if ((ms_iLevel & c_iDebugInfo) != 0) { break; } return; // Log verbose when bit-1 is set... case "V": if ((ms_iLevel & c_iDebugVerbose) != 0) { a_szSeverity = "."; break; } return; // Log verbose data when bit-1 is set... case "D": if ((ms_iLevel & c_iDebugVerboseData) != 0) { a_szSeverity = "."; break; } return; } // Get our thread id... if (ms_blIsWindows) { lThreadId = NativeMethods.GetCurrentThreadId(); } else { lThreadId = Thread.CurrentThread.ManagedThreadId; } // First pass... if (ms_blFirstPass) { string szPlatform; // We're Windows... if (Environment.OSVersion.ToString().Contains("Microsoft Windows")) { szPlatform = "windows"; } // We're Mac OS X (this has to come before LINUX!!!)... else if (Directory.Exists("/Library/Application Support")) { szPlatform = "macosx"; } // We're Linux... else if (Environment.OSVersion.ToString().Contains("Unix")) { szPlatform = "linux"; } // We have a problem, Log will throw for us... else { szPlatform = "unknown"; } if (!ms_blOpened) { // We'll assume they want logging, since they didn't tell us... Open("Twain", ".", 1); } Trace.UseGlobalLock = true; ms_blFirstPass = false; Trace.WriteLine ( string.Format ( "{0:D6} {1} {2} T{3:D8} V{4} ts:{5} os:{6}", ms_iMessageNumber++, DateTime.Now.ToString("HHmmssffffff"), (ms_twain != null) ? ms_twain.GetState().ToString() : "S1", lThreadId, a_szSeverity.ToString(), DateTime.Now.ToString("yyyy/MM/dd HH:mm:ss.ffffff"), szPlatform ) ); } // And log it... Trace.WriteLine ( string.Format ( "{0:D6} {1} {2} T{3:D8} V{4} {5}", ms_iMessageNumber++, DateTime.Now.ToString("HHmmssffffff"), (ms_twain != null) ? ms_twain.GetState().ToString() : "S1", lThreadId, a_szSeverity.ToString(), a_szMessage ) ); // Flush it... if (a_blFlush) { Trace.Flush(); } } #endregion // Private Definitions... #region Private Definitions /// /// LogLevel bitmask... /// private const int c_iDebugInfo = 0x0001; private const int c_iDebugVerbose = 0x0002; private const int c_iDebugVerboseData = 0x0004; private const int c_iDebugNoFlush = 0x0008; #endregion // Private Attributes... #region Private Attributes private static bool ms_blFirstPass = true; private static bool ms_blOpened = false; private static bool ms_blFlush = false; private static int ms_iMessageNumber = 0; private static int ms_iLevel = 0; private static TWAIN ms_twain = null; private static bool ms_blIsWindows = false; private static FileStream ms_filestream; #endregion } } ================================================ FILE: twaincs/source/TWAINH.cs ================================================ /////////////////////////////////////////////////////////////////////////////////////// // // TwainWorkingGroup.TWAIN // // These are the definitions for TWAIN. They're essentially the C/C++ // TWAIN.H file contents translated to C#, with modifications that // recognize the differences between Windows, Linux and Mac OS X. // /////////////////////////////////////////////////////////////////////////////////////// // Author Date TWAIN Comment // M.McLaughlin 17-May-2021 2.5.0.0 Updated to latest spec // M.McLaughlin 13-Mar-2019 2.4.0.3 Add language code page support for strings // M.McLaughlin 13-Nov-2015 2.4.0.0 Updated to latest spec // M.McLaughlin 13-Sep-2015 2.3.1.2 DsmMem bug fixes // M.McLaughlin 26-Aug-2015 2.3.1.1 Log fix and sync with TWAIN Direct // M.McLaughlin 13-Mar-2015 2.3.1.0 Numerous fixes // M.McLaughlin 13-Oct-2014 2.3.0.4 Added logging // M.McLaughlin 24-Jun-2014 2.3.0.3 Stability fixes // M.McLaughlin 21-May-2014 2.3.0.2 64-Bit Linux // M.McLaughlin 27-Feb-2014 2.3.0.1 AnyCPU support // M.McLaughlin 21-Oct-2013 2.3.0.0 Initial Release /////////////////////////////////////////////////////////////////////////////////////// // Copyright (C) 2013-2021 Kodak Alaris Inc. // // Permission is hereby granted, free of charge, to any person obtaining a // copy of this software and associated documentation files (the "Software"), // to deal in the Software without restriction, including without limitation // the rights to use, copy, modify, merge, publish, distribute, sublicense, // and/or sell copies of the Software, and to permit persons to whom the // Software is furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL // THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER // DEALINGS IN THE SOFTWARE. /////////////////////////////////////////////////////////////////////////////////////// using System; using System.Diagnostics.CodeAnalysis; using System.Runtime.InteropServices; using System.Text; namespace TWAINWorkingGroup { /// /// This file contains content gleaned from version 2.4 of the C/C++ TWAIN.H /// header file released by the TWAIN Working Group. It's organized like that /// file to make it easier to maintain. /// /// Please do not add any code to this module, save for the minimum needed to /// maintain a particular definition (such as TW_STR32)... /// public partial class TWAIN { /////////////////////////////////////////////////////////////////////////////// // TWAIN Version... /////////////////////////////////////////////////////////////////////////////// #region Protocol Version... public enum TWON_PROTOCOL { MAJOR = 2, MINOR = 5 // Changed for Version 2.5 }; #endregion /////////////////////////////////////////////////////////////////////////////// // Type Definitions... /////////////////////////////////////////////////////////////////////////////// #region Type Definitions... // Follow these rules /****************************************************************************** TW_HANDLE...............IntPtr TW_MEMREF...............IntPtr TW_UINTPTR..............UIntPtr TW_INT8.................char TW_INT16................short TW_INT32................int (was long on Linux 64-bit) TW_UINT8................byte TW_UINT16...............ushort TW_UINT32...............uint (was ulong on Linux 64-bit) TW_BOOL.................ushort ******************************************************************************/ /// /// Our supported platforms... /// public enum Platform { UNKNOWN, WINDOWS, LINUX, MACOSX }; /// /// Our supported processors... /// public enum Processor { UNKNOWN, X86, X86_64, MIPS64EL }; /// /// Used for strings that go up to 32-bytes... /// [StructLayout(LayoutKind.Sequential, Pack = 1, CharSet = CharSet.Ansi)] public struct TW_STR32 { /// /// We're stuck with this, because marshalling with packed alignment /// can't handle arrays... /// private byte byItem000; private byte byItem001; private byte byItem002; private byte byItem003; private byte byItem004; private byte byItem005; private byte byItem006; private byte byItem007; private byte byItem008; private byte byItem009; private byte byItem010; private byte byItem011; private byte byItem012; private byte byItem013; private byte byItem014; private byte byItem015; private byte byItem016; private byte byItem017; private byte byItem018; private byte byItem019; private byte byItem020; private byte byItem021; private byte byItem022; private byte byItem023; private byte byItem024; private byte byItem025; private byte byItem026; private byte byItem027; private byte byItem028; private byte byItem029; private byte byItem030; private byte byItem031; private byte byItem032; private byte byItem033; /// /// The normal get... /// /// public string Get() { return (GetValue(true)); } /// /// Use this on Mac OS X if you have a call that uses a string /// that doesn't include the prefix byte... /// /// public string GetNoPrefix() { return (GetValue(false)); } /// /// Get our value... /// /// private string GetValue(bool a_blMayHavePrefix) { // convert what we have into a byte array byte[] abyItem = new byte[34]; abyItem[0] = byItem000; abyItem[1] = byItem001; abyItem[2] = byItem002; abyItem[3] = byItem003; abyItem[4] = byItem004; abyItem[5] = byItem005; abyItem[6] = byItem006; abyItem[7] = byItem007; abyItem[8] = byItem008; abyItem[9] = byItem009; abyItem[10] = byItem010; abyItem[11] = byItem011; abyItem[12] = byItem012; abyItem[13] = byItem013; abyItem[14] = byItem014; abyItem[15] = byItem015; abyItem[16] = byItem016; abyItem[17] = byItem017; abyItem[18] = byItem018; abyItem[19] = byItem019; abyItem[20] = byItem020; abyItem[21] = byItem021; abyItem[22] = byItem022; abyItem[23] = byItem023; abyItem[24] = byItem024; abyItem[25] = byItem025; abyItem[26] = byItem026; abyItem[27] = byItem027; abyItem[28] = byItem028; abyItem[29] = byItem029; abyItem[30] = byItem030; abyItem[31] = byItem031; abyItem[32] = byItem032; abyItem[33] = byItem033; // Zero anything after the NUL... bool blNul = false; for (int ii = 0; ii < abyItem.Length; ii++) { if (!blNul && (abyItem[ii] == 0)) { blNul = true; } else if (blNul) { abyItem[ii] = 0; } } // change encoding of byte array, then convert the bytes array to a string string sz = Encoding.Unicode.GetString(Encoding.Convert(Language.GetEncoding(), Encoding.Unicode, abyItem)); // If the first character is a NUL, then return the empty string... while ((sz.Length > 0) && (sz[0] == '\0')) { sz = sz.Remove(0, 1); } // We have an emptry string... if (sz.Length == 0) { return (""); } // If we're running on a Mac, take off the prefix 'byte'... if (a_blMayHavePrefix && (TWAIN.GetPlatform() == Platform.MACOSX)) { sz = sz.Remove(0, 1); } // If we detect a NUL, then split around it... if (sz.IndexOf('\0') >= 0) { sz = sz.Split(new char[] { '\0' })[0]; } // All done... return (sz); } /// /// The normal set... /// /// public void Set(string a_sz) { SetValue(a_sz, true); } /// /// Use this on Mac OS X if you have a call that uses a string /// that doesn't include the prefix byte... /// /// public void SetNoPrefix(string a_sz) { SetValue(a_sz, false); } /// /// Set our value... /// /// private void SetValue(string a_sz, bool a_blMayHavePrefix) { // If we're running on a Mac, tack on the prefix 'byte'... if (a_sz == null) { a_sz = ""; } else if (a_blMayHavePrefix && (TWAIN.GetPlatform() == Platform.MACOSX)) { a_sz = (char)a_sz.Length + a_sz; } // Make sure that we're NUL padded... string sz = a_sz + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0"; if (sz.Length > 34) { sz = sz.Remove(34); } // convert string to byte array, then change the encoding of the byte array byte[] abyItem = Encoding.Convert(Encoding.Unicode, Language.GetEncoding(), Encoding.Unicode.GetBytes(sz)); // convert byte array to bytes if (abyItem.Length > 0) { byItem000 = abyItem[0]; byItem001 = abyItem[1]; byItem002 = abyItem[2]; byItem003 = abyItem[3]; byItem004 = abyItem[4]; byItem005 = abyItem[5]; byItem006 = abyItem[6]; byItem007 = abyItem[7]; byItem008 = abyItem[8]; byItem009 = abyItem[9]; byItem010 = abyItem[10]; byItem011 = abyItem[11]; byItem012 = abyItem[12]; byItem013 = abyItem[13]; byItem014 = abyItem[14]; byItem015 = abyItem[15]; byItem016 = abyItem[16]; byItem017 = abyItem[17]; byItem018 = abyItem[18]; byItem019 = abyItem[19]; byItem020 = abyItem[20]; byItem021 = abyItem[21]; byItem022 = abyItem[22]; byItem023 = abyItem[23]; byItem024 = abyItem[24]; byItem025 = abyItem[25]; byItem026 = abyItem[26]; byItem027 = abyItem[27]; byItem028 = abyItem[28]; byItem029 = abyItem[29]; byItem030 = abyItem[30]; byItem031 = abyItem[31]; byItem032 = abyItem[32]; byItem033 = abyItem[33]; } } } /// /// Used for strings that go up to 64-bytes... /// [StructLayout(LayoutKind.Sequential, Pack = 1, CharSet = CharSet.Ansi)] public struct TW_STR64 { /// /// We're stuck with this, because marshalling with packed alignment /// can't handle arrays... /// private byte byItem000; private byte byItem001; private byte byItem002; private byte byItem003; private byte byItem004; private byte byItem005; private byte byItem006; private byte byItem007; private byte byItem008; private byte byItem009; private byte byItem010; private byte byItem011; private byte byItem012; private byte byItem013; private byte byItem014; private byte byItem015; private byte byItem016; private byte byItem017; private byte byItem018; private byte byItem019; private byte byItem020; private byte byItem021; private byte byItem022; private byte byItem023; private byte byItem024; private byte byItem025; private byte byItem026; private byte byItem027; private byte byItem028; private byte byItem029; private byte byItem030; private byte byItem031; private byte byItem032; private byte byItem033; private byte byItem034; private byte byItem035; private byte byItem036; private byte byItem037; private byte byItem038; private byte byItem039; private byte byItem040; private byte byItem041; private byte byItem042; private byte byItem043; private byte byItem044; private byte byItem045; private byte byItem046; private byte byItem047; private byte byItem048; private byte byItem049; private byte byItem050; private byte byItem051; private byte byItem052; private byte byItem053; private byte byItem054; private byte byItem055; private byte byItem056; private byte byItem057; private byte byItem058; private byte byItem059; private byte byItem060; private byte byItem061; private byte byItem062; private byte byItem063; private byte byItem064; private byte byItem065; /// /// The normal get... /// /// public string Get() { return (GetValue(true)); } /// /// Use this on Mac OS X if you have a call that uses a string /// that doesn't include the prefix byte... /// /// public string GetNoPrefix() { return (GetValue(false)); } /// /// Get our value... /// /// private string GetValue(bool a_blMayHavePrefix) { // convert what we have into a byte array byte[] abyItem = new byte[66]; abyItem[0] = byItem000; abyItem[1] = byItem001; abyItem[2] = byItem002; abyItem[3] = byItem003; abyItem[4] = byItem004; abyItem[5] = byItem005; abyItem[6] = byItem006; abyItem[7] = byItem007; abyItem[8] = byItem008; abyItem[9] = byItem009; abyItem[10] = byItem010; abyItem[11] = byItem011; abyItem[12] = byItem012; abyItem[13] = byItem013; abyItem[14] = byItem014; abyItem[15] = byItem015; abyItem[16] = byItem016; abyItem[17] = byItem017; abyItem[18] = byItem018; abyItem[19] = byItem019; abyItem[20] = byItem020; abyItem[21] = byItem021; abyItem[22] = byItem022; abyItem[23] = byItem023; abyItem[24] = byItem024; abyItem[25] = byItem025; abyItem[26] = byItem026; abyItem[27] = byItem027; abyItem[28] = byItem028; abyItem[29] = byItem029; abyItem[30] = byItem030; abyItem[31] = byItem031; abyItem[32] = byItem032; abyItem[33] = byItem033; abyItem[34] = byItem034; abyItem[35] = byItem035; abyItem[36] = byItem036; abyItem[37] = byItem037; abyItem[38] = byItem038; abyItem[39] = byItem039; abyItem[40] = byItem040; abyItem[41] = byItem041; abyItem[42] = byItem042; abyItem[43] = byItem043; abyItem[44] = byItem044; abyItem[45] = byItem045; abyItem[46] = byItem046; abyItem[47] = byItem047; abyItem[48] = byItem048; abyItem[49] = byItem049; abyItem[50] = byItem050; abyItem[51] = byItem051; abyItem[52] = byItem052; abyItem[53] = byItem053; abyItem[54] = byItem054; abyItem[55] = byItem055; abyItem[56] = byItem056; abyItem[57] = byItem057; abyItem[58] = byItem058; abyItem[59] = byItem059; abyItem[60] = byItem060; abyItem[61] = byItem061; abyItem[62] = byItem062; abyItem[63] = byItem063; abyItem[64] = byItem064; abyItem[65] = byItem065; // Zero anything after the NUL... bool blNul = false; for (int ii = 0; ii < abyItem.Length; ii++) { if (!blNul && (abyItem[ii] == 0)) { blNul = true; } else if (blNul) { abyItem[ii] = 0; } } // change encoding of byte array, then convert the bytes array to a string string sz = Encoding.Unicode.GetString(Encoding.Convert(Language.GetEncoding(), Encoding.Unicode, abyItem)); // If the first character is a NUL, then return the empty string... if (sz[0] == '\0') { return (""); } // If we're running on a Mac, take off the prefix 'byte'... if (a_blMayHavePrefix && (TWAIN.GetPlatform() == Platform.MACOSX)) { sz = sz.Remove(0, 1); } // If we detect a NUL, then split around it... if (sz.IndexOf('\0') >= 0) { sz = sz.Split(new char[] { '\0' })[0]; } // All done... return (sz); } /// /// The normal set... /// /// public void Set(string a_sz) { SetValue(a_sz, true); } /// /// Use this on Mac OS X if you have a call that uses a string /// that doesn't include the prefix byte... /// /// public void SetNoPrefix(string a_sz) { SetValue(a_sz, false); } /// /// Set our value... /// /// private void SetValue(string a_sz, bool a_blMayHavePrefix) { // If we're running on a Mac, tack on the prefix 'byte'... if (a_sz == null) { a_sz = ""; } else if (a_blMayHavePrefix && (TWAIN.GetPlatform() == Platform.MACOSX)) { a_sz = (char)a_sz.Length + a_sz; } // Make sure that we're NUL padded... string sz = a_sz + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0"; if (sz.Length > 66) { sz = sz.Remove(66); } // convert string to byte array, then change the encoding of the byte array byte[] abyItem = Encoding.Convert(Encoding.Unicode, Language.GetEncoding(), Encoding.Unicode.GetBytes(sz)); // concert byte array to bytes byItem000 = abyItem[0]; byItem001 = abyItem[1]; byItem002 = abyItem[2]; byItem003 = abyItem[3]; byItem004 = abyItem[4]; byItem005 = abyItem[5]; byItem006 = abyItem[6]; byItem007 = abyItem[7]; byItem008 = abyItem[8]; byItem009 = abyItem[9]; byItem010 = abyItem[10]; byItem011 = abyItem[11]; byItem012 = abyItem[12]; byItem013 = abyItem[13]; byItem014 = abyItem[14]; byItem015 = abyItem[15]; byItem016 = abyItem[16]; byItem017 = abyItem[17]; byItem018 = abyItem[18]; byItem019 = abyItem[19]; byItem020 = abyItem[20]; byItem021 = abyItem[21]; byItem022 = abyItem[22]; byItem023 = abyItem[23]; byItem024 = abyItem[24]; byItem025 = abyItem[25]; byItem026 = abyItem[26]; byItem027 = abyItem[27]; byItem028 = abyItem[28]; byItem029 = abyItem[29]; byItem030 = abyItem[30]; byItem031 = abyItem[31]; byItem032 = abyItem[32]; byItem033 = abyItem[33]; byItem034 = abyItem[34]; byItem035 = abyItem[35]; byItem036 = abyItem[36]; byItem037 = abyItem[37]; byItem038 = abyItem[38]; byItem039 = abyItem[39]; byItem040 = abyItem[40]; byItem041 = abyItem[41]; byItem042 = abyItem[42]; byItem043 = abyItem[43]; byItem044 = abyItem[44]; byItem045 = abyItem[45]; byItem046 = abyItem[46]; byItem047 = abyItem[47]; byItem048 = abyItem[48]; byItem049 = abyItem[49]; byItem050 = abyItem[50]; byItem051 = abyItem[51]; byItem052 = abyItem[52]; byItem053 = abyItem[53]; byItem054 = abyItem[54]; byItem055 = abyItem[55]; byItem056 = abyItem[56]; byItem057 = abyItem[57]; byItem058 = abyItem[58]; byItem059 = abyItem[59]; byItem060 = abyItem[60]; byItem061 = abyItem[61]; byItem062 = abyItem[62]; byItem063 = abyItem[63]; byItem064 = abyItem[64]; byItem065 = abyItem[65]; } } /// /// Used for strings that go up to 128-bytes... /// [StructLayout(LayoutKind.Sequential, Pack = 1, CharSet = CharSet.Ansi)] public struct TW_STR128 { /// /// We're stuck with this, because marshalling with packed alignment /// can't handle arrays... /// private byte byItem000; private byte byItem001; private byte byItem002; private byte byItem003; private byte byItem004; private byte byItem005; private byte byItem006; private byte byItem007; private byte byItem008; private byte byItem009; private byte byItem010; private byte byItem011; private byte byItem012; private byte byItem013; private byte byItem014; private byte byItem015; private byte byItem016; private byte byItem017; private byte byItem018; private byte byItem019; private byte byItem020; private byte byItem021; private byte byItem022; private byte byItem023; private byte byItem024; private byte byItem025; private byte byItem026; private byte byItem027; private byte byItem028; private byte byItem029; private byte byItem030; private byte byItem031; private byte byItem032; private byte byItem033; private byte byItem034; private byte byItem035; private byte byItem036; private byte byItem037; private byte byItem038; private byte byItem039; private byte byItem040; private byte byItem041; private byte byItem042; private byte byItem043; private byte byItem044; private byte byItem045; private byte byItem046; private byte byItem047; private byte byItem048; private byte byItem049; private byte byItem050; private byte byItem051; private byte byItem052; private byte byItem053; private byte byItem054; private byte byItem055; private byte byItem056; private byte byItem057; private byte byItem058; private byte byItem059; private byte byItem060; private byte byItem061; private byte byItem062; private byte byItem063; private byte byItem064; private byte byItem065; private byte byItem066; private byte byItem067; private byte byItem068; private byte byItem069; private byte byItem070; private byte byItem071; private byte byItem072; private byte byItem073; private byte byItem074; private byte byItem075; private byte byItem076; private byte byItem077; private byte byItem078; private byte byItem079; private byte byItem080; private byte byItem081; private byte byItem082; private byte byItem083; private byte byItem084; private byte byItem085; private byte byItem086; private byte byItem087; private byte byItem088; private byte byItem089; private byte byItem090; private byte byItem091; private byte byItem092; private byte byItem093; private byte byItem094; private byte byItem095; private byte byItem096; private byte byItem097; private byte byItem098; private byte byItem099; private byte byItem100; private byte byItem101; private byte byItem102; private byte byItem103; private byte byItem104; private byte byItem105; private byte byItem106; private byte byItem107; private byte byItem108; private byte byItem109; private byte byItem110; private byte byItem111; private byte byItem112; private byte byItem113; private byte byItem114; private byte byItem115; private byte byItem116; private byte byItem117; private byte byItem118; private byte byItem119; private byte byItem120; private byte byItem121; private byte byItem122; private byte byItem123; private byte byItem124; private byte byItem125; private byte byItem126; private byte byItem127; private byte byItem128; private byte byItem129; /// /// The normal get... /// /// public string Get() { return (GetValue(true)); } /// /// Use this on Mac OS X if you have a call that uses a string /// that doesn't include the prefix byte... /// /// public string GetNoPrefix() { return (GetValue(false)); } /// /// Get our value... /// /// private string GetValue(bool a_blMayHavePrefix) { // convert what we have into a byte array byte[] abyItem = new byte[130]; abyItem[0] = byItem000; abyItem[1] = byItem001; abyItem[2] = byItem002; abyItem[3] = byItem003; abyItem[4] = byItem004; abyItem[5] = byItem005; abyItem[6] = byItem006; abyItem[7] = byItem007; abyItem[8] = byItem008; abyItem[9] = byItem009; abyItem[10] = byItem010; abyItem[11] = byItem011; abyItem[12] = byItem012; abyItem[13] = byItem013; abyItem[14] = byItem014; abyItem[15] = byItem015; abyItem[16] = byItem016; abyItem[17] = byItem017; abyItem[18] = byItem018; abyItem[19] = byItem019; abyItem[20] = byItem020; abyItem[21] = byItem021; abyItem[22] = byItem022; abyItem[23] = byItem023; abyItem[24] = byItem024; abyItem[25] = byItem025; abyItem[26] = byItem026; abyItem[27] = byItem027; abyItem[28] = byItem028; abyItem[29] = byItem029; abyItem[30] = byItem030; abyItem[31] = byItem031; abyItem[32] = byItem032; abyItem[33] = byItem033; abyItem[34] = byItem034; abyItem[35] = byItem035; abyItem[36] = byItem036; abyItem[37] = byItem037; abyItem[38] = byItem038; abyItem[39] = byItem039; abyItem[40] = byItem040; abyItem[41] = byItem041; abyItem[42] = byItem042; abyItem[43] = byItem043; abyItem[44] = byItem044; abyItem[45] = byItem045; abyItem[46] = byItem046; abyItem[47] = byItem047; abyItem[48] = byItem048; abyItem[49] = byItem049; abyItem[50] = byItem050; abyItem[51] = byItem051; abyItem[52] = byItem052; abyItem[53] = byItem053; abyItem[54] = byItem054; abyItem[55] = byItem055; abyItem[56] = byItem056; abyItem[57] = byItem057; abyItem[58] = byItem058; abyItem[59] = byItem059; abyItem[60] = byItem060; abyItem[61] = byItem061; abyItem[62] = byItem062; abyItem[63] = byItem063; abyItem[64] = byItem064; abyItem[65] = byItem065; abyItem[66] = byItem066; abyItem[67] = byItem067; abyItem[68] = byItem068; abyItem[69] = byItem069; abyItem[70] = byItem070; abyItem[71] = byItem071; abyItem[72] = byItem072; abyItem[73] = byItem073; abyItem[74] = byItem074; abyItem[75] = byItem075; abyItem[76] = byItem076; abyItem[77] = byItem077; abyItem[78] = byItem078; abyItem[79] = byItem079; abyItem[80] = byItem080; abyItem[81] = byItem081; abyItem[82] = byItem082; abyItem[83] = byItem083; abyItem[84] = byItem084; abyItem[85] = byItem085; abyItem[86] = byItem086; abyItem[87] = byItem087; abyItem[88] = byItem088; abyItem[89] = byItem089; abyItem[90] = byItem090; abyItem[91] = byItem091; abyItem[92] = byItem092; abyItem[93] = byItem093; abyItem[94] = byItem094; abyItem[95] = byItem095; abyItem[96] = byItem096; abyItem[97] = byItem097; abyItem[98] = byItem098; abyItem[99] = byItem099; abyItem[100] = byItem100; abyItem[101] = byItem101; abyItem[102] = byItem102; abyItem[103] = byItem103; abyItem[104] = byItem104; abyItem[105] = byItem105; abyItem[106] = byItem106; abyItem[107] = byItem107; abyItem[108] = byItem108; abyItem[109] = byItem109; abyItem[110] = byItem110; abyItem[111] = byItem111; abyItem[112] = byItem112; abyItem[113] = byItem113; abyItem[114] = byItem114; abyItem[115] = byItem115; abyItem[116] = byItem116; abyItem[117] = byItem117; abyItem[118] = byItem118; abyItem[119] = byItem119; abyItem[120] = byItem120; abyItem[121] = byItem121; abyItem[122] = byItem122; abyItem[123] = byItem123; abyItem[124] = byItem124; abyItem[125] = byItem125; abyItem[126] = byItem126; abyItem[127] = byItem127; abyItem[128] = byItem128; abyItem[129] = byItem129; // Zero anything after the NUL... bool blNul = false; for (int ii = 0; ii < abyItem.Length; ii++) { if (!blNul && (abyItem[ii] == 0)) { blNul = true; } else if (blNul) { abyItem[ii] = 0; } } // change encoding of byte array, then convert the bytes array to a string string sz = Encoding.Unicode.GetString(Encoding.Convert(Language.GetEncoding(), Encoding.Unicode, abyItem)); // If the first character is a NUL, then return the empty string... if (sz[0] == '\0') { return (""); } // If we're running on a Mac, take off the prefix 'byte'... if (a_blMayHavePrefix && (TWAIN.GetPlatform() == Platform.MACOSX)) { sz = sz.Remove(0, 1); } // If we detect a NUL, then split around it... if (sz.IndexOf('\0') >= 0) { sz = sz.Split(new char[] { '\0' })[0]; } // All done... return (sz); } /// /// The normal set... /// /// public void Set(string a_sz) { SetValue(a_sz, true); } /// /// Use this on Mac OS X if you have a call that uses a string /// that doesn't include the prefix byte... /// /// public void SetNoPrefix(string a_sz) { SetValue(a_sz, false); } /// /// Set our value... /// /// private void SetValue(string a_sz, bool a_blMayHavePrefix) { // If we're running on a Mac, tack on the prefix 'byte'... if (a_sz == null) { a_sz = ""; } else if (a_blMayHavePrefix && (TWAIN.GetPlatform() == Platform.MACOSX)) { a_sz = (char)a_sz.Length + a_sz; } // Make sure that we're NUL padded... string sz = a_sz + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0"; if (sz.Length > 130) { sz = sz.Remove(130); } // convert string to byte array, then change the encoding of the byte array byte[] abyItem = Encoding.Convert(Encoding.Unicode, Language.GetEncoding(), Encoding.Unicode.GetBytes(sz)); // concert byte array to bytes byItem000 = abyItem[0]; byItem001 = abyItem[1]; byItem002 = abyItem[2]; byItem003 = abyItem[3]; byItem004 = abyItem[4]; byItem005 = abyItem[5]; byItem006 = abyItem[6]; byItem007 = abyItem[7]; byItem008 = abyItem[8]; byItem009 = abyItem[9]; byItem010 = abyItem[10]; byItem011 = abyItem[11]; byItem012 = abyItem[12]; byItem013 = abyItem[13]; byItem014 = abyItem[14]; byItem015 = abyItem[15]; byItem016 = abyItem[16]; byItem017 = abyItem[17]; byItem018 = abyItem[18]; byItem019 = abyItem[19]; byItem020 = abyItem[20]; byItem021 = abyItem[21]; byItem022 = abyItem[22]; byItem023 = abyItem[23]; byItem024 = abyItem[24]; byItem025 = abyItem[25]; byItem026 = abyItem[26]; byItem027 = abyItem[27]; byItem028 = abyItem[28]; byItem029 = abyItem[29]; byItem030 = abyItem[30]; byItem031 = abyItem[31]; byItem032 = abyItem[32]; byItem033 = abyItem[33]; byItem034 = abyItem[34]; byItem035 = abyItem[35]; byItem036 = abyItem[36]; byItem037 = abyItem[37]; byItem038 = abyItem[38]; byItem039 = abyItem[39]; byItem040 = abyItem[40]; byItem041 = abyItem[41]; byItem042 = abyItem[42]; byItem043 = abyItem[43]; byItem044 = abyItem[44]; byItem045 = abyItem[45]; byItem046 = abyItem[46]; byItem047 = abyItem[47]; byItem048 = abyItem[48]; byItem049 = abyItem[49]; byItem050 = abyItem[50]; byItem051 = abyItem[51]; byItem052 = abyItem[52]; byItem053 = abyItem[53]; byItem054 = abyItem[54]; byItem055 = abyItem[55]; byItem056 = abyItem[56]; byItem057 = abyItem[57]; byItem058 = abyItem[58]; byItem059 = abyItem[59]; byItem060 = abyItem[60]; byItem061 = abyItem[61]; byItem062 = abyItem[62]; byItem063 = abyItem[63]; byItem064 = abyItem[64]; byItem065 = abyItem[65]; byItem066 = abyItem[66]; byItem067 = abyItem[67]; byItem068 = abyItem[68]; byItem069 = abyItem[69]; byItem070 = abyItem[70]; byItem071 = abyItem[71]; byItem072 = abyItem[72]; byItem073 = abyItem[73]; byItem074 = abyItem[74]; byItem075 = abyItem[75]; byItem076 = abyItem[76]; byItem077 = abyItem[77]; byItem078 = abyItem[78]; byItem079 = abyItem[79]; byItem080 = abyItem[80]; byItem081 = abyItem[81]; byItem082 = abyItem[82]; byItem083 = abyItem[83]; byItem084 = abyItem[84]; byItem085 = abyItem[85]; byItem086 = abyItem[86]; byItem087 = abyItem[87]; byItem088 = abyItem[88]; byItem089 = abyItem[89]; byItem090 = abyItem[90]; byItem091 = abyItem[91]; byItem092 = abyItem[92]; byItem093 = abyItem[93]; byItem094 = abyItem[94]; byItem095 = abyItem[95]; byItem096 = abyItem[96]; byItem097 = abyItem[97]; byItem098 = abyItem[98]; byItem099 = abyItem[99]; byItem100 = abyItem[100]; byItem101 = abyItem[101]; byItem102 = abyItem[102]; byItem103 = abyItem[103]; byItem104 = abyItem[104]; byItem105 = abyItem[105]; byItem106 = abyItem[106]; byItem107 = abyItem[107]; byItem108 = abyItem[108]; byItem109 = abyItem[109]; byItem110 = abyItem[110]; byItem111 = abyItem[111]; byItem112 = abyItem[112]; byItem113 = abyItem[113]; byItem114 = abyItem[114]; byItem115 = abyItem[115]; byItem116 = abyItem[116]; byItem117 = abyItem[117]; byItem118 = abyItem[118]; byItem119 = abyItem[119]; byItem120 = abyItem[120]; byItem121 = abyItem[121]; byItem122 = abyItem[122]; byItem123 = abyItem[123]; byItem124 = abyItem[124]; byItem125 = abyItem[125]; byItem126 = abyItem[126]; byItem127 = abyItem[127]; byItem128 = abyItem[128]; byItem129 = abyItem[129]; } } /// /// Used for strings that go up to 256-bytes... /// [StructLayout(LayoutKind.Sequential, Pack = 1, CharSet = CharSet.Ansi)] public struct TW_STR255 { /// /// We're stuck with this, because marshalling with packed alignment /// can't handle arrays... /// private byte byItem000; private byte byItem001; private byte byItem002; private byte byItem003; private byte byItem004; private byte byItem005; private byte byItem006; private byte byItem007; private byte byItem008; private byte byItem009; private byte byItem010; private byte byItem011; private byte byItem012; private byte byItem013; private byte byItem014; private byte byItem015; private byte byItem016; private byte byItem017; private byte byItem018; private byte byItem019; private byte byItem020; private byte byItem021; private byte byItem022; private byte byItem023; private byte byItem024; private byte byItem025; private byte byItem026; private byte byItem027; private byte byItem028; private byte byItem029; private byte byItem030; private byte byItem031; private byte byItem032; private byte byItem033; private byte byItem034; private byte byItem035; private byte byItem036; private byte byItem037; private byte byItem038; private byte byItem039; private byte byItem040; private byte byItem041; private byte byItem042; private byte byItem043; private byte byItem044; private byte byItem045; private byte byItem046; private byte byItem047; private byte byItem048; private byte byItem049; private byte byItem050; private byte byItem051; private byte byItem052; private byte byItem053; private byte byItem054; private byte byItem055; private byte byItem056; private byte byItem057; private byte byItem058; private byte byItem059; private byte byItem060; private byte byItem061; private byte byItem062; private byte byItem063; private byte byItem064; private byte byItem065; private byte byItem066; private byte byItem067; private byte byItem068; private byte byItem069; private byte byItem070; private byte byItem071; private byte byItem072; private byte byItem073; private byte byItem074; private byte byItem075; private byte byItem076; private byte byItem077; private byte byItem078; private byte byItem079; private byte byItem080; private byte byItem081; private byte byItem082; private byte byItem083; private byte byItem084; private byte byItem085; private byte byItem086; private byte byItem087; private byte byItem088; private byte byItem089; private byte byItem090; private byte byItem091; private byte byItem092; private byte byItem093; private byte byItem094; private byte byItem095; private byte byItem096; private byte byItem097; private byte byItem098; private byte byItem099; private byte byItem100; private byte byItem101; private byte byItem102; private byte byItem103; private byte byItem104; private byte byItem105; private byte byItem106; private byte byItem107; private byte byItem108; private byte byItem109; private byte byItem110; private byte byItem111; private byte byItem112; private byte byItem113; private byte byItem114; private byte byItem115; private byte byItem116; private byte byItem117; private byte byItem118; private byte byItem119; private byte byItem120; private byte byItem121; private byte byItem122; private byte byItem123; private byte byItem124; private byte byItem125; private byte byItem126; private byte byItem127; private byte byItem128; private byte byItem129; private byte byItem130; private byte byItem131; private byte byItem132; private byte byItem133; private byte byItem134; private byte byItem135; private byte byItem136; private byte byItem137; private byte byItem138; private byte byItem139; private byte byItem140; private byte byItem141; private byte byItem142; private byte byItem143; private byte byItem144; private byte byItem145; private byte byItem146; private byte byItem147; private byte byItem148; private byte byItem149; private byte byItem150; private byte byItem151; private byte byItem152; private byte byItem153; private byte byItem154; private byte byItem155; private byte byItem156; private byte byItem157; private byte byItem158; private byte byItem159; private byte byItem160; private byte byItem161; private byte byItem162; private byte byItem163; private byte byItem164; private byte byItem165; private byte byItem166; private byte byItem167; private byte byItem168; private byte byItem169; private byte byItem170; private byte byItem171; private byte byItem172; private byte byItem173; private byte byItem174; private byte byItem175; private byte byItem176; private byte byItem177; private byte byItem178; private byte byItem179; private byte byItem180; private byte byItem181; private byte byItem182; private byte byItem183; private byte byItem184; private byte byItem185; private byte byItem186; private byte byItem187; private byte byItem188; private byte byItem189; private byte byItem190; private byte byItem191; private byte byItem192; private byte byItem193; private byte byItem194; private byte byItem195; private byte byItem196; private byte byItem197; private byte byItem198; private byte byItem199; private byte byItem200; private byte byItem201; private byte byItem202; private byte byItem203; private byte byItem204; private byte byItem205; private byte byItem206; private byte byItem207; private byte byItem208; private byte byItem209; private byte byItem210; private byte byItem211; private byte byItem212; private byte byItem213; private byte byItem214; private byte byItem215; private byte byItem216; private byte byItem217; private byte byItem218; private byte byItem219; private byte byItem220; private byte byItem221; private byte byItem222; private byte byItem223; private byte byItem224; private byte byItem225; private byte byItem226; private byte byItem227; private byte byItem228; private byte byItem229; private byte byItem230; private byte byItem231; private byte byItem232; private byte byItem233; private byte byItem234; private byte byItem235; private byte byItem236; private byte byItem237; private byte byItem238; private byte byItem239; private byte byItem240; private byte byItem241; private byte byItem242; private byte byItem243; private byte byItem244; private byte byItem245; private byte byItem246; private byte byItem247; private byte byItem248; private byte byItem249; private byte byItem250; private byte byItem251; private byte byItem252; private byte byItem253; private byte byItem254; private byte byItem255; /// /// The normal get... /// /// public string Get() { return (GetValue(true)); } /// /// Use this on Mac OS X if you have a call that uses a string /// that doesn't include the prefix byte... /// /// public string GetNoPrefix() { return (GetValue(false)); } /// /// Get our value... /// /// private string GetValue(bool a_blMayHavePrefix) { // convert what we have into a byte array byte[] abyItem = new byte[256]; abyItem[0] = byItem000; abyItem[1] = byItem001; abyItem[2] = byItem002; abyItem[3] = byItem003; abyItem[4] = byItem004; abyItem[5] = byItem005; abyItem[6] = byItem006; abyItem[7] = byItem007; abyItem[8] = byItem008; abyItem[9] = byItem009; abyItem[10] = byItem010; abyItem[11] = byItem011; abyItem[12] = byItem012; abyItem[13] = byItem013; abyItem[14] = byItem014; abyItem[15] = byItem015; abyItem[16] = byItem016; abyItem[17] = byItem017; abyItem[18] = byItem018; abyItem[19] = byItem019; abyItem[20] = byItem020; abyItem[21] = byItem021; abyItem[22] = byItem022; abyItem[23] = byItem023; abyItem[24] = byItem024; abyItem[25] = byItem025; abyItem[26] = byItem026; abyItem[27] = byItem027; abyItem[28] = byItem028; abyItem[29] = byItem029; abyItem[30] = byItem030; abyItem[31] = byItem031; abyItem[32] = byItem032; abyItem[33] = byItem033; abyItem[34] = byItem034; abyItem[35] = byItem035; abyItem[36] = byItem036; abyItem[37] = byItem037; abyItem[38] = byItem038; abyItem[39] = byItem039; abyItem[40] = byItem040; abyItem[41] = byItem041; abyItem[42] = byItem042; abyItem[43] = byItem043; abyItem[44] = byItem044; abyItem[45] = byItem045; abyItem[46] = byItem046; abyItem[47] = byItem047; abyItem[48] = byItem048; abyItem[49] = byItem049; abyItem[50] = byItem050; abyItem[51] = byItem051; abyItem[52] = byItem052; abyItem[53] = byItem053; abyItem[54] = byItem054; abyItem[55] = byItem055; abyItem[56] = byItem056; abyItem[57] = byItem057; abyItem[58] = byItem058; abyItem[59] = byItem059; abyItem[60] = byItem060; abyItem[61] = byItem061; abyItem[62] = byItem062; abyItem[63] = byItem063; abyItem[64] = byItem064; abyItem[65] = byItem065; abyItem[66] = byItem066; abyItem[67] = byItem067; abyItem[68] = byItem068; abyItem[69] = byItem069; abyItem[70] = byItem070; abyItem[71] = byItem071; abyItem[72] = byItem072; abyItem[73] = byItem073; abyItem[74] = byItem074; abyItem[75] = byItem075; abyItem[76] = byItem076; abyItem[77] = byItem077; abyItem[78] = byItem078; abyItem[79] = byItem079; abyItem[80] = byItem080; abyItem[81] = byItem081; abyItem[82] = byItem082; abyItem[83] = byItem083; abyItem[84] = byItem084; abyItem[85] = byItem085; abyItem[86] = byItem086; abyItem[87] = byItem087; abyItem[88] = byItem088; abyItem[89] = byItem089; abyItem[90] = byItem090; abyItem[91] = byItem091; abyItem[92] = byItem092; abyItem[93] = byItem093; abyItem[94] = byItem094; abyItem[95] = byItem095; abyItem[96] = byItem096; abyItem[97] = byItem097; abyItem[98] = byItem098; abyItem[99] = byItem099; abyItem[100] = byItem100; abyItem[101] = byItem101; abyItem[102] = byItem102; abyItem[103] = byItem103; abyItem[104] = byItem104; abyItem[105] = byItem105; abyItem[106] = byItem106; abyItem[107] = byItem107; abyItem[108] = byItem108; abyItem[109] = byItem109; abyItem[110] = byItem110; abyItem[111] = byItem111; abyItem[112] = byItem112; abyItem[113] = byItem113; abyItem[114] = byItem114; abyItem[115] = byItem115; abyItem[116] = byItem116; abyItem[117] = byItem117; abyItem[118] = byItem118; abyItem[119] = byItem119; abyItem[120] = byItem120; abyItem[121] = byItem121; abyItem[122] = byItem122; abyItem[123] = byItem123; abyItem[124] = byItem124; abyItem[125] = byItem125; abyItem[126] = byItem126; abyItem[127] = byItem127; abyItem[128] = byItem128; abyItem[129] = byItem129; abyItem[130] = byItem130; abyItem[131] = byItem131; abyItem[132] = byItem132; abyItem[133] = byItem133; abyItem[134] = byItem134; abyItem[135] = byItem135; abyItem[136] = byItem136; abyItem[137] = byItem137; abyItem[138] = byItem138; abyItem[139] = byItem139; abyItem[140] = byItem140; abyItem[141] = byItem141; abyItem[142] = byItem142; abyItem[143] = byItem143; abyItem[144] = byItem144; abyItem[145] = byItem145; abyItem[146] = byItem146; abyItem[147] = byItem147; abyItem[148] = byItem148; abyItem[149] = byItem149; abyItem[150] = byItem150; abyItem[151] = byItem151; abyItem[152] = byItem152; abyItem[153] = byItem153; abyItem[154] = byItem154; abyItem[155] = byItem155; abyItem[156] = byItem156; abyItem[157] = byItem157; abyItem[158] = byItem158; abyItem[159] = byItem159; abyItem[160] = byItem160; abyItem[161] = byItem161; abyItem[162] = byItem162; abyItem[163] = byItem163; abyItem[164] = byItem164; abyItem[165] = byItem165; abyItem[166] = byItem166; abyItem[167] = byItem167; abyItem[168] = byItem168; abyItem[169] = byItem169; abyItem[170] = byItem170; abyItem[171] = byItem171; abyItem[172] = byItem172; abyItem[173] = byItem173; abyItem[174] = byItem174; abyItem[175] = byItem175; abyItem[176] = byItem176; abyItem[177] = byItem177; abyItem[178] = byItem178; abyItem[179] = byItem179; abyItem[180] = byItem180; abyItem[181] = byItem181; abyItem[182] = byItem182; abyItem[183] = byItem183; abyItem[184] = byItem184; abyItem[185] = byItem185; abyItem[186] = byItem186; abyItem[187] = byItem187; abyItem[188] = byItem188; abyItem[189] = byItem189; abyItem[190] = byItem190; abyItem[191] = byItem191; abyItem[192] = byItem192; abyItem[193] = byItem193; abyItem[194] = byItem194; abyItem[195] = byItem195; abyItem[196] = byItem196; abyItem[197] = byItem197; abyItem[198] = byItem198; abyItem[199] = byItem199; abyItem[200] = byItem200; abyItem[201] = byItem201; abyItem[202] = byItem202; abyItem[203] = byItem203; abyItem[204] = byItem204; abyItem[205] = byItem205; abyItem[206] = byItem206; abyItem[207] = byItem207; abyItem[208] = byItem208; abyItem[209] = byItem209; abyItem[210] = byItem210; abyItem[211] = byItem211; abyItem[212] = byItem212; abyItem[213] = byItem213; abyItem[214] = byItem214; abyItem[215] = byItem215; abyItem[216] = byItem216; abyItem[217] = byItem217; abyItem[218] = byItem218; abyItem[219] = byItem219; abyItem[220] = byItem220; abyItem[221] = byItem221; abyItem[222] = byItem222; abyItem[223] = byItem223; abyItem[224] = byItem224; abyItem[225] = byItem225; abyItem[226] = byItem226; abyItem[227] = byItem227; abyItem[228] = byItem228; abyItem[229] = byItem229; abyItem[230] = byItem230; abyItem[231] = byItem231; abyItem[232] = byItem232; abyItem[233] = byItem233; abyItem[234] = byItem234; abyItem[235] = byItem235; abyItem[236] = byItem236; abyItem[237] = byItem237; abyItem[238] = byItem238; abyItem[239] = byItem239; abyItem[240] = byItem240; abyItem[241] = byItem241; abyItem[242] = byItem242; abyItem[243] = byItem243; abyItem[244] = byItem244; abyItem[245] = byItem245; abyItem[246] = byItem246; abyItem[247] = byItem247; abyItem[248] = byItem248; abyItem[249] = byItem249; abyItem[250] = byItem250; abyItem[251] = byItem251; abyItem[252] = byItem252; abyItem[253] = byItem253; abyItem[254] = byItem254; abyItem[255] = byItem255; // Zero anything after the NUL... bool blNul = false; for (int ii = 0; ii < abyItem.Length; ii++) { if (!blNul && (abyItem[ii] == 0)) { blNul = true; } else if (blNul) { abyItem[ii] = 0; } } // change encoding of byte array, then convert the bytes array to a string string sz = Encoding.Unicode.GetString(Encoding.Convert(Language.GetEncoding(), Encoding.Unicode, abyItem)); // If the first character is a NUL, then return the empty string... if (sz[0] == '\0') { return (""); } // If we're running on a Mac, take off the prefix 'byte'... if (a_blMayHavePrefix && (TWAIN.GetPlatform() == Platform.MACOSX)) { sz = sz.Remove(0, 1); } // If we detect a NUL, then split around it... if (sz.IndexOf('\0') >= 0) { sz = sz.Split(new char[] { '\0' })[0]; } // All done... return (sz); } /// /// The normal set... /// /// public void Set(string a_sz) { SetValue(a_sz, true); } /// /// Use this on Mac OS X if you have a call that uses a string /// that doesn't include the prefix byte... /// /// public void SetNoPrefix(string a_sz) { SetValue(a_sz, false); } /// /// Set our value... /// /// private void SetValue(string a_sz, bool a_blMayHavePrefix) { // If we're running on a Mac, tack on the prefix 'byte'... if (a_sz == null) { a_sz = ""; } else if (a_blMayHavePrefix && (TWAIN.GetPlatform() == Platform.MACOSX)) { a_sz = (char)a_sz.Length + a_sz; } // Make sure that we're NUL padded... string sz = a_sz + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"; if (sz.Length > 256) { sz = sz.Remove(256); } // convert string to byte array, then change the encoding of the byte array byte[] abyItem = Encoding.Convert(Encoding.Unicode, Language.GetEncoding(), Encoding.Unicode.GetBytes(sz)); // concert byte array to bytes byItem000 = abyItem[0]; byItem001 = abyItem[1]; byItem002 = abyItem[2]; byItem003 = abyItem[3]; byItem004 = abyItem[4]; byItem005 = abyItem[5]; byItem006 = abyItem[6]; byItem007 = abyItem[7]; byItem008 = abyItem[8]; byItem009 = abyItem[9]; byItem010 = abyItem[10]; byItem011 = abyItem[11]; byItem012 = abyItem[12]; byItem013 = abyItem[13]; byItem014 = abyItem[14]; byItem015 = abyItem[15]; byItem016 = abyItem[16]; byItem017 = abyItem[17]; byItem018 = abyItem[18]; byItem019 = abyItem[19]; byItem020 = abyItem[20]; byItem021 = abyItem[21]; byItem022 = abyItem[22]; byItem023 = abyItem[23]; byItem024 = abyItem[24]; byItem025 = abyItem[25]; byItem026 = abyItem[26]; byItem027 = abyItem[27]; byItem028 = abyItem[28]; byItem029 = abyItem[29]; byItem030 = abyItem[30]; byItem031 = abyItem[31]; byItem032 = abyItem[32]; byItem033 = abyItem[33]; byItem034 = abyItem[34]; byItem035 = abyItem[35]; byItem036 = abyItem[36]; byItem037 = abyItem[37]; byItem038 = abyItem[38]; byItem039 = abyItem[39]; byItem040 = abyItem[40]; byItem041 = abyItem[41]; byItem042 = abyItem[42]; byItem043 = abyItem[43]; byItem044 = abyItem[44]; byItem045 = abyItem[45]; byItem046 = abyItem[46]; byItem047 = abyItem[47]; byItem048 = abyItem[48]; byItem049 = abyItem[49]; byItem050 = abyItem[50]; byItem051 = abyItem[51]; byItem052 = abyItem[52]; byItem053 = abyItem[53]; byItem054 = abyItem[54]; byItem055 = abyItem[55]; byItem056 = abyItem[56]; byItem057 = abyItem[57]; byItem058 = abyItem[58]; byItem059 = abyItem[59]; byItem060 = abyItem[60]; byItem061 = abyItem[61]; byItem062 = abyItem[62]; byItem063 = abyItem[63]; byItem064 = abyItem[64]; byItem065 = abyItem[65]; byItem066 = abyItem[66]; byItem067 = abyItem[67]; byItem068 = abyItem[68]; byItem069 = abyItem[69]; byItem070 = abyItem[70]; byItem071 = abyItem[71]; byItem072 = abyItem[72]; byItem073 = abyItem[73]; byItem074 = abyItem[74]; byItem075 = abyItem[75]; byItem076 = abyItem[76]; byItem077 = abyItem[77]; byItem078 = abyItem[78]; byItem079 = abyItem[79]; byItem080 = abyItem[80]; byItem081 = abyItem[81]; byItem082 = abyItem[82]; byItem083 = abyItem[83]; byItem084 = abyItem[84]; byItem085 = abyItem[85]; byItem086 = abyItem[86]; byItem087 = abyItem[87]; byItem088 = abyItem[88]; byItem089 = abyItem[89]; byItem090 = abyItem[90]; byItem091 = abyItem[91]; byItem092 = abyItem[92]; byItem093 = abyItem[93]; byItem094 = abyItem[94]; byItem095 = abyItem[95]; byItem096 = abyItem[96]; byItem097 = abyItem[97]; byItem098 = abyItem[98]; byItem099 = abyItem[99]; byItem100 = abyItem[100]; byItem101 = abyItem[101]; byItem102 = abyItem[102]; byItem103 = abyItem[103]; byItem104 = abyItem[104]; byItem105 = abyItem[105]; byItem106 = abyItem[106]; byItem107 = abyItem[107]; byItem108 = abyItem[108]; byItem109 = abyItem[109]; byItem110 = abyItem[110]; byItem111 = abyItem[111]; byItem112 = abyItem[112]; byItem113 = abyItem[113]; byItem114 = abyItem[114]; byItem115 = abyItem[115]; byItem116 = abyItem[116]; byItem117 = abyItem[117]; byItem118 = abyItem[118]; byItem119 = abyItem[119]; byItem120 = abyItem[120]; byItem121 = abyItem[121]; byItem122 = abyItem[122]; byItem123 = abyItem[123]; byItem124 = abyItem[124]; byItem125 = abyItem[125]; byItem126 = abyItem[126]; byItem127 = abyItem[127]; byItem128 = abyItem[128]; byItem129 = abyItem[129]; byItem130 = abyItem[130]; byItem131 = abyItem[131]; byItem132 = abyItem[132]; byItem133 = abyItem[133]; byItem134 = abyItem[134]; byItem135 = abyItem[135]; byItem136 = abyItem[136]; byItem137 = abyItem[137]; byItem138 = abyItem[138]; byItem139 = abyItem[139]; byItem140 = abyItem[140]; byItem141 = abyItem[141]; byItem142 = abyItem[142]; byItem143 = abyItem[143]; byItem144 = abyItem[144]; byItem145 = abyItem[145]; byItem146 = abyItem[146]; byItem147 = abyItem[147]; byItem148 = abyItem[148]; byItem149 = abyItem[149]; byItem150 = abyItem[150]; byItem151 = abyItem[151]; byItem152 = abyItem[152]; byItem153 = abyItem[153]; byItem154 = abyItem[154]; byItem155 = abyItem[155]; byItem156 = abyItem[156]; byItem157 = abyItem[157]; byItem158 = abyItem[158]; byItem159 = abyItem[159]; byItem160 = abyItem[160]; byItem161 = abyItem[161]; byItem162 = abyItem[162]; byItem163 = abyItem[163]; byItem164 = abyItem[164]; byItem165 = abyItem[165]; byItem166 = abyItem[166]; byItem167 = abyItem[167]; byItem168 = abyItem[168]; byItem169 = abyItem[169]; byItem170 = abyItem[170]; byItem171 = abyItem[171]; byItem172 = abyItem[172]; byItem173 = abyItem[173]; byItem174 = abyItem[174]; byItem175 = abyItem[175]; byItem176 = abyItem[176]; byItem177 = abyItem[177]; byItem178 = abyItem[178]; byItem179 = abyItem[179]; byItem180 = abyItem[180]; byItem181 = abyItem[181]; byItem182 = abyItem[182]; byItem183 = abyItem[183]; byItem184 = abyItem[184]; byItem185 = abyItem[185]; byItem186 = abyItem[186]; byItem187 = abyItem[187]; byItem188 = abyItem[188]; byItem189 = abyItem[189]; byItem190 = abyItem[190]; byItem191 = abyItem[191]; byItem192 = abyItem[192]; byItem193 = abyItem[193]; byItem194 = abyItem[194]; byItem195 = abyItem[195]; byItem196 = abyItem[196]; byItem197 = abyItem[197]; byItem198 = abyItem[198]; byItem199 = abyItem[199]; byItem200 = abyItem[200]; byItem201 = abyItem[201]; byItem202 = abyItem[202]; byItem203 = abyItem[203]; byItem204 = abyItem[204]; byItem205 = abyItem[205]; byItem206 = abyItem[206]; byItem207 = abyItem[207]; byItem208 = abyItem[208]; byItem209 = abyItem[209]; byItem210 = abyItem[210]; byItem211 = abyItem[211]; byItem212 = abyItem[212]; byItem213 = abyItem[213]; byItem214 = abyItem[214]; byItem215 = abyItem[215]; byItem216 = abyItem[216]; byItem217 = abyItem[217]; byItem218 = abyItem[218]; byItem219 = abyItem[219]; byItem220 = abyItem[220]; byItem221 = abyItem[221]; byItem222 = abyItem[222]; byItem223 = abyItem[223]; byItem224 = abyItem[224]; byItem225 = abyItem[225]; byItem226 = abyItem[226]; byItem227 = abyItem[227]; byItem228 = abyItem[228]; byItem229 = abyItem[229]; byItem230 = abyItem[230]; byItem231 = abyItem[231]; byItem232 = abyItem[232]; byItem233 = abyItem[233]; byItem234 = abyItem[234]; byItem235 = abyItem[235]; byItem236 = abyItem[236]; byItem237 = abyItem[237]; byItem238 = abyItem[238]; byItem239 = abyItem[239]; byItem240 = abyItem[240]; byItem241 = abyItem[241]; byItem242 = abyItem[242]; byItem243 = abyItem[243]; byItem244 = abyItem[244]; byItem245 = abyItem[245]; byItem246 = abyItem[246]; byItem247 = abyItem[247]; byItem248 = abyItem[248]; byItem249 = abyItem[249]; byItem250 = abyItem[250]; byItem251 = abyItem[251]; byItem252 = abyItem[252]; byItem253 = abyItem[253]; byItem254 = abyItem[254]; byItem255 = abyItem[255]; } } #endregion /////////////////////////////////////////////////////////////////////////////// // Structure Definitions... /////////////////////////////////////////////////////////////////////////////// #region Structure Definitions.. /// /// Fixed point structure type. /// [StructLayout(LayoutKind.Sequential, Pack = 2)] public struct TW_FIX32 { public short Whole; public ushort Frac; } /// /// Defines a frame rectangle in ICAP_UNITS coordinates. /// [StructLayout(LayoutKind.Sequential, Pack = 2)] public struct TW_FRAME { public TW_FIX32 Left; public TW_FIX32 Top; public TW_FIX32 Right; public TW_FIX32 Bottom; } /// /// Defines the parameters used for channel-specific transformation. /// [StructLayout(LayoutKind.Sequential, Pack = 2)] public struct TW_DECODEFUNCTION { public TW_FIX32 StartIn; public TW_FIX32 BreakIn; public TW_FIX32 EndIn; public TW_FIX32 StartOut; public TW_FIX32 BreakOut; public TW_FIX32 EndOut; public TW_FIX32 Gamma; public TW_FIX32 SampleCount; } /// /// Stores a Fixed point number in two parts, a whole and a fractional part. /// [StructLayout(LayoutKind.Sequential, Pack = 2)] public struct TW_TRANSFORMSTAGE { public TW_DECODEFUNCTION Decode_0; public TW_DECODEFUNCTION Decode_1; public TW_DECODEFUNCTION Decode_2; public TW_FIX32 Mix_0_0; public TW_FIX32 Mix_0_1; public TW_FIX32 Mix_0_2; public TW_FIX32 Mix_1_0; public TW_FIX32 Mix_1_1; public TW_FIX32 Mix_1_2; public TW_FIX32 Mix_2_0; public TW_FIX32 Mix_2_1; public TW_FIX32 Mix_2_2; } /// /// Stores a list of values for a capability, the ItemList is commented /// out so that the caller can collect information about it with a /// marshalling call... /// [StructLayout(LayoutKind.Sequential, Pack = 2)] public struct TW_ARRAY { public TWTY ItemType; public uint NumItems; //public byte[] ItemList; } [StructLayout(LayoutKind.Sequential, Pack = 2)] public struct TW_ARRAY_MACOSX { public uint ItemType; public uint NumItems; //public byte[] ItemList; } /// /// Information about audio data. /// [StructLayout(LayoutKind.Sequential, Pack = 2)] public struct TW_AUDIOINFO { public TW_STR255 Name; public uint Reserved; } /// /// Used to register callbacks. /// [SuppressMessage("Microsoft.Design", "CA1049:TypesThatOwnNativeResourcesShouldBeDisposable")] [StructLayout(LayoutKind.Sequential, Pack = 2)] public struct TW_CALLBACK { [SuppressMessage("Microsoft.Security", "CA2111:PointersShouldNotBeVisible")] public IntPtr CallBackProc; public uint RefCon; public ushort Message; } /// /// Used to register callbacks. /// [StructLayout(LayoutKind.Sequential, Pack = 2)] public struct TW_CALLBACK2 { [SuppressMessage("Microsoft.Security", "CA2111:PointersShouldNotBeVisible")] public IntPtr CallBackProc; [SuppressMessage("Microsoft.Security", "CA2111:PointersShouldNotBeVisible")] public UIntPtr RefCon; public ushort Message; } /// /// Used by application to get/set capability from/in a data source. /// [StructLayout(LayoutKind.Sequential, Pack = 2, CharSet = CharSet.Ansi)] public struct TW_CAPABILITY { public CAP Cap; public TWON ConType; [SuppressMessage("Microsoft.Security", "CA2111:PointersShouldNotBeVisible")] public IntPtr hContainer; } /// /// Defines a CIE XYZ space tri-stimulus value. /// [StructLayout(LayoutKind.Sequential, Pack = 2)] public struct TW_CIEPOINT { public TW_FIX32 X; public TW_FIX32 Y; public TW_FIX32 Z; } /// /// Defines the mapping from an RGB color space device into CIE 1931 (XYZ) color space. /// [StructLayout(LayoutKind.Sequential, Pack = 2)] public struct TW_CIECOLOR { public ushort ColorSpace; public short LowEndian; public short DeviceDependent; public int VersionNumber; public TW_TRANSFORMSTAGE StageABC; public TW_TRANSFORMSTAGE StageLNM; public TW_CIEPOINT WhitePoint; public TW_CIEPOINT BlackPoint; public TW_CIEPOINT WhitePaper; public TW_CIEPOINT BlackInk; public TW_FIX32 Samples; } /// /// Allows for a data source and application to pass custom data to each other. /// [StructLayout(LayoutKind.Sequential, Pack = 2)] public struct TW_CUSTOMDSDATA { public uint InfoLength; [SuppressMessage("Microsoft.Security", "CA2111:PointersShouldNotBeVisible")] public IntPtr hData; } /// /// Provides information about the Event that was raised by the Source. /// [StructLayout(LayoutKind.Sequential, Pack = 2)] public struct TW_DEVICEEVENT { public uint Event; public TW_STR255 DeviceName; public uint BatteryMinutes; public short BatteryPercentage; public int PowerSupply; public TW_FIX32 XResolution; public TW_FIX32 YResolution; public uint FlashUsed2; public uint AutomaticCapture; public uint TimeBeforeFirstCapture; public uint TimeBetweenCaptures; } /// /// This structure holds the tri-stimulus color palette information for TW_PALETTE8 structures. /// [StructLayout(LayoutKind.Sequential, Pack = 2)] public struct TW_ELEMENT8 { public byte Index; public byte Channel1; public byte Channel2; public byte Channel3; } /// /// DAT_ENTRYPOINT. returns essential entry points. /// [StructLayout(LayoutKind.Sequential, Pack = 2)] public struct TW_ENTRYPOINT { public UInt32 Size; [SuppressMessage("Microsoft.Security", "CA2111:PointersShouldNotBeVisible")] public IntPtr DSM_Entry; [SuppressMessage("Microsoft.Security", "CA2111:PointersShouldNotBeVisible")] public IntPtr DSM_MemAllocate; [SuppressMessage("Microsoft.Security", "CA2111:PointersShouldNotBeVisible")] public IntPtr DSM_MemFree; [SuppressMessage("Microsoft.Security", "CA2111:PointersShouldNotBeVisible")] public IntPtr DSM_MemLock; [SuppressMessage("Microsoft.Security", "CA2111:PointersShouldNotBeVisible")] public IntPtr DSM_MemUnlock; } [StructLayout(LayoutKind.Sequential, Pack = 2)] public struct TW_ENTRYPOINT_LINUX64 { public long Size; [SuppressMessage("Microsoft.Security", "CA2111:PointersShouldNotBeVisible")] public IntPtr DSM_Entry; [SuppressMessage("Microsoft.Security", "CA2111:PointersShouldNotBeVisible")] public IntPtr DSM_MemAllocate; [SuppressMessage("Microsoft.Security", "CA2111:PointersShouldNotBeVisible")] public IntPtr DSM_MemFree; [SuppressMessage("Microsoft.Security", "CA2111:PointersShouldNotBeVisible")] public IntPtr DSM_MemLock; [SuppressMessage("Microsoft.Security", "CA2111:PointersShouldNotBeVisible")] public IntPtr DSM_MemUnlock; } public struct TW_ENTRYPOINT_DELEGATES { public UInt32 Size; [SuppressMessage("Microsoft.Security", "CA2111:PointersShouldNotBeVisible")] public IntPtr DSM_Entry; public DSM_MEMALLOC DSM_MemAllocate; public DSM_MEMFREE DSM_MemFree; public DSM_MEMLOCK DSM_MemLock; public DSM_MEMUNLOCK DSM_MemUnlock; } public delegate IntPtr DSM_MEMALLOC(uint size); public delegate void DSM_MEMFREE(IntPtr handle); public delegate IntPtr DSM_MEMLOCK(IntPtr handle); public delegate void DSM_MEMUNLOCK(IntPtr handle); /// /// Stores a group of enumerated values for a capability, the ItemList is /// commented out so that the caller can collect information about it with /// a marshalling call... /// [StructLayout(LayoutKind.Sequential, Pack = 2)] public struct TW_ENUMERATION { public TWTY ItemType; public uint NumItems; public uint CurrentIndex; public uint DefaultIndex; //public byte[] ItemList; } [StructLayout(LayoutKind.Sequential, Pack = 2)] public struct TW_ENUMERATION_LINUX64 { public TWTY ItemType; public ulong NumItems; public ulong CurrentIndex; public ulong DefaultIndex; //public byte[] ItemList; } [StructLayout(LayoutKind.Sequential, Pack = 4)] public struct TW_ENUMERATION_MACOSX { public uint ItemType; public uint NumItems; public uint CurrentIndex; public uint DefaultIndex; //public byte[] ItemList; } /// /// Used to pass application events/messages from the application to the Source. /// [SuppressMessage("Microsoft.Design", "CA1049:TypesThatOwnNativeResourcesShouldBeDisposable")] [StructLayout(LayoutKind.Sequential, Pack = 2)] public struct TW_EVENT { [SuppressMessage("Microsoft.Security", "CA2111:PointersShouldNotBeVisible")] public IntPtr pEvent; public ushort TWMessage; } /// /// DAT_FILTER... /// [StructLayout(LayoutKind.Sequential, Pack = 2)] public struct TW_FILTER_DESCRIPTOR { public UInt32 Size; public UInt32 HueStart; public UInt32 HueEnd; public UInt32 SaturationStart; public UInt32 SaturationEnd; public UInt32 ValueStart; public UInt32 ValueEnd; public UInt32 Replacement; } /// /// DAT_FILTER... /// [StructLayout(LayoutKind.Sequential, Pack = 2)] public struct TW_FILTER { public UInt32 Size; public UInt32 DescriptorCount; public UInt32 MaxDescriptorCount; public UInt32 Condition; [SuppressMessage("Microsoft.Security", "CA2111:PointersShouldNotBeVisible")] public IntPtr hDescriptors; } /// /// This structure is used to pass specific information between the data source and the application. /// [StructLayout(LayoutKind.Sequential, Pack = 2)] public struct TW_INFO { public ushort InfoId; public ushort ItemType; public ushort NumItems; public ushort ReturnCode; [SuppressMessage("Microsoft.Security", "CA2111:PointersShouldNotBeVisible")] public UIntPtr Item; } /// /// This structure is used to pass specific information between the data source and the application. /// [StructLayout(LayoutKind.Sequential, Pack = 2)] public struct TW_EXTIMAGEINFO { public uint NumInfos; public TW_INFO Info_000; public TW_INFO Info_001; public TW_INFO Info_002; public TW_INFO Info_003; public TW_INFO Info_004; public TW_INFO Info_005; public TW_INFO Info_006; public TW_INFO Info_007; public TW_INFO Info_008; public TW_INFO Info_009; public TW_INFO Info_010; public TW_INFO Info_011; public TW_INFO Info_012; public TW_INFO Info_013; public TW_INFO Info_014; public TW_INFO Info_015; public TW_INFO Info_016; public TW_INFO Info_017; public TW_INFO Info_018; public TW_INFO Info_019; public TW_INFO Info_020; public TW_INFO Info_021; public TW_INFO Info_022; public TW_INFO Info_023; public TW_INFO Info_024; public TW_INFO Info_025; public TW_INFO Info_026; public TW_INFO Info_027; public TW_INFO Info_028; public TW_INFO Info_029; public TW_INFO Info_030; public TW_INFO Info_031; public TW_INFO Info_032; public TW_INFO Info_033; public TW_INFO Info_034; public TW_INFO Info_035; public TW_INFO Info_036; public TW_INFO Info_037; public TW_INFO Info_038; public TW_INFO Info_039; public TW_INFO Info_040; public TW_INFO Info_041; public TW_INFO Info_042; public TW_INFO Info_043; public TW_INFO Info_044; public TW_INFO Info_045; public TW_INFO Info_046; public TW_INFO Info_047; public TW_INFO Info_048; public TW_INFO Info_049; public TW_INFO Info_050; public TW_INFO Info_051; public TW_INFO Info_052; public TW_INFO Info_053; public TW_INFO Info_054; public TW_INFO Info_055; public TW_INFO Info_056; public TW_INFO Info_057; public TW_INFO Info_058; public TW_INFO Info_059; public TW_INFO Info_060; public TW_INFO Info_061; public TW_INFO Info_062; public TW_INFO Info_063; public TW_INFO Info_064; public TW_INFO Info_065; public TW_INFO Info_066; public TW_INFO Info_067; public TW_INFO Info_068; public TW_INFO Info_069; public TW_INFO Info_070; public TW_INFO Info_071; public TW_INFO Info_072; public TW_INFO Info_073; public TW_INFO Info_074; public TW_INFO Info_075; public TW_INFO Info_076; public TW_INFO Info_077; public TW_INFO Info_078; public TW_INFO Info_079; public TW_INFO Info_080; public TW_INFO Info_081; public TW_INFO Info_082; public TW_INFO Info_083; public TW_INFO Info_084; public TW_INFO Info_085; public TW_INFO Info_086; public TW_INFO Info_087; public TW_INFO Info_088; public TW_INFO Info_089; public TW_INFO Info_090; public TW_INFO Info_091; public TW_INFO Info_092; public TW_INFO Info_093; public TW_INFO Info_094; public TW_INFO Info_095; public TW_INFO Info_096; public TW_INFO Info_097; public TW_INFO Info_098; public TW_INFO Info_099; public TW_INFO Info_100; public TW_INFO Info_101; public TW_INFO Info_102; public TW_INFO Info_103; public TW_INFO Info_104; public TW_INFO Info_105; public TW_INFO Info_106; public TW_INFO Info_107; public TW_INFO Info_108; public TW_INFO Info_109; public TW_INFO Info_110; public TW_INFO Info_111; public TW_INFO Info_112; public TW_INFO Info_113; public TW_INFO Info_114; public TW_INFO Info_115; public TW_INFO Info_116; public TW_INFO Info_117; public TW_INFO Info_118; public TW_INFO Info_119; public TW_INFO Info_120; public TW_INFO Info_121; public TW_INFO Info_122; public TW_INFO Info_123; public TW_INFO Info_124; public TW_INFO Info_125; public TW_INFO Info_126; public TW_INFO Info_127; public TW_INFO Info_128; public TW_INFO Info_129; public TW_INFO Info_130; public TW_INFO Info_131; public TW_INFO Info_132; public TW_INFO Info_133; public TW_INFO Info_134; public TW_INFO Info_135; public TW_INFO Info_136; public TW_INFO Info_137; public TW_INFO Info_138; public TW_INFO Info_139; public TW_INFO Info_140; public TW_INFO Info_141; public TW_INFO Info_142; public TW_INFO Info_143; public TW_INFO Info_144; public TW_INFO Info_145; public TW_INFO Info_146; public TW_INFO Info_147; public TW_INFO Info_148; public TW_INFO Info_149; public TW_INFO Info_150; public TW_INFO Info_151; public TW_INFO Info_152; public TW_INFO Info_153; public TW_INFO Info_154; public TW_INFO Info_155; public TW_INFO Info_156; public TW_INFO Info_157; public TW_INFO Info_158; public TW_INFO Info_159; public TW_INFO Info_160; public TW_INFO Info_161; public TW_INFO Info_162; public TW_INFO Info_163; public TW_INFO Info_164; public TW_INFO Info_165; public TW_INFO Info_166; public TW_INFO Info_167; public TW_INFO Info_168; public TW_INFO Info_169; public TW_INFO Info_170; public TW_INFO Info_171; public TW_INFO Info_172; public TW_INFO Info_173; public TW_INFO Info_174; public TW_INFO Info_175; public TW_INFO Info_176; public TW_INFO Info_177; public TW_INFO Info_178; public TW_INFO Info_179; public TW_INFO Info_180; public TW_INFO Info_181; public TW_INFO Info_182; public TW_INFO Info_183; public TW_INFO Info_184; public TW_INFO Info_185; public TW_INFO Info_186; public TW_INFO Info_187; public TW_INFO Info_188; public TW_INFO Info_189; public TW_INFO Info_190; public TW_INFO Info_191; public TW_INFO Info_192; public TW_INFO Info_193; public TW_INFO Info_194; public TW_INFO Info_195; public TW_INFO Info_196; public TW_INFO Info_197; public TW_INFO Info_198; public TW_INFO Info_199; public void Get(uint a_uIndex, ref TW_INFO a_twinfo) { switch (a_uIndex) { default: return; case 0: a_twinfo = Info_000; return; case 1: a_twinfo = Info_001; return; case 2: a_twinfo = Info_002; return; case 3: a_twinfo = Info_003; return; case 4: a_twinfo = Info_004; return; case 5: a_twinfo = Info_005; return; case 6: a_twinfo = Info_006; return; case 7: a_twinfo = Info_007; return; case 8: a_twinfo = Info_008; return; case 9: a_twinfo = Info_009; return; case 10: a_twinfo = Info_010; return; case 11: a_twinfo = Info_011; return; case 12: a_twinfo = Info_012; return; case 13: a_twinfo = Info_013; return; case 14: a_twinfo = Info_014; return; case 15: a_twinfo = Info_015; return; case 16: a_twinfo = Info_016; return; case 17: a_twinfo = Info_017; return; case 18: a_twinfo = Info_018; return; case 19: a_twinfo = Info_019; return; case 20: a_twinfo = Info_020; return; case 21: a_twinfo = Info_021; return; case 22: a_twinfo = Info_022; return; case 23: a_twinfo = Info_023; return; case 24: a_twinfo = Info_024; return; case 25: a_twinfo = Info_025; return; case 26: a_twinfo = Info_026; return; case 27: a_twinfo = Info_027; return; case 28: a_twinfo = Info_028; return; case 29: a_twinfo = Info_029; return; case 30: a_twinfo = Info_030; return; case 31: a_twinfo = Info_031; return; case 32: a_twinfo = Info_032; return; case 33: a_twinfo = Info_033; return; case 34: a_twinfo = Info_034; return; case 35: a_twinfo = Info_035; return; case 36: a_twinfo = Info_036; return; case 37: a_twinfo = Info_037; return; case 38: a_twinfo = Info_038; return; case 39: a_twinfo = Info_039; return; case 40: a_twinfo = Info_040; return; case 41: a_twinfo = Info_041; return; case 42: a_twinfo = Info_042; return; case 43: a_twinfo = Info_043; return; case 44: a_twinfo = Info_044; return; case 45: a_twinfo = Info_045; return; case 46: a_twinfo = Info_046; return; case 47: a_twinfo = Info_047; return; case 48: a_twinfo = Info_048; return; case 49: a_twinfo = Info_049; return; case 50: a_twinfo = Info_050; return; case 51: a_twinfo = Info_051; return; case 52: a_twinfo = Info_052; return; case 53: a_twinfo = Info_053; return; case 54: a_twinfo = Info_054; return; case 55: a_twinfo = Info_055; return; case 56: a_twinfo = Info_056; return; case 57: a_twinfo = Info_057; return; case 58: a_twinfo = Info_058; return; case 59: a_twinfo = Info_059; return; case 60: a_twinfo = Info_060; return; case 61: a_twinfo = Info_061; return; case 62: a_twinfo = Info_062; return; case 63: a_twinfo = Info_063; return; case 64: a_twinfo = Info_064; return; case 65: a_twinfo = Info_065; return; case 66: a_twinfo = Info_066; return; case 67: a_twinfo = Info_067; return; case 68: a_twinfo = Info_068; return; case 69: a_twinfo = Info_069; return; case 70: a_twinfo = Info_070; return; case 71: a_twinfo = Info_071; return; case 72: a_twinfo = Info_072; return; case 73: a_twinfo = Info_073; return; case 74: a_twinfo = Info_074; return; case 75: a_twinfo = Info_075; return; case 76: a_twinfo = Info_076; return; case 77: a_twinfo = Info_077; return; case 78: a_twinfo = Info_078; return; case 79: a_twinfo = Info_079; return; case 80: a_twinfo = Info_080; return; case 81: a_twinfo = Info_081; return; case 82: a_twinfo = Info_082; return; case 83: a_twinfo = Info_083; return; case 84: a_twinfo = Info_084; return; case 85: a_twinfo = Info_085; return; case 86: a_twinfo = Info_086; return; case 87: a_twinfo = Info_087; return; case 88: a_twinfo = Info_088; return; case 89: a_twinfo = Info_089; return; case 90: a_twinfo = Info_090; return; case 91: a_twinfo = Info_091; return; case 92: a_twinfo = Info_092; return; case 93: a_twinfo = Info_093; return; case 94: a_twinfo = Info_094; return; case 95: a_twinfo = Info_095; return; case 96: a_twinfo = Info_096; return; case 97: a_twinfo = Info_097; return; case 98: a_twinfo = Info_098; return; case 99: a_twinfo = Info_099; return; case 100: a_twinfo = Info_100; return; case 101: a_twinfo = Info_101; return; case 102: a_twinfo = Info_102; return; case 103: a_twinfo = Info_103; return; case 104: a_twinfo = Info_104; return; case 105: a_twinfo = Info_105; return; case 106: a_twinfo = Info_106; return; case 107: a_twinfo = Info_107; return; case 108: a_twinfo = Info_108; return; case 109: a_twinfo = Info_109; return; case 110: a_twinfo = Info_110; return; case 111: a_twinfo = Info_111; return; case 112: a_twinfo = Info_112; return; case 113: a_twinfo = Info_113; return; case 114: a_twinfo = Info_114; return; case 115: a_twinfo = Info_115; return; case 116: a_twinfo = Info_116; return; case 117: a_twinfo = Info_117; return; case 118: a_twinfo = Info_118; return; case 119: a_twinfo = Info_119; return; case 120: a_twinfo = Info_120; return; case 121: a_twinfo = Info_121; return; case 122: a_twinfo = Info_122; return; case 123: a_twinfo = Info_123; return; case 124: a_twinfo = Info_124; return; case 125: a_twinfo = Info_125; return; case 126: a_twinfo = Info_126; return; case 127: a_twinfo = Info_127; return; case 128: a_twinfo = Info_128; return; case 129: a_twinfo = Info_129; return; case 130: a_twinfo = Info_130; return; case 131: a_twinfo = Info_131; return; case 132: a_twinfo = Info_132; return; case 133: a_twinfo = Info_133; return; case 134: a_twinfo = Info_134; return; case 135: a_twinfo = Info_135; return; case 136: a_twinfo = Info_136; return; case 137: a_twinfo = Info_137; return; case 138: a_twinfo = Info_138; return; case 139: a_twinfo = Info_139; return; case 140: a_twinfo = Info_140; return; case 141: a_twinfo = Info_141; return; case 142: a_twinfo = Info_142; return; case 143: a_twinfo = Info_143; return; case 144: a_twinfo = Info_144; return; case 145: a_twinfo = Info_145; return; case 146: a_twinfo = Info_146; return; case 147: a_twinfo = Info_147; return; case 148: a_twinfo = Info_148; return; case 149: a_twinfo = Info_149; return; case 150: a_twinfo = Info_150; return; case 151: a_twinfo = Info_151; return; case 152: a_twinfo = Info_152; return; case 153: a_twinfo = Info_153; return; case 154: a_twinfo = Info_154; return; case 155: a_twinfo = Info_155; return; case 156: a_twinfo = Info_156; return; case 157: a_twinfo = Info_157; return; case 158: a_twinfo = Info_158; return; case 159: a_twinfo = Info_159; return; case 160: a_twinfo = Info_160; return; case 161: a_twinfo = Info_161; return; case 162: a_twinfo = Info_162; return; case 163: a_twinfo = Info_163; return; case 164: a_twinfo = Info_164; return; case 165: a_twinfo = Info_165; return; case 166: a_twinfo = Info_166; return; case 167: a_twinfo = Info_167; return; case 168: a_twinfo = Info_168; return; case 169: a_twinfo = Info_169; return; case 170: a_twinfo = Info_170; return; case 171: a_twinfo = Info_171; return; case 172: a_twinfo = Info_172; return; case 173: a_twinfo = Info_173; return; case 174: a_twinfo = Info_174; return; case 175: a_twinfo = Info_175; return; case 176: a_twinfo = Info_176; return; case 177: a_twinfo = Info_177; return; case 178: a_twinfo = Info_178; return; case 179: a_twinfo = Info_179; return; case 180: a_twinfo = Info_180; return; case 181: a_twinfo = Info_181; return; case 182: a_twinfo = Info_182; return; case 183: a_twinfo = Info_183; return; case 184: a_twinfo = Info_184; return; case 185: a_twinfo = Info_185; return; case 186: a_twinfo = Info_186; return; case 187: a_twinfo = Info_187; return; case 188: a_twinfo = Info_188; return; case 189: a_twinfo = Info_189; return; case 190: a_twinfo = Info_190; return; case 191: a_twinfo = Info_191; return; case 192: a_twinfo = Info_192; return; case 193: a_twinfo = Info_193; return; case 194: a_twinfo = Info_194; return; case 195: a_twinfo = Info_195; return; case 196: a_twinfo = Info_196; return; case 197: a_twinfo = Info_197; return; case 198: a_twinfo = Info_198; return; case 199: a_twinfo = Info_199; return; } } public void Set(uint a_uIndex, ref TW_INFO a_twinfo) { switch (a_uIndex) { default: return; case 0: Info_000 = a_twinfo; return; case 1: Info_001 = a_twinfo; return; case 2: Info_002 = a_twinfo; return; case 3: Info_003 = a_twinfo; return; case 4: Info_004 = a_twinfo; return; case 5: Info_005 = a_twinfo; return; case 6: Info_006 = a_twinfo; return; case 7: Info_007 = a_twinfo; return; case 8: Info_008 = a_twinfo; return; case 9: Info_009 = a_twinfo; return; case 10: Info_010 = a_twinfo; return; case 11: Info_011 = a_twinfo; return; case 12: Info_012 = a_twinfo; return; case 13: Info_013 = a_twinfo; return; case 14: Info_014 = a_twinfo; return; case 15: Info_015 = a_twinfo; return; case 16: Info_016 = a_twinfo; return; case 17: Info_017 = a_twinfo; return; case 18: Info_018 = a_twinfo; return; case 19: Info_019 = a_twinfo; return; case 20: Info_020 = a_twinfo; return; case 21: Info_021 = a_twinfo; return; case 22: Info_022 = a_twinfo; return; case 23: Info_023 = a_twinfo; return; case 24: Info_024 = a_twinfo; return; case 25: Info_025 = a_twinfo; return; case 26: Info_026 = a_twinfo; return; case 27: Info_027 = a_twinfo; return; case 28: Info_028 = a_twinfo; return; case 29: Info_029 = a_twinfo; return; case 30: Info_030 = a_twinfo; return; case 31: Info_031 = a_twinfo; return; case 32: Info_032 = a_twinfo; return; case 33: Info_033 = a_twinfo; return; case 34: Info_034 = a_twinfo; return; case 35: Info_035 = a_twinfo; return; case 36: Info_036 = a_twinfo; return; case 37: Info_037 = a_twinfo; return; case 38: Info_038 = a_twinfo; return; case 39: Info_039 = a_twinfo; return; case 40: Info_040 = a_twinfo; return; case 41: Info_041 = a_twinfo; return; case 42: Info_042 = a_twinfo; return; case 43: Info_043 = a_twinfo; return; case 44: Info_044 = a_twinfo; return; case 45: Info_045 = a_twinfo; return; case 46: Info_046 = a_twinfo; return; case 47: Info_047 = a_twinfo; return; case 48: Info_048 = a_twinfo; return; case 49: Info_049 = a_twinfo; return; case 50: Info_050 = a_twinfo; return; case 51: Info_051 = a_twinfo; return; case 52: Info_052 = a_twinfo; return; case 53: Info_053 = a_twinfo; return; case 54: Info_054 = a_twinfo; return; case 55: Info_055 = a_twinfo; return; case 56: Info_056 = a_twinfo; return; case 57: Info_057 = a_twinfo; return; case 58: Info_058 = a_twinfo; return; case 59: Info_059 = a_twinfo; return; case 60: Info_060 = a_twinfo; return; case 61: Info_061 = a_twinfo; return; case 62: Info_062 = a_twinfo; return; case 63: Info_063 = a_twinfo; return; case 64: Info_064 = a_twinfo; return; case 65: Info_065 = a_twinfo; return; case 66: Info_066 = a_twinfo; return; case 67: Info_067 = a_twinfo; return; case 68: Info_068 = a_twinfo; return; case 69: Info_069 = a_twinfo; return; case 70: Info_070 = a_twinfo; return; case 71: Info_071 = a_twinfo; return; case 72: Info_072 = a_twinfo; return; case 73: Info_073 = a_twinfo; return; case 74: Info_074 = a_twinfo; return; case 75: Info_075 = a_twinfo; return; case 76: Info_076 = a_twinfo; return; case 77: Info_077 = a_twinfo; return; case 78: Info_078 = a_twinfo; return; case 79: Info_079 = a_twinfo; return; case 80: Info_080 = a_twinfo; return; case 81: Info_081 = a_twinfo; return; case 82: Info_082 = a_twinfo; return; case 83: Info_083 = a_twinfo; return; case 84: Info_084 = a_twinfo; return; case 85: Info_085 = a_twinfo; return; case 86: Info_086 = a_twinfo; return; case 87: Info_087 = a_twinfo; return; case 88: Info_088 = a_twinfo; return; case 89: Info_089 = a_twinfo; return; case 90: Info_090 = a_twinfo; return; case 91: Info_091 = a_twinfo; return; case 92: Info_092 = a_twinfo; return; case 93: Info_093 = a_twinfo; return; case 94: Info_094 = a_twinfo; return; case 95: Info_095 = a_twinfo; return; case 96: Info_096 = a_twinfo; return; case 97: Info_097 = a_twinfo; return; case 98: Info_098 = a_twinfo; return; case 99: Info_099 = a_twinfo; return; case 100: Info_100 = a_twinfo; return; case 101: Info_101 = a_twinfo; return; case 102: Info_102 = a_twinfo; return; case 103: Info_103 = a_twinfo; return; case 104: Info_104 = a_twinfo; return; case 105: Info_105 = a_twinfo; return; case 106: Info_106 = a_twinfo; return; case 107: Info_107 = a_twinfo; return; case 108: Info_108 = a_twinfo; return; case 109: Info_109 = a_twinfo; return; case 110: Info_110 = a_twinfo; return; case 111: Info_111 = a_twinfo; return; case 112: Info_112 = a_twinfo; return; case 113: Info_113 = a_twinfo; return; case 114: Info_114 = a_twinfo; return; case 115: Info_115 = a_twinfo; return; case 116: Info_116 = a_twinfo; return; case 117: Info_117 = a_twinfo; return; case 118: Info_118 = a_twinfo; return; case 119: Info_119 = a_twinfo; return; case 120: Info_120 = a_twinfo; return; case 121: Info_121 = a_twinfo; return; case 122: Info_122 = a_twinfo; return; case 123: Info_123 = a_twinfo; return; case 124: Info_124 = a_twinfo; return; case 125: Info_125 = a_twinfo; return; case 126: Info_126 = a_twinfo; return; case 127: Info_127 = a_twinfo; return; case 128: Info_128 = a_twinfo; return; case 129: Info_129 = a_twinfo; return; case 130: Info_130 = a_twinfo; return; case 131: Info_131 = a_twinfo; return; case 132: Info_132 = a_twinfo; return; case 133: Info_133 = a_twinfo; return; case 134: Info_134 = a_twinfo; return; case 135: Info_135 = a_twinfo; return; case 136: Info_136 = a_twinfo; return; case 137: Info_137 = a_twinfo; return; case 138: Info_138 = a_twinfo; return; case 139: Info_139 = a_twinfo; return; case 140: Info_140 = a_twinfo; return; case 141: Info_141 = a_twinfo; return; case 142: Info_142 = a_twinfo; return; case 143: Info_143 = a_twinfo; return; case 144: Info_144 = a_twinfo; return; case 145: Info_145 = a_twinfo; return; case 146: Info_146 = a_twinfo; return; case 147: Info_147 = a_twinfo; return; case 148: Info_148 = a_twinfo; return; case 149: Info_149 = a_twinfo; return; case 150: Info_150 = a_twinfo; return; case 151: Info_151 = a_twinfo; return; case 152: Info_152 = a_twinfo; return; case 153: Info_153 = a_twinfo; return; case 154: Info_154 = a_twinfo; return; case 155: Info_155 = a_twinfo; return; case 156: Info_156 = a_twinfo; return; case 157: Info_157 = a_twinfo; return; case 158: Info_158 = a_twinfo; return; case 159: Info_159 = a_twinfo; return; case 160: Info_160 = a_twinfo; return; case 161: Info_161 = a_twinfo; return; case 162: Info_162 = a_twinfo; return; case 163: Info_163 = a_twinfo; return; case 164: Info_164 = a_twinfo; return; case 165: Info_165 = a_twinfo; return; case 166: Info_166 = a_twinfo; return; case 167: Info_167 = a_twinfo; return; case 168: Info_168 = a_twinfo; return; case 169: Info_169 = a_twinfo; return; case 170: Info_170 = a_twinfo; return; case 171: Info_171 = a_twinfo; return; case 172: Info_172 = a_twinfo; return; case 173: Info_173 = a_twinfo; return; case 174: Info_174 = a_twinfo; return; case 175: Info_175 = a_twinfo; return; case 176: Info_176 = a_twinfo; return; case 177: Info_177 = a_twinfo; return; case 178: Info_178 = a_twinfo; return; case 179: Info_179 = a_twinfo; return; case 180: Info_180 = a_twinfo; return; case 181: Info_181 = a_twinfo; return; case 182: Info_182 = a_twinfo; return; case 183: Info_183 = a_twinfo; return; case 184: Info_184 = a_twinfo; return; case 185: Info_185 = a_twinfo; return; case 186: Info_186 = a_twinfo; return; case 187: Info_187 = a_twinfo; return; case 188: Info_188 = a_twinfo; return; case 189: Info_189 = a_twinfo; return; case 190: Info_190 = a_twinfo; return; case 191: Info_191 = a_twinfo; return; case 192: Info_192 = a_twinfo; return; case 193: Info_193 = a_twinfo; return; case 194: Info_194 = a_twinfo; return; case 195: Info_195 = a_twinfo; return; case 196: Info_196 = a_twinfo; return; case 197: Info_197 = a_twinfo; return; case 198: Info_198 = a_twinfo; return; case 199: Info_199 = a_twinfo; return; } } } /// /// Provides information about the currently selected device. /// TBD -- need a 32/64 bit solution for this mess /// [SuppressMessage("Microsoft.Portability", "CA1900:ValueTypeFieldsShouldBePortable", MessageId = "ModifiedTimeDate")] [SuppressMessage("Microsoft.Portability", "CA1900:ValueTypeFieldsShouldBePortable", MessageId = "CreateTimeDate")] [StructLayout(LayoutKind.Explicit, Pack = 2)] public struct TW_FILESYSTEM { [FieldOffset(0)] public TW_STR255 InputName; [FieldOffset(256)] public TW_STR255 OutputName; [SuppressMessage("Microsoft.Security", "CA2111:PointersShouldNotBeVisible")] [FieldOffset(512)] public IntPtr Context; [FieldOffset(520)] public Int32 Recursive; [FieldOffset(520)] public UInt16 Subdirectories; [FieldOffset(524)] public Int32 FileType; [FieldOffset(524)] public UInt32 FileSystemType; [FieldOffset(528)] public UInt32 Size; [FieldOffset(532)] public TW_STR32 CreateTimeDate; [FieldOffset(566)] public TW_STR32 ModifiedTimeDate; [FieldOffset(600)] public UInt32 FreeSpace; [FieldOffset(604)] public UInt32 NewImageSize; [FieldOffset(608)] public UInt32 NumberOfFiles; [FieldOffset(612)] public UInt32 NumberOfSnippets; [FieldOffset(616)] public UInt32 DeviceGroupMask; [FieldOffset(620)] public byte Reserved; [FieldOffset(1127)] // 620 + 508 - 1 private byte ReservedEnd; } [SuppressMessage("Microsoft.Portability", "CA1900:ValueTypeFieldsShouldBePortable", MessageId = "ModifiedTimeDate")] [StructLayout(LayoutKind.Explicit, Pack = 2)] public struct TW_FILESYSTEM_LEGACY { [FieldOffset(0)] public TW_STR255 InputName; [FieldOffset(256)] public TW_STR255 OutputName; [FieldOffset(512)] public UInt32 Context; [FieldOffset(516)] public Int32 Recursive; [FieldOffset(516)] public UInt16 Subdirectories; [FieldOffset(520)] public Int32 FileType; [FieldOffset(520)] public UInt32 FileSystemType; [FieldOffset(524)] public UInt32 Size; [FieldOffset(528)] public TW_STR32 CreateTimeDate; [FieldOffset(562)] public TW_STR32 ModifiedTimeDate; [FieldOffset(596)] public UInt32 FreeSpace; [FieldOffset(600)] public UInt32 NewImageSize; [FieldOffset(604)] public UInt32 NumberOfFiles; [FieldOffset(608)] public UInt32 NumberOfSnippets; [FieldOffset(612)] public UInt32 DeviceGroupMask; [FieldOffset(616)] public byte Reserved; [FieldOffset(1123)] // 616 + 508 - 1 private byte ReservedEnd; } /// /// This structure is used by the application to specify a set of mapping values to be applied to grayscale data. /// [StructLayout(LayoutKind.Sequential, Pack = 2)] public struct TW_GRAYRESPONSE { public TW_ELEMENT8 Response_00; } /// /// A general way to describe the version of software that is running. /// [StructLayout(LayoutKind.Sequential, Pack = 2, CharSet = CharSet.Ansi)] public struct TW_VERSION { public ushort MajorNum; public ushort MinorNum; public TWLG Language; public TWCY Country; public TW_STR32 Info; } /// /// Provides identification information about a TWAIN entity. /// The use of Padding is there to allow us to use the structure /// with Linux 64-bit systems where the TW_INT32 and TW_UINT32 /// types were long, and therefore 64-bits in size. This should /// have no impact with well-behaved systems that have these types /// as 32-bit, but should prevent memory corruption in all other /// situations... /// [StructLayout(LayoutKind.Sequential, Pack = 2, CharSet = CharSet.Ansi)] public struct TW_IDENTITY { public ulong Id; public TW_VERSION Version; public ushort ProtocolMajor; public ushort ProtocolMinor; public uint SupportedGroups; public TW_STR32 Manufacturer; public TW_STR32 ProductFamily; public TW_STR32 ProductName; } [StructLayout(LayoutKind.Sequential, Pack = 2, CharSet = CharSet.Ansi)] public struct TW_IDENTITY_LEGACY { public uint Id; public TW_VERSION Version; public ushort ProtocolMajor; public ushort ProtocolMinor; public uint SupportedGroups; public TW_STR32 Manufacturer; public TW_STR32 ProductFamily; public TW_STR32 ProductName; private UInt64 Padding; // accounts for Id and SupportedGroups } [StructLayout(LayoutKind.Sequential, Pack = 2, CharSet = CharSet.Ansi)] public struct TW_IDENTITY_LINUX64 { public ulong Id; public TW_VERSION Version; public ushort ProtocolMajor; public ushort ProtocolMinor; public ulong SupportedGroups; public TW_STR32 Manufacturer; public TW_STR32 ProductFamily; public TW_STR32 ProductName; } [StructLayout(LayoutKind.Sequential, Pack = 2, CharSet = CharSet.Ansi)] public struct TW_IDENTITY_MACOSX { public uint Id; public TW_VERSION Version; public ushort ProtocolMajor; public ushort ProtocolMinor; private ushort padding; public uint SupportedGroups; public TW_STR32 Manufacturer; public TW_STR32 ProductFamily; public TW_STR32 ProductName; } /// /// Describes the “real” image data, that is, the complete image being transferred between the Source and application. /// [StructLayout(LayoutKind.Sequential, Pack = 2)] public struct TW_IMAGEINFO { public TW_FIX32 XResolution; public TW_FIX32 YResolution; public int ImageWidth; public int ImageLength; public short SamplesPerPixel; public short BitsPerSample_0; public short BitsPerSample_1; public short BitsPerSample_2; public short BitsPerSample_3; public short BitsPerSample_4; public short BitsPerSample_5; public short BitsPerSample_6; public short BitsPerSample_7; public short BitsPerPixel; public ushort Planar; public short PixelType; public ushort Compression; } [StructLayout(LayoutKind.Sequential, Pack = 2)] public struct TW_IMAGEINFO_LINUX64 { public TW_FIX32 XResolution; public TW_FIX32 YResolution; public int ImageWidth; public int ImageLength; public short SamplesPerPixel; public short BitsPerSample_0; public short BitsPerSample_1; public short BitsPerSample_2; public short BitsPerSample_3; public short BitsPerSample_4; public short BitsPerSample_5; public short BitsPerSample_6; public short BitsPerSample_7; public short BitsPerPixel; public ushort Planar; public short PixelType; public ushort Compression; } /// /// Involves information about the original size of the acquired image. /// [StructLayout(LayoutKind.Sequential, Pack = 2)] public struct TW_IMAGELAYOUT { public TW_FRAME Frame; public uint DocumentNumber; public uint PageNumber; public uint FrameNumber; } /// /// Provides information for managing memory buffers. /// [StructLayout(LayoutKind.Sequential, Pack = 2)] public struct TW_MEMORY { public uint Flags; public uint Length; [SuppressMessage("Microsoft.Security", "CA2111:PointersShouldNotBeVisible")] public IntPtr TheMem; } /// /// Describes the form of the acquired data being passed from the Source to the application. /// [StructLayout(LayoutKind.Sequential, Pack = 2)] public struct TW_IMAGEMEMXFER { public ushort Compression; public uint BytesPerRow; public uint Columns; public uint Rows; public uint XOffset; public uint YOffset; public uint BytesWritten; public TW_MEMORY Memory; } [StructLayout(LayoutKind.Sequential, Pack = 2)] public struct TW_IMAGEMEMXFER_LINUX64 { public ushort Compression; public UInt64 BytesPerRow; public UInt64 Columns; public UInt64 Rows; public UInt64 XOffset; public UInt64 YOffset; public UInt64 BytesWritten; public UInt64 MemoryFlags; public UInt64 MemoryLength; [SuppressMessage("Microsoft.Security", "CA2111:PointersShouldNotBeVisible")] public IntPtr MemoryTheMem; } [StructLayout(LayoutKind.Sequential, Pack = 2)] public struct TW_IMAGEMEMXFER_MACOSX { public uint Compression; public uint BytesPerRow; public uint Columns; public uint Rows; public uint XOffset; public uint YOffset; public uint BytesWritten; public TW_MEMORY Memory; } /// /// Describes the information necessary to transfer a JPEG-compressed image. /// [StructLayout(LayoutKind.Sequential, Pack = 2)] public struct TW_JPEGCOMPRESSION { public ushort ColorSpace; public uint SubSampling; public ushort NumComponents; public ushort QuantMap_0; public ushort QuantMap_1; public ushort QuantMap_2; public ushort QuantMap_3; public TW_MEMORY QuantTable_0; public TW_MEMORY QuantTable_1; public TW_MEMORY QuantTable_2; public TW_MEMORY QuantTable_3; public ushort HuffmanMap_0; public ushort HuffmanMap_1; public ushort HuffmanMap_2; public ushort HuffmanMap_3; public TW_MEMORY HuffmanDC_0; public TW_MEMORY HuffmanDC_1; public TW_MEMORY HuffmanAC_0; public TW_MEMORY HuffmanAC_2; } /// /// Collects scanning metrics after returning to state 4 /// [StructLayout(LayoutKind.Sequential, Pack = 2)] public struct TW_METRICS { public uint SizeOf; public uint ImageCount; public uint SheetCount; } /// /// Stores a single value (item) which describes a capability. /// [StructLayout(LayoutKind.Sequential, Pack = 2)] public struct TW_ONEVALUE { public TWTY ItemType; // public uint Item; } [StructLayout(LayoutKind.Sequential, Pack = 4)] public struct TW_ONEVALUE_MACOSX { public uint ItemType; // public uint Item; } /// /// This structure holds the color palette information. /// [StructLayout(LayoutKind.Sequential, Pack = 2)] public struct TW_PALETTE8 { public ushort Flags; public ushort Length; public TW_ELEMENT8 Colors_000; } /// /// Used to bypass the TWAIN protocol when communicating with a device. /// [StructLayout(LayoutKind.Sequential, Pack = 2)] public struct TW_PASSTHRU { [SuppressMessage("Microsoft.Security", "CA2111:PointersShouldNotBeVisible")] public IntPtr pCommand; public uint CommandBytes; public int Direction; [SuppressMessage("Microsoft.Security", "CA2111:PointersShouldNotBeVisible")] public IntPtr pData; public uint DataBytes; public uint DataBytesXfered; } /// /// This structure tells the application how many more complete transfers the Source currently has available. /// [StructLayout(LayoutKind.Sequential, Pack = 2)] public struct TW_PENDINGXFERS { public ushort Count; public uint EOJ; } /// /// Stores a range of individual values describing a capability. /// [StructLayout(LayoutKind.Sequential, Pack = 2)] public struct TW_RANGE { public TWTY ItemType; public uint MinValue; public uint MaxValue; public uint StepSize; public uint DefaultValue; public uint CurrentValue; } [StructLayout(LayoutKind.Sequential, Pack = 2)] public struct TW_RANGE_LINUX64 { public TWTY ItemType; public ulong MinValue; public ulong MaxValue; public ulong StepSize; public ulong DefaultValue; public ulong CurrentValue; } [StructLayout(LayoutKind.Sequential, Pack = 4)] public struct TW_RANGE_MACOSX { public uint ItemType; public uint MinValue; public uint MaxValue; public uint StepSize; public uint DefaultValue; public uint CurrentValue; } [StructLayout(LayoutKind.Sequential, Pack = 2)] private struct TW_RANGE_FIX32 { public TWTY ItemType; public TW_FIX32 MinValue; public TW_FIX32 MaxValue; public TW_FIX32 StepSize; public TW_FIX32 DefaultValue; public TW_FIX32 CurrentValue; } [StructLayout(LayoutKind.Sequential, Pack = 4)] private struct TW_RANGE_FIX32_MACOSX { public uint ItemType; public TW_FIX32 MinValue; public TW_FIX32 MaxValue; public TW_FIX32 StepSize; public TW_FIX32 DefaultValue; public TW_FIX32 CurrentValue; } /// /// This structure is used by the application to specify a set of mapping values to be applied to RGB color data. /// [StructLayout(LayoutKind.Sequential, Pack = 2)] public struct TW_RGBRESPONSE { public TW_ELEMENT8 Response_00; } /// /// Describes the file format and file specification information for a transfer through a disk file. /// [StructLayout(LayoutKind.Sequential, Pack = 2)] public struct TW_SETUPFILEXFER { public TW_STR255 FileName; public TWFF Format; public short VRefNum; } /// /// Provides the application information about the Source’s requirements and preferences regarding allocation of transfer buffer(s). /// [StructLayout(LayoutKind.Sequential, Pack = 2)] public struct TW_SETUPMEMXFER { public uint MinBufSize; public uint MaxBufSize; public uint Preferred; } /// /// Describes the status of a source. /// [StructLayout(LayoutKind.Sequential, Pack = 2)] public struct TW_STATUS { public ushort ConditionCode; public ushort Data; } /// /// Translates the contents of Status into a localized UTF8string. /// [StructLayout(LayoutKind.Sequential, Pack = 2)] public struct TW_STATUSUTF8 { public TW_STATUS Status; public uint Size; [SuppressMessage("Microsoft.Security", "CA2111:PointersShouldNotBeVisible")] public IntPtr UTF8string; } /// /// Passthru for TWAIN Direct tasks. /// [StructLayout(LayoutKind.Sequential, Pack = 2, CharSet = CharSet.Ansi)] public struct TW_TWAINDIRECT { public uint SizeOf; public ushort CommunicationManager; [SuppressMessage("Microsoft.Security", "CA2111:PointersShouldNotBeVisible")] public IntPtr Send; public uint SendSize; [SuppressMessage("Microsoft.Security", "CA2111:PointersShouldNotBeVisible")] public IntPtr Receive; public uint ReceiveSize; } /// /// This structure is used to handle the user interface coordination between an application and a Source. /// [StructLayout(LayoutKind.Sequential, Pack = 2, CharSet = CharSet.Ansi)] public struct TW_USERINTERFACE { public ushort ShowUI; public ushort ModalUI; [SuppressMessage("Microsoft.Security", "CA2111:PointersShouldNotBeVisible")] public IntPtr hParent; } #endregion /////////////////////////////////////////////////////////////////////////////// // Generic Constants... /////////////////////////////////////////////////////////////////////////////// #region Generic Constants... /// /// Container Types... /// public enum TWON : ushort { ARRAY = 3, ENUMERATION = 4, ONEVALUE = 5, RANGE = 6, ICONID = 962, DSMID = 461, DSMCODEID = 63 } /// /// Don't care values... /// public const byte TWON_DONTCARE8 = 0xff; public const ushort TWON_DONTCARE16 = 0xffff; public const uint TWON_DONTCARE32 = 0xffffffff; /// /// Flags used in TW_MEMORY structure. /// public enum TWMF : ushort { APPOWNS = 0x0001, DSMOWNS = 0x0002, DSOWNS = 0x0004, POINTER = 0x0008, HANDLE = 0x0010 } /// /// Type values... /// public enum TWTY : ushort { INT8 = 0x0000, INT16 = 0x0001, INT32 = 0x0002, UINT8 = 0x0003, UINT16 = 0x0004, UINT32 = 0x0005, BOOL = 0x0006, FIX32 = 0x0007, FRAME = 0x0008, STR32 = 0x0009, STR64 = 0x000a, STR128 = 0x000b, STR255 = 0x000c, HANDLE = 0x000f } #endregion /////////////////////////////////////////////////////////////////////////////// // Capability Constants... /////////////////////////////////////////////////////////////////////////////// #region Capability Constants... /// /// CAP_ALARMS values /// public enum TWAL : ushort { ALARM = 0, FEEDERERROR = 1, FEEDERWARNING = 2, BARCODE = 3, DOUBLEFEED = 4, JAM = 5, PATCHCODE = 6, POWER = 7, SKEW = 8 } /// /// ICAP_AUTOSIZE values /// public enum TWAS : ushort { NONE = 0, AUTO = 1, CURRENT = 2 } /// /// TWEI_BARCODEROTATION values /// public enum TWBCOR : ushort { ROT0 = 0, ROT90 = 1, ROT180 = 2, ROT270 = 3, ROTX = 4 } /// /// ICAP_BARCODESEARCHMODE values /// public enum TWBD : ushort { HORZ = 0, VERT = 1, HORZVERT = 2, VERTHORZ = 3 } /// /// ICAP_BITORDER values /// public enum TWBO : ushort { LSBFIRST = 0, MSBFIRST = 1 } /// /// ICAP_AUTODISCARDBLANKPAGES values /// public enum TWBP : short { DISABLE = -2, AUTO = -1 } /// /// ICAP_BITDEPTHREDUCTION values /// public enum TWBR : ushort { THRESHOLD = 0, HALFTONE = 1, CUSTHALFTONE = 2, DIFFUSION = 3, DYNAMICTHRESHOLD = 4 } /// /// ICAP_SUPPORTEDBARCODETYPES and TWEI_BARCODETYPE values /// public enum TWBT : ushort { X3OF9 = 0, // 3OF9 in TWAIN.H X2OF5INTERLEAVED = 1, // 2OF5INTERLEAVED in TWAIN.H X2OF5NONINTERLEAVED = 2, // 2OF5NONINTERLEAVED in TWAIN.H CODE93 = 3, CODE128 = 4, UCC128 = 5, CODABAR = 6, UPCA = 7, UPCE = 8, EAN8 = 9, EAN13 = 10, POSTNET = 11, PDF417 = 12, X2OF5INDUSTRIAL = 13, // 2OF5INDUSTRIAL in TWAIN.H X2OF5MATRIX = 14, // 2OF5MATRIX in TWAIN.H X2OF5DATALOGIC = 15, // 2OF5DATALOGIC in TWAIN.H X2OF5IATA = 16, // 2OF5IATA in TWAIN.H X3OF9FULLASCII = 17, // 3OF9FULLASCII in TWAIN.H CODABARWITHSTARTSTOP = 18, MAXICODE = 19, QRCODE = 20 } /// /// ICAP_COMPRESSION values /// public enum TWCP : ushort { NONE = 0, PACKBITS = 1, GROUP31D = 2, GROUP31DEOL = 3, GROUP32D = 4, GROUP4 = 5, JPEG = 6, LZW = 7, JBIG = 8, PNG = 9, RLE4 = 10, RLE8 = 11, BITFIELDS = 12, ZIP = 13, JPEG2000 = 14 } /// /// CAP_CAMERASIDE and TWEI_PAGESIDE values /// public enum TWCS : ushort { BOTH = 0, TOP = 1, BOTTOM = 2 } /// /// CAP_CLEARBUFFERS values /// public enum TWCB : ushort { AUTO = 0, CLEAR = 1, NOCLEAR = 2 } /// /// CAP_DEVICEEVENT values /// public enum TWDE : ushort { CUSTOMEVENTS = 0x8000, CHECKAUTOMATICCAPTURE = 0, CHECKBATTERY = 1, CHECKDEVICEONLINE = 2, CHECKFLASH = 3, CHECKPOWERSUPPLY = 4, CHECKRESOLUTION = 5, DEVICEADDED = 6, DEVICEOFFLINE = 7, DEVICEREADY = 8, DEVICEREMOVED = 9, IMAGECAPTURED = 10, IMAGEDELETED = 11, PAPERDOUBLEFEED = 12, PAPERJAM = 13, LAMPFAILURE = 14, POWERSAVE = 15, POWERSAVENOTIFY = 16 } /// /// TW_PASSTHRU.Direction values /// public enum TWDR : ushort { GET = 1, SET = 2 } /// /// TWEI_DESKEWSTATUS values /// public enum TWDSK : ushort { SUCCESS = 0, REPORTONLY = 1, FAIL = 2, DISABLED = 3 } /// /// CAP_DUPLEX values /// public enum TWDX : ushort { NONE = 0, X1PASSDUPLEX = 1, // 1PASSDUPLEX in TWAIN.H X2PASSDUPLEX = 2 // 2PASSDUPLEX in TWAIN.H } /// /// CAP_FEEDERALIGNMENT values /// public enum TWFA : ushort { NONE = 0, LEFT = 1, CENTER = 2, RIGHT = 3 } /// /// ICAP_FEEDERTYPE values /// public enum TWFE : ushort { GENERAL = 0, PHOTO = 1 } /// /// ICAP_IMAGEFILEFORMAT values /// public enum TWFF : ushort { TIFF = 0, PICT = 1, BMP = 2, XBM = 3, JFIF = 4, FPX = 5, TIFFMULTI = 6, PNG = 7, SPIFF = 8, EXIF = 9, PDF = 10, JP2 = 11, JPX = 13, DEJAVU = 14, PDFA = 15, PDFA2 = 16, PDFRASTER = 17 } /// /// ICAP_FLASHUSED2 values /// public enum TWFL : ushort { NONE = 0, OFF = 1, ON = 2, AUTO = 3, REDEYE = 4 } /// /// CAP_FEEDERORDER values /// public enum TWFO : ushort { FIRSTPAGEFIRST = 0, LASTPAGEFIRST = 1 } /// /// CAP_FEEDERPOCKET values /// public enum TWFP : ushort { POCKETERROR = 0, POCKET1 = 1, POCKET2 = 2, POCKET3 = 3, POCKET4 = 4, POCKET5 = 5, POCKET6 = 6, POCKET7 = 7, POCKET8 = 8, POCKET9 = 9, POCKET10 = 10, POCKET11 = 11, POCKET12 = 12, POCKET13 = 13, POCKET14 = 14, POCKET15 = 15, POCKET16 = 16 } /// /// ICAP_FLIPROTATION values /// public enum TWFR : ushort { BOOK = 0, FANFOLD = 1 } /// /// ICAP_FILTER values /// public enum TWFT : ushort { RED = 0, GREEN = 1, BLUE = 2, NONE = 3, WHITE = 4, CYAN = 5, MAGENTA = 6, YELLOW = 7, BLACK = 8 } /// /// TW_FILESYSTEM.FileType values /// public enum TWFY : ushort { CAMERA = 0, CAMERATOP = 1, CAMERABOTTOM = 2, CAMERAPREVIEW = 3, DOMAIN = 4, HOST = 5, DIRECTORY = 6, IMAGE = 7, UNKNOWN = 8 } /// /// CAP_IAFIELD*_LEVEL values /// public enum TWIA : ushort { UNUSED = 0, FIXED = 1, LEVEL1 = 2, LEVEL2 = 3, LEVEL3 = 4, LEVEL4 = 5 } /// /// ICAP_ICCPROFILE values /// public enum TWIC : ushort { NONE = 0, LINK = 1, EMBED = 2 } /// /// ICAP_IMAGEFILTER values /// public enum TWIF : ushort { NONE = 0, AUTO = 1, LOWPASS = 2, BANDPASS = 3, HIGHPASS = 4, TEXT = BANDPASS, FINELINE = HIGHPASS } /// /// ICAP_IMAGEMERGE values /// public enum TWIM : ushort { NONE = 0, FRONTONTOP = 1, FRONTONBOTTOM = 2, FRONTONLEFT = 3, FRONTONRIGHT = 4 } /// /// CAP_JOBCONTROL values /// public enum TWJC : ushort { NONE = 0, JSIC = 1, JSIS = 2, JSXC = 3, JSXS = 4 } /// /// ICAP_JPEGQUALITY values /// public enum TWJQ : short { UNKNOWN = -4, LOW = -3, MEDIUM = -2, HIGH = -1 } /// /// ICAP_LIGHTPATH values /// public enum TWLP : ushort { REFLECTIVE = 0, TRANSMISSIVE = 1 } /// /// ICAP_LIGHTSOURCE values /// public enum TWLS : ushort { RED = 0, GREEN = 1, BLUE = 2, NONE = 3, WHITE = 4, UV = 5, IR = 6 } /// /// TWEI_MAGTYPE values /// public enum TWMD : ushort { MICR = 0, RAW = 1, INVALID = 2 } /// /// ICAP_NOISEFILTER values /// public enum TWNF : ushort { NONE = 0, AUTO = 1, LONEPIXEL = 2, MAJORITYRULE = 3 } /// /// ICAP_ORIENTATION values /// public enum TWOR : ushort { ROT0 = 0, ROT90 = 1, ROT180 = 2, ROT270 = 3, PORTRAIT = ROT0, LANDSCAPE = ROT270, AUTO = 4, AUTOTEXT = 5, AUTOPICTURE = 6 } /// /// ICAP_OVERSCAN values /// public enum TWOV : ushort { NONE = 0, AUTO = 1, TOPBOTTOM = 2, LEFTRIGHT = 3, ALL = 4 } /// /// Palette types for TW_PALETTE8 /// public enum TWPA : ushort { RGB = 0, GRAY = 1, CMY = 2 } /// /// ICAP_PLANARCHUNKY values /// public enum TWPC : ushort { CHUNKY = 0, PLANAR = 1 } /// /// TWEI_PATCHCODE values /// public enum TWPCH : ushort { PATCH1 = 0, PATCH2 = 1, PATCH3 = 2, PATCH4 = 3, PATCH6 = 4, PATCHT = 5 } /// /// ICAP_PIXELFLAVOR values /// public enum TWPF : ushort { CHOCOLATE = 0, VANILLA = 1 } /// /// CAP_PRINTERMODE values /// public enum TWPM : ushort { SINGLESTRING = 0, MULTISTRING = 1, COMPOUNDSTRING = 2, IMAGEADDRESSSTRING = 3 } /// /// CAP_PRINTER values /// public enum TWPR : ushort { IMPRINTERTOPBEFORE = 0, IMPRINTERTOPAFTER = 1, IMPRINTERBOTTOMBEFORE = 2, IMPRINTERBOTTOMAFTER = 3, ENDORSERTOPBEFORE = 4, ENDORSERTOPAFTER = 5, ENDORSERBOTTOMBEFORE = 6, ENDORSERBOTTOMAFTER = 7 } /// /// CAP_PRINTERFONTSTYLE Added 2.3 (TWPF in TWAIN.H) /// public enum TWPFS : ushort { NORMAL = 0, BOLD = 1, ITALIC = 2, LARGESIZE = 3, SMALLSIZE = 4 } /// /// CAP_PRINTERINDEXTRIGGER Added 2.3 /// public enum TWCT : ushort { PAGE = 0, PATCH1 = 1, PATCH2 = 2, PATCH3 = 3, PATCH4 = 4, PATCHT = 5, PATCH6 = 6 } /// /// CAP_POWERSUPPLY values /// public enum TWPS : ushort { EXTERNAL = 0, BATTERY = 1 } /// /// ICAP_PIXELTYPE values (PT_ means Pixel Type) /// public enum TWPT : ushort { BW = 0, GRAY = 1, RGB = 2, PALETTE = 3, CMY = 4, CMYK = 5, YUV = 6, YUVK = 7, CIEXYZ = 8, LAB = 9, SRGB = 10, SCRGB = 11, INFRARED = 16 } /// /// CAP_SEGMENTED values /// public enum TWSG : ushort { NONE = 0, AUTO = 1, MANUAL = 2 } /// /// ICAP_FILMTYPE values /// public enum TWFM : ushort { POSITIVE = 0, NEGATIVE = 1 } /// /// CAP_DOUBLEFEEDDETECTION values /// public enum TWDF : ushort { ULTRASONIC = 0, BYLENGTH = 1, INFRARED = 2 } /// /// CAP_DOUBLEFEEDDETECTIONSENSITIVITY values /// public enum TWUS : ushort { LOW = 0, MEDIUM = 1, HIGH = 2 } /// /// CAP_DOUBLEFEEDDETECTIONRESPONSE values /// public enum TWDP : ushort { STOP = 0, STOPANDWAIT = 1, SOUND = 2, DONOTIMPRINT = 3 } /// /// ICAP_MIRROR values /// public enum TWMR : ushort { NONE = 0, VERTICAL = 1, HORIZONTAL = 2 } /// /// ICAP_JPEGSUBSAMPLING values /// public enum TWJS : ushort { X444YCBCR = 0, // 444YCBCR in TWAIN.H X444RGB = 1, // 444RGB in TWAIN.H X422 = 2, // 422 in TWAIN.H X421 = 3, // 421 in TWAIN.H X411 = 4, // 411 in TWAIN.H X420 = 5, // 420 in TWAIN.H X410 = 6, // 410 in TWAIN.H X311 = 7 // 311 in TWAIN.H } /// /// CAP_PAPERHANDLING values /// public enum TWPH : ushort { NORMAL = 0, FRAGILE = 1, THICK = 2, TRIFOLD = 3, PHOTOGRAPH = 4 } /// /// CAP_INDICATORSMODE values /// public enum TWCI : ushort { INFO = 0, WARNING = 1, ERROR = 2, WARMUP = 3 } /// /// ICAP_SUPPORTEDSIZES values (SS_ means Supported Sizes) /// public enum TWSS : ushort { NONE = 0, A4 = 1, JISB5 = 2, USLETTER = 3, USLEGAL = 4, A5 = 5, ISOB4 = 6, ISOB6 = 7, USLEDGER = 9, USEXECUTIVE = 10, A3 = 11, ISOB3 = 12, A6 = 13, C4 = 14, C5 = 15, C6 = 16, X4A0 = 17, // 4A0 in TWAIN.H X2A0 = 18, // 2A0 in TWAIN.H A0 = 19, A1 = 20, A2 = 21, A7 = 22, A8 = 23, A9 = 24, A10 = 25, ISOB0 = 26, ISOB1 = 27, ISOB2 = 28, ISOB5 = 29, ISOB7 = 30, ISOB8 = 31, ISOB9 = 32, ISOB10 = 33, JISB0 = 34, JISB1 = 35, JISB2 = 36, JISB3 = 37, JISB4 = 38, JISB6 = 39, JISB7 = 40, JISB8 = 41, JISB9 = 42, JISB10 = 43, C0 = 44, C1 = 45, C2 = 46, C3 = 47, C7 = 48, C8 = 49, C9 = 50, C10 = 51, USSTATEMENT = 52, BUSINESSCARD = 53, MAXSIZE = 54 } /// /// ICAP_XFERMECH values (SX_ means Setup XFer) /// public enum TWSX : ushort { NATIVE = 0, FILE = 1, MEMORY = 2, MEMFILE = 4 } /// /// ICAP_UNITS values (UN_ means UNits) /// public enum TWUN : ushort { INCHES = 0, CENTIMETERS = 1, PICAS = 2, POINTS = 3, TWIPS = 4, PIXELS = 5, MILLIMETERS = 6 } /// /// Country Constants /// public enum TWCY : ushort { AFGHANISTAN = 1001, ALGERIA = 213, AMERICANSAMOA = 684, ANDORRA = 33, ANGOLA = 1002, ANGUILLA = 8090, ANTIGUA = 8091, ARGENTINA = 54, ARUBA = 297, ASCENSIONI = 247, AUSTRALIA = 61, AUSTRIA = 43, BAHAMAS = 8092, BAHRAIN = 973, BANGLADESH = 880, BARBADOS = 8093, BELGIUM = 32, BELIZE = 501, BENIN = 229, BERMUDA = 8094, BHUTAN = 1003, BOLIVIA = 591, BOTSWANA = 267, BRITAIN = 6, BRITVIRGINIS = 8095, BRAZIL = 55, BRUNEI = 673, BULGARIA = 359, BURKINAFASO = 1004, BURMA = 1005, BURUNDI = 1006, CAMAROON = 237, CANADA = 2, CAPEVERDEIS = 238, CAYMANIS = 8096, CENTRALAFREP = 1007, CHAD = 1008, CHILE = 56, CHINA = 86, CHRISTMASIS = 1009, COCOSIS = 1009, COLOMBIA = 57, COMOROS = 1010, CONGO = 1011, COOKIS = 1012, COSTARICA = 506, CUBA = 5, CYPRUS = 357, CZECHOSLOVAKIA = 42, DENMARK = 45, DJIBOUTI = 1013, DOMINICA = 8097, DOMINCANREP = 8098, EASTERIS = 1014, ECUADOR = 593, EGYPT = 20, ELSALVADOR = 503, EQGUINEA = 1015, ETHIOPIA = 251, FALKLANDIS = 1016, FAEROEIS = 298, FIJIISLANDS = 679, FINLAND = 358, FRANCE = 33, FRANTILLES = 596, FRGUIANA = 594, FRPOLYNEISA = 689, FUTANAIS = 1043, GABON = 241, GAMBIA = 220, GERMANY = 49, GHANA = 233, GIBRALTER = 350, GREECE = 30, GREENLAND = 299, GRENADA = 8099, GRENEDINES = 8015, GUADELOUPE = 590, GUAM = 671, GUANTANAMOBAY = 5399, GUATEMALA = 502, GUINEA = 224, GUINEABISSAU = 1017, GUYANA = 592, HAITI = 509, HONDURAS = 504, HONGKONG = 852, HUNGARY = 36, ICELAND = 354, INDIA = 91, INDONESIA = 62, IRAN = 98, IRAQ = 964, IRELAND = 353, ISRAEL = 972, ITALY = 39, IVORYCOAST = 225, JAMAICA = 8010, JAPAN = 81, JORDAN = 962, KENYA = 254, KIRIBATI = 1018, KOREA = 82, KUWAIT = 965, LAOS = 1019, LEBANON = 1020, LIBERIA = 231, LIBYA = 218, LIECHTENSTEIN = 41, LUXENBOURG = 352, MACAO = 853, MADAGASCAR = 1021, MALAWI = 265, MALAYSIA = 60, MALDIVES = 960, MALI = 1022, MALTA = 356, MARSHALLIS = 692, MAURITANIA = 1023, MAURITIUS = 230, MEXICO = 3, MICRONESIA = 691, MIQUELON = 508, MONACO = 33, MONGOLIA = 1024, MONTSERRAT = 8011, MOROCCO = 212, MOZAMBIQUE = 1025, NAMIBIA = 264, NAURU = 1026, NEPAL = 977, NETHERLANDS = 31, NETHANTILLES = 599, NEVIS = 8012, NEWCALEDONIA = 687, NEWZEALAND = 64, NICARAGUA = 505, NIGER = 227, NIGERIA = 234, NIUE = 1027, NORFOLKI = 1028, NORWAY = 47, OMAN = 968, PAKISTAN = 92, PALAU = 1029, PANAMA = 507, PARAGUAY = 595, PERU = 51, PHILLIPPINES = 63, PITCAIRNIS = 1030, PNEWGUINEA = 675, POLAND = 48, PORTUGAL = 351, QATAR = 974, REUNIONI = 1031, ROMANIA = 40, RWANDA = 250, SAIPAN = 670, SANMARINO = 39, SAOTOME = 1033, SAUDIARABIA = 966, SENEGAL = 221, SEYCHELLESIS = 1034, SIERRALEONE = 1035, SINGAPORE = 65, SOLOMONIS = 1036, SOMALI = 1037, SOUTHAFRICA = 27, SPAIN = 34, SRILANKA = 94, STHELENA = 1032, STKITTS = 8013, STLUCIA = 8014, STPIERRE = 508, STVINCENT = 8015, SUDAN = 1038, SURINAME = 597, SWAZILAND = 268, SWEDEN = 46, SWITZERLAND = 41, SYRIA = 1039, TAIWAN = 886, TANZANIA = 255, THAILAND = 66, TOBAGO = 8016, TOGO = 228, TONGAIS = 676, TRINIDAD = 8016, TUNISIA = 216, TURKEY = 90, TURKSCAICOS = 8017, TUVALU = 1040, UGANDA = 256, USSR = 7, UAEMIRATES = 971, UNITEDKINGDOM = 44, USA = 1, URUGUAY = 598, VANUATU = 1041, VATICANCITY = 39, VENEZUELA = 58, WAKE = 1042, WALLISIS = 1043, WESTERNSAHARA = 1044, WESTERNSAMOA = 1045, YEMEN = 1046, YUGOSLAVIA = 38, ZAIRE = 243, ZAMBIA = 260, ZIMBABWE = 263, ALBANIA = 355, ARMENIA = 374, AZERBAIJAN = 994, BELARUS = 375, BOSNIAHERZGO = 387, CAMBODIA = 855, CROATIA = 385, CZECHREPUBLIC = 420, DIEGOGARCIA = 246, ERITREA = 291, ESTONIA = 372, GEORGIA = 995, LATVIA = 371, LESOTHO = 266, LITHUANIA = 370, MACEDONIA = 389, MAYOTTEIS = 269, MOLDOVA = 373, MYANMAR = 95, NORTHKOREA = 850, PUERTORICO = 787, RUSSIA = 7, SERBIA = 381, SLOVAKIA = 421, SLOVENIA = 386, SOUTHKOREA = 82, UKRAINE = 380, USVIRGINIS = 340, VIETNAM = 84 } /// /// Language Constants /// public enum TWLG : short { USERLOCALE = -1, DAN = 0, DUT = 1, ENG = 2, FCF = 3, FIN = 4, FRN = 5, GER = 6, ICE = 7, ITN = 8, NOR = 9, POR = 10, SPA = 11, SWE = 12, USA = 13, AFRIKAANS = 14, ALBANIA = 15, ARABIC = 16, ARABIC_ALGERIA = 17, ARABIC_BAHRAIN = 18, ARABIC_EGYPT = 19, ARABIC_IRAQ = 20, ARABIC_JORDAN = 21, ARABIC_KUWAIT = 22, ARABIC_LEBANON = 23, ARABIC_LIBYA = 24, ARABIC_MOROCCO = 25, ARABIC_OMAN = 26, ARABIC_QATAR = 27, ARABIC_SAUDIARABIA = 28, ARABIC_SYRIA = 29, ARABIC_TUNISIA = 30, ARABIC_UAE = 31, ARABIC_YEMEN = 32, BASQUE = 33, BYELORUSSIAN = 34, BULGARIAN = 35, CATALAN = 36, CHINESE = 37, CHINESE_HONGKONG = 38, CHINESE_PRC = 39, CHINESE_SINGAPORE = 40, CHINESE_SIMPLIFIED = 41, CHINESE_TAIWAN = 42, CHINESE_TRADITIONAL = 43, CROATIA = 44, CZECH = 45, DANISH = DAN, DUTCH = DUT, DUTCH_BELGIAN = 46, ENGLISH = ENG, ENGLISH_AUSTRALIAN = 47, ENGLISH_CANADIAN = 48, ENGLISH_IRELAND = 49, ENGLISH_NEWZEALAND = 50, ENGLISH_SOUTHAFRICA = 51, ENGLISH_UK = 52, ENGLISH_USA = USA, ESTONIAN = 53, FAEROESE = 54, FARSI = 55, FINNISH = FIN, FRENCH = FRN, FRENCH_BELGIAN = 56, FRENCH_CANADIAN = FCF, FRENCH_LUXEMBOURG = 57, FRENCH_SWISS = 58, GERMAN = GER, GERMAN_AUSTRIAN = 59, GERMAN_LUXEMBOURG = 60, GERMAN_LIECHTENSTEIN = 61, GERMAN_SWISS = 62, GREEK = 63, HEBREW = 64, HUNGARIAN = 65, ICELANDIC = ICE, INDONESIAN = 66, ITALIAN = ITN, ITALIAN_SWISS = 67, JAPANESE = 68, KOREAN = 69, KOREAN_JOHAB = 70, LATVIAN = 71, LITHUANIAN = 72, NORWEGIAN = NOR, NORWEGIAN_BOKMAL = 73, NORWEGIAN_NYNORSK = 74, POLISH = 75, PORTUGUESE = POR, PORTUGUESE_BRAZIL = 76, ROMANIAN = 77, RUSSIAN = 78, SERBIAN_LATIN = 79, SLOVAK = 80, SLOVENIAN = 81, SPANISH = TWLG.SPA, SPANISH_MEXICAN = 82, SPANISH_MODERN = 83, SWEDISH = TWLG.SWE, THAI = 84, TURKISH = 85, UKRANIAN = 86, ASSAMESE = 87, BENGALI = 88, BIHARI = 89, BODO = 90, DOGRI = 91, GUJARATI = 92, HARYANVI = 93, HINDI = 94, KANNADA = 95, KASHMIRI = 96, MALAYALAM = 97, MARATHI = 98, MARWARI = 99, MEGHALAYAN = 100, MIZO = 101, NAGA = 102, ORISSI = 103, PUNJABI = 104, PUSHTU = 105, SERBIAN_CYRILLIC = 106, SIKKIMI = 107, SWEDISH_FINLAND = 108, TAMIL = 109, TELUGU = 110, TRIPURI = 111, URDU = 112, VIETNAMESE = 113 //NOTE: when adding to this list, also update Language->Set() } #endregion /////////////////////////////////////////////////////////////////////////////// // Data Groups... /////////////////////////////////////////////////////////////////////////////// #region Data Groups... /// /// Data Groups... /// public enum DG : uint { CONTROL = 0x1, IMAGE = 0x2, AUDIO = 0x4, // More Data Functionality may be added in the future. // These are for items that need to be determined before DS is opened. // NOTE: Supported Functionality constants must be powers of 2 as they are // used as bitflags when Application asks DSM to present a list of DSs. // to support backward capability the App and DS will not use the fields DSM2 = 0x10000000, APP2 = 0x20000000, DS2 = 0x40000000, MASK = 0xFFFF } #endregion /////////////////////////////////////////////////////////////////////////////// // Data Argument Types... /////////////////////////////////////////////////////////////////////////////// #region Data Argument Types... /// /// Data Argument Types... /// public enum DAT : ushort { // NULL and Custom Base... NULL = 0x0, CUSTOM = 0x8000, // Data Argument Types for the DG_CONTROL Data Group. CAPABILITY = 0x1, EVENT = 0x2, IDENTITY = 0x3, PARENT = 0x4, PENDINGXFERS = 0x5, SETUPMEMXFER = 0x6, SETUPFILEXFER = 0x7, STATUS = 0x8, USERINTERFACE = 0x9, XFERGROUP = 0xa, CUSTOMDSDATA = 0xc, DEVICEEVENT = 0xd, FILESYSTEM = 0xe, PASSTHRU = 0xf, CALLBACK = 0x10, STATUSUTF8 = 0x11, CALLBACK2 = 0x12, METRICS = 0x13, TWAINDIRECT = 0x14, // Data Argument Types for the DG_IMAGE Data Group. IMAGEINFO = 0x0101, IMAGELAYOUT = 0x0102, IMAGEMEMXFER = 0x0103, IMAGENATIVEXFER = 0x0104, IMAGEFILEXFER = 0x105, CIECOLOR = 0x106, GRAYRESPONSE = 0x107, RGBRESPONSE = 0x108, JPEGCOMPRESSION = 0x109, PALETTE8 = 0x10a, EXTIMAGEINFO = 0x10b, FILTER = 0x10c, /* Data Argument Types for the DG_AUDIO Data Group. */ AUDIOFILEXFER = 0x201, AUDIOINFO = 0x202, AUDIONATIVEXFER = 0x203, /* misplaced */ ICCPROFILE = 0x401, IMAGEMEMFILEXFER = 0x402, ENTRYPOINT = 0x403 } #endregion /////////////////////////////////////////////////////////////////////////////// // Messages... /////////////////////////////////////////////////////////////////////////////// #region Messages... /// /// All message constants are unique. /// Messages are grouped according to which DATs they are used with. /// public enum MSG : ushort { // Only used to clear fields... NULL = 0x0, // Generic messages may be used with any of several DATs. GET = 0x1, GETCURRENT = 0x2, GETDEFAULT = 0x3, GETFIRST = 0x4, GETNEXT = 0x5, SET = 0x6, RESET = 0x7, QUERYSUPPORT = 0x8, GETHELP = 0x9, GETLABEL = 0xa, GETLABELENUM = 0xb, SETCONSTRAINT = 0xc, // Messages used with DAT_NULL. XFERREADY = 0x101, CLOSEDSREQ = 0x102, CLOSEDSOK = 0x103, DEVICEEVENT = 0x104, // Messages used with a pointer to DAT_PARENT data. OPENDSM = 0x301, CLOSEDSM = 0x302, // Messages used with a pointer to a DAT_IDENTITY structure. OPENDS = 0x401, CLOSEDS = 0x402, USERSELECT = 0x403, // Messages used with a pointer to a DAT_USERINTERFACE structure. DISABLEDS = 0x501, ENABLEDS = 0x502, ENABLEDSUIONLY = 0x503, // Messages used with a pointer to a DAT_EVENT structure. PROCESSEVENT = 0x601, // Messages used with a pointer to a DAT_PENDINGXFERS structure ENDXFER = 0x701, STOPFEEDER = 0x702, // Messages used with a pointer to a DAT_FILESYSTEM structure CHANGEDIRECTORY = 0x0801, CREATEDIRECTORY = 0x0802, DELETE = 0x0803, FORMATMEDIA = 0x0804, GETCLOSE = 0x0805, GETFIRSTFILE = 0x0806, GETINFO = 0x0807, GETNEXTFILE = 0x0808, RENAME = 0x0809, COPY = 0x080A, AUTOMATICCAPTUREDIRECTORY = 0x080B, // Messages used with a pointer to a DAT_PASSTHRU structure PASSTHRU = 0x0901, // used with DAT_CALLBACK REGISTER_CALLBACK = 0x0902, // used with DAT_CAPABILITY RESETALL = 0x0A01, // used with DAT_TWAINDIRECT SETTASK = 0x0B01 } #endregion /////////////////////////////////////////////////////////////////////////////// // Capabilities... /////////////////////////////////////////////////////////////////////////////// #region Capabilities... /// /// The naming convention is a little awkward, but it allows us to /// achieve a unified capability type... /// public enum CAP : ushort { // Base of custom capabilities. CAP_CUSTOMBASE = 0x8000, /* all data sources are REQUIRED to support these caps */ CAP_XFERCOUNT = 0x0001, /* image data sources are REQUIRED to support these caps */ ICAP_COMPRESSION = 0x0100, ICAP_PIXELTYPE = 0x0101, ICAP_UNITS = 0x0102, ICAP_XFERMECH = 0x0103, // all data sources MAY support these caps. CAP_AUTHOR = 0x1000, CAP_CAPTION = 0x1001, CAP_FEEDERENABLED = 0x1002, CAP_FEEDERLOADED = 0x1003, CAP_TIMEDATE = 0x1004, CAP_SUPPORTEDCAPS = 0x1005, CAP_EXTENDEDCAPS = 0x1006, CAP_AUTOFEED = 0x1007, CAP_CLEARPAGE = 0x1008, CAP_FEEDPAGE = 0x1009, CAP_REWINDPAGE = 0x100a, CAP_INDICATORS = 0x100b, CAP_PAPERDETECTABLE = 0x100d, CAP_UICONTROLLABLE = 0x100e, CAP_DEVICEONLINE = 0x100f, CAP_AUTOSCAN = 0x1010, CAP_THUMBNAILSENABLED = 0x1011, CAP_DUPLEX = 0x1012, CAP_DUPLEXENABLED = 0x1013, CAP_ENABLEDSUIONLY = 0x1014, CAP_CUSTOMDSDATA = 0x1015, CAP_ENDORSER = 0x1016, CAP_JOBCONTROL = 0x1017, CAP_ALARMS = 0x1018, CAP_ALARMVOLUME = 0x1019, CAP_AUTOMATICCAPTURE = 0x101a, CAP_TIMEBEFOREFIRSTCAPTURE = 0x101b, CAP_TIMEBETWEENCAPTURES = 0x101c, CAP_CLEARBUFFERS = 0x101d, CAP_MAXBATCHBUFFERS = 0x101e, CAP_DEVICETIMEDATE = 0x101f, CAP_POWERSUPPLY = 0x1020, CAP_CAMERAPREVIEWUI = 0x1021, CAP_DEVICEEVENT = 0x1022, CAP_SERIALNUMBER = 0x1024, CAP_PRINTER = 0x1026, CAP_PRINTERENABLED = 0x1027, CAP_PRINTERINDEX = 0x1028, CAP_PRINTERMODE = 0x1029, CAP_PRINTERSTRING = 0x102a, CAP_PRINTERSUFFIX = 0x102b, CAP_LANGUAGE = 0x102c, CAP_FEEDERALIGNMENT = 0x102d, CAP_FEEDERORDER = 0x102e, CAP_REACQUIREALLOWED = 0x1030, CAP_BATTERYMINUTES = 0x1032, CAP_BATTERYPERCENTAGE = 0x1033, CAP_CAMERASIDE = 0x1034, CAP_SEGMENTED = 0x1035, CAP_CAMERAENABLED = 0x1036, CAP_CAMERAORDER = 0x1037, CAP_MICRENABLED = 0x1038, CAP_FEEDERPREP = 0x1039, CAP_FEEDERPOCKET = 0x103a, CAP_AUTOMATICSENSEMEDIUM = 0x103b, CAP_CUSTOMINTERFACEGUID = 0x103c, CAP_SUPPORTEDCAPSSEGMENTUNIQUE = 0x103d, CAP_SUPPORTEDDATS = 0x103e, CAP_DOUBLEFEEDDETECTION = 0x103f, CAP_DOUBLEFEEDDETECTIONLENGTH = 0x1040, CAP_DOUBLEFEEDDETECTIONSENSITIVITY = 0x1041, CAP_DOUBLEFEEDDETECTIONRESPONSE = 0x1042, CAP_PAPERHANDLING = 0x1043, CAP_INDICATORSMODE = 0x1044, CAP_PRINTERVERTICALOFFSET = 0x1045, CAP_POWERSAVETIME = 0x1046, CAP_PRINTERCHARROTATION = 0x1047, CAP_PRINTERFONTSTYLE = 0x1048, CAP_PRINTERINDEXLEADCHAR = 0x1049, CAP_PRINTERINDEXMAXVALUE = 0x104A, CAP_PRINTERINDEXNUMDIGITS = 0x104B, CAP_PRINTERINDEXSTEP = 0x104C, CAP_PRINTERINDEXTRIGGER = 0x104D, CAP_PRINTERSTRINGPREVIEW = 0x104E, CAP_SHEETCOUNT = 0x104F, CAP_IMAGEADDRESSENABLED = 0x1050, CAP_IAFIELDA_LEVEL = 0x1051, CAP_IAFIELDB_LEVEL = 0x1052, CAP_IAFIELDC_LEVEL = 0x1053, CAP_IAFIELDD_LEVEL = 0x1054, CAP_IAFIELDE_LEVEL = 0x1055, CAP_IAFIELDA_PRINTFORMAT = 0x1056, CAP_IAFIELDB_PRINTFORMAT = 0x1057, CAP_IAFIELDC_PRINTFORMAT = 0x1058, CAP_IAFIELDD_PRINTFORMAT = 0x1059, CAP_IAFIELDE_PRINTFORMAT = 0x105A, CAP_IAFIELDA_VALUE = 0x105B, CAP_IAFIELDB_VALUE = 0x105C, CAP_IAFIELDC_VALUE = 0x105D, CAP_IAFIELDD_VALUE = 0x105E, CAP_IAFIELDE_VALUE = 0x105F, CAP_IAFIELDA_LASTPAGE = 0x1060, CAP_IAFIELDB_LASTPAGE = 0x1061, CAP_IAFIELDC_LASTPAGE = 0x1062, CAP_IAFIELDD_LASTPAGE = 0x1063, CAP_IAFIELDE_LASTPAGE = 0x1064, // image data sources MAY support these caps. ICAP_AUTOBRIGHT = 0x1100, ICAP_BRIGHTNESS = 0x1101, ICAP_CONTRAST = 0x1103, ICAP_CUSTHALFTONE = 0x1104, ICAP_EXPOSURETIME = 0x1105, ICAP_FILTER = 0x1106, ICAP_FLASHUSED = 0x1107, ICAP_GAMMA = 0x1108, ICAP_HALFTONES = 0x1109, ICAP_HIGHLIGHT = 0x110a, ICAP_IMAGEFILEFORMAT = 0x110c, ICAP_LAMPSTATE = 0x110d, ICAP_LIGHTSOURCE = 0x110e, ICAP_ORIENTATION = 0x1110, ICAP_PHYSICALWIDTH = 0x1111, ICAP_PHYSICALHEIGHT = 0x1112, ICAP_SHADOW = 0x1113, ICAP_FRAMES = 0x1114, ICAP_XNATIVERESOLUTION = 0x1116, ICAP_YNATIVERESOLUTION = 0x1117, ICAP_XRESOLUTION = 0x1118, ICAP_YRESOLUTION = 0x1119, ICAP_MAXFRAMES = 0x111a, ICAP_TILES = 0x111b, ICAP_BITORDER = 0x111c, ICAP_CCITTKFACTOR = 0x111d, ICAP_LIGHTPATH = 0x111e, ICAP_PIXELFLAVOR = 0x111f, ICAP_PLANARCHUNKY = 0x1120, ICAP_ROTATION = 0x1121, ICAP_SUPPORTEDSIZES = 0x1122, ICAP_THRESHOLD = 0x1123, ICAP_XSCALING = 0x1124, ICAP_YSCALING = 0x1125, ICAP_BITORDERCODES = 0x1126, ICAP_PIXELFLAVORCODES = 0x1127, ICAP_JPEGPIXELTYPE = 0x1128, ICAP_TIMEFILL = 0x112a, ICAP_BITDEPTH = 0x112b, ICAP_BITDEPTHREDUCTION = 0x112c, ICAP_UNDEFINEDIMAGESIZE = 0x112d, ICAP_IMAGEDATASET = 0x112e, ICAP_EXTIMAGEINFO = 0x112f, ICAP_MINIMUMHEIGHT = 0x1130, ICAP_MINIMUMWIDTH = 0x1131, ICAP_AUTODISCARDBLANKPAGES = 0x1134, ICAP_FLIPROTATION = 0x1136, ICAP_BARCODEDETECTIONENABLED = 0x1137, ICAP_SUPPORTEDBARCODETYPES = 0x1138, ICAP_BARCODEMAXSEARCHPRIORITIES = 0x1139, ICAP_BARCODESEARCHPRIORITIES = 0x113a, ICAP_BARCODESEARCHMODE = 0x113b, ICAP_BARCODEMAXRETRIES = 0x113c, ICAP_BARCODETIMEOUT = 0x113d, ICAP_ZOOMFACTOR = 0x113e, ICAP_PATCHCODEDETECTIONENABLED = 0x113f, ICAP_SUPPORTEDPATCHCODETYPES = 0x1140, ICAP_PATCHCODEMAXSEARCHPRIORITIES = 0x1141, ICAP_PATCHCODESEARCHPRIORITIES = 0x1142, ICAP_PATCHCODESEARCHMODE = 0x1143, ICAP_PATCHCODEMAXRETRIES = 0x1144, ICAP_PATCHCODETIMEOUT = 0x1145, ICAP_FLASHUSED2 = 0x1146, ICAP_IMAGEFILTER = 0x1147, ICAP_NOISEFILTER = 0x1148, ICAP_OVERSCAN = 0x1149, ICAP_AUTOMATICBORDERDETECTION = 0x1150, ICAP_AUTOMATICDESKEW = 0x1151, ICAP_AUTOMATICROTATE = 0x1152, ICAP_JPEGQUALITY = 0x1153, ICAP_FEEDERTYPE = 0x1154, ICAP_ICCPROFILE = 0x1155, ICAP_AUTOSIZE = 0x1156, ICAP_AUTOMATICCROPUSESFRAME = 0x1157, ICAP_AUTOMATICLENGTHDETECTION = 0x1158, ICAP_AUTOMATICCOLORENABLED = 0x1159, ICAP_AUTOMATICCOLORNONCOLORPIXELTYPE = 0x115a, ICAP_COLORMANAGEMENTENABLED = 0x115b, ICAP_IMAGEMERGE = 0x115c, ICAP_IMAGEMERGEHEIGHTTHRESHOLD = 0x115d, ICAP_SUPPORTEDEXTIMAGEINFO = 0x115e, ICAP_FILMTYPE = 0x115f, ICAP_MIRROR = 0x1160, ICAP_JPEGSUBSAMPLING = 0x1161, // image data sources MAY support these audio caps. ACAP_XFERMECH = 0x1202 } #endregion /////////////////////////////////////////////////////////////////////////////// // Extended Image Info Attributes section Added 1.7... /////////////////////////////////////////////////////////////////////////////// #region Extended Image Info Attributes section Added 1.7... /// /// Extended Image Info Attributes... /// public enum TWEI : ushort { BARCODEX = 0x1200, BARCODEY = 0x1201, BARCODETEXT = 0x1202, BARCODETYPE = 0x1203, DESHADETOP = 0x1204, DESHADELEFT = 0x1205, DESHADEHEIGHT = 0x1206, DESHADEWIDTH = 0x1207, DESHADESIZE = 0x1208, SPECKLESREMOVED = 0x1209, HORZLINEXCOORD = 0x120A, HORZLINEYCOORD = 0x120B, HORZLINELENGTH = 0x120C, HORZLINETHICKNESS = 0x120D, VERTLINEXCOORD = 0x120E, VERTLINEYCOORD = 0x120F, VERTLINELENGTH = 0x1210, VERTLINETHICKNESS = 0x1211, PATCHCODE = 0x1212, ENDORSEDTEXT = 0x1213, FORMCONFIDENCE = 0x1214, FORMTEMPLATEMATCH = 0x1215, FORMTEMPLATEPAGEMATCH = 0x1216, FORMHORZDOCOFFSET = 0x1217, FORMVERTDOCOFFSET = 0x1218, BARCODECOUNT = 0x1219, BARCODECONFIDENCE = 0x121A, BARCODEROTATION = 0x121B, BARCODETEXTLENGTH = 0x121C, DESHADECOUNT = 0x121D, DESHADEBLACKCOUNTOLD = 0x121E, DESHADEBLACKCOUNTNEW = 0x121F, DESHADEBLACKRLMIN = 0x1220, DESHADEBLACKRLMAX = 0x1221, DESHADEWHITECOUNTOLD = 0x1222, DESHADEWHITECOUNTNEW = 0x1223, DESHADEWHITERLMIN = 0x1224, DESHADEWHITERLAVE = 0x1225, DESHADEWHITERLMAX = 0x1226, BLACKSPECKLESREMOVED = 0x1227, WHITESPECKLESREMOVED = 0x1228, HORZLINECOUNT = 0x1229, VERTLINECOUNT = 0x122A, DESKEWSTATUS = 0x122B, SKEWORIGINALANGLE = 0x122C, SKEWFINALANGLE = 0x122D, SKEWCONFIDENCE = 0x122E, SKEWWINDOWX1 = 0x122F, SKEWWINDOWY1 = 0x1230, SKEWWINDOWX2 = 0x1231, SKEWWINDOWY2 = 0x1232, SKEWWINDOWX3 = 0x1233, SKEWWINDOWY3 = 0x1234, SKEWWINDOWX4 = 0x1235, SKEWWINDOWY4 = 0x1236, BOOKNAME = 0x1238, CHAPTERNUMBER = 0x1239, DOCUMENTNUMBER = 0x123A, PAGENUMBER = 0x123B, CAMERA = 0x123C, FRAMENUMBER = 0x123D, FRAME = 0x123E, PIXELFLAVOR = 0x123F, ICCPROFILE = 0x1240, LASTSEGMENT = 0x1241, SEGMENTNUMBER = 0x1242, MAGDATA = 0x1243, MAGTYPE = 0x1244, PAGESIDE = 0x1245, FILESYSTEMSOURCE = 0x1246, IMAGEMERGED = 0x1247, MAGDATALENGTH = 0x1248, PAPERCOUNT = 0x1249, PRINTERTEXT = 0x124A, TWAINDIRECTMETADATA = 0x124B, IAFIELDA_VALUE = 0x124C, IAFIELDB_VALUE = 0x124D, IAFIELDC_VALUE = 0x124E, IAFIELDD_VALUE = 0x124F, IAFIELDE_VALUE = 0x1250, IALEVEL = 0x1251, PRINTER = 0x1252, BARCODETEXT2 = 0x1253 } public enum TWEJ : ushort { NONE = 0x0000, MIDSEPARATOR = 0x0001, PATCH1 = 0x0002, PATCH2 = 0x0003, PATCH3 = 0x0004, PATCH4 = 0x0005, PATCH6 = 0x0006, PATCHT = 0x0007 } #endregion /////////////////////////////////////////////////////////////////////////////// // Return Codes and Condition Codes section... /////////////////////////////////////////////////////////////////////////////// #region Return Codes and Condition Codes section... /// /// We're departing from a strict translation of TWAIN.H so that /// we can achieve a unified status return type. /// public const int STSCC = 0x10000; // get us past the custom space public enum STS { // Custom base (same for TWRC and TWCC)... CUSTOMBASE = 0x8000, // Return codes... SUCCESS = 0, FAILURE = 1, CHECKSTATUS = 2, CANCEL = 3, DSEVENT = 4, NOTDSEVENT = 5, XFERDONE = 6, ENDOFLIST = 7, INFONOTSUPPORTED = 8, DATANOTAVAILABLE = 9, BUSY = 10, SCANNERLOCKED = 11, // Condition codes (always associated with TWRC_FAILURE)... BUMMER = STSCC + 1, LOWMEMORY = STSCC + 2, NODS = STSCC + 3, MAXCONNECTIONS = STSCC + 4, OPERATIONERROR = STSCC + 5, BADCAP = STSCC + 6, BADPROTOCOL = STSCC + 9, BADVALUE = STSCC + 10, SEQERROR = STSCC + 11, BADDEST = STSCC + 12, CAPUNSUPPORTED = STSCC + 13, CAPBADOPERATION = STSCC + 14, CAPSEQERROR = STSCC + 15, DENIED = STSCC + 16, FILEEXISTS = STSCC + 17, FILENOTFOUND = STSCC + 18, NOTEMPTY = STSCC + 19, PAPERJAM = STSCC + 20, PAPERDOUBLEFEED = STSCC + 21, FILEWRITEERROR = STSCC + 22, CHECKDEVICEONLINE = STSCC + 23, INTERLOCK = STSCC + 24, DAMAGEDCORNER = STSCC + 25, FOCUSERROR = STSCC + 26, DOCTOOLIGHT = STSCC + 27, DOCTOODARK = STSCC + 28, NOMEDIA = STSCC + 29 } /// /// bit patterns: for query the operation that are supported by the data source on a capability /// Application gets these through DG_CONTROL/DAT_CAPABILITY/MSG_QUERYSUPPORT /// public enum TWQC : ushort { GET = 0x0001, SET = 0x0002, GETDEFAULT = 0x0004, GETCURRENT = 0x0008, RESET = 0x0010, SETCONSTRAINT = 0x0020, CONSTRAINABLE = 0x0040 } /// /// The TWAIN States... /// public enum STATE { S1 = 1, // Nothing loaded or open S2 = 2, // DSM loaded S3 = 3, // DSM open S4 = 4, // Data Source open, programmatic mode (no GUI) S5 = 5, // GUI up or waiting to transfer first image S6 = 6, // ready to start transferring image S7 = 7 // transferring image or transfer done } #endregion /////////////////////////////////////////////////////////////////////////////// // Language section... /////////////////////////////////////////////////////////////////////////////// #region Language section... /// /// Handle encoding between C# and what the DS is currently set to. /// NOTE: this is static for users of this object do not have to track /// the encoding (i.e. let TWAIN.cs deal with all of this). This /// means there is one language for all open DSes, so the last one wins. /// private static class Language { /// /// The encoding to use for strings to/from the DS /// /// public static Encoding GetEncoding() { return (m_encoding); } /// /// The current language of the DS /// /// public static void Set(TWLG a_twlg) { switch (a_twlg) { default: // NOTE: can only get here if a TWLG was added, but it wasn't added here m_encoding = Encoding.GetEncoding(1252); break; case TWLG.USERLOCALE: // NOTE: this should never come back from the DS. only here for completeness m_encoding = Encoding.GetEncoding(1252); break; case TWLG.THAI: m_encoding = Encoding.GetEncoding(874); break; case TWLG.JAPANESE: m_encoding = Encoding.GetEncoding(932); break; case TWLG.CHINESE: case TWLG.CHINESE_PRC: case TWLG.CHINESE_SINGAPORE: case TWLG.CHINESE_SIMPLIFIED: m_encoding = Encoding.GetEncoding(936); break; case TWLG.KOREAN: case TWLG.KOREAN_JOHAB: m_encoding = Encoding.GetEncoding(949); break; case TWLG.CHINESE_HONGKONG: case TWLG.CHINESE_TAIWAN: case TWLG.CHINESE_TRADITIONAL: m_encoding = Encoding.GetEncoding(950); break; case TWLG.ALBANIA: case TWLG.CROATIA: case TWLG.CZECH: case TWLG.HUNGARIAN: case TWLG.POLISH: case TWLG.ROMANIAN: case TWLG.SERBIAN_LATIN: case TWLG.SLOVAK: case TWLG.SLOVENIAN: m_encoding = Encoding.GetEncoding(1250); break; case TWLG.BYELORUSSIAN: case TWLG.BULGARIAN: case TWLG.RUSSIAN: case TWLG.SERBIAN_CYRILLIC: case TWLG.UKRANIAN: m_encoding = Encoding.GetEncoding(1251); break; case TWLG.AFRIKAANS: case TWLG.BASQUE: case TWLG.CATALAN: case TWLG.DAN: // DANISH case TWLG.DUT: // DUTCH case TWLG.DUTCH_BELGIAN: case TWLG.ENG: // ENGLISH case TWLG.ENGLISH_AUSTRALIAN: case TWLG.ENGLISH_CANADIAN: case TWLG.ENGLISH_IRELAND: case TWLG.ENGLISH_NEWZEALAND: case TWLG.ENGLISH_SOUTHAFRICA: case TWLG.ENGLISH_UK: case TWLG.USA: case TWLG.FAEROESE: case TWLG.FIN: // FINNISH case TWLG.FRN: // FRENCH case TWLG.FRENCH_BELGIAN: case TWLG.FCF: // FRENCH_CANADIAN case TWLG.FRENCH_LUXEMBOURG: case TWLG.FRENCH_SWISS: case TWLG.GER: // GERMAN case TWLG.GERMAN_AUSTRIAN: case TWLG.GERMAN_LIECHTENSTEIN: case TWLG.GERMAN_LUXEMBOURG: case TWLG.GERMAN_SWISS: case TWLG.ICE: // ICELANDIC case TWLG.INDONESIAN: case TWLG.ITN: // ITALIAN case TWLG.ITALIAN_SWISS: case TWLG.NOR: // NORWEGIAN case TWLG.NORWEGIAN_BOKMAL: case TWLG.NORWEGIAN_NYNORSK: case TWLG.POR: // PORTUGUESE case TWLG.PORTUGUESE_BRAZIL: case TWLG.SPA: // SPANISH case TWLG.SPANISH_MEXICAN: case TWLG.SPANISH_MODERN: case TWLG.SWE: // SWEDISH case TWLG.SWEDISH_FINLAND: m_encoding = Encoding.GetEncoding(1252); break; case TWLG.GREEK: m_encoding = Encoding.GetEncoding(1253); break; case TWLG.TURKISH: m_encoding = Encoding.GetEncoding(1254); break; case TWLG.HEBREW: m_encoding = Encoding.GetEncoding(1255); break; case TWLG.ARABIC: case TWLG.ARABIC_ALGERIA: case TWLG.ARABIC_BAHRAIN: case TWLG.ARABIC_EGYPT: case TWLG.ARABIC_IRAQ: case TWLG.ARABIC_JORDAN: case TWLG.ARABIC_KUWAIT: case TWLG.ARABIC_LEBANON: case TWLG.ARABIC_LIBYA: case TWLG.ARABIC_MOROCCO: case TWLG.ARABIC_OMAN: case TWLG.ARABIC_QATAR: case TWLG.ARABIC_SAUDIARABIA: case TWLG.ARABIC_SYRIA: case TWLG.ARABIC_TUNISIA: case TWLG.ARABIC_UAE: case TWLG.ARABIC_YEMEN: case TWLG.FARSI: case TWLG.URDU: m_encoding = Encoding.GetEncoding(1256); break; case TWLG.ESTONIAN: case TWLG.LATVIAN: case TWLG.LITHUANIAN: m_encoding = Encoding.GetEncoding(1257); break; case TWLG.VIETNAMESE: m_encoding = Encoding.GetEncoding(1258); break; case TWLG.ASSAMESE: case TWLG.BENGALI: case TWLG.BIHARI: case TWLG.BODO: case TWLG.DOGRI: case TWLG.GUJARATI: case TWLG.HARYANVI: case TWLG.HINDI: case TWLG.KANNADA: case TWLG.KASHMIRI: case TWLG.MALAYALAM: case TWLG.MARATHI: case TWLG.MARWARI: case TWLG.MEGHALAYAN: case TWLG.MIZO: case TWLG.NAGA: case TWLG.ORISSI: case TWLG.PUNJABI: case TWLG.PUSHTU: case TWLG.SIKKIMI: case TWLG.TAMIL: case TWLG.TELUGU: case TWLG.TRIPURI: // NOTE: there are no known code pages for these, so we will use English m_encoding = Encoding.GetEncoding(1252); break; } } private static Encoding m_encoding = Encoding.GetEncoding(1252); } #endregion } /// /// All of our DllImports live here... /// internal sealed class NativeMethods { /////////////////////////////////////////////////////////////////////////////// // Windows /////////////////////////////////////////////////////////////////////////////// #region Windows /// /// Get the ID for the current thread... /// /// [DllImport("kernel32.dll")] internal static extern uint GetCurrentThreadId(); /// /// Allocate a handle to memory... /// /// /// /// [DllImport("kernel32.dll")] internal static extern IntPtr GlobalAlloc(uint uFlags, UIntPtr dwBytes); /// /// Free a memory handle... /// /// /// [DllImport("kernel32.dll")] internal static extern IntPtr GlobalFree(IntPtr hMem); /// /// Lock a memory handle... /// /// /// [DllImport("kernel32.dll")] internal static extern IntPtr GlobalLock(IntPtr hMem); /// /// Unlock a memory handle... /// /// /// [DllImport("kernel32.dll")] [return: MarshalAs(UnmanagedType.Bool)] internal static extern bool GlobalUnlock(IntPtr hMem); [DllImport("kernel32.dll")] internal static extern UIntPtr GlobalSize(IntPtr hMem); [DllImport("msvcrt.dll")] internal static extern UIntPtr _msize(IntPtr ptr); [DllImport("libc.so")] internal static extern UIntPtr malloc_usable_size(IntPtr ptr); [DllImport("libSystem.dylib")] internal static extern UIntPtr malloc_size(IntPtr ptr); [DllImport("kernel32.dll", EntryPoint = "CopyMemory", SetLastError = false)] internal static extern void CopyMemory(IntPtr dest, IntPtr src, uint count); [DllImport("libc", EntryPoint = "memcpy", SetLastError = false)] internal static extern void memcpy(IntPtr dest, IntPtr src, IntPtr count); [DllImport("kernel32.dll", EntryPoint = "MoveMemory", SetLastError = false)] internal static extern void MoveMemory(IntPtr dest, IntPtr src, uint count); [DllImport("libc", EntryPoint = "memmove", SetLastError = false)] internal static extern void memmove(IntPtr dest, IntPtr src, IntPtr count); [DllImport("msvcrt.dll", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Unicode, SetLastError = true)] internal static extern Int32 _wfopen_s(out IntPtr pFile, string filename, string mode); [DllImport("libc", CharSet = CharSet.Ansi, SetLastError = true, BestFitMapping = false, ThrowOnUnmappableChar = true)] internal static extern IntPtr fopen([MarshalAs(UnmanagedType.LPStr)] string filename, [MarshalAs(UnmanagedType.LPStr)] string mode); [DllImport("msvcrt.dll", EntryPoint = "fwrite", CallingConvention = CallingConvention.Cdecl, SetLastError = true)] internal static extern IntPtr fwriteWin(IntPtr buffer, IntPtr size, IntPtr number, IntPtr file); [DllImport("libc", EntryPoint = "fwrite", SetLastError = true)] internal static extern IntPtr fwrite(IntPtr buffer, IntPtr size, IntPtr number, IntPtr file); [DllImport("msvcrt.dll", EntryPoint = "fclose", CallingConvention = CallingConvention.Cdecl, SetLastError = true)] internal static extern IntPtr fcloseWin(IntPtr file); [DllImport("libc", EntryPoint = "fclose", SetLastError = true)] internal static extern IntPtr fclose(IntPtr file); #endregion // We're supporting every DSM that we can... /// /// Use this entry for generic access to the DSM where the /// destination must be IntPtr.Zero (null)... /// /// /// /// /// /// /// /// [SuppressMessage("Microsoft.Interoperability", "CA1400:PInvokeEntryPointsShouldExist")] [DllImport("twain_32.dll", EntryPoint = "DSM_Entry", CharSet = CharSet.Ansi)] internal static extern UInt16 WindowsTwain32DsmEntryNullDest ( ref TWAIN.TW_IDENTITY_LEGACY origin, IntPtr zero, TWAIN.DG dg, TWAIN.DAT dat, TWAIN.MSG msg, IntPtr memref ); [SuppressMessage("Microsoft.Interoperability", "CA1400:PInvokeEntryPointsShouldExist")] [DllImport("twaindsm.dll", EntryPoint = "DSM_Entry", CharSet = CharSet.Ansi)] internal static extern UInt16 WindowsTwaindsmDsmEntryNullDest ( ref TWAIN.TW_IDENTITY_LEGACY origin, IntPtr zero, TWAIN.DG dg, TWAIN.DAT dat, TWAIN.MSG msg, IntPtr memref ); [SuppressMessage("Microsoft.Interoperability", "CA1400:PInvokeEntryPointsShouldExist")] [DllImport("/usr/local/lib/libtwaindsm.so", EntryPoint = "DSM_Entry", CharSet = CharSet.Ansi)] internal static extern UInt16 LinuxDsmEntryNullDest ( ref TWAIN.TW_IDENTITY_LEGACY origin, IntPtr zero, TWAIN.DG dg, TWAIN.DAT dat, TWAIN.MSG msg, IntPtr memref ); [SuppressMessage("Microsoft.Interoperability", "CA1400:PInvokeEntryPointsShouldExist")] [DllImport("/usr/local/lib64/libtwaindsm.so", EntryPoint = "DSM_Entry", CharSet = CharSet.Ansi)] internal static extern UInt16 Linux64DsmEntryNullDest ( ref TWAIN.TW_IDENTITY_LEGACY origin, IntPtr zero, TWAIN.DG dg, TWAIN.DAT dat, TWAIN.MSG msg, IntPtr memref ); [SuppressMessage("Microsoft.Interoperability", "CA1400:PInvokeEntryPointsShouldExist")] [DllImport("/usr/local/lib/libtwaindsm.so.2.3.2", EntryPoint = "DSM_Entry", CharSet = CharSet.Ansi)] internal static extern UInt16 Linux020302Dsm64bitEntryNullDest ( ref TWAIN.TW_IDENTITY origin, IntPtr zero, TWAIN.DG dg, TWAIN.DAT dat, TWAIN.MSG msg, IntPtr memref ); [SuppressMessage("Microsoft.Interoperability", "CA1400:PInvokeEntryPointsShouldExist")] [DllImport("/System/Library/Frameworks/TWAIN.framework/TWAIN", EntryPoint = "DSM_Entry", CharSet = CharSet.Ansi)] internal static extern UInt16 MacosxTwainDsmEntryNullDest ( ref TWAIN.TW_IDENTITY_MACOSX origin, IntPtr zero, TWAIN.DG dg, TWAIN.DAT dat, TWAIN.MSG msg, IntPtr memref ); [SuppressMessage("Microsoft.Interoperability", "CA1400:PInvokeEntryPointsShouldExist")] [DllImport("/Library/Frameworks/TWAINDSM.framework/TWAINDSM", EntryPoint = "DSM_Entry", CharSet = CharSet.Ansi)] internal static extern UInt16 MacosxTwaindsmDsmEntryNullDest ( ref TWAIN.TW_IDENTITY_MACOSX origin, IntPtr zero, TWAIN.DG dg, TWAIN.DAT dat, TWAIN.MSG msg, IntPtr memref ); /// /// Use for generic access to the DSM where the destination must /// reference a data source... /// /// /// /// /// /// /// /// [SuppressMessage("Microsoft.Interoperability", "CA1400:PInvokeEntryPointsShouldExist")] [DllImport("twain_32.dll", EntryPoint = "DSM_Entry", CharSet = CharSet.Ansi)] internal static extern UInt16 WindowsTwain32DsmEntry ( ref TWAIN.TW_IDENTITY_LEGACY origin, ref TWAIN.TW_IDENTITY_LEGACY dest, TWAIN.DG dg, TWAIN.DAT dat, TWAIN.MSG msg, IntPtr memref ); [SuppressMessage("Microsoft.Interoperability", "CA1400:PInvokeEntryPointsShouldExist")] [DllImport("twaindsm.dll", EntryPoint = "DSM_Entry", CharSet = CharSet.Ansi)] internal static extern UInt16 WindowsTwaindsmDsmEntry ( ref TWAIN.TW_IDENTITY_LEGACY origin, ref TWAIN.TW_IDENTITY_LEGACY dest, TWAIN.DG dg, TWAIN.DAT dat, TWAIN.MSG msg, IntPtr memref ); [SuppressMessage("Microsoft.Interoperability", "CA1400:PInvokeEntryPointsShouldExist")] [DllImport("/usr/local/lib/libtwaindsm.so", EntryPoint = "DSM_Entry", CharSet = CharSet.Ansi)] internal static extern UInt16 LinuxDsmEntry ( ref TWAIN.TW_IDENTITY_LEGACY origin, ref TWAIN.TW_IDENTITY_LEGACY dest, TWAIN.DG dg, TWAIN.DAT dat, TWAIN.MSG msg, IntPtr memref ); [SuppressMessage("Microsoft.Interoperability", "CA1400:PInvokeEntryPointsShouldExist")] [DllImport("/usr/local/lib64/libtwaindsm.so", EntryPoint = "DSM_Entry", CharSet = CharSet.Ansi)] internal static extern UInt16 Linux64DsmEntry ( ref TWAIN.TW_IDENTITY_LEGACY origin, ref TWAIN.TW_IDENTITY_LEGACY dest, TWAIN.DG dg, TWAIN.DAT dat, TWAIN.MSG msg, IntPtr memref ); [SuppressMessage("Microsoft.Interoperability", "CA1400:PInvokeEntryPointsShouldExist")] [DllImport("/usr/local/lib/libtwaindsm.so.2.3.2", EntryPoint = "DSM_Entry", CharSet = CharSet.Ansi)] internal static extern UInt16 Linux020302Dsm64bitEntry ( ref TWAIN.TW_IDENTITY origin, ref TWAIN.TW_IDENTITY dest, TWAIN.DG dg, TWAIN.DAT dat, TWAIN.MSG msg, IntPtr memref ); [SuppressMessage("Microsoft.Interoperability", "CA1400:PInvokeEntryPointsShouldExist")] [DllImport("/System/Library/Frameworks/TWAIN.framework/TWAIN", EntryPoint = "DSM_Entry", CharSet = CharSet.Ansi)] internal static extern UInt16 MacosxTwainDsmEntry ( ref TWAIN.TW_IDENTITY_MACOSX origin, ref TWAIN.TW_IDENTITY_MACOSX dest, TWAIN.DG dg, TWAIN.DAT dat, TWAIN.MSG msg, IntPtr memref ); [SuppressMessage("Microsoft.Interoperability", "CA1400:PInvokeEntryPointsShouldExist")] [DllImport("/Library/Frameworks/TWAINDSM.framework/TWAINDSM", EntryPoint = "DSM_Entry", CharSet = CharSet.Ansi)] internal static extern UInt16 MacosxTwaindsmDsmEntry ( ref TWAIN.TW_IDENTITY_MACOSX origin, ref TWAIN.TW_IDENTITY_MACOSX dest, TWAIN.DG dg, TWAIN.DAT dat, TWAIN.MSG msg, IntPtr memref ); /// /// Use this for DG_AUDIO / DAT.AUDIOFILEXFER / MSG.GET calls... /// /// /// /// /// /// /// /// [SuppressMessage("Microsoft.Interoperability", "CA1400:PInvokeEntryPointsShouldExist")] [DllImport("twain_32.dll", EntryPoint = "DSM_Entry", CharSet = CharSet.Ansi)] internal static extern UInt16 WindowsTwain32DsmEntryAudioAudiofilexfer ( ref TWAIN.TW_IDENTITY_LEGACY origin, ref TWAIN.TW_IDENTITY_LEGACY dest, TWAIN.DG dg, TWAIN.DAT dat, TWAIN.MSG msg, IntPtr memref ); [SuppressMessage("Microsoft.Interoperability", "CA1400:PInvokeEntryPointsShouldExist")] [DllImport("twaindsm.dll", EntryPoint = "DSM_Entry", CharSet = CharSet.Ansi)] internal static extern UInt16 WindowsTwaindsmDsmEntryAudioAudiofilexfer ( ref TWAIN.TW_IDENTITY_LEGACY origin, ref TWAIN.TW_IDENTITY_LEGACY dest, TWAIN.DG dg, TWAIN.DAT dat, TWAIN.MSG msg, IntPtr memref ); [SuppressMessage("Microsoft.Interoperability", "CA1400:PInvokeEntryPointsShouldExist")] [DllImport("/usr/local/lib/libtwaindsm.so", EntryPoint = "DSM_Entry", CharSet = CharSet.Ansi)] internal static extern UInt16 LinuxDsmEntryAudioAudiofilexfer ( ref TWAIN.TW_IDENTITY_LEGACY origin, ref TWAIN.TW_IDENTITY_LEGACY dest, TWAIN.DG dg, TWAIN.DAT dat, TWAIN.MSG msg, IntPtr memref ); [SuppressMessage("Microsoft.Interoperability", "CA1400:PInvokeEntryPointsShouldExist")] [DllImport("/usr/local/lib64/libtwaindsm.so", EntryPoint = "DSM_Entry", CharSet = CharSet.Ansi)] internal static extern UInt16 Linux64DsmEntryAudioAudiofilexfer ( ref TWAIN.TW_IDENTITY_LEGACY origin, ref TWAIN.TW_IDENTITY_LEGACY dest, TWAIN.DG dg, TWAIN.DAT dat, TWAIN.MSG msg, IntPtr memref ); [SuppressMessage("Microsoft.Interoperability", "CA1400:PInvokeEntryPointsShouldExist")] [DllImport("/usr/local/lib/libtwaindsm.so.2.3.2", EntryPoint = "DSM_Entry", CharSet = CharSet.Ansi)] internal static extern UInt16 Linux020302Dsm64bitEntryAudioAudiofilexfer ( ref TWAIN.TW_IDENTITY origin, ref TWAIN.TW_IDENTITY dest, TWAIN.DG dg, TWAIN.DAT dat, TWAIN.MSG msg, IntPtr memref ); [SuppressMessage("Microsoft.Interoperability", "CA1400:PInvokeEntryPointsShouldExist")] [DllImport("/System/Library/Frameworks/TWAIN.framework/TWAIN", EntryPoint = "DSM_Entry", CharSet = CharSet.Ansi)] internal static extern UInt16 MacosxTwainDsmEntryAudioAudiofilexfer ( ref TWAIN.TW_IDENTITY_MACOSX origin, ref TWAIN.TW_IDENTITY_MACOSX dest, TWAIN.DG dg, TWAIN.DAT dat, TWAIN.MSG msg, IntPtr memref ); [SuppressMessage("Microsoft.Interoperability", "CA1400:PInvokeEntryPointsShouldExist")] [DllImport("/Library/Frameworks/TWAINDSM.framework/TWAINDSM", EntryPoint = "DSM_Entry", CharSet = CharSet.Ansi)] internal static extern UInt16 MacosxTwaindsmDsmEntryAudioAudiofilexfer ( ref TWAIN.TW_IDENTITY_MACOSX origin, ref TWAIN.TW_IDENTITY_MACOSX dest, TWAIN.DG dg, TWAIN.DAT dat, TWAIN.MSG msg, IntPtr memref ); /// /// Use this for DG_AUDIO / DAT.AUDIOINFO / MSG.GET calls... /// /// /// /// /// /// /// /// [SuppressMessage("Microsoft.Interoperability", "CA1400:PInvokeEntryPointsShouldExist")] [DllImport("twain_32.dll", EntryPoint = "DSM_Entry", CharSet = CharSet.Ansi)] internal static extern UInt16 WindowsTwain32DsmEntryAudioAudioinfo ( ref TWAIN.TW_IDENTITY_LEGACY origin, ref TWAIN.TW_IDENTITY_LEGACY dest, TWAIN.DG dg, TWAIN.DAT dat, TWAIN.MSG msg, ref TWAIN.TW_AUDIOINFO twaudioinfo ); [SuppressMessage("Microsoft.Interoperability", "CA1400:PInvokeEntryPointsShouldExist")] [DllImport("twaindsm.dll", EntryPoint = "DSM_Entry", CharSet = CharSet.Ansi)] internal static extern UInt16 WindowsTwaindsmDsmEntryAudioAudioinfo ( ref TWAIN.TW_IDENTITY_LEGACY origin, ref TWAIN.TW_IDENTITY_LEGACY dest, TWAIN.DG dg, TWAIN.DAT dat, TWAIN.MSG msg, ref TWAIN.TW_AUDIOINFO twaudioinfo ); [SuppressMessage("Microsoft.Interoperability", "CA1400:PInvokeEntryPointsShouldExist")] [DllImport("/usr/local/lib/libtwaindsm.so", EntryPoint = "DSM_Entry", CharSet = CharSet.Ansi)] internal static extern UInt16 LinuxDsmEntryAudioAudioinfo ( ref TWAIN.TW_IDENTITY_LEGACY origin, ref TWAIN.TW_IDENTITY_LEGACY dest, TWAIN.DG dg, TWAIN.DAT dat, TWAIN.MSG msg, ref TWAIN.TW_AUDIOINFO twaudioinfo ); [SuppressMessage("Microsoft.Interoperability", "CA1400:PInvokeEntryPointsShouldExist")] [DllImport("/usr/local/lib64/libtwaindsm.so", EntryPoint = "DSM_Entry", CharSet = CharSet.Ansi)] internal static extern UInt16 Linux64DsmEntryAudioAudioinfo ( ref TWAIN.TW_IDENTITY_LEGACY origin, ref TWAIN.TW_IDENTITY_LEGACY dest, TWAIN.DG dg, TWAIN.DAT dat, TWAIN.MSG msg, ref TWAIN.TW_AUDIOINFO twaudioinfo ); [SuppressMessage("Microsoft.Interoperability", "CA1400:PInvokeEntryPointsShouldExist")] [DllImport("/usr/local/lib/libtwaindsm.so.2.3.2", EntryPoint = "DSM_Entry", CharSet = CharSet.Ansi)] internal static extern UInt16 Linux020302Dsm64bitEntryAudioAudioinfo ( ref TWAIN.TW_IDENTITY origin, ref TWAIN.TW_IDENTITY dest, TWAIN.DG dg, TWAIN.DAT dat, TWAIN.MSG msg, ref TWAIN.TW_AUDIOINFO twaudioinfo ); [SuppressMessage("Microsoft.Interoperability", "CA1400:PInvokeEntryPointsShouldExist")] [DllImport("/System/Library/Frameworks/TWAIN.framework/TWAIN", EntryPoint = "DSM_Entry", CharSet = CharSet.Ansi)] internal static extern UInt16 MacosxTwainDsmEntryAudioAudioinfo ( ref TWAIN.TW_IDENTITY_MACOSX origin, ref TWAIN.TW_IDENTITY_MACOSX dest, TWAIN.DG dg, TWAIN.DAT dat, TWAIN.MSG msg, ref TWAIN.TW_AUDIOINFO twaudioinfo ); [SuppressMessage("Microsoft.Interoperability", "CA1400:PInvokeEntryPointsShouldExist")] [DllImport("/Library/Frameworks/TWAINDSM.framework/TWAINDSM", EntryPoint = "DSM_Entry", CharSet = CharSet.Ansi)] internal static extern UInt16 MacosxTwaindsmDsmEntryAudioAudioinfo ( ref TWAIN.TW_IDENTITY_MACOSX origin, ref TWAIN.TW_IDENTITY_MACOSX dest, TWAIN.DG dg, TWAIN.DAT dat, TWAIN.MSG msg, ref TWAIN.TW_AUDIOINFO twaudioinfo ); /// /// Use this for DG_AUDIO / DAT.AUDIONATIVEXFER / MSG.GET... /// /// /// /// /// /// /// /// /// *** We'll add this later...maybe*** /// /// Use this for DG_CONTROL / DAT.CALLBACK / MSG.* calls... /// /// /// /// /// /// /// /// [SuppressMessage("Microsoft.Interoperability", "CA1400:PInvokeEntryPointsShouldExist")] [DllImport("twain_32.dll", EntryPoint = "DSM_Entry", CharSet = CharSet.Ansi)] internal static extern UInt16 WindowsTwain32DsmEntryCallback ( ref TWAIN.TW_IDENTITY_LEGACY origin, ref TWAIN.TW_IDENTITY_LEGACY dest, TWAIN.DG dg, TWAIN.DAT dat, TWAIN.MSG msg, ref TWAIN.TW_CALLBACK twcallback ); [SuppressMessage("Microsoft.Interoperability", "CA1400:PInvokeEntryPointsShouldExist")] [DllImport("twaindsm.dll", EntryPoint = "DSM_Entry", CharSet = CharSet.Ansi)] internal static extern UInt16 WindowsTwaindsmDsmEntryCallback ( ref TWAIN.TW_IDENTITY_LEGACY origin, ref TWAIN.TW_IDENTITY_LEGACY dest, TWAIN.DG dg, TWAIN.DAT dat, TWAIN.MSG msg, ref TWAIN.TW_CALLBACK twcallback ); [SuppressMessage("Microsoft.Interoperability", "CA1400:PInvokeEntryPointsShouldExist")] [DllImport("/usr/local/lib/libtwaindsm.so", EntryPoint = "DSM_Entry", CharSet = CharSet.Ansi)] internal static extern UInt16 LinuxDsmEntryCallback ( ref TWAIN.TW_IDENTITY_LEGACY origin, ref TWAIN.TW_IDENTITY_LEGACY dest, TWAIN.DG dg, TWAIN.DAT dat, TWAIN.MSG msg, ref TWAIN.TW_CALLBACK twcallback ); [SuppressMessage("Microsoft.Interoperability", "CA1400:PInvokeEntryPointsShouldExist")] [DllImport("/usr/local/lib64/libtwaindsm.so", EntryPoint = "DSM_Entry", CharSet = CharSet.Ansi)] internal static extern UInt16 Linux64DsmEntryCallback ( ref TWAIN.TW_IDENTITY_LEGACY origin, ref TWAIN.TW_IDENTITY_LEGACY dest, TWAIN.DG dg, TWAIN.DAT dat, TWAIN.MSG msg, ref TWAIN.TW_CALLBACK twcallback ); [SuppressMessage("Microsoft.Interoperability", "CA1400:PInvokeEntryPointsShouldExist")] [DllImport("/usr/local/lib/libtwaindsm.so.2.3.2", EntryPoint = "DSM_Entry", CharSet = CharSet.Ansi)] internal static extern UInt16 Linux020302Dsm64bitEntryCallback ( ref TWAIN.TW_IDENTITY origin, ref TWAIN.TW_IDENTITY dest, TWAIN.DG dg, TWAIN.DAT dat, TWAIN.MSG msg, ref TWAIN.TW_CALLBACK twcallback ); [SuppressMessage("Microsoft.Interoperability", "CA1400:PInvokeEntryPointsShouldExist")] [DllImport("/System/Library/Frameworks/TWAIN.framework/TWAIN", EntryPoint = "DSM_Entry", CharSet = CharSet.Ansi)] internal static extern UInt16 MacosxTwainDsmEntryCallback ( ref TWAIN.TW_IDENTITY_MACOSX origin, IntPtr dest, TWAIN.DG dg, TWAIN.DAT dat, TWAIN.MSG msg, ref TWAIN.TW_CALLBACK twcallback ); [SuppressMessage("Microsoft.Interoperability", "CA1400:PInvokeEntryPointsShouldExist")] [DllImport("/Library/Frameworks/TWAINDSM.framework/TWAINDSM", EntryPoint = "DSM_Entry", CharSet = CharSet.Ansi)] internal static extern UInt16 MacosxTwaindsmDsmEntryCallback ( ref TWAIN.TW_IDENTITY_MACOSX origin, ref TWAIN.TW_IDENTITY dest, TWAIN.DG dg, TWAIN.DAT dat, TWAIN.MSG msg, ref TWAIN.TW_CALLBACK twcallback ); public delegate UInt16 WindowsDsmEntryCallbackDelegate ( ref TWAIN.TW_IDENTITY_LEGACY origin, ref TWAIN.TW_IDENTITY_LEGACY dest, TWAIN.DG dg, TWAIN.DAT dat, TWAIN.MSG msg, IntPtr twnull ); public delegate UInt16 LinuxDsmEntryCallbackDelegate ( ref TWAIN.TW_IDENTITY_LEGACY origin, ref TWAIN.TW_IDENTITY_LEGACY dest, TWAIN.DG dg, TWAIN.DAT dat, TWAIN.MSG msg, IntPtr twnull ); public delegate UInt16 Linux020302Dsm64bitEntryCallbackDelegate ( ref TWAIN.TW_IDENTITY origin, ref TWAIN.TW_IDENTITY dest, TWAIN.DG dg, TWAIN.DAT dat, TWAIN.MSG msg, IntPtr twnull ); public delegate UInt16 MacosxDsmEntryCallbackDelegate ( ref TWAIN.TW_IDENTITY_MACOSX origin, ref TWAIN.TW_IDENTITY_MACOSX dest, TWAIN.DG dg, TWAIN.DAT dat, TWAIN.MSG msg, IntPtr twnull ); /// /// Use this for DG_CONTROL / DAT.CALLBACK2 / MSG.* calls... /// /// /// /// /// /// /// /// [SuppressMessage("Microsoft.Interoperability", "CA1400:PInvokeEntryPointsShouldExist")] [DllImport("twain_32.dll", EntryPoint = "DSM_Entry", CharSet = CharSet.Ansi)] internal static extern UInt16 WindowsTwain32DsmEntryCallback2 ( ref TWAIN.TW_IDENTITY_LEGACY origin, ref TWAIN.TW_IDENTITY_LEGACY dest, TWAIN.DG dg, TWAIN.DAT dat, TWAIN.MSG msg, ref TWAIN.TW_CALLBACK2 twcallback2 ); [SuppressMessage("Microsoft.Interoperability", "CA1400:PInvokeEntryPointsShouldExist")] [DllImport("twaindsm.dll", EntryPoint = "DSM_Entry", CharSet = CharSet.Ansi)] internal static extern UInt16 WindowsTwaindsmDsmEntryCallback2 ( ref TWAIN.TW_IDENTITY_LEGACY origin, ref TWAIN.TW_IDENTITY_LEGACY dest, TWAIN.DG dg, TWAIN.DAT dat, TWAIN.MSG msg, ref TWAIN.TW_CALLBACK2 twcallback2 ); [SuppressMessage("Microsoft.Interoperability", "CA1400:PInvokeEntryPointsShouldExist")] [DllImport("/usr/local/lib/libtwaindsm.so", EntryPoint = "DSM_Entry", CharSet = CharSet.Ansi)] internal static extern UInt16 LinuxDsmEntryCallback2 ( ref TWAIN.TW_IDENTITY_LEGACY origin, ref TWAIN.TW_IDENTITY_LEGACY dest, TWAIN.DG dg, TWAIN.DAT dat, TWAIN.MSG msg, ref TWAIN.TW_CALLBACK2 twcallback2 ); [SuppressMessage("Microsoft.Interoperability", "CA1400:PInvokeEntryPointsShouldExist")] [DllImport("/usr/local/lib64/libtwaindsm.so", EntryPoint = "DSM_Entry", CharSet = CharSet.Ansi)] internal static extern UInt16 Linux64DsmEntryCallback2 ( ref TWAIN.TW_IDENTITY_LEGACY origin, ref TWAIN.TW_IDENTITY_LEGACY dest, TWAIN.DG dg, TWAIN.DAT dat, TWAIN.MSG msg, ref TWAIN.TW_CALLBACK2 twcallback2 ); [SuppressMessage("Microsoft.Interoperability", "CA1400:PInvokeEntryPointsShouldExist")] [DllImport("/usr/local/lib/libtwaindsm.so.2.3.2", EntryPoint = "DSM_Entry", CharSet = CharSet.Ansi)] internal static extern UInt16 Linux020302Dsm64bitEntryCallback2 ( ref TWAIN.TW_IDENTITY origin, ref TWAIN.TW_IDENTITY dest, TWAIN.DG dg, TWAIN.DAT dat, TWAIN.MSG msg, ref TWAIN.TW_CALLBACK2 twcallback2 ); [SuppressMessage("Microsoft.Interoperability", "CA1400:PInvokeEntryPointsShouldExist")] [DllImport("/System/Library/Frameworks/TWAIN.framework/TWAIN", EntryPoint = "DSM_Entry", CharSet = CharSet.Ansi)] internal static extern UInt16 MacosxTwainDsmEntryCallback2 ( ref TWAIN.TW_IDENTITY_MACOSX origin, IntPtr dest, TWAIN.DG dg, TWAIN.DAT dat, TWAIN.MSG msg, ref TWAIN.TW_CALLBACK2 twcallback ); [SuppressMessage("Microsoft.Interoperability", "CA1400:PInvokeEntryPointsShouldExist")] [DllImport("/Library/Frameworks/TWAINDSM.framework/TWAINDSM", EntryPoint = "DSM_Entry", CharSet = CharSet.Ansi)] internal static extern UInt16 MacosxTwaindsmDsmEntryCallback2 ( ref TWAIN.TW_IDENTITY_MACOSX origin, ref TWAIN.TW_IDENTITY des, TWAIN.DG dg, TWAIN.DAT dat, TWAIN.MSG msg, ref TWAIN.TW_CALLBACK2 twcallback ); private delegate UInt16 WindowsDsmEntryCallback2Delegate ( ref TWAIN.TW_IDENTITY_LEGACY origin, ref TWAIN.TW_IDENTITY_LEGACY dest, TWAIN.DG dg, TWAIN.DAT dat, TWAIN.MSG msg, IntPtr twnull ); private delegate UInt16 LinuxDsmEntryCallback2Delegate ( ref TWAIN.TW_IDENTITY_LEGACY origin, ref TWAIN.TW_IDENTITY_LEGACY dest, TWAIN.DG dg, TWAIN.DAT dat, TWAIN.MSG msg, IntPtr twnull ); private delegate UInt16 Linux020302Dsm64bitEntryCallback2Delegate ( ref TWAIN.TW_IDENTITY origin, ref TWAIN.TW_IDENTITY dest, TWAIN.DG dg, TWAIN.DAT dat, TWAIN.MSG msg, IntPtr twnull ); private delegate UInt16 MacosxDsmEntryCallback2Delegate ( ref TWAIN.TW_IDENTITY_MACOSX origin, ref TWAIN.TW_IDENTITY_MACOSX dest, TWAIN.DG dg, TWAIN.DAT dat, TWAIN.MSG msg, IntPtr twnull ); /// /// Use this for DG_CONTROL / DAT.CAPABILITY / MSG.* calls... /// /// /// /// /// /// /// /// [SuppressMessage("Microsoft.Interoperability", "CA1400:PInvokeEntryPointsShouldExist")] [DllImport("twain_32.dll", EntryPoint = "DSM_Entry", CharSet = CharSet.Ansi)] internal static extern UInt16 WindowsTwain32DsmEntryCapability ( ref TWAIN.TW_IDENTITY_LEGACY origin, ref TWAIN.TW_IDENTITY_LEGACY dest, TWAIN.DG dg, TWAIN.DAT dat, TWAIN.MSG msg, ref TWAIN.TW_CAPABILITY twcapability ); [SuppressMessage("Microsoft.Interoperability", "CA1400:PInvokeEntryPointsShouldExist")] [DllImport("twaindsm.dll", EntryPoint = "DSM_Entry", CharSet = CharSet.Ansi)] internal static extern UInt16 WindowsTwaindsmDsmEntryCapability ( ref TWAIN.TW_IDENTITY_LEGACY origin, ref TWAIN.TW_IDENTITY_LEGACY dest, TWAIN.DG dg, TWAIN.DAT dat, TWAIN.MSG msg, ref TWAIN.TW_CAPABILITY twcapability ); [SuppressMessage("Microsoft.Interoperability", "CA1400:PInvokeEntryPointsShouldExist")] [DllImport("/usr/local/lib/libtwaindsm.so", EntryPoint = "DSM_Entry", CharSet = CharSet.Ansi)] internal static extern UInt16 LinuxDsmEntryCapability ( ref TWAIN.TW_IDENTITY_LEGACY origin, ref TWAIN.TW_IDENTITY_LEGACY dest, TWAIN.DG dg, TWAIN.DAT dat, TWAIN.MSG msg, ref TWAIN.TW_CAPABILITY twcapability ); [SuppressMessage("Microsoft.Interoperability", "CA1400:PInvokeEntryPointsShouldExist")] [DllImport("/usr/local/lib64/libtwaindsm.so", EntryPoint = "DSM_Entry", CharSet = CharSet.Ansi)] internal static extern UInt16 Linux64DsmEntryCapability ( ref TWAIN.TW_IDENTITY_LEGACY origin, ref TWAIN.TW_IDENTITY_LEGACY dest, TWAIN.DG dg, TWAIN.DAT dat, TWAIN.MSG msg, ref TWAIN.TW_CAPABILITY twcapability ); [SuppressMessage("Microsoft.Interoperability", "CA1400:PInvokeEntryPointsShouldExist")] [DllImport("/usr/local/lib/libtwaindsm.so.2.3.2", EntryPoint = "DSM_Entry", CharSet = CharSet.Ansi)] internal static extern UInt16 Linux020302Dsm64bitEntryCapability ( ref TWAIN.TW_IDENTITY origin, ref TWAIN.TW_IDENTITY dest, TWAIN.DG dg, TWAIN.DAT dat, TWAIN.MSG msg, ref TWAIN.TW_CAPABILITY twcapability ); [SuppressMessage("Microsoft.Interoperability", "CA1400:PInvokeEntryPointsShouldExist")] [DllImport("/System/Library/Frameworks/TWAIN.framework/TWAIN", EntryPoint = "DSM_Entry", CharSet = CharSet.Ansi)] internal static extern UInt16 MacosxTwainDsmEntryCapability ( ref TWAIN.TW_IDENTITY_MACOSX origin, ref TWAIN.TW_IDENTITY_MACOSX dest, TWAIN.DG dg, TWAIN.DAT dat, TWAIN.MSG msg, ref TWAIN.TW_CAPABILITY twcapability ); [SuppressMessage("Microsoft.Interoperability", "CA1400:PInvokeEntryPointsShouldExist")] [DllImport("/Library/Frameworks/TWAINDSM.framework/TWAINDSM", EntryPoint = "DSM_Entry", CharSet = CharSet.Ansi)] internal static extern UInt16 MacosxTwaindsmDsmEntryCapability ( ref TWAIN.TW_IDENTITY_MACOSX origin, ref TWAIN.TW_IDENTITY_MACOSX dest, TWAIN.DG dg, TWAIN.DAT dat, TWAIN.MSG msg, ref TWAIN.TW_CAPABILITY twcapability ); /// /// Use this for DG_CONTROL / DAT.CUSTOMDSDATA / MSG.* calls... /// /// /// /// /// /// /// /// [SuppressMessage("Microsoft.Interoperability", "CA1400:PInvokeEntryPointsShouldExist")] [DllImport("twain_32.dll", EntryPoint = "DSM_Entry", CharSet = CharSet.Ansi)] internal static extern UInt16 WindowsTwain32DsmEntryCustomdsdata ( ref TWAIN.TW_IDENTITY_LEGACY origin, ref TWAIN.TW_IDENTITY_LEGACY dest, TWAIN.DG dg, TWAIN.DAT dat, TWAIN.MSG msg, ref TWAIN.TW_CUSTOMDSDATA twcustomedsdata ); [SuppressMessage("Microsoft.Interoperability", "CA1400:PInvokeEntryPointsShouldExist")] [DllImport("twaindsm.dll", EntryPoint = "DSM_Entry", CharSet = CharSet.Ansi)] internal static extern UInt16 WindowsTwaindsmDsmEntryCustomdsdata ( ref TWAIN.TW_IDENTITY_LEGACY origin, ref TWAIN.TW_IDENTITY_LEGACY dest, TWAIN.DG dg, TWAIN.DAT dat, TWAIN.MSG msg, ref TWAIN.TW_CUSTOMDSDATA twcustomdsdata ); [SuppressMessage("Microsoft.Interoperability", "CA1400:PInvokeEntryPointsShouldExist")] [DllImport("/usr/local/lib/libtwaindsm.so", EntryPoint = "DSM_Entry", CharSet = CharSet.Ansi)] internal static extern UInt16 LinuxDsmEntryCustomdsdata ( ref TWAIN.TW_IDENTITY_LEGACY origin, ref TWAIN.TW_IDENTITY_LEGACY dest, TWAIN.DG dg, TWAIN.DAT dat, TWAIN.MSG msg, ref TWAIN.TW_CUSTOMDSDATA twcustomdsdata ); [SuppressMessage("Microsoft.Interoperability", "CA1400:PInvokeEntryPointsShouldExist")] [DllImport("/usr/local/lib64/libtwaindsm.so", EntryPoint = "DSM_Entry", CharSet = CharSet.Ansi)] internal static extern UInt16 Linux64DsmEntryCustomdsdata ( ref TWAIN.TW_IDENTITY_LEGACY origin, ref TWAIN.TW_IDENTITY_LEGACY dest, TWAIN.DG dg, TWAIN.DAT dat, TWAIN.MSG msg, ref TWAIN.TW_CUSTOMDSDATA twcustomdsdata ); [SuppressMessage("Microsoft.Interoperability", "CA1400:PInvokeEntryPointsShouldExist")] [DllImport("/usr/local/lib/libtwaindsm.so.2.3.2", EntryPoint = "DSM_Entry", CharSet = CharSet.Ansi)] internal static extern UInt16 Linux020302Dsm64bitEntryCustomdsdata ( ref TWAIN.TW_IDENTITY origin, ref TWAIN.TW_IDENTITY dest, TWAIN.DG dg, TWAIN.DAT dat, TWAIN.MSG msg, ref TWAIN.TW_CUSTOMDSDATA twcustomdsdata ); [SuppressMessage("Microsoft.Interoperability", "CA1400:PInvokeEntryPointsShouldExist")] [DllImport("/System/Library/Frameworks/TWAIN.framework/TWAIN", EntryPoint = "DSM_Entry", CharSet = CharSet.Ansi)] internal static extern UInt16 MacosxTwainDsmEntryCustomdsdata ( ref TWAIN.TW_IDENTITY_MACOSX origin, ref TWAIN.TW_IDENTITY_MACOSX dest, TWAIN.DG dg, TWAIN.DAT dat, TWAIN.MSG msg, ref TWAIN.TW_CUSTOMDSDATA twcustomedsdata ); [SuppressMessage("Microsoft.Interoperability", "CA1400:PInvokeEntryPointsShouldExist")] [DllImport("/Library/Frameworks/TWAINDSM.framework/TWAINDSM", EntryPoint = "DSM_Entry", CharSet = CharSet.Ansi)] internal static extern UInt16 MacosxTwaindsmDsmEntryCustomdsdata ( ref TWAIN.TW_IDENTITY_MACOSX origin, ref TWAIN.TW_IDENTITY_MACOSX dest, TWAIN.DG dg, TWAIN.DAT dat, TWAIN.MSG msg, ref TWAIN.TW_CUSTOMDSDATA twcustomedsdata ); /// /// Use this for DG_CONTROL / DAT.DEVICEEVENT / MSG.* calls... /// /// /// /// /// /// /// /// [SuppressMessage("Microsoft.Interoperability", "CA1400:PInvokeEntryPointsShouldExist")] [DllImport("twain_32.dll", EntryPoint = "DSM_Entry", CharSet = CharSet.Ansi)] internal static extern UInt16 WindowsTwain32DsmEntryDeviceevent ( ref TWAIN.TW_IDENTITY_LEGACY origin, ref TWAIN.TW_IDENTITY_LEGACY dest, TWAIN.DG dg, TWAIN.DAT dat, TWAIN.MSG msg, ref TWAIN.TW_DEVICEEVENT twdeviceevent ); [SuppressMessage("Microsoft.Interoperability", "CA1400:PInvokeEntryPointsShouldExist")] [DllImport("twaindsm.dll", EntryPoint = "DSM_Entry", CharSet = CharSet.Ansi)] internal static extern UInt16 WindowsTwaindsmDsmEntryDeviceevent ( ref TWAIN.TW_IDENTITY_LEGACY origin, ref TWAIN.TW_IDENTITY_LEGACY dest, TWAIN.DG dg, TWAIN.DAT dat, TWAIN.MSG msg, ref TWAIN.TW_DEVICEEVENT twdeviceevent ); [SuppressMessage("Microsoft.Interoperability", "CA1400:PInvokeEntryPointsShouldExist")] [DllImport("/usr/local/lib/libtwaindsm.so", EntryPoint = "DSM_Entry", CharSet = CharSet.Ansi)] internal static extern UInt16 LinuxDsmEntryDeviceevent ( ref TWAIN.TW_IDENTITY_LEGACY origin, ref TWAIN.TW_IDENTITY_LEGACY dest, TWAIN.DG dg, TWAIN.DAT dat, TWAIN.MSG msg, ref TWAIN.TW_DEVICEEVENT twdeviceevent ); [SuppressMessage("Microsoft.Interoperability", "CA1400:PInvokeEntryPointsShouldExist")] [DllImport("/usr/local/lib64/libtwaindsm.so", EntryPoint = "DSM_Entry", CharSet = CharSet.Ansi)] internal static extern UInt16 Linux64DsmEntryDeviceevent ( ref TWAIN.TW_IDENTITY_LEGACY origin, ref TWAIN.TW_IDENTITY_LEGACY dest, TWAIN.DG dg, TWAIN.DAT dat, TWAIN.MSG msg, ref TWAIN.TW_DEVICEEVENT twdeviceevent ); [SuppressMessage("Microsoft.Interoperability", "CA1400:PInvokeEntryPointsShouldExist")] [DllImport("/usr/local/lib/libtwaindsm.so.2.3.2", EntryPoint = "DSM_Entry", CharSet = CharSet.Ansi)] internal static extern UInt16 Linux020302Dsm64bitEntryDeviceevent ( ref TWAIN.TW_IDENTITY origin, ref TWAIN.TW_IDENTITY dest, TWAIN.DG dg, TWAIN.DAT dat, TWAIN.MSG msg, ref TWAIN.TW_DEVICEEVENT twdeviceevent ); [SuppressMessage("Microsoft.Interoperability", "CA1400:PInvokeEntryPointsShouldExist")] [DllImport("/System/Library/Frameworks/TWAIN.framework/TWAIN", EntryPoint = "DSM_Entry", CharSet = CharSet.Ansi)] internal static extern UInt16 MacosxTwainDsmEntryDeviceevent ( ref TWAIN.TW_IDENTITY_MACOSX origin, ref TWAIN.TW_IDENTITY_MACOSX dest, TWAIN.DG dg, TWAIN.DAT dat, TWAIN.MSG msg, ref TWAIN.TW_DEVICEEVENT twdeviceevent ); [SuppressMessage("Microsoft.Interoperability", "CA1400:PInvokeEntryPointsShouldExist")] [DllImport("/Library/Frameworks/TWAINDSM.framework/TWAINDSM", EntryPoint = "DSM_Entry", CharSet = CharSet.Ansi)] internal static extern UInt16 MacosxTwaindsmDsmEntryDeviceevent ( ref TWAIN.TW_IDENTITY_MACOSX origin, ref TWAIN.TW_IDENTITY_MACOSX dest, TWAIN.DG dg, TWAIN.DAT dat, TWAIN.MSG msg, ref TWAIN.TW_DEVICEEVENT twdeviceevent ); /// /// Use this for DG_CONTROL / DAT.EVENT / MSG.* calls... /// /// /// /// /// /// /// /// [SuppressMessage("Microsoft.Interoperability", "CA1400:PInvokeEntryPointsShouldExist")] [DllImport("twain_32.dll", EntryPoint = "DSM_Entry", CharSet = CharSet.Ansi)] internal static extern UInt16 WindowsTwain32DsmEntryEvent ( ref TWAIN.TW_IDENTITY_LEGACY origin, ref TWAIN.TW_IDENTITY_LEGACY dest, TWAIN.DG dg, TWAIN.DAT dat, TWAIN.MSG msg, ref TWAIN.TW_EVENT twevent ); [SuppressMessage("Microsoft.Interoperability", "CA1400:PInvokeEntryPointsShouldExist")] [DllImport("twaindsm.dll", EntryPoint = "DSM_Entry", CharSet = CharSet.Ansi)] internal static extern UInt16 WindowsTwaindsmDsmEntryEvent ( ref TWAIN.TW_IDENTITY_LEGACY origin, ref TWAIN.TW_IDENTITY_LEGACY dest, TWAIN.DG dg, TWAIN.DAT dat, TWAIN.MSG msg, ref TWAIN.TW_EVENT twevent ); [SuppressMessage("Microsoft.Interoperability", "CA1400:PInvokeEntryPointsShouldExist")] [DllImport("/usr/local/lib/libtwaindsm.so", EntryPoint = "DSM_Entry", CharSet = CharSet.Ansi)] internal static extern UInt16 LinuxDsmEntryEvent ( ref TWAIN.TW_IDENTITY_LEGACY origin, ref TWAIN.TW_IDENTITY_LEGACY dest, TWAIN.DG dg, TWAIN.DAT dat, TWAIN.MSG msg, ref TWAIN.TW_EVENT twevent ); [SuppressMessage("Microsoft.Interoperability", "CA1400:PInvokeEntryPointsShouldExist")] [DllImport("/usr/local/lib64/libtwaindsm.so", EntryPoint = "DSM_Entry", CharSet = CharSet.Ansi)] internal static extern UInt16 Linux64DsmEntryEvent ( ref TWAIN.TW_IDENTITY_LEGACY origin, ref TWAIN.TW_IDENTITY_LEGACY dest, TWAIN.DG dg, TWAIN.DAT dat, TWAIN.MSG msg, ref TWAIN.TW_EVENT twevent ); [SuppressMessage("Microsoft.Interoperability", "CA1400:PInvokeEntryPointsShouldExist")] [DllImport("/usr/local/lib/libtwaindsm.so.2.3.2", EntryPoint = "DSM_Entry", CharSet = CharSet.Ansi)] internal static extern UInt16 Linux020302Dsm64bitEntryEvent ( ref TWAIN.TW_IDENTITY origin, ref TWAIN.TW_IDENTITY dest, TWAIN.DG dg, TWAIN.DAT dat, TWAIN.MSG msg, ref TWAIN.TW_EVENT twevent ); [SuppressMessage("Microsoft.Interoperability", "CA1400:PInvokeEntryPointsShouldExist")] [DllImport("/System/Library/Frameworks/TWAIN.framework/TWAIN", EntryPoint = "DSM_Entry", CharSet = CharSet.Ansi)] internal static extern UInt16 MacosxTwainDsmEntryEvent ( ref TWAIN.TW_IDENTITY_MACOSX origin, ref TWAIN.TW_IDENTITY_MACOSX dest, TWAIN.DG dg, TWAIN.DAT dat, TWAIN.MSG msg, ref TWAIN.TW_EVENT twevent ); [SuppressMessage("Microsoft.Interoperability", "CA1400:PInvokeEntryPointsShouldExist")] [DllImport("/Library/Frameworks/TWAINDSM.framework/TWAINDSM", EntryPoint = "DSM_Entry", CharSet = CharSet.Ansi)] internal static extern UInt16 MacosxTwaindsmDsmEntryEvent ( ref TWAIN.TW_IDENTITY_MACOSX origin, ref TWAIN.TW_IDENTITY_MACOSX dest, TWAIN.DG dg, TWAIN.DAT dat, TWAIN.MSG msg, ref TWAIN.TW_EVENT twevent ); /// /// Use this for DG_CONTROL / DAT.ENTRYPOINT / MSG.* calls... /// /// /// /// /// /// /// /// [SuppressMessage("Microsoft.Interoperability", "CA1400:PInvokeEntryPointsShouldExist")] [DllImport("twain_32.dll", EntryPoint = "DSM_Entry", CharSet = CharSet.Ansi)] internal static extern UInt16 WindowsTwain32DsmEntryEntrypoint ( ref TWAIN.TW_IDENTITY_LEGACY origin, ref TWAIN.TW_IDENTITY_LEGACY dest, TWAIN.DG dg, TWAIN.DAT dat, TWAIN.MSG msg, ref TWAIN.TW_ENTRYPOINT twentrypoint ); [SuppressMessage("Microsoft.Interoperability", "CA1400:PInvokeEntryPointsShouldExist")] [DllImport("twaindsm.dll", EntryPoint = "DSM_Entry", CharSet = CharSet.Ansi)] internal static extern UInt16 WindowsTwaindsmDsmEntryEntrypoint ( ref TWAIN.TW_IDENTITY_LEGACY origin, ref TWAIN.TW_IDENTITY_LEGACY dest, TWAIN.DG dg, TWAIN.DAT dat, TWAIN.MSG msg, ref TWAIN.TW_ENTRYPOINT twentrypoint ); [SuppressMessage("Microsoft.Interoperability", "CA1400:PInvokeEntryPointsShouldExist")] [DllImport("/usr/local/lib/libtwaindsm.so", EntryPoint = "DSM_Entry", CharSet = CharSet.Ansi)] internal static extern UInt16 LinuxDsmEntryEntrypoint ( ref TWAIN.TW_IDENTITY_LEGACY origin, ref TWAIN.TW_IDENTITY_LEGACY dest, TWAIN.DG dg, TWAIN.DAT dat, TWAIN.MSG msg, ref TWAIN.TW_ENTRYPOINT twentrypoint ); [SuppressMessage("Microsoft.Interoperability", "CA1400:PInvokeEntryPointsShouldExist")] [DllImport("/usr/local/lib64/libtwaindsm.so", EntryPoint = "DSM_Entry", CharSet = CharSet.Ansi)] internal static extern UInt16 Linux64DsmEntryEntrypoint ( ref TWAIN.TW_IDENTITY_LEGACY origin, ref TWAIN.TW_IDENTITY_LEGACY dest, TWAIN.DG dg, TWAIN.DAT dat, TWAIN.MSG msg, ref TWAIN.TW_ENTRYPOINT twentrypoint ); [SuppressMessage("Microsoft.Interoperability", "CA1400:PInvokeEntryPointsShouldExist")] [DllImport("/usr/local/lib/libtwaindsm.so.2.3.2", EntryPoint = "DSM_Entry", CharSet = CharSet.Ansi)] internal static extern UInt16 Linux020302Dsm64bitEntryEntrypoint ( ref TWAIN.TW_IDENTITY origin, ref TWAIN.TW_IDENTITY dest, TWAIN.DG dg, TWAIN.DAT dat, TWAIN.MSG msg, ref TWAIN.TW_ENTRYPOINT_LINUX64 twentrypoint ); [SuppressMessage("Microsoft.Interoperability", "CA1400:PInvokeEntryPointsShouldExist")] [DllImport("/System/Library/Frameworks/TWAIN.framework/TWAIN", EntryPoint = "DSM_Entry", CharSet = CharSet.Ansi)] internal static extern UInt16 MacosxTwainDsmEntryEntrypoint ( ref TWAIN.TW_IDENTITY_MACOSX origin, ref TWAIN.TW_IDENTITY_MACOSX dest, TWAIN.DG dg, TWAIN.DAT dat, TWAIN.MSG msg, ref TWAIN.TW_ENTRYPOINT twentrypoint ); [SuppressMessage("Microsoft.Interoperability", "CA1400:PInvokeEntryPointsShouldExist")] [DllImport("/Library/Frameworks/TWAINDSM.framework/TWAINDSM", EntryPoint = "DSM_Entry", CharSet = CharSet.Ansi)] internal static extern UInt16 MacosxTwaindsmDsmEntryEntrypoint ( ref TWAIN.TW_IDENTITY_MACOSX origin, ref TWAIN.TW_IDENTITY_MACOSX dest, TWAIN.DG dg, TWAIN.DAT dat, TWAIN.MSG msg, ref TWAIN.TW_ENTRYPOINT twentrypoint ); /// /// Use this for DG_CONTROL / DAT.FILESYSTEM / MSG.* calls... /// /// /// /// /// /// /// /// [SuppressMessage("Microsoft.Interoperability", "CA1400:PInvokeEntryPointsShouldExist")] [DllImport("twain_32.dll", EntryPoint = "DSM_Entry", CharSet = CharSet.Ansi)] internal static extern UInt16 WindowsTwain32DsmEntryFilesystem ( ref TWAIN.TW_IDENTITY_LEGACY origin, ref TWAIN.TW_IDENTITY_LEGACY dest, TWAIN.DG dg, TWAIN.DAT dat, TWAIN.MSG msg, ref TWAIN.TW_FILESYSTEM twfilesystem ); [SuppressMessage("Microsoft.Interoperability", "CA1400:PInvokeEntryPointsShouldExist")] [DllImport("twaindsm.dll", EntryPoint = "DSM_Entry", CharSet = CharSet.Ansi)] internal static extern UInt16 WindowsTwaindsmDsmEntryFilesystem ( ref TWAIN.TW_IDENTITY_LEGACY origin, ref TWAIN.TW_IDENTITY_LEGACY dest, TWAIN.DG dg, TWAIN.DAT dat, TWAIN.MSG msg, ref TWAIN.TW_FILESYSTEM twfilesystem ); [SuppressMessage("Microsoft.Interoperability", "CA1400:PInvokeEntryPointsShouldExist")] [DllImport("/usr/local/lib/libtwaindsm.so", EntryPoint = "DSM_Entry", CharSet = CharSet.Ansi)] internal static extern UInt16 LinuxDsmEntryFilesystem ( ref TWAIN.TW_IDENTITY_LEGACY origin, ref TWAIN.TW_IDENTITY_LEGACY dest, TWAIN.DG dg, TWAIN.DAT dat, TWAIN.MSG msg, ref TWAIN.TW_FILESYSTEM twfilesystem ); [SuppressMessage("Microsoft.Interoperability", "CA1400:PInvokeEntryPointsShouldExist")] [DllImport("/usr/local/lib64/libtwaindsm.so", EntryPoint = "DSM_Entry", CharSet = CharSet.Ansi)] internal static extern UInt16 Linux64DsmEntryFilesystem ( ref TWAIN.TW_IDENTITY_LEGACY origin, ref TWAIN.TW_IDENTITY_LEGACY dest, TWAIN.DG dg, TWAIN.DAT dat, TWAIN.MSG msg, ref TWAIN.TW_FILESYSTEM twfilesystem ); [SuppressMessage("Microsoft.Interoperability", "CA1400:PInvokeEntryPointsShouldExist")] [DllImport("/usr/local/lib/libtwaindsm.so.2.3.2", EntryPoint = "DSM_Entry", CharSet = CharSet.Ansi)] internal static extern UInt16 Linux020302Dsm64bitEntryFilesystem ( ref TWAIN.TW_IDENTITY origin, ref TWAIN.TW_IDENTITY dest, TWAIN.DG dg, TWAIN.DAT dat, TWAIN.MSG msg, ref TWAIN.TW_FILESYSTEM twfilesystem ); [SuppressMessage("Microsoft.Interoperability", "CA1400:PInvokeEntryPointsShouldExist")] [DllImport("/System/Library/Frameworks/TWAIN.framework/TWAIN", EntryPoint = "DSM_Entry", CharSet = CharSet.Ansi)] internal static extern UInt16 MacosxTwainDsmEntryFilesystem ( ref TWAIN.TW_IDENTITY_MACOSX origin, ref TWAIN.TW_IDENTITY_MACOSX dest, TWAIN.DG dg, TWAIN.DAT dat, TWAIN.MSG msg, ref TWAIN.TW_FILESYSTEM twfilesystem ); [SuppressMessage("Microsoft.Interoperability", "CA1400:PInvokeEntryPointsShouldExist")] [DllImport("/Library/Frameworks/TWAINDSM.framework/TWAINDSM", EntryPoint = "DSM_Entry", CharSet = CharSet.Ansi)] internal static extern UInt16 MacosxTwaindsmDsmEntryFilesystem ( ref TWAIN.TW_IDENTITY_MACOSX origin, ref TWAIN.TW_IDENTITY_MACOSX dest, TWAIN.DG dg, TWAIN.DAT dat, TWAIN.MSG msg, ref TWAIN.TW_FILESYSTEM twfilesystem ); /// /// Use this for DG_CONTROL / DAT.IDENTITY / MSG.* calls... /// /// /// /// /// /// /// /// [SuppressMessage("Microsoft.Interoperability", "CA1400:PInvokeEntryPointsShouldExist")] [DllImport("twain_32.dll", EntryPoint = "DSM_Entry", CharSet = CharSet.Ansi)] internal static extern UInt16 WindowsTwain32DsmEntryIdentity ( ref TWAIN.TW_IDENTITY_LEGACY origin, IntPtr dest, TWAIN.DG dg, TWAIN.DAT dat, TWAIN.MSG msg, ref TWAIN.TW_IDENTITY_LEGACY twidentity ); [SuppressMessage("Microsoft.Interoperability", "CA1400:PInvokeEntryPointsShouldExist")] [DllImport("twain_32.dll", EntryPoint = "DSM_Entry", CharSet = CharSet.Ansi)] internal static extern UInt16 WindowsTwain32DsmEntryIdentityState4 ( ref TWAIN.TW_IDENTITY_LEGACY origin, ref TWAIN.TW_IDENTITY_LEGACY dest, TWAIN.DG dg, TWAIN.DAT dat, TWAIN.MSG msg, ref TWAIN.TW_IDENTITY_LEGACY twidentity ); [SuppressMessage("Microsoft.Interoperability", "CA1400:PInvokeEntryPointsShouldExist")] [DllImport("twaindsm.dll", EntryPoint = "DSM_Entry", CharSet = CharSet.Ansi)] internal static extern UInt16 WindowsTwaindsmDsmEntryIdentity ( ref TWAIN.TW_IDENTITY_LEGACY origin, IntPtr dest, TWAIN.DG dg, TWAIN.DAT dat, TWAIN.MSG msg, ref TWAIN.TW_IDENTITY_LEGACY twidentity ); [SuppressMessage("Microsoft.Interoperability", "CA1400:PInvokeEntryPointsShouldExist")] [DllImport("/usr/local/lib/libtwaindsm.so", EntryPoint = "DSM_Entry", CharSet = CharSet.Ansi)] internal static extern UInt16 LinuxDsmEntryIdentity ( ref TWAIN.TW_IDENTITY_LEGACY origin, IntPtr dest, TWAIN.DG dg, TWAIN.DAT dat, TWAIN.MSG msg, ref TWAIN.TW_IDENTITY_LEGACY twidentity ); [SuppressMessage("Microsoft.Interoperability", "CA1400:PInvokeEntryPointsShouldExist")] [DllImport("/usr/local/lib64/libtwaindsm.so", EntryPoint = "DSM_Entry", CharSet = CharSet.Ansi)] internal static extern UInt16 Linux64DsmEntryIdentity ( ref TWAIN.TW_IDENTITY_LEGACY origin, IntPtr dest, TWAIN.DG dg, TWAIN.DAT dat, TWAIN.MSG msg, ref TWAIN.TW_IDENTITY_LEGACY twidentity ); [SuppressMessage("Microsoft.Interoperability", "CA1400:PInvokeEntryPointsShouldExist")] [DllImport("/usr/local/lib/libtwaindsm.so.2.3.2", EntryPoint = "DSM_Entry", CharSet = CharSet.Ansi)] internal static extern UInt16 Linux020302Dsm64bitEntryIdentity ( ref TWAIN.TW_IDENTITY_LINUX64 origin, IntPtr dest, TWAIN.DG dg, TWAIN.DAT dat, TWAIN.MSG msg, ref TWAIN.TW_IDENTITY_LINUX64 twidentity ); [SuppressMessage("Microsoft.Interoperability", "CA1400:PInvokeEntryPointsShouldExist")] [DllImport("/System/Library/Frameworks/TWAIN.framework/TWAIN", EntryPoint = "DSM_Entry", CharSet = CharSet.Ansi)] internal static extern UInt16 MacosxTwainDsmEntryIdentity ( ref TWAIN.TW_IDENTITY_MACOSX origin, IntPtr dest, TWAIN.DG dg, TWAIN.DAT dat, TWAIN.MSG msg, ref TWAIN.TW_IDENTITY_MACOSX twidentity ); [SuppressMessage("Microsoft.Interoperability", "CA1400:PInvokeEntryPointsShouldExist")] [DllImport("/Library/Frameworks/TWAINDSM.framework/TWAINDSM", EntryPoint = "DSM_Entry", CharSet = CharSet.Ansi)] internal static extern UInt16 MacosxTwaindsmDsmEntryIdentity ( ref TWAIN.TW_IDENTITY_MACOSX origin, IntPtr dest, TWAIN.DG dg, TWAIN.DAT dat, TWAIN.MSG msg, ref TWAIN.TW_IDENTITY_MACOSX twidentity ); /// /// Use this for DG_CONTROL / DAT.NULL / MSG.* calls... /// /// /// /// /// /// /// /// /// ***Only needed for drivers, so we don't have it*** /// /// Use this for DG_CONTROL / DAT.PARENT / MSG.* calls... /// /// /// /// /// /// /// /// [SuppressMessage("Microsoft.Interoperability", "CA1400:PInvokeEntryPointsShouldExist")] [DllImport("twain_32.dll", EntryPoint = "DSM_Entry", CharSet = CharSet.Ansi)] internal static extern UInt16 WindowsTwain32DsmEntryParent ( ref TWAIN.TW_IDENTITY_LEGACY origin, IntPtr dest, TWAIN.DG dg, TWAIN.DAT dat, TWAIN.MSG msg, ref IntPtr hwnd ); [SuppressMessage("Microsoft.Interoperability", "CA1400:PInvokeEntryPointsShouldExist")] [DllImport("twaindsm.dll", EntryPoint = "DSM_Entry", CharSet = CharSet.Ansi)] internal static extern UInt16 WindowsTwaindsmDsmEntryParent ( ref TWAIN.TW_IDENTITY_LEGACY origin, IntPtr dest, TWAIN.DG dg, TWAIN.DAT dat, TWAIN.MSG msg, ref IntPtr hwnd ); [SuppressMessage("Microsoft.Interoperability", "CA1400:PInvokeEntryPointsShouldExist")] [DllImport("/usr/local/lib/libtwaindsm.so", EntryPoint = "DSM_Entry", CharSet = CharSet.Ansi)] internal static extern UInt16 LinuxDsmEntryParent ( ref TWAIN.TW_IDENTITY_LEGACY origin, IntPtr dest, TWAIN.DG dg, TWAIN.DAT dat, TWAIN.MSG msg, ref IntPtr hwnd ); [SuppressMessage("Microsoft.Interoperability", "CA1400:PInvokeEntryPointsShouldExist")] [DllImport("/usr/local/lib64/libtwaindsm.so", EntryPoint = "DSM_Entry", CharSet = CharSet.Ansi)] internal static extern UInt16 Linux64DsmEntryParent ( ref TWAIN.TW_IDENTITY_LEGACY origin, IntPtr dest, TWAIN.DG dg, TWAIN.DAT dat, TWAIN.MSG msg, ref IntPtr hwnd ); [SuppressMessage("Microsoft.Interoperability", "CA1400:PInvokeEntryPointsShouldExist")] [DllImport("/usr/local/lib/libtwaindsm.so.2.3.2", EntryPoint = "DSM_Entry", CharSet = CharSet.Ansi)] internal static extern UInt16 Linux020302Dsm64bitEntryParent ( ref TWAIN.TW_IDENTITY origin, IntPtr dest, TWAIN.DG dg, TWAIN.DAT dat, TWAIN.MSG msg, ref IntPtr hwnd ); [SuppressMessage("Microsoft.Interoperability", "CA1400:PInvokeEntryPointsShouldExist")] [DllImport("/System/Library/Frameworks/TWAIN.framework/TWAIN", EntryPoint = "DSM_Entry", CharSet = CharSet.Ansi)] internal static extern UInt16 MacosxTwainDsmEntryParent ( ref TWAIN.TW_IDENTITY_MACOSX origin, IntPtr dest, TWAIN.DG dg, TWAIN.DAT dat, TWAIN.MSG msg, ref IntPtr hwnd ); [SuppressMessage("Microsoft.Interoperability", "CA1400:PInvokeEntryPointsShouldExist")] [DllImport("/Library/Frameworks/TWAINDSM.framework/TWAINDSM", EntryPoint = "DSM_Entry", CharSet = CharSet.Ansi)] internal static extern UInt16 MacosxTwaindsmDsmEntryParent ( ref TWAIN.TW_IDENTITY_MACOSX origin, IntPtr dest, TWAIN.DG dg, TWAIN.DAT dat, TWAIN.MSG msg, ref IntPtr hwnd ); /// /// Use this for DG_CONTROL / DAT.PASSTHRU / MSG.* calls... /// /// /// /// /// /// /// /// [SuppressMessage("Microsoft.Interoperability", "CA1400:PInvokeEntryPointsShouldExist")] [DllImport("twain_32.dll", EntryPoint = "DSM_Entry", CharSet = CharSet.Ansi)] internal static extern UInt16 WindowsTwain32DsmEntryPassthru ( ref TWAIN.TW_IDENTITY_LEGACY origin, ref TWAIN.TW_IDENTITY_LEGACY dest, TWAIN.DG dg, TWAIN.DAT dat, TWAIN.MSG msg, ref TWAIN.TW_PASSTHRU twpassthru ); [SuppressMessage("Microsoft.Interoperability", "CA1400:PInvokeEntryPointsShouldExist")] [DllImport("twaindsm.dll", EntryPoint = "DSM_Entry", CharSet = CharSet.Ansi)] internal static extern UInt16 WindowsTwaindsmDsmEntryPassthru ( ref TWAIN.TW_IDENTITY_LEGACY origin, ref TWAIN.TW_IDENTITY_LEGACY dest, TWAIN.DG dg, TWAIN.DAT dat, TWAIN.MSG msg, ref TWAIN.TW_PASSTHRU twpassthru ); [SuppressMessage("Microsoft.Interoperability", "CA1400:PInvokeEntryPointsShouldExist")] [DllImport("/usr/local/lib/libtwaindsm.so", EntryPoint = "DSM_Entry", CharSet = CharSet.Ansi)] internal static extern UInt16 LinuxDsmEntryPassthru ( ref TWAIN.TW_IDENTITY_LEGACY origin, ref TWAIN.TW_IDENTITY_LEGACY dest, TWAIN.DG dg, TWAIN.DAT dat, TWAIN.MSG msg, ref TWAIN.TW_PASSTHRU twpassthru ); [SuppressMessage("Microsoft.Interoperability", "CA1400:PInvokeEntryPointsShouldExist")] [DllImport("/usr/local/lib64/libtwaindsm.so", EntryPoint = "DSM_Entry", CharSet = CharSet.Ansi)] internal static extern UInt16 Linux64DsmEntryPassthru ( ref TWAIN.TW_IDENTITY_LEGACY origin, ref TWAIN.TW_IDENTITY_LEGACY dest, TWAIN.DG dg, TWAIN.DAT dat, TWAIN.MSG msg, ref TWAIN.TW_PASSTHRU twpassthru ); [SuppressMessage("Microsoft.Interoperability", "CA1400:PInvokeEntryPointsShouldExist")] [DllImport("/usr/local/lib/libtwaindsm.so.2.3.2", EntryPoint = "DSM_Entry", CharSet = CharSet.Ansi)] internal static extern UInt16 Linux020302Dsm64bitEntryPassthru ( ref TWAIN.TW_IDENTITY origin, ref TWAIN.TW_IDENTITY dest, TWAIN.DG dg, TWAIN.DAT dat, TWAIN.MSG msg, ref TWAIN.TW_PASSTHRU twpassthru ); [SuppressMessage("Microsoft.Interoperability", "CA1400:PInvokeEntryPointsShouldExist")] [DllImport("/System/Library/Frameworks/TWAIN.framework/TWAIN", EntryPoint = "DSM_Entry", CharSet = CharSet.Ansi)] internal static extern UInt16 MacosxTwainDsmEntryPassthru ( ref TWAIN.TW_IDENTITY_MACOSX origin, ref TWAIN.TW_IDENTITY_MACOSX dest, TWAIN.DG dg, TWAIN.DAT dat, TWAIN.MSG msg, ref TWAIN.TW_PASSTHRU twpassthru ); [SuppressMessage("Microsoft.Interoperability", "CA1400:PInvokeEntryPointsShouldExist")] [DllImport("/Library/Frameworks/TWAINDSM.framework/TWAINDSM", EntryPoint = "DSM_Entry", CharSet = CharSet.Ansi)] internal static extern UInt16 MacosxTwaindsmDsmEntryPassthru ( ref TWAIN.TW_IDENTITY_MACOSX origin, ref TWAIN.TW_IDENTITY_MACOSX dest, TWAIN.DG dg, TWAIN.DAT dat, TWAIN.MSG msg, ref TWAIN.TW_PASSTHRU twpassthru ); /// /// Use this for DG_CONTROL / DAT.PENDINGXFERS / MSG.* calls... /// /// /// /// /// /// /// /// [SuppressMessage("Microsoft.Interoperability", "CA1400:PInvokeEntryPointsShouldExist")] [DllImport("twain_32.dll", EntryPoint = "DSM_Entry", CharSet = CharSet.Ansi)] internal static extern UInt16 WindowsTwain32DsmEntryPendingxfers ( ref TWAIN.TW_IDENTITY_LEGACY origin, ref TWAIN.TW_IDENTITY_LEGACY dest, TWAIN.DG dg, TWAIN.DAT dat, TWAIN.MSG msg, ref TWAIN.TW_PENDINGXFERS twpendingxfers ); [SuppressMessage("Microsoft.Interoperability", "CA1400:PInvokeEntryPointsShouldExist")] [DllImport("twaindsm.dll", EntryPoint = "DSM_Entry", CharSet = CharSet.Ansi)] internal static extern UInt16 WindowsTwaindsmDsmEntryPendingxfers ( ref TWAIN.TW_IDENTITY_LEGACY origin, ref TWAIN.TW_IDENTITY_LEGACY dest, TWAIN.DG dg, TWAIN.DAT dat, TWAIN.MSG msg, ref TWAIN.TW_PENDINGXFERS twpendingxfers ); [SuppressMessage("Microsoft.Interoperability", "CA1400:PInvokeEntryPointsShouldExist")] [DllImport("/usr/local/lib/libtwaindsm.so", EntryPoint = "DSM_Entry", CharSet = CharSet.Ansi)] internal static extern UInt16 LinuxDsmEntryPendingxfers ( ref TWAIN.TW_IDENTITY_LEGACY origin, ref TWAIN.TW_IDENTITY_LEGACY dest, TWAIN.DG dg, TWAIN.DAT dat, TWAIN.MSG msg, ref TWAIN.TW_PENDINGXFERS twpendingxfers ); [SuppressMessage("Microsoft.Interoperability", "CA1400:PInvokeEntryPointsShouldExist")] [DllImport("/usr/local/lib64/libtwaindsm.so", EntryPoint = "DSM_Entry", CharSet = CharSet.Ansi)] internal static extern UInt16 Linux64DsmEntryPendingxfers ( ref TWAIN.TW_IDENTITY_LEGACY origin, ref TWAIN.TW_IDENTITY_LEGACY dest, TWAIN.DG dg, TWAIN.DAT dat, TWAIN.MSG msg, ref TWAIN.TW_PENDINGXFERS twpendingxfers ); [SuppressMessage("Microsoft.Interoperability", "CA1400:PInvokeEntryPointsShouldExist")] [DllImport("/usr/local/lib/libtwaindsm.so.2.3.2", EntryPoint = "DSM_Entry", CharSet = CharSet.Ansi)] internal static extern UInt16 Linux020302Dsm64bitEntryPendingxfers ( ref TWAIN.TW_IDENTITY origin, ref TWAIN.TW_IDENTITY dest, TWAIN.DG dg, TWAIN.DAT dat, TWAIN.MSG msg, ref TWAIN.TW_PENDINGXFERS twpendingxfers ); [SuppressMessage("Microsoft.Interoperability", "CA1400:PInvokeEntryPointsShouldExist")] [DllImport("/System/Library/Frameworks/TWAIN.framework/TWAIN", EntryPoint = "DSM_Entry", CharSet = CharSet.Ansi)] internal static extern UInt16 MacosxTwainDsmEntryPendingxfers ( ref TWAIN.TW_IDENTITY_MACOSX origin, ref TWAIN.TW_IDENTITY_MACOSX dest, TWAIN.DG dg, TWAIN.DAT dat, TWAIN.MSG msg, ref TWAIN.TW_PENDINGXFERS twpendingxfers ); [SuppressMessage("Microsoft.Interoperability", "CA1400:PInvokeEntryPointsShouldExist")] [DllImport("/Library/Frameworks/TWAINDSM.framework/TWAINDSM", EntryPoint = "DSM_Entry", CharSet = CharSet.Ansi)] internal static extern UInt16 MacosxTwaindsmDsmEntryPendingxfers ( ref TWAIN.TW_IDENTITY_MACOSX origin, ref TWAIN.TW_IDENTITY_MACOSX dest, TWAIN.DG dg, TWAIN.DAT dat, TWAIN.MSG msg, ref TWAIN.TW_PENDINGXFERS twpendingxfers ); /// /// Use this for DG_IMAGE / DAT.SETUPFILEXFER / MSG.* calls... /// /// /// /// /// /// /// /// [SuppressMessage("Microsoft.Interoperability", "CA1400:PInvokeEntryPointsShouldExist")] [DllImport("twain_32.dll", EntryPoint = "DSM_Entry", CharSet = CharSet.Ansi)] internal static extern UInt16 WindowsTwain32DsmEntrySetupfilexfer ( ref TWAIN.TW_IDENTITY_LEGACY origin, ref TWAIN.TW_IDENTITY_LEGACY dest, TWAIN.DG dg, TWAIN.DAT dat, TWAIN.MSG msg, ref TWAIN.TW_SETUPFILEXFER twsetupfilexfer ); [SuppressMessage("Microsoft.Interoperability", "CA1400:PInvokeEntryPointsShouldExist")] [DllImport("twaindsm.dll", EntryPoint = "DSM_Entry", CharSet = CharSet.Ansi)] internal static extern UInt16 WindowsTwaindsmDsmEntrySetupfilexfer ( ref TWAIN.TW_IDENTITY_LEGACY origin, ref TWAIN.TW_IDENTITY_LEGACY dest, TWAIN.DG dg, TWAIN.DAT dat, TWAIN.MSG msg, ref TWAIN.TW_SETUPFILEXFER twsetupfilexfer ); [SuppressMessage("Microsoft.Interoperability", "CA1400:PInvokeEntryPointsShouldExist")] [DllImport("/usr/local/lib/libtwaindsm.so", EntryPoint = "DSM_Entry", CharSet = CharSet.Ansi)] internal static extern UInt16 LinuxDsmEntrySetupfilexfer ( ref TWAIN.TW_IDENTITY_LEGACY origin, ref TWAIN.TW_IDENTITY_LEGACY dest, TWAIN.DG dg, TWAIN.DAT dat, TWAIN.MSG msg, ref TWAIN.TW_SETUPFILEXFER twsetupfilexfer ); [SuppressMessage("Microsoft.Interoperability", "CA1400:PInvokeEntryPointsShouldExist")] [DllImport("/usr/local/lib64/libtwaindsm.so", EntryPoint = "DSM_Entry", CharSet = CharSet.Ansi)] internal static extern UInt16 Linux64DsmEntrySetupfilexfer ( ref TWAIN.TW_IDENTITY_LEGACY origin, ref TWAIN.TW_IDENTITY_LEGACY dest, TWAIN.DG dg, TWAIN.DAT dat, TWAIN.MSG msg, ref TWAIN.TW_SETUPFILEXFER twsetupfilexfer ); [SuppressMessage("Microsoft.Interoperability", "CA1400:PInvokeEntryPointsShouldExist")] [DllImport("/usr/local/lib/libtwaindsm.so.2.3.2", EntryPoint = "DSM_Entry", CharSet = CharSet.Ansi)] internal static extern UInt16 Linux020302Dsm64bitEntrySetupfilexfer ( ref TWAIN.TW_IDENTITY origin, ref TWAIN.TW_IDENTITY dest, TWAIN.DG dg, TWAIN.DAT dat, TWAIN.MSG msg, ref TWAIN.TW_SETUPFILEXFER twsetupfilexfer ); [SuppressMessage("Microsoft.Interoperability", "CA1400:PInvokeEntryPointsShouldExist")] [DllImport("/System/Library/Frameworks/TWAIN.framework/TWAIN", EntryPoint = "DSM_Entry", CharSet = CharSet.Ansi)] internal static extern UInt16 MacosxTwainDsmEntrySetupfilexfer ( ref TWAIN.TW_IDENTITY_MACOSX origin, ref TWAIN.TW_IDENTITY_MACOSX dest, TWAIN.DG dg, TWAIN.DAT dat, TWAIN.MSG msg, ref TWAIN.TW_SETUPFILEXFER twsetupfilexfer ); [SuppressMessage("Microsoft.Interoperability", "CA1400:PInvokeEntryPointsShouldExist")] [DllImport("/Library/Frameworks/TWAINDSM.framework/TWAINDSM", EntryPoint = "DSM_Entry", CharSet = CharSet.Ansi)] internal static extern UInt16 MacosxTwaindsmDsmEntrySetupfilexfer ( ref TWAIN.TW_IDENTITY_MACOSX origin, ref TWAIN.TW_IDENTITY_MACOSX dest, TWAIN.DG dg, TWAIN.DAT dat, TWAIN.MSG msg, ref TWAIN.TW_SETUPFILEXFER twsetupfilexfer ); /// /// Use this for DG_IMAGE / DAT.SETUPMEMXFER / MSG.* calls... /// /// /// /// /// /// /// /// [SuppressMessage("Microsoft.Interoperability", "CA1400:PInvokeEntryPointsShouldExist")] [DllImport("twain_32.dll", EntryPoint = "DSM_Entry", CharSet = CharSet.Ansi)] internal static extern UInt16 WindowsTwain32DsmEntrySetupmemxfer ( ref TWAIN.TW_IDENTITY_LEGACY origin, ref TWAIN.TW_IDENTITY_LEGACY dest, TWAIN.DG dg, TWAIN.DAT dat, TWAIN.MSG msg, ref TWAIN.TW_SETUPMEMXFER twsetupmemxfer ); [SuppressMessage("Microsoft.Interoperability", "CA1400:PInvokeEntryPointsShouldExist")] [DllImport("twaindsm.dll", EntryPoint = "DSM_Entry", CharSet = CharSet.Ansi)] internal static extern UInt16 WindowsTwaindsmDsmEntrySetupmemxfer ( ref TWAIN.TW_IDENTITY_LEGACY origin, ref TWAIN.TW_IDENTITY_LEGACY dest, TWAIN.DG dg, TWAIN.DAT dat, TWAIN.MSG msg, ref TWAIN.TW_SETUPMEMXFER twsetupmemxfer ); [SuppressMessage("Microsoft.Interoperability", "CA1400:PInvokeEntryPointsShouldExist")] [DllImport("/usr/local/lib/libtwaindsm.so", EntryPoint = "DSM_Entry", CharSet = CharSet.Ansi)] internal static extern UInt16 LinuxDsmEntrySetupmemxfer ( ref TWAIN.TW_IDENTITY_LEGACY origin, ref TWAIN.TW_IDENTITY_LEGACY dest, TWAIN.DG dg, TWAIN.DAT dat, TWAIN.MSG msg, ref TWAIN.TW_SETUPMEMXFER twsetupmemxfer ); [SuppressMessage("Microsoft.Interoperability", "CA1400:PInvokeEntryPointsShouldExist")] [DllImport("/usr/local/lib64/libtwaindsm.so", EntryPoint = "DSM_Entry", CharSet = CharSet.Ansi)] internal static extern UInt16 Linux64DsmEntrySetupmemxfer ( ref TWAIN.TW_IDENTITY_LEGACY origin, ref TWAIN.TW_IDENTITY_LEGACY dest, TWAIN.DG dg, TWAIN.DAT dat, TWAIN.MSG msg, ref TWAIN.TW_SETUPMEMXFER twsetupmemxfer ); [SuppressMessage("Microsoft.Interoperability", "CA1400:PInvokeEntryPointsShouldExist")] [DllImport("/usr/local/lib/libtwaindsm.so.2.3.2", EntryPoint = "DSM_Entry", CharSet = CharSet.Ansi)] internal static extern UInt16 Linux020302Dsm64bitEntrySetupmemxfer ( ref TWAIN.TW_IDENTITY origin, ref TWAIN.TW_IDENTITY dest, TWAIN.DG dg, TWAIN.DAT dat, TWAIN.MSG msg, ref TWAIN.TW_SETUPMEMXFER twsetupmemxfer ); [SuppressMessage("Microsoft.Interoperability", "CA1400:PInvokeEntryPointsShouldExist")] [DllImport("/System/Library/Frameworks/TWAIN.framework/TWAIN", EntryPoint = "DSM_Entry", CharSet = CharSet.Ansi)] internal static extern UInt16 MacosxTwainDsmEntrySetupmemxfer ( ref TWAIN.TW_IDENTITY_MACOSX origin, ref TWAIN.TW_IDENTITY_MACOSX dest, TWAIN.DG dg, TWAIN.DAT dat, TWAIN.MSG msg, ref TWAIN.TW_SETUPMEMXFER twsetupmemxfer ); [SuppressMessage("Microsoft.Interoperability", "CA1400:PInvokeEntryPointsShouldExist")] [DllImport("/Library/Frameworks/TWAINDSM.framework/TWAINDSM", EntryPoint = "DSM_Entry", CharSet = CharSet.Ansi)] internal static extern UInt16 MacosxTwaindsmDsmEntrySetupmemxfer ( ref TWAIN.TW_IDENTITY_MACOSX origin, ref TWAIN.TW_IDENTITY_MACOSX dest, TWAIN.DG dg, TWAIN.DAT dat, TWAIN.MSG msg, ref TWAIN.TW_SETUPMEMXFER twsetupmemxfer ); /// /// Use this for DG_CONTROL / DAT.STATUS / MSG.* calls... /// /// /// /// /// /// /// /// [SuppressMessage("Microsoft.Interoperability", "CA1400:PInvokeEntryPointsShouldExist")] [DllImport("twain_32.dll", EntryPoint = "DSM_Entry", CharSet = CharSet.Ansi)] internal static extern UInt16 WindowsTwain32DsmEntryStatus ( ref TWAIN.TW_IDENTITY_LEGACY origin, ref TWAIN.TW_IDENTITY_LEGACY dest, TWAIN.DG dg, TWAIN.DAT dat, TWAIN.MSG msg, ref TWAIN.TW_STATUS twstatus ); [SuppressMessage("Microsoft.Interoperability", "CA1400:PInvokeEntryPointsShouldExist")] [DllImport("twain_32.dll", EntryPoint = "DSM_Entry", CharSet = CharSet.Ansi)] internal static extern UInt16 WindowsTwain32DsmEntryStatusState3 ( ref TWAIN.TW_IDENTITY_LEGACY origin, IntPtr dest, TWAIN.DG dg, TWAIN.DAT dat, TWAIN.MSG msg, ref TWAIN.TW_STATUS twstatus ); [SuppressMessage("Microsoft.Interoperability", "CA1400:PInvokeEntryPointsShouldExist")] [DllImport("twaindsm.dll", EntryPoint = "DSM_Entry", CharSet = CharSet.Ansi)] internal static extern UInt16 WindowsTwaindsmDsmEntryStatus ( ref TWAIN.TW_IDENTITY_LEGACY origin, ref TWAIN.TW_IDENTITY_LEGACY dest, TWAIN.DG dg, TWAIN.DAT dat, TWAIN.MSG msg, ref TWAIN.TW_STATUS twstatus ); [SuppressMessage("Microsoft.Interoperability", "CA1400:PInvokeEntryPointsShouldExist")] [DllImport("twaindsm.dll", EntryPoint = "DSM_Entry", CharSet = CharSet.Ansi)] internal static extern UInt16 WindowsTwaindsmDsmEntryStatusState3 ( ref TWAIN.TW_IDENTITY_LEGACY origin, IntPtr dest, TWAIN.DG dg, TWAIN.DAT dat, TWAIN.MSG msg, ref TWAIN.TW_STATUS twstatus ); [SuppressMessage("Microsoft.Interoperability", "CA1400:PInvokeEntryPointsShouldExist")] [DllImport("/usr/local/lib/libtwaindsm.so", EntryPoint = "DSM_Entry", CharSet = CharSet.Ansi)] internal static extern UInt16 LinuxDsmEntryStatus ( ref TWAIN.TW_IDENTITY_LEGACY origin, ref TWAIN.TW_IDENTITY_LEGACY dest, TWAIN.DG dg, TWAIN.DAT dat, TWAIN.MSG msg, ref TWAIN.TW_STATUS twstatus ); [SuppressMessage("Microsoft.Interoperability", "CA1400:PInvokeEntryPointsShouldExist")] [DllImport("/usr/local/lib/libtwaindsm.so", EntryPoint = "DSM_Entry", CharSet = CharSet.Ansi)] internal static extern UInt16 LinuxDsmEntryStatusState3 ( ref TWAIN.TW_IDENTITY_LEGACY origin, IntPtr dest, TWAIN.DG dg, TWAIN.DAT dat, TWAIN.MSG msg, ref TWAIN.TW_STATUS twstatus ); [SuppressMessage("Microsoft.Interoperability", "CA1400:PInvokeEntryPointsShouldExist")] [DllImport("/usr/local/lib64/libtwaindsm.so", EntryPoint = "DSM_Entry", CharSet = CharSet.Ansi)] internal static extern UInt16 Linux64DsmEntryStatus ( ref TWAIN.TW_IDENTITY_LEGACY origin, ref TWAIN.TW_IDENTITY_LEGACY dest, TWAIN.DG dg, TWAIN.DAT dat, TWAIN.MSG msg, ref TWAIN.TW_STATUS twstatus ); [SuppressMessage("Microsoft.Interoperability", "CA1400:PInvokeEntryPointsShouldExist")] [DllImport("/usr/local/lib64/libtwaindsm.so", EntryPoint = "DSM_Entry", CharSet = CharSet.Ansi)] internal static extern UInt16 Linux64DsmEntryStatusState3 ( ref TWAIN.TW_IDENTITY_LEGACY origin, IntPtr dest, TWAIN.DG dg, TWAIN.DAT dat, TWAIN.MSG msg, ref TWAIN.TW_STATUS twstatus ); [SuppressMessage("Microsoft.Interoperability", "CA1400:PInvokeEntryPointsShouldExist")] [DllImport("/usr/local/lib/libtwaindsm.so.2.3.2", EntryPoint = "DSM_Entry", CharSet = CharSet.Ansi)] internal static extern UInt16 Linux020302Dsm64bitEntryStatus ( ref TWAIN.TW_IDENTITY origin, ref TWAIN.TW_IDENTITY dest, TWAIN.DG dg, TWAIN.DAT dat, TWAIN.MSG msg, ref TWAIN.TW_STATUS twstatus ); [SuppressMessage("Microsoft.Interoperability", "CA1400:PInvokeEntryPointsShouldExist")] [DllImport("/usr/local/lib/libtwaindsm.so.2.3.2", EntryPoint = "DSM_Entry", CharSet = CharSet.Ansi)] internal static extern UInt16 Linux020302Dsm64bitEntryStatusState3 ( ref TWAIN.TW_IDENTITY origin, IntPtr dest, TWAIN.DG dg, TWAIN.DAT dat, TWAIN.MSG msg, ref TWAIN.TW_STATUS twstatus ); [SuppressMessage("Microsoft.Interoperability", "CA1400:PInvokeEntryPointsShouldExist")] [DllImport("/System/Library/Frameworks/TWAIN.framework/TWAIN", EntryPoint = "DSM_Entry", CharSet = CharSet.Ansi)] internal static extern UInt16 MacosxTwainDsmEntryStatus ( ref TWAIN.TW_IDENTITY_MACOSX origin, ref TWAIN.TW_IDENTITY_MACOSX dest, TWAIN.DG dg, TWAIN.DAT dat, TWAIN.MSG msg, ref TWAIN.TW_STATUS twstatus ); [SuppressMessage("Microsoft.Interoperability", "CA1400:PInvokeEntryPointsShouldExist")] [DllImport("/System/Library/Frameworks/TWAIN.framework/TWAIN", EntryPoint = "DSM_Entry", CharSet = CharSet.Ansi)] internal static extern UInt16 MacosxTwainDsmEntryStatusState3 ( ref TWAIN.TW_IDENTITY_MACOSX origin, IntPtr dest, TWAIN.DG dg, TWAIN.DAT dat, TWAIN.MSG msg, ref TWAIN.TW_STATUS twstatus ); [SuppressMessage("Microsoft.Interoperability", "CA1400:PInvokeEntryPointsShouldExist")] [DllImport("/Library/Frameworks/TWAINDSM.framework/TWAINDSM", EntryPoint = "DSM_Entry", CharSet = CharSet.Ansi)] internal static extern UInt16 MacosxTwaindsmDsmEntryStatus ( ref TWAIN.TW_IDENTITY_MACOSX origin, ref TWAIN.TW_IDENTITY_MACOSX dest, TWAIN.DG dg, TWAIN.DAT dat, TWAIN.MSG msg, ref TWAIN.TW_STATUS twstatus ); [SuppressMessage("Microsoft.Interoperability", "CA1400:PInvokeEntryPointsShouldExist")] [DllImport("/Library/Frameworks/TWAINDSM.framework/TWAINDSM", EntryPoint = "DSM_Entry", CharSet = CharSet.Ansi)] internal static extern UInt16 MacosxTwaindsmDsmEntryStatusState3 ( ref TWAIN.TW_IDENTITY_MACOSX origin, IntPtr dest, TWAIN.DG dg, TWAIN.DAT dat, TWAIN.MSG msg, ref TWAIN.TW_STATUS twstatus ); /// /// Use this for DG_CONTROL / DAT.STATUSUTF8 / MSG.* calls... /// /// /// /// /// /// /// /// [SuppressMessage("Microsoft.Interoperability", "CA1400:PInvokeEntryPointsShouldExist")] [DllImport("twain_32.dll", EntryPoint = "DSM_Entry", CharSet = CharSet.Ansi)] internal static extern UInt16 WindowsTwain32DsmEntryStatusutf8 ( ref TWAIN.TW_IDENTITY_LEGACY origin, ref TWAIN.TW_IDENTITY_LEGACY dest, TWAIN.DG dg, TWAIN.DAT dat, TWAIN.MSG msg, ref TWAIN.TW_STATUSUTF8 twstatusutf8 ); [SuppressMessage("Microsoft.Interoperability", "CA1400:PInvokeEntryPointsShouldExist")] [DllImport("twaindsm.dll", EntryPoint = "DSM_Entry", CharSet = CharSet.Ansi)] internal static extern UInt16 WindowsTwaindsmDsmEntryStatusutf8 ( ref TWAIN.TW_IDENTITY_LEGACY origin, ref TWAIN.TW_IDENTITY_LEGACY dest, TWAIN.DG dg, TWAIN.DAT dat, TWAIN.MSG msg, ref TWAIN.TW_STATUSUTF8 twstatusutf8 ); [SuppressMessage("Microsoft.Interoperability", "CA1400:PInvokeEntryPointsShouldExist")] [DllImport("/usr/local/lib/libtwaindsm.so", EntryPoint = "DSM_Entry", CharSet = CharSet.Ansi)] internal static extern UInt16 LinuxDsmEntryStatusutf8 ( ref TWAIN.TW_IDENTITY_LEGACY origin, ref TWAIN.TW_IDENTITY_LEGACY dest, TWAIN.DG dg, TWAIN.DAT dat, TWAIN.MSG msg, ref TWAIN.TW_STATUSUTF8 twstatusutf8 ); [SuppressMessage("Microsoft.Interoperability", "CA1400:PInvokeEntryPointsShouldExist")] [DllImport("/usr/local/lib64/libtwaindsm.so", EntryPoint = "DSM_Entry", CharSet = CharSet.Ansi)] internal static extern UInt16 Linux64DsmEntryStatusutf8 ( ref TWAIN.TW_IDENTITY_LEGACY origin, ref TWAIN.TW_IDENTITY_LEGACY dest, TWAIN.DG dg, TWAIN.DAT dat, TWAIN.MSG msg, ref TWAIN.TW_STATUSUTF8 twstatusutf8 ); [SuppressMessage("Microsoft.Interoperability", "CA1400:PInvokeEntryPointsShouldExist")] [DllImport("/usr/local/lib/libtwaindsm.so.2.3.2", EntryPoint = "DSM_Entry", CharSet = CharSet.Ansi)] internal static extern UInt16 Linux020302Dsm64bitEntryStatusutf8 ( ref TWAIN.TW_IDENTITY origin, ref TWAIN.TW_IDENTITY dest, TWAIN.DG dg, TWAIN.DAT dat, TWAIN.MSG msg, ref TWAIN.TW_STATUSUTF8 twstatusutf8 ); [SuppressMessage("Microsoft.Interoperability", "CA1400:PInvokeEntryPointsShouldExist")] [DllImport("/System/Library/Frameworks/TWAIN.framework/TWAIN", EntryPoint = "DSM_Entry", CharSet = CharSet.Ansi)] internal static extern UInt16 MacosxTwainDsmEntryStatusutf8 ( ref TWAIN.TW_IDENTITY_MACOSX origin, ref TWAIN.TW_IDENTITY_MACOSX dest, TWAIN.DG dg, TWAIN.DAT dat, TWAIN.MSG msg, ref TWAIN.TW_STATUSUTF8 twstatusutf8 ); [SuppressMessage("Microsoft.Interoperability", "CA1400:PInvokeEntryPointsShouldExist")] [DllImport("/Library/Frameworks/TWAINDSM.framework/TWAINDSM", EntryPoint = "DSM_Entry", CharSet = CharSet.Ansi)] internal static extern UInt16 MacosxTwaindsmDsmEntryStatusutf8 ( ref TWAIN.TW_IDENTITY_MACOSX origin, ref TWAIN.TW_IDENTITY_MACOSX dest, TWAIN.DG dg, TWAIN.DAT dat, TWAIN.MSG msg, ref TWAIN.TW_STATUSUTF8 twstatusutf8 ); /// /// Use this for DG.CONTROL / DAT.TWAINDIRECT / MSG.* calls... /// /// /// /// /// /// /// /// [SuppressMessage("Microsoft.Interoperability", "CA1400:PInvokeEntryPointsShouldExist")] [DllImport("twain_32.dll", EntryPoint = "DSM_Entry", CharSet = CharSet.Ansi)] internal static extern UInt16 WindowsTwain32DsmEntryTwaindirect ( ref TWAIN.TW_IDENTITY_LEGACY origin, ref TWAIN.TW_IDENTITY_LEGACY dest, TWAIN.DG dg, TWAIN.DAT dat, TWAIN.MSG msg, ref TWAIN.TW_TWAINDIRECT twtwaindirect ); [SuppressMessage("Microsoft.Interoperability", "CA1400:PInvokeEntryPointsShouldExist")] [DllImport("twaindsm.dll", EntryPoint = "DSM_Entry", CharSet = CharSet.Ansi)] internal static extern UInt16 WindowsTwaindsmDsmEntryTwaindirect ( ref TWAIN.TW_IDENTITY_LEGACY origin, ref TWAIN.TW_IDENTITY_LEGACY dest, TWAIN.DG dg, TWAIN.DAT dat, TWAIN.MSG msg, ref TWAIN.TW_TWAINDIRECT twtwaindirect ); [SuppressMessage("Microsoft.Interoperability", "CA1400:PInvokeEntryPointsShouldExist")] [DllImport("/usr/local/lib/libtwaindsm.so", EntryPoint = "DSM_Entry", CharSet = CharSet.Ansi)] internal static extern UInt16 LinuxDsmEntryTwaindirect ( ref TWAIN.TW_IDENTITY_LEGACY origin, ref TWAIN.TW_IDENTITY_LEGACY dest, TWAIN.DG dg, TWAIN.DAT dat, TWAIN.MSG msg, ref TWAIN.TW_TWAINDIRECT twtwaindirect ); [SuppressMessage("Microsoft.Interoperability", "CA1400:PInvokeEntryPointsShouldExist")] [DllImport("/usr/local/lib64/libtwaindsm.so", EntryPoint = "DSM_Entry", CharSet = CharSet.Ansi)] internal static extern UInt16 Linux64DsmEntryTwaindirect ( ref TWAIN.TW_IDENTITY_LEGACY origin, ref TWAIN.TW_IDENTITY_LEGACY dest, TWAIN.DG dg, TWAIN.DAT dat, TWAIN.MSG msg, ref TWAIN.TW_TWAINDIRECT twtwaindirect ); [SuppressMessage("Microsoft.Interoperability", "CA1400:PInvokeEntryPointsShouldExist")] [DllImport("/usr/local/lib/libtwaindsm.so.2.3.2", EntryPoint = "DSM_Entry", CharSet = CharSet.Ansi)] internal static extern UInt16 Linux020302Dsm64bitEntryTwaindirect ( ref TWAIN.TW_IDENTITY origin, ref TWAIN.TW_IDENTITY dest, TWAIN.DG dg, TWAIN.DAT dat, TWAIN.MSG msg, ref TWAIN.TW_TWAINDIRECT twtwaindirect ); [SuppressMessage("Microsoft.Interoperability", "CA1400:PInvokeEntryPointsShouldExist")] [DllImport("/System/Library/Frameworks/TWAIN.framework/TWAIN", EntryPoint = "DSM_Entry", CharSet = CharSet.Ansi)] internal static extern UInt16 MacosxTwainDsmEntryTwaindirect ( ref TWAIN.TW_IDENTITY_MACOSX origin, ref TWAIN.TW_IDENTITY_MACOSX dest, TWAIN.DG dg, TWAIN.DAT dat, TWAIN.MSG msg, ref TWAIN.TW_TWAINDIRECT twtwaindirect ); [SuppressMessage("Microsoft.Interoperability", "CA1400:PInvokeEntryPointsShouldExist")] [DllImport("/Library/Frameworks/TWAINDSM.framework/TWAINDSM", EntryPoint = "DSM_Entry", CharSet = CharSet.Ansi)] internal static extern UInt16 MacosxTwaindsmDsmEntryTwaindirect ( ref TWAIN.TW_IDENTITY_MACOSX origin, ref TWAIN.TW_IDENTITY_MACOSX dest, TWAIN.DG dg, TWAIN.DAT dat, TWAIN.MSG msg, ref TWAIN.TW_TWAINDIRECT twtwaindirect ); /// /// Use this for DG_CONTROL / DAT.USERINTERFACE / MSG.* calls... /// /// /// /// /// /// /// /// [SuppressMessage("Microsoft.Interoperability", "CA1400:PInvokeEntryPointsShouldExist")] [DllImport("twain_32.dll", EntryPoint = "DSM_Entry", CharSet = CharSet.Ansi)] internal static extern UInt16 WindowsTwain32DsmEntryUserinterface ( ref TWAIN.TW_IDENTITY_LEGACY origin, ref TWAIN.TW_IDENTITY_LEGACY dest, TWAIN.DG dg, TWAIN.DAT dat, TWAIN.MSG msg, ref TWAIN.TW_USERINTERFACE twuserinterface ); [SuppressMessage("Microsoft.Interoperability", "CA1400:PInvokeEntryPointsShouldExist")] [DllImport("twaindsm.dll", EntryPoint = "DSM_Entry", CharSet = CharSet.Ansi)] internal static extern UInt16 WindowsTwaindsmDsmEntryUserinterface ( ref TWAIN.TW_IDENTITY_LEGACY origin, ref TWAIN.TW_IDENTITY_LEGACY dest, TWAIN.DG dg, TWAIN.DAT dat, TWAIN.MSG msg, ref TWAIN.TW_USERINTERFACE twuserinterface ); [SuppressMessage("Microsoft.Interoperability", "CA1400:PInvokeEntryPointsShouldExist")] [DllImport("/usr/local/lib/libtwaindsm.so", EntryPoint = "DSM_Entry", CharSet = CharSet.Ansi)] internal static extern UInt16 LinuxDsmEntryUserinterface ( ref TWAIN.TW_IDENTITY_LEGACY origin, ref TWAIN.TW_IDENTITY_LEGACY dest, TWAIN.DG dg, TWAIN.DAT dat, TWAIN.MSG msg, ref TWAIN.TW_USERINTERFACE twuserinterface ); [SuppressMessage("Microsoft.Interoperability", "CA1400:PInvokeEntryPointsShouldExist")] [DllImport("/usr/local/lib64/libtwaindsm.so", EntryPoint = "DSM_Entry", CharSet = CharSet.Ansi)] internal static extern UInt16 Linux64DsmEntryUserinterface ( ref TWAIN.TW_IDENTITY_LEGACY origin, ref TWAIN.TW_IDENTITY_LEGACY dest, TWAIN.DG dg, TWAIN.DAT dat, TWAIN.MSG msg, ref TWAIN.TW_USERINTERFACE twuserinterface ); [SuppressMessage("Microsoft.Interoperability", "CA1400:PInvokeEntryPointsShouldExist")] [DllImport("/usr/local/lib/libtwaindsm.so.2.3.2", EntryPoint = "DSM_Entry", CharSet = CharSet.Ansi)] internal static extern UInt16 Linux020302Dsm64bitEntryUserinterface ( ref TWAIN.TW_IDENTITY origin, ref TWAIN.TW_IDENTITY dest, TWAIN.DG dg, TWAIN.DAT dat, TWAIN.MSG msg, ref TWAIN.TW_USERINTERFACE twuserinterface ); [SuppressMessage("Microsoft.Interoperability", "CA1400:PInvokeEntryPointsShouldExist")] [DllImport("/System/Library/Frameworks/TWAIN.framework/TWAIN", EntryPoint = "DSM_Entry", CharSet = CharSet.Ansi)] internal static extern UInt16 MacosxTwainDsmEntryUserinterface ( ref TWAIN.TW_IDENTITY_MACOSX origin, ref TWAIN.TW_IDENTITY_MACOSX dest, TWAIN.DG dg, TWAIN.DAT dat, TWAIN.MSG msg, ref TWAIN.TW_USERINTERFACE twuserinterface ); [SuppressMessage("Microsoft.Interoperability", "CA1400:PInvokeEntryPointsShouldExist")] [DllImport("/Library/Frameworks/TWAINDSM.framework/TWAINDSM", EntryPoint = "DSM_Entry", CharSet = CharSet.Ansi)] internal static extern UInt16 MacosxTwaindsmDsmEntryUserinterface ( ref TWAIN.TW_IDENTITY_MACOSX origin, ref TWAIN.TW_IDENTITY_MACOSX dest, TWAIN.DG dg, TWAIN.DAT dat, TWAIN.MSG msg, ref TWAIN.TW_USERINTERFACE twuserinterface ); /// /// Use this for DG_CONTROL / DAT.XFERGROUP / MSG.* calls... /// /// /// /// /// /// /// /// [SuppressMessage("Microsoft.Interoperability", "CA1400:PInvokeEntryPointsShouldExist")] [DllImport("twain_32.dll", EntryPoint = "DSM_Entry", CharSet = CharSet.Ansi)] internal static extern UInt16 WindowsTwain32DsmEntryXfergroup ( ref TWAIN.TW_IDENTITY_LEGACY origin, ref TWAIN.TW_IDENTITY_LEGACY dest, TWAIN.DG dg, TWAIN.DAT dat, TWAIN.MSG msg, ref UInt32 twuint32 ); [SuppressMessage("Microsoft.Interoperability", "CA1400:PInvokeEntryPointsShouldExist")] [DllImport("twaindsm.dll", EntryPoint = "DSM_Entry", CharSet = CharSet.Ansi)] internal static extern UInt16 WindowsTwaindsmDsmEntryXfergroup ( ref TWAIN.TW_IDENTITY_LEGACY origin, ref TWAIN.TW_IDENTITY_LEGACY dest, TWAIN.DG dg, TWAIN.DAT dat, TWAIN.MSG msg, ref UInt32 twuint32 ); [SuppressMessage("Microsoft.Interoperability", "CA1400:PInvokeEntryPointsShouldExist")] [DllImport("/usr/local/lib/libtwaindsm.so", EntryPoint = "DSM_Entry", CharSet = CharSet.Ansi)] internal static extern UInt16 LinuxDsmEntryXfergroup ( ref TWAIN.TW_IDENTITY_LEGACY origin, ref TWAIN.TW_IDENTITY_LEGACY dest, TWAIN.DG dg, TWAIN.DAT dat, TWAIN.MSG msg, ref UInt32 twuint32 ); [SuppressMessage("Microsoft.Interoperability", "CA1400:PInvokeEntryPointsShouldExist")] [DllImport("/usr/local/lib64/libtwaindsm.so", EntryPoint = "DSM_Entry", CharSet = CharSet.Ansi)] internal static extern UInt16 Linux64DsmEntryXfergroup ( ref TWAIN.TW_IDENTITY_LEGACY origin, ref TWAIN.TW_IDENTITY_LEGACY dest, TWAIN.DG dg, TWAIN.DAT dat, TWAIN.MSG msg, ref UInt32 twuint32 ); [SuppressMessage("Microsoft.Interoperability", "CA1400:PInvokeEntryPointsShouldExist")] [DllImport("/usr/local/lib/libtwaindsm.so.2.3.2", EntryPoint = "DSM_Entry", CharSet = CharSet.Ansi)] internal static extern UInt16 Linux020302Dsm64bitEntryXfergroup ( ref TWAIN.TW_IDENTITY origin, ref TWAIN.TW_IDENTITY dest, TWAIN.DG dg, TWAIN.DAT dat, TWAIN.MSG msg, ref UInt32 twuint32 ); [SuppressMessage("Microsoft.Interoperability", "CA1400:PInvokeEntryPointsShouldExist")] [DllImport("/System/Library/Frameworks/TWAIN.framework/TWAIN", EntryPoint = "DSM_Entry", CharSet = CharSet.Ansi)] internal static extern UInt16 MacosxTwainDsmEntryXfergroup ( ref TWAIN.TW_IDENTITY_MACOSX origin, ref TWAIN.TW_IDENTITY_MACOSX dest, TWAIN.DG dg, TWAIN.DAT dat, TWAIN.MSG msg, ref UInt32 twuint32 ); [SuppressMessage("Microsoft.Interoperability", "CA1400:PInvokeEntryPointsShouldExist")] [DllImport("/Library/Frameworks/TWAINDSM.framework/TWAINDSM", EntryPoint = "DSM_Entry", CharSet = CharSet.Ansi)] internal static extern UInt16 MacosxTwaindsmDsmEntryXfergroup ( ref TWAIN.TW_IDENTITY_MACOSX origin, ref TWAIN.TW_IDENTITY_MACOSX dest, TWAIN.DG dg, TWAIN.DAT dat, TWAIN.MSG msg, ref UInt32 twuint32 ); /// /// Use this for DG_AUDIO / DAT.AUDIOFILEXFER / MSG.* calls... /// /// /// /// /// /// /// /// [SuppressMessage("Microsoft.Interoperability", "CA1400:PInvokeEntryPointsShouldExist")] [DllImport("twain_32.dll", EntryPoint = "DSM_Entry", CharSet = CharSet.Ansi)] internal static extern UInt16 WindowsTwain32DsmEntryAudiofilexfer ( ref TWAIN.TW_IDENTITY_LEGACY origin, ref TWAIN.TW_IDENTITY_LEGACY dest, TWAIN.DG dg, TWAIN.DAT dat, TWAIN.MSG msg, IntPtr twmemref ); [SuppressMessage("Microsoft.Interoperability", "CA1400:PInvokeEntryPointsShouldExist")] [DllImport("twaindsm.dll", EntryPoint = "DSM_Entry", CharSet = CharSet.Ansi)] internal static extern UInt16 WindowsTwaindsmDsmEntryAudiofilexfer ( ref TWAIN.TW_IDENTITY_LEGACY origin, ref TWAIN.TW_IDENTITY_LEGACY dest, TWAIN.DG dg, TWAIN.DAT dat, TWAIN.MSG msg, IntPtr twmemref ); [SuppressMessage("Microsoft.Interoperability", "CA1400:PInvokeEntryPointsShouldExist")] [DllImport("/usr/local/lib/libtwaindsm.so", EntryPoint = "DSM_Entry", CharSet = CharSet.Ansi)] internal static extern UInt16 LinuxDsmEntryAudiofilexfer ( ref TWAIN.TW_IDENTITY_LEGACY origin, ref TWAIN.TW_IDENTITY_LEGACY dest, TWAIN.DG dg, TWAIN.DAT dat, TWAIN.MSG msg, IntPtr twmemref ); [SuppressMessage("Microsoft.Interoperability", "CA1400:PInvokeEntryPointsShouldExist")] [DllImport("/usr/local/lib64/libtwaindsm.so", EntryPoint = "DSM_Entry", CharSet = CharSet.Ansi)] internal static extern UInt16 Linux64DsmEntryAudiofilexfer ( ref TWAIN.TW_IDENTITY_LEGACY origin, ref TWAIN.TW_IDENTITY_LEGACY dest, TWAIN.DG dg, TWAIN.DAT dat, TWAIN.MSG msg, IntPtr twmemref ); [SuppressMessage("Microsoft.Interoperability", "CA1400:PInvokeEntryPointsShouldExist")] [DllImport("/usr/local/lib/libtwaindsm.so.2.3.2", EntryPoint = "DSM_Entry", CharSet = CharSet.Ansi)] internal static extern UInt16 Linux020302Dsm64bitEntryAudiofilexfer ( ref TWAIN.TW_IDENTITY origin, ref TWAIN.TW_IDENTITY dest, TWAIN.DG dg, TWAIN.DAT dat, TWAIN.MSG msg, IntPtr twmemref ); [SuppressMessage("Microsoft.Interoperability", "CA1400:PInvokeEntryPointsShouldExist")] [DllImport("/System/Library/Frameworks/TWAIN.framework/TWAIN", EntryPoint = "DSM_Entry", CharSet = CharSet.Ansi)] internal static extern UInt16 MacosxTwainDsmEntryAudiofilexfer ( ref TWAIN.TW_IDENTITY_MACOSX origin, ref TWAIN.TW_IDENTITY_MACOSX dest, TWAIN.DG dg, TWAIN.DAT dat, TWAIN.MSG msg, IntPtr twmemref ); [SuppressMessage("Microsoft.Interoperability", "CA1400:PInvokeEntryPointsShouldExist")] [DllImport("/Library/Frameworks/TWAINDSM.framework/TWAINDSM", EntryPoint = "DSM_Entry", CharSet = CharSet.Ansi)] internal static extern UInt16 MacosxTwaindsmDsmEntryAudiofilexfer ( ref TWAIN.TW_IDENTITY_MACOSX origin, ref TWAIN.TW_IDENTITY_MACOSX dest, TWAIN.DG dg, TWAIN.DAT dat, TWAIN.MSG msg, IntPtr twmemref ); /// /// Use this for DG_AUDIO / DAT.AUDIONATIVEXFER / MSG.* calls... /// /// /// /// /// /// /// /// [SuppressMessage("Microsoft.Interoperability", "CA1400:PInvokeEntryPointsShouldExist")] [DllImport("twain_32.dll", EntryPoint = "DSM_Entry", CharSet = CharSet.Ansi)] internal static extern UInt16 WindowsTwain32DsmEntryAudionativexfer ( ref TWAIN.TW_IDENTITY_LEGACY origin, ref TWAIN.TW_IDENTITY_LEGACY dest, TWAIN.DG dg, TWAIN.DAT dat, TWAIN.MSG msg, ref IntPtr intptrWav ); [SuppressMessage("Microsoft.Interoperability", "CA1400:PInvokeEntryPointsShouldExist")] [DllImport("twaindsm.dll", EntryPoint = "DSM_Entry", CharSet = CharSet.Ansi)] internal static extern UInt16 WindowsTwaindsmDsmEntryAudionativexfer ( ref TWAIN.TW_IDENTITY_LEGACY origin, ref TWAIN.TW_IDENTITY_LEGACY dest, TWAIN.DG dg, TWAIN.DAT dat, TWAIN.MSG msg, ref IntPtr intptrWav ); [SuppressMessage("Microsoft.Interoperability", "CA1400:PInvokeEntryPointsShouldExist")] [DllImport("/usr/local/lib/libtwaindsm.so", EntryPoint = "DSM_Entry", CharSet = CharSet.Ansi)] internal static extern UInt16 LinuxDsmEntryAudionativexfer ( ref TWAIN.TW_IDENTITY_LEGACY origin, ref TWAIN.TW_IDENTITY_LEGACY dest, TWAIN.DG dg, TWAIN.DAT dat, TWAIN.MSG msg, ref IntPtr intptrWav ); [SuppressMessage("Microsoft.Interoperability", "CA1400:PInvokeEntryPointsShouldExist")] [DllImport("/usr/local/lib64/libtwaindsm.so", EntryPoint = "DSM_Entry", CharSet = CharSet.Ansi)] internal static extern UInt16 Linux64DsmEntryAudionativexfer ( ref TWAIN.TW_IDENTITY_LEGACY origin, ref TWAIN.TW_IDENTITY_LEGACY dest, TWAIN.DG dg, TWAIN.DAT dat, TWAIN.MSG msg, ref IntPtr intptrWav ); [SuppressMessage("Microsoft.Interoperability", "CA1400:PInvokeEntryPointsShouldExist")] [DllImport("/usr/local/lib/libtwaindsm.so.2.3.2", EntryPoint = "DSM_Entry", CharSet = CharSet.Ansi)] internal static extern UInt16 Linux020302Dsm64bitEntryAudionativexfer ( ref TWAIN.TW_IDENTITY origin, ref TWAIN.TW_IDENTITY dest, TWAIN.DG dg, TWAIN.DAT dat, TWAIN.MSG msg, ref IntPtr intptrWav ); [SuppressMessage("Microsoft.Interoperability", "CA1400:PInvokeEntryPointsShouldExist")] [DllImport("/System/Library/Frameworks/TWAIN.framework/TWAIN", EntryPoint = "DSM_Entry", CharSet = CharSet.Ansi)] internal static extern UInt16 MacosxTwainDsmEntryAudionativexfer ( ref TWAIN.TW_IDENTITY_MACOSX origin, ref TWAIN.TW_IDENTITY_MACOSX dest, TWAIN.DG dg, TWAIN.DAT dat, TWAIN.MSG msg, ref IntPtr intptrAiff ); [SuppressMessage("Microsoft.Interoperability", "CA1400:PInvokeEntryPointsShouldExist")] [DllImport("/Library/Frameworks/TWAINDSM.framework/TWAINDSM", EntryPoint = "DSM_Entry", CharSet = CharSet.Ansi)] internal static extern UInt16 MacosxTwaindsmDsmEntryAudionativexfer ( ref TWAIN.TW_IDENTITY_MACOSX origin, ref TWAIN.TW_IDENTITY_MACOSX dest, TWAIN.DG dg, TWAIN.DAT dat, TWAIN.MSG msg, ref IntPtr intptrAiff ); /// /// Use this for DG_IMAGE / DAT.CIECOLOR / MSG.* calls... /// /// /// /// /// /// /// /// [SuppressMessage("Microsoft.Interoperability", "CA1400:PInvokeEntryPointsShouldExist")] [DllImport("twain_32.dll", EntryPoint = "DSM_Entry", CharSet = CharSet.Ansi)] internal static extern UInt16 WindowsTwain32DsmEntryCiecolor ( ref TWAIN.TW_IDENTITY_LEGACY origin, ref TWAIN.TW_IDENTITY_LEGACY dest, TWAIN.DG dg, TWAIN.DAT dat, TWAIN.MSG msg, ref TWAIN.TW_CIECOLOR twciecolor ); [SuppressMessage("Microsoft.Interoperability", "CA1400:PInvokeEntryPointsShouldExist")] [DllImport("twaindsm.dll", EntryPoint = "DSM_Entry", CharSet = CharSet.Ansi)] internal static extern UInt16 WindowsTwaindsmDsmEntryCiecolor ( ref TWAIN.TW_IDENTITY_LEGACY origin, ref TWAIN.TW_IDENTITY_LEGACY dest, TWAIN.DG dg, TWAIN.DAT dat, TWAIN.MSG msg, ref TWAIN.TW_CIECOLOR twciecolor ); [SuppressMessage("Microsoft.Interoperability", "CA1400:PInvokeEntryPointsShouldExist")] [DllImport("/usr/local/lib/libtwaindsm.so", EntryPoint = "DSM_Entry", CharSet = CharSet.Ansi)] internal static extern UInt16 LinuxDsmEntryCiecolor ( ref TWAIN.TW_IDENTITY_LEGACY origin, ref TWAIN.TW_IDENTITY_LEGACY dest, TWAIN.DG dg, TWAIN.DAT dat, TWAIN.MSG msg, ref TWAIN.TW_CIECOLOR twciecolor ); [SuppressMessage("Microsoft.Interoperability", "CA1400:PInvokeEntryPointsShouldExist")] [DllImport("/usr/local/lib64/libtwaindsm.so", EntryPoint = "DSM_Entry", CharSet = CharSet.Ansi)] internal static extern UInt16 Linux64DsmEntryCiecolor ( ref TWAIN.TW_IDENTITY_LEGACY origin, ref TWAIN.TW_IDENTITY_LEGACY dest, TWAIN.DG dg, TWAIN.DAT dat, TWAIN.MSG msg, ref TWAIN.TW_CIECOLOR twciecolor ); [SuppressMessage("Microsoft.Interoperability", "CA1400:PInvokeEntryPointsShouldExist")] [DllImport("/usr/local/lib/libtwaindsm.so.2.3.2", EntryPoint = "DSM_Entry", CharSet = CharSet.Ansi)] internal static extern UInt16 Linux020302Dsm64bitEntryCiecolor ( ref TWAIN.TW_IDENTITY origin, ref TWAIN.TW_IDENTITY dest, TWAIN.DG dg, TWAIN.DAT dat, TWAIN.MSG msg, ref TWAIN.TW_CIECOLOR twciecolor ); [SuppressMessage("Microsoft.Interoperability", "CA1400:PInvokeEntryPointsShouldExist")] [DllImport("/System/Library/Frameworks/TWAIN.framework/TWAIN", EntryPoint = "DSM_Entry", CharSet = CharSet.Ansi)] internal static extern UInt16 MacosxTwainDsmEntryCiecolor ( ref TWAIN.TW_IDENTITY_MACOSX origin, ref TWAIN.TW_IDENTITY_MACOSX dest, TWAIN.DG dg, TWAIN.DAT dat, TWAIN.MSG msg, ref TWAIN.TW_CIECOLOR twciecolor ); [SuppressMessage("Microsoft.Interoperability", "CA1400:PInvokeEntryPointsShouldExist")] [DllImport("/Library/Frameworks/TWAINDSM.framework/TWAINDSM", EntryPoint = "DSM_Entry", CharSet = CharSet.Ansi)] internal static extern UInt16 MacosxTwaindsmDsmEntryCiecolor ( ref TWAIN.TW_IDENTITY_MACOSX origin, ref TWAIN.TW_IDENTITY_MACOSX dest, TWAIN.DG dg, TWAIN.DAT dat, TWAIN.MSG msg, ref TWAIN.TW_CIECOLOR twciecolor ); /// /// Use this for DG_IMAGE / DAT.EXTIMAGEINFO / MSG.* calls... /// /// /// /// /// /// /// /// [SuppressMessage("Microsoft.Interoperability", "CA1400:PInvokeEntryPointsShouldExist")] [DllImport("twain_32.dll", EntryPoint = "DSM_Entry", CharSet = CharSet.Ansi)] internal static extern UInt16 WindowsTwain32DsmEntryExtimageinfo ( ref TWAIN.TW_IDENTITY_LEGACY origin, ref TWAIN.TW_IDENTITY_LEGACY dest, TWAIN.DG dg, TWAIN.DAT dat, TWAIN.MSG msg, ref TWAIN.TW_EXTIMAGEINFO twextimageinfo ); [SuppressMessage("Microsoft.Interoperability", "CA1400:PInvokeEntryPointsShouldExist")] [DllImport("twaindsm.dll", EntryPoint = "DSM_Entry", CharSet = CharSet.Ansi)] internal static extern UInt16 WindowsTwaindsmDsmEntryExtimageinfo ( ref TWAIN.TW_IDENTITY_LEGACY origin, ref TWAIN.TW_IDENTITY_LEGACY dest, TWAIN.DG dg, TWAIN.DAT dat, TWAIN.MSG msg, ref TWAIN.TW_EXTIMAGEINFO twextimageinfo ); [SuppressMessage("Microsoft.Interoperability", "CA1400:PInvokeEntryPointsShouldExist")] [DllImport("/usr/local/lib/libtwaindsm.so", EntryPoint = "DSM_Entry", CharSet = CharSet.Ansi)] internal static extern UInt16 LinuxDsmEntryExtimageinfo ( ref TWAIN.TW_IDENTITY_LEGACY origin, ref TWAIN.TW_IDENTITY_LEGACY dest, TWAIN.DG dg, TWAIN.DAT dat, TWAIN.MSG msg, ref TWAIN.TW_EXTIMAGEINFO twextimageinfo ); [SuppressMessage("Microsoft.Interoperability", "CA1400:PInvokeEntryPointsShouldExist")] [DllImport("/usr/local/lib64/libtwaindsm.so", EntryPoint = "DSM_Entry", CharSet = CharSet.Ansi)] internal static extern UInt16 Linux64DsmEntryExtimageinfo ( ref TWAIN.TW_IDENTITY_LEGACY origin, ref TWAIN.TW_IDENTITY_LEGACY dest, TWAIN.DG dg, TWAIN.DAT dat, TWAIN.MSG msg, ref TWAIN.TW_EXTIMAGEINFO twextimageinfo ); [SuppressMessage("Microsoft.Interoperability", "CA1400:PInvokeEntryPointsShouldExist")] [DllImport("/usr/local/lib/libtwaindsm.so.2.3.2", EntryPoint = "DSM_Entry", CharSet = CharSet.Ansi)] internal static extern UInt16 Linux020302Dsm64bitEntryExtimageinfo ( ref TWAIN.TW_IDENTITY origin, ref TWAIN.TW_IDENTITY dest, TWAIN.DG dg, TWAIN.DAT dat, TWAIN.MSG msg, ref TWAIN.TW_EXTIMAGEINFO twextimageinfo ); [SuppressMessage("Microsoft.Interoperability", "CA1400:PInvokeEntryPointsShouldExist")] [DllImport("/System/Library/Frameworks/TWAIN.framework/TWAIN", EntryPoint = "DSM_Entry", CharSet = CharSet.Ansi)] internal static extern UInt16 MacosxTwainDsmEntryExtimageinfo ( ref TWAIN.TW_IDENTITY_MACOSX origin, ref TWAIN.TW_IDENTITY_MACOSX dest, TWAIN.DG dg, TWAIN.DAT dat, TWAIN.MSG msg, ref TWAIN.TW_EXTIMAGEINFO twextimageinfo ); [SuppressMessage("Microsoft.Interoperability", "CA1400:PInvokeEntryPointsShouldExist")] [DllImport("/Library/Frameworks/TWAINDSM.framework/TWAINDSM", EntryPoint = "DSM_Entry", CharSet = CharSet.Ansi)] internal static extern UInt16 MacosxTwaindsmDsmEntryExtimageinfo ( ref TWAIN.TW_IDENTITY_MACOSX origin, ref TWAIN.TW_IDENTITY_MACOSX dest, TWAIN.DG dg, TWAIN.DAT dat, TWAIN.MSG msg, ref TWAIN.TW_EXTIMAGEINFO twextimageinfo ); /// /// Use this for DG_IMAGE / DAT.FILTER / MSG.* calls... /// /// /// /// /// /// /// /// [SuppressMessage("Microsoft.Interoperability", "CA1400:PInvokeEntryPointsShouldExist")] [DllImport("twain_32.dll", EntryPoint = "DSM_Entry", CharSet = CharSet.Ansi)] internal static extern UInt16 WindowsTwain32DsmEntryFilter ( ref TWAIN.TW_IDENTITY_LEGACY origin, ref TWAIN.TW_IDENTITY_LEGACY dest, TWAIN.DG dg, TWAIN.DAT dat, TWAIN.MSG msg, ref TWAIN.TW_FILTER twfilter ); [SuppressMessage("Microsoft.Interoperability", "CA1400:PInvokeEntryPointsShouldExist")] [DllImport("twaindsm.dll", EntryPoint = "DSM_Entry", CharSet = CharSet.Ansi)] internal static extern UInt16 WindowsTwaindsmDsmEntryFilter ( ref TWAIN.TW_IDENTITY_LEGACY origin, ref TWAIN.TW_IDENTITY_LEGACY dest, TWAIN.DG dg, TWAIN.DAT dat, TWAIN.MSG msg, ref TWAIN.TW_FILTER twfilter ); [SuppressMessage("Microsoft.Interoperability", "CA1400:PInvokeEntryPointsShouldExist")] [DllImport("/usr/local/lib/libtwaindsm.so", EntryPoint = "DSM_Entry", CharSet = CharSet.Ansi)] internal static extern UInt16 LinuxDsmEntryFilter ( ref TWAIN.TW_IDENTITY_LEGACY origin, ref TWAIN.TW_IDENTITY_LEGACY dest, TWAIN.DG dg, TWAIN.DAT dat, TWAIN.MSG msg, ref TWAIN.TW_FILTER twfilter ); [SuppressMessage("Microsoft.Interoperability", "CA1400:PInvokeEntryPointsShouldExist")] [DllImport("/usr/local/lib64/libtwaindsm.so", EntryPoint = "DSM_Entry", CharSet = CharSet.Ansi)] internal static extern UInt16 Linux64DsmEntryFilter ( ref TWAIN.TW_IDENTITY_LEGACY origin, ref TWAIN.TW_IDENTITY_LEGACY dest, TWAIN.DG dg, TWAIN.DAT dat, TWAIN.MSG msg, ref TWAIN.TW_FILTER twfilter ); [SuppressMessage("Microsoft.Interoperability", "CA1400:PInvokeEntryPointsShouldExist")] [DllImport("/usr/local/lib/libtwaindsm.so.2.3.2", EntryPoint = "DSM_Entry", CharSet = CharSet.Ansi)] internal static extern UInt16 Linux020302Dsm64bitEntryFilter ( ref TWAIN.TW_IDENTITY origin, ref TWAIN.TW_IDENTITY dest, TWAIN.DG dg, TWAIN.DAT dat, TWAIN.MSG msg, ref TWAIN.TW_FILTER twfilter ); [SuppressMessage("Microsoft.Interoperability", "CA1400:PInvokeEntryPointsShouldExist")] [DllImport("/System/Library/Frameworks/TWAIN.framework/TWAIN", EntryPoint = "DSM_Entry", CharSet = CharSet.Ansi)] internal static extern UInt16 MacosxTwainDsmEntryFilter ( ref TWAIN.TW_IDENTITY_MACOSX origin, ref TWAIN.TW_IDENTITY_MACOSX dest, TWAIN.DG dg, TWAIN.DAT dat, TWAIN.MSG msg, ref TWAIN.TW_FILTER twfilter ); [SuppressMessage("Microsoft.Interoperability", "CA1400:PInvokeEntryPointsShouldExist")] [DllImport("/Library/Frameworks/TWAINDSM.framework/TWAINDSM", EntryPoint = "DSM_Entry", CharSet = CharSet.Ansi)] internal static extern UInt16 MacosxTwaindsmDsmEntryFilter ( ref TWAIN.TW_IDENTITY_MACOSX origin, ref TWAIN.TW_IDENTITY_MACOSX dest, TWAIN.DG dg, TWAIN.DAT dat, TWAIN.MSG msg, ref TWAIN.TW_FILTER twfilter ); /// /// Use this for DG_IMAGE / DAT.GRAYRESPONSE / MSG.* calls... /// /// /// /// /// /// /// /// [SuppressMessage("Microsoft.Interoperability", "CA1400:PInvokeEntryPointsShouldExist")] [DllImport("twain_32.dll", EntryPoint = "DSM_Entry", CharSet = CharSet.Ansi)] internal static extern UInt16 WindowsTwain32DsmEntryGrayresponse ( ref TWAIN.TW_IDENTITY_LEGACY origin, ref TWAIN.TW_IDENTITY_LEGACY dest, TWAIN.DG dg, TWAIN.DAT dat, TWAIN.MSG msg, ref TWAIN.TW_GRAYRESPONSE twgrayresponse ); [SuppressMessage("Microsoft.Interoperability", "CA1400:PInvokeEntryPointsShouldExist")] [DllImport("twaindsm.dll", EntryPoint = "DSM_Entry", CharSet = CharSet.Ansi)] internal static extern UInt16 WindowsTwaindsmDsmEntryGrayresponse ( ref TWAIN.TW_IDENTITY_LEGACY origin, ref TWAIN.TW_IDENTITY_LEGACY dest, TWAIN.DG dg, TWAIN.DAT dat, TWAIN.MSG msg, ref TWAIN.TW_GRAYRESPONSE twgrayresponse ); [SuppressMessage("Microsoft.Interoperability", "CA1400:PInvokeEntryPointsShouldExist")] [DllImport("/usr/local/lib/libtwaindsm.so", EntryPoint = "DSM_Entry", CharSet = CharSet.Ansi)] internal static extern UInt16 LinuxDsmEntryGrayresponse ( ref TWAIN.TW_IDENTITY_LEGACY origin, ref TWAIN.TW_IDENTITY_LEGACY dest, TWAIN.DG dg, TWAIN.DAT dat, TWAIN.MSG msg, ref TWAIN.TW_GRAYRESPONSE twgrayresponse ); [SuppressMessage("Microsoft.Interoperability", "CA1400:PInvokeEntryPointsShouldExist")] [DllImport("/usr/local/lib64/libtwaindsm.so", EntryPoint = "DSM_Entry", CharSet = CharSet.Ansi)] internal static extern UInt16 Linux64DsmEntryGrayresponse ( ref TWAIN.TW_IDENTITY_LEGACY origin, ref TWAIN.TW_IDENTITY_LEGACY dest, TWAIN.DG dg, TWAIN.DAT dat, TWAIN.MSG msg, ref TWAIN.TW_GRAYRESPONSE twgrayresponse ); [SuppressMessage("Microsoft.Interoperability", "CA1400:PInvokeEntryPointsShouldExist")] [DllImport("/usr/local/lib/libtwaindsm.so.2.3.2", EntryPoint = "DSM_Entry", CharSet = CharSet.Ansi)] internal static extern UInt16 Linux020302Dsm64bitEntryGrayresponse ( ref TWAIN.TW_IDENTITY origin, ref TWAIN.TW_IDENTITY dest, TWAIN.DG dg, TWAIN.DAT dat, TWAIN.MSG msg, ref TWAIN.TW_GRAYRESPONSE twgrayresponse ); [SuppressMessage("Microsoft.Interoperability", "CA1400:PInvokeEntryPointsShouldExist")] [DllImport("/System/Library/Frameworks/TWAIN.framework/TWAIN", EntryPoint = "DSM_Entry", CharSet = CharSet.Ansi)] internal static extern UInt16 MacosxTwainDsmEntryGrayresponse ( ref TWAIN.TW_IDENTITY_MACOSX origin, ref TWAIN.TW_IDENTITY_MACOSX dest, TWAIN.DG dg, TWAIN.DAT dat, TWAIN.MSG msg, ref TWAIN.TW_GRAYRESPONSE twgrayresponse ); [SuppressMessage("Microsoft.Interoperability", "CA1400:PInvokeEntryPointsShouldExist")] [DllImport("/Library/Frameworks/TWAINDSM.framework/TWAINDSM", EntryPoint = "DSM_Entry", CharSet = CharSet.Ansi)] internal static extern UInt16 MacosxTwaindsmDsmEntryGrayresponse ( ref TWAIN.TW_IDENTITY_MACOSX origin, ref TWAIN.TW_IDENTITY_MACOSX dest, TWAIN.DG dg, TWAIN.DAT dat, TWAIN.MSG msg, ref TWAIN.TW_GRAYRESPONSE twgrayresponse ); /// /// Use this for DG_IMAGE / DAT.ICCPROFILE / MSG.* calls... /// /// /// /// /// /// /// /// [SuppressMessage("Microsoft.Interoperability", "CA1400:PInvokeEntryPointsShouldExist")] [DllImport("twain_32.dll", EntryPoint = "DSM_Entry", CharSet = CharSet.Ansi)] internal static extern UInt16 WindowsTwain32DsmEntryIccprofile ( ref TWAIN.TW_IDENTITY_LEGACY origin, ref TWAIN.TW_IDENTITY_LEGACY dest, TWAIN.DG dg, TWAIN.DAT dat, TWAIN.MSG msg, ref TWAIN.TW_MEMORY twmemory ); [SuppressMessage("Microsoft.Interoperability", "CA1400:PInvokeEntryPointsShouldExist")] [DllImport("twaindsm.dll", EntryPoint = "DSM_Entry", CharSet = CharSet.Ansi)] internal static extern UInt16 WindowsTwaindsmDsmEntryIccprofile ( ref TWAIN.TW_IDENTITY_LEGACY origin, ref TWAIN.TW_IDENTITY_LEGACY dest, TWAIN.DG dg, TWAIN.DAT dat, TWAIN.MSG msg, ref TWAIN.TW_MEMORY twmemory ); [SuppressMessage("Microsoft.Interoperability", "CA1400:PInvokeEntryPointsShouldExist")] [DllImport("/usr/local/lib/libtwaindsm.so", EntryPoint = "DSM_Entry", CharSet = CharSet.Ansi)] internal static extern UInt16 LinuxDsmEntryIccprofile ( ref TWAIN.TW_IDENTITY_LEGACY origin, ref TWAIN.TW_IDENTITY_LEGACY dest, TWAIN.DG dg, TWAIN.DAT dat, TWAIN.MSG msg, ref TWAIN.TW_MEMORY twmemory ); [SuppressMessage("Microsoft.Interoperability", "CA1400:PInvokeEntryPointsShouldExist")] [DllImport("/usr/local/lib64/libtwaindsm.so", EntryPoint = "DSM_Entry", CharSet = CharSet.Ansi)] internal static extern UInt16 Linux64DsmEntryIccprofile ( ref TWAIN.TW_IDENTITY_LEGACY origin, ref TWAIN.TW_IDENTITY_LEGACY dest, TWAIN.DG dg, TWAIN.DAT dat, TWAIN.MSG msg, ref TWAIN.TW_MEMORY twmemory ); [SuppressMessage("Microsoft.Interoperability", "CA1400:PInvokeEntryPointsShouldExist")] [DllImport("/usr/local/lib/libtwaindsm.so.2.3.2", EntryPoint = "DSM_Entry", CharSet = CharSet.Ansi)] internal static extern UInt16 Linux020302Dsm64bitEntryIccprofile ( ref TWAIN.TW_IDENTITY origin, ref TWAIN.TW_IDENTITY dest, TWAIN.DG dg, TWAIN.DAT dat, TWAIN.MSG msg, ref TWAIN.TW_MEMORY twmemory ); [SuppressMessage("Microsoft.Interoperability", "CA1400:PInvokeEntryPointsShouldExist")] [DllImport("/System/Library/Frameworks/TWAIN.framework/TWAIN", EntryPoint = "DSM_Entry", CharSet = CharSet.Ansi)] internal static extern UInt16 MacosxTwainDsmEntryIccprofile ( ref TWAIN.TW_IDENTITY_MACOSX origin, ref TWAIN.TW_IDENTITY_MACOSX dest, TWAIN.DG dg, TWAIN.DAT dat, TWAIN.MSG msg, ref TWAIN.TW_MEMORY twmemory ); [SuppressMessage("Microsoft.Interoperability", "CA1400:PInvokeEntryPointsShouldExist")] [DllImport("/Library/Frameworks/TWAINDSM.framework/TWAINDSM", EntryPoint = "DSM_Entry", CharSet = CharSet.Ansi)] internal static extern UInt16 MacosxTwaindsmDsmEntryIccprofile ( ref TWAIN.TW_IDENTITY_MACOSX origin, ref TWAIN.TW_IDENTITY_MACOSX dest, TWAIN.DG dg, TWAIN.DAT dat, TWAIN.MSG msg, ref TWAIN.TW_MEMORY twmemory ); /// /// Use this for DG_IMAGE / DAT.IMAGEFILEXFER / MSG.* calls... /// /// /// /// /// /// /// /// [SuppressMessage("Microsoft.Interoperability", "CA1400:PInvokeEntryPointsShouldExist")] [DllImport("twain_32.dll", EntryPoint = "DSM_Entry", CharSet = CharSet.Ansi)] internal static extern UInt16 WindowsTwain32DsmEntryImagefilexfer ( ref TWAIN.TW_IDENTITY_LEGACY origin, ref TWAIN.TW_IDENTITY_LEGACY dest, TWAIN.DG dg, TWAIN.DAT dat, TWAIN.MSG msg, IntPtr twmemref ); [SuppressMessage("Microsoft.Interoperability", "CA1400:PInvokeEntryPointsShouldExist")] [DllImport("twaindsm.dll", EntryPoint = "DSM_Entry", CharSet = CharSet.Ansi)] internal static extern UInt16 WindowsTwaindsmDsmEntryImagefilexfer ( ref TWAIN.TW_IDENTITY_LEGACY origin, ref TWAIN.TW_IDENTITY_LEGACY dest, TWAIN.DG dg, TWAIN.DAT dat, TWAIN.MSG msg, IntPtr twmemref ); [SuppressMessage("Microsoft.Interoperability", "CA1400:PInvokeEntryPointsShouldExist")] [DllImport("/usr/local/lib/libtwaindsm.so", EntryPoint = "DSM_Entry", CharSet = CharSet.Ansi)] internal static extern UInt16 LinuxDsmEntryImagefilexfer ( ref TWAIN.TW_IDENTITY_LEGACY origin, ref TWAIN.TW_IDENTITY_LEGACY dest, TWAIN.DG dg, TWAIN.DAT dat, TWAIN.MSG msg, IntPtr twmemref ); [SuppressMessage("Microsoft.Interoperability", "CA1400:PInvokeEntryPointsShouldExist")] [DllImport("/usr/local/lib64/libtwaindsm.so", EntryPoint = "DSM_Entry", CharSet = CharSet.Ansi)] internal static extern UInt16 Linux64DsmEntryImagefilexfer ( ref TWAIN.TW_IDENTITY_LEGACY origin, ref TWAIN.TW_IDENTITY_LEGACY dest, TWAIN.DG dg, TWAIN.DAT dat, TWAIN.MSG msg, IntPtr twmemref ); [SuppressMessage("Microsoft.Interoperability", "CA1400:PInvokeEntryPointsShouldExist")] [DllImport("/usr/local/lib/libtwaindsm.so.2.3.2", EntryPoint = "DSM_Entry", CharSet = CharSet.Ansi)] internal static extern UInt16 Linux020302Dsm64bitEntryImagefilexfer ( ref TWAIN.TW_IDENTITY origin, ref TWAIN.TW_IDENTITY dest, TWAIN.DG dg, TWAIN.DAT dat, TWAIN.MSG msg, IntPtr twmemref ); [SuppressMessage("Microsoft.Interoperability", "CA1400:PInvokeEntryPointsShouldExist")] [DllImport("/System/Library/Frameworks/TWAIN.framework/TWAIN", EntryPoint = "DSM_Entry", CharSet = CharSet.Ansi)] internal static extern UInt16 MacosxTwainDsmEntryImagefilexfer ( ref TWAIN.TW_IDENTITY_MACOSX origin, ref TWAIN.TW_IDENTITY_MACOSX dest, TWAIN.DG dg, TWAIN.DAT dat, TWAIN.MSG msg, IntPtr twmemref ); [SuppressMessage("Microsoft.Interoperability", "CA1400:PInvokeEntryPointsShouldExist")] [DllImport("/Library/Frameworks/TWAINDSM.framework/TWAINDSM", EntryPoint = "DSM_Entry", CharSet = CharSet.Ansi)] internal static extern UInt16 MacosxTwaindsmDsmEntryImagefilexfer ( ref TWAIN.TW_IDENTITY_MACOSX origin, ref TWAIN.TW_IDENTITY_MACOSX dest, TWAIN.DG dg, TWAIN.DAT dat, TWAIN.MSG msg, IntPtr twmemref ); /// /// Use this for DG_IMAGE / DAT.IMAGEINFO / MSG.* calls... /// /// /// /// /// /// /// /// [SuppressMessage("Microsoft.Interoperability", "CA1400:PInvokeEntryPointsShouldExist")] [DllImport("twain_32.dll", EntryPoint = "DSM_Entry", CharSet = CharSet.Ansi)] internal static extern UInt16 WindowsTwain32DsmEntryImageinfo ( ref TWAIN.TW_IDENTITY_LEGACY origin, ref TWAIN.TW_IDENTITY_LEGACY dest, TWAIN.DG dg, TWAIN.DAT dat, TWAIN.MSG msg, ref TWAIN.TW_IMAGEINFO twimageinfo ); [SuppressMessage("Microsoft.Interoperability", "CA1400:PInvokeEntryPointsShouldExist")] [DllImport("twaindsm.dll", EntryPoint = "DSM_Entry", CharSet = CharSet.Ansi)] internal static extern UInt16 WindowsTwaindsmDsmEntryImageinfo ( ref TWAIN.TW_IDENTITY_LEGACY origin, ref TWAIN.TW_IDENTITY_LEGACY dest, TWAIN.DG dg, TWAIN.DAT dat, TWAIN.MSG msg, ref TWAIN.TW_IMAGEINFO twimageinfo ); [SuppressMessage("Microsoft.Interoperability", "CA1400:PInvokeEntryPointsShouldExist")] [DllImport("/usr/local/lib/libtwaindsm.so", EntryPoint = "DSM_Entry", CharSet = CharSet.Ansi)] internal static extern UInt16 LinuxDsmEntryImageinfo ( ref TWAIN.TW_IDENTITY_LEGACY origin, ref TWAIN.TW_IDENTITY_LEGACY dest, TWAIN.DG dg, TWAIN.DAT dat, TWAIN.MSG msg, ref TWAIN.TW_IMAGEINFO twimageinfo ); [SuppressMessage("Microsoft.Interoperability", "CA1400:PInvokeEntryPointsShouldExist")] [DllImport("/usr/local/lib64/libtwaindsm.so", EntryPoint = "DSM_Entry", CharSet = CharSet.Ansi)] internal static extern UInt16 Linux64DsmEntryImageinfo ( ref TWAIN.TW_IDENTITY_LEGACY origin, ref TWAIN.TW_IDENTITY_LEGACY dest, TWAIN.DG dg, TWAIN.DAT dat, TWAIN.MSG msg, ref TWAIN.TW_IMAGEINFO twimageinfo ); [SuppressMessage("Microsoft.Interoperability", "CA1400:PInvokeEntryPointsShouldExist")] [DllImport("/usr/local/lib/libtwaindsm.so.2.3.2", EntryPoint = "DSM_Entry", CharSet = CharSet.Ansi)] internal static extern UInt16 Linux020302Dsm64bitEntryImageinfo ( ref TWAIN.TW_IDENTITY origin, ref TWAIN.TW_IDENTITY dest, TWAIN.DG dg, TWAIN.DAT dat, TWAIN.MSG msg, ref TWAIN.TW_IMAGEINFO_LINUX64 twimageinfolinux64 ); [SuppressMessage("Microsoft.Interoperability", "CA1400:PInvokeEntryPointsShouldExist")] [DllImport("/System/Library/Frameworks/TWAIN.framework/TWAIN", EntryPoint = "DSM_Entry", CharSet = CharSet.Ansi)] internal static extern UInt16 MacosxTwainDsmEntryImageinfo ( ref TWAIN.TW_IDENTITY_MACOSX origin, ref TWAIN.TW_IDENTITY_MACOSX dest, TWAIN.DG dg, TWAIN.DAT dat, TWAIN.MSG msg, ref TWAIN.TW_IMAGEINFO twimageinfo ); [SuppressMessage("Microsoft.Interoperability", "CA1400:PInvokeEntryPointsShouldExist")] [DllImport("/Library/Frameworks/TWAINDSM.framework/TWAINDSM", EntryPoint = "DSM_Entry", CharSet = CharSet.Ansi)] internal static extern UInt16 MacosxTwaindsmDsmEntryImageinfo ( ref TWAIN.TW_IDENTITY_MACOSX origin, ref TWAIN.TW_IDENTITY_MACOSX dest, TWAIN.DG dg, TWAIN.DAT dat, TWAIN.MSG msg, ref TWAIN.TW_IMAGEINFO twimageinfo ); /// /// Use this for DG_IMAGE / DAT.IMAGELAYOUT / MSG.* calls... /// /// /// /// /// /// /// /// [SuppressMessage("Microsoft.Interoperability", "CA1400:PInvokeEntryPointsShouldExist")] [DllImport("twain_32.dll", EntryPoint = "DSM_Entry", CharSet = CharSet.Ansi)] internal static extern UInt16 WindowsTwain32DsmEntryImagelayout ( ref TWAIN.TW_IDENTITY_LEGACY origin, ref TWAIN.TW_IDENTITY_LEGACY dest, TWAIN.DG dg, TWAIN.DAT dat, TWAIN.MSG msg, ref TWAIN.TW_IMAGELAYOUT twimagelayout ); [SuppressMessage("Microsoft.Interoperability", "CA1400:PInvokeEntryPointsShouldExist")] [DllImport("twaindsm.dll", EntryPoint = "DSM_Entry", CharSet = CharSet.Ansi)] internal static extern UInt16 WindowsTwaindsmDsmEntryImagelayout ( ref TWAIN.TW_IDENTITY_LEGACY origin, ref TWAIN.TW_IDENTITY_LEGACY dest, TWAIN.DG dg, TWAIN.DAT dat, TWAIN.MSG msg, ref TWAIN.TW_IMAGELAYOUT twimagelayout ); [SuppressMessage("Microsoft.Interoperability", "CA1400:PInvokeEntryPointsShouldExist")] [DllImport("/usr/local/lib/libtwaindsm.so", EntryPoint = "DSM_Entry", CharSet = CharSet.Ansi)] internal static extern UInt16 LinuxDsmEntryImagelayout ( ref TWAIN.TW_IDENTITY_LEGACY origin, ref TWAIN.TW_IDENTITY_LEGACY dest, TWAIN.DG dg, TWAIN.DAT dat, TWAIN.MSG msg, ref TWAIN.TW_IMAGELAYOUT twimagelayout ); [SuppressMessage("Microsoft.Interoperability", "CA1400:PInvokeEntryPointsShouldExist")] [DllImport("/usr/local/lib64/libtwaindsm.so", EntryPoint = "DSM_Entry", CharSet = CharSet.Ansi)] internal static extern UInt16 Linux64DsmEntryImagelayout ( ref TWAIN.TW_IDENTITY_LEGACY origin, ref TWAIN.TW_IDENTITY_LEGACY dest, TWAIN.DG dg, TWAIN.DAT dat, TWAIN.MSG msg, ref TWAIN.TW_IMAGELAYOUT twimagelayout ); [SuppressMessage("Microsoft.Interoperability", "CA1400:PInvokeEntryPointsShouldExist")] [DllImport("/usr/local/lib/libtwaindsm.so.2.3.2", EntryPoint = "DSM_Entry", CharSet = CharSet.Ansi)] internal static extern UInt16 Linux020302Dsm64bitEntryImagelayout ( ref TWAIN.TW_IDENTITY origin, ref TWAIN.TW_IDENTITY dest, TWAIN.DG dg, TWAIN.DAT dat, TWAIN.MSG msg, ref TWAIN.TW_IMAGELAYOUT twimagelayout ); [SuppressMessage("Microsoft.Interoperability", "CA1400:PInvokeEntryPointsShouldExist")] [DllImport("/System/Library/Frameworks/TWAIN.framework/TWAIN", EntryPoint = "DSM_Entry", CharSet = CharSet.Ansi)] internal static extern UInt16 MacosxTwainDsmEntryImagelayout ( ref TWAIN.TW_IDENTITY_MACOSX origin, ref TWAIN.TW_IDENTITY_MACOSX dest, TWAIN.DG dg, TWAIN.DAT dat, TWAIN.MSG msg, ref TWAIN.TW_IMAGELAYOUT twimagelayout ); [SuppressMessage("Microsoft.Interoperability", "CA1400:PInvokeEntryPointsShouldExist")] [DllImport("/Library/Frameworks/TWAINDSM.framework/TWAINDSM", EntryPoint = "DSM_Entry", CharSet = CharSet.Ansi)] internal static extern UInt16 MacosxTwaindsmDsmEntryImagelayout ( ref TWAIN.TW_IDENTITY_MACOSX origin, ref TWAIN.TW_IDENTITY_MACOSX dest, TWAIN.DG dg, TWAIN.DAT dat, TWAIN.MSG msg, ref TWAIN.TW_IMAGELAYOUT twimagelayout ); /// /// Use this for DG_IMAGE / DAT.IMAGEMEMFILEXFER / MSG.* calls... /// /// /// /// /// /// /// /// [SuppressMessage("Microsoft.Interoperability", "CA1400:PInvokeEntryPointsShouldExist")] [DllImport("twain_32.dll", EntryPoint = "DSM_Entry", CharSet = CharSet.Ansi)] internal static extern UInt16 WindowsTwain32DsmEntryImagememfilexfer ( ref TWAIN.TW_IDENTITY_LEGACY origin, ref TWAIN.TW_IDENTITY_LEGACY dest, TWAIN.DG dg, TWAIN.DAT dat, TWAIN.MSG msg, ref TWAIN.TW_IMAGEMEMXFER twimagememxfer ); [SuppressMessage("Microsoft.Interoperability", "CA1400:PInvokeEntryPointsShouldExist")] [DllImport("twaindsm.dll", EntryPoint = "DSM_Entry", CharSet = CharSet.Ansi)] internal static extern UInt16 WindowsTwaindsmDsmEntryImagememfilexfer ( ref TWAIN.TW_IDENTITY_LEGACY origin, ref TWAIN.TW_IDENTITY_LEGACY dest, TWAIN.DG dg, TWAIN.DAT dat, TWAIN.MSG msg, ref TWAIN.TW_IMAGEMEMXFER twimagememxfer ); [SuppressMessage("Microsoft.Interoperability", "CA1400:PInvokeEntryPointsShouldExist")] [DllImport("/usr/local/lib/libtwaindsm.so", EntryPoint = "DSM_Entry", CharSet = CharSet.Ansi)] internal static extern UInt16 LinuxDsmEntryImagememfilexfer ( ref TWAIN.TW_IDENTITY_LEGACY origin, ref TWAIN.TW_IDENTITY_LEGACY dest, TWAIN.DG dg, TWAIN.DAT dat, TWAIN.MSG msg, ref TWAIN.TW_IMAGEMEMXFER twimagememxfer ); [SuppressMessage("Microsoft.Interoperability", "CA1400:PInvokeEntryPointsShouldExist")] [DllImport("/usr/local/lib64/libtwaindsm.so", EntryPoint = "DSM_Entry", CharSet = CharSet.Ansi)] internal static extern UInt16 Linux64DsmEntryImagememfilexfer ( ref TWAIN.TW_IDENTITY_LEGACY origin, ref TWAIN.TW_IDENTITY_LEGACY dest, TWAIN.DG dg, TWAIN.DAT dat, TWAIN.MSG msg, ref TWAIN.TW_IMAGEMEMXFER twimagememxfer ); [SuppressMessage("Microsoft.Interoperability", "CA1400:PInvokeEntryPointsShouldExist")] [DllImport("/usr/local/lib/libtwaindsm.so.2.3.2", EntryPoint = "DSM_Entry", CharSet = CharSet.Ansi)] internal static extern UInt16 Linux020302Dsm64bitEntryImagememfilexfer ( ref TWAIN.TW_IDENTITY origin, ref TWAIN.TW_IDENTITY dest, TWAIN.DG dg, TWAIN.DAT dat, TWAIN.MSG msg, ref TWAIN.TW_IMAGEMEMXFER_LINUX64 twimagememxferlinux64 ); [SuppressMessage("Microsoft.Interoperability", "CA1400:PInvokeEntryPointsShouldExist")] [DllImport("/System/Library/Frameworks/TWAIN.framework/TWAIN", EntryPoint = "DSM_Entry", CharSet = CharSet.Ansi)] internal static extern UInt16 MacosxTwainDsmEntryImagememfilexfer ( ref TWAIN.TW_IDENTITY_MACOSX origin, ref TWAIN.TW_IDENTITY_MACOSX dest, TWAIN.DG dg, TWAIN.DAT dat, TWAIN.MSG msg, ref TWAIN.TW_IMAGEMEMXFER_MACOSX twimagememxfer ); [SuppressMessage("Microsoft.Interoperability", "CA1400:PInvokeEntryPointsShouldExist")] [DllImport("/Library/Frameworks/TWAINDSM.framework/TWAINDSM", EntryPoint = "DSM_Entry", CharSet = CharSet.Ansi)] internal static extern UInt16 MacosxTwaindsmDsmEntryImagememfilexfer ( ref TWAIN.TW_IDENTITY_MACOSX origin, ref TWAIN.TW_IDENTITY_MACOSX dest, TWAIN.DG dg, TWAIN.DAT dat, TWAIN.MSG msg, ref TWAIN.TW_IMAGEMEMXFER_MACOSX twimagememxfer ); /// /// Use this for DG_IMAGE / DAT.IMAGEMEMXFER / MSG.* calls... /// /// /// /// /// /// /// /// [SuppressMessage("Microsoft.Interoperability", "CA1400:PInvokeEntryPointsShouldExist")] [DllImport("twain_32.dll", EntryPoint = "DSM_Entry", CharSet = CharSet.Ansi)] internal static extern UInt16 WindowsTwain32DsmEntryImagememxfer ( ref TWAIN.TW_IDENTITY_LEGACY origin, ref TWAIN.TW_IDENTITY_LEGACY dest, TWAIN.DG dg, TWAIN.DAT dat, TWAIN.MSG msg, ref TWAIN.TW_IMAGEMEMXFER twimagememxfer ); [SuppressMessage("Microsoft.Interoperability", "CA1400:PInvokeEntryPointsShouldExist")] [DllImport("twaindsm.dll", EntryPoint = "DSM_Entry", CharSet = CharSet.Ansi)] internal static extern UInt16 WindowsTwaindsmDsmEntryImagememxfer ( ref TWAIN.TW_IDENTITY_LEGACY origin, ref TWAIN.TW_IDENTITY_LEGACY dest, TWAIN.DG dg, TWAIN.DAT dat, TWAIN.MSG msg, ref TWAIN.TW_IMAGEMEMXFER twimagememxfer ); [SuppressMessage("Microsoft.Interoperability", "CA1400:PInvokeEntryPointsShouldExist")] [DllImport("/usr/local/lib/libtwaindsm.so", EntryPoint = "DSM_Entry", CharSet = CharSet.Ansi)] internal static extern UInt16 LinuxDsmEntryImagememxfer ( ref TWAIN.TW_IDENTITY_LEGACY origin, ref TWAIN.TW_IDENTITY_LEGACY dest, TWAIN.DG dg, TWAIN.DAT dat, TWAIN.MSG msg, ref TWAIN.TW_IMAGEMEMXFER twimagememxfer ); [SuppressMessage("Microsoft.Interoperability", "CA1400:PInvokeEntryPointsShouldExist")] [DllImport("/usr/local/lib64/libtwaindsm.so", EntryPoint = "DSM_Entry", CharSet = CharSet.Ansi)] internal static extern UInt16 Linux64DsmEntryImagememxfer ( ref TWAIN.TW_IDENTITY_LEGACY origin, ref TWAIN.TW_IDENTITY_LEGACY dest, TWAIN.DG dg, TWAIN.DAT dat, TWAIN.MSG msg, ref TWAIN.TW_IMAGEMEMXFER twimagememxfer ); [SuppressMessage("Microsoft.Interoperability", "CA1400:PInvokeEntryPointsShouldExist")] [DllImport("/usr/local/lib/libtwaindsm.so.2.3.2", EntryPoint = "DSM_Entry", CharSet = CharSet.Ansi)] internal static extern UInt16 Linux020302Dsm64bitEntryImagememxfer ( ref TWAIN.TW_IDENTITY origin, ref TWAIN.TW_IDENTITY dest, TWAIN.DG dg, TWAIN.DAT dat, TWAIN.MSG msg, ref TWAIN.TW_IMAGEMEMXFER_LINUX64 twimagememxferlinux64 ); [SuppressMessage("Microsoft.Interoperability", "CA1400:PInvokeEntryPointsShouldExist")] [DllImport("/System/Library/Frameworks/TWAIN.framework/TWAIN", EntryPoint = "DSM_Entry", CharSet = CharSet.Ansi)] internal static extern UInt16 MacosxTwainDsmEntryImagememxfer ( ref TWAIN.TW_IDENTITY_MACOSX origin, ref TWAIN.TW_IDENTITY_MACOSX dest, TWAIN.DG dg, TWAIN.DAT dat, TWAIN.MSG msg, ref TWAIN.TW_IMAGEMEMXFER_MACOSX twimagememxfer ); [SuppressMessage("Microsoft.Interoperability", "CA1400:PInvokeEntryPointsShouldExist")] [DllImport("/Library/Frameworks/TWAINDSM.framework/TWAINDSM", EntryPoint = "DSM_Entry", CharSet = CharSet.Ansi)] internal static extern UInt16 MacosxTwaindsmDsmEntryImagememxfer ( ref TWAIN.TW_IDENTITY_MACOSX origin, ref TWAIN.TW_IDENTITY_MACOSX dest, TWAIN.DG dg, TWAIN.DAT dat, TWAIN.MSG msg, ref TWAIN.TW_IMAGEMEMXFER_MACOSX twimagememxfer ); /// /// Use this for DG_IMAGE / DAT.IMAGENATIVEXFER / MSG.* calls... /// /// /// /// /// /// /// /// [SuppressMessage("Microsoft.Interoperability", "CA1400:PInvokeEntryPointsShouldExist")] [DllImport("twain_32.dll", EntryPoint = "DSM_Entry", CharSet = CharSet.Ansi)] internal static extern UInt16 WindowsTwain32DsmEntryImagenativexfer ( ref TWAIN.TW_IDENTITY_LEGACY origin, ref TWAIN.TW_IDENTITY_LEGACY dest, TWAIN.DG dg, TWAIN.DAT dat, TWAIN.MSG msg, ref IntPtr intptrBitmap ); [SuppressMessage("Microsoft.Interoperability", "CA1400:PInvokeEntryPointsShouldExist")] [DllImport("twaindsm.dll", EntryPoint = "DSM_Entry", CharSet = CharSet.Ansi)] internal static extern UInt16 WindowsTwaindsmDsmEntryImagenativexfer ( ref TWAIN.TW_IDENTITY_LEGACY origin, ref TWAIN.TW_IDENTITY_LEGACY dest, TWAIN.DG dg, TWAIN.DAT dat, TWAIN.MSG msg, ref IntPtr intptrBitmap ); [SuppressMessage("Microsoft.Interoperability", "CA1400:PInvokeEntryPointsShouldExist")] [DllImport("/usr/local/lib/libtwaindsm.so", EntryPoint = "DSM_Entry", CharSet = CharSet.Ansi)] internal static extern UInt16 LinuxDsmEntryImagenativexfer ( ref TWAIN.TW_IDENTITY_LEGACY origin, ref TWAIN.TW_IDENTITY_LEGACY dest, TWAIN.DG dg, TWAIN.DAT dat, TWAIN.MSG msg, ref IntPtr intptrBitmap ); [SuppressMessage("Microsoft.Interoperability", "CA1400:PInvokeEntryPointsShouldExist")] [DllImport("/usr/local/lib64/libtwaindsm.so", EntryPoint = "DSM_Entry", CharSet = CharSet.Ansi)] internal static extern UInt16 Linux64DsmEntryImagenativexfer ( ref TWAIN.TW_IDENTITY_LEGACY origin, ref TWAIN.TW_IDENTITY_LEGACY dest, TWAIN.DG dg, TWAIN.DAT dat, TWAIN.MSG msg, ref IntPtr intptrBitmap ); [SuppressMessage("Microsoft.Interoperability", "CA1400:PInvokeEntryPointsShouldExist")] [DllImport("/usr/local/lib/libtwaindsm.so.2.3.2", EntryPoint = "DSM_Entry", CharSet = CharSet.Ansi)] internal static extern UInt16 Linux020302Dsm64bitEntryImagenativexfer ( ref TWAIN.TW_IDENTITY origin, ref TWAIN.TW_IDENTITY dest, TWAIN.DG dg, TWAIN.DAT dat, TWAIN.MSG msg, ref IntPtr intptrBitmap ); [SuppressMessage("Microsoft.Interoperability", "CA1400:PInvokeEntryPointsShouldExist")] [DllImport("/System/Library/Frameworks/TWAIN.framework/TWAIN", EntryPoint = "DSM_Entry", CharSet = CharSet.Ansi)] internal static extern UInt16 MacosxTwainDsmEntryImagenativexfer ( ref TWAIN.TW_IDENTITY_MACOSX origin, ref TWAIN.TW_IDENTITY_MACOSX dest, TWAIN.DG dg, TWAIN.DAT dat, TWAIN.MSG msg, ref IntPtr intptrBitmap ); [SuppressMessage("Microsoft.Interoperability", "CA1400:PInvokeEntryPointsShouldExist")] [DllImport("/Library/Frameworks/TWAINDSM.framework/TWAINDSM", EntryPoint = "DSM_Entry", CharSet = CharSet.Ansi)] internal static extern UInt16 MacosxTwaindsmDsmEntryImagenativexfer ( ref TWAIN.TW_IDENTITY_MACOSX origin, ref TWAIN.TW_IDENTITY_MACOSX dest, TWAIN.DG dg, TWAIN.DAT dat, TWAIN.MSG msg, ref IntPtr intptrBitmap ); /// /// Use this for DG_IMAGE / DAT.JPEGCOMPRESSION / MSG.* calls... /// /// /// /// /// /// /// /// [SuppressMessage("Microsoft.Interoperability", "CA1400:PInvokeEntryPointsShouldExist")] [DllImport("twain_32.dll", EntryPoint = "DSM_Entry", CharSet = CharSet.Ansi)] internal static extern UInt16 WindowsTwain32DsmEntryJpegcompression ( ref TWAIN.TW_IDENTITY_LEGACY origin, ref TWAIN.TW_IDENTITY_LEGACY dest, TWAIN.DG dg, TWAIN.DAT dat, TWAIN.MSG msg, ref TWAIN.TW_JPEGCOMPRESSION twjpegcompression ); [SuppressMessage("Microsoft.Interoperability", "CA1400:PInvokeEntryPointsShouldExist")] [DllImport("twaindsm.dll", EntryPoint = "DSM_Entry", CharSet = CharSet.Ansi)] internal static extern UInt16 WindowsTwaindsmDsmEntryJpegcompression ( ref TWAIN.TW_IDENTITY_LEGACY origin, ref TWAIN.TW_IDENTITY_LEGACY dest, TWAIN.DG dg, TWAIN.DAT dat, TWAIN.MSG msg, ref TWAIN.TW_JPEGCOMPRESSION twjpegcompression ); [SuppressMessage("Microsoft.Interoperability", "CA1400:PInvokeEntryPointsShouldExist")] [DllImport("/usr/local/lib/libtwaindsm.so", EntryPoint = "DSM_Entry", CharSet = CharSet.Ansi)] internal static extern UInt16 LinuxDsmEntryJpegcompression ( ref TWAIN.TW_IDENTITY_LEGACY origin, ref TWAIN.TW_IDENTITY_LEGACY dest, TWAIN.DG dg, TWAIN.DAT dat, TWAIN.MSG msg, ref TWAIN.TW_JPEGCOMPRESSION twjpegcompression ); [SuppressMessage("Microsoft.Interoperability", "CA1400:PInvokeEntryPointsShouldExist")] [DllImport("/usr/local/lib64/libtwaindsm.so", EntryPoint = "DSM_Entry", CharSet = CharSet.Ansi)] internal static extern UInt16 Linux64DsmEntryJpegcompression ( ref TWAIN.TW_IDENTITY_LEGACY origin, ref TWAIN.TW_IDENTITY_LEGACY dest, TWAIN.DG dg, TWAIN.DAT dat, TWAIN.MSG msg, ref TWAIN.TW_JPEGCOMPRESSION twjpegcompression ); [SuppressMessage("Microsoft.Interoperability", "CA1400:PInvokeEntryPointsShouldExist")] [DllImport("/usr/local/lib/libtwaindsm.so.2.3.2", EntryPoint = "DSM_Entry", CharSet = CharSet.Ansi)] internal static extern UInt16 Linux020302Dsm64bitEntryJpegcompression ( ref TWAIN.TW_IDENTITY origin, ref TWAIN.TW_IDENTITY dest, TWAIN.DG dg, TWAIN.DAT dat, TWAIN.MSG msg, ref TWAIN.TW_JPEGCOMPRESSION twjpegcompression ); [SuppressMessage("Microsoft.Interoperability", "CA1400:PInvokeEntryPointsShouldExist")] [DllImport("/System/Library/Frameworks/TWAIN.framework/TWAIN", EntryPoint = "DSM_Entry", CharSet = CharSet.Ansi)] internal static extern UInt16 MacosxTwainDsmEntryJpegcompression ( ref TWAIN.TW_IDENTITY_MACOSX origin, ref TWAIN.TW_IDENTITY_MACOSX dest, TWAIN.DG dg, TWAIN.DAT dat, TWAIN.MSG msg, ref TWAIN.TW_JPEGCOMPRESSION twjpegcompression ); [SuppressMessage("Microsoft.Interoperability", "CA1400:PInvokeEntryPointsShouldExist")] [DllImport("/Library/Frameworks/TWAINDSM.framework/TWAINDSM", EntryPoint = "DSM_Entry", CharSet = CharSet.Ansi)] internal static extern UInt16 MacosxTwaindsmDsmEntryJpegcompression ( ref TWAIN.TW_IDENTITY_MACOSX origin, ref TWAIN.TW_IDENTITY_MACOSX dest, TWAIN.DG dg, TWAIN.DAT dat, TWAIN.MSG msg, ref TWAIN.TW_JPEGCOMPRESSION twjpegcompression ); /// /// Use this for DG_CONTROL / DAT.METRICS / MSG.* calls... /// /// /// /// /// /// /// /// [SuppressMessage("Microsoft.Interoperability", "CA1400:PInvokeEntryPointsShouldExist")] [DllImport("twain_32.dll", EntryPoint = "DSM_Entry", CharSet = CharSet.Ansi)] internal static extern UInt16 WindowsTwain32DsmEntryMetrics ( ref TWAIN.TW_IDENTITY_LEGACY origin, ref TWAIN.TW_IDENTITY_LEGACY dest, TWAIN.DG dg, TWAIN.DAT dat, TWAIN.MSG msg, ref TWAIN.TW_METRICS twmetrics ); [SuppressMessage("Microsoft.Interoperability", "CA1400:PInvokeEntryPointsShouldExist")] [DllImport("twaindsm.dll", EntryPoint = "DSM_Entry", CharSet = CharSet.Ansi)] internal static extern UInt16 WindowsTwaindsmDsmEntryMetrics ( ref TWAIN.TW_IDENTITY_LEGACY origin, ref TWAIN.TW_IDENTITY_LEGACY dest, TWAIN.DG dg, TWAIN.DAT dat, TWAIN.MSG msg, ref TWAIN.TW_METRICS twmetrics ); [SuppressMessage("Microsoft.Interoperability", "CA1400:PInvokeEntryPointsShouldExist")] [DllImport("/usr/local/lib/libtwaindsm.so", EntryPoint = "DSM_Entry", CharSet = CharSet.Ansi)] internal static extern UInt16 LinuxDsmEntryMetrics ( ref TWAIN.TW_IDENTITY_LEGACY origin, ref TWAIN.TW_IDENTITY_LEGACY dest, TWAIN.DG dg, TWAIN.DAT dat, TWAIN.MSG msg, ref TWAIN.TW_METRICS twmetrics ); [SuppressMessage("Microsoft.Interoperability", "CA1400:PInvokeEntryPointsShouldExist")] [DllImport("/usr/local/lib64/libtwaindsm.so", EntryPoint = "DSM_Entry", CharSet = CharSet.Ansi)] internal static extern UInt16 Linux64DsmEntryMetrics ( ref TWAIN.TW_IDENTITY_LEGACY origin, ref TWAIN.TW_IDENTITY_LEGACY dest, TWAIN.DG dg, TWAIN.DAT dat, TWAIN.MSG msg, ref TWAIN.TW_METRICS twmetrics ); [SuppressMessage("Microsoft.Interoperability", "CA1400:PInvokeEntryPointsShouldExist")] [DllImport("/usr/local/lib/libtwaindsm.so.2.3.2", EntryPoint = "DSM_Entry", CharSet = CharSet.Ansi)] internal static extern UInt16 Linux020302Dsm64bitEntryMetrics ( ref TWAIN.TW_IDENTITY origin, ref TWAIN.TW_IDENTITY dest, TWAIN.DG dg, TWAIN.DAT dat, TWAIN.MSG msg, ref TWAIN.TW_METRICS twmetrics ); [SuppressMessage("Microsoft.Interoperability", "CA1400:PInvokeEntryPointsShouldExist")] [DllImport("/System/Library/Frameworks/TWAIN.framework/TWAIN", EntryPoint = "DSM_Entry", CharSet = CharSet.Ansi)] internal static extern UInt16 MacosxTwainDsmEntryMetrics ( ref TWAIN.TW_IDENTITY_MACOSX origin, ref TWAIN.TW_IDENTITY_MACOSX dest, TWAIN.DG dg, TWAIN.DAT dat, TWAIN.MSG msg, ref TWAIN.TW_METRICS twmetrics ); [SuppressMessage("Microsoft.Interoperability", "CA1400:PInvokeEntryPointsShouldExist")] [DllImport("/Library/Frameworks/TWAINDSM.framework/TWAINDSM", EntryPoint = "DSM_Entry", CharSet = CharSet.Ansi)] internal static extern UInt16 MacosxTwaindsmDsmEntryMetrics ( ref TWAIN.TW_IDENTITY_MACOSX origin, ref TWAIN.TW_IDENTITY_MACOSX dest, TWAIN.DG dg, TWAIN.DAT dat, TWAIN.MSG msg, ref TWAIN.TW_METRICS twmetrics ); /// /// Use this for DG_IMAGE / DAT.PALETTE8 / MSG.* calls... /// /// /// /// /// /// /// /// [SuppressMessage("Microsoft.Interoperability", "CA1400:PInvokeEntryPointsShouldExist")] [DllImport("twain_32.dll", EntryPoint = "DSM_Entry", CharSet = CharSet.Ansi)] internal static extern UInt16 WindowsTwain32DsmEntryPalette8 ( ref TWAIN.TW_IDENTITY_LEGACY origin, ref TWAIN.TW_IDENTITY_LEGACY dest, TWAIN.DG dg, TWAIN.DAT dat, TWAIN.MSG msg, ref TWAIN.TW_PALETTE8 twpalette8 ); [SuppressMessage("Microsoft.Interoperability", "CA1400:PInvokeEntryPointsShouldExist")] [DllImport("twaindsm.dll", EntryPoint = "DSM_Entry", CharSet = CharSet.Ansi)] internal static extern UInt16 WindowsTwaindsmDsmEntryPalette8 ( ref TWAIN.TW_IDENTITY_LEGACY origin, ref TWAIN.TW_IDENTITY_LEGACY dest, TWAIN.DG dg, TWAIN.DAT dat, TWAIN.MSG msg, ref TWAIN.TW_PALETTE8 twpalette8 ); [SuppressMessage("Microsoft.Interoperability", "CA1400:PInvokeEntryPointsShouldExist")] [DllImport("/usr/local/lib/libtwaindsm.so", EntryPoint = "DSM_Entry", CharSet = CharSet.Ansi)] internal static extern UInt16 LinuxDsmEntryPalette8 ( ref TWAIN.TW_IDENTITY_LEGACY origin, ref TWAIN.TW_IDENTITY_LEGACY dest, TWAIN.DG dg, TWAIN.DAT dat, TWAIN.MSG msg, ref TWAIN.TW_PALETTE8 twpalette8 ); [SuppressMessage("Microsoft.Interoperability", "CA1400:PInvokeEntryPointsShouldExist")] [DllImport("/usr/local/lib64/libtwaindsm.so", EntryPoint = "DSM_Entry", CharSet = CharSet.Ansi)] internal static extern UInt16 Linux64DsmEntryPalette8 ( ref TWAIN.TW_IDENTITY_LEGACY origin, ref TWAIN.TW_IDENTITY_LEGACY dest, TWAIN.DG dg, TWAIN.DAT dat, TWAIN.MSG msg, ref TWAIN.TW_PALETTE8 twpalette8 ); [SuppressMessage("Microsoft.Interoperability", "CA1400:PInvokeEntryPointsShouldExist")] [DllImport("/usr/local/lib/libtwaindsm.so.2.3.2", EntryPoint = "DSM_Entry", CharSet = CharSet.Ansi)] internal static extern UInt16 Linux020302Dsm64bitEntryPalette8 ( ref TWAIN.TW_IDENTITY origin, ref TWAIN.TW_IDENTITY dest, TWAIN.DG dg, TWAIN.DAT dat, TWAIN.MSG msg, ref TWAIN.TW_PALETTE8 twpalette8 ); [SuppressMessage("Microsoft.Interoperability", "CA1400:PInvokeEntryPointsShouldExist")] [DllImport("/System/Library/Frameworks/TWAIN.framework/TWAIN", EntryPoint = "DSM_Entry", CharSet = CharSet.Ansi)] internal static extern UInt16 MacosxTwainDsmEntryPalette8 ( ref TWAIN.TW_IDENTITY_MACOSX origin, ref TWAIN.TW_IDENTITY_MACOSX dest, TWAIN.DG dg, TWAIN.DAT dat, TWAIN.MSG msg, ref TWAIN.TW_PALETTE8 twpalette8 ); [SuppressMessage("Microsoft.Interoperability", "CA1400:PInvokeEntryPointsShouldExist")] [DllImport("/Library/Frameworks/TWAINDSM.framework/TWAINDSM", EntryPoint = "DSM_Entry", CharSet = CharSet.Ansi)] internal static extern UInt16 MacosxTwaindsmDsmEntryPalette8 ( ref TWAIN.TW_IDENTITY_MACOSX origin, ref TWAIN.TW_IDENTITY_MACOSX dest, TWAIN.DG dg, TWAIN.DAT dat, TWAIN.MSG msg, ref TWAIN.TW_PALETTE8 twpalette8 ); /// /// Use this for DG_IMAGE / DAT.RGBRESPONSE / MSG.* calls... /// /// /// /// /// /// /// /// [SuppressMessage("Microsoft.Interoperability", "CA1400:PInvokeEntryPointsShouldExist")] [DllImport("twain_32.dll", EntryPoint = "DSM_Entry", CharSet = CharSet.Ansi)] internal static extern UInt16 WindowsTwain32DsmEntryRgbresponse ( ref TWAIN.TW_IDENTITY_LEGACY origin, ref TWAIN.TW_IDENTITY_LEGACY dest, TWAIN.DG dg, TWAIN.DAT dat, TWAIN.MSG msg, ref TWAIN.TW_RGBRESPONSE twrgbresponse ); [SuppressMessage("Microsoft.Interoperability", "CA1400:PInvokeEntryPointsShouldExist")] [DllImport("twaindsm.dll", EntryPoint = "DSM_Entry", CharSet = CharSet.Ansi)] internal static extern UInt16 WindowsTwaindsmDsmEntryRgbresponse ( ref TWAIN.TW_IDENTITY_LEGACY origin, ref TWAIN.TW_IDENTITY_LEGACY dest, TWAIN.DG dg, TWAIN.DAT dat, TWAIN.MSG msg, ref TWAIN.TW_RGBRESPONSE twrgbresponse ); [SuppressMessage("Microsoft.Interoperability", "CA1400:PInvokeEntryPointsShouldExist")] [DllImport("/usr/local/lib/libtwaindsm.so", EntryPoint = "DSM_Entry", CharSet = CharSet.Ansi)] internal static extern UInt16 LinuxDsmEntryRgbresponse ( ref TWAIN.TW_IDENTITY_LEGACY origin, ref TWAIN.TW_IDENTITY_LEGACY dest, TWAIN.DG dg, TWAIN.DAT dat, TWAIN.MSG msg, ref TWAIN.TW_RGBRESPONSE twrgbresponse ); [SuppressMessage("Microsoft.Interoperability", "CA1400:PInvokeEntryPointsShouldExist")] [DllImport("/usr/local/lib64/libtwaindsm.so", EntryPoint = "DSM_Entry", CharSet = CharSet.Ansi)] internal static extern UInt16 Linux64DsmEntryRgbresponse ( ref TWAIN.TW_IDENTITY_LEGACY origin, ref TWAIN.TW_IDENTITY_LEGACY dest, TWAIN.DG dg, TWAIN.DAT dat, TWAIN.MSG msg, ref TWAIN.TW_RGBRESPONSE twrgbresponse ); [SuppressMessage("Microsoft.Interoperability", "CA1400:PInvokeEntryPointsShouldExist")] [DllImport("/usr/local/lib/libtwaindsm.so.2.3.2", EntryPoint = "DSM_Entry", CharSet = CharSet.Ansi)] internal static extern UInt16 Linux020302Dsm64bitEntryRgbresponse ( ref TWAIN.TW_IDENTITY origin, ref TWAIN.TW_IDENTITY dest, TWAIN.DG dg, TWAIN.DAT dat, TWAIN.MSG msg, ref TWAIN.TW_RGBRESPONSE twrgbresponse ); [SuppressMessage("Microsoft.Interoperability", "CA1400:PInvokeEntryPointsShouldExist")] [DllImport("/System/Library/Frameworks/TWAIN.framework/TWAIN", EntryPoint = "DSM_Entry", CharSet = CharSet.Ansi)] internal static extern UInt16 MacosxTwainDsmEntryRgbresponse ( ref TWAIN.TW_IDENTITY_MACOSX origin, ref TWAIN.TW_IDENTITY_MACOSX dest, TWAIN.DG dg, TWAIN.DAT dat, TWAIN.MSG msg, ref TWAIN.TW_RGBRESPONSE twrgbresponse ); [SuppressMessage("Microsoft.Interoperability", "CA1400:PInvokeEntryPointsShouldExist")] [DllImport("/Library/Frameworks/TWAINDSM.framework/TWAINDSM", EntryPoint = "DSM_Entry", CharSet = CharSet.Ansi)] internal static extern UInt16 MacosxTwaindsmDsmEntryRgbresponse ( ref TWAIN.TW_IDENTITY_MACOSX origin, ref TWAIN.TW_IDENTITY_MACOSX dest, TWAIN.DG dg, TWAIN.DAT dat, TWAIN.MSG msg, ref TWAIN.TW_RGBRESPONSE twrgbresponse ); } } ================================================ FILE: twaincs/source/twaincs.csproj ================================================  15.0.27428.2005 false true Debug AnyCPU {E00DEC90-0A85-47D5-B0E4-39940AF8C141} Library false Properties TWAIN v4.5.2 512 true full false bin\AnyCPU\Debug\ DEBUG;TRACE prompt 4 true false pdbonly true bin\AnyCPU\Release\ TRACE prompt 4 true false TWAINWorkingGroup true bin\x64\Debug\ DEBUG;TRACE full x64 prompt false false true false bin\x64\Release\ TRACE true pdbonly x64 prompt false false false true false true bin\x86\Debug\ DEBUG;TRACE full x86 prompt false false false true true false bin\x86\Release\ TRACE true pdbonly x86 prompt false false false true true false ================================================ FILE: twaincs/source/twaincs.sln ================================================  Microsoft Visual Studio Solution File, Format Version 12.00 # Visual Studio 15 VisualStudioVersion = 15.0.28307.572 MinimumVisualStudioVersion = 10.0.40219.1 Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "twaincs", "twaincs.csproj", "{E00DEC90-0A85-47D5-B0E4-39940AF8C141}" EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "twaincstst", "twaincstst\source\twaincstst.csproj", "{7D3F078C-BAE8-4975-9EBA-F162ABD64BBD}" ProjectSection(ProjectDependencies) = postProject {E00DEC90-0A85-47D5-B0E4-39940AF8C141} = {E00DEC90-0A85-47D5-B0E4-39940AF8C141} EndProjectSection EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "twaincsscan", "twaincsscan\source\twaincsscan.csproj", "{DE8AC167-CFF1-446D-9145-29179CA1B472}" ProjectSection(ProjectDependencies) = postProject {E00DEC90-0A85-47D5-B0E4-39940AF8C141} = {E00DEC90-0A85-47D5-B0E4-39940AF8C141} EndProjectSection EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "twaincscert", "twaincscert\source\twaincscert.csproj", "{ED11A4C1-1C03-4092-B1FA-F1D35C47D59E}" ProjectSection(ProjectDependencies) = postProject {E00DEC90-0A85-47D5-B0E4-39940AF8C141} = {E00DEC90-0A85-47D5-B0E4-39940AF8C141} EndProjectSection EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU Debug|x64 = Debug|x64 Debug|x86 = Debug|x86 Release|Any CPU = Release|Any CPU Release|x64 = Release|x64 Release|x86 = Release|x86 EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution {E00DEC90-0A85-47D5-B0E4-39940AF8C141}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {E00DEC90-0A85-47D5-B0E4-39940AF8C141}.Debug|Any CPU.Build.0 = Debug|Any CPU {E00DEC90-0A85-47D5-B0E4-39940AF8C141}.Debug|x64.ActiveCfg = Debug|x64 {E00DEC90-0A85-47D5-B0E4-39940AF8C141}.Debug|x64.Build.0 = Debug|x64 {E00DEC90-0A85-47D5-B0E4-39940AF8C141}.Debug|x86.ActiveCfg = Debug|x86 {E00DEC90-0A85-47D5-B0E4-39940AF8C141}.Debug|x86.Build.0 = Debug|x86 {E00DEC90-0A85-47D5-B0E4-39940AF8C141}.Release|Any CPU.ActiveCfg = Release|Any CPU {E00DEC90-0A85-47D5-B0E4-39940AF8C141}.Release|Any CPU.Build.0 = Release|Any CPU {E00DEC90-0A85-47D5-B0E4-39940AF8C141}.Release|x64.ActiveCfg = Release|x64 {E00DEC90-0A85-47D5-B0E4-39940AF8C141}.Release|x64.Build.0 = Release|x64 {E00DEC90-0A85-47D5-B0E4-39940AF8C141}.Release|x86.ActiveCfg = Release|x86 {E00DEC90-0A85-47D5-B0E4-39940AF8C141}.Release|x86.Build.0 = Release|x86 {7D3F078C-BAE8-4975-9EBA-F162ABD64BBD}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {7D3F078C-BAE8-4975-9EBA-F162ABD64BBD}.Debug|Any CPU.Build.0 = Debug|Any CPU {7D3F078C-BAE8-4975-9EBA-F162ABD64BBD}.Debug|x64.ActiveCfg = Debug|x64 {7D3F078C-BAE8-4975-9EBA-F162ABD64BBD}.Debug|x64.Build.0 = Debug|x64 {7D3F078C-BAE8-4975-9EBA-F162ABD64BBD}.Debug|x86.ActiveCfg = Debug|x86 {7D3F078C-BAE8-4975-9EBA-F162ABD64BBD}.Debug|x86.Build.0 = Debug|x86 {7D3F078C-BAE8-4975-9EBA-F162ABD64BBD}.Release|Any CPU.ActiveCfg = Release|Any CPU {7D3F078C-BAE8-4975-9EBA-F162ABD64BBD}.Release|Any CPU.Build.0 = Release|Any CPU {7D3F078C-BAE8-4975-9EBA-F162ABD64BBD}.Release|x64.ActiveCfg = Release|x64 {7D3F078C-BAE8-4975-9EBA-F162ABD64BBD}.Release|x64.Build.0 = Release|x64 {7D3F078C-BAE8-4975-9EBA-F162ABD64BBD}.Release|x86.ActiveCfg = Release|x86 {7D3F078C-BAE8-4975-9EBA-F162ABD64BBD}.Release|x86.Build.0 = Release|x86 {DE8AC167-CFF1-446D-9145-29179CA1B472}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {DE8AC167-CFF1-446D-9145-29179CA1B472}.Debug|Any CPU.Build.0 = Debug|Any CPU {DE8AC167-CFF1-446D-9145-29179CA1B472}.Debug|x64.ActiveCfg = Debug|x64 {DE8AC167-CFF1-446D-9145-29179CA1B472}.Debug|x64.Build.0 = Debug|x64 {DE8AC167-CFF1-446D-9145-29179CA1B472}.Debug|x86.ActiveCfg = Debug|x86 {DE8AC167-CFF1-446D-9145-29179CA1B472}.Debug|x86.Build.0 = Debug|x86 {DE8AC167-CFF1-446D-9145-29179CA1B472}.Release|Any CPU.ActiveCfg = Release|Any CPU {DE8AC167-CFF1-446D-9145-29179CA1B472}.Release|Any CPU.Build.0 = Release|Any CPU {DE8AC167-CFF1-446D-9145-29179CA1B472}.Release|x64.ActiveCfg = Release|x64 {DE8AC167-CFF1-446D-9145-29179CA1B472}.Release|x64.Build.0 = Release|x64 {DE8AC167-CFF1-446D-9145-29179CA1B472}.Release|x86.ActiveCfg = Release|x86 {DE8AC167-CFF1-446D-9145-29179CA1B472}.Release|x86.Build.0 = Release|x86 {ED11A4C1-1C03-4092-B1FA-F1D35C47D59E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {ED11A4C1-1C03-4092-B1FA-F1D35C47D59E}.Debug|Any CPU.Build.0 = Debug|Any CPU {ED11A4C1-1C03-4092-B1FA-F1D35C47D59E}.Debug|x64.ActiveCfg = Debug|x64 {ED11A4C1-1C03-4092-B1FA-F1D35C47D59E}.Debug|x64.Build.0 = Debug|x64 {ED11A4C1-1C03-4092-B1FA-F1D35C47D59E}.Debug|x86.ActiveCfg = Debug|x86 {ED11A4C1-1C03-4092-B1FA-F1D35C47D59E}.Debug|x86.Build.0 = Debug|x86 {ED11A4C1-1C03-4092-B1FA-F1D35C47D59E}.Release|Any CPU.ActiveCfg = Release|Any CPU {ED11A4C1-1C03-4092-B1FA-F1D35C47D59E}.Release|Any CPU.Build.0 = Release|Any CPU {ED11A4C1-1C03-4092-B1FA-F1D35C47D59E}.Release|x64.ActiveCfg = Release|x64 {ED11A4C1-1C03-4092-B1FA-F1D35C47D59E}.Release|x64.Build.0 = Release|x64 {ED11A4C1-1C03-4092-B1FA-F1D35C47D59E}.Release|x86.ActiveCfg = Release|x86 {ED11A4C1-1C03-4092-B1FA-F1D35C47D59E}.Release|x86.Build.0 = Release|x86 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {9B80A60B-1770-4684-B075-19CC3FDAEB35} EndGlobalSection EndGlobal ================================================ FILE: twaincs/source/twaincscert/source/FormMain.Designer.cs ================================================ namespace twaincscert { partial class FormMain { /// /// Required designer variable. /// private System.ComponentModel.IContainer components = null; /// /// Clean up any resources being used. /// /// true if managed resources should be disposed; otherwise, false. protected override void Dispose(bool disposing) { if (disposing && (components != null)) { components.Dispose(); } base.Dispose(disposing); } #region Windows Form Designer generated code /// /// Required method for Designer support - do not modify /// the contents of this method with the code editor. /// private void InitializeComponent() { this.SuspendLayout(); // // FormMain // this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; this.ClientSize = new System.Drawing.Size(285, 193); this.Name = "FormMain"; this.Opacity = 0D; this.ShowInTaskbar = false; this.Text = "FormMain"; this.ResumeLayout(false); } #endregion } } ================================================ FILE: twaincs/source/twaincscert/source/FormMain.cs ================================================ using System; using System.Security.Permissions; using System.Threading; using System.Windows.Forms; using TWAINWorkingGroup; namespace twaincscert { public partial class FormMain : Form, IMessageFilter { /// /// Our constructor... /// public FormMain() { // Not much going on here, because we never show this form... InitializeComponent(); SetMessageFilter(true); } /// /// Prevent us from getting the focus, so we don't steal it from /// our console... /// protected override bool ShowWithoutActivation { get { return (true); } } /// /// Monitor for DG_CONTROL / DAT_NULL / MSG_* stuff (ex MSG_XFERREADY), this /// function is only triggered when SetMessageFilter() is called with 'true'... /// /// Message to process /// Result of the processing [SecurityPermissionAttribute(SecurityAction.LinkDemand, Flags = SecurityPermissionFlag.UnmanagedCode)] public bool PreFilterMessage(ref Message a_message) { if (m_terminal != null) { return (m_terminal.PreFilterMessage(a_message.HWnd, a_message.Msg, a_message.WParam, a_message.LParam)); } return (true); } /// /// Turn message filtering on or off, we use this to capture stuff /// like MSG_XFERREADY. If it's off, then it's assumed we're getting /// this info through DAT_CALLBACK2... /// /// True to turn it on public void SetMessageFilter(bool a_blAdd) { if (a_blAdd) { Application.AddMessageFilter(this); } else { Application.RemoveMessageFilter(this); } } /// /// Link us to our terminal object... /// /// our terminal object public void SetTerminal(Terminal a_terminal) { m_terminal = a_terminal; } /// /// Our event handler for the scan callback event. This will be /// called once by ScanCallbackTrigger on receipt of an event /// like MSG_XFERREADY, and then will be reissued on every call /// into ScanCallback until we're done and get back to state 4. /// /// This helps to make sure we're always running in the context /// of FormMain on Windows, which is critical if we want drivers /// to work properly. It also gives a way to break up the calls /// so the message pump is still responsive. /// /// /// public void ScanCallbackEventHandler(object sender, EventArgs e) { m_terminal.ScanCallback((m_terminal.GetTwain() == null) ? true : (m_terminal.GetTwain().GetState() <= TWAIN.STATE.S3)); } /// /// Private attributes... /// private Terminal m_terminal = null; } } ================================================ FILE: twaincs/source/twaincscert/source/FormMain.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 ================================================ FILE: twaincs/source/twaincscert/source/MsBuildAL1073WarningWorkaround.targets ================================================ $(TargetFrameworkSDKToolsDirectory)$(Platform)\ ================================================ FILE: twaincs/source/twaincscert/source/Program.cs ================================================ /////////////////////////////////////////////////////////////////////////////////////// // // twaincscert.Program // // Our entry point. // /////////////////////////////////////////////////////////////////////////////////////// // Author Date Comment // M.McLaughlin 13-Jan-2020 Initial Release /////////////////////////////////////////////////////////////////////////////////////// // Copyright (C) 2020-2021 Kodak Alaris Inc. // // Permission is hereby granted, free of charge, to any person obtaining a // copy of this software and associated documentation files (the "Software"), // to deal in the Software without restriction, including without limitation // the rights to use, copy, modify, merge, publish, distribute, sublicense, // and/or sell copies of the Software, and to permit persons to whom the // Software is furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL // THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER // DEALINGS IN THE SOFTWARE. /////////////////////////////////////////////////////////////////////////////////////// // Helpers... using System; using System.Threading; using System.Windows.Forms; using TWAINWorkingGroup; namespace twaincscert { static class Program { /// /// The main entry point for the application. /// /// interesting arguments [STAThread] static void Main(string[] a_aszArgs) { string szExecutableName; string szWriteFolder; // Load our configuration information and our arguments, // so that we can access them from anywhere in the code... if (!Config.Load(System.Reflection.Assembly.GetEntryAssembly().Location, a_aszArgs, "appdata.txt")) { Console.Out.WriteLine("Error starting. Try uninstalling and reinstalling this software."); Environment.Exit(1); } // Set up our data folders... szWriteFolder = Config.Get("writeFolder", ""); szExecutableName = Config.Get("executableName", ""); // Turn on logging... Log.Open(szExecutableName, szWriteFolder, 1); Log.SetLevel((int)Config.Get("logLevel", 0)); Log.Info(szExecutableName + " Log Started..."); // Windows needs a window, we need our console and window // in different threads for full control... if (TWAIN.GetPlatform() == TWAIN.Platform.WINDOWS) { // Init our form... Application.EnableVisualStyles(); Application.SetCompatibleTextRenderingDefault(false); FormMain formmain = new FormMain(); // Launch the terminal window, we're doing this in // a thread so we can have a console and a form. When // the thread is done there's no reason to be subtle, // we can exit the application... Terminal terminal = new twaincscert.Terminal(formmain); Thread threadTerminal = new Thread( new ThreadStart( delegate () { terminal.Run(); Environment.Exit(0); } ) ); threadTerminal.Start(); // Run our form, the exit above will kill it off... formmain.SetTerminal(terminal); Application.Run(formmain); } // Linux and Mac come here, life is much simpler for them... else { Terminal terminal = new twaincscert.Terminal(null); terminal.Run(); } // All done... Log.Info(szExecutableName + " Log Ended..."); Log.Close(); Environment.Exit(0); } } } ================================================ FILE: twaincs/source/twaincscert/source/Properties/AssemblyInfo.cs ================================================ /////////////////////////////////////////////////////////////////////////////////////// // // twaincscert AssemblyInfo // /////////////////////////////////////////////////////////////////////////////////////// // Author Date Comment // M.McLaughlin 13-Jan-2020 Initial Release /////////////////////////////////////////////////////////////////////////////////////// // Copyright (C) 2020-2021 Kodak Alaris Inc. // // Permission is hereby granted, free of charge, to any person obtaining a // copy of this software and associated documentation files (the "Software"), // to deal in the Software without restriction, including without limitation // the rights to use, copy, modify, merge, publish, distribute, sublicense, // and/or sell copies of the Software, and to permit persons to whom the // Software is furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL // THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER // DEALINGS IN THE SOFTWARE. /////////////////////////////////////////////////////////////////////////////////////// using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; // General Information about an assembly is controlled through the following // set of attributes. Change these attribute values to modify the information // associated with an assembly. [assembly: AssemblyTitle("twaincscert")] [assembly: AssemblyDescription("TWAIN Certification")] [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany("Kodak Alaris Inc.")] [assembly: AssemblyProduct("twaincscert")] [assembly: AssemblyCopyright("Copyright © 2020-2020, Kodak Alaris Inc.")] [assembly: AssemblyTrademark("")] [assembly: AssemblyCulture("")] // Setting ComVisible to false makes the types in this assembly not visible // to COM components. If you need to access a type in this assembly from // COM, set the ComVisible attribute to true on that type. [assembly: ComVisible(false)] // The following GUID is for the ID of the typelib if this project is exposed to COM [assembly: Guid("18d8384f-90a8-4fc1-aca9-60ec4c86b3a2")] // Version information for an assembly consists of the following four values: // // Major Version // Minor Version // Build Number // Revision // // You can specify all the values or you can default the Build and Revision Numbers // by using the '*' as shown below: [assembly: AssemblyVersion("2.5.*")] [assembly: AssemblyFileVersion("2.5.0.0")] ================================================ FILE: twaincs/source/twaincscert/source/Properties/Resources.Designer.cs ================================================ //------------------------------------------------------------------------------ // // This code was generated by a tool. // Runtime Version:4.0.30319.42000 // // Changes to this file may cause incorrect behavior and will be lost if // the code is regenerated. // //------------------------------------------------------------------------------ namespace twaincscert.Properties { using System; /// /// A strongly-typed resource class, for looking up localized strings, etc. /// // This class was auto-generated by the StronglyTypedResourceBuilder // class via a tool like ResGen or Visual Studio. // To add or remove a member, edit your .ResX file then rerun ResGen // with the /str option, or rebuild your VS project. [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "15.0.0.0")] [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] internal class Resources { private static global::System.Resources.ResourceManager resourceMan; private static global::System.Globalization.CultureInfo resourceCulture; [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] internal Resources() { } /// /// Returns the cached ResourceManager instance used by this class. /// [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] internal static global::System.Resources.ResourceManager ResourceManager { get { if (object.ReferenceEquals(resourceMan, null)) { global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("twaincscert.Properties.Resources", typeof(Resources).Assembly); resourceMan = temp; } return resourceMan; } } /// /// Overrides the current thread's CurrentUICulture property for all /// resource lookups using this strongly typed resource class. /// [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] internal static global::System.Globalization.CultureInfo Culture { get { return resourceCulture; } set { resourceCulture = value; } } /// /// Looks up a localized resource of type System.Byte[]. /// internal static byte[] data { get { object obj = ResourceManager.GetObject("data", resourceCulture); return ((byte[])(obj)); } } } } ================================================ FILE: twaincs/source/twaincscert/source/Properties/Resources.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 data.zip;System.Byte[], mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 ================================================ FILE: twaincs/source/twaincscert/source/Properties/Settings.Designer.cs ================================================ //------------------------------------------------------------------------------ // // This code was generated by a tool. // Runtime Version:4.0.30319.42000 // // Changes to this file may cause incorrect behavior and will be lost if // the code is regenerated. // //------------------------------------------------------------------------------ namespace twaincscert.Properties { [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "15.7.0.0")] internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase { private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings()))); public static Settings Default { get { return defaultInstance; } } } } ================================================ FILE: twaincs/source/twaincscert/source/Properties/Settings.settings ================================================  ================================================ FILE: twaincs/source/twaincscert/source/app.config ================================================ ================================================ FILE: twaincs/source/twaincscert/source/data/certification/010 - TWAIN Standard Capability Tests/CAP_SUPPORTEDCAPS.tc ================================================ ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; CAP_SUPPORTEDCAPS ; Confirm Basic Negotiation with CAP_SUPPORTEDCAPS ; ; Arguments ; arg:1 - TW_IDENTITY.ProductName of scanner to test ; ; Globals ; sys_capabilitytable - from LoadTables.tc ; ; Locals ; name - current test being done ; certifyresult - result of the tests ; supportedcaps - data from MSG_GET for CAP_SUPPORTEDCAPS ; capabilitytable.index - index of current value ; capabilitytable.value - current value based on capabilitytable.index ; capabilitytable.flags - current value's flags ; ; Returns ; pass or fail ; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Initialize... ; echo.titletest 'CAP_SUPPORTEDCAPS' setlocal supportedcaps '' setlocal certifyresult 'pass' ; assume success ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Check for TWAIN protocol 2.4 or higher ; We won't abort on this, since it may be useful for folks to run the ; tests, but we won't let it pass... ; setlocal name 'Check for TWAIN 2.4 protocol or higher' if '${ds:${get:TW_IDENTITY.ProtocolMajor}}' >= 3 goto MAIN.PROTOCOLVERSION.PASS ; >=3 is good if '${ds:${get:TW_IDENTITY.ProtocolMajor}}' < 2 goto MAIN.PROTOCOLVERSION.FAIL ; <2 is bad if '${ds:${get:TW_IDENTITY.ProtocolMinor}}' < 4 goto MAIN.PROTOCOLVERSION.FAIL ; <2.4 is bad goto MAIN.PROTOCOLVERSION.PASS ; :MAIN.PROTOCOLVERSION.FAIL echo.passfail '${get:name}' 'fail - ${ds:${get:TW_IDENTITY.ProtocolMajor}}.${ds:${get:TW_IDENTITY.ProtocolMinor}}' setlocal certifyresult 'fail' goto MAIN.PROTOCOLVERSION.DONE ; :MAIN.PROTOCOLVERSION.PASS echo.passfail '${get:name}' 'pass' :MAIN.PROTOCOLVERSION.DONE ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; MSG_GET CAP_SUPPORTEDCAPS ; If result is not TWRC_SUCCESS, then end with error ; setlocal name 'MSG_GET' dsmentry src ds dg_control dat_capability msg_get 'CAP_SUPPORTEDCAPS,0,0,0' if '${sts:}' != 'SUCCESS' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:name}' 'pass' setlocal supportedcaps '${ret:}' ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; If TW_CAPABILITY.Cap is not CAP_SUPPORTEDCAPS, then end with error ; setlocal name 'TW_CAPABILITY.Cap is CAP_SUPPORTEDCAPS' if '${getindex:supportedcaps:${get:TW_CAPABILITY.Cap}}' != 'CAP_SUPPORTEDCAPS' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:name}' 'pass' ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; If TW_CAPABILITY.ConType is not TWON_ARRAY, then end with error ; setlocal name 'TW_CAPABILITY.ConType is TWON_ARRAY' if '${getindex:supportedcaps:${get:TW_CAPABILITY.ConType}}' != 'TWON_ARRAY' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:name}' 'pass' ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; If TW_ARRAY.ItemType is not TWTY_UINT16, then end with error ; setlocal name 'TW_ARRAY.ItemType is TWTY_UINT16' if '${getindex:supportedcaps:${get:TW_ARRAY.ItemType}}' != 'TWTY_UINT16' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:name}' 'pass' ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; If TW_ARRAY.NumItems is equal to zero, then end with error ; setlocal name 'TW_ARRAY.NumItems > 0' if '${getindex:supportedcaps:${get:TW_ARRAY.NumItems}}' <= '0' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:name}' 'pass' ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; SPECNOTE: the tests ask that CAP_SUPPORTEDCAPS, ICAP_PIXELTYPE, ICAP_XFERMECH be ; confirmed, but the spec lists many manadatory capabilities. So we'll go through ; the table to identify them all. Note the use of the extra commas to make sure we ; correctly identify full items, and not substrings... ; setlocal name 'Check for mandatory capabilities' setlocal capabilitytable.index '-1' ; :MAIN.SUPPORTEDCAPS.NEXT increment capabilitytable.index '${get:capabilitytable.index}' 1 setlocal capabilitytable.value '${getindex:sys_capabilitytable:${get:capabilitytable.index}}' if '${get:capabilitytable.value}' == '' goto MAIN.SUPPORTEDCAPS.DONE setlocal capabilitytable.flags '${get:${get:capabilitytable.value}.Flags}' ; ex: ICAP_PIXELTYPE.Flags if '${get:capabilitytable.flags}' !~contains 'mandatory' goto MAIN.SUPPORTEDCAPS.NEXT ; if not mandatory, skip it if ',${get:supportedcaps},' !~contains ',${get:capabilitytable.value},' goto MAIN.ERROR.ECHOPASSFAIL goto MAIN.SUPPORTEDCAPS.NEXT ; :MAIN.SUPPORTEDCAPS.DONE echo.passfail '${get:name}' 'pass' ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Summary and cleanup... ; ; Did we pass? if '${get:certifyresult}' != 'pass' goto MAIN.ERROR echo.passfail 'SUMMARY' 'pass' return 'pass' ; ; Ruh-roh... :MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:name}' 'fail - ${sts:} ${ret:}' :MAIN.ERROR echo.passfail 'SUMMARY' 'fail' return 'fail' ================================================ FILE: twaincs/source/twaincscert/source/data/certification/010 - TWAIN Standard Capability Tests/Certification.tc ================================================ ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; TWAIN Standard Capability Tests ; Test for capabilties described in the specification. ; ; Arguments ; arg:1 - TW_IDENTITY.ProductName of scanner to test ; arg:2 - global to set on fail ; ; Globals ; (none) ; ; Locals ; twidentity.productname - product name of scanner to test ; certifyresult - global to set on fail ; ; Returns ; (none) ; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Initialize stuff, load tables if not already done for us... ; echo.titlesuite 'TWAIN Standard Capability Tests v1.0 23-Feb-2020' setlocal twidentity.productname '${arg:1}' setlocal certifyresult '${arg:2}' if '${get:TW_ARRAY.ItemType}' != '' goto MAIN.LOADTABLES.SKIP run '${folder:certification}/LoadTables' :MAIN.LOADTABLES.SKIP ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Run the tests... ; call CERTIFY '${folder:certification}/Opends' '${get:twidentity.productname}' '${get:certifyresult}' if '${get:${get:certifyresult}}' == 'fail' goto MAIN.CLOSEDS call CERTIFY 'CAP_SUPPORTEDCAPS' '${get:twidentity.productname}' '${get:certifyresult}' call CERTIFY 'ICAP_PIXELTYPE' '${get:twidentity.productname}' '${get:certifyresult}' call CERTIFY 'ICAP_XFERMECH' '${get:twidentity.productname}' '${get:certifyresult}' call CERTIFY 'DAT_CAPABILITY' '${get:twidentity.productname}' '${get:certifyresult}' :MAIN.CLOSEDS call CERTIFY '${folder:certification}/Closeds' '${get:twidentity.productname}' '${get:certifyresult}' return ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Function: Certify ; arg:1 - script to run ; arg:2 - TW_IDENTITY.ProductName of scanner to test ; arg:3 - global value to update on fail ; returns: (none) ; :CERTIFY ; run '${arg:1}' '${arg:2}' if '${ret:}' != 'pass' goto CERTIFY.FAIL return 'pass' ; :CERTIFY.FAIL setglobal '${arg:3}' 'fail' return 'fail' ================================================ FILE: twaincs/source/twaincscert/source/data/certification/010 - TWAIN Standard Capability Tests/DAT_CAPABILITY.tc ================================================ ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; DAT_CAPABILITY ; Exercise DAT_CAPABILITY for the standard TWAIN capabilities ; ; Arguments ; arg:1 - TW_IDENTITY.ProductName of scanner to test ; ; Globals ; g_datcapabilityresult - pass/fail for the entire test ; g_querysupport - numeric value of query support for a capability ; g_pixeltype.value - for restoring pixel type ; ; Locals ; name - current test being done ; indent - amount to indent echo.passfail ; ; pixeltype.itemlist - list of pixeltypes to check ; pixeltype.index - index of current pixeltype being checked ; ; supportedcaps - data from MSG_GET for CAP_SUPPORTEDCAPS ; supportedcaps.index - index of capability from supportedcaps ; supportedcaps.value - current cap value for supportedcaps.index ; ; Returns ; pass or fail ; ; History ; v1.0 21-Feb-2020 - first version ; v1.1 29-Apr-2020 - fixed MSG_SET test to use TW_ONEVALUE, per the spec ; v1.2 03-Jun-2020 - skip MSG_SET if any previous test failed ; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Initialize... ; echo.titletest 'DAT_CAPABILITY' setlocal indent '' setlocal pixeltype.itemlist 'TWPT_BW,TWPT_GRAY,TWPT_RGB' setlocal pixeltype.index '-1' setglobal g_datcapabilityresult 'pass' ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; MSG_RESETALL ; If return code is not TWRC_SUCCESS, end with an error ; setlocal name 'MSG_RESETALL' dsmentry src ds dg_control dat_capability msg_resetall '0,0,0,0' if '${sts:}' != 'SUCCESS' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Repeat this section for each enumerated value found inside of ICAP_PIXELTYPE, ; (testing is done for each value of ICAP_PIXELTYPE, to provide the best chance ; of exercising every available capability). Remember the pixeltype setting, ; because we have to restore it as part of the MSG_RESET and MSG_SET tests. ; :MAIN.NEXTTWPT setlocal indent '' increment pixeltype.index '${get:pixeltype.index}' setglobal g_pixeltype.value '${getindex:pixeltype.itemlist:${get:pixeltype.index}}' if '${get:g_pixeltype.value}' != '' goto MAIN.TWPTSET goto MAIN.PASS :MAIN.TWPTSET dsmentry src ds dg_control dat_capability msg_set 'ICAP_PIXELTYPE,TWON_ONEVALUE,TWTY_UINT16,${get:g_pixeltype.value}' if '${sts:}' == 'SUCCESS' goto MAIN.TWPTCONTINUE echo.passfail '${get:indent}${get:g_pixeltype.value}' 'skip' goto MAIN.NEXTTWPT :MAIN.TWPTCONTINUE echo.passfail '${get:indent}${get:g_pixeltype.value}' 'pass' ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Repeat this section for Standard TWAIN array values found inside of ; CAP_SUPPORTEDCAPS (each Standard TWAIN capability ID is referred to as #CAP# ; for the rest of this section) ; setlocal indent ' ' setlocal name 'CAP_SUPPORTEDCAPS MSG_GET' dsmentry src ds dg_control dat_capability msg_get 'CAP_SUPPORTEDCAPS,0,0,0' if '${sts:}' != 'SUCCESS' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' setlocal supportedcaps '${ret:}' ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Turn on capabilities that enable the use of other capabilities ; SPECNOTE: this isn't described in the tests, but it seems like a good idea ; call ENABLECAPABILITIES '${get:supportedcaps}' ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Grab a standard TWAIN capability from CAP_SUPPORTEDCAPS, we know it's ; supported if we have a name for it (it's not a number). ; setlocal supportedcaps.index '${get:TW_ARRAY.ItemList}' increment supportedcaps.index '${get:supportedcaps.index}' -1 :MAIN.NEXTCAP ; increment supportedcaps.index '${get:supportedcaps.index}' setlocal supportedcaps.value '${getindex:supportedcaps:${get:supportedcaps.index}}' if '${get:supportedcaps.value}' == '' goto MAIN.NEXTTWPT ; we've run out of supportedcaps values if '${get:supportedcaps.value}' ~contains '0x' goto MAIN.NEXTCAP ; not a standard cap ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Perform these tests on each capability... ; SPECNOTE: because we're referencing the querysupport value we don't have to accept ; TWCC_CAPSEQERROR as a valid value, so it'll be an error just like everything else... ; call MSGQUERYSUPPORT '${get:supportedcaps.value}' g_querysupport g_datcapabilityresult call MSGGET '${get:supportedcaps.value}' '${get:g_querysupport}' g_datcapabilityresult call MSGGETCURRENT '${get:supportedcaps.value}' '${get:g_querysupport}' g_datcapabilityresult call MSGGETDEFAULT '${get:supportedcaps.value}' '${get:g_querysupport}' g_datcapabilityresult call MSGRESET '${get:supportedcaps.value}' '${get:g_querysupport}' g_datcapabilityresult call MSGSET '${get:supportedcaps.value}' '${get:g_querysupport}' g_datcapabilityresult goto MAIN.NEXTCAP ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Summary and cleanup... ; ; Did we pass? (do an extra check) :MAIN.PASS if '${get:g_datcapabilityresult}' != 'pass' goto MAIN.ERROR echo.passfail 'SUMMARY' 'pass' return 'pass' ; ; Ruh-roh... :MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'fail - ${sts:} ${ret:}' :MAIN.ERROR echo.passfail 'SUMMARY' 'fail' return 'fail' ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Function: MSGQUERYSUPPORT ; ; Arguments ; arg:1 - capability to check ; arg:2 - value returned ; arg:3 - only updated on fail ; ; Globals ; (none) ; ; Locals ; name - name of current test ; indent - amount to indent echo.passfail ; capability - MSG_QUERYSUPPORT on arg:1 ; ; Returns ; (none) ; :MSGQUERYSUPPORT ; ; Header... setlocal indent ' ' echo ' ' echo ' ${arg:1}' ; ; Check if it's deprecated... setlocal capabilitytable.flags '${get:${arg:1}.Flags}' ; ex: ICAP_PIXELTYPE.Flags if '${get:capabilitytable.flags}' ~contains 'deprecated' goto MSGQUERYSUPPORT.DEPRECATED ; ; Send the command... setlocal name 'Send MSG_QUERYSUPPORT' dsmentry src ds dg_control dat_capability msg_querysupport '${arg:1},0,0,0' if '${sts:}' != 'SUCCESS' goto MSGQUERYSUPPORT.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' setlocal capability '${ret:}' ; ; If TW_CAPABILITY.Cap is not #CAP#, then end with error setlocal name 'Verify Cap' setlocal failinfo ' (found ${getindex:capability:${get:TW_CAPABILITY.Cap}})' if '${getindex:capability:${get:TW_CAPABILITY.Cap}}' != '${arg:1}' goto MSGQUERYSUPPORT.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' ; ; If TW_CAPABILITY.ConType is not TWON_ONEVALUE, then end with error. setlocal name 'Verify ConType is TWON_ONEVALUE' setlocal failinfo ' (found ${getindex:capability:${get:TW_CAPABILITY.ConType}})' if '${getindex:capability:${get:TW_CAPABILITY.ConType}}' != 'TWON_ONEVALUE' goto MSGQUERYSUPPORT.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' ; ; If TW_ONEVALUE.ItemType is not TWTY_UINT32, then end with error ; SPECNOTE: spec says TWTY_INT32, test says TWTY_UINT32...spec wins... setlocal name 'Verify ItemType is TWTY_INT32' setlocal failinfo ' (found ${getindex:capability:${get:TW_ONEVALUE.ItemType}}' if '${getindex:capability:${get:TW_ONEVALUE.ItemType}}' != 'TWTY_INT32' goto MSGQUERYSUPPORT.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' ; ; If TWQC_GET, TWQC_GETCURRENT or TWQC_GETDEFAULT is detected, then ; all three must be present, if any are missing end with error setlocal name 'Verify GET, GETCURRENT, GETDEFAULT' setlocal failinfo ' (found ${getindex:capability:${get:TW_ONEVALUE.Item}}' if '${getindex:capability:${get:TW_ONEVALUE.Item}}' & '0x000D' == '0' goto MSGQUERYSUPPORT.VERIFYSET if '${getindex:capability:${get:TW_ONEVALUE.Item}}' & '0x000D' != '0x000D' goto MSGQUERYSUPPORT.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' ; ; If TWQC_RESET or TWQC_SET is detected, then both must be present, ; plus TWQC_GET, TWQC_GETCURRENT and TWQC_GETDEFAULT, if not true ; then end with error :MSGQUERYSUPPORT.VERIFYSET setlocal name 'Verify SET, RESET with GETs' setlocal failinfo ' (found ${getindex:capability:${get:TW_ONEVALUE.Item}}' if '${getindex:capability:${get:TW_ONEVALUE.Item}}' & '0x0012' == '0' goto MSGQUERYSUPPORT.PASS if '${getindex:capability:${get:TW_ONEVALUE.Item}}' & '0x001F' != '0x001F' goto MSGQUERYSUPPORT.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' goto MSGQUERYSUPPORT.PASS ; ; All done... :MSGQUERYSUPPORT.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'woof${get:failinfo}' setglobal '${arg:2}' '0' setglobal '${arg:3}' 'fail' return ; :MSGQUERYSUPPORT.PASS setglobal '${arg:2}' '${getindex:capability:${get:TW_ONEVALUE.Item}}' ; the value for this capability return ; :MSGQUERYSUPPORT.DEPRECATED echo.passfail '${get:indent}Note' 'deprecated (this is not a failure)' setglobal '${arg:2}' '0' ; the value for this capability return ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Function: MSGGET ; ; Arguments ; arg:1 - capability to check ; arg:2 - value from MSG_QUERYSUPPORT ; arg:3 - only updated on fail ; ; Globals ; (none) ; ; Locals ; name - name of current test ; indent - amount to indent echo.passfail ; capability - MSG_QUERYSUPPORT on arg:1 ; ; Returns ; (none) ; :MSGGET ; ; Skip if not supported (TWQC_GET)... if '${arg:2}' & '0x0001' == '0' goto MSGGET.SKIP setlocal indent ' ' ; ; Send the command... setlocal name 'Send MSG_GET' dsmentry src ds dg_control dat_capability msg_get '${arg:1},0,0,0' if '${sts:}' != 'SUCCESS' goto MSGGET.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' setlocal capability '${ret:}' ; ; If TW_CAPABILITY.Cap is not #CAP#, then end with error setlocal name 'Verify Cap' if '${getindex:capability:${get:TW_CAPABILITY.Cap}}' != '${arg:1}' goto MSGGET.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' ; ; If the value of TW_CAPABILITY.ConType doesn’t match the Specification’s ; MSG_GET container for this capability, then end with error setlocal name 'Verify ConType contains ${get:${arg:1}.ConType}' if '${get:${arg:1}.ConType}' !~contains '${getindex:capability:${get:TW_CAPABILITY.ConType}}' goto MSGGET.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' ; ; If container’s ItemType doesn’t match the Specification’s ItemType for ; this capability, then end with error. Note that the index for ItemType ; is the same for all containers, so it doesn't matter which one we use ; to check this... setlocal name 'Verify ItemType contains ${get:${arg:1}.ItemType}' if '${get:${arg:1}.ItemType}' !~contains '${getindex:capability:${get:TW_ONEVALUE.ItemType}}' goto MSGGET.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' ; ; All done... goto MSGGET.PASS :MSGGET.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'fail' setglobal '${arg:3}' 'fail' return :MSGGET.SKIP return :MSGGET.PASS return ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Function: MSGGETCURRENT ; ; Arguments ; arg:1 - capability to check ; arg:2 - value from MSG_QUERYSUPPORT ; arg:3 - only updated on fail ; ; Globals ; (none) ; ; Locals ; name - name of current test ; indent - amount to indent echo.passfail ; capability - MSG_QUERYSUPPORT on arg:1 ; ; Returns ; (none) ; :MSGGETCURRENT ; ; Skip if not supported (TWQC_GETCURRENT)... if '${arg:2}' & '0x0008' == '0' goto MSGGETCURRENT.SKIP setlocal indent ' ' ; ; Send the command... setlocal name 'Send MSG_GETCURRENT' dsmentry src ds dg_control dat_capability msg_getcurrent '${arg:1},0,0,0' if '${sts:}' != 'SUCCESS' goto MSGGETCURRENT.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' setlocal capability '${ret:}' ; ; If TW_CAPABILITY.Cap is not #CAP#, then end with error setlocal name 'Verify Cap' if '${getindex:capability:${get:TW_CAPABILITY.Cap}}' != '${arg:1}' goto MSGGETCURRENT.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' ; ; If the TW_CAPABILITY.ConType for MSG_GET was TWON_ENUMERATION, TWON_ONEVALUE ; or TWON_RANGE, then the TW_CAPABILITY.ConType for MSG_GETCURRENT must be ; TWTY_ONEVALUE, if not then end with error ; SPECNOTE: we're testing for array, which gives us the same result... if '${get:${arg:1}.ConType}' contains 'TWON_ARRAY' goto MSGGETCURRENT.ARRAY setlocal name 'Verify ConType contains TWON_ONEVALUE' if '${getindex:capability:${get:TW_CAPABILITY.ConType}}' != 'TWON_ONEVALUE' goto MSGGETCURRENT.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' goto MSGGETCURRENT.ITEMTYPE :MSGGETCURRENT.ARRAY setlocal name 'Verify ConType contains TWON_ARRAY' if '${getindex:capability:${get:TW_CAPABILITY.ConType}}' != 'TWON_ARRAY' goto MSGGETCURRENT.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' ; ; If container’s ItemType doesn’t match the Specification’s ItemType for ; this capability, then end with error. Note that the index for ItemType ; is the same for all containers, so it doesn't matter which one we use ; to check this... :MSGGETCURRENT.ITEMTYPE setlocal name 'Verify ItemType contains ${get:${arg:1}.ItemType}' if '${get:${arg:1}.ItemType}' !~contains '${getindex:capability:${get:TW_ONEVALUE.ItemType}}' goto MSGGETCURRENT.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' ; ; All done... goto MSGGETCURRENT.PASS :MSGGETCURRENT.ERROR.ECHOPASSFAIL echo.passfail ' ${get:name}' 'fail' setglobal '${arg:3}' 'fail' return :MSGGETCURRENT.SKIP return :MSGGETCURRENT.PASS return ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Function: MSGGETDEFAULT ; ; Arguments ; arg:1 - capability to check ; arg:2 - value from MSG_QUERYSUPPORT ; arg:3 - only updated on fail ; ; Globals ; (none) ; ; Locals ; name - name of current test ; indent - amount to indent echo.passfail ; capability - MSG_QUERYSUPPORT on arg:1 ; ; Returns ; (none) ; :MSGGETDEFAULT ; ; Skip if not supported (TWQC_GETDEFAULT)... if '${arg:2}' & '0x0004' == '0' goto MSGGETDEFAULT.SKIP setlocal indent ' ' ; ; Send the command... setlocal name 'Send MSG_GETDEFAULT' dsmentry src ds dg_control dat_capability msg_getdefault '${arg:1},0,0,0' if '${sts:}' != 'SUCCESS' goto MSGGETDEFAULT.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' setlocal capability '${ret:}' ; ; If TW_CAPABILITY.Cap is not #CAP#, then end with error setlocal name 'Verify Cap' if '${getindex:capability:${get:TW_CAPABILITY.Cap}}' != '${arg:1}' goto MSGGETDEFAULT.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' ; ; If the TW_CAPABILITY.ConType for MSG_GET was TWON_ENUMERATION, TWON_ONEVALUE ; or TWON_RANGE, then the TW_CAPABILITY.ConType for MSG_GETDEFAULT must be ; TWTY_ONEVALUE, if not then end with error ; SPECNOTE: we're testing for array, which gives us the same result... if '${get:${arg:1}.ConType}' contains 'TWON_ARRAY' goto MSGGETDEFAULT.ARRAY setlocal name 'Verify ConType contains TWON_ONEVALUE' if '${getindex:capability:${get:TW_CAPABILITY.ConType}}' != 'TWON_ONEVALUE' goto MSGGETDEFAULT.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' goto MSGGETDEFAULT.ITEMTYPE :MSGGETDEFAULT.ARRAY setlocal name 'Verify ConType contains TWON_ARRAY' if '${getindex:capability:${get:TW_CAPABILITY.ConType}}' != 'TWON_ARRAY' goto MSGGETDEFAULT.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' ; ; If container’s ItemType doesn’t match the Specification’s ItemType for ; this capability, then end with error. Note that the index for ItemType ; is the same for all containers, so it doesn't matter which one we use ; to check this... :MSGGETDEFAULT.ITEMTYPE setlocal name 'Verify ItemType contains ${get:${arg:1}.ItemType}' if '${get:${arg:1}.ItemType}' !~contains '${getindex:capability:${get:TW_ONEVALUE.ItemType}}' goto MSGGETDEFAULT.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' ; ; All done... goto MSGGETDEFAULT.PASS :MSGGETDEFAULT.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'fail' setglobal '${arg:3}' 'fail' return :MSGGETDEFAULT.SKIP return :MSGGETDEFAULT.PASS return ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Function: MSGRESET ; ; Arguments ; arg:1 - capability to check ; arg:2 - value from MSG_QUERYSUPPORT ; arg:3 - only updated on fail ; ; Globals ; (none) ; ; Locals ; name - name of current test ; indent - amount to indent echo.passfail ; capability - MSG_QUERYSUPPORT on arg:1 ; ; Returns ; (none) ; :MSGRESET ; ; Skip if not supported (TWQC_RESET)... if '${arg:2}' & '0x0010' == '0' goto MSGRESET.SKIP setlocal indent ' ' ; ; Send the command... setlocal name 'Send MSG_RESET' dsmentry src ds dg_control dat_capability msg_reset '${arg:1},0,0,0' if '${sts:}' != 'SUCCESS' goto MSGRESET.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' setlocal capability '${ret:}' ; ; If TW_CAPABILITY.Cap is not #CAP#, then end with error setlocal name 'Verify Cap' if '${getindex:capability:${get:TW_CAPABILITY.Cap}}' != '${arg:1}' goto MSGRESET.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' ; ; If the TW_CAPABILITY.ConType for MSG_GET was TWON_ENUMERATION, TWON_ONEVALUE ; or TWON_RANGE, then the TW_CAPABILITY.ConType for MSG_GETDEFAULT must be ; TWTY_ONEVALUE, if not then end with error ; SPECNOTE: the test implies that the MSG_GET container should returned, this is wrong... ; SPECNOTE: we're testing for array, which gives us the same result... if '${get:${arg:1}.ConType}' contains 'TWON_ARRAY' goto MSGRESET.ARRAY setlocal name 'Verify ConType contains TWON_ONEVALUE' if '${getindex:capability:${get:TW_CAPABILITY.ConType}}' != 'TWON_ONEVALUE' goto MSGRESET.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' goto MSGRESET.ITEMTYPE :MSGRESET.ARRAY setlocal name 'Verify ConType contains TWON_ARRAY' if '${getindex:capability:${get:TW_CAPABILITY.ConType}}' != 'TWON_ARRAY' goto MSGRESET.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' ; ; If container’s ItemType doesn’t match the Specification’s ItemType for ; this capability, then end with error. Note that the index for ItemType ; is the same for all containers, so it doesn't matter which one we use ; to check this... :MSGRESET.ITEMTYPE setlocal name 'Verify ItemType contains ${get:${arg:1}.ItemType}' if '${get:${arg:1}.ItemType}' !~contains '${getindex:capability:${get:TW_ONEVALUE.ItemType}}' goto MSGRESET.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' ; ; All done... goto MSGRESET.PASS :MSGRESET.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'fail' call RESTORECAPABILITY '${arg:1}' setglobal '${arg:3}' 'fail' return :MSGRESET.SKIP return :MSGRESET.PASS call RESTORECAPABILITY '${arg:1}' return ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Function: MSGSET ; First we're going to do a MSG_GET followed by a MSG_SET with either a TW_ARRAY or a ; TW_ONEVALUE, as indicated by the spec. Note that prior to 2.4 MSG_SET allowed one ; to send any container. For the second round we do a MSG_GETCURRENT and set with that ; value, which also must be a TW_ARRAY or TW_ONEVALUE. ; ; Arguments ; arg:1 - capability to check ; arg:2 - value from MSG_QUERYSUPPORT ; arg:3 - only updated on fail ; ; Globals ; (none) ; ; Locals ; name - name of current test ; indent - amount to indent echo.passfail ; capability - MSG_QUERYSUPPORT on arg:1 ; ; Returns ; (none) ; :MSGSET ; ; Skip if not supported (TWQC_SET)... if '${arg:2}' & '0x0002' == '0' goto MSGSET.SKIP if '${arg:3}' != 'pass' goto MSGSET.SKIP setlocal indent ' ' ; ; Explain what's going on... setlocal name 'Test MSG_SET' echo.passfail '${get:indent}${get:name}' 'pass' ; ; GET -> SET, and check they match with a final GET ; We'll accept SUCCESS or CHECKSTATUS setlocal name 'Send MSG_GET' dsmentry src ds dg_control dat_capability msg_get '${arg:1},0,0,0' if '${sts:}' != 'SUCCESS' goto MSGSET.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' setlocal capability '${ret:}' setlocal name 'Send MSG_SET with that GET' if '${getindex:capability:${get:TW_CAPABILITY.ConType}}' == 'TWON_ONEVALUE' goto MSGSET.SET ; ready to go as-is if '${getindex:capability:${get:TW_CAPABILITY.ConType}}' == 'TWON_ARRAY' goto MSGSET.SET ; ready to go as-is if '${getindex:capability:${get:TW_CAPABILITY.ConType}}' == 'TWON_RANGE' goto MSGSET.SETRANGE ; the rest must convert to TW_ONEVALUE ; increment currentindex '${get:TW_ENUMERATION.ItemList}' '${getindex:capability:${get:TW_ENUMERATION.CurrentIndex}}' setlocal currentvalue '${getindex:capability:${get:currentindex}}' if '${get:currentvalue}' contains ',' goto MSGSET.NEEDQUOTES ; if the data has a comma in it, we're going to need quotes ; setlocal capability '${getindex:capability:${get:TW_CAPABILITY.Cap}},TWON_ONEVALUE,${getindex:capability:${get:TW_ENUMERATION.ItemType}},${get:currentvalue}' goto MSGSET.SET ; :MSGSET.NEEDQUOTES setlocal capability '${getindex:capability:${get:TW_CAPABILITY.Cap}},TWON_ONEVALUE,${getindex:capability:${get:TW_ENUMERATION.ItemType}},"${get:currentvalue}"' goto MSGSET.SET ; :MSGSET.SETRANGE setlocal capability '${getindex:capability:${get:TW_CAPABILITY.Cap}},TWON_ONEVALUE,${getindex:capability:${get:TW_RANGE.ItemType}},${getindex:capability:${get:TW_RANGE.CurrentValue}}' ; :MSGSET.SET dsmentry src ds dg_control dat_capability msg_set '${get:capability}' if '/CHECKSTATUS/SUCCESS/' !~contains '/${sts:}/' goto MSGSET.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' setlocal name 'Send MSG_GETCURRENTpability msg_getcurrent '${arg:1},0,0,0' setlocal value '${ret:}' if '${sts:}' != 'SUCCESS' goto MSGSET.ERROR.ECHOPASSFAIL if '${get:value}' != '${get:capability}' goto MSGSET.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' ; ; GETGURRENT -> SET, and check they match with a final GETCURRENT setlocal name 'Send MSG_GETCURRENT' dsmentry src ds dg_control dat_capability msg_getcurrent '${arg:1},0,0,0' if '${sts:}' != 'SUCCESS' goto MSGSET.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' setlocal capability '${ret:}' setlocal name 'Send MSG_SET with that GETCURRENT' dsmentry src ds dg_control dat_capability msg_set '${get:capability}' if '${sts:}' != 'SUCCESS' goto MSGSET.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' setlocal name 'Send MSG_GETCURRENT to confirm MSG_SET' dsmentry src ds dg_control dat_capability msg_getcurrent '${arg:1},0,0,0' setlocal value '${ret:}' if '${sts:}' != 'SUCCESS' goto MSGSET.ERROR.ECHOPASSFAIL if '${get:value}' != '${get:capability}' goto MSGSET.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' ; ; GETDEFAULT -> SET, and check they match with a final GETCURRENT setlocal name 'Send MSG_GETDEFAULT' dsmentry src ds dg_control dat_capability msg_getdefault '${arg:1},0,0,0' if '${sts:}' != 'SUCCESS' goto MSGSET.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' setlocal capability '${ret:}' setlocal name 'Send MSG_SET with that GETDEFAULT' dsmentry src ds dg_control dat_capability msg_set '${get:capability}' if '${sts:}' != 'SUCCESS' goto MSGSET.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' setlocal name 'Send MSG_GETCURRENT to confirm MSG_SET' dsmentry src ds dg_control dat_capability msg_getcurrent '${arg:1},0,0,0' setlocal value '${ret:}' if '${sts:}' != 'SUCCESS' goto MSGSET.ERROR.ECHOPASSFAIL if '${get:value}' != '${get:capability}' goto MSGSET.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' ; ; RESET -> SET, and check they match with a final GETCURRENT setlocal name 'Send MSG_RESET' dsmentry src ds dg_control dat_capability msg_reset '${arg:1},0,0,0' if '${sts:}' != 'SUCCESS' goto MSGSET.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' setlocal capability '${ret:}' setlocal name 'Send MSG_SET with that RESET' dsmentry src ds dg_control dat_capability msg_set '${get:capability}' if '${sts:}' != 'SUCCESS' goto MSGSET.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' setlocal name 'Send MSG_GETCURRENT to confirm MSG_SET' dsmentry src ds dg_control dat_capability msg_getcurrent '${arg:1},0,0,0' setlocal value '${ret:}' if '${sts:}' != 'SUCCESS' goto MSGSET.ERROR.ECHOPASSFAIL if '${get:value}' != '${get:capability}' goto MSGSET.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' ; ; All done... goto MSGSET.PASS :MSGSET.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'fail ${sts:} <${get:capability}> <${get:value}>' call RESTORECAPABILITY '${arg:1}' setglobal '${arg:3}' 'fail' return ; :MSGSET.SKIP return ; :MSGSET.PASS call RESTORECAPABILITY '${arg:1}' return ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Function: ENABLECAPABILITIES ; Turn on stuff that we find in the list, we don't care if it fails, ; we'll keep on going... ; ; Arguments ; arg:1 - supportedcaps ; ; Globals ; (none) ; ; Locals ; (none) ; ; Returns ; (none) ; :ENABLECAPABILITIES setlocal indent ' ' ; ; CAP_PRINTERENABLED :ENABLECAPABILITIES.CAP_PRINTERENABLED if '${arg:1}' !~contains 'CAP_PRINTERENABLED' goto ENABLECAPABILITIES.ICAP_BARCODEDETECTIONENABLED dsmentry src ds dg_control dat_capability msg_set 'CAP_PRINTERENABLED,TWON_ONEVALUE,TWTY_BOOL,TRUE' if '${sts:}' != 'SUCCESS' goto ENABLECAPABILITIES.CAP_PRINTERENABLED.ECHOPASSFAIL echo.passfail '${get:indent}Enable CAP_PRINTERENABLED' 'pass' goto ENABLECAPABILITIES.ICAP_BARCODEDETECTIONENABLED :ENABLECAPABILITIES.CAP_PRINTERENABLED.ECHOPASSFAIL echo.passfail '${get:indent}Enable CAP_PRINTERENABLED' 'fail (but we won't fail on it here)' ; ; ICAP_BARCODEDETECTIONENABLED :ENABLECAPABILITIES.ICAP_BARCODEDETECTIONENABLED if '${arg:1}' !~contains 'ICAP_BARCODEDETECTIONENABLED' goto ENABLECAPABILITIES.ICAP_PATCHCODEDETECTIONENABLED dsmentry src ds dg_control dat_capability msg_set 'ICAP_BARCODEDETECTIONENABLED,TWON_ONEVALUE,TWTY_BOOL,TRUE' if '${sts:}' != 'SUCCESS' goto ENABLECAPABILITIES.ICAP_BARCODEDETECTIONENABLED.ECHOPASSFAIL echo.passfail '${get:indent}Enable ICAP_BARCODEDETECTIONENABLED' 'pass' goto ENABLECAPABILITIES.ICAP_PATCHCODEDETECTIONENABLED :ENABLECAPABILITIES.ICAP_BARCODEDETECTIONENABLED.ECHOPASSFAIL echo.passfail '${get:indent}Enable ICAP_BARCODEDETECTIONENABLED' 'fail (but we won't fail on it here)' ; ; ICAP_PATCHCODEDETECTIONENABLED :ENABLECAPABILITIES.ICAP_PATCHCODEDETECTIONENABLED if '${arg:1}' !~contains 'CAP_PATCHCODEDETECTIONENABLED' goto ENABLECAPABILITIES.DONE dsmentry src ds dg_control dat_capability msg_set 'ICAP_PATCHCODEDETECTIONENABLED,TWON_ONEVALUE,TWTY_BOOL,TRUE' if '${sts:}' != 'SUCCESS' goto ENABLECAPABILITIES.ICAP_PATCHCODEDETECTIONENABLED.ECHOPASSFAIL echo.passfail '${get:indent}Enable CAP_PATCHCODEDETECTIONENABLED' 'pass' goto ENABLECAPABILITIES.DONE :ENABLECAPABILITIES.ICAP_PATCHCODEDETECTIONENABLED.ECHOPASSFAIL echo.passfail '${get:indent}Enable CAP_PATCHCODEDETECTIONENABLED' 'fail (but we won't fail on it here)' ; ; All done... :ENABLECAPABILITIES.DONE return ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Function: RESTORECAPABILITY ; If we recognize it and need to maintain it, restore it. Note that to get into ; this function we're assuming the capability exists, so it's okay to set it. ; SPECNOTE: the concept of restoring isn't described in the tests ; ; Arguments ; arg:1 - the current capability ; ; Globals ; g_pixeltype.value - using it to make life easier ; ; Locals ; indent - amount to indent echo.passfail ; ; Returns ; (none) ; :RESTORECAPABILITY setlocal indent ' ' if '${arg:1}' == 'CAP_PRINTERENABLED' goto RESTORECAPABILITY.CAP_PRINTERENABLED if '${arg:1}' == 'ICAP_BARCODEDETECTIONENABLED' goto RESTORECAPABILITY.ICAP_BARCODEDETECTIONENABLED if '${arg:1}' == 'ICAP_PATCHCODEDETECTIONENABLED' goto RESTORECAPABILITY.ICAP_PATCHCODEDETECTIONENABLED if '${arg:1}' == 'ICAP_PIXELTYPE' goto RESTORECAPABILITY.ICAP_PIXELTYPE return ; ; CAP_PRINTERENABLED :RESTORECAPABILITY.CAP_PRINTERENABLED dsmentry src ds dg_control dat_capability msg_set 'CAP_PRINTERENABLED,TWON_ONEVALUE,TWTY_BOOL,TRUE' if '${sts:}' != 'SUCCESS' goto RESTORECAPABILITY.CAP_PRINTERENABLED.ECHOPASSFAIL echo.passfail '${get:indent}Restore CAP_PRINTERENABLED value to TRUE' 'pass' return :RESTORECAPABILITY.CAP_PRINTERENABLED.ECHOPASSFAIL echo.passfail '${get:indent}Restore CAP_PRINTERENABLED value to TRUE' 'fail (but we won't fail on it here)' return ; ; ICAP_BARCODEDETECTIONENABLED :RESTORECAPABILITY.ICAP_BARCODEDETECTIONENABLED dsmentry src ds dg_control dat_capability msg_set 'ICAP_BARCODEDETECTIONENABLED,TWON_ONEVALUE,TWTY_UINT16,TRUE' if '${sts:}' != 'SUCCESS' goto RESTORECAPABILITY.ICAP_BARCODEDETECTIONENABLED.ECHOPASSFAIL echo.passfail '${get:indent}Restore ICAP_BARCODEDETECTIONENABLED value to TRUE' 'pass' return :RESTORECAPABILITY.ICAP_BARCODEDETECTIONENABLED.ECHOPASSFAIL echo.passfail '${get:indent}Restore ICAP_BARCODEDETECTIONENABLED value to TRUE' 'fail (but we won't fail on it here)' return ; ; ICAP_PATCHCODEDETECTIONENABLED :RESTORECAPABILITY.ICAP_PATCHCODEDETECTIONENABLED dsmentry src ds dg_control dat_capability msg_set 'ICAP_PATCHCODEDETECTIONENABLED,TWON_ONEVALUE,TWTY_UINT16,TRUE' if '${sts:}' != 'SUCCESS' goto RESTORECAPABILITY.ICAP_PATCHCODEDETECTIONENABLED.ECHOPASSFAIL echo.passfail '${get:indent}Restore ICAP_PATCHCODEDETECTIONENABLED value to TRUE' 'pass' return :RESTORECAPABILITY.ICAP_PATCHCODEDETECTIONENABLED.ECHOPASSFAIL echo.passfail '${get:indent}Restore ICAP_PATCHCODEDETECTIONENABLED value to TRUE' 'fail (but we won't fail on it here)' return ; ; ICAP_PIXELTYPE :RESTORECAPABILITY.ICAP_PIXELTYPE dsmentry src ds dg_control dat_capability msg_set 'ICAP_PIXELTYPE,TWON_ONEVALUE,TWTY_UINT16,${get:g_pixeltype.value}' if '${sts:}' != 'SUCCESS' goto RESTORECAPABILITY.ICAP_PIXELTYPE.ECHOPASSFAIL echo.passfail '${get:indent}Restore ICAP_PIXELTYPE value to ${get:g_pixeltype.value}' 'pass' return :RESTORECAPABILITY.ICAP_PIXELTYPE.ECHOPASSFAIL echo.passfail '${get:indent}Restore ICAP_PIXELTYPE value to ${get:g_pixeltype.value}' 'fail (but we won't fail on it here)' return ================================================ FILE: twaincs/source/twaincscert/source/data/certification/010 - TWAIN Standard Capability Tests/ICAP_PIXELTYPE.tc ================================================ ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; ICAP_PIXELTYPE/ICAP_BITDEPTH ; Confirm Basic Negotiation with ICAP_PIXELTYPE/ICAP_BITDEPTH ; ; Arguments ; arg:1 - TW_IDENTITY.ProductName of scanner to test ; ; Globals ; (none) ; ; Locals ; name - current test being done ; bitdepth - data from MSG_GET for ICAP_BITDEPTH ; ; Returns ; pass or fail ; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Initialize... ; echo.titletest 'ICAP_PIXELTYPE/ICAP_BITDEPTH' setlocal bitdepth '' ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; TWPT_BW MSG_SET ; If result is not TWRC_SUCCESS, then proceed to the TWPT_GRAY test ; setlocal name 'TWPT_BW MSG_SET' dsmentry src ds dg_control dat_capability msg_set 'ICAP_PIXELTYPE,TWON_ONEVALUE,TWTY_UINT16,TWPT_BW' if '${sts:}' != 'SUCCESS' goto MAIN.TWPTGRAY echo.passfail '${get:name}' 'pass' ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; TWPT_BW MSG_GET ICAP_BITDEPTH ; setlocal name 'TWPT_BW MSG_GET ICAP_BITDEPTH' dsmentry src ds dg_control dat_capability msg_get 'ICAP_BITDEPTH,0,0,0' if '${sts:}' != 'SUCCESS' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:name}' 'pass' setlocal bitdepth '${ret:}' ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; If TW_CAPABILITY.ConType is not TWON_ENUMERATION, then proceed to the TWPT_RGB test below ; SPECNOTE: well, this is wrong, goto TWPT_GRAY ; setlocal name 'TWPT_BW TW_CAPABILITY.ConType is TWON_ENUMERATION' if '${getindex:bitdepth:${get:TW_CAPABILITY.ConType}}' != 'TWON_ENUMERATION' goto MAIN.TWPTGRAY echo.passfail '${get:name}' 'pass' ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; If TW_ENUMERATION.ItemType is not TWTY_UINT16, then end with error ; setlocal name 'TWPT_BW TW_ENUMERATION.ItemType is TWTY_UINT16' if '${getindex:bitdepth:${get:TW_ENUMERATION.ItemType}}' != 'TWTY_UINT16' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:name}' 'pass' ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; If the TW_ENUMERATION.ItemList includes a value of 8 or 24, then end with error ; setlocal name 'TWPT_BW TW_ENUMERATION does not contain 8 or 24' call CHECKENUMERATION '${get:bitdepth}' '8' '24' if '${ret:}' == 'pass' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:name}' 'pass' ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; TWPT_GRAY MSG_SET ; If result is not TWRC_SUCCESS, then proceed to the TWPT_RGB test ; :MAIN.TWPTGRAY setlocal name 'TWPT_GRAY MSG_SET' dsmentry src ds dg_control dat_capability msg_set 'ICAP_PIXELTYPE,TWON_ONEVALUE,TWTY_UINT16,TWPT_GRAY' if '${sts:}' != 'SUCCESS' goto MAIN.TWPTRGB echo.passfail '${get:name}' 'pass' ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; TWPT_GRAY MSG_GET ICAP_BITDEPTH ; setlocal name 'TWPT_GRAY MSG_GET ICAP_BITDEPTH' dsmentry src ds dg_control dat_capability msg_get 'ICAP_BITDEPTH,0,0,0' if '${sts:}' != 'SUCCESS' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:name}' 'pass' setlocal bitdepth '${ret:}' ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; If TW_CAPABILITY.ConType is not TWON_ENUMERATION, then proceed to the TWPT_RGB test below ; setlocal name 'TWPT_GRAY TW_CAPABILITY.ConType is TWON_ENUMERATION' if '${getindex:bitdepth:${get:TW_CAPABILITY.ConType}}' != 'TWON_ENUMERATION' goto MAIN.TWPTRGB echo.passfail '${get:name}' 'pass' ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; If TW_ENUMERATION.ItemType is not TWTY_UINT16, then end with error ; setlocal name 'TWPT_GRAY TW_ENUMERATION.ItemType is TWTY_UINT16' if '${getindex:bitdepth:${get:TW_ENUMERATION.ItemType}}' != 'TWTY_UINT16' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:name}' 'pass' ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; If the TW_ENUMERATION.ItemList includes a value of 1 or 24, then end with error ; setlocal name 'TWPT_GRAY TW_ENUMERATION does not contain 1 or 24' call CHECKENUMERATION '${get:bitdepth}' '1' '24' if '${ret:}' == 'pass' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:name}' 'pass' ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; TWPT_RGB MSG_SET ; If result is not TWRC_SUCCESS, then pass ; :MAIN.TWPTRGB setlocal name 'TWPT_RGB MSG_SET' dsmentry src ds dg_control dat_capability msg_set 'ICAP_PIXELTYPE,TWON_ONEVALUE,TWTY_UINT16,TWPT_RGB' if '${sts:}' != 'SUCCESS' goto MAIN.PASS echo.passfail '${get:name}' 'pass' ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; TWPT_RGB MSG_GET ICAP_BITDEPTH ; setlocal name 'TWPT_RGB MSG_GET ICAP_BITDEPTH' dsmentry src ds dg_control dat_capability msg_get 'ICAP_BITDEPTH,0,0,0' if '${sts:}' != 'SUCCESS' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:name}' 'pass' setlocal bitdepth '${ret:}' ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; If TW_CAPABILITY.ConType is not TWON_ENUMERATION, then pass ; setlocal name 'TWPT_RGB TW_CAPABILITY.ConType is TWON_ENUMERATION' if '${getindex:bitdepth:${get:TW_CAPABILITY.ConType}}' != 'TWON_ENUMERATION' goto MAIN.PASS echo.passfail '${get:name}' 'pass' ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; If TW_ENUMERATION.ItemType is not TWTY_UINT16, then end with error ; setlocal name 'TWPT_RGB TW_ENUMERATION.ItemType is TWTY_UINT16' if '${getindex:bitdepth:${get:TW_ENUMERATION.ItemType}}' != 'TWTY_UINT16' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:name}' 'pass' ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; If the TW_ENUMERATION.ItemList includes a value of 1 or 8, then end with error ; setlocal name 'TWPT_RGB TW_ENUMERATION does not contain 1 or 8' call CHECKENUMERATION '${get:bitdepth}' '1' '8' if '${ret:}' == 'pass' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:name}' 'pass' ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Summary and cleanup... ; ; We passed... :MAIN.PASS echo.passfail 'SUMMARY' 'pass' return 'pass' ; ; Ruh-roh... :MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:name}' 'fail - ${sts:} ${ret:}' :MAIN.ERROR echo.passfail 'SUMMARY' 'fail' return 'fail' ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Function: Check Enumeration ; arg:1 - enumeration to check ; arg:2/n - values to check for ; returns: pass/fail ; :CHECKENUMERATION ; setlocal enum '${arg:1}' setlocal ee '5' :NEXTENUM increment ee '${get:ee}' if '${getindex:enum:${get:ee}}' == '' goto CHECKENUMERATION.FAIL setlocal aa '2' :NEXTARG if '${arg:${get:aa}}' == '' goto NEXTENUM if '${arg:${get:aa}}' == '${getindex:enum:${get:ee}}' goto CHECKENUMERATION.PASS increment aa '${get:aa}' goto NEXTARG :CHECKENUMERATION.FAIL return 'fail' :CHECKENUMERATION.PASS return 'pass' ================================================ FILE: twaincs/source/twaincscert/source/data/certification/010 - TWAIN Standard Capability Tests/ICAP_XFERMECH.tc ================================================ ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; ICAP_XFERMECH ; Confirm Basic Negotiation with ICAP_XFERMECH ; ; Arguments ; arg:1 - TW_IDENTITY.ProductName of scanner to test ; ; Globals ; (none) ; ; Locals ; name - current test being done ; xfermech - data from MSG_GET for ICAP_XFERMECH ; ; Returns ; pass or fail ; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Initialize... ; echo.titletest 'ICAP_XFERMECH' setlocal xfermech '' ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; MSG_GET ICAP_XFERMECH ; If result is not TWRC_SUCCESS, then end with error ; setlocal name 'MSG_GET' dsmentry src ds dg_control dat_capability msg_get 'ICAP_XFERMECH,0,0,0' if '${sts:}' != 'SUCCESS' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:name}' 'pass' setlocal xfermech '${ret:}' ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; If TW_CAPABILITY.Cap is not ICAP_XFERMECH, then end with error ; setlocal name 'TW_CAPABILITY.Cap is ICAP_XFERMECH' if '${getindex:xfermech:${get:TW_CAPABILITY.Cap}}' != 'ICAP_XFERMECH' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:name}' 'pass' ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; If TW_CAPABILITY.ConType is not TWON_ENUMERATION, then end with error ; setlocal name 'TW_CAPABILITY.ConType is TWON_ENUMERATION' if '${getindex:xfermech:${get:TW_CAPABILITY.ConType}}' != 'TWON_ENUMERATION' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:name}' 'pass' ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; If TW_ENUMERATION.ItemType is not TWTY_UINT16, then end with error ; setlocal name 'TW_ENUMERATION.ItemType is TWTY_UINT16' if '${getindex:xfermech:${get:TW_ENUMERATION.ItemType}}' != 'TWTY_UINT16' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:name}' 'pass' ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; If TW_ENUMERATION contains TWSX_NATIVE (0)... ; setlocal name 'TW_ENUMERATION contains TWSX_NATIVE' call CHECKENUMERATION '${get:xfermech}' '0' if '${ret:}' == 'pass' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:name}' 'pass' ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; If TW_ENUMERATION contains TWSX_MEMORY (2)... ; setlocal name 'TW_ENUMERATION contains TWSX_MEMORY' call CHECKENUMERATION '${get:xfermech}' '2' if '${ret:}' == 'pass' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:name}' 'pass' ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Summary and cleanup... ; ; We passed... :MAIN.PASS echo.passfail 'SUMMARY' 'pass' return 'pass' ; ; Ruh-roh... :MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:name}' 'fail - ${sts:} ${ret:}' :MAIN.ERROR echo.passfail 'SUMMARY' 'fail' return 'fail' ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Function: Check Enumeration ; arg:1 - enumeration to check ; arg:2/n - values to check for ; returns: pass/fail ; :CHECKENUMERATION ; setlocal enum '${arg:1}' setlocal ee '5' :NEXTENUM increment ee '${get:ee}' if '${getindex:enum:${get:ee}}' == '' goto CHECKENUMERATION.FAIL setlocal aa '2' :NEXTARG if '${arg:${get:aa}}' == '' goto NEXTENUM if '${arg:${get:aa}}' == '${getindex:enum:${get:ee}}' goto CHECKENUMERATION.PASS increment aa '${get:aa}' goto NEXTARG :CHECKENUMERATION.FAIL return 'fail' :CHECKENUMERATION.PASS return 'pass' ================================================ FILE: twaincs/source/twaincscert/source/data/certification/020 - Vendor Custom Capability Tests/Certification.tc ================================================ ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Vendor Custom Capability Tests ; Test for capabilties in the custom space 0x8000 and higher ; ; Arguments ; arg:1 - TW_IDENTITY.ProductName of scanner to test ; arg:2 - global to set on fail ; ; Globals ; (none) ; ; Locals ; twidentity.productname - product name of scanner to test ; certifyresult - global to set on fail ; ; Returns ; (none) ; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Initialize stuff, load tables if not already done for us... ; echo.titlesuite 'Vendor Custom Capability Tests v1.0 23-Feb-2020' setlocal twidentity.productname '${arg:1}' setlocal certifyresult '${arg:2}' if '${get:TW_ARRAY.ItemType}' != '' goto MAIN.LOADTABLES.SKIP run '${folder:certification}/LoadTables' :MAIN.LOADTABLES.SKIP ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Run the tests... ; call CERTIFY '${folder:certification}/Opends' '${get:twidentity.productname}' '${get:certifyresult}' if '${get:${get:certifyresult}}' == 'fail' goto MAIN.CLOSEDS call CERTIFY 'DAT_CAPABILITY' '${get:twidentity.productname}' '${get:certifyresult}' :MAIN.CLOSEDS call CERTIFY '${folder:certification}/Closeds' '${get:twidentity.productname}' '${get:certifyresult}' return ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Function: Certify ; arg:1 - script to run ; arg:2 - TW_IDENTITY.ProductName of scanner to test ; arg:3 - global value to update on fail ; returns: (none) ; :CERTIFY ; run '${arg:1}' '${arg:2}' if '${ret:}' != 'pass' goto CERTIFY.FAIL return 'pass' ; :CERTIFY.FAIL setglobal '${arg:3}' 'fail' return 'fail' ================================================ FILE: twaincs/source/twaincscert/source/data/certification/020 - Vendor Custom Capability Tests/DAT_CAPABILITY.tc ================================================ ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; DAT_CAPABILITY ; Exercise DAT_CAPABILITY for the vendor custom capabilities ; ; Arguments ; arg:1 - TW_IDENTITY.ProductName of scanner to test ; ; Globals ; g_datcapabilityresult - pass/fail for the entire test ; g_querysupport - numeric value of query support for a capability ; g_pixeltype.value - for restoring pixel type ; ; Locals ; name - current test being done ; indent - padding for echo.passfail ; ; pixeltype.itemlist - list of pixeltypes to check ; pixeltype.index - index of current pixeltype being checked ; pixeltype.value - current pixel type value for pixeltype.index ; ; supportedcaps - data from MSG_GET for CAP_SUPPORTEDCAPS ; supportedcaps.index - index of capability from supportedcaps ; supportedcaps.value - current cap value for supportedcaps.index ; ; Returns ; pass or fail ; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Initialize... ; echo.titletest 'DAT_CAPABILITY' setlocal indent '' setlocal pixeltype.itemlist 'TWPT_BW,TWPT_GRAY,TWPT_RGB' setlocal pixeltype.index '-1' setglobal g_datcapabilityresult 'pass' ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; MSG_RESETALL ; If return code is not TWRC_SUCCESS, end with an error ; setlocal name 'MSG_RESETALL' dsmentry src ds dg_control dat_capability msg_resetall '0,0,0,0' if '${sts:}' != 'SUCCESS' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Repeat this section for each enumerated value found inside of ICAP_PIXELTYPE, ; (testing is done for each value of ICAP_PIXELTYPE, to provide the best chance ; of exercising every available capability). Remember the pixeltype setting, ; because we have to restore it as part of the MSG_RESET and MSG_SET tests. ; :NEXTTWPT setlocal indent ' ' increment pixeltype.index '${get:pixeltype.index}' setglobal g_pixeltype.value '${getindex:pixeltype.itemlist:${get:pixeltype.index}}' if '${get:g_pixeltype.value}' != '' goto MAIN.TWPTSET goto MAIN.PASS :MAIN.TWPTSET dsmentry src ds dg_control dat_capability msg_set 'ICAP_PIXELTYPE,TWON_ONEVALUE,TWTY_UINT16,${get:g_pixeltype.value}' if '${sts:}' == 'SUCCESS' goto MAIN.TWPTCONTINUE echo.passfail '${get:indent}${get:g_pixeltype.value}' 'skip' goto NEXTTWPT :MAIN.TWPTCONTINUE echo.passfail '${get:indent}${get:g_pixeltype.value}' 'pass' ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Repeat this section for vendor custom array values found inside of ; CAP_SUPPORTEDCAPS (each vendor custom capability ID is referred to as #CAP# ; for the rest of this section) ; setlocal name 'CAP_SUPPORTEDCAPS MSG_GET' dsmentry src ds dg_control dat_capability msg_get 'CAP_SUPPORTEDCAPS,0,0,0' if '${sts:}' != 'SUCCESS' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' setlocal supportedcaps '${ret:}' ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Turn on capabilities that enable the use of other capabilities ; SPECNOTE: this isn't described in the tests, but it seems like a good idea ; call ENABLECAPABILITIES '${get:supportedcaps}' ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Grab a vendor custom capability from CAP_SUPPORTEDCAPS, we know it's ; vendor custom if it's a number. ; setlocal supportedcaps.index '${get:TW_ARRAY.ItemList}' increment supportedcaps.index '${get:supportedcaps.index}' -1 :NEXTCAP increment supportedcaps.index '${get:supportedcaps.index}' 1 setlocal supportedcaps.value '${getindex:supportedcaps:${get:supportedcaps.index}}' if '${get:supportedcaps.value}' == '' goto NEXTTWPT if '${get:supportedcaps.value}' !~contains '0x' goto NEXTCAP ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Perform these tests on each capability... ; SPECNOTE: because we're referencing the querysupport value we don't have to accept ; TWCC_CAPSEQERROR as a valid value, so it'll be an error just like everything else... ; call MSGQUERYSUPPORT '${get:supportedcaps.value}' g_querysupport g_datcapabilityresult call MSGGET '${get:supportedcaps.value}' '${get:g_querysupport}' g_datcapabilityresult call MSGGETCURRENT '${get:supportedcaps.value}' '${get:g_querysupport}' g_datcapabilityresult call MSGGETDEFAULT '${get:supportedcaps.value}' '${get:g_querysupport}' g_datcapabilityresult call MSGRESET '${get:supportedcaps.value}' '${get:g_querysupport}' g_datcapabilityresult call MSGSET '${get:supportedcaps.value}' '${get:g_querysupport}' g_datcapabilityresult goto NEXTCAP ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Summary and cleanup... ; ; Did we pass? (do an extra check) :MAIN.PASS if '${get:g_datcapabilityresult}' != 'pass' goto MAIN.ERROR echo.passfail 'SUMMARY' 'pass' return 'pass' ; ; Ruh-roh... :MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'fail - ${sts:} ${ret:}' :MAIN.ERROR echo.passfail 'SUMMARY' 'fail' return 'fail' ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Function: MSGQUERYSUPPORT ; ; Arguments ; arg:1 - capability to check ; arg:2 - value returned ; arg:3 - only updated on fail ; ; Globals ; (none) ; ; Locals ; name - name of current test ; indent - amount to indent echo.passfail ; capability - MSG_QUERYSUPPORT on arg:1 ; ; Returns ; (none) ; :MSGQUERYSUPPORT setlocal indent ' ' ; ; Send the command... echo ' ' echo ' ${arg:1}' setlocal name 'Send MSG_QUERYSUPPORT' dsmentry src ds dg_control dat_capability msg_querysupport '${arg:1},0,0,0' if '${sts:}' != 'SUCCESS' goto MSGQUERYSUPPORT.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' setlocal capability '${ret:}' ; ; If TW_CAPABILITY.Cap is not #CAP#, then end with error setlocal name 'Verify Cap' if '${getindex:capability:${get:TW_CAPABILITY.Cap}}' != '${arg:1}' goto MSGQUERYSUPPORT.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' ; ; If TW_CAPABILITY.ConType is not TWON_ONEVALUE, then end with error. setlocal name 'Verify ConType is TWON_ONEVALUE' if '${getindex:capability:${get:TW_CAPABILITY.ConType}}' != 'TWON_ONEVALUE' goto MSGQUERYSUPPORT.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' ; ; If TW_ONEVALUE.ItemType is not TWTY_UINT32, then end with error ; SPECNOTE: spec says TWTY_INT32, test says TWTY_UINT32...spec wins... setlocal name 'Verify ItemType is TWTY_INT32' if '${getindex:capability:${get:TW_ONEVALUE.ItemType}}' != 'TWTY_INT32' goto MSGQUERYSUPPORT.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' ; ; If TWQC_GET, TWQC_GETCURRENT or TWQC_GETDEFAULT is detected, then ; all three must be present, if any are missing end with error setlocal name 'Verify GET, GETCURRENT, GETDEFAULT' if '${getindex:capability:${get:TW_ONEVALUE.Item}}' & '0x000D' == '0' goto MSGQUERYSUPPORT.VERIFYSET if '${getindex:capability:${get:TW_ONEVALUE.Item}}' & '0x000D' != '0x000D' goto MSGQUERYSUPPORT.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' ; ; If TWQC_RESET or TWQC_SET is detected, then both must be present, ; plus TWQC_GET, TWQC_GETCURRENT and TWQC_GETDEFAULT, if not true ; then end with error :MSGQUERYSUPPORT.VERIFYSET setlocal name 'Verify SET, RESET with GETs' if '${getindex:capability:${get:TW_ONEVALUE.Item}}' & '0x0012' == '0' goto MSGQUERYSUPPORT.PASS if '${getindex:capability:${get:TW_ONEVALUE.Item}}' & '0x001F' != '0x001F' goto MSGQUERYSUPPORT.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' ; ; All done... goto MSGQUERYSUPPORT.PASS :MSGQUERYSUPPORT.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'fail' setglobal '${arg:2}' '0' setglobal '${arg:3}' 'fail' return :MSGQUERYSUPPORT.PASS setglobal '${arg:2}' '${getindex:capability:${get:TW_ONEVALUE.Item}}' return ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Function: MSGGET ; ; Arguments ; arg:1 - capability to check ; arg:2 - value from MSG_QUERYSUPPORT ; arg:3 - only updated on fail ; ; Globals ; (none) ; ; Locals ; name - name of current test ; indent - amount to indent echo.passfail ; capability - MSG_QUERYSUPPORT on arg:1 ; ; Returns ; (none) ; :MSGGET ; ; Skip if not supported (TWQC_GET)... if '${arg:2}' & '0x0001' == '0' goto MSGGET.SKIP setlocal indent ' ' ; ; Send the command... setlocal name 'Send MSG_GET' dsmentry src ds dg_control dat_capability msg_get '${arg:1},0,0,0' if '${sts:}' != 'SUCCESS' goto MSGGET.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' setlocal capability '${ret:}' ; ; If TW_CAPABILITY.Cap is not #CAP#, then end with error setlocal name 'Verify Cap' if '${getindex:capability:${get:TW_CAPABILITY.Cap}}' != '${arg:1}' goto MSGGET.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' ; ; All done... goto MSGGET.PASS :MSGGET.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'fail' setglobal '${arg:3}' 'fail' return :MSGGET.SKIP return :MSGGET.PASS return ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Function: MSGGETCURRENT ; ; Arguments ; arg:1 - capability to check ; arg:2 - value from MSG_QUERYSUPPORT ; arg:3 - only updated on fail ; ; Globals ; (none) ; ; Locals ; name - name of current test ; indent - amount to indent echo.passfail ; capability - MSG_QUERYSUPPORT on arg:1 ; ; Returns ; (none) ; :MSGGETCURRENT ; ; Skip if not supported (TWQC_GETCURRENT)... if '${arg:2}' & '0x0008' == '0' goto MSGGETCURRENT.SKIP setlocal indent ' ' ; ; Send the command... setlocal name 'Send MSG_GETCURRENT' dsmentry src ds dg_control dat_capability msg_getcurrent '${arg:1},0,0,0' if '${sts:}' != 'SUCCESS' goto MSGGETCURRENT.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' setlocal capability '${ret:}' ; ; If TW_CAPABILITY.Cap is not #CAP#, then end with error setlocal name 'Verify Cap' if '${getindex:capability:${get:TW_CAPABILITY.Cap}}' != '${arg:1}' goto MSGGETCURRENT.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' ; ; All done... goto MSGGETCURRENT.PASS :MSGGETCURRENT.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'fail' setglobal '${arg:3}' 'fail' return :MSGGETCURRENT.SKIP return :MSGGETCURRENT.PASS return ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Function: MSGGETDEFAULT ; ; Arguments ; arg:1 - capability to check ; arg:2 - value from MSG_QUERYSUPPORT ; arg:3 - only updated on fail ; ; Globals ; (none) ; ; Locals ; name - name of current test ; indent - amount to indent echo.passfail ; capability - MSG_QUERYSUPPORT on arg:1 ; ; Returns ; (none) ; :MSGGETDEFAULT ; ; Skip if not supported (TWQC_GETDEFAULT)... if '${arg:2}' & '0x0004' == '0' goto MSGGETDEFAULT.SKIP setlocal indent ' ' ; ; Send the command... setlocal name 'Send MSG_GETDEFAULT' dsmentry src ds dg_control dat_capability msg_getdefault '${arg:1},0,0,0' if '${sts:}' != 'SUCCESS' goto MSGGETDEFAULT.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' setlocal capability '${ret:}' ; ; If TW_CAPABILITY.Cap is not #CAP#, then end with error setlocal name 'Verify Cap' if '${getindex:capability:${get:TW_CAPABILITY.Cap}}' != '${arg:1}' goto MSGGETDEFAULT.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' ; ; All done... goto MSGGETDEFAULT.PASS :MSGGETDEFAULT.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'fail' setglobal '${arg:3}' 'fail' return :MSGGETDEFAULT.SKIP return :MSGGETDEFAULT.PASS return ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Function: MSGRESET ; ; Arguments ; arg:1 - capability to check ; arg:2 - value from MSG_QUERYSUPPORT ; arg:3 - only updated on fail ; ; Globals ; (none) ; ; Locals ; name - name of current test ; indent - amount to indent echo.passfail ; capability - MSG_QUERYSUPPORT on arg:1 ; ; Returns ; (none) ; :MSGRESET ; ; Skip if not supported (TWQC_RESET)... if '${arg:2}' & '0x0010' == '0' goto MSGRESET.SKIP setlocal indent ' ' ; ; Send the command... setlocal name 'Send MSG_RESET' dsmentry src ds dg_control dat_capability msg_reset '${arg:1},0,0,0' if '${sts:}' != 'SUCCESS' goto MSGRESET.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' setlocal capability '${ret:}' ; ; If TW_CAPABILITY.Cap is not #CAP#, then end with error setlocal name 'Verify Cap' if '${getindex:capability:${get:TW_CAPABILITY.Cap}}' != '${arg:1}' goto MSGRESET.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' ; ; All done... goto MSGRESET.PASS :MSGRESET.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'fail' setglobal '${arg:3}' 'fail' return :MSGRESET.SKIP return :MSGRESET.PASS return ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Function: MSGSET ; ; Arguments ; arg:1 - capability to check ; arg:2 - value from MSG_QUERYSUPPORT ; arg:3 - only updated on fail ; ; Globals ; (none) ; ; Locals ; name - name of current test ; indent - amount to indent echo.passfail ; capability - MSG_QUERYSUPPORT on arg:1 ; capabilityrestore - value to restore when we're done ; ; Returns ; (none) ; :MSGSET ; ; Skip if not supported (TWQC_SET)... if '${arg:2}' & '0x0002' == '0' goto MSGSET.SKIP setlocal indent ' ' ; ; Explain what's going on... setlocal name 'Test MSG_SET' echo.passfail '${get:indent}${get:name}' 'pass' ; ; GET -> SET, and check they match with a final GET ; We'll accept SUCCESS or CHECKSTATUS setlocal name 'Send MSG_GET' dsmentry src ds dg_control dat_capability msg_get '${arg:1},0,0,0' if '${sts:}' != 'SUCCESS' goto MSGSET.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' setlocal capability '${ret:}' setlocal capabilityrestore '${ret:}' setlocal name 'Send MSG_SET with that GET' dsmentry src ds dg_control dat_capability msg_set '${get:capability}' if '/CHECKSTATUS/SUCCESS/' !~contains '/${sts:}/' goto MSGSET.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' setlocal name 'Send MSG_GET to confirm MSG_SET' dsmentry src ds dg_control dat_capability msg_get '${arg:1},0,0,0' setlocal value '${ret:}' if '${sts:}' != 'SUCCESS' goto MSGSET.ERROR.ECHOPASSFAIL if '${get:value}' != '${get:capability}' goto MSGSET.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' ; ; GETGURRENT -> SET, and check they match with a final GETCURRENT setlocal name 'Send MSG_GETCURRENT' dsmentry src ds dg_control dat_capability msg_getcurrent '${arg:1},0,0,0' if '${sts:}' != 'SUCCESS' goto MSGSET.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' setlocal capability '${ret:}' setlocal name 'Send MSG_SET with that GETCURRENT' dsmentry src ds dg_control dat_capability msg_set '${get:capability}' if '${sts:}' != 'SUCCESS' goto MSGSET.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' setlocal name 'Send MSG_GETCURRENT to confirm MSG_SET' dsmentry src ds dg_control dat_capability msg_getcurrent '${arg:1},0,0,0' setlocal value '${ret:}' if '${sts:}' != 'SUCCESS' goto MSGSET.ERROR.ECHOPASSFAIL if '${get:value}' != '${get:capability}' goto MSGSET.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' ; ; GETDEFAULT -> SET, and check they match with a final GETCURRENT setlocal name 'Send MSG_GETDEFAULT' dsmentry src ds dg_control dat_capability msg_getdefault '${arg:1},0,0,0' if '${sts:}' != 'SUCCESS' goto MSGSET.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' setlocal capability '${ret:}' setlocal name 'Send MSG_SET with that GETDEFAULT' dsmentry src ds dg_control dat_capability msg_set '${get:capability}' if '${sts:}' != 'SUCCESS' goto MSGSET.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' setlocal name 'Send MSG_GETCURRENT to confirm MSG_SET' dsmentry src ds dg_control dat_capability msg_getcurrent '${arg:1},0,0,0' setlocal value '${ret:}' if '${sts:}' != 'SUCCESS' goto MSGSET.ERROR.ECHOPASSFAIL if '${get:value}' != '${get:capability}' goto MSGSET.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' ; ; RESET -> SET, and check they match with a final GETCURRENT setlocal name 'Send MSG_RESET' dsmentry src ds dg_control dat_capability msg_reset '${arg:1},0,0,0' if '${sts:}' != 'SUCCESS' goto MSGSET.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' setlocal capability '${ret:}' setlocal name 'Send MSG_SET with that RESET' dsmentry src ds dg_control dat_capability msg_set '${get:capability}' if '${sts:}' != 'SUCCESS' goto MSGSET.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' setlocal name 'Send MSG_GETCURRENT to confirm MSG_SET' dsmentry src ds dg_control dat_capability msg_getcurrent '${arg:1},0,0,0' setlocal value '${ret:}' if '${sts:}' != 'SUCCESS' goto MSGSET.ERROR.ECHOPASSFAIL if '${get:value}' != '${get:capability}' goto MSGSET.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' ; ; Restore the setting when we came into this function... dsmentry src ds dg_control dat_capability msg_set '${get:capabilityrestore}' ; ; All done... goto MSGSET.PASS :MSGSET.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'fail ${sts:} <${get:capability}> <${get:value}>' setglobal '${arg:3}' 'fail' return :MSGSET.SKIP return :MSGSET.PASS return ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Function: ENABLECAPABILITIES ; Turn on stuff that we find in the list, we don't care if it fails, ; we'll keep on going... ; ; Arguments ; arg:1 - supportedcaps ; ; Globals ; (none) ; ; Locals ; (none) ; ; Returns ; (none) ; :ENABLECAPABILITIES setlocal indent ' ' ; ; CAP_PRINTERENABLED :ENABLECAPABILITIES.CAP_PRINTERENABLED if '${arg:1}' !~contains 'CAP_PRINTERENABLED' goto ENABLECAPABILITIES.ICAP_BARCODEDETECTIONENABLED dsmentry src ds dg_control dat_capability msg_set 'CAP_PRINTERENABLED,TWON_ONEVALUE,TWTY_BOOL,TRUE' if '${sts:}' != 'SUCCESS' goto ENABLECAPABILITIES.CAP_PRINTERENABLED.ECHOPASSFAIL echo.passfail '${get:indent}Enable CAP_PRINTERENABLED' 'pass' goto ENABLECAPABILITIES.ICAP_BARCODEDETECTIONENABLED :ENABLECAPABILITIES.CAP_PRINTERENABLED.ECHOPASSFAIL echo.passfail '${get:indent}Enable CAP_PRINTERENABLED' 'fail (but we won't fail on it here)' ; ; ICAP_BARCODEDETECTIONENABLED :ENABLECAPABILITIES.ICAP_BARCODEDETECTIONENABLED if '${arg:1}' !~contains 'ICAP_BARCODEDETECTIONENABLED' goto ENABLECAPABILITIES.ICAP_PATCHCODEDETECTIONENABLED dsmentry src ds dg_control dat_capability msg_set 'ICAP_BARCODEDETECTIONENABLED,TWON_ONEVALUE,TWTY_BOOL,TRUE' if '${sts:}' != 'SUCCESS' goto ENABLECAPABILITIES.ICAP_BARCODEDETECTIONENABLED.ECHOPASSFAIL echo.passfail '${get:indent}Enable ICAP_BARCODEDETECTIONENABLED' 'pass' goto ENABLECAPABILITIES.ICAP_PATCHCODEDETECTIONENABLED :ENABLECAPABILITIES.ICAP_BARCODEDETECTIONENABLED.ECHOPASSFAIL echo.passfail '${get:indent}Enable ICAP_BARCODEDETECTIONENABLED' 'fail (but we won't fail on it here)' ; ; ICAP_PATCHCODEDETECTIONENABLED :ENABLECAPABILITIES.ICAP_PATCHCODEDETECTIONENABLED if '${arg:1}' !~contains 'CAP_PATCHCODEDETECTIONENABLED' goto ENABLECAPABILITIES.DONE dsmentry src ds dg_control dat_capability msg_set 'ICAP_PATCHCODEDETECTIONENABLED,TWON_ONEVALUE,TWTY_BOOL,TRUE' if '${sts:}' != 'SUCCESS' goto ENABLECAPABILITIES.ICAP_PATCHCODEDETECTIONENABLED.ECHOPASSFAIL echo.passfail '${get:indent}Enable CAP_PATCHCODEDETECTIONENABLED' 'pass' goto ENABLECAPABILITIES.DONE :ENABLECAPABILITIES.ICAP_PATCHCODEDETECTIONENABLED.ECHOPASSFAIL echo.passfail '${get:indent}Enable CAP_PATCHCODEDETECTIONENABLED' 'fail (but we won't fail on it here)' ; ; All done... :ENABLECAPABILITIES.DONE return ================================================ FILE: twaincs/source/twaincscert/source/data/certification/030 - Status Return Tests/Certification.tc ================================================ ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Status Return Tests ; Check the TWRC/TWCC values for some situations... ; ; Arguments ; arg:1 - TW_IDENTITY.ProductName of scanner to test ; arg:2 - global to set on fail ; ; Globals ; g_localcertifyresult - global to report to caller on fail ; ; Locals ; twidentity.productname - product name of scanner to test ; ; Returns ; (none) ; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Initialize stuff, load tables if not already done for us... ; echo.titlesuite 'Status Return Tests v1.0 23-Feb-2020' setlocal twidentity.productname '${arg:1}' setglobal g_localcertifyresult 'pass' ; assume success if '${get:TW_ARRAY.ItemType}' != '' goto MAIN.LOADTABLES.SKIP run '${folder:certification}/LoadTables' :MAIN.LOADTABLES.SKIP ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Run the tests... ; call CERTIFY '${folder:certification}/Opends' '${get:twidentity.productname}' g_localcertifyresult embedded if '${get:g_localcertifyresult}' == 'fail' goto MAIN.CLOSEDS call CERTIFY 'Status Return Tests' '${get:twidentity.productname}' g_localcertifyresult :MAIN.CLOSEDS call CERTIFY '${folder:certification}/Closeds' '${get:twidentity.productname}' g_localcertifyresult embedded ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Summary and cleanup... ; ; Did we pass? if '${get:g_localcertifyresult}' != 'pass' goto MAIN.ERROR echo.passfail 'SUMMARY' 'pass' return 'pass' ; ; Ruh-roh... :MAIN.ERROR echo.passfail 'SUMMARY' 'fail' setglobal '${arg:2}' 'fail' return 'fail' ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Function: Certify ; arg:1 - script to run ; arg:2 - TW_IDENTITY.ProductName of scanner to test ; arg:3 - global value to update on fail ; arg:4 - embeded flag for open/close ; returns: (none) ; :CERTIFY ; run '${arg:1}' '${arg:2}' '${arg:4}' if '${ret:}' != 'pass' goto CERTIFY.FAIL return 'pass' ; :CERTIFY.FAIL setglobal '${arg:3}' 'fail' return 'fail' ================================================ FILE: twaincs/source/twaincscert/source/data/certification/030 - Status Return Tests/Status Return Tests.tc ================================================ ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Status Return Tests ; Confirm that the expected status return is reported by certain operations. ; ; Arguments ; arg:1 - TW_IDENTITY.ProductName of scanner to test ; arg:2 - global to set on fail ; ; Globals ; g_value - data return from dsmentry call ; ; Locals ; certifyresult - global to report back on fail ; ; Returns ; pass or fail ; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Initialize... ; setlocal certifyresult '${arg:2}' ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Prompt the user... ; if '${get:g_skipprompts}' != '' goto MAIN.SKIP.PROMPTS echo.prompt echo.prompt '*** DO NOT CLICK ON THE TWAIN USER INTERFACE WHEN IT COMES UP ***' echo.prompt 'We are checking that the driver works correctly in state 5.' echo.prompt 'When done the TWAIN user interface will exit on its own.' echo.prompt pause '(press the ENTER key when ready to continue)' echo.prompt :MAIN.SKIP.PROMPTS ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; DAT_IMAGELAYOUT ; Confirm that DAT_IMAGELAYOUT returns the correct status ; in various error conditions. We're doing tests in state 5 ; so we need the driver's user interface... ; call SENDANDCHECK SUCCESS '${get:certifyresult}' discard dg_control dat_userinterface msg_enabledsuionly '1,0' sleep 5000 ; give the ui time to come up, we want to make sure we're really in state 5 call SENDANDCHECK SUCCESS '${get:certifyresult}' g_value dg_image dat_imagelayout msg_get '0,0,0,0,0,0,0' call SENDANDCHECK SEQERROR '${get:certifyresult}' discard dg_image dat_imagelayout msg_set '${get:g_value}' call SENDANDCHECK SEQERROR '${get:certifyresult}' discard dg_image dat_imagelayout msg_reset '0,0,0,0,0,0,0' call SENDANDCHECK SUCCESS '${get:certifyresult}' discard dg_control dat_userinterface msg_disableds '0,0' ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; DAT_IMAGEMEMXFER ; Confirm that DAT_IMAGEMEMXFER returns the correct status ; in various error conditions. ; call SENDANDCHECK BADPROTOCOL '${get:certifyresult}' discard dg_image dat_imagememxfer msg_set '0,0,0,0,0,0,0,9,0,0' call SENDANDCHECK SEQERROR '${get:certifyresult}' discard dg_image dat_imagememxfer msg_get '0,0,0,0,0,0,0,9,0,0' ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; DAT_IMAGENATIVEXFER ; Confirm that DAT_IMAGENATIVEXFER returns the correct status ; in various error conditions. ; call SENDANDCHECK BADPROTOCOL '${get:certifyresult}' discard dg_image dat_imagenativexfer msg_set '0' call SENDANDCHECK SEQERROR '${get:certifyresult}' discard dg_image dat_imagenativexfer msg_get '0' ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; All done... ; return 'pass' ; caller figures out what really happened based on certifyresult... ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Function: SENDANDCHECK ; arg:1 - expected status ; arg:2 - status to return ; arg:3 - data to return ; arg:4 - DG to send ; arg:5 - DAT to send ; arg:6 - MSG to send ; arg:7 - TW_MEMREF to send ; returns: (none) ; :SENDANDCHECK dsmentry src ds '${arg:4}' '${arg:5}' '${arg:6}' '${arg:7}' if '${sts:}' != '${arg:1}' goto SENDANDCHECK.ERROR.ECHOPASSFAIL echo.passfail '${arg:5}/${arg:6} --> ${arg:1}' 'pass' setglobal '${arg:3}' '${ret:}' return :SENDANDCHECK.ERROR.ECHOPASSFAIL echo.passfail '${arg:5}/${arg:6} --> ${arg:1}' 'fail ${sts:} ${ret:}' setglobal '${arg:2}' 'fail' return ================================================ FILE: twaincs/source/twaincscert/source/data/certification/040 - Stress Tests/Certification.tc ================================================ ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Stress Tests ; Perform repeated open/close commands ; ; Arguments ; arg:1 - TW_IDENTITY.ProductName of scanner to test ; arg:2 - global to set on fail ; ; Globals ; g_localcertifyresult - global to report to caller on fail ; ; Locals ; twidentity.productname - product name of scanner to test ; ; Returns ; (none) ; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Initialize stuff, load tables if not already done for us... ; echo.titlesuite 'Stress Tests v1.0 23-Feb-2020' setlocal twidentity.productname '${arg:1}' setglobal g_localcertifyresult 'pass' if '${get:TW_ARRAY.ItemType}' != '' goto MAIN.LOADTABLES.SKIP run '${folder:certification}/LoadTables' :MAIN.LOADTABLES.SKIP ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Run the tests... ; call CERTIFY '${folder:certification}/Opends' '${get:twidentity.productname}' g_localcertifyresult embedded call CERTIFY '${folder:certification}/Closeds' '${get:twidentity.productname}' g_localcertifyresult embedded if '${get:g_localcertifyresult}' == 'fail' goto MAIN.ERROR call CERTIFY '${folder:certification}/Opends' '${get:twidentity.productname}' g_localcertifyresult embedded call CERTIFY '${folder:certification}/Closeds' '${get:twidentity.productname}' g_localcertifyresult embedded call CERTIFY '${folder:certification}/Opends' '${get:twidentity.productname}' g_localcertifyresult embedded call CERTIFY '${folder:certification}/Closeds' '${get:twidentity.productname}' g_localcertifyresult embedded call CERTIFY '${folder:certification}/Opends' '${get:twidentity.productname}' g_localcertifyresult embedded call CERTIFY '${folder:certification}/Closeds' '${get:twidentity.productname}' g_localcertifyresult embedded call CERTIFY '${folder:certification}/Opends' '${get:twidentity.productname}' g_localcertifyresult embedded call CERTIFY '${folder:certification}/Closeds' '${get:twidentity.productname}' g_localcertifyresult embedded ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Summary and cleanup... ; ; Did we pass? if '${get:g_localcertifyresult}' != 'pass' goto MAIN.ERROR echo.passfail 'SUMMARY' 'pass' return 'pass' ; ; Ruh-roh... :MAIN.ERROR echo.passfail 'SUMMARY' 'fail - ${sts:} ${ret:}' setglobal '${arg:2}' 'fail' return 'fail' ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Function: Certify ; arg:1 - script to run ; arg:2 - TW_IDENTITY.ProductName of scanner to test ; arg:3 - global value to update on fail ; arg:4 - embeded flag for open/close ; returns: (none) ; :CERTIFY ; run '${arg:1}' '${arg:2}' '${arg:4}' if '${ret:}' != 'pass' goto CERTIFY.FAIL return 'pass' ; :CERTIFY.FAIL setglobal '${arg:3}' 'fail' return 'fail' ================================================ FILE: twaincs/source/twaincscert/source/data/certification/050 - Non-UI Image Transfer Tests/Certification.tc ================================================ ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Non-UI Image Transfer Tests ; Confirm that multiple MSG_ENABLEDS and MSG_DISABLEDS calls can be made in the context of ; one MSG_OPENDS / MSG_CLOSEDS. This test focuses on image capture with no UI, verifying ; that the Application does not have to close the driver after capturing images. ; ; Arguments ; arg:1 - TW_IDENTITY.ProductName of scanner to test ; arg:2 - global to set on fail ; ; Globals ; (none) ; ; Locals ; twidentity.productname - product name of scanner to test ; certifyresult - global to set on fail ; xfermech - result of getting ICAP_XFERMECH ; sheets - count of sheets the user needs ; ; Returns ; (none) ; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Initialize stuff, load tables if not already done for us... ; echo.titlesuite 'Non-UI Image Transfer Tests v1.0 01-Mar-2020' setlocal twidentity.productname '${arg:1}' setlocal certifyresult '${arg:2}' setlocal sheets '0' if '${get:TW_ARRAY.ItemType}' != '' goto MAIN.LOADTABLES.SKIP run '${folder:certification}/LoadTables' :MAIN.LOADTABLES.SKIP ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Open the scanner... ; call CERTIFY '${folder:certification}/Opends' '${get:twidentity.productname}' '${get:certifyresult}' if '${get:${get:certifyresult}}' == 'fail' goto MAIN.CLOSEDS ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Prompt the user, if they have an ADF... ; :MAIN.PROMPT if '${get:g_skipprompts}' != '' goto MAIN.SKIP.PROMPTS dsmentry src ds dg_control dat_capability msg_get 'CAP_FEEDERENABLED,0,0,0' if '${ret:}' !~contains 'TRUE' goto MAIN.SKIP.PROMPTS dsmentry src ds dg_control dat_capability msg_get 'ICAP_XFERMECH,0,0,0' setlocal xfermech '${ret:}' dsmentry src ds dg_control dat_capability msg_get 'ICAP_PIXELTYPE,0,0,0' if '${ret:}' !~contains 'TWPT_BW' goto MAIN.PROMPTS.SKIP.BW increment sheets '${get:sheets}' '${getindex:xfermech:${get:TW_ENUMERATION.NumItems}}' :MAIN.PROMPTS.SKIP.BW if '${ret:}' !~contains 'TWPT_GRAY' goto MAIN.PROMPTS.SKIP.GRAY increment sheets '${get:sheets}' '${getindex:xfermech:${get:TW_ENUMERATION.NumItems}}' :MAIN.PROMPTS.SKIP.GRAY if '${ret:}' !~contains 'TWPT_RGB' goto MAIN.PROMPTS.SKIP.RGB increment sheets '${get:sheets}' '${getindex:xfermech:${get:TW_ENUMERATION.NumItems}}' :MAIN.PROMPTS.SKIP.RGB echo.prompt echo.prompt "Scanning will take place during this test. There will be no" echo.prompt "need to press any button on the TWAIN user interface to start" echo.prompt "the scanner. A progress indicator may appear during scanning." echo.prompt echo.prompt "Place ${get:sheets} sheets of paper in the scanner's feeder." pause '(press the ENTER key when ready to continue)' echo.prompt :MAIN.SKIP.PROMPTS ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Get ICAP_XFERMECH... ; setlocal name 'ICAP_XFERMECH MSG_GET' dsmentry src ds dg_control dat_capability msg_get 'ICAP_XFERMECH,0,0,0' if '${sts:}' != 'SUCCESS' goto CERTIFY.FAIL setlocal xfermech '${ret:}' echo.passfail '${get:name}' 'pass' ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Do the tests... ; call CERTIFY 'DAT_IMAGENATIVEXFER' '${get:twidentity.productname}' '${get:certifyresult}' 'FALSE' '${folder:parent}' call CERTIFY 'DAT_IMAGEMEMXFER' '${get:twidentity.productname}' '${get:certifyresult}' 'FALSE' '${folder:parent}' call CERTIFY 'DAT_IMAGEFILEXFER' '${get:twidentity.productname}' '${get:certifyresult}' 'FALSE' '${folder:parent}' '${get:xfermech}' call CERTIFY 'DAT_IMAGEMEMFILEXFER' '${get:twidentity.productname}' '${get:certifyresult}' 'FALSE' '${folder:parent}' '${get:xfermech}' :MAIN.CLOSEDS call CERTIFY '${folder:certification}/Closeds' '${get:twidentity.productname}' '${get:certifyresult}' return ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Function: Certify ; arg:1 - script to run ; arg:2 - TW_IDENTITY.ProductName of scanner to test ; arg:3 - global value to update on fail ; arg:4 - showui value ; arg:5 - name of test ; arg:6 - xfermech values ; returns: (none) ; :CERTIFY ; run '${arg:1}' '${arg:2}' '${arg:3}' '${arg:4}' '${arg:5}' '${arg:6}' if '${ret:}' != 'pass' goto CERTIFY.FAIL return 'pass' ; :CERTIFY.FAIL setglobal '${arg:3}' 'fail' return 'fail' ================================================ FILE: twaincs/source/twaincscert/source/data/certification/050 - Non-UI Image Transfer Tests/DAT_IMAGEFILEXFER.tc ================================================ ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; DAT_IMAGEFILEXFER ; This test issues multiple image transfer sessions using DAT_IMAGEFILEXFER. It is performed ; for all available image sources (unspecified, flatbed and/or ADF). Only one image is transferred ; per session. ; ; We follow the capability ordering, so the loops take the form: ; set ICAP_XFERMECH TWSX_FILE ; foreach CAP_FEEDERENABLED ; foreach ICAP_PIXELTYPE ; scan ; end ; end ; ; Arguments ; arg:1 - TW_IDENTITY.ProductName of scanner to test ; arg:2 - global for us to update on failure ; arg:3 - value of ShowUI (TRUE or FALSE) ; arg:4 - test name for the image folder ; arg:5 - result of a MSG_GET on ICAP_XFERMECH ; ; Globals ; (none) ; ; Locals ; name - current test being done ; indent - indent the passfail text ; twimageinfo.compression - compression for current image ; showui - value of showui ; ; image.count - count of images from 1 ; image.folder - folder to put the images in ; image.prefix - adf or fb ; ; feederenabled.list - scanner's feederenabled values ; feederenabled.index - index of feederenabled values ; feederenabled.value - current feederenabled value ; ; pixeltype.list - scanner's pixeltype values for this feederenabled ; pixeltype.index - index of pixeltype values ; pixeltype.value - current pixeltype value ; ; Returns ; pass or fail ; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; If not supported, quietly leave... ; if '${arg:5}' ~contains 'TWSX_FILE' goto MAIN.CONTINUE return 'pass' :MAIN.CONTINUE ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Initialize... ; echo.titletest 'DAT_IMAGEFILEXFER' setlocal indent '' setlocal image.count '0' setlocal image.folder '${folder:certimages}/${arg:4}/DAT_IMAGEFILEXFER' setlocal image.prefix 'fb' setlocal image.showname '' setlocal showui '${arg:3}' ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Clean the image folder for this test... ; image cleanfolder '${get:image.folder}' ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; MSG_RESETALL ; If return code is not TWRC_SUCCESS, end with an error ; setlocal name 'MSG_RESETALL' dsmentry src ds dg_control dat_capability msg_resetall '0,0,0,0' if '${sts:}' != 'SUCCESS' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Get and set ICAP_XFERMECH... ; setlocal name 'ICAP_XFERMECH MSG_GET' dsmentry src ds dg_control dat_capability msg_get 'ICAP_XFERMECH,0,0,0' if '${sts:}' != 'SUCCESS' goto MAIN.ERROR.ECHOPASSFAIL if '${ret:}' !~contains 'TWSX_FILE' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' ; setlocal name 'ICAP_XFERMECH MSG_SET TWSX_FILE' dsmentry src ds dg_control dat_capability msg_set 'ICAP_XFERMECH,TWON_ONEVALUE,TWTY_UINT16,TWSX_FILE' if '${sts:}' != 'SUCCESS' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Get CAP_FEEDERENABLED, and loop so we test all values ; for the current ICAP_XFERMECH setting. ; setlocal name 'CAP_FEEDERENABLED MSG_GET' dsmentry src ds dg_control dat_capability msg_get 'CAP_FEEDERENABLED,0,0,0' if '${sts:}' != 'SUCCESS' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' ; setlocal feederenabled.list '${ret:}' ; what the scanner told us setlocal feederenabled.index '${get:TW_ENUMERATION.ItemList}' ; point to itemlist increment feederenabled.index '${get:feederenabled.index}' -1 ; less 1 ; :MAIN.FEEDERENABLED.NEXT setlocal indent '' setlocal image.count '0' ; reset count to 0 increment feederenabled.index '${get:feederenabled.index}' 1 ; next itemlist setlocal feederenabled.value '${getindex:feederenabled.list:${get:feederenabled.index}}' ; get the value if '${get:feederenabled.value}' == '' goto MAIN.PASS ; we've passed all tests!!! ; setlocal name 'CAP_FEEDERENABLED MSG_SET ${get:feederenabled.value}' dsmentry src ds dg_control dat_capability msg_set 'CAP_FEEDERENABLED,TWON_ONEVALUE,TWTY_BOOL,${get:feederenabled.value}' if '${sts:}' != 'SUCCESS' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' ; if '${get:feederenabled.value}' ~~ 'FALSE' goto MAIN.FEEDERENABLED.SETFB setlocal image.prefix 'adf' goto MAIN.FEEDERENABLED.SETDONE :MAIN.FEEDERENABLED.SETFB setlocal image.prefix 'fb' :MAIN.FEEDERENABLED.SETDONE ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Get ICAP_PIXELTYPE, and loop so we test all values for ; the current CAP_FEEDERENABLED setting. ; setlocal indent ' ' setlocal name 'ICAP_PIXELTYPE MSG_GET' dsmentry src ds dg_control dat_capability msg_get 'ICAP_PIXELTYPE,0,0,0' if '${sts:}' != 'SUCCESS' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' ; setlocal pixeltype.list '${ret:}' ; what the scanner told us setlocal pixeltype.index '${get:TW_ENUMERATION.ItemList}' ; point to itemlist increment pixeltype.index '${get:pixeltype.index}' -1 ; less 1 ; :MAIN.PIXELTYPE.NEXT setlocal indent ' ' increment pixeltype.index '${get:pixeltype.index}' 1 ; next itemlist setlocal pixeltype.value '${getindex:pixeltype.list:${get:pixeltype.index}}' ; get the value if '${get:pixeltype.value}' == '' goto MAIN.FEEDERENABLED.NEXT ; pixeltypes done for this feederenabled ; setlocal name 'ICAP_PIXELTYPE MSG_SET ${get:pixeltype.value}' dsmentry src ds dg_control dat_capability msg_set 'ICAP_PIXELTYPE,TWON_ONEVALUE,TWTY_UINT16,${get:pixeltype.value}' if '${sts:}' != 'SUCCESS' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; If we're a flatbed, we can start scanning... ; setlocal indent ' ' if '${get:feederenabled.value}' ~~ 'FALSE' goto MAIN.USERINTERFACE ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Check for paper in the feeder... ; dsmentry src ds dg_control dat_capability msg_getcurrent 'CAP_FEEDERLOADED,0,0,0' if '${sts:}' != 'SUCCESS' goto MAIN.FEEDERLOADED.DONE if '${ret:${get:TW_ONEVALUE.Item}}' ~~ 'TRUE' goto MAIN.FEEDERLOADED.DONE echo.prompt echo.prompt "Place paper in the scanner's feeder." pause '(press the ENTER key when ready to continue)' :MAIN.FEEDERLOADED.DONE ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Start scanning... ; :MAIN.USERINTERFACE setlocal name 'dg_control/dat_userinterface/msg_enableds' wait reset dsmentry src null dg_control dat_userinterface msg_enableds '${get:showui},0' if '${sts:}' != 'SUCCESS' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Wait for MSG_XFERREADY, if we don't see it then scoot... ; setlocal name 'wait ${get:sys_waittimeout} seconds for MSG_XFERREADY' wait '${get:sys_waittimeout}000' if '${ret:}' !~contains 'msg_xferready' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Get information about the image... ; :MAIN.IMAGEINFO.NEXT setlocal name 'dg_image/dat_imageinfo/msg_get' dsmentry src ds dg_image dat_imageinfo msg_get '0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0' if '${sts:}' != 'SUCCESS' goto MAIN.ERROR.ECHOPASSFAIL setlocal twimageinfo.compression '${ret:${get:index.twimageinfo.compression}}' echo.passfail '${get:indent}${get:name}' 'pass' ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Set up the file transfer... ; increment image.count '${get:image.count}' 1 if '${get:twimageinfo.compression}' == 'JPEG' goto MAIN.SETUPFILEXFER.JPEG setlocal image.showname 'DAT_IMAGEFILEXFER/${get:image.prefix}${format:D6|${get:image.count}}.tif' setlocal twsetupfilexfer.filename '${get:image.folder}/${get:image.prefix}${format:D6|${get:image.count}}.tif' setlocal twsetupfilexfer.format 'TWFF_TIFF' goto MAIN.SETUPFILEXFER :MAIN.SETUPFILEXFER.JPEG setlocal image.showname 'DAT_IMAGEFILEXFER/${get:image.prefix}${format:D6|${get:image.count}}.jpg' setlocal twsetupfilexfer.filename '${get:image.folder}/${get:image.prefix}${format:D6|${get:image.count}}.jpg' setlocal twsetupfilexfer.format 'TWFF_JFIF' :MAIN.SETUPFILEXFER setlocal name 'dg_control/dat_setupfilexfer/msg_set' dsmentry src ds dg_control dat_setupfilexfer msg_set '"${get:twsetupfilexfer.filename}",${get:twsetupfilexfer.format},0' if '${sts:}' != 'SUCCESS' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Transfer the image... ; setlocal name 'dg_image/dat_imagefilexfer/msg_get' dsmentry src ds dg_image dat_imagefilexfer msg_get null if '${sts:}' != 'XFERDONE' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' echo.passfail '${get:indent}image <${get:image.showname}>' 'pass' ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; End the transfer, see if we're done... ; setlocal name 'dg_control/dat_pendingxfers/msg_endxfer' dsmentry src ds dg_control dat_pendingxfers msg_endxfer '0,0' if '${sts:}' != 'SUCCESS' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' if '${ret:${get:TW_PENDINGXFERS.Count}}' != '0' goto MAIN.IMAGEINFO.NEXT ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; We're out of images, so disable and go back up to ; do the next ICAP_PIXELTYPE... ; setlocal name 'dg_control/dat_userinterface/msg_disableds' dsmentry src ds dg_control dat_userinterface msg_disableds '0,0' if '${sts:}' != 'SUCCESS' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' goto MAIN.PIXELTYPE.NEXT ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Summary and cleanup... ; ; We passed... :MAIN.PASS echo.passfail 'SUMMARY' 'pass' return 'pass' ; ; Ruh-roh... :MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'fail - ${sts:} ${ret:}' echo.passfail 'SUMMARY' 'fail' setglobal '${arg:2}' 'fail' return 'fail' ================================================ FILE: twaincs/source/twaincscert/source/data/certification/050 - Non-UI Image Transfer Tests/DAT_IMAGEMEMFILEXFER.tc ================================================ ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; DAT_IMAGEMEMFILEXFER ; This test issues multiple image transfer sessions using DAT_IMAGEMEMFILEXFER. It is performed ; for all available image sources (unspecified, flatbed and/or ADF). Only one image is transferred ; per session. ; ; We follow the capability ordering, so the loops take the form: ; set ICAP_XFERMECH TWSX_MEMFILE ; foreach CAP_FEEDERENABLED ; foreach ICAP_PIXELTYPE ; scan ; end ; end ; ; Arguments ; arg:1 - TW_IDENTITY.ProductName of scanner to test ; arg:2 - global for us to update on failure ; arg:3 - value of ShowUI (TRUE or FALSE) ; arg:4 - test name for the image folder ; arg:5 - result of a MSG_GET on ICAP_XFERMECH ; ; Globals ; (none) ; ; Locals ; name - current test being done ; indent - indent the passfail text ; imagememxfer - result of DAT_IMAGEMEMXFER call ; setupmemxfer.preferred - preferred field from DAT_SETUPMEMXFER call ; ; image.count - count of images from 1 ; image.folder - folder to put the images in ; image.prefix - adf or fb ; ; feederenabled.list - scanner's feederenabled values ; feederenabled.index - index of feederenabled values ; feederenabled.value - current feederenabled value ; ; pixeltype.list - scanner's pixeltype values for this feederenabled ; pixeltype.index - index of pixeltype values ; pixeltype.value - current pixeltype value ; ; Returns ; pass or fail ; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; If not supported, quietly leave... ; if '${arg:5}' ~contains 'TWSX_MEMFILE' goto MAIN.CONTINUE return 'pass' :MAIN.CONTINUE ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Initialize... ; echo.titletest 'DAT_IMAGEMEMFILEXFER' setlocal indent '' setlocal image.pointer '0' setlocal image.count '0' setlocal image.folder '${folder:certimages}/${arg:4}/DAT_IMAGEMEMFILEXFER' setlocal image.prefix 'fb' setlocal showui '${arg:3}' ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Clean the image folder for this test... ; image cleanfolder '${get:image.folder}' ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; MSG_RESETALL ; If return code is not TWRC_SUCCESS, end with an error ; setlocal name 'MSG_RESETALL' dsmentry src ds dg_control dat_capability msg_resetall '0,0,0,0' if '${sts:}' != 'SUCCESS' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Get and set ICAP_XFERMECH... ; setlocal name 'ICAP_XFERMECH MSG_GET' dsmentry src ds dg_control dat_capability msg_get 'ICAP_XFERMECH,0,0,0' if '${sts:}' != 'SUCCESS' goto MAIN.ERROR.ECHOPASSFAIL if '${ret:}' !~contains 'TWSX_MEMFILE' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' ; setlocal name 'ICAP_XFERMECH MSG_SET TWSX_MEMFILE' dsmentry src ds dg_control dat_capability msg_set 'ICAP_XFERMECH,TWON_ONEVALUE,TWTY_UINT16,TWSX_MEMFILE' if '${sts:}' != 'SUCCESS' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Get CAP_FEEDERENABLED, and loop so we test all values ; for the current ICAP_XFERMECH setting. ; setlocal name 'CAP_FEEDERENABLED MSG_GET' dsmentry src ds dg_control dat_capability msg_get 'CAP_FEEDERENABLED,0,0,0' if '${sts:}' != 'SUCCESS' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' ; setlocal feederenabled.list '${ret:}' ; what the scanner told us setlocal feederenabled.index '${get:TW_ENUMERATION.ItemList}' ; point to itemlist increment feederenabled.index '${get:feederenabled.index}' -1 ; less 1 ; :MAIN.FEEDERENABLED.NEXT setlocal indent '' setlocal image.count '0' ; reset count to 0 increment feederenabled.index '${get:feederenabled.index}' 1 ; next itemlist setlocal feederenabled.value '${getindex:feederenabled.list:${get:feederenabled.index}}' ; get the value if '${get:feederenabled.value}' == '' goto MAIN.PASS ; we've passed all tests!!! ; setlocal name 'CAP_FEEDERENABLED MSG_SET ${get:feederenabled.value}' dsmentry src ds dg_control dat_capability msg_set 'CAP_FEEDERENABLED,TWON_ONEVALUE,TWTY_BOOL,${get:feederenabled.value}' if '${sts:}' != 'SUCCESS' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' ; if '${get:feederenabled.value}' ~~ 'FALSE' goto MAIN.FEEDERENABLED.SETFB setlocal image.prefix 'adf' goto MAIN.FEEDERENABLED.SETDONE :MAIN.FEEDERENABLED.SETFB setlocal image.prefix 'fb' :MAIN.FEEDERENABLED.SETDONE ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Get ICAP_PIXELTYPE, and loop so we test all values for ; the current CAP_FEEDERENABLED setting. ; setlocal indent ' ' setlocal name 'ICAP_PIXELTYPE MSG_GET' dsmentry src ds dg_control dat_capability msg_get 'ICAP_PIXELTYPE,0,0,0' if '${sts:}' != 'SUCCESS' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' ; setlocal pixeltype.list '${ret:}' ; what the scanner told us setlocal pixeltype.index '${get:TW_ENUMERATION.ItemList}' ; point to itemlist increment pixeltype.index '${get:pixeltype.index}' -1 ; less 1 ; :MAIN.PIXELTYPE.NEXT setlocal indent ' ' increment pixeltype.index '${get:pixeltype.index}' 1 ; next itemlist setlocal pixeltype.value '${getindex:pixeltype.list:${get:pixeltype.index}}' ; get the value if '${get:pixeltype.value}' == '' goto MAIN.FEEDERENABLED.NEXT ; pixeltypes done for this feederenabled ; setlocal name 'ICAP_PIXELTYPE MSG_SET ${get:pixeltype.value}' dsmentry src ds dg_control dat_capability msg_set 'ICAP_PIXELTYPE,TWON_ONEVALUE,TWTY_UINT16,${get:pixeltype.value}' if '${sts:}' != 'SUCCESS' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Get the preferred size for memory transfers, and allocate ; a pointer for the memory transfers... ; setlocal indent ' ' setlocal name 'dg_control/dat_setupmemxfer/msg_get' dsmentry src ds dg_control dat_setupmemxfer msg_get '0,0,0' if '${sts:}' != 'SUCCESS' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' ; setlocal name 'TW_SETUPMEMXFER.Preferred > 0' setlocal setupmemxfer.preferred '${ret:${get:TW_SETUPMEMXFER.Preferred}}' if '${get:setupmemxfer.preferred}' <= '0' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' ; setlocal name 'allocate pointer for ${get:setupmemxfer.preferred} bytes' free pointer image.pointer ; for the last loop allocate pointer image.pointer '${get:setupmemxfer.preferred}' if '${get:image.pointer}' == '0' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Set DAT_SETUPFILEXFER to TWFF_TIFF ; setlocal name 'dg_control/dat_setupfilexfer/msg_set TWFF_TIFF' dsmentry src null dg_control dat_setupfilexfer msg_set 'file,TWFF_TIFF,0' if '${sts:}' != 'SUCCESS' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; If we're a flatbed, we can start scanning... ; if '${get:feederenabled.value}' ~~ 'FALSE' goto MAIN.USERINTERFACE ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Check for paper in the feeder... ; dsmentry src ds dg_control dat_capability msg_getcurrent 'CAP_FEEDERLOADED,0,0,0' if '${sts:}' != 'SUCCESS' goto MAIN.FEEDERLOADED.DONE if '${ret:${get:TW_ONEVALUE.Item}}' ~~ 'TRUE' goto MAIN.FEEDERLOADED.DONE echo.prompt echo.prompt "Place paper in the scanner's feeder." pause '(press the ENTER key when ready to continue)' :MAIN.FEEDERLOADED.DONE ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; We only need one sheet of paper... ; setlocal name 'CAP_XFERCOUNT MSG_SET 1' dsmentry src ds dg_control dat_capability msg_set 'CAP_XFERCOUNT,TWON_ONEVALUE,TWTY_INT16,1' if '${sts:}' != 'SUCCESS' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Start scanning... ; :MAIN.USERINTERFACE setlocal name 'dg_control/dat_userinterface/msg_enableds' wait reset dsmentry src null dg_control dat_userinterface msg_enableds '${get:showui},0' if '${sts:}' != 'SUCCESS' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Wait for MSG_XFERREADY, if we don't see it then scoot... ; setlocal name 'wait ${get:sys_waittimeout} seconds for MSG_XFERREADY' wait '${get:sys_waittimeout}000' if '${ret:}' !~contains 'msg_xferready' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Do a memory file transfer... ; This little song and dance with the states is so that we can ; start the transfer in state 6 with each new image, but switch ; to state 7 if we need multiple calls to capture the current ; image... ; ; The saved images will be in TIFF format, which includes TIFF ; JPEG (the better form, where a simple TIFF header is added). ; increment image.count '${get:image.count}' 1 image free memfileimage ; :MAIN.IMAGEMEMFILEXFER.NEXT setlocal name 'dg_image/dat_imagememxfer/msg_get' dsmentry src ds dg_image dat_imagememfilexfer msg_get '0,0,0,0,0,0,0,9,${get:setupmemxfer.preferred},${get:image.pointer}' setlocal imagememxfer '${ret:}' if '${sts:}' == 'XFERDONE' goto MAIN.IMAGEMEMFILEXFER.XFERDONE if '${sts:}' != 'SUCCESS' goto MAIN.ERROR.ECHOPASSFAIL ; echo.passfail '${get:indent}${get:name} SUCCESS' 'pass' image append memfileimage '${get:imagememxfer}' goto MAIN.IMAGEMEMFILEXFER.NEXT ; :MAIN.IMAGEMEMFILEXFER.XFERDONE echo.passfail '${get:indent}${get:name} XFERDONE' 'pass' image append memfileimage '${get:imagememxfer}' image save memfileimage memfile '${get:image.folder}/${get:image.prefix}${format:D6|${get:image.count}}' echo.passfail '${get:indent}image <${ret:}>' 'pass' image free memfileimage ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; End the transfer, see if we're done... ; setlocal name 'dg_control/dat_pendingxfers/msg_endxfer' dsmentry src ds dg_control dat_pendingxfers msg_endxfer '0,0' if '${sts:}' != 'SUCCESS' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' if '${ret:${get:TW_PENDINGXFERS.Count}}' != '0' goto MAIN.IMAGEMEMFILEXFER.NEXT ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; We're out of images, so disable and go back up to ; do the next ICAP_PIXELTYPE... ; setlocal name 'dg_control/dat_userinterface/msg_disableds' dsmentry src ds dg_control dat_userinterface msg_disableds '0,0' if '${sts:}' != 'SUCCESS' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' goto MAIN.PIXELTYPE.NEXT ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Summary and cleanup... ; ; We passed... :MAIN.PASS image free memfileimage free pointer image.pointer echo.passfail 'SUMMARY' 'pass' return 'pass' ; ; Ruh-roh... :MAIN.ERROR.ECHOPASSFAIL image free memfileimage free pointer image.pointer echo.passfail '${get:indent}${get:name}' 'fail - ${sts:} ${ret:}' echo.passfail 'SUMMARY' 'fail' setglobal '${arg:2}' 'fail' return 'fail' ================================================ FILE: twaincs/source/twaincscert/source/data/certification/050 - Non-UI Image Transfer Tests/DAT_IMAGEMEMXFER.tc ================================================ ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; DAT_IMAGEMEMXFER ; This test issues multiple image transfer sessions using DAT_IMAGEMEMXFER. It is performed ; for all available image sources (unspecified, flatbed and/or ADF). Only one image is transferred ; per session. ; ; We follow the capability ordering, so the loops take the form: ; set ICAP_XFERMECH TWSX_MEMORY ; foreach CAP_FEEDERENABLED ; foreach ICAP_PIXELTYPE ; scan ; end ; end ; ; Arguments ; arg:1 - TW_IDENTITY.ProductName of scanner to test ; arg:2 - global for us to update on failure ; arg:3 - value of ShowUI (TRUE or FALSE) ; arg:4 - test name for the image folder ; ; Globals ; (none) ; ; Locals ; name - current test being done ; indent - indent the passfail text ; imageinfo - metadata for the current image ; imagememxfer - result of DAT_IMAGEMEMXFER call ; setupmemxfer.preferred - preferred field from DAT_SETUPMEMXFER call ; ; image.count - count of images from 1 ; image.folder - folder to put the images in ; image.prefix - adf or fb ; ; feederenabled.list - scanner's feederenabled values ; feederenabled.index - index of feederenabled values ; feederenabled.value - current feederenabled value ; ; pixeltype.list - scanner's pixeltype values for this feederenabled ; pixeltype.index - index of pixeltype values ; pixeltype.value - current pixeltype value ; ; Returns ; pass or fail ; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Initialize... ; echo.titletest 'DAT_IMAGEMEMXFER' setlocal indent '' setlocal image.pointer '0' setlocal image.count '0' setlocal image.folder '${folder:certimages}/${arg:4}/DAT_IMAGEMEMXFER' setlocal image.prefix 'fb' setlocal showui '${arg:3}' ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Clean the image folder for this test... ; image cleanfolder '${get:image.folder}' ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; MSG_RESETALL ; If return code is not TWRC_SUCCESS, end with an error ; setlocal name 'MSG_RESETALL' dsmentry src ds dg_control dat_capability msg_resetall '0,0,0,0' if '${sts:}' != 'SUCCESS' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Get and set ICAP_XFERMECH... ; setlocal name 'ICAP_XFERMECH MSG_GET' dsmentry src ds dg_control dat_capability msg_get 'ICAP_XFERMECH,0,0,0' if '${sts:}' != 'SUCCESS' goto MAIN.ERROR.ECHOPASSFAIL if '${ret:}' !~contains 'TWSX_MEMORY' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' ; setlocal name 'ICAP_XFERMECH MSG_SET TWSX_MEMORY' dsmentry src ds dg_control dat_capability msg_set 'ICAP_XFERMECH,TWON_ONEVALUE,TWTY_UINT16,TWSX_MEMORY' if '${sts:}' != 'SUCCESS' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Get CAP_FEEDERENABLED, and loop so we test all values ; for the current ICAP_XFERMECH setting. ; setlocal name 'CAP_FEEDERENABLED MSG_GET' dsmentry src ds dg_control dat_capability msg_get 'CAP_FEEDERENABLED,0,0,0' if '${sts:}' != 'SUCCESS' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' ; setlocal feederenabled.list '${ret:}' ; what the scanner told us setlocal feederenabled.index '${get:TW_ENUMERATION.ItemList}' ; point to itemlist increment feederenabled.index '${get:feederenabled.index}' -1 ; less 1 ; :MAIN.FEEDERENABLED.NEXT setlocal indent '' setlocal image.count '0' ; reset count to 0 increment feederenabled.index '${get:feederenabled.index}' 1 ; next itemlist setlocal feederenabled.value '${getindex:feederenabled.list:${get:feederenabled.index}}' ; get the value if '${get:feederenabled.value}' == '' goto MAIN.PASS ; we've passed all tests!!! ; setlocal name 'CAP_FEEDERENABLED MSG_SET ${get:feederenabled.value}' dsmentry src ds dg_control dat_capability msg_set 'CAP_FEEDERENABLED,TWON_ONEVALUE,TWTY_BOOL,${get:feederenabled.value}' if '${sts:}' != 'SUCCESS' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' ; if '${get:feederenabled.value}' ~~ 'FALSE' goto MAIN.FEEDERENABLED.SETFB setlocal image.prefix 'adf' goto MAIN.FEEDERENABLED.SETDONE :MAIN.FEEDERENABLED.SETFB setlocal image.prefix 'fb' :MAIN.FEEDERENABLED.SETDONE ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Get ICAP_PIXELTYPE, and loop so we test all values for ; the current CAP_FEEDERENABLED setting. ; setlocal indent ' ' setlocal name 'ICAP_PIXELTYPE MSG_GET' dsmentry src ds dg_control dat_capability msg_get 'ICAP_PIXELTYPE,0,0,0' if '${sts:}' != 'SUCCESS' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' ; setlocal pixeltype.list '${ret:}' ; what the scanner told us setlocal pixeltype.index '${get:TW_ENUMERATION.ItemList}' ; point to itemlist increment pixeltype.index '${get:pixeltype.index}' -1 ; less 1 ; :MAIN.PIXELTYPE.NEXT setlocal indent ' ' increment pixeltype.index '${get:pixeltype.index}' 1 ; next itemlist setlocal pixeltype.value '${getindex:pixeltype.list:${get:pixeltype.index}}' ; get the value if '${get:pixeltype.value}' == '' goto MAIN.FEEDERENABLED.NEXT ; pixeltypes done for this feederenabled ; setlocal name 'ICAP_PIXELTYPE MSG_SET ${get:pixeltype.value}' dsmentry src ds dg_control dat_capability msg_set 'ICAP_PIXELTYPE,TWON_ONEVALUE,TWTY_UINT16,${get:pixeltype.value}' if '${sts:}' != 'SUCCESS' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Get the preferred size for memory transfers, and allocate ; a pointer for the memory transfers... ; setlocal indent ' ' setlocal name 'dg_control/dat_setupmemxfer/msg_get' dsmentry src ds dg_control dat_setupmemxfer msg_get '0,0,0' if '${sts:}' != 'SUCCESS' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' ; setlocal name 'TW_SETUPMEMXFER.Preferred > 0' setlocal setupmemxfer.preferred '${ret:${get:TW_SETUPMEMXFER.Preferred}}' if '${get:setupmemxfer.preferred}' <= '0' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' ; setlocal name 'allocate pointer for ${get:setupmemxfer.preferred} bytes' free pointer image.pointer ; for the last loop allocate pointer image.pointer '${get:setupmemxfer.preferred}' if '${get:image.pointer}' == '0' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; If we're a flatbed, we can start scanning... ; if '${get:feederenabled.value}' ~~ 'FALSE' goto MAIN.USERINTERFACE ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Check for paper in the feeder... ; dsmentry src ds dg_control dat_capability msg_getcurrent 'CAP_FEEDERLOADED,0,0,0' if '${sts:}' != 'SUCCESS' goto MAIN.FEEDERLOADED.DONE if '${ret:${get:TW_ONEVALUE.Item}}' ~~ 'TRUE' goto MAIN.FEEDERLOADED.DONE echo.prompt echo.prompt "Place paper in the scanner's feeder." pause '(press the ENTER key when ready to continue)' :MAIN.FEEDERLOADED.DONE ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; We only need one sheet of paper... ; setlocal name 'CAP_XFERCOUNT MSG_SET 1' dsmentry src ds dg_control dat_capability msg_set 'CAP_XFERCOUNT,TWON_ONEVALUE,TWTY_INT16,1' if '${sts:}' != 'SUCCESS' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Start scanning... ; :MAIN.USERINTERFACE setlocal name 'dg_control/dat_userinterface/msg_enableds' wait reset dsmentry src null dg_control dat_userinterface msg_enableds '${get:showui},0' if '${sts:}' != 'SUCCESS' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Wait for MSG_XFERREADY, if we don't see it then scoot... ; setlocal name 'wait ${get:sys_waittimeout} seconds for MSG_XFERREADY' wait '${get:sys_waittimeout}000' if '${ret:}' !~contains 'msg_xferready' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Do a memory transfer... ; This little song and dance with the states is so that we can ; start the transfer in state 6 with each new image, but switch ; to state 7 if we need multiple calls to capture the current ; image... ; ; The saved images will be in TIFF format, which includes TIFF ; JPEG (the better form, where a simple TIFF header is added). ; increment image.count '${get:image.count}' 1 image free memimage ; :MAIN.IMAGEMEMXFER.NEXT setlocal name 'dg_image/dat_imagememxfer/msg_get' dsmentry src ds dg_image dat_imagememxfer msg_get '0,0,0,0,0,0,0,9,${get:setupmemxfer.preferred},${get:image.pointer}' setlocal imagememxfer '${ret:}' if '${sts:}' == 'XFERDONE' goto MAIN.IMAGEMEMXFER.XFERDONE if '${sts:}' != 'SUCCESS' goto MAIN.ERROR.ECHOPASSFAIL ; echo.passfail '${get:indent}${get:name} SUCCESS' 'pass' image append memimage '${get:imagememxfer}' goto MAIN.IMAGEMEMXFER.NEXT ; :MAIN.IMAGEMEMXFER.XFERDONE echo.passfail '${get:indent}${get:name} XFERDONE' 'pass' ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; We need image info to make sense of this data... ; setlocal name 'dg_image/dat_imageinfo/msg_get' dsmentry src ds dg_image dat_imageinfo msg_get '0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0' setlocal imageinfo '${ret:}' if '${sts:}' != 'SUCCESS' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Save the image... ; image append memimage '${get:imagememxfer}' image addheader memimage '${get:imageinfo}' image save memimage memory '${get:image.folder}/${get:image.prefix}${format:D6|${get:image.count}}' echo.passfail '${get:indent}image <${ret:}>' 'pass' image free memimage ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; End the transfer, see if we're done... ; setlocal name 'dg_control/dat_pendingxfers/msg_endxfer' dsmentry src ds dg_control dat_pendingxfers msg_endxfer '0,0' if '${sts:}' != 'SUCCESS' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' if '${ret:${get:TW_PENDINGXFERS.Count}}' != '0' goto MAIN.IMAGEMEMXFER.NEXT ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; We're out of images, so disable and go back up to ; do the next ICAP_PIXELTYPE... ; setlocal name 'dg_control/dat_userinterface/msg_disableds' dsmentry src ds dg_control dat_userinterface msg_disableds '0,0' if '${sts:}' != 'SUCCESS' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' goto MAIN.PIXELTYPE.NEXT ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Summary and cleanup... ; ; We passed... :MAIN.PASS image free memimage free pointer image.pointer echo.passfail 'SUMMARY' 'pass' return 'pass' ; ; Ruh-roh... :MAIN.ERROR.ECHOPASSFAIL image free memimage free pointer image.pointer echo.passfail '${get:indent}${get:name}' 'fail - ${sts:} ${ret:}' echo.passfail 'SUMMARY' 'fail' setglobal '${arg:2}' 'fail' return 'fail' ================================================ FILE: twaincs/source/twaincscert/source/data/certification/050 - Non-UI Image Transfer Tests/DAT_IMAGENATIVEXFER.tc ================================================ ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; DAT_IMAGENATIVEXFER ; This test issues multiple image transfer sessions using DAT_IMAGENATIVEXFER. It is performed ; for all available image sources (unspecified, flatbed and/or ADF). Only one image is transferred ; per session. ; ; We follow the capability ordering, so the loops take the form: ; set ICAP_XFERMECH TWSX_NATIVE ; foreach CAP_FEEDERENABLED ; foreach ICAP_PIXELTYPE ; scan ; end ; end ; ; Arguments ; arg:1 - TW_IDENTITY.ProductName of scanner to test ; arg:2 - global for us to update on failure ; arg:3 - value of ShowUI (TRUE or FALSE) ; arg:4 - test name for the image folder ; ; Globals ; (none) ; ; Locals ; name - current test being done ; indent - indent the passfail text ; ; image.handle - native handle ; image.count - count of images from 1 ; image.folder - folder to put the images in ; image.prefix - adf or fb ; ; feederenabled.list - scanner's feederenabled values ; feederenabled.index - index of feederenabled values ; feederenabled.value - current feederenabled value ; ; pixeltype.list - scanner's pixeltype values for this feederenabled ; pixeltype.index - index of pixeltype values ; pixeltype.value - current pixeltype value ; ; Returns ; pass or fail ; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Initialize... ; echo.titletest 'DAT_IMAGENATIVEXFER' setlocal indent '' setlocal image.handle '0' setlocal image.count '0' setlocal image.folder '${folder:certimages}/${arg:4}/DAT_IMAGENATIVEXFER' setlocal image.prefix 'fb' setlocal showui '${arg:3}' ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Clean the image folder for this test... ; image cleanfolder '${get:image.folder}' ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; MSG_RESETALL ; If return code is not TWRC_SUCCESS, end with an error ; setlocal name 'MSG_RESETALL' dsmentry src ds dg_control dat_capability msg_resetall '0,0,0,0' if '${sts:}' != 'SUCCESS' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Get and set ICAP_XFERMECH... ; setlocal name 'ICAP_XFERMECH MSG_GET' dsmentry src ds dg_control dat_capability msg_get 'ICAP_XFERMECH,0,0,0' if '${sts:}' != 'SUCCESS' goto MAIN.ERROR.ECHOPASSFAIL if '${ret:}' !~contains 'TWSX_NATIVE' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' ; setlocal name 'ICAP_XFERMECH MSG_SET TWSX_NATIVE' dsmentry src ds dg_control dat_capability msg_set 'ICAP_XFERMECH,TWON_ONEVALUE,TWTY_UINT16,TWSX_NATIVE' if '${sts:}' != 'SUCCESS' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Get CAP_FEEDERENABLED, and loop so we test all values ; for the current ICAP_XFERMECH setting. ; setlocal name 'CAP_FEEDERENABLED MSG_GET' dsmentry src ds dg_control dat_capability msg_get 'CAP_FEEDERENABLED,0,0,0' if '${sts:}' != 'SUCCESS' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' ; setlocal feederenabled.list '${ret:}' ; what the scanner told us setlocal feederenabled.index '${get:TW_ENUMERATION.ItemList}' ; point to itemlist increment feederenabled.index '${get:feederenabled.index}' -1 ; less 1 ; :MAIN.FEEDERENABLED.NEXT setlocal indent '' setlocal image.count '0' ; reset count to 0 increment feederenabled.index '${get:feederenabled.index}' 1 ; next itemlist setlocal feederenabled.value '${getindex:feederenabled.list:${get:feederenabled.index}}' ; get the value if '${get:feederenabled.value}' == '' goto MAIN.PASS ; we've passed all tests!!! ; setlocal name 'CAP_FEEDERENABLED MSG_SET ${get:feederenabled.value}' dsmentry src ds dg_control dat_capability msg_set 'CAP_FEEDERENABLED,TWON_ONEVALUE,TWTY_BOOL,${get:feederenabled.value}' if '${sts:}' != 'SUCCESS' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' ; if '${get:feederenabled.value}' ~~ 'FALSE' goto MAIN.FEEDERENABLED.SETFB setlocal image.prefix 'adf' goto MAIN.FEEDERENABLED.SETDONE :MAIN.FEEDERENABLED.SETFB setlocal image.prefix 'fb' :MAIN.FEEDERENABLED.SETDONE ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Get ICAP_PIXELTYPE, and loop so we test all values for ; the current CAP_FEEDERENABLED setting. ; setlocal indent ' ' setlocal name 'ICAP_PIXELTYPE MSG_GET' dsmentry src ds dg_control dat_capability msg_get 'ICAP_PIXELTYPE,0,0,0' if '${sts:}' != 'SUCCESS' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' ; setlocal pixeltype.list '${ret:}' ; what the scanner told us setlocal pixeltype.index '${get:TW_ENUMERATION.ItemList}' ; point to itemlist increment pixeltype.index '${get:pixeltype.index}' -1 ; less 1 ; :MAIN.PIXELTYPE.NEXT setlocal indent ' ' increment pixeltype.index '${get:pixeltype.index}' 1 ; next itemlist setlocal pixeltype.value '${getindex:pixeltype.list:${get:pixeltype.index}}' ; get the value if '${get:pixeltype.value}' == '' goto MAIN.FEEDERENABLED.NEXT ; pixeltypes done for this feederenabled ; setlocal name 'ICAP_PIXELTYPE MSG_SET ${get:pixeltype.value}' dsmentry src ds dg_control dat_capability msg_set 'ICAP_PIXELTYPE,TWON_ONEVALUE,TWTY_UINT16,${get:pixeltype.value}' if '${sts:}' != 'SUCCESS' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; If we're a flatbed, we can start scanning... ; setlocal indent ' ' if '${get:feederenabled.value}' ~~ 'FALSE' goto MAIN.USERINTERFACE ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Check for paper in the feeder... ; dsmentry src ds dg_control dat_capability msg_getcurrent 'CAP_FEEDERLOADED,0,0,0' if '${sts:}' != 'SUCCESS' goto MAIN.FEEDERLOADED.DONE if '${ret:${get:TW_ONEVALUE.Item}}' ~~ 'TRUE' goto MAIN.FEEDERLOADED.DONE echo.prompt echo.prompt "Place paper in the scanner's feeder." pause '(press the ENTER key when ready to continue)' :MAIN.FEEDERLOADED.DONE ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; We only need one sheet of paper... ; setlocal name 'CAP_XFERCOUNT MSG_SET 1' dsmentry src ds dg_control dat_capability msg_set 'CAP_XFERCOUNT,TWON_ONEVALUE,TWTY_INT16,1' if '${sts:}' != 'SUCCESS' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Start scanning... ; :MAIN.USERINTERFACE setlocal name 'dg_control/dat_userinterface/msg_enableds' wait reset dsmentry src null dg_control dat_userinterface msg_enableds '${get:showui},0' if '${sts:}' != 'SUCCESS' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Wait for MSG_XFERREADY, if we don't see it then scoot... ; setlocal name 'wait ${get:sys_waittimeout} seconds for MSG_XFERREADY' wait '${get:sys_waittimeout}000' if '${ret:}' !~contains 'msg_xferready' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Do a native transfer... ; :MAIN.IMAGENATIVEXFER.NEXT setlocal name 'dg_image/dat_imagenativexfer/msg_get' increment image.count '${get:image.count}' 1 dsmentry src ds dg_image dat_imagenativexfer msg_get '0' setlocal image.handle '${ret:}' if '${sts:}' != 'XFERDONE' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' image save image.handle native '${get:image.folder}/${get:image.prefix}${format:D6|${get:image.count}}' echo.passfail '${get:indent}image <${ret:}>' 'pass' free handle image.handle ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; End the transfer, see if we're done... ; setlocal name 'dg_control/dat_pendingxfers/msg_endxfer' dsmentry src ds dg_control dat_pendingxfers msg_endxfer '0,0' if '${sts:}' != 'SUCCESS' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' if '${ret:${get:TW_PENDINGXFERS.Count}}' != '0' goto MAIN.IMAGENATIVEXFER.NEXT ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; We're out of images, so disable and go back up to ; do the next ICAP_PIXELTYPE... ; setlocal name 'dg_control/dat_userinterface/msg_disableds' dsmentry src ds dg_control dat_userinterface msg_disableds '0,0' if '${sts:}' != 'SUCCESS' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' goto MAIN.PIXELTYPE.NEXT ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Summary and cleanup... ; ; We passed... :MAIN.PASS free handle image.handle echo.passfail 'SUMMARY' 'pass' return 'pass' ; ; Ruh-roh... :MAIN.ERROR.ECHOPASSFAIL free handle image.handle echo.passfail '${get:indent}${get:name}' 'fail - ${sts:} ${ret:}' echo.passfail 'SUMMARY' 'fail' setglobal '${arg:2}' 'fail' return 'fail' ================================================ FILE: twaincs/source/twaincscert/source/data/certification/060 - UI Image Transfer Tests/Certification.tc ================================================ ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; UI Image Transfer Tests ; Confirm that multiple MSG_ENABLEDS and MSG_DISABLEDS calls can be made in the context of ; one MSG_OPENDS / MSG_CLOSEDS. This test focuses on image capture with no UI, verifying ; that the Application does not have to close the driver after capturing images. ; ; Arguments ; arg:1 - TW_IDENTITY.ProductName of scanner to test ; arg:2 - global to set on fail ; ; Globals ; (none) ; ; Locals ; twidentity.productname - product name of scanner to test ; certifyresult - global to set on fail ; xfermech - result of getting ICAP_XFERMECH ; sheets - count of sheets the user needs ; ; Returns ; (none) ; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Initialize stuff, load tables if not already done for us... ; echo.titlesuite 'UI Image Transfer Tests v1.0 03-Mar-2020' setlocal twidentity.productname '${arg:1}' setlocal certifyresult '${arg:2}' setlocal sheets '0' if '${get:TW_ARRAY.ItemType}' != '' goto MAIN.LOADTABLES.SKIP run '${folder:certification}/LoadTables' :MAIN.LOADTABLES.SKIP ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Open the scanner... ; call CERTIFY '${folder:certification}/Opends' '${get:twidentity.productname}' '${get:certifyresult}' if '${get:${get:certifyresult}}' == 'fail' goto MAIN.CLOSEDS ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Prompt the user, if they have an ADF... ; :MAIN.PROMPT if '${get:g_skipprompts}' != '' goto MAIN.SKIP.PROMPTS dsmentry src ds dg_control dat_capability msg_get 'CAP_FEEDERENABLED,0,0,0' if '${ret:}' !~contains 'TRUE' goto MAIN.SKIP.PROMPTS dsmentry src ds dg_control dat_capability msg_get 'ICAP_XFERMECH,0,0,0' setlocal xfermech '${ret:}' dsmentry src ds dg_control dat_capability msg_get 'ICAP_PIXELTYPE,0,0,0' if '${ret:}' !~contains 'TWPT_BW' goto MAIN.PROMPTS.SKIP.BW increment sheets '${get:sheets}' '${getindex:xfermech:${get:TW_ENUMERATION.NumItems}}' :MAIN.PROMPTS.SKIP.BW if '${ret:}' !~contains 'TWPT_GRAY' goto MAIN.PROMPTS.SKIP.GRAY increment sheets '${get:sheets}' '${getindex:xfermech:${get:TW_ENUMERATION.NumItems}}' :MAIN.PROMPTS.SKIP.GRAY if '${ret:}' !~contains 'TWPT_RGB' goto MAIN.PROMPTS.SKIP.RGB increment sheets '${get:sheets}' '${getindex:xfermech:${get:TW_ENUMERATION.NumItems}}' :MAIN.PROMPTS.SKIP.RGB echo.prompt echo.prompt "Scanning will take place during this test. The SCAN button" echo.prompt "on the TWAIN user interface must be pressed. This may also" echo.prompt "have names like START or ACQUIRE." echo.prompt echo.prompt "Place ${get:sheets} sheets of paper in the scanner's feeder." pause '(press the ENTER key when ready to continue)' echo.prompt :MAIN.SKIP.PROMPTS ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Get ICAP_XFERMECH... ; setlocal name 'ICAP_XFERMECH MSG_GET' dsmentry src ds dg_control dat_capability msg_get 'ICAP_XFERMECH,0,0,0' if '${sts:}' != 'SUCCESS' goto CERTIFY.FAIL setlocal xfermech '${ret:}' echo.passfail '${get:name}' 'pass' ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Do the tests... ; call CERTIFY 'DAT_IMAGENATIVEXFER' '${get:twidentity.productname}' '${get:certifyresult}' 'TRUE' '${folder:parent}' call CERTIFY 'DAT_IMAGEMEMXFER' '${get:twidentity.productname}' '${get:certifyresult}' 'TRUE' '${folder:parent}' call CERTIFY 'DAT_IMAGEFILEXFER' '${get:twidentity.productname}' '${get:certifyresult}' 'TRUE' '${folder:parent}' '${get:xfermech}' call CERTIFY 'DAT_IMAGEMEMFILEXFER' '${get:twidentity.productname}' '${get:certifyresult}' 'TRUE' '${folder:parent}' '${get:xfermech}' :MAIN.CLOSEDS call CERTIFY '${folder:certification}/Closeds' '${get:twidentity.productname}' '${get:certifyresult}' return ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Function: Certify ; arg:1 - script to run ; arg:2 - TW_IDENTITY.ProductName of scanner to test ; arg:3 - global value to update on fail ; arg:4 - showui value ; arg:5 - name of test ; arg:6 - xfermech values ; returns: (none) ; :CERTIFY ; run '${arg:1}' '${arg:2}' '${arg:3}' '${arg:4}' '${arg:5}' '${arg:6}' if '${ret:}' != 'pass' goto CERTIFY.FAIL return 'pass' ; :CERTIFY.FAIL setglobal '${arg:3}' 'fail' return 'fail' ================================================ FILE: twaincs/source/twaincscert/source/data/certification/060 - UI Image Transfer Tests/DAT_IMAGEFILEXFER.tc ================================================ ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; DAT_IMAGEFILEXFER ; This test issues multiple image transfer sessions using DAT_IMAGEFILEXFER. It is performed ; for all available image sources (unspecified, flatbed and/or ADF). Only one image is transferred ; per session. ; ; We follow the capability ordering, so the loops take the form: ; set ICAP_XFERMECH TWSX_FILE ; foreach CAP_FEEDERENABLED ; foreach ICAP_PIXELTYPE ; scan ; end ; end ; ; Arguments ; arg:1 - TW_IDENTITY.ProductName of scanner to test ; arg:2 - global for us to update on failure ; arg:3 - value of ShowUI (TRUE or FALSE) ; arg:4 - test name for the image folder ; arg:5 - result of a MSG_GET on ICAP_XFERMECH ; ; Globals ; (none) ; ; Locals ; name - current test being done ; indent - indent the passfail text ; twimageinfo.compression - compression for current image ; showui - value of showui ; ; image.count - count of images from 1 ; image.folder - folder to put the images in ; image.prefix - adf or fb ; ; feederenabled.list - scanner's feederenabled values ; feederenabled.index - index of feederenabled values ; feederenabled.value - current feederenabled value ; ; pixeltype.list - scanner's pixeltype values for this feederenabled ; pixeltype.index - index of pixeltype values ; pixeltype.value - current pixeltype value ; ; Returns ; pass or fail ; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; If not supported, quietly leave... ; if '${arg:5}' ~contains 'TWSX_FILE' goto MAIN.CONTINUE return 'pass' :MAIN.CONTINUE ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Initialize... ; echo.titletest 'DAT_IMAGEFILEXFER' setlocal indent '' setlocal image.count '0' setlocal image.folder '${folder:certimages}/${arg:4}/DAT_IMAGEFILEXFER' setlocal image.prefix 'fb' setlocal image.showname '' setlocal showui '${arg:3}' ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Clean the image folder for this test... ; image cleanfolder '${get:image.folder}' ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; MSG_RESETALL ; If return code is not TWRC_SUCCESS, end with an error ; setlocal name 'MSG_RESETALL' dsmentry src ds dg_control dat_capability msg_resetall '0,0,0,0' if '${sts:}' != 'SUCCESS' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Get and set ICAP_XFERMECH... ; setlocal name 'ICAP_XFERMECH MSG_GET' dsmentry src ds dg_control dat_capability msg_get 'ICAP_XFERMECH,0,0,0' if '${sts:}' != 'SUCCESS' goto MAIN.ERROR.ECHOPASSFAIL if '${ret:}' !~contains 'TWSX_FILE' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' ; setlocal name 'ICAP_XFERMECH MSG_SET TWSX_FILE' dsmentry src ds dg_control dat_capability msg_set 'ICAP_XFERMECH,TWON_ONEVALUE,TWTY_UINT16,TWSX_FILE' if '${sts:}' != 'SUCCESS' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Get CAP_FEEDERENABLED, and loop so we test all values ; for the current ICAP_XFERMECH setting. ; setlocal name 'CAP_FEEDERENABLED MSG_GET' dsmentry src ds dg_control dat_capability msg_get 'CAP_FEEDERENABLED,0,0,0' if '${sts:}' != 'SUCCESS' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' ; setlocal feederenabled.list '${ret:}' ; what the scanner told us setlocal feederenabled.index '${get:TW_ENUMERATION.ItemList}' ; point to itemlist increment feederenabled.index '${get:feederenabled.index}' -1 ; less 1 ; :MAIN.FEEDERENABLED.NEXT setlocal indent '' setlocal image.count '0' ; reset count to 0 increment feederenabled.index '${get:feederenabled.index}' 1 ; next itemlist setlocal feederenabled.value '${getindex:feederenabled.list:${get:feederenabled.index}}' ; get the value if '${get:feederenabled.value}' == '' goto MAIN.PASS ; we've passed all tests!!! ; setlocal name 'CAP_FEEDERENABLED MSG_SET ${get:feederenabled.value}' dsmentry src ds dg_control dat_capability msg_set 'CAP_FEEDERENABLED,TWON_ONEVALUE,TWTY_BOOL,${get:feederenabled.value}' if '${sts:}' != 'SUCCESS' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' ; if '${get:feederenabled.value}' ~~ 'FALSE' goto MAIN.FEEDERENABLED.SETFB setlocal image.prefix 'adf' goto MAIN.FEEDERENABLED.SETDONE :MAIN.FEEDERENABLED.SETFB setlocal image.prefix 'fb' :MAIN.FEEDERENABLED.SETDONE ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Get ICAP_PIXELTYPE, and loop so we test all values for ; the current CAP_FEEDERENABLED setting. ; setlocal indent ' ' setlocal name 'ICAP_PIXELTYPE MSG_GET' dsmentry src ds dg_control dat_capability msg_get 'ICAP_PIXELTYPE,0,0,0' if '${sts:}' != 'SUCCESS' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' ; setlocal pixeltype.list '${ret:}' ; what the scanner told us setlocal pixeltype.index '${get:TW_ENUMERATION.ItemList}' ; point to itemlist increment pixeltype.index '${get:pixeltype.index}' -1 ; less 1 ; :MAIN.PIXELTYPE.NEXT setlocal indent ' ' increment pixeltype.index '${get:pixeltype.index}' 1 ; next itemlist setlocal pixeltype.value '${getindex:pixeltype.list:${get:pixeltype.index}}' ; get the value if '${get:pixeltype.value}' == '' goto MAIN.FEEDERENABLED.NEXT ; pixeltypes done for this feederenabled ; setlocal name 'ICAP_PIXELTYPE MSG_SET ${get:pixeltype.value}' dsmentry src ds dg_control dat_capability msg_set 'ICAP_PIXELTYPE,TWON_ONEVALUE,TWTY_UINT16,${get:pixeltype.value}' if '${sts:}' != 'SUCCESS' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; If we're a flatbed, we can start scanning... ; setlocal indent ' ' if '${get:feederenabled.value}' ~~ 'FALSE' goto MAIN.USERINTERFACE ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Check for paper in the feeder... ; dsmentry src ds dg_control dat_capability msg_getcurrent 'CAP_FEEDERLOADED,0,0,0' if '${sts:}' != 'SUCCESS' goto MAIN.FEEDERLOADED.DONE if '${ret:${get:TW_ONEVALUE.Item}}' ~~ 'TRUE' goto MAIN.FEEDERLOADED.DONE echo.prompt echo.prompt "Place paper in the scanner's feeder." pause '(press the ENTER key when ready to continue)' :MAIN.FEEDERLOADED.DONE ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; We only need one sheet of paper... ; setlocal name 'CAP_XFERCOUNT MSG_SET 1' dsmentry src ds dg_control dat_capability msg_set 'CAP_XFERCOUNT,TWON_ONEVALUE,TWTY_INT16,1' if '${sts:}' != 'SUCCESS' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Start scanning... ; :MAIN.USERINTERFACE setlocal name 'dg_control/dat_userinterface/msg_enableds' wait reset dsmentry src null dg_control dat_userinterface msg_enableds '${get:showui},0' if '${sts:}' != 'SUCCESS' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Wait for MSG_XFERREADY, if we don't see it then scoot... ; setlocal name 'wait ${get:sys_waittimeout} seconds for MSG_XFERREADY' wait '${get:sys_waittimeout}000' if '${ret:}' !~contains 'msg_xferready' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Get information about the image... ; :MAIN.IMAGEINFO.NEXT setlocal name 'dg_image/dat_imageinfo/msg_get' dsmentry src ds dg_image dat_imageinfo msg_get '0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0' if '${sts:}' != 'SUCCESS' goto MAIN.ERROR.ECHOPASSFAIL setlocal twimageinfo.compression '${ret:${get:index.twimageinfo.compression}}' echo.passfail '${get:indent}${get:name}' 'pass' ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Set up the file transfer... ; increment image.count '${get:image.count}' 1 if '${get:twimageinfo.compression}' == 'JPEG' goto MAIN.SETUPFILEXFER.JPEG setlocal image.showname 'DAT_IMAGEFILEXFER/${get:image.prefix}${format:D6|${get:image.count}}.tif' setlocal twsetupfilexfer.filename '${get:image.folder}/${get:image.prefix}${format:D6|${get:image.count}}.tif' setlocal twsetupfilexfer.format 'TWFF_TIFF' goto MAIN.SETUPFILEXFER :MAIN.SETUPFILEXFER.JPEG setlocal image.showname 'DAT_IMAGEFILEXFER/${get:image.prefix}${format:D6|${get:image.count}}.jpg' setlocal twsetupfilexfer.filename '${get:image.folder}/${get:image.prefix}${format:D6|${get:image.count}}.jpg' setlocal twsetupfilexfer.format 'TWFF_JFIF' :MAIN.SETUPFILEXFER setlocal name 'dg_control/dat_setupfilexfer/msg_set' dsmentry src ds dg_control dat_setupfilexfer msg_set '"${get:twsetupfilexfer.filename}",${get:twsetupfilexfer.format},0' if '${sts:}' != 'SUCCESS' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Transfer the image... ; setlocal name 'dg_image/dat_imagefilexfer/msg_get' dsmentry src ds dg_image dat_imagefilexfer msg_get null if '${sts:}' != 'XFERDONE' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' echo.passfail '${get:indent}image <${get:image.showname}>' 'pass' ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; End the transfer, see if we're done... ; setlocal name 'dg_control/dat_pendingxfers/msg_endxfer' dsmentry src ds dg_control dat_pendingxfers msg_endxfer '0,0' if '${sts:}' != 'SUCCESS' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' if '${ret:${get:TW_PENDINGXFERS.Count}}' != '0' goto MAIN.IMAGEINFO.NEXT ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; We're out of images, so disable and go back up to ; do the next ICAP_PIXELTYPE... ; setlocal name 'dg_control/dat_userinterface/msg_disableds' dsmentry src ds dg_control dat_userinterface msg_disableds '0,0' if '${sts:}' != 'SUCCESS' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' goto MAIN.PIXELTYPE.NEXT ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Summary and cleanup... ; ; We passed... :MAIN.PASS echo.passfail 'SUMMARY' 'pass' return 'pass' ; ; Ruh-roh... :MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'fail - ${sts:} ${ret:}' echo.passfail 'SUMMARY' 'fail' setglobal '${arg:2}' 'fail' return 'fail' ================================================ FILE: twaincs/source/twaincscert/source/data/certification/060 - UI Image Transfer Tests/DAT_IMAGEMEMFILEXFER.tc ================================================ ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; DAT_IMAGEMEMFILEXFER ; This test issues multiple image transfer sessions using DAT_IMAGEMEMFILEXFER. It is performed ; for all available image sources (unspecified, flatbed and/or ADF). Only one image is transferred ; per session. ; ; We follow the capability ordering, so the loops take the form: ; set ICAP_XFERMECH TWSX_MEMFILE ; foreach CAP_FEEDERENABLED ; foreach ICAP_PIXELTYPE ; scan ; end ; end ; ; Arguments ; arg:1 - TW_IDENTITY.ProductName of scanner to test ; arg:2 - global for us to update on failure ; arg:3 - value of ShowUI (TRUE or FALSE) ; arg:4 - test name for the image folder ; arg:5 - result of a MSG_GET on ICAP_XFERMECH ; ; Globals ; (none) ; ; Locals ; name - current test being done ; indent - indent the passfail text ; imagememxfer - result of DAT_IMAGEMEMXFER call ; setupmemxfer.preferred - preferred field from DAT_SETUPMEMXFER call ; ; image.count - count of images from 1 ; image.folder - folder to put the images in ; image.prefix - adf or fb ; ; feederenabled.list - scanner's feederenabled values ; feederenabled.index - index of feederenabled values ; feederenabled.value - current feederenabled value ; ; pixeltype.list - scanner's pixeltype values for this feederenabled ; pixeltype.index - index of pixeltype values ; pixeltype.value - current pixeltype value ; ; Returns ; pass or fail ; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; If not supported, quietly leave... ; if '${arg:5}' ~contains 'TWSX_MEMFILE' goto MAIN.CONTINUE return 'pass' :MAIN.CONTINUE ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Initialize... ; echo.titletest 'DAT_IMAGEMEMFILEXFER' setlocal indent '' setlocal image.pointer '0' setlocal image.count '0' setlocal image.folder '${folder:certimages}/${arg:4}/DAT_IMAGEMEMFILEXFER' setlocal image.prefix 'fb' setlocal showui '${arg:3}' ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Clean the image folder for this test... ; image cleanfolder '${get:image.folder}' ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; MSG_RESETALL ; If return code is not TWRC_SUCCESS, end with an error ; setlocal name 'MSG_RESETALL' dsmentry src ds dg_control dat_capability msg_resetall '0,0,0,0' if '${sts:}' != 'SUCCESS' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Get and set ICAP_XFERMECH... ; setlocal name 'ICAP_XFERMECH MSG_GET' dsmentry src ds dg_control dat_capability msg_get 'ICAP_XFERMECH,0,0,0' if '${sts:}' != 'SUCCESS' goto MAIN.ERROR.ECHOPASSFAIL if '${ret:}' !~contains 'TWSX_MEMFILE' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' ; setlocal name 'ICAP_XFERMECH MSG_SET TWSX_MEMFILE' dsmentry src ds dg_control dat_capability msg_set 'ICAP_XFERMECH,TWON_ONEVALUE,TWTY_UINT16,TWSX_MEMFILE' if '${sts:}' != 'SUCCESS' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Get CAP_FEEDERENABLED, and loop so we test all values ; for the current ICAP_XFERMECH setting. ; setlocal name 'CAP_FEEDERENABLED MSG_GET' dsmentry src ds dg_control dat_capability msg_get 'CAP_FEEDERENABLED,0,0,0' if '${sts:}' != 'SUCCESS' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' ; setlocal feederenabled.list '${ret:}' ; what the scanner told us setlocal feederenabled.index '${get:TW_ENUMERATION.ItemList}' ; point to itemlist increment feederenabled.index '${get:feederenabled.index}' -1 ; less 1 ; :MAIN.FEEDERENABLED.NEXT setlocal indent '' setlocal image.count '0' ; reset count to 0 increment feederenabled.index '${get:feederenabled.index}' 1 ; next itemlist setlocal feederenabled.value '${getindex:feederenabled.list:${get:feederenabled.index}}' ; get the value if '${get:feederenabled.value}' == '' goto MAIN.PASS ; we've passed all tests!!! ; setlocal name 'CAP_FEEDERENABLED MSG_SET ${get:feederenabled.value}' dsmentry src ds dg_control dat_capability msg_set 'CAP_FEEDERENABLED,TWON_ONEVALUE,TWTY_BOOL,${get:feederenabled.value}' if '${sts:}' != 'SUCCESS' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' ; if '${get:feederenabled.value}' ~~ 'FALSE' goto MAIN.FEEDERENABLED.SETFB setlocal image.prefix 'adf' goto MAIN.FEEDERENABLED.SETDONE :MAIN.FEEDERENABLED.SETFB setlocal image.prefix 'fb' :MAIN.FEEDERENABLED.SETDONE ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Get ICAP_PIXELTYPE, and loop so we test all values for ; the current CAP_FEEDERENABLED setting. ; setlocal indent ' ' setlocal name 'ICAP_PIXELTYPE MSG_GET' dsmentry src ds dg_control dat_capability msg_get 'ICAP_PIXELTYPE,0,0,0' if '${sts:}' != 'SUCCESS' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' ; setlocal pixeltype.list '${ret:}' ; what the scanner told us setlocal pixeltype.index '${get:TW_ENUMERATION.ItemList}' ; point to itemlist increment pixeltype.index '${get:pixeltype.index}' -1 ; less 1 ; :MAIN.PIXELTYPE.NEXT setlocal indent ' ' increment pixeltype.index '${get:pixeltype.index}' 1 ; next itemlist setlocal pixeltype.value '${getindex:pixeltype.list:${get:pixeltype.index}}' ; get the value if '${get:pixeltype.value}' == '' goto MAIN.FEEDERENABLED.NEXT ; pixeltypes done for this feederenabled ; setlocal name 'ICAP_PIXELTYPE MSG_SET ${get:pixeltype.value}' dsmentry src ds dg_control dat_capability msg_set 'ICAP_PIXELTYPE,TWON_ONEVALUE,TWTY_UINT16,${get:pixeltype.value}' if '${sts:}' != 'SUCCESS' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Get the preferred size for memory transfers, and allocate ; a pointer for the memory transfers... ; setlocal indent ' ' setlocal name 'dg_control/dat_setupmemxfer/msg_get' dsmentry src ds dg_control dat_setupmemxfer msg_get '0,0,0' if '${sts:}' != 'SUCCESS' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' ; setlocal name 'TW_SETUPMEMXFER.Preferred > 0' setlocal setupmemxfer.preferred '${ret:${get:TW_SETUPMEMXFER.Preferred}}' if '${get:setupmemxfer.preferred}' <= '0' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' ; setlocal name 'allocate pointer for ${get:setupmemxfer.preferred} bytes' free pointer image.pointer ; for the last loop allocate pointer image.pointer '${get:setupmemxfer.preferred}' if '${get:image.pointer}' == '0' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Set DAT_SETUPFILEXFER to TWFF_TIFF ; setlocal name 'dg_control/dat_setupfilexfer/msg_set TWFF_TIFF' dsmentry src null dg_control dat_setupfilexfer msg_set 'file,TWFF_TIFF,0' if '${sts:}' != 'SUCCESS' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; If we're a flatbed, we can start scanning... ; if '${get:feederenabled.value}' ~~ 'FALSE' goto MAIN.USERINTERFACE ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Check for paper in the feeder... ; dsmentry src ds dg_control dat_capability msg_getcurrent 'CAP_FEEDERLOADED,0,0,0' if '${sts:}' != 'SUCCESS' goto MAIN.FEEDERLOADED.DONE if '${ret:${get:TW_ONEVALUE.Item}}' ~~ 'TRUE' goto MAIN.FEEDERLOADED.DONE echo.prompt echo.prompt "Place paper in the scanner's feeder." pause '(press the ENTER key when ready to continue)' :MAIN.FEEDERLOADED.DONE ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; We only need one sheet of paper... ; setlocal name 'CAP_XFERCOUNT MSG_SET 1' dsmentry src ds dg_control dat_capability msg_set 'CAP_XFERCOUNT,TWON_ONEVALUE,TWTY_INT16,1' if '${sts:}' != 'SUCCESS' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Start scanning... ; :MAIN.USERINTERFACE setlocal name 'dg_control/dat_userinterface/msg_enableds' wait reset dsmentry src null dg_control dat_userinterface msg_enableds '${get:showui},0' if '${sts:}' != 'SUCCESS' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Wait for MSG_XFERREADY, if we don't see it then scoot... ; setlocal name 'wait ${get:sys_waittimeout} seconds for MSG_XFERREADY' wait '${get:sys_waittimeout}000' if '${ret:}' !~contains 'msg_xferready' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Do a memory file transfer... ; This little song and dance with the states is so that we can ; start the transfer in state 6 with each new image, but switch ; to state 7 if we need multiple calls to capture the current ; image... ; ; The saved images will be in TIFF format, which includes TIFF ; JPEG (the better form, where a simple TIFF header is added). ; increment image.count '${get:image.count}' 1 image free memfileimage ; :MAIN.IMAGEMEMFILEXFER.NEXT setlocal name 'dg_image/dat_imagememxfer/msg_get' dsmentry src ds dg_image dat_imagememfilexfer msg_get '0,0,0,0,0,0,0,9,${get:setupmemxfer.preferred},${get:image.pointer}' setlocal imagememxfer '${ret:}' if '${sts:}' == 'XFERDONE' goto MAIN.IMAGEMEMFILEXFER.XFERDONE if '${sts:}' != 'SUCCESS' goto MAIN.ERROR.ECHOPASSFAIL ; echo.passfail '${get:indent}${get:name} SUCCESS' 'pass' image append memfileimage '${get:imagememxfer}' goto MAIN.IMAGEMEMFILEXFER.NEXT ; :MAIN.IMAGEMEMFILEXFER.XFERDONE echo.passfail '${get:indent}${get:name} XFERDONE' 'pass' image append memfileimage '${get:imagememxfer}' image save memfileimage memfile '${get:image.folder}/${get:image.prefix}${format:D6|${get:image.count}}' echo.passfail '${get:indent}image <${ret:}>' 'pass' image free memfileimage ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; End the transfer, see if we're done... ; setlocal name 'dg_control/dat_pendingxfers/msg_endxfer' dsmentry src ds dg_control dat_pendingxfers msg_endxfer '0,0' if '${sts:}' != 'SUCCESS' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' if '${ret:${get:TW_PENDINGXFERS.Count}}' != '0' goto MAIN.IMAGEMEMFILEXFER.NEXT ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; We're out of images, so disable and go back up to ; do the next ICAP_PIXELTYPE... ; setlocal name 'dg_control/dat_userinterface/msg_disableds' dsmentry src ds dg_control dat_userinterface msg_disableds '0,0' if '${sts:}' != 'SUCCESS' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' goto MAIN.PIXELTYPE.NEXT ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Summary and cleanup... ; ; We passed... :MAIN.PASS image free memfileimage free pointer image.pointer echo.passfail 'SUMMARY' 'pass' return 'pass' ; ; Ruh-roh... :MAIN.ERROR.ECHOPASSFAIL image free memfileimage free pointer image.pointer echo.passfail '${get:indent}${get:name}' 'fail - ${sts:} ${ret:}' echo.passfail 'SUMMARY' 'fail' setglobal '${arg:2}' 'fail' return 'fail' ================================================ FILE: twaincs/source/twaincscert/source/data/certification/060 - UI Image Transfer Tests/DAT_IMAGEMEMXFER.tc ================================================ ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; DAT_IMAGEMEMXFER ; This test issues multiple image transfer sessions using DAT_IMAGEMEMXFER. It is performed ; for all available image sources (unspecified, flatbed and/or ADF). Only one image is transferred ; per session. ; ; We follow the capability ordering, so the loops take the form: ; set ICAP_XFERMECH TWSX_MEMORY ; foreach CAP_FEEDERENABLED ; foreach ICAP_PIXELTYPE ; scan ; end ; end ; ; Arguments ; arg:1 - TW_IDENTITY.ProductName of scanner to test ; arg:2 - global for us to update on failure ; arg:3 - value of ShowUI (TRUE or FALSE) ; arg:4 - test name for the image folder ; ; Globals ; (none) ; ; Locals ; name - current test being done ; indent - indent the passfail text ; imageinfo - metadata for the current image ; imagememxfer - result of DAT_IMAGEMEMXFER call ; setupmemxfer.preferred - preferred field from DAT_SETUPMEMXFER call ; ; image.count - count of images from 1 ; image.folder - folder to put the images in ; image.prefix - adf or fb ; ; feederenabled.list - scanner's feederenabled values ; feederenabled.index - index of feederenabled values ; feederenabled.value - current feederenabled value ; ; pixeltype.list - scanner's pixeltype values for this feederenabled ; pixeltype.index - index of pixeltype values ; pixeltype.value - current pixeltype value ; ; Returns ; pass or fail ; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Initialize... ; echo.titletest 'DAT_IMAGEMEMXFER' setlocal indent '' setlocal image.pointer '0' setlocal image.count '0' setlocal image.folder '${folder:certimages}/${arg:4}/DAT_IMAGEMEMXFER' setlocal image.prefix 'fb' setlocal showui '${arg:3}' ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Clean the image folder for this test... ; image cleanfolder '${get:image.folder}' ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; MSG_RESETALL ; If return code is not TWRC_SUCCESS, end with an error ; setlocal name 'MSG_RESETALL' dsmentry src ds dg_control dat_capability msg_resetall '0,0,0,0' if '${sts:}' != 'SUCCESS' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Get and set ICAP_XFERMECH... ; setlocal name 'ICAP_XFERMECH MSG_GET' dsmentry src ds dg_control dat_capability msg_get 'ICAP_XFERMECH,0,0,0' if '${sts:}' != 'SUCCESS' goto MAIN.ERROR.ECHOPASSFAIL if '${ret:}' !~contains 'TWSX_MEMORY' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' ; setlocal name 'ICAP_XFERMECH MSG_SET TWSX_MEMORY' dsmentry src ds dg_control dat_capability msg_set 'ICAP_XFERMECH,TWON_ONEVALUE,TWTY_UINT16,TWSX_MEMORY' if '${sts:}' != 'SUCCESS' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Get CAP_FEEDERENABLED, and loop so we test all values ; for the current ICAP_XFERMECH setting. ; setlocal name 'CAP_FEEDERENABLED MSG_GET' dsmentry src ds dg_control dat_capability msg_get 'CAP_FEEDERENABLED,0,0,0' if '${sts:}' != 'SUCCESS' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' ; setlocal feederenabled.list '${ret:}' ; what the scanner told us setlocal feederenabled.index '${get:TW_ENUMERATION.ItemList}' ; point to itemlist increment feederenabled.index '${get:feederenabled.index}' -1 ; less 1 ; :MAIN.FEEDERENABLED.NEXT setlocal indent '' setlocal image.count '0' ; reset count to 0 increment feederenabled.index '${get:feederenabled.index}' 1 ; next itemlist setlocal feederenabled.value '${getindex:feederenabled.list:${get:feederenabled.index}}' ; get the value if '${get:feederenabled.value}' == '' goto MAIN.PASS ; we've passed all tests!!! ; setlocal name 'CAP_FEEDERENABLED MSG_SET ${get:feederenabled.value}' dsmentry src ds dg_control dat_capability msg_set 'CAP_FEEDERENABLED,TWON_ONEVALUE,TWTY_BOOL,${get:feederenabled.value}' if '${sts:}' != 'SUCCESS' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' ; if '${get:feederenabled.value}' ~~ 'FALSE' goto MAIN.FEEDERENABLED.SETFB setlocal image.prefix 'adf' goto MAIN.FEEDERENABLED.SETDONE :MAIN.FEEDERENABLED.SETFB setlocal image.prefix 'fb' :MAIN.FEEDERENABLED.SETDONE ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Get ICAP_PIXELTYPE, and loop so we test all values for ; the current CAP_FEEDERENABLED setting. ; setlocal indent ' ' setlocal name 'ICAP_PIXELTYPE MSG_GET' dsmentry src ds dg_control dat_capability msg_get 'ICAP_PIXELTYPE,0,0,0' if '${sts:}' != 'SUCCESS' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' ; setlocal pixeltype.list '${ret:}' ; what the scanner told us setlocal pixeltype.index '${get:TW_ENUMERATION.ItemList}' ; point to itemlist increment pixeltype.index '${get:pixeltype.index}' -1 ; less 1 ; :MAIN.PIXELTYPE.NEXT setlocal indent ' ' increment pixeltype.index '${get:pixeltype.index}' 1 ; next itemlist setlocal pixeltype.value '${getindex:pixeltype.list:${get:pixeltype.index}}' ; get the value if '${get:pixeltype.value}' == '' goto MAIN.FEEDERENABLED.NEXT ; pixeltypes done for this feederenabled ; setlocal name 'ICAP_PIXELTYPE MSG_SET ${get:pixeltype.value}' dsmentry src ds dg_control dat_capability msg_set 'ICAP_PIXELTYPE,TWON_ONEVALUE,TWTY_UINT16,${get:pixeltype.value}' if '${sts:}' != 'SUCCESS' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Get the preferred size for memory transfers, and allocate ; a pointer for the memory transfers... ; setlocal indent ' ' setlocal name 'dg_control/dat_setupmemxfer/msg_get' dsmentry src ds dg_control dat_setupmemxfer msg_get '0,0,0' if '${sts:}' != 'SUCCESS' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' ; setlocal name 'TW_SETUPMEMXFER.Preferred > 0' setlocal setupmemxfer.preferred '${ret:${get:TW_SETUPMEMXFER.Preferred}}' if '${get:setupmemxfer.preferred}' <= '0' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' ; setlocal name 'allocate pointer for ${get:setupmemxfer.preferred} bytes' free pointer image.pointer ; for the last loop allocate pointer image.pointer '${get:setupmemxfer.preferred}' if '${get:image.pointer}' == '0' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; If we're a flatbed, we can start scanning... ; if '${get:feederenabled.value}' ~~ 'FALSE' goto MAIN.USERINTERFACE ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Check for paper in the feeder... ; dsmentry src ds dg_control dat_capability msg_getcurrent 'CAP_FEEDERLOADED,0,0,0' if '${sts:}' != 'SUCCESS' goto MAIN.FEEDERLOADED.DONE if '${ret:${get:TW_ONEVALUE.Item}}' ~~ 'TRUE' goto MAIN.FEEDERLOADED.DONE echo.prompt echo.prompt "Place paper in the scanner's feeder." pause '(press the ENTER key when ready to continue)' :MAIN.FEEDERLOADED.DONE ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; We only need one sheet of paper... ; setlocal name 'CAP_XFERCOUNT MSG_SET 1' dsmentry src ds dg_control dat_capability msg_set 'CAP_XFERCOUNT,TWON_ONEVALUE,TWTY_INT16,1' if '${sts:}' != 'SUCCESS' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Start scanning... ; :MAIN.USERINTERFACE setlocal name 'dg_control/dat_userinterface/msg_enableds' wait reset dsmentry src null dg_control dat_userinterface msg_enableds '${get:showui},0' if '${sts:}' != 'SUCCESS' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Wait for MSG_XFERREADY, if we don't see it then scoot... ; setlocal name 'wait ${get:sys_waittimeout} seconds for MSG_XFERREADY' wait '${get:sys_waittimeout}000' if '${ret:}' !~contains 'msg_xferready' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Do a memory transfer... ; This little song and dance with the states is so that we can ; start the transfer in state 6 with each new image, but switch ; to state 7 if we need multiple calls to capture the current ; image... ; ; The saved images will be in TIFF format, which includes TIFF ; JPEG (the better form, where a simple TIFF header is added). ; increment image.count '${get:image.count}' 1 image free memimage ; :MAIN.IMAGEMEMXFER.NEXT setlocal name 'dg_image/dat_imagememxfer/msg_get' dsmentry src ds dg_image dat_imagememxfer msg_get '0,0,0,0,0,0,0,9,${get:setupmemxfer.preferred},${get:image.pointer}' setlocal imagememxfer '${ret:}' if '${sts:}' == 'XFERDONE' goto MAIN.IMAGEMEMXFER.XFERDONE if '${sts:}' != 'SUCCESS' goto MAIN.ERROR.ECHOPASSFAIL ; echo.passfail '${get:indent}${get:name} SUCCESS' 'pass' image append memimage '${get:imagememxfer}' goto MAIN.IMAGEMEMXFER.NEXT ; :MAIN.IMAGEMEMXFER.XFERDONE echo.passfail '${get:indent}${get:name} XFERDONE' 'pass' ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; We need image info to make sense of this data... ; setlocal name 'dg_image/dat_imageinfo/msg_get' dsmentry src ds dg_image dat_imageinfo msg_get '0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0' setlocal imageinfo '${ret:}' if '${sts:}' != 'SUCCESS' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Save the image... ; image append memimage '${get:imagememxfer}' image addheader memimage '${get:imageinfo}' image save memimage memory '${get:image.folder}/${get:image.prefix}${format:D6|${get:image.count}}' echo.passfail '${get:indent}image <${ret:}>' 'pass' image free memimage ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; End the transfer, see if we're done... ; setlocal name 'dg_control/dat_pendingxfers/msg_endxfer' dsmentry src ds dg_control dat_pendingxfers msg_endxfer '0,0' if '${sts:}' != 'SUCCESS' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' if '${ret:${get:TW_PENDINGXFERS.Count}}' != '0' goto MAIN.IMAGEMEMXFER.NEXT ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; We're out of images, so disable and go back up to ; do the next ICAP_PIXELTYPE... ; setlocal name 'dg_control/dat_userinterface/msg_disableds' dsmentry src ds dg_control dat_userinterface msg_disableds '0,0' if '${sts:}' != 'SUCCESS' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' goto MAIN.PIXELTYPE.NEXT ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Summary and cleanup... ; ; We passed... :MAIN.PASS image free memfileimage free pointer image.pointer echo.passfail 'SUMMARY' 'pass' return 'pass' ; ; Ruh-roh... :MAIN.ERROR.ECHOPASSFAIL image free memimage free pointer image.pointer echo.passfail '${get:indent}${get:name}' 'fail - ${sts:} ${ret:}' echo.passfail 'SUMMARY' 'fail' setglobal '${arg:2}' 'fail' return 'fail' ================================================ FILE: twaincs/source/twaincscert/source/data/certification/060 - UI Image Transfer Tests/DAT_IMAGENATIVEXFER.tc ================================================ ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; DAT_IMAGENATIVEXFER ; This test issues multiple image transfer sessions using DAT_IMAGENATIVEXFER. It is performed ; for all available image sources (unspecified, flatbed and/or ADF). Only one image is transferred ; per session. ; ; We follow the capability ordering, so the loops take the form: ; set ICAP_XFERMECH TWSX_NATIVE ; foreach CAP_FEEDERENABLED ; foreach ICAP_PIXELTYPE ; scan ; end ; end ; ; Arguments ; arg:1 - TW_IDENTITY.ProductName of scanner to test ; arg:2 - global for us to update on failure ; arg:3 - value of ShowUI (TRUE or FALSE) ; arg:4 - test name for the image folder ; ; Globals ; (none) ; ; Locals ; name - current test being done ; indent - indent the passfail text ; ; image.handle - native handle ; image.count - count of images from 1 ; image.folder - folder to put the images in ; image.prefix - adf or fb ; ; feederenabled.list - scanner's feederenabled values ; feederenabled.index - index of feederenabled values ; feederenabled.value - current feederenabled value ; ; pixeltype.list - scanner's pixeltype values for this feederenabled ; pixeltype.index - index of pixeltype values ; pixeltype.value - current pixeltype value ; ; Returns ; pass or fail ; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Initialize... ; echo.titletest 'DAT_IMAGENATIVEXFER' setlocal indent '' setlocal image.handle '0' setlocal image.count '0' setlocal image.folder '${folder:certimages}/${arg:4}/DAT_IMAGENATIVEXFER' setlocal image.prefix 'fb' setlocal showui '${arg:3}' ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Clean the image folder for this test... ; image cleanfolder '${get:image.folder}' ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; MSG_RESETALL ; If return code is not TWRC_SUCCESS, end with an error ; setlocal name 'MSG_RESETALL' dsmentry src ds dg_control dat_capability msg_resetall '0,0,0,0' if '${sts:}' != 'SUCCESS' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Get and set ICAP_XFERMECH... ; setlocal name 'ICAP_XFERMECH MSG_GET' dsmentry src ds dg_control dat_capability msg_get 'ICAP_XFERMECH,0,0,0' if '${sts:}' != 'SUCCESS' goto MAIN.ERROR.ECHOPASSFAIL if '${ret:}' !~contains 'TWSX_NATIVE' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' ; setlocal name 'ICAP_XFERMECH MSG_SET TWSX_NATIVE' dsmentry src ds dg_control dat_capability msg_set 'ICAP_XFERMECH,TWON_ONEVALUE,TWTY_UINT16,TWSX_NATIVE' if '${sts:}' != 'SUCCESS' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Get CAP_FEEDERENABLED, and loop so we test all values ; for the current ICAP_XFERMECH setting. ; setlocal name 'CAP_FEEDERENABLED MSG_GET' dsmentry src ds dg_control dat_capability msg_get 'CAP_FEEDERENABLED,0,0,0' if '${sts:}' != 'SUCCESS' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' ; setlocal feederenabled.list '${ret:}' ; what the scanner told us setlocal feederenabled.index '${get:TW_ENUMERATION.ItemList}' ; point to itemlist increment feederenabled.index '${get:feederenabled.index}' -1 ; less 1 ; :MAIN.FEEDERENABLED.NEXT setlocal indent '' setlocal image.count '0' ; reset count to 0 increment feederenabled.index '${get:feederenabled.index}' 1 ; next itemlist setlocal feederenabled.value '${getindex:feederenabled.list:${get:feederenabled.index}}' ; get the value if '${get:feederenabled.value}' == '' goto MAIN.PASS ; we've passed all tests!!! ; setlocal name 'CAP_FEEDERENABLED MSG_SET ${get:feederenabled.value}' dsmentry src ds dg_control dat_capability msg_set 'CAP_FEEDERENABLED,TWON_ONEVALUE,TWTY_BOOL,${get:feederenabled.value}' if '${sts:}' != 'SUCCESS' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' ; if '${get:feederenabled.value}' ~~ 'FALSE' goto MAIN.FEEDERENABLED.SETFB setlocal image.prefix 'adf' goto MAIN.FEEDERENABLED.SETDONE :MAIN.FEEDERENABLED.SETFB setlocal image.prefix 'fb' :MAIN.FEEDERENABLED.SETDONE ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Get ICAP_PIXELTYPE, and loop so we test all values for ; the current CAP_FEEDERENABLED setting. ; setlocal indent ' ' setlocal name 'ICAP_PIXELTYPE MSG_GET' dsmentry src ds dg_control dat_capability msg_get 'ICAP_PIXELTYPE,0,0,0' if '${sts:}' != 'SUCCESS' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' ; setlocal pixeltype.list '${ret:}' ; what the scanner told us setlocal pixeltype.index '${get:TW_ENUMERATION.ItemList}' ; point to itemlist increment pixeltype.index '${get:pixeltype.index}' -1 ; less 1 ; :MAIN.PIXELTYPE.NEXT setlocal indent ' ' increment pixeltype.index '${get:pixeltype.index}' 1 ; next itemlist setlocal pixeltype.value '${getindex:pixeltype.list:${get:pixeltype.index}}' ; get the value if '${get:pixeltype.value}' == '' goto MAIN.FEEDERENABLED.NEXT ; pixeltypes done for this feederenabled ; setlocal name 'ICAP_PIXELTYPE MSG_SET ${get:pixeltype.value}' dsmentry src ds dg_control dat_capability msg_set 'ICAP_PIXELTYPE,TWON_ONEVALUE,TWTY_UINT16,${get:pixeltype.value}' if '${sts:}' != 'SUCCESS' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; If we're a flatbed, we can start scanning... ; setlocal indent ' ' if '${get:feederenabled.value}' ~~ 'FALSE' goto MAIN.USERINTERFACE ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Check for paper in the feeder... ; dsmentry src ds dg_control dat_capability msg_getcurrent 'CAP_FEEDERLOADED,0,0,0' if '${sts:}' != 'SUCCESS' goto MAIN.FEEDERLOADED.DONE if '${ret:${get:TW_ONEVALUE.Item}}' ~~ 'TRUE' goto MAIN.FEEDERLOADED.DONE echo.prompt echo.prompt "Place paper in the scanner's feeder." pause '(press the ENTER key when ready to continue)' :MAIN.FEEDERLOADED.DONE ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; We only need one sheet of paper... ; setlocal name 'CAP_XFERCOUNT MSG_SET 1' dsmentry src ds dg_control dat_capability msg_set 'CAP_XFERCOUNT,TWON_ONEVALUE,TWTY_INT16,1' if '${sts:}' != 'SUCCESS' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Start scanning... ; :MAIN.USERINTERFACE setlocal name 'dg_control/dat_userinterface/msg_enableds' wait reset dsmentry src null dg_control dat_userinterface msg_enableds '${get:showui},0' if '${sts:}' != 'SUCCESS' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Wait for MSG_XFERREADY, if we don't see it then scoot... ; setlocal name 'wait ${get:sys_waittimeout} seconds for MSG_XFERREADY' wait '${get:sys_waittimeout}000' if '${ret:}' !~contains 'msg_xferready' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Do a native transfer... ; :MAIN.IMAGENATIVEXFER.NEXT setlocal name 'dg_image/dat_imagenativexfer/msg_get' increment image.count '${get:image.count}' 1 dsmentry src ds dg_image dat_imagenativexfer msg_get '0' setlocal image.handle '${ret:}' if '${sts:}' != 'XFERDONE' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' image save image.handle native '${get:image.folder}/${get:image.prefix}${format:D6|${get:image.count}}' echo.passfail '${get:indent}image <${ret:}>' 'pass' free handle image.handle ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; End the transfer, see if we're done... ; setlocal name 'dg_control/dat_pendingxfers/msg_endxfer' dsmentry src ds dg_control dat_pendingxfers msg_endxfer '0,0' if '${sts:}' != 'SUCCESS' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' if '${ret:${get:TW_PENDINGXFERS.Count}}' != '0' goto MAIN.IMAGENATIVEXFER.NEXT ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; We're out of images, so disable and go back up to ; do the next ICAP_PIXELTYPE... ; setlocal name 'dg_control/dat_userinterface/msg_disableds' dsmentry src ds dg_control dat_userinterface msg_disableds '0,0' if '${sts:}' != 'SUCCESS' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' goto MAIN.PIXELTYPE.NEXT ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Summary and cleanup... ; ; We passed... :MAIN.PASS free handle image.handle echo.passfail 'SUMMARY' 'pass' return 'pass' ; ; Ruh-roh... :MAIN.ERROR.ECHOPASSFAIL free handle image.handle echo.passfail '${get:indent}${get:name}' 'fail - ${sts:} ${ret:}' echo.passfail 'SUMMARY' 'fail' setglobal '${arg:2}' 'fail' return 'fail' ================================================ FILE: twaincs/source/twaincscert/source/data/certification/070 - CAP_XFERCOUNT Tests/Certification.tc ================================================ ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; CAP_XFERCOUNT Tests ; Confirm that when the data source accepts various values for CAP_XFERCOUNT, that it ; returns the specified number of images. Test both flatbed and document feeders. ; ; Arguments ; arg:1 - TW_IDENTITY.ProductName of scanner to test ; arg:2 - global to set on fail ; ; Globals ; (none) ; ; Locals ; twidentity.productname - product name of scanner to test ; certifyresult - global to set on fail ; xfermech - result of getting ICAP_XFERMECH ; ; Returns ; (none) ; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Initialize stuff, load tables if not already done for us... ; echo.titlesuite 'CAP_XFERCOUNT Tests v1.0 04-Mar-2020' setlocal twidentity.productname '${arg:1}' setlocal certifyresult '${arg:2}' if '${get:TW_ARRAY.ItemType}' != '' goto MAIN.LOADTABLES.SKIP run '${folder:certification}/LoadTables' :MAIN.LOADTABLES.SKIP ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Run the tests... ; call CERTIFY '${folder:certification}/Opends' '${get:twidentity.productname}' '${get:certifyresult}' if '${get:${get:certifyresult}}' == 'fail' goto MAIN.CLOSEDS ; Get ICAP_XFERMECH... setlocal name 'ICAP_XFERMECH MSG_GET' dsmentry src ds dg_control dat_capability msg_get 'ICAP_XFERMECH,0,0,0' if '${sts:}' != 'SUCCESS' goto CERTIFY.FAIL setlocal xfermech '${ret:}' echo.passfail '${get:name}' 'pass' ; Do the tests... call CERTIFY 'DAT_IMAGENATIVEXFER' '${get:twidentity.productname}' '${get:certifyresult}' 'FALSE' '${folder:parent}' call CERTIFY 'DAT_IMAGEMEMXFER' '${get:twidentity.productname}' '${get:certifyresult}' 'FALSE' '${folder:parent}' call CERTIFY 'DAT_IMAGEFILEXFER' '${get:twidentity.productname}' '${get:certifyresult}' 'FALSE' '${folder:parent}' '${get:xfermech}' call CERTIFY 'DAT_IMAGEMEMFILEXFER' '${get:twidentity.productname}' '${get:certifyresult}' 'FALSE' '${folder:parent}' '${get:xfermech}' :MAIN.CLOSEDS call CERTIFY '${folder:certification}/Closeds' '${get:twidentity.productname}' '${get:certifyresult}' return ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Function: Certify ; arg:1 - script to run ; arg:2 - TW_IDENTITY.ProductName of scanner to test ; arg:3 - global value to update on fail ; arg:4 - showui value ; arg:5 - name of test ; arg:6 - xfermech values ; returns: (none) ; :CERTIFY ; run '${arg:1}' '${arg:2}' '${arg:3}' '${arg:4}' '${arg:5}' '${arg:6}' if '${ret:}' != 'pass' goto CERTIFY.FAIL return 'pass' ; :CERTIFY.FAIL setglobal '${arg:3}' 'fail' return 'fail' ================================================ FILE: twaincs/source/twaincscert/source/data/certification/070 - CAP_XFERCOUNT Tests/DAT_IMAGEFILEXFER.tc ================================================ ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; DAT_IMAGEFILEXFER ; This test sets CAP_XFERCOUNT to 0, 1 and -1 for a flatbed scanner. It expects an error for the ; value 0, and only one image to be transferred per scanning session for the values 1 and -1. ; ; We follow the capability ordering, so the loops take the form: ; set ICAP_XFERMECH TWSX_FILE ; foreach CAP_FEEDERENABLED ; foreach ICAP_PIXELTYPE ; scan ; end ; end ; ; Arguments ; arg:1 - TW_IDENTITY.ProductName of scanner to test ; arg:2 - global for us to update on failure ; arg:3 - value of ShowUI (TRUE or FALSE) ; arg:4 - test name for the image folder ; arg:5 - result of a MSG_GET on ICAP_XFERMECH ; ; Globals ; (none) ; ; Locals ; name - current test being done ; indent - indent the passfail text ; twimageinfo.compression - compression for current image ; showui - value of showui ; ; image.count - count of images from 1 ; image.folder - folder to put the images in ; image.folderone - path for CAP_XFERCOUNT=1 test ; image.folderall - path for CAP_XFERCOUNT=-1 test ; image.prefix - adf or fb ; image.testcount - count of images from 0 for a specific test ; ; feederenabled.list - scanner's feederenabled values ; feederenabled.index - index of feederenabled values ; feederenabled.value - current feederenabled value ; ; xfercount.test - number of test we're running ; ; Returns ; pass or fail ; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; If not supported, quietly leave... ; if '${arg:5}' ~contains 'TWSX_FILE' goto MAIN.CONTINUE return 'pass' :MAIN.CONTINUE ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Initialize... ; echo.titletest 'DAT_IMAGEFILEXFER' setlocal indent '' setlocal image.count '0' setlocal image.folder '' setlocal image.folderone '${folder:certimages}/${arg:4}/DAT_IMAGEFILEXFER/one' setlocal image.folderall '${folder:certimages}/${arg:4}/DAT_IMAGEFILEXFER/all' setlocal image.prefix 'fb' setlocal image.testcount '1' setlocal showui '${arg:3}' setlocal xfercount.test '0' ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Prompt the user, if they have an ADF... ; if '${get:g_skipprompts}' != '' goto MAIN.SKIP.PROMPTS dsmentry src ds dg_control dat_capability msg_get 'CAP_FEEDERENABLED,0,0,0' if '${ret:}' !~contains 'TRUE' goto MAIN.SKIP.PROMPTS echo.prompt echo.prompt "Scanning will take place during this test. There will be no" echo.prompt "need to press any button on the TWAIN user interface to start" echo.prompt "the scanner. A progress indicator may appear during scanning." echo.prompt echo.prompt "Place at least 3 sheets of paper in the scanner's feeder." pause '(press the ENTER key when ready to continue)' echo.prompt :MAIN.SKIP.PROMPTS ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Clean the image folder for this test... ; image cleanfolder '${get:image.folderone}' image cleanfolder '${get:image.folderall}' ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; MSG_RESETALL ; If return code is not TWRC_SUCCESS, end with an error ; setlocal name 'MSG_RESETALL' dsmentry src ds dg_control dat_capability msg_resetall '0,0,0,0' if '${sts:}' != 'SUCCESS' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Get and set ICAP_XFERMECH... ; setlocal name 'ICAP_XFERMECH MSG_GET' dsmentry src ds dg_control dat_capability msg_get 'ICAP_XFERMECH,0,0,0' if '${sts:}' != 'SUCCESS' goto MAIN.ERROR.ECHOPASSFAIL if '${ret:}' !~contains 'TWSX_FILE' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' ; setlocal name 'ICAP_XFERMECH MSG_SET TWSX_FILE' dsmentry src ds dg_control dat_capability msg_set 'ICAP_XFERMECH,TWON_ONEVALUE,TWTY_UINT16,TWSX_FILE' if '${sts:}' != 'SUCCESS' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Get CAP_FEEDERENABLED, and loop so we test all values ; for the current ICAP_XFERMECH setting. ; setlocal name 'CAP_FEEDERENABLED MSG_GET' dsmentry src ds dg_control dat_capability msg_get 'CAP_FEEDERENABLED,0,0,0' if '${sts:}' != 'SUCCESS' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' ; setlocal feederenabled.list '${ret:}' ; what the scanner told us setlocal feederenabled.index '${get:TW_ENUMERATION.ItemList}' ; point to itemlist increment feederenabled.index '${get:feederenabled.index}' -1 ; less 1 ; :MAIN.FEEDERENABLED.NEXT setlocal indent '' setlocal xfercount.test '0' ; reset the tests increment feederenabled.index '${get:feederenabled.index}' 1 ; next itemlist setlocal feederenabled.value '${getindex:feederenabled.list:${get:feederenabled.index}}' ; get the value if '${get:feederenabled.value}' == '' goto MAIN.PASS ; we've passed all tests!!! ; setlocal name 'CAP_FEEDERENABLED MSG_SET ${get:feederenabled.value}' dsmentry src ds dg_control dat_capability msg_set 'CAP_FEEDERENABLED,TWON_ONEVALUE,TWTY_BOOL,${get:feederenabled.value}' if '${sts:}' != 'SUCCESS' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' ; if '${get:feederenabled.value}' ~~ 'FALSE' goto MAIN.FEEDERENABLED.SETFB setlocal image.prefix 'adf' goto MAIN.FEEDERENABLED.SETDONE :MAIN.FEEDERENABLED.SETFB setlocal image.prefix 'fb' :MAIN.FEEDERENABLED.SETDONE ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Dispatch to the CAP_XFERCOUNT test we want to run... ; :MAIN.XFERCOUNT.NEXT setlocal indent ' ' increment xfercount.test '${get:xfercount.test}' 1 if '${get:xfercount.test}' == '1' goto MAIN.XFERCOUNT.TEST1 if '${get:xfercount.test}' == '2' goto MAIN.XFERCOUNT.TEST2 if '${get:xfercount.test}' == '3' goto MAIN.XFERCOUNT.TEST3 goto MAIN.FEEDERENABLED.NEXT ; we're done test with this paper source, go to the next one ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Set CAP_XFERCOUNT to 0... ; :MAIN.XFERCOUNT.TEST1 setlocal name 'CAP_XFERCOUNT == 0' dsmentry src ds dg_control dat_capability msg_set 'CAP_XFERCOUNT,TWON_ONEVALUE,TWTY_INT16,0' if '${sts:}' == 'SUCCESS' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' goto MAIN.XFERCOUNT.NEXT ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Set CAP_XFERCOUNT to 1... ; :MAIN.XFERCOUNT.TEST2 setlocal name 'CAP_XFERCOUNT == 1' dsmentry src ds dg_control dat_capability msg_set 'CAP_XFERCOUNT,TWON_ONEVALUE,TWTY_INT16,1' if '${sts:}' != 'SUCCESS' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' setlocal image.folder '${get:image.folderone}' goto MAIN.FEEDERLOADED ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Set CAP_XFERCOUNT to -1... ; :MAIN.XFERCOUNT.TEST3 setlocal name 'CAP_XFERCOUNT == -1' dsmentry src ds dg_control dat_capability msg_set 'CAP_XFERCOUNT,TWON_ONEVALUE,TWTY_INT16,-1' if '${sts:}' != 'SUCCESS' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' setlocal image.folder '${get:image.folderall}' goto MAIN.FEEDERLOADED ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Check for paper in the feeder, skip for a flatbed... ; :MAIN.FEEDERLOADED if '${get:feederenabled.value}' ~~ 'FALSE' goto MAIN.FEEDERLOADED.DONE dsmentry src ds dg_control dat_capability msg_getcurrent 'CAP_FEEDERLOADED,0,0,0' if '${sts:}' != 'SUCCESS' goto MAIN.FEEDERLOADED.DONE if '${ret:${get:TW_ONEVALUE.Item}}' ~~ 'TRUE' goto MAIN.FEEDERLOADED.DONE echo.prompt echo.prompt "Place paper in the scanner's feeder." pause '(press the ENTER key when ready to continue)' :MAIN.FEEDERLOADED.DONE ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Start scanning... ; setlocal indent ' ' setlocal name 'dg_control/dat_userinterface/msg_enableds' setlocal image.testcount '1' ; reset to 1 wait reset dsmentry src null dg_control dat_userinterface msg_enableds '${get:showui},0' if '${sts:}' != 'SUCCESS' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Wait for MSG_XFERREADY, if we don't see it then scoot... ; setlocal name 'wait ${get:sys_waittimeout} seconds for MSG_XFERREADY' wait '${get:sys_waittimeout}000' if '${ret:}' !~contains 'msg_xferready' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Get information about the image... ; :MAIN.IMAGEINFO.NEXT setlocal name 'dg_image/dat_imageinfo/msg_get' dsmentry src ds dg_image dat_imageinfo msg_get '0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0' if '${sts:}' != 'SUCCESS' goto MAIN.ERROR.ECHOPASSFAIL setlocal twimageinfo.compression '${ret:${get:index.twimageinfo.compression}}' echo.passfail '${get:indent}${get:name}' 'pass' ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Set up the file transfer... ; increment image.count '${get:image.count}' 1 if '${get:twimageinfo.compression}' == 'JPEG' goto MAIN.SETUPFILEXFER.JPEG setlocal image.showname 'DAT_IMAGEFILEXFER/${get:image.prefix}${format:D6|${get:image.count}}.tif' setlocal twsetupfilexfer.filename '${get:image.folder}/${get:image.prefix}${format:D6|${get:image.testcount}}.tif' setlocal twsetupfilexfer.format 'TWFF_TIFF' goto MAIN.SETUPFILEXFER :MAIN.SETUPFILEXFER.JPEG setlocal image.showname 'DAT_IMAGEFILEXFER/${get:image.prefix}${format:D6|${get:image.count}}.jpg' setlocal twsetupfilexfer.filename '${get:image.folder}/${get:image.prefix}${format:D6|${get:image.testcount}}.jpg' setlocal twsetupfilexfer.format 'TWFF_JFIF' :MAIN.SETUPFILEXFER setlocal name 'dg_control/dat_setupfilexfer/msg_set' dsmentry src ds dg_control dat_setupfilexfer msg_set '"${get:twsetupfilexfer.filename}",${get:twsetupfilexfer.format},0' if '${sts:}' != 'SUCCESS' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Transfer the image... ; setlocal name 'dg_image/dat_imagefilexfer/msg_get' dsmentry src ds dg_image dat_imagefilexfer msg_get null if '${sts:}' != 'XFERDONE' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' echo.passfail '${get:indent}image <${get:image.showname}>' 'pass' ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; End the transfer, see if we're done... ; setlocal name 'dg_control/dat_pendingxfers/msg_endxfer' dsmentry src ds dg_control dat_pendingxfers msg_endxfer '0,0' if '${sts:}' != 'SUCCESS' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' increment image.testcount '${get:image.testcount}' 1 ; count the image if '${ret:${get:TW_PENDINGXFERS.Count}}' != '0' goto MAIN.IMAGEINFO.NEXT ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; We're out of images, so disable... ; setlocal name 'dg_control/dat_userinterface/msg_disableds' dsmentry src ds dg_control dat_userinterface msg_disableds '0,0' if '${sts:}' != 'SUCCESS' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Check the results before going up to the next CAP_XFERCOUNT test. ; Note that flatbeds should always return one image. ; if '${get:feederenabled.value}' ~~ 'FALSE' goto MAIN.XFERCOUNT.CHECKTEST2 if '${get:xfercount.test}' == '2' goto MAIN.XFERCOUNT.CHECKTEST2 if '${get:xfercount.test}' == '3' goto MAIN.XFERCOUNT.CHECKTEST3 echo.passfail '${get:indent}WE SHOULD NOT BE HERE' 'fail - test=${get:xfercount.test}' goto MAIN.ERROR.ECHOPASSFAIL ; :MAIN.XFERCOUNT.CHECKTEST2 setlocal name 'one image transferred' if '${get:image.testcount}' != '2' goto MAIN.ERROR.ECHOPASSFAIL ; image.testcountstarted at 1 echo.passfail '${get:indent}${get:name}' 'pass' goto MAIN.XFERCOUNT.NEXT ; :MAIN.XFERCOUNT.CHECKTEST3 setlocal name 'multiple images transferred (${get:image.testcount})' if '${get:image.testcount}' < '3' goto MAIN.ERROR.ECHOPASSFAIL ; image.testcountstarted at 1 echo.passfail '${get:indent}${get:name}' 'pass' goto MAIN.XFERCOUNT.NEXT ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Summary and cleanup... ; ; We passed... :MAIN.PASS echo.passfail 'SUMMARY' 'pass' return 'pass' ; ; Ruh-roh... :MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'fail - ${sts:} ${ret:}' echo.passfail 'SUMMARY' 'fail' setglobal '${arg:2}' 'fail' return 'fail' ================================================ FILE: twaincs/source/twaincscert/source/data/certification/070 - CAP_XFERCOUNT Tests/DAT_IMAGEMEMFILEXFER.tc ================================================ ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; DAT_IMAGEMEMFILEXFER ; This test sets CAP_XFERCOUNT to 0, 1 and -1 for a flatbed scanner. It expects an error for the ; value 0, and only one image to be transferred per scanning session for the values 1 and -1. ; ; We follow the capability ordering, so the loops take the form: ; set ICAP_XFERMECH TWSX_MEMFILE ; foreach CAP_FEEDERENABLED ; foreach ICAP_PIXELTYPE ; scan ; end ; end ; ; Arguments ; arg:1 - TW_IDENTITY.ProductName of scanner to test ; arg:2 - global for us to update on failure ; arg:3 - value of ShowUI (TRUE or FALSE) ; arg:4 - test name for the image folder ; arg:5 - result of a MSG_GET on ICAP_XFERMECH ; ; Globals ; (none) ; ; Locals ; name - current test being done ; indent - indent the passfail text ; imagememxfer - result of DAT_IMAGEMEMXFER call ; setupmemxfer.preferred - preferred field from DAT_SETUPMEMXFER call ; ; image.count - count of images from 1 ; image.folder - folder to put the images in ; image.folderone - path for CAP_XFERCOUNT=1 test ; image.folderall - path for CAP_XFERCOUNT=-1 test ; image.prefix - adf or fb ; image.testcount - count of images from 0 for a specific test ; ; feederenabled.list - scanner's feederenabled values ; feederenabled.index - index of feederenabled values ; feederenabled.value - current feederenabled value ; ; Returns ; pass or fail ; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; If not supported, quietly leave... ; if '${arg:5}' ~contains 'TWSX_MEMFILE' goto MAIN.CONTINUE return 'pass' :MAIN.CONTINUE ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Initialize... ; echo.titletest 'DAT_IMAGEMEMFILEXFER' setlocal indent '' setlocal image.pointer '0' setlocal image.count '0' setlocal image.folder '' setlocal image.folderone '${folder:certimages}/${arg:4}/DAT_IMAGEMEMFILEXFER/one' setlocal image.folderall '${folder:certimages}/${arg:4}/DAT_IMAGEMEMFILEXFER/all' setlocal image.prefix 'fb' setlocal image.testcount '1' setlocal showui '${arg:3}' setlocal xfercount.test '0' ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Prompt the user, if they have an ADF... ; if '${get:g_skipprompts}' != '' goto MAIN.SKIP.PROMPTS dsmentry src ds dg_control dat_capability msg_get 'CAP_FEEDERENABLED,0,0,0' if '${ret:}' !~contains 'TRUE' goto MAIN.SKIP.PROMPTS echo.prompt echo.prompt "Scanning will take place during this test. There will be no" echo.prompt "need to press any button on the TWAIN user interface to start" echo.prompt "the scanner. A progress indicator may appear during scanning." echo.prompt echo.prompt "Place at least 3 sheets of paper in the scanner's feeder." pause '(press the ENTER key when ready to continue)' echo.prompt :MAIN.SKIP.PROMPTS ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Clean the image folder for this test... ; image cleanfolder '${get:image.folderone}' image cleanfolder '${get:image.folderall}' ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; MSG_RESETALL ; If return code is not TWRC_SUCCESS, end with an error ; setlocal name 'MSG_RESETALL' dsmentry src ds dg_control dat_capability msg_resetall '0,0,0,0' if '${sts:}' != 'SUCCESS' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Get and set ICAP_XFERMECH... ; setlocal name 'ICAP_XFERMECH MSG_GET' dsmentry src ds dg_control dat_capability msg_get 'ICAP_XFERMECH,0,0,0' if '${sts:}' != 'SUCCESS' goto MAIN.ERROR.ECHOPASSFAIL if '${ret:}' !~contains 'TWSX_MEMFILE' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' ; setlocal name 'ICAP_XFERMECH MSG_SET TWSX_MEMFILE' dsmentry src ds dg_control dat_capability msg_set 'ICAP_XFERMECH,TWON_ONEVALUE,TWTY_UINT16,TWSX_MEMFILE' if '${sts:}' != 'SUCCESS' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Get CAP_FEEDERENABLED, and loop so we test all values ; for the current ICAP_XFERMECH setting. ; setlocal name 'CAP_FEEDERENABLED MSG_GET' dsmentry src ds dg_control dat_capability msg_get 'CAP_FEEDERENABLED,0,0,0' if '${sts:}' != 'SUCCESS' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' ; setlocal feederenabled.list '${ret:}' ; what the scanner told us setlocal feederenabled.index '${get:TW_ENUMERATION.ItemList}' ; point to itemlist increment feederenabled.index '${get:feederenabled.index}' -1 ; less 1 ; :MAIN.FEEDERENABLED.NEXT setlocal indent '' setlocal xfercount.test '0' ; reset the tests increment feederenabled.index '${get:feederenabled.index}' 1 ; next itemlist setlocal feederenabled.value '${getindex:feederenabled.list:${get:feederenabled.index}}' ; get the value if '${get:feederenabled.value}' == '' goto MAIN.PASS ; we've passed all tests!!! ; setlocal name 'CAP_FEEDERENABLED MSG_SET ${get:feederenabled.value}' dsmentry src ds dg_control dat_capability msg_set 'CAP_FEEDERENABLED,TWON_ONEVALUE,TWTY_BOOL,${get:feederenabled.value}' if '${sts:}' != 'SUCCESS' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' ; if '${get:feederenabled.value}' ~~ 'FALSE' goto MAIN.FEEDERENABLED.SETFB setlocal image.prefix 'adf' goto MAIN.FEEDERENABLED.SETDONE :MAIN.FEEDERENABLED.SETFB setlocal image.prefix 'fb' :MAIN.FEEDERENABLED.SETDONE ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Dispatch to the CAP_XFERCOUNT test we want to run... ; :MAIN.XFERCOUNT.NEXT setlocal indent ' ' increment xfercount.test '${get:xfercount.test}' 1 if '${get:xfercount.test}' == '1' goto MAIN.XFERCOUNT.TEST1 if '${get:xfercount.test}' == '2' goto MAIN.XFERCOUNT.TEST2 if '${get:xfercount.test}' == '3' goto MAIN.XFERCOUNT.TEST3 goto MAIN.FEEDERENABLED.NEXT ; we're done test with this paper source, go to the next one ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Set CAP_XFERCOUNT to 0... ; :MAIN.XFERCOUNT.TEST1 setlocal name 'CAP_XFERCOUNT == 0' dsmentry src ds dg_control dat_capability msg_set 'CAP_XFERCOUNT,TWON_ONEVALUE,TWTY_INT16,0' if '${sts:}' == 'SUCCESS' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' goto MAIN.XFERCOUNT.NEXT ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Set CAP_XFERCOUNT to 1... ; :MAIN.XFERCOUNT.TEST2 setlocal name 'CAP_XFERCOUNT == 1' dsmentry src ds dg_control dat_capability msg_set 'CAP_XFERCOUNT,TWON_ONEVALUE,TWTY_INT16,1' if '${sts:}' != 'SUCCESS' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' setlocal image.folder '${get:image.folderone}' goto MAIN.FEEDERLOADED ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Set CAP_XFERCOUNT to -1... ; :MAIN.XFERCOUNT.TEST3 setlocal name 'CAP_XFERCOUNT == -1' dsmentry src ds dg_control dat_capability msg_set 'CAP_XFERCOUNT,TWON_ONEVALUE,TWTY_INT16,-1' if '${sts:}' != 'SUCCESS' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' setlocal image.folder '${get:image.folderall}' goto MAIN.FEEDERLOADED ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Check for paper in the feeder, skip for a flatbed... ; :MAIN.FEEDERLOADED if '${get:feederenabled.value}' ~~ 'FALSE' goto MAIN.FEEDERLOADED.DONE dsmentry src ds dg_control dat_capability msg_getcurrent 'CAP_FEEDERLOADED,0,0,0' if '${sts:}' != 'SUCCESS' goto MAIN.FEEDERLOADED.DONE if '${ret:${get:TW_ONEVALUE.Item}}' ~~ 'TRUE' goto MAIN.FEEDERLOADED.DONE echo.prompt echo.prompt "Place paper in the scanner's feeder." pause '(press the ENTER key when ready to continue)' :MAIN.FEEDERLOADED.DONE ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Get the preferred size for memory transfers, and allocate ; a pointer for the memory transfers... ; setlocal indent ' ' setlocal name 'dg_control/dat_setupmemxfer/msg_get' dsmentry src ds dg_control dat_setupmemxfer msg_get '0,0,0' if '${sts:}' != 'SUCCESS' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' ; setlocal name 'TW_SETUPMEMXFER.Preferred > 0' setlocal setupmemxfer.preferred '${ret:${get:TW_SETUPMEMXFER.Preferred}}' if '${get:setupmemxfer.preferred}' <= '0' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' ; setlocal name 'allocate pointer for ${get:setupmemxfer.preferred} bytes' free pointer image.pointer ; for the last loop allocate pointer image.pointer '${get:setupmemxfer.preferred}' if '${get:image.pointer}' == '0' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Set DAT_SETUPFILEXFER to TWFF_TIFF ; setlocal name 'dg_control/dat_setupfilexfer/msg_set TWFF_TIFF' dsmentry src null dg_control dat_setupfilexfer msg_set 'file,TWFF_TIFF,0' if '${sts:}' != 'SUCCESS' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Start scanning... ; :MAIN.USERINTERFACE setlocal indent ' ' setlocal name 'dg_control/dat_userinterface/msg_enableds' setlocal image.testcount '1' ; reset to 1 setlocal name 'dg_control/dat_userinterface/msg_enableds' wait reset dsmentry src null dg_control dat_userinterface msg_enableds '${get:showui},0' if '${sts:}' != 'SUCCESS' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Wait for MSG_XFERREADY, if we don't see it then scoot... ; setlocal name 'wait ${get:sys_waittimeout} seconds for MSG_XFERREADY' wait '${get:sys_waittimeout}000' if '${ret:}' !~contains 'msg_xferready' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Do a memory file transfer... ; This little song and dance with the states is so that we can ; start the transfer in state 6 with each new image, but switch ; to state 7 if we need multiple calls to capture the current ; image... ; ; The saved images will be in TIFF format, which includes TIFF ; JPEG (the better form, where a simple TIFF header is added). ; increment image.count '${get:image.count}' 1 image free memfileimage ; :MAIN.IMAGEMEMFILEXFER.NEXT setlocal name 'dg_image/dat_imagememxfer/msg_get' dsmentry src ds dg_image dat_imagememfilexfer msg_get '0,0,0,0,0,0,0,9,${get:setupmemxfer.preferred},${get:image.pointer}' setlocal imagememxfer '${ret:}' if '${sts:}' == 'XFERDONE' goto MAIN.IMAGEMEMFILEXFER.XFERDONE if '${sts:}' != 'SUCCESS' goto MAIN.ERROR.ECHOPASSFAIL ; echo.passfail '${get:indent}${get:name} SUCCESS' 'pass' image append memfileimage '${get:imagememxfer}' goto MAIN.IMAGEMEMFILEXFER.NEXT ; :MAIN.IMAGEMEMFILEXFER.XFERDONE echo.passfail '${get:indent}${get:name} XFERDONE' 'pass' image append memfileimage '${get:imagememxfer}' image save memfileimage memfile '${get:image.folder}/${get:image.prefix}${format:D6|${get:image.testcount}}' echo.passfail '${get:indent}image <${ret:}>' 'pass' image free memfileimage ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; End the transfer, see if we're done... ; setlocal name 'dg_control/dat_pendingxfers/msg_endxfer' dsmentry src ds dg_control dat_pendingxfers msg_endxfer '0,0' if '${sts:}' != 'SUCCESS' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' increment image.testcount '${get:image.testcount}' 1 ; count the image if '${ret:${get:TW_PENDINGXFERS.Count}}' != '0' goto MAIN.IMAGEMEMFILEXFER.NEXT ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; We're out of images, so disable... ; setlocal name 'dg_control/dat_userinterface/msg_disableds' dsmentry src ds dg_control dat_userinterface msg_disableds '0,0' if '${sts:}' != 'SUCCESS' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Check the results before going up to the next CAP_XFERCOUNT test. ; Note that flatbeds should always return one image. ; if '${get:feederenabled.value}' ~~ 'FALSE' goto MAIN.XFERCOUNT.CHECKTEST2 if '${get:xfercount.test}' == '2' goto MAIN.XFERCOUNT.CHECKTEST2 if '${get:xfercount.test}' == '3' goto MAIN.XFERCOUNT.CHECKTEST3 echo.passfail '${get:indent}WE SHOULD NOT BE HERE' 'fail - test=${get:xfercount.test}' goto MAIN.ERROR.ECHOPASSFAIL ; :MAIN.XFERCOUNT.CHECKTEST2 setlocal name 'one image transferred' if '${get:image.testcount}' != '2' goto MAIN.ERROR.ECHOPASSFAIL ; image.testcount started at 1 echo.passfail '${get:indent}${get:name}' 'pass' goto MAIN.XFERCOUNT.NEXT ; :MAIN.XFERCOUNT.CHECKTEST3 setlocal name 'multiple images transferred (${get:image.testcount})' if '${get:image.testcount}' < '3' goto MAIN.ERROR.ECHOPASSFAIL ; image.testcount started at 1 echo.passfail '${get:indent}${get:name}' 'pass' goto MAIN.XFERCOUNT.NEXT ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Summary and cleanup... ; ; We passed... :MAIN.PASS image free memfileimage free pointer image.pointer echo.passfail 'SUMMARY' 'pass' return 'pass' ; ; Ruh-roh... :MAIN.ERROR.ECHOPASSFAIL image free memfileimage free pointer image.pointer echo.passfail '${get:indent}${get:name}' 'fail - ${sts:} ${ret:}' echo.passfail 'SUMMARY' 'fail' setglobal '${arg:2}' 'fail' return 'fail' ================================================ FILE: twaincs/source/twaincscert/source/data/certification/070 - CAP_XFERCOUNT Tests/DAT_IMAGEMEMXFER.tc ================================================ ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; DAT_IMAGEMEMXFER ; This test sets CAP_XFERCOUNT to 0, 1 and -1 for a flatbed scanner. It expects an error for the ; value 0, and only one image to be transferred per scanning session for the values 1 and -1. ; ; We follow the capability ordering, so the loops take the form: ; set ICAP_XFERMECH TWSX_MEMORY ; foreach CAP_FEEDERENABLED ; foreach ICAP_PIXELTYPE ; scan ; end ; end ; ; Arguments ; arg:1 - TW_IDENTITY.ProductName of scanner to test ; arg:2 - global for us to update on failure ; arg:3 - value of ShowUI (TRUE or FALSE) ; arg:4 - test name for the image folder ; ; Globals ; (none) ; ; Locals ; name - current test being done ; indent - indent the passfail text ; imageinfo - metadata for the current image ; imagememxfer - result of DAT_IMAGEMEMXFER call ; setupmemxfer.preferred - preferred field from DAT_SETUPMEMXFER call ; ; image.count - count of images from 1 ; image.folder - folder to put the images in ; image.folderone - path for CAP_XFERCOUNT=1 test ; image.folderall - path for CAP_XFERCOUNT=-1 test ; image.prefix - adf or fb ; image.testcount - count of images from 0 for a specific test ; ; feederenabled.list - scanner's feederenabled values ; feederenabled.index - index of feederenabled values ; feederenabled.value - current feederenabled value ; ; pixeltype.list - scanner's pixeltype values for this feederenabled ; pixeltype.index - index of pixeltype values ; pixeltype.value - current pixeltype value ; ; Returns ; pass or fail ; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Initialize... ; echo.titletest 'DAT_IMAGEMEMXFER' setlocal indent '' setlocal image.pointer '0' setlocal image.count '0' setlocal image.folder '' setlocal image.folderone '${folder:certimages}/${arg:4}/DAT_IMAGEMEMXFER/one' setlocal image.folderall '${folder:certimages}/${arg:4}/DAT_IMAGEMEMXFER/all' setlocal image.prefix 'fb' setlocal image.testcount '1' setlocal showui '${arg:3}' setlocal xfercount.test '0' ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Prompt the user, if they have an ADF... ; if '${get:g_skipprompts}' != '' goto MAIN.SKIP.PROMPTS dsmentry src ds dg_control dat_capability msg_get 'CAP_FEEDERENABLED,0,0,0' if '${ret:}' !~contains 'TRUE' goto MAIN.SKIP.PROMPTS echo.prompt echo.prompt "Scanning will take place during this test. There will be no" echo.prompt "need to press any button on the TWAIN user interface to start" echo.prompt "the scanner. A progress indicator may appear during scanning." echo.prompt echo.prompt "Place at least 3 sheets of paper in the scanner's feeder." pause '(press the ENTER key when ready to continue)' echo.prompt :MAIN.SKIP.PROMPTS ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Clean the image folder for this test... ; image cleanfolder '${get:image.folderone}' image cleanfolder '${get:image.folderall}' ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; MSG_RESETALL ; If return code is not TWRC_SUCCESS, end with an error ; setlocal name 'MSG_RESETALL' dsmentry src ds dg_control dat_capability msg_resetall '0,0,0,0' if '${sts:}' != 'SUCCESS' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Get and set ICAP_XFERMECH... ; setlocal name 'ICAP_XFERMECH MSG_GET' dsmentry src ds dg_control dat_capability msg_get 'ICAP_XFERMECH,0,0,0' if '${sts:}' != 'SUCCESS' goto MAIN.ERROR.ECHOPASSFAIL if '${ret:}' !~contains 'TWSX_MEMORY' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' ; setlocal name 'ICAP_XFERMECH MSG_SET TWSX_MEMORY' dsmentry src ds dg_control dat_capability msg_set 'ICAP_XFERMECH,TWON_ONEVALUE,TWTY_UINT16,TWSX_MEMORY' if '${sts:}' != 'SUCCESS' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Get CAP_FEEDERENABLED, and loop so we test all values ; for the current ICAP_XFERMECH setting. ; setlocal name 'CAP_FEEDERENABLED MSG_GET' dsmentry src ds dg_control dat_capability msg_get 'CAP_FEEDERENABLED,0,0,0' if '${sts:}' != 'SUCCESS' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' ; setlocal feederenabled.list '${ret:}' ; what the scanner told us setlocal feederenabled.index '${get:TW_ENUMERATION.ItemList}' ; point to itemlist increment feederenabled.index '${get:feederenabled.index}' -1 ; less 1 ; :MAIN.FEEDERENABLED.NEXT setlocal indent '' setlocal xfercount.test '0' ; reset the tests increment feederenabled.index '${get:feederenabled.index}' 1 ; next itemlist setlocal feederenabled.value '${getindex:feederenabled.list:${get:feederenabled.index}}' ; get the value if '${get:feederenabled.value}' == '' goto MAIN.PASS ; we've passed all tests!!! ; setlocal name 'CAP_FEEDERENABLED MSG_SET ${get:feederenabled.value}' dsmentry src ds dg_control dat_capability msg_set 'CAP_FEEDERENABLED,TWON_ONEVALUE,TWTY_BOOL,${get:feederenabled.value}' if '${sts:}' != 'SUCCESS' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' ; if '${get:feederenabled.value}' ~~ 'FALSE' goto MAIN.FEEDERENABLED.SETFB setlocal image.prefix 'adf' goto MAIN.FEEDERENABLED.SETDONE :MAIN.FEEDERENABLED.SETFB setlocal image.prefix 'fb' :MAIN.FEEDERENABLED.SETDONE ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Dispatch to the CAP_XFERCOUNT test we want to run... ; :MAIN.XFERCOUNT.NEXT setlocal indent ' ' increment xfercount.test '${get:xfercount.test}' 1 if '${get:xfercount.test}' == '1' goto MAIN.XFERCOUNT.TEST1 if '${get:xfercount.test}' == '2' goto MAIN.XFERCOUNT.TEST2 if '${get:xfercount.test}' == '3' goto MAIN.XFERCOUNT.TEST3 goto MAIN.FEEDERENABLED.NEXT ; we're done test with this paper source, go to the next one ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Set CAP_XFERCOUNT to 0... ; :MAIN.XFERCOUNT.TEST1 setlocal name 'CAP_XFERCOUNT == 0' dsmentry src ds dg_control dat_capability msg_set 'CAP_XFERCOUNT,TWON_ONEVALUE,TWTY_INT16,0' if '${sts:}' == 'SUCCESS' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' goto MAIN.XFERCOUNT.NEXT ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Set CAP_XFERCOUNT to 1... ; :MAIN.XFERCOUNT.TEST2 setlocal name 'CAP_XFERCOUNT == 1' dsmentry src ds dg_control dat_capability msg_set 'CAP_XFERCOUNT,TWON_ONEVALUE,TWTY_INT16,1' if '${sts:}' != 'SUCCESS' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' setlocal image.folder '${get:image.folderone}' goto MAIN.FEEDERLOADED ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Set CAP_XFERCOUNT to -1... ; :MAIN.XFERCOUNT.TEST3 setlocal name 'CAP_XFERCOUNT == -1' dsmentry src ds dg_control dat_capability msg_set 'CAP_XFERCOUNT,TWON_ONEVALUE,TWTY_INT16,-1' if '${sts:}' != 'SUCCESS' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' setlocal image.folder '${get:image.folderall}' goto MAIN.FEEDERLOADED ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Check for paper in the feeder, skip for a flatbed... ; :MAIN.FEEDERLOADED if '${get:feederenabled.value}' ~~ 'FALSE' goto MAIN.FEEDERLOADED.DONE dsmentry src ds dg_control dat_capability msg_getcurrent 'CAP_FEEDERLOADED,0,0,0' if '${sts:}' != 'SUCCESS' goto MAIN.FEEDERLOADED.DONE if '${ret:${get:TW_ONEVALUE.Item}}' ~~ 'TRUE' goto MAIN.FEEDERLOADED.DONE echo.prompt echo.prompt "Place paper in the scanner's feeder." pause '(press the ENTER key when ready to continue)' :MAIN.FEEDERLOADED.DONE ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Get the preferred size for memory transfers, and allocate ; a pointer for the memory transfers... ; setlocal indent ' ' setlocal name 'dg_control/dat_setupmemxfer/msg_get' dsmentry src ds dg_control dat_setupmemxfer msg_get '0,0,0' if '${sts:}' != 'SUCCESS' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' ; setlocal name 'TW_SETUPMEMXFER.Preferred > 0' setlocal setupmemxfer.preferred '${ret:${get:TW_SETUPMEMXFER.Preferred}}' if '${get:setupmemxfer.preferred}' <= '0' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' ; setlocal name 'allocate pointer for ${get:setupmemxfer.preferred} bytes' free pointer image.pointer ; for the last loop allocate pointer image.pointer '${get:setupmemxfer.preferred}' if '${get:image.pointer}' == '0' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Start scanning... ; :MAIN.USERINTERFACE setlocal indent ' ' setlocal name 'dg_control/dat_userinterface/msg_enableds' setlocal image.testcount '1' ; reset to 1 wait reset dsmentry src null dg_control dat_userinterface msg_enableds '${get:showui},0' if '${sts:}' != 'SUCCESS' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Wait for MSG_XFERREADY, if we don't see it then scoot... ; setlocal name 'wait ${get:sys_waittimeout} seconds for MSG_XFERREADY' wait '${get:sys_waittimeout}000' if '${ret:}' !~contains 'msg_xferready' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Do a memory transfer... ; This little song and dance with the states is so that we can ; start the transfer in state 6 with each new image, but switch ; to state 7 if we need multiple calls to capture the current ; image... ; ; The saved images will be in TIFF format, which includes TIFF ; JPEG (the better form, where a simple TIFF header is added). ; increment image.count '${get:image.count}' 1 image free memimage ; :MAIN.IMAGEMEMXFER.NEXT setlocal name 'dg_image/dat_imagememxfer/msg_get' dsmentry src ds dg_image dat_imagememxfer msg_get '0,0,0,0,0,0,0,9,${get:setupmemxfer.preferred},${get:image.pointer}' setlocal imagememxfer '${ret:}' if '${sts:}' == 'XFERDONE' goto MAIN.IMAGEMEMXFER.XFERDONE if '${sts:}' != 'SUCCESS' goto MAIN.ERROR.ECHOPASSFAIL ; echo.passfail '${get:indent}${get:name} SUCCESS' 'pass' image append memimage '${get:imagememxfer}' goto MAIN.IMAGEMEMXFER.NEXT ; :MAIN.IMAGEMEMXFER.XFERDONE echo.passfail '${get:indent}${get:name} XFERDONE' 'pass' ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; We need image info to make sense of this data... ; setlocal name 'dg_image/dat_imageinfo/msg_get' dsmentry src ds dg_image dat_imageinfo msg_get '0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0' setlocal imageinfo '${ret:}' if '${sts:}' != 'SUCCESS' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Save the image... ; image append memimage '${get:imagememxfer}' image addheader memimage '${get:imageinfo}' image save memimage memory '${get:image.folder}/${get:image.prefix}${format:D6|${get:image.testcount}}' echo.passfail '${get:indent}image <${ret:}>' 'pass' image free memimage ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; End the transfer, see if we're done... ; setlocal name 'dg_control/dat_pendingxfers/msg_endxfer' dsmentry src ds dg_control dat_pendingxfers msg_endxfer '0,0' if '${sts:}' != 'SUCCESS' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' increment image.testcount '${get:image.testcount}' 1 ; count the image if '${ret:${get:TW_PENDINGXFERS.Count}}' != '0' goto MAIN.IMAGEMEMXFER.NEXT ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; We're out of images, so disable... ; setlocal name 'dg_control/dat_userinterface/msg_disableds' dsmentry src ds dg_control dat_userinterface msg_disableds '0,0' if '${sts:}' != 'SUCCESS' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Check the results before going up to the next CAP_XFERCOUNT test. ; Note that flatbeds should always return one image. ; if '${get:feederenabled.value}' ~~ 'FALSE' goto MAIN.XFERCOUNT.CHECKTEST2 if '${get:xfercount.test}' == '2' goto MAIN.XFERCOUNT.CHECKTEST2 if '${get:xfercount.test}' == '3' goto MAIN.XFERCOUNT.CHECKTEST3 echo.passfail '${get:indent}WE SHOULD NOT BE HERE' 'fail - test=${get:xfercount.test}' goto MAIN.ERROR.ECHOPASSFAIL ; :MAIN.XFERCOUNT.CHECKTEST2 setlocal name 'one image transferred' if '${get:image.testcount}' != '2' goto MAIN.ERROR.ECHOPASSFAIL ; image.testcount started at 1 echo.passfail '${get:indent}${get:name}' 'pass' goto MAIN.XFERCOUNT.NEXT ; :MAIN.XFERCOUNT.CHECKTEST3 setlocal name 'multiple images transferred (${get:image.testcount})' ; image.testcount started at 1 if '${get:image.testcount}' < '3' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' goto MAIN.XFERCOUNT.NEXT ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Summary and cleanup... ; ; We passed... :MAIN.PASS image free memimage free pointer image.pointer echo.passfail 'SUMMARY' 'pass' return 'pass' ; ; Ruh-roh... :MAIN.ERROR.ECHOPASSFAIL image free memimage free pointer image.pointer echo.passfail '${get:indent}${get:name}' 'fail - ${sts:} ${ret:}' echo.passfail 'SUMMARY' 'fail' setglobal '${arg:2}' 'fail' return 'fail' ================================================ FILE: twaincs/source/twaincscert/source/data/certification/070 - CAP_XFERCOUNT Tests/DAT_IMAGENATIVEXFER.tc ================================================ ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; DAT_IMAGENATIVEXFER ; This test sets CAP_XFERCOUNT to 0, 1 and -1 for a flatbed scanner. It expects an error for the ; value 0, and only one image to be transferred per scanning session for the values 1 and -1. ; ; We follow the capability ordering, so the loops take the form: ; set ICAP_XFERMECH TWSX_NATIVE ; foreach CAP_FEEDERENABLED ; foreach ICAP_PIXELTYPE ; scan ; end ; end ; ; Arguments ; arg:1 - TW_IDENTITY.ProductName of scanner to test ; arg:2 - global for us to update on failure ; arg:3 - value of ShowUI (TRUE or FALSE) ; arg:4 - test name for the image folder ; ; Globals ; (none) ; ; Locals ; name - current test being done ; indent - indent the passfail text ; ; image.handle - native handle ; image.count - count of images from 1 ; image.folder - folder to put the images in ; image.folderone - path for CAP_XFERCOUNT=1 test ; image.folderall - path for CAP_XFERCOUNT=-1 test ; image.prefix - adf or fb ; image.testcount - count of images from 0 for a specific test ; ; feederenabled.list - scanner's feederenabled values ; feederenabled.index - index of feederenabled values ; feederenabled.value - current feederenabled value ; ; Returns ; pass or fail ; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Initialize... ; echo.titletest 'DAT_IMAGENATIVEXFER' setlocal indent '' setlocal image.handle '0' setlocal image.count '0' setlocal image.folder '' setlocal image.folderone '${folder:certimages}/${arg:4}/DAT_IMAGENATIVEXFER/one' setlocal image.folderall '${folder:certimages}/${arg:4}/DAT_IMAGENATIVEXFER/all' setlocal image.prefix 'fb' setlocal image.testcount '1' setlocal showui '${arg:3}' setlocal xfercount.test '0' ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Prompt the user, if they have an ADF... ; if '${get:g_skipprompts}' != '' goto MAIN.SKIP.PROMPTS dsmentry src ds dg_control dat_capability msg_get 'CAP_FEEDERENABLED,0,0,0' if '${ret:}' !~contains 'TRUE' goto MAIN.SKIP.PROMPTS echo.prompt echo.prompt "Scanning will take place during this test. There will be no" echo.prompt "need to press any button on the TWAIN user interface to start" echo.prompt "the scanner. A progress indicator may appear during scanning." echo.prompt echo.prompt "Place at least 3 sheets of paper in the scanner's feeder." pause '(press the ENTER key when ready to continue)' echo.prompt :MAIN.SKIP.PROMPTS ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Clean the image folder for this test... ; image cleanfolder '${get:image.folderone}' image cleanfolder '${get:image.folderall}' ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; MSG_RESETALL ; If return code is not TWRC_SUCCESS, end with an error ; setlocal name 'MSG_RESETALL' dsmentry src ds dg_control dat_capability msg_resetall '0,0,0,0' if '${sts:}' != 'SUCCESS' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Get and set ICAP_XFERMECH... ; setlocal name 'ICAP_XFERMECH MSG_GET' dsmentry src ds dg_control dat_capability msg_get 'ICAP_XFERMECH,0,0,0' if '${sts:}' != 'SUCCESS' goto MAIN.ERROR.ECHOPASSFAIL if '${ret:}' !~contains 'TWSX_NATIVE' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' ; setlocal name 'ICAP_XFERMECH MSG_SET TWSX_NATIVE' dsmentry src ds dg_control dat_capability msg_set 'ICAP_XFERMECH,TWON_ONEVALUE,TWTY_UINT16,TWSX_NATIVE' if '${sts:}' != 'SUCCESS' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Get CAP_FEEDERENABLED, and loop so we test all values ; for the current ICAP_XFERMECH setting. ; setlocal name 'CAP_FEEDERENABLED MSG_GET' dsmentry src ds dg_control dat_capability msg_get 'CAP_FEEDERENABLED,0,0,0' if '${sts:}' != 'SUCCESS' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' ; setlocal feederenabled.list '${ret:}' ; what the scanner told us setlocal feederenabled.index '${get:TW_ENUMERATION.ItemList}' ; point to itemlist increment feederenabled.index '${get:feederenabled.index}' -1 ; less 1 ; :MAIN.FEEDERENABLED.NEXT setlocal indent '' setlocal xfercount.test '0' ; reset the tests increment feederenabled.index '${get:feederenabled.index}' 1 ; next itemlist setlocal feederenabled.value '${getindex:feederenabled.list:${get:feederenabled.index}}' ; get the value if '${get:feederenabled.value}' == '' goto MAIN.PASS ; we've passed all tests!!! ; setlocal name 'CAP_FEEDERENABLED MSG_SET ${get:feederenabled.value}' dsmentry src ds dg_control dat_capability msg_set 'CAP_FEEDERENABLED,TWON_ONEVALUE,TWTY_BOOL,${get:feederenabled.value}' if '${sts:}' != 'SUCCESS' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' ; if '${get:feederenabled.value}' ~~ 'FALSE' goto MAIN.FEEDERENABLED.SETFB setlocal image.prefix 'adf' goto MAIN.FEEDERENABLED.SETDONE :MAIN.FEEDERENABLED.SETFB setlocal image.prefix 'fb' :MAIN.FEEDERENABLED.SETDONE ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Dispatch to the CAP_XFERCOUNT test we want to run... ; :MAIN.XFERCOUNT.NEXT setlocal indent ' ' increment xfercount.test '${get:xfercount.test}' 1 if '${get:xfercount.test}' == '1' goto MAIN.XFERCOUNT.TEST1 if '${get:xfercount.test}' == '2' goto MAIN.XFERCOUNT.TEST2 if '${get:xfercount.test}' == '3' goto MAIN.XFERCOUNT.TEST3 goto MAIN.FEEDERENABLED.NEXT ; we're done test with this paper source, go to the next one ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Set CAP_XFERCOUNT to 0... ; :MAIN.XFERCOUNT.TEST1 setlocal name 'CAP_XFERCOUNT == 0' dsmentry src ds dg_control dat_capability msg_set 'CAP_XFERCOUNT,TWON_ONEVALUE,TWTY_INT16,0' if '${sts:}' == 'SUCCESS' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' goto MAIN.XFERCOUNT.NEXT ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Set CAP_XFERCOUNT to 1... ; :MAIN.XFERCOUNT.TEST2 setlocal name 'CAP_XFERCOUNT == 1' dsmentry src ds dg_control dat_capability msg_set 'CAP_XFERCOUNT,TWON_ONEVALUE,TWTY_INT16,1' if '${sts:}' != 'SUCCESS' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' setlocal image.folder '${get:image.folderone}' goto MAIN.FEEDERLOADED ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Set CAP_XFERCOUNT to -1... ; :MAIN.XFERCOUNT.TEST3 setlocal name 'CAP_XFERCOUNT == -1' dsmentry src ds dg_control dat_capability msg_set 'CAP_XFERCOUNT,TWON_ONEVALUE,TWTY_INT16,-1' if '${sts:}' != 'SUCCESS' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' setlocal image.folder '${get:image.folderall}' goto MAIN.FEEDERLOADED ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Check for paper in the feeder, skip for a flatbed... ; :MAIN.FEEDERLOADED if '${get:feederenabled.value}' ~~ 'FALSE' goto MAIN.FEEDERLOADED.DONE dsmentry src ds dg_control dat_capability msg_getcurrent 'CAP_FEEDERLOADED,0,0,0' if '${sts:}' != 'SUCCESS' goto MAIN.FEEDERLOADED.DONE if '${ret:${get:TW_ONEVALUE.Item}}' ~~ 'TRUE' goto MAIN.FEEDERLOADED.DONE echo.prompt echo.prompt "Place paper in the scanner's feeder." pause '(press the ENTER key when ready to continue)' :MAIN.FEEDERLOADED.DONE ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Start scanning... ; setlocal indent ' ' setlocal name 'dg_control/dat_userinterface/msg_enableds' setlocal image.testcount '1' ; reset to 1 wait reset dsmentry src null dg_control dat_userinterface msg_enableds '${get:showui},0' if '${sts:}' != 'SUCCESS' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Wait for MSG_XFERREADY, if we don't see it then scoot... ; setlocal name 'wait ${get:sys_waittimeout} seconds for MSG_XFERREADY' wait '${get:sys_waittimeout}000' if '${ret:}' !~contains 'msg_xferready' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Do a native transfer... ; :MAIN.IMAGENATIVEXFER.NEXT setlocal name 'dg_control/dat_imagenativexfer/msg_get' increment image.count '${get:image.count}' 1 dsmentry src ds dg_image dat_imagenativexfer msg_get '0' setlocal image.handle '${ret:}' if '${sts:}' != 'XFERDONE' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' image save image.handle native '${get:image.folder}/${get:image.prefix}${format:D6|${get:image.testcount}}' echo.passfail '${get:indent}image <${ret:}>' 'pass' free handle image.handle ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; End the transfer, see if we're done... ; setlocal name 'dg_control/dat_pendingxfers/msg_endxfer' dsmentry src ds dg_control dat_pendingxfers msg_endxfer '0,0' if '${sts:}' != 'SUCCESS' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' increment image.testcount '${get:image.testcount}' 1 ; count the image if '${ret:${get:TW_PENDINGXFERS.Count}}' != '0' goto MAIN.IMAGENATIVEXFER.NEXT ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; We're out of images, so disable... ; setlocal name 'dg_control/dat_userinterface/msg_disableds' dsmentry src ds dg_control dat_userinterface msg_disableds '0,0' if '${sts:}' != 'SUCCESS' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Check the results before going up to the next CAP_XFERCOUNT test. ; Note that flatbeds should always return one image. ; if '${get:feederenabled.value}' ~~ 'FALSE' goto MAIN.XFERCOUNT.CHECKTEST2 if '${get:xfercount.test}' == '2' goto MAIN.XFERCOUNT.CHECKTEST2 if '${get:xfercount.test}' == '3' goto MAIN.XFERCOUNT.CHECKTEST3 echo.passfail '${get:indent}WE SHOULD NOT BE HERE' 'fail - test=${get:xfercount.test}' goto MAIN.ERROR.ECHOPASSFAIL ; :MAIN.XFERCOUNT.CHECKTEST2 setlocal name 'one image transferred' if '${get:image.testcount}' != '2' goto MAIN.ERROR.ECHOPASSFAIL ; image.testcount started at 1 echo.passfail '${get:indent}${get:name}' 'pass' goto MAIN.XFERCOUNT.NEXT ; :MAIN.XFERCOUNT.CHECKTEST3 setlocal name 'multiple images transferred (${get:image.testcount})' if '${get:image.testcount}' < '3' goto MAIN.ERROR.ECHOPASSFAIL ; image.testcount started at 1 echo.passfail '${get:indent}${get:name}' 'pass' goto MAIN.XFERCOUNT.NEXT ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Summary and cleanup... ; ; We passed... :MAIN.PASS free handle image.handle echo.passfail 'SUMMARY' 'pass' return 'pass' ; ; Ruh-roh... :MAIN.ERROR.ECHOPASSFAIL free handle image.handle echo.passfail '${get:indent}${get:name}' 'fail - ${sts:} ${ret:}' echo.passfail 'SUMMARY' 'fail' setglobal '${arg:2}' 'fail' return 'fail' ================================================ FILE: twaincs/source/twaincscert/source/data/certification/080 - Version Tests/Certification.tc ================================================ ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Version Tests ; Confirm that the data sources responds correctly to different TWAIN versions of ; data source manager and application. ; ; Arguments ; arg:1 - TW_IDENTITY.ProductName of scanner to test ; arg:2 - global to set on fail ; ; Globals ; g_localcertifyresult - used locally to report to caller on fail ; ; Locals ; identity.productname - product name of scanner to test ; feederenabled - MSG_GET of CAP_FEEDERENABLED ; xfermech - MSG_GET of ICAP_XFERMECH ; ; Returns ; (none) ; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Initialize stuff, load tables if not already done for us... ; echo.titlesuite 'Version Tests v1.0 09-Mar-2020' setlocal identity.productname '${arg:1}' setglobal g_localcertifyresult 'pass' ; assume the best if '${get:TW_ARRAY.ItemType}' != '' goto MAIN.LOADTABLES.SKIP run '${folder:certification}/LoadTables' :MAIN.LOADTABLES.SKIP ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Only do this on 32-bit Windows... ; if '${platform:}' !~ 'WINDOWS' goto MAIN.PASS ; if not windows, we're done if '${bits:}' !~ '32' goto MAIN.PASS ; if not 32-bit, we're done ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Prompt the user, if they have an ADF... ; (if more tests are added, be sure to bump up the number of sheets needed) ; if '${get:g_skipprompts}' != '' goto MAIN.SKIP.PROMPTS call CERTIFY '${folder:certification}/Opends' '${get:identity.productname}' embedded if '${ret:}' != 'fail' goto MAIN.FEEDERENABLED call CERTIFY '${folder:certification}/Closeds' '${get:identity.productname}' embedded return ; :MAIN.FEEDERENABLED dsmentry src ds dg_control dat_capability msg_get 'CAP_FEEDERENABLED,0,0,0' setlocal feederenabled '${ret:}' call CERTIFY '${folder:certification}/Closeds' '${get:identity.productname}' embedded if '${get:feederenabled}' !~contains 'TRUE' goto MAIN.SKIP.PROMPTS echo.prompt echo.prompt "Scanning will take place during this test. There will be no" echo.prompt "need to press any button on the TWAIN user interface to start" echo.prompt "the scanner. A progress indicator may appear during scanning." echo.prompt echo.prompt "Place 6 sheets of paper in the scanner's feeder." pause '(press the ENTER key when ready to continue)' echo.prompt :MAIN.SKIP.PROMPTS ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Run the tests... ; ; MSG_OPENDSM using old DSM as TWAIN version 1.9 application, with DF_APP2 set echo.titletest 'MSG_OPENDSM using old DSM as TWAIN version 1.9 application, with DF_APP2 set' call CERTIFY '${folder:certification}/Opends' '${get:identity.productname}' embedded '' 'protocolmajor=1' 'protocolminor=9' 'uselegacydsm=true' call CERTIFY 'DAT_IMAGEMEMXFER' '${get:identity.productname}' g_localcertifyresult 'FALSE' '${folder:parent}/DAT_IMAGEMEMXFER/1' call CERTIFY '${folder:certification}/Closeds' '${get:identity.productname}' embedded echo.passfail 'SUMMARY' '${get:g_localcertifyresult}' ; MSG_OPENDSM using old DSM as TWAIN version 2.x application, with DF_APP2 not set echo.titletest 'MSG_OPENDSM using old DSM as TWAIN version 2.x application, with DF_APP2 not set' call CERTIFY '${folder:certification}/Opends' '${get:identity.productname}' embedded '' 'protocolmajor=2' 'protocolminor=4' 'uselegacydsm=true' 'supportedgroups=0x00000003' call CERTIFY 'DAT_IMAGEMEMXFER' '${get:identity.productname}' g_localcertifyresult 'FALSE' '${folder:parent}/DAT_IMAGEMEMXFER/2' call CERTIFY '${folder:certification}/Closeds' '${get:identity.productname}' embedded echo.passfail 'SUMMARY' '${get:g_localcertifyresult}' ; MSG_OPENDSM using old DSM as TWAIN version 2.x application, with DF_APP2 set echo.titletest 'MSG_OPENDSM using old DSM as TWAIN version 2.x application, with DF_APP2 set' call CERTIFY '${folder:certification}/Opends' '${get:identity.productname}' embedded '' 'protocolmajor=2' 'protocolminor=4' 'uselegacydsm=true' 'supportedgroups=0x20000003' call CERTIFY 'DAT_IMAGEMEMXFER' '${get:identity.productname}' g_localcertifyresult 'FALSE' '${folder:parent}/DAT_IMAGEMEMXFER/3' call CERTIFY '${folder:certification}/Closeds' '${get:identity.productname}' embedded echo.passfail 'SUMMARY' '${get:g_localcertifyresult}' ; MSG_OPENDSM using TWAIN 2 DSM as TWAIN version 1.9 application, with DF_APP2 set echo.titletest 'MSG_OPENDSM using TWAIN 2 DSM as TWAIN version 1.9 application, with DF_APP2 set' call CERTIFY '${folder:certification}/Opends' '${get:identity.productname}' embedded '' 'protocolmajor=1' 'protocolminor=9' 'uselegacydsm=false' 'supportedgroups=0x20000003' call CERTIFY 'DAT_IMAGEMEMXFER' '${get:identity.productname}' g_localcertifyresult 'FALSE' '${folder:parent}/DAT_IMAGEMEMXFER/4' call CERTIFY '${folder:certification}/Closeds' '${get:identity.productname}' embedded echo.passfail 'SUMMARY' '${get:g_localcertifyresult}' ; MSG_OPENDSM using TWAIN 2 DSM as TWAIN version 2.x application, with DF_APP2 not set echo.titletest 'MSG_OPENDSM using TWAIN 2 DSM as TWAIN version 2.x application, with DF_APP2 not set' call CERTIFY '${folder:certification}/Opends' '${get:identity.productname}' embedded '' 'protocolmajor=2' 'protocolminor=4' 'uselegacydsm=false' 'supportedgroups=0x00000003' call CERTIFY 'DAT_IMAGEMEMXFER' '${get:identity.productname}' g_localcertifyresult 'FALSE' '${folder:parent}/DAT_IMAGEMEMXFER/5' call CERTIFY '${folder:certification}/Closeds' '${get:identity.productname}' embedded echo.passfail 'SUMMARY' '${get:g_localcertifyresult}' ; MSG_OPENDSM using TWAIN 2 DSM as TWAIN version 1.9 application, with DF_APP2 not set echo.titletest 'MSG_OPENDSM using TWAIN 2 DSM as TWAIN version 1.9 application, with DF_APP2 not set' call CERTIFY '${folder:certification}/Opends' '${get:identity.productname}' embedded '' 'protocolmajor=1' 'protocolminor=9' 'uselegacydsm=false' 'supportedgroups=0x00000003' call CERTIFY 'DAT_IMAGEMEMXFER' '${get:identity.productname}' g_localcertifyresult 'FALSE' '${folder:parent}/DAT_IMAGEMEMXFER/6' call CERTIFY '${folder:certification}/Closeds' '${get:identity.productname}' embedded echo.passfail 'SUMMARY' '${get:g_localcertifyresult}' ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Summary and cleanup... ; ; Did we pass? (do an extra check) :MAIN.PASS if '${get:g_localcertifyresult}' != 'pass' goto MAIN.ERROR echo.passfail 'SUMMARY' 'pass' return 'pass' ; ; Ruh-roh... :MAIN.ERROR echo.passfail 'SUMMARY' 'fail' setglobal '${arg:2}' 'fail' return 'fail' ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Function: Certify ; arg:1 - script to run ; arg:2 - TW_IDENTITY.ProductName of scanner to test ; arg:3 - embeded flag for open/close -or- global to set on fail ; arg:4 - dsmload arg -or- showui ; arg:5 - dsmload arg -or- image folder ; arg:6 - dsmload arg ; arg:7 - dsmload arg ; arg:8 - dsmload arg ; returns: (none) ; :CERTIFY ; run '${arg:1}' '${arg:2}' '${arg:3}' '${arg:4}' '${arg:5}' '${arg:6}' '${arg:7}' '${arg:8}' if '${ret:}' != 'pass' goto CERTIFY.FAIL return 'pass' ; :CERTIFY.FAIL setglobal g_localcertifyresult 'fail' return 'fail' ================================================ FILE: twaincs/source/twaincscert/source/data/certification/080 - Version Tests/DAT_IMAGEMEMXFER.tc ================================================ ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; DAT_IMAGEMEMXFER ; Confirm that the data source can respond correctly to different TWAIN version of application ; and data source manager by attempting to scan using different setups. This tests for hangs and ; crashes. Use Memory transfer if available. Scan one image without UI. Testing with old DSM is ; only for 32-bit data sources only. ; ; Arguments ; arg:1 - TW_IDENTITY.ProductName of scanner to test ; arg:2 - global for us to update on failure ; arg:3 - value of ShowUI (TRUE or FALSE) ; arg:4 - test name for the image folder ; ; Globals ; (none) ; ; Locals ; name - current test being done ; indent - indent the passfail text ; imageinfo - metadata for the current image ; imagememxfer - result of DAT_IMAGEMEMXFER call ; setupmemxfer.preferred - preferred field from DAT_SETUPMEMXFER call ; ; image.count - count of images from 1 ; image.folder - folder to put the images in ; ; feederenabled.list - scanner's feederenabled values ; feederenabled.index - index of feederenabled values ; feederenabled.value - current feederenabled value ; ; pixeltype.list - scanner's pixeltype values for this feederenabled ; pixeltype.index - index of pixeltype values ; pixeltype.value - current pixeltype value ; ; Returns ; pass or fail ; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Initialize... ; setlocal indent '' setlocal image.pointer '0' setlocal image.count '0' setlocal image.folder '${folder:certimages}/${arg:4}' setlocal showui '${arg:3}' ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Clean the image folder for this test... ; image cleanfolder '${get:image.folder}' ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; MSG_RESETALL ; If return code is not TWRC_SUCCESS, end with an error ; setlocal name 'MSG_RESETALL' dsmentry src ds dg_control dat_capability msg_resetall '0,0,0,0' if '${sts:}' != 'SUCCESS' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Get and set ICAP_XFERMECH... ; setlocal name 'ICAP_XFERMECH MSG_GET' dsmentry src ds dg_control dat_capability msg_get 'ICAP_XFERMECH,0,0,0' if '${sts:}' != 'SUCCESS' goto MAIN.ERROR.ECHOPASSFAIL if '${ret:}' !~contains 'TWSX_MEMORY' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' ; setlocal name 'ICAP_XFERMECH MSG_SET TWSX_MEMORY' dsmentry src ds dg_control dat_capability msg_set 'ICAP_XFERMECH,TWON_ONEVALUE,TWTY_UINT16,TWSX_MEMORY' if '${sts:}' != 'SUCCESS' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Get the preferred size for memory transfers, and allocate ; a pointer for the memory transfers... ; setlocal name 'dg_control/dat_setupmemxfer/msg_get' dsmentry src ds dg_control dat_setupmemxfer msg_get '0,0,0' if '${sts:}' != 'SUCCESS' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' ; setlocal name 'TW_SETUPMEMXFER.Preferred > 0' setlocal setupmemxfer.preferred '${ret:${get:TW_SETUPMEMXFER.Preferred}}' if '${get:setupmemxfer.preferred}' <= '0' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' ; setlocal name 'allocate pointer for ${get:setupmemxfer.preferred} bytes' allocate pointer image.pointer '${get:setupmemxfer.preferred}' if '${get:image.pointer}' == '0' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Check for paper in the feeder, skip for a flatbed... ; :MAIN.FEEDERLOADED dsmentry src ds dg_control dat_capability msg_getcurrent 'CAP_FEEDERENABLED,0,0,0' if '${sts:}' != 'SUCCESS' goto MAIN.FEEDERLOADED.DONE if '${ret:${get:TW_ONEVALUE.Item}}' ~~ 'FALSE' goto MAIN.FEEDERLOADED.DONE dsmentry src ds dg_control dat_capability msg_getcurrent 'CAP_FEEDERLOADED,0,0,0' if '${sts:}' != 'SUCCESS' goto MAIN.FEEDERLOADED.DONE if '${ret:${get:TW_ONEVALUE.Item}}' ~~ 'TRUE' goto MAIN.FEEDERLOADED.DONE echo.prompt echo.prompt "Place paper in the scanner's feeder." pause '(press the ENTER key when ready to continue)' :MAIN.FEEDERLOADED.DONE ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; We only need one sheet of paper... ; setlocal name 'CAP_XFERCOUNT MSG_SET 1' dsmentry src ds dg_control dat_capability msg_set 'CAP_XFERCOUNT,TWON_ONEVALUE,TWTY_INT16,1' if '${sts:}' != 'SUCCESS' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Start scanning... ; :MAIN.USERINTERFACE setlocal name 'dg_control/dat_userinterface/msg_enableds' wait reset dsmentry src null dg_control dat_userinterface msg_enableds '${get:showui},0' if '${sts:}' != 'SUCCESS' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Wait for MSG_XFERREADY, if we don't see it then scoot... ; setlocal name 'wait ${get:sys_waittimeout} seconds for MSG_XFERREADY' wait '${get:sys_waittimeout}000' if '${ret:}' !~contains 'msg_xferready' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Do a memory transfer... ; This little song and dance with the states is so that we can ; start the transfer in state 6 with each new image, but switch ; to state 7 if we need multiple calls to capture the current ; image... ; ; The saved images will be in TIFF format, which includes TIFF ; JPEG (the better form, where a simple TIFF header is added). ; increment image.count '${get:image.count}' 1 image free memimage ; :MAIN.IMAGEMEMXFER.NEXT setlocal name 'dg_image/dat_imagememxfer/msg_get' dsmentry src ds dg_image dat_imagememxfer msg_get '0,0,0,0,0,0,0,9,${get:setupmemxfer.preferred},${get:image.pointer}' setlocal imagememxfer '${ret:}' if '${sts:}' == 'XFERDONE' goto MAIN.IMAGEMEMXFER.XFERDONE if '${sts:}' != 'SUCCESS' goto MAIN.ERROR.ECHOPASSFAIL ; echo.passfail '${get:indent}${get:name} SUCCESS' 'pass' image append memimage '${get:imagememxfer}' goto MAIN.IMAGEMEMXFER.NEXT ; :MAIN.IMAGEMEMXFER.XFERDONE echo.passfail '${get:indent}${get:name} XFERDONE' 'pass' ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; We need image info to make sense of this data... ; setlocal name 'dg_image/dat_imageinfo/msg_get' dsmentry src ds dg_image dat_imageinfo msg_get '0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0' setlocal imageinfo '${ret:}' if '${sts:}' != 'SUCCESS' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Save the image... ; image append memimage '${get:imagememxfer}' image addheader memimage '${get:imageinfo}' image save memimage memory '${get:image.folder}/img${format:D6|${get:image.count}}' echo.passfail '${get:indent}image <${ret:}>' 'pass' image free memimage ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; End the transfer, see if we're done... ; setlocal name 'dg_control/dat_pendingxfers/msg_endxfer' dsmentry src ds dg_control dat_pendingxfers msg_endxfer '0,0' if '${sts:}' != 'SUCCESS' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' if '${ret:${get:TW_PENDINGXFERS.Count}}' != '0' goto MAIN.IMAGEMEMXFER.NEXT ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; We're out of images, so disable; we'll drop down to MAIN.PASS... ; setlocal name 'dg_control/dat_userinterface/msg_disableds' dsmentry src ds dg_control dat_userinterface msg_disableds '0,0' if '${sts:}' != 'SUCCESS' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Summary and cleanup... ; ; We passed... :MAIN.PASS image free memimage free pointer image.pointer return 'pass' ; ; Ruh-roh... :MAIN.ERROR.ECHOPASSFAIL image free memimage free pointer image.pointer echo.passfail '${get:indent}${get:name}' 'fail - ${sts:} ${ret:}' setglobal '${arg:2}' 'fail' return 'fail' ================================================ FILE: twaincs/source/twaincscert/source/data/certification/090 - Verify Values for MSG_OPENDS, MSG_RESET, and MSG_RESETALL/Certification.tc ================================================ ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Verify Values for MSG_OPENDS, MSG_RESET, and MSG_RESETALL ; Confirm that the indicated capabilities have the values required by the Specification ; after aDG_CONTROL / DAT_CAPABILITY / MSG_RESETALL is applied to the entire driver, or ; a DG_CONTROL / DAT_CAPABILITY / MSG_RESET is applied to a single capability. Also, ; confirm those capabilities that have mandatory values after MSG_OPENDS. ; ; Arguments ; arg:1 - TW_IDENTITY.ProductName of scanner to test ; arg:2 - global to set on fail ; ; Globals ; (none) ; ; Locals ; twidentity.productname - product name of scanner to test ; certifyresult - global to set on fail ; xfermech - result of getting ICAP_XFERMECH ; ; Returns ; (none) ; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Initialize stuff, load tables if not already done for us... ; echo.titlesuite 'Verify Values for MSG_OPENDS, MSG_RESET, and MSG_RESETALL v1.0 02-Mar-2020' setlocal twidentity.productname '${arg:1}' setlocal certifyresult '${arg:2}' if '${get:TW_ARRAY.ItemType}' != '' goto MAIN.LOADTABLES.SKIP run '${folder:certification}/LoadTables' :MAIN.LOADTABLES.SKIP ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Run the tests... ; call CERTIFY 'MSG_OPENDS' '${get:twidentity.productname}' '${get:certifyresult}' if '${get:${get:certifyresult}}' == 'fail' goto MAIN.RETURN call CERTIFY 'MSG_RESET' '${get:twidentity.productname}' '${get:certifyresult}' call CERTIFY 'MSG_RESETALL' '${get:twidentity.productname}' '${get:certifyresult}' :MAIN.RETURN return ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Function: Certify ; arg:1 - script to run ; arg:2 - TW_IDENTITY.ProductName of scanner to test ; arg:3 - global value to update on fail ; arg:4 - xfermech values ; returns: (none) ; :CERTIFY ; run '${arg:1}' '${arg:2}' '${arg:3}' '${arg:4}' if '${ret:}' != 'pass' goto CERTIFY.FAIL return 'pass' ; :CERTIFY.FAIL setglobal '${arg:3}' 'fail' return 'fail' ================================================ FILE: twaincs/source/twaincscert/source/data/certification/090 - Verify Values for MSG_OPENDS, MSG_RESET, and MSG_RESETALL/MSG_OPENDS.tc ================================================ ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; MSG_OPENDS ; Compare the CAP.ValueAfterOpen values of all TWAIN standard capabilities ; for the values of CAP_FEEDERENABLES and ICAP_PIXELTYPE to make sure they ; have their mandatory settting after MSG_OPENDS. ; ; Our loop takes the form: ; foreach CAP_FEEDERENABLED ; foreach ICAP_PIXELTYPE ; foreach CAP_SUPPORTEDCAPS ; check values ; end ; end ; end ; ; Arguments ; arg:1 - TW_IDENTITY.ProductName of scanner to test ; arg:2 - global for us to update on failure ; ; Globals ; (none) ; ; Locals ; name - current test being done ; indent - indent the passfail text ; capability - getcurrent result for capability ; ; feederenabled.list - scanner's feederenabled values ; feederenabled.index - index of feederenabled values ; feederenabled.value - current feederenabled value ; ; pixeltype.list - scanner's pixeltype values for this feederenabled ; pixeltype.index - index of pixeltype values ; pixeltype.value - current pixeltype value ; ; supportedcaps.list - scanner's capabilities ; supportedcaps.index - index of supportedcaps values ; supportedcaps.value - current supportedcap value ; ; Returns ; pass or fail ; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Initialize... ; echo.titletest 'MSG_OPENDS' setlocal indent '' ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Open the source... ; run '${folder:certification}/Opends' '${arg:1}' embedded if '${ret:}' != 'pass' goto MAIN.ERROR.ECHOPASSFAIL ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Get CAP_FEEDERENABLED, and loop so we test all values ; for the current ICAP_XFERMECH setting. ; setlocal name 'CAP_FEEDERENABLED MSG_GET' dsmentry src ds dg_control dat_capability msg_get 'CAP_FEEDERENABLED,0,0,0' if '${sts:}' != 'SUCCESS' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' ; setlocal feederenabled.list '${ret:}' ; what the scanner told us setlocal feederenabled.index '${get:TW_ENUMERATION.ItemList}' ; point to itemlist increment feederenabled.index '${get:feederenabled.index}' -1 ; less 1 ; :MAIN.FEEDERENABLED.NEXT setlocal indent '' increment feederenabled.index '${get:feederenabled.index}' 1 ; next itemlist setlocal feederenabled.value '${getindex:feederenabled.list:${get:feederenabled.index}}' ; get the value if '${get:feederenabled.value}' == '' goto MAIN.PASS ; we've passed all tests!!! ; setlocal name 'CAP_FEEDERENABLED MSG_SET ${get:feederenabled.value}' dsmentry src ds dg_control dat_capability msg_set 'CAP_FEEDERENABLED,TWON_ONEVALUE,TWTY_BOOL,${get:feederenabled.value}' if '${sts:}' != 'SUCCESS' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Get ICAP_PIXELTYPE, and loop so we test all values for ; the current CAP_FEEDERENABLED setting. ; setlocal indent ' ' setlocal name 'ICAP_PIXELTYPE MSG_GET' dsmentry src ds dg_control dat_capability msg_get 'ICAP_PIXELTYPE,0,0,0' if '${sts:}' != 'SUCCESS' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' ; setlocal pixeltype.list '${ret:}' ; what the scanner told us setlocal pixeltype.index '${get:TW_ENUMERATION.ItemList}' ; point to itemlist increment pixeltype.index '${get:pixeltype.index}' -1 ; less 1 ; :MAIN.PIXELTYPE.NEXT setlocal indent ' ' increment pixeltype.index '${get:pixeltype.index}' 1 ; next itemlist setlocal pixeltype.value '${getindex:pixeltype.list:${get:pixeltype.index}}' ; get the value if '${get:pixeltype.value}' == '' goto MAIN.FEEDERENABLED.NEXT ; pixeltypes done for this feederenabled ; setlocal name 'ICAP_PIXELTYPE MSG_SET ${get:pixeltype.value}' dsmentry src ds dg_control dat_capability msg_set 'ICAP_PIXELTYPE,TWON_ONEVALUE,TWTY_UINT16,${get:pixeltype.value}' if '${sts:}' != 'SUCCESS' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Get CAP_SUPPORTEDCAPS, and loop so we test all values for ; the current ICAP_PIXELTYPE setting. ; setlocal indent ' ' setlocal name 'CAP_SUPPORTEDCAPS MSG_GET' dsmentry src ds dg_control dat_capability msg_get 'CAP_SUPPORTEDCAPS,0,0,0' if '${sts:}' != 'SUCCESS' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' ; setlocal supportedcaps.list '${ret:}' ; what the scanner told us setlocal supportedcaps.index '${get:TW_ENUMERATION.ItemList}' ; point to itemlist increment supportedcaps.index '${get:supportedcaps.index}' -1 ; less 1 ; :MAIN.SUPPORTEDCAPS.NEXT setlocal indent ' ' increment supportedcaps.index '${get:supportedcaps.index}' 1 ; next itemlist setlocal supportedcaps.value '${getindex:supportedcaps.list:${get:supportedcaps.index}}' ; get the value if '${get:supportedcaps.value}' ~contains '0x' goto MAIN.SUPPORTEDCAPS.NEXT ; nonstandard TWAIN, skip it if '${get:supportedcaps.value}' == '' goto MAIN.PIXELTYPE.NEXT ; supportedcaps done for this pixeltype ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Get the CAP.ValueAfterOpen, and skip if it's UNDEFINED ; setlocal valueafteropen '${get:${get:supportedcaps.value}.ValueAfterOpen}' if '${get:valueafteropen}' == 'UNDEFINED' goto MAIN.SUPPORTEDCAPS.NEXT ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Get the current value... ; setlocal name '${get:supportedcaps.value} MSG_GETCURRENT' dsmentry src ds dg_control dat_capability msg_getcurrent '${get:supportedcaps.value},0,0,0' setlocal capability '${ret:}' if '${sts:}' == 'CAPSEQERROR' goto MAIN.SUPPORTEDCAPS.NEXT ; skip items that we can't access right now if '${sts:}' != 'SUCCESS' goto MAIN.ERROR.ECHOPASSFAIL ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Compare the values for a TW_ONEVALUE... ; setlocal name '${get:supportedcaps.value} ${getindex:capability:${get:TW_ONEVALUE.Item}} == ${get:valueafteropen}' if '${getindex:capability:${get:TW_CAPABILITY.ConType}}' == 'TWON_ARRAY' goto MAIN.COMPARE.ARRAY.EMPTY if '${getindex:capability:${get:TW_CAPABILITY.ConType}}' != 'TWON_ONEVALUE' goto MAIN.ERROR.ECHOPASSFAIL if '${getindex:capability:${get:TW_ONEVALUE.Item}}' != '${get:valueafteropen}' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:index}${get:name}' 'pass' goto MAIN.SUPPORTEDCAPS.NEXT ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Compare the values for a TW_ARRAY that should be empty... ; :MAIN.COMPARE.ARRAY.EMPTY setlocal name '${get:supportedcaps.value} array is empty' if '${get:valueafteropen}' != '' goto MAIN.COMPARE.ARRAY.NOTEMPTY if '${getindex:capability:${get:TW_ARRAY.ItemList}' != '' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:index}${get:name}' 'pass' goto MAIN.SUPPORTEDCAPS.NEXT ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Compare the values for a TW_ARRAY that has mandatory values... ; :MAIN.COMPARE.ARRAY.NOTEMPTY setlocal name '${get:supportedcaps.value} array with values' if '${getindex:capability:${get:TW_ARRAY.ItemList}' == '' goto MAIN.ERROR.ECHOPASSFAIL ; setlocal valueafteropen.index '0' :MAIN.VALUE.NEXT setlocal value '${getindex:valueafteropen:${get:valueafteropen.index}}' if '${get:value}' == '' goto MAIN.SUPPORTEDCAPS.NEXT ; we did okay, go to the next capability setlocal name '${get:supportedcaps.value} contains '${get:value}' if '${get:capability}' !~contains '${get:value}' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:index}${get:name}' 'pass' goto MAIN.VALUE.NEXT ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Summary and cleanup... ; ; We passed... :MAIN.PASS run '${folder:certification}/Closeds' '${arg:1}' embedded echo.passfail 'SUMMARY' 'pass' return 'pass' ; ; Ruh-roh... :MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'fail - ${sts:} ${ret:}' run '${folder:certification}/Closeds' '${arg:1}' embedded echo.passfail 'SUMMARY' 'fail' setglobal '${arg:2}' 'fail' return 'fail' ================================================ FILE: twaincs/source/twaincscert/source/data/certification/090 - Verify Values for MSG_OPENDS, MSG_RESET, and MSG_RESETALL/MSG_RESET.tc ================================================ ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; MSG_RESET ; Compare the CAP.ValueAfterReset values of all TWAIN standard capabilities ; for the values of CAP_FEEDERENABLED and ICAP_PIXELTYPE to make sure they ; have their mandatory settting after running MSG_RESET on them. ; ; Our loop takes the form: ; foreach CAP_FEEDERENABLED ; foreach ICAP_PIXELTYPE ; foreach CAP_SUPPORTEDCAPS ; reset capability ; check values ; end ; end ; end ; ; Arguments ; arg:1 - TW_IDENTITY.ProductName of scanner to test ; arg:2 - global for us to update on failure ; ; Globals ; (none) ; ; Locals ; name - current test being done ; indent - indent the passfail text ; capability - getcurrent result for capability ; ; feederenabled.list - scanner's feederenabled values ; feederenabled.index - index of feederenabled values ; feederenabled.value - current feederenabled value ; ; pixeltype.list - scanner's pixeltype values for this feederenabled ; pixeltype.index - index of pixeltype values ; pixeltype.value - current pixeltype value ; ; supportedcaps.list - scanner's capabilities ; supportedcaps.index - index of supportedcaps values ; supportedcaps.value - current supportedcap value ; ; Returns ; pass or fail ; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Initialize... ; echo.titletest 'MSG_RESET' setlocal indent '' ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Open the source... ; run '${folder:certification}/Opends' '${arg:1}' embedded if '${ret:}' != 'pass' goto MAIN.ERROR.ECHOPASSFAIL ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Get CAP_FEEDERENABLED, and loop so we test all values ; for the current ICAP_XFERMECH setting. ; setlocal name 'CAP_FEEDERENABLED MSG_GET' dsmentry src ds dg_control dat_capability msg_get 'CAP_FEEDERENABLED,0,0,0' if '${sts:}' != 'SUCCESS' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' ; setlocal feederenabled.list '${ret:}' ; what the scanner told us setlocal feederenabled.index '${get:TW_ENUMERATION.ItemList}' ; point to itemlist increment feederenabled.index '${get:feederenabled.index}' -1 ; less 1 ; :MAIN.FEEDERENABLED.NEXT setlocal indent '' increment feederenabled.index '${get:feederenabled.index}' 1 ; next itemlist setlocal feederenabled.value '${getindex:feederenabled.list:${get:feederenabled.index}}' ; get the value if '${get:feederenabled.value}' == '' goto MAIN.PASS ; we've passed all tests!!! ; setlocal name 'CAP_FEEDERENABLED MSG_SET ${get:feederenabled.value}' dsmentry src ds dg_control dat_capability msg_set 'CAP_FEEDERENABLED,TWON_ONEVALUE,TWTY_BOOL,${get:feederenabled.value}' if '${sts:}' != 'SUCCESS' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Get ICAP_PIXELTYPE, and loop so we test all values for ; the current CAP_FEEDERENABLED setting. ; setlocal indent ' ' setlocal name 'ICAP_PIXELTYPE MSG_GET' dsmentry src ds dg_control dat_capability msg_get 'ICAP_PIXELTYPE,0,0,0' if '${sts:}' != 'SUCCESS' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' ; setlocal pixeltype.list '${ret:}' ; what the scanner told us setlocal pixeltype.index '${get:TW_ENUMERATION.ItemList}' ; point to itemlist increment pixeltype.index '${get:pixeltype.index}' -1 ; less 1 ; :MAIN.PIXELTYPE.NEXT setlocal indent ' ' increment pixeltype.index '${get:pixeltype.index}' 1 ; next itemlist setlocal pixeltype.value '${getindex:pixeltype.list:${get:pixeltype.index}}' ; get the value if '${get:pixeltype.value}' == '' goto MAIN.FEEDERENABLED.NEXT ; pixeltypes done for this feederenabled ; setlocal name 'ICAP_PIXELTYPE MSG_SET ${get:pixeltype.value}' dsmentry src ds dg_control dat_capability msg_set 'ICAP_PIXELTYPE,TWON_ONEVALUE,TWTY_UINT16,${get:pixeltype.value}' if '${sts:}' != 'SUCCESS' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Get CAP_SUPPORTEDCAPS, and loop so we test all values for ; the current ICAP_PIXELTYPE setting. ; setlocal indent ' ' setlocal name 'CAP_SUPPORTEDCAPS MSG_GET' dsmentry src ds dg_control dat_capability msg_get 'CAP_SUPPORTEDCAPS,0,0,0' if '${sts:}' != 'SUCCESS' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' ; setlocal supportedcaps.list '${ret:}' ; what the scanner told us setlocal supportedcaps.index '${get:TW_ENUMERATION.ItemList}' ; point to itemlist increment supportedcaps.index '${get:supportedcaps.index}' -1 ; less 1 ; :MAIN.SUPPORTEDCAPS.NEXT setlocal indent ' ' increment supportedcaps.index '${get:supportedcaps.index}' 1 ; next itemlist setlocal supportedcaps.value '${getindex:supportedcaps.list:${get:supportedcaps.index}}' ; get the value if '${get:supportedcaps.value}' ~contains '0x' goto MAIN.SUPPORTEDCAPS.NEXT ; nonstandard TWAIN, skip it if '${get:supportedcaps.value}' == '' goto MAIN.PIXELTYPE.NEXT ; supportedcaps done for this pixeltype ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Get the CAP.ValueAfterReset, and skip if it's UNDEFINED ; setlocal valueafterreset '${get:${get:supportedcaps.value}.ValueAfterReset}' if '${get:valueafterreset}' == 'UNDEFINED' goto MAIN.SUPPORTEDCAPS.NEXT ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Reset the current value... ; setlocal name '${get:supportedcaps.value} MSG_RESET' dsmentry src ds dg_control dat_capability msg_reset '${get:supportedcaps.value},0,0,0' setlocal capability '${ret:}' if '${sts:}' == 'CAPSEQERROR' goto MAIN.SUPPORTEDCAPS.NEXT ; skip items that we can't access right now if '${sts:}' != 'SUCCESS' goto MAIN.ERROR.ECHOPASSFAIL ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Compare the values for a TW_ONEVALUE... ; setlocal name '${get:supportedcaps.value} ${getindex:capability:${get:TW_ONEVALUE.Item}} == ${get:valueafterreset}' if '${getindex:capability:${get:TW_CAPABILITY.ConType}}' == 'TWON_ARRAY' goto MAIN.COMPARE.ARRAY.EMPTY if '${getindex:capability:${get:TW_CAPABILITY.ConType}}' != 'TWON_ONEVALUE' goto MAIN.ERROR.ECHOPASSFAIL if '${get:valueafterreset}' contains '|' goto MAIN.MULTIPLE.VALUES if '${getindex:capability:${get:TW_ONEVALUE.Item}}' != '${get:valueafterreset}' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' goto MAIN.SUPPORTEDCAPS.NEXT ; :MAIN.MULTIPLE.VALUES if '|${get:valueafterreset}|' !~contains '|${getindex:capability:${get:TW_ONEVALUE.Item}}|' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' goto MAIN.SUPPORTEDCAPS.NEXT ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Compare the values for a TW_ARRAY that should be empty... ; :MAIN.COMPARE.ARRAY.EMPTY setlocal name '${get:supportedcaps.value} array is empty' if '${get:valueafterreset}' != '' goto MAIN.COMPARE.ARRAY.NOTEMPTY if '${getindex:capability:${get:TW_ARRAY.ItemList}}' != '' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' goto MAIN.SUPPORTEDCAPS.NEXT ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Compare the values for a TW_ARRAY that has mandatory values... ; :MAIN.COMPARE.ARRAY.NOTEMPTY setlocal name '${get:supportedcaps.value} array with values' if '${getindex:capability:${get:TW_ARRAY.ItemList}}' == '' goto MAIN.ERROR.ECHOPASSFAIL ; setlocal valueafterreset.index '-1' :MAIN.VALUE.NEXT increment valueafterreset.index '${get:valueafterreset.index}' 1 setlocal value '${getindex:valueafterreset:${get:valueafterreset.index}}' if '${get:value}' == '' goto MAIN.SUPPORTEDCAPS.NEXT ; we did okay, go to the next capability setlocal name '${get:supportedcaps.value} contains ${get:value}' if '${get:capability}' !~contains '${get:value}' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' goto MAIN.VALUE.NEXT ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Summary and cleanup... ; ; We passed... :MAIN.PASS run '${folder:certification}/Closeds' '${arg:1}' embedded echo.passfail 'SUMMARY' 'pass' return 'pass' ; ; Ruh-roh... :MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'fail - ${sts:} ${ret:}' run '${folder:certification}/Closeds' '${arg:1}' embedded echo.passfail 'SUMMARY' 'fail' setglobal '${arg:2}' 'fail' return 'fail' ================================================ FILE: twaincs/source/twaincscert/source/data/certification/090 - Verify Values for MSG_OPENDS, MSG_RESET, and MSG_RESETALL/MSG_RESETALL.tc ================================================ ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; MSG_RESETALL ; Compare the CAP.ValueAfterReset values of all TWAIN standard capabilities ; for the values of CAP_FEEDERENABLED and ICAP_PIXELTYPE to make sure they ; have their mandatory settting after running MSG_RESETALL. ; ; Our loop takes the form: ; resetall ; foreach CAP_FEEDERENABLED ; foreach ICAP_PIXELTYPE ; foreach CAP_SUPPORTEDCAPS ; check values ; end ; end ; end ; ; Arguments ; arg:1 - TW_IDENTITY.ProductName of scanner to test ; arg:2 - global for us to update on failure ; ; Globals ; (none) ; ; Locals ; name - current test being done ; indent - indent the passfail text ; capability - getcurrent result for capability ; ; feederenabled.list - scanner's feederenabled values ; feederenabled.index - index of feederenabled values ; feederenabled.value - current feederenabled value ; ; pixeltype.list - scanner's pixeltype values for this feederenabled ; pixeltype.index - index of pixeltype values ; pixeltype.value - current pixeltype value ; ; supportedcaps.list - scanner's capabilities ; supportedcaps.index - index of supportedcaps values ; supportedcaps.value - current supportedcap value ; ; Returns ; pass or fail ; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Initialize... ; echo.titletest 'MSG_RESETALL' setlocal indent '' ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Open the source... ; run '${folder:certification}/Opends' '${arg:1}' embedded if '${ret:}' != 'pass' goto MAIN.ERROR.ECHOPASSFAIL ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Reset all... ; setlocal name 'MSG_RESETALL' dsmentry src ds dg_control dat_capability msg_resetall '0,0,0,0' if '${sts:}' != 'SUCCESS' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Get CAP_FEEDERENABLED, and loop so we test all values ; for the current ICAP_XFERMECH setting. ; setlocal name 'CAP_FEEDERENABLED MSG_GET' dsmentry src ds dg_control dat_capability msg_get 'CAP_FEEDERENABLED,0,0,0' if '${sts:}' != 'SUCCESS' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' ; setlocal feederenabled.list '${ret:}' ; what the scanner told us setlocal feederenabled.index '${get:TW_ENUMERATION.ItemList}' ; point to itemlist increment feederenabled.index '${get:feederenabled.index}' -1 ; less 1 ; :MAIN.FEEDERENABLED.NEXT setlocal indent '' increment feederenabled.index '${get:feederenabled.index}' 1 ; next itemlist setlocal feederenabled.value '${getindex:feederenabled.list:${get:feederenabled.index}}' ; get the value if '${get:feederenabled.value}' == '' goto MAIN.PASS ; we've passed all tests!!! ; setlocal name 'CAP_FEEDERENABLED MSG_SET ${get:feederenabled.value}' dsmentry src ds dg_control dat_capability msg_set 'CAP_FEEDERENABLED,TWON_ONEVALUE,TWTY_BOOL,${get:feederenabled.value}' if '${sts:}' != 'SUCCESS' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Get ICAP_PIXELTYPE, and loop so we test all values for ; the current CAP_FEEDERENABLED setting. ; setlocal indent ' ' setlocal name 'ICAP_PIXELTYPE MSG_GET' dsmentry src ds dg_control dat_capability msg_get 'ICAP_PIXELTYPE,0,0,0' if '${sts:}' != 'SUCCESS' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' ; setlocal pixeltype.list '${ret:}' ; what the scanner told us setlocal pixeltype.index '${get:TW_ENUMERATION.ItemList}' ; point to itemlist increment pixeltype.index '${get:pixeltype.index}' -1 ; less 1 ; :MAIN.PIXELTYPE.NEXT setlocal indent ' ' increment pixeltype.index '${get:pixeltype.index}' 1 ; next itemlist setlocal pixeltype.value '${getindex:pixeltype.list:${get:pixeltype.index}}' ; get the value if '${get:pixeltype.value}' == '' goto MAIN.FEEDERENABLED.NEXT ; pixeltypes done for this feederenabled ; setlocal name 'ICAP_PIXELTYPE MSG_SET ${get:pixeltype.value}' dsmentry src ds dg_control dat_capability msg_set 'ICAP_PIXELTYPE,TWON_ONEVALUE,TWTY_UINT16,${get:pixeltype.value}' if '${sts:}' != 'SUCCESS' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Get CAP_SUPPORTEDCAPS, and loop so we test all values for ; the current ICAP_PIXELTYPE setting. ; setlocal indent ' ' setlocal name 'CAP_SUPPORTEDCAPS MSG_GET' dsmentry src ds dg_control dat_capability msg_get 'CAP_SUPPORTEDCAPS,0,0,0' if '${sts:}' != 'SUCCESS' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' ; setlocal supportedcaps.list '${ret:}' ; what the scanner told us setlocal supportedcaps.index '${get:TW_ENUMERATION.ItemList}' ; point to itemlist increment supportedcaps.index '${get:supportedcaps.index}' -1 ; less 1 ; :MAIN.SUPPORTEDCAPS.NEXT setlocal indent ' ' increment supportedcaps.index '${get:supportedcaps.index}' 1 ; next itemlist setlocal supportedcaps.value '${getindex:supportedcaps.list:${get:supportedcaps.index}}' ; get the value if '${get:supportedcaps.value}' ~contains '0x' goto MAIN.SUPPORTEDCAPS.NEXT ; nonstandard TWAIN, skip it if '${get:supportedcaps.value}' == '' goto MAIN.PIXELTYPE.NEXT ; supportedcaps done for this pixeltype ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Get the CAP.ValueAfterReset, and skip if it's UNDEFINED ; setlocal valueafterreset '${get:${get:supportedcaps.value}.ValueAfterReset}' if '${get:valueafterreset}' == 'UNDEFINED' goto MAIN.SUPPORTEDCAPS.NEXT ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Reset the current value... ; setlocal name '${get:supportedcaps.value} MSG_GETCURRENT' dsmentry src ds dg_control dat_capability msg_getcurrent '${get:supportedcaps.value},0,0,0' setlocal capability '${ret:}' if '${sts:}' == 'CAPSEQERROR' goto MAIN.SUPPORTEDCAPS.NEXT ; skip items that we can't access right now if '${sts:}' != 'SUCCESS' goto MAIN.ERROR.ECHOPASSFAIL ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Compare the values for a TW_ONEVALUE... ; setlocal name '${get:supportedcaps.value} ${getindex:capability:${get:TW_ONEVALUE.Item}} == ${get:valueafterreset}' if '${getindex:capability:${get:TW_CAPABILITY.ConType}}' == 'TWON_ARRAY' goto MAIN.COMPARE.ARRAY.EMPTY if '${getindex:capability:${get:TW_CAPABILITY.ConType}}' != 'TWON_ONEVALUE' goto MAIN.ERROR.ECHOPASSFAIL if '${get:valueafterreset}' contains '|' goto MAIN.MULTIPLE.VALUES if '${getindex:capability:${get:TW_ONEVALUE.Item}}' != '${get:valueafterreset}' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' goto MAIN.SUPPORTEDCAPS.NEXT ; :MAIN.MULTIPLE.VALUES if '|${get:valueafterreset}|' !~contains '|${getindex:capability:${get:TW_ONEVALUE.Item}}|' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' goto MAIN.SUPPORTEDCAPS.NEXT ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Compare the values for a TW_ARRAY that should be empty... ; :MAIN.COMPARE.ARRAY.EMPTY setlocal name '${get:supportedcaps.value} array is empty' if '${get:valueafterreset}' != '' goto MAIN.COMPARE.ARRAY.NOTEMPTY if '${getindex:capability:${get:TW_ARRAY.ItemList}}' != '' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' goto MAIN.SUPPORTEDCAPS.NEXT ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Compare the values for a TW_ARRAY that has mandatory values... ; :MAIN.COMPARE.ARRAY.NOTEMPTY setlocal name '${get:supportedcaps.value} array with values' if '${getindex:capability:${get:TW_ARRAY.ItemList}}' == '' goto MAIN.ERROR.ECHOPASSFAIL ; setlocal valueafterreset.index '-1' :MAIN.VALUE.NEXT increment valueafterreset.index '${get:valueafterreset.index}' 1 setlocal value '${getindex:valueafterreset:${get:valueafterreset.index}}' if '${get:value}' == '' goto MAIN.SUPPORTEDCAPS.NEXT ; we did okay, go to the next capability setlocal name '${get:supportedcaps.value} contains ${get:value}' if '${get:capability}' !~contains '${get:value}' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' goto MAIN.VALUE.NEXT ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Summary and cleanup... ; ; We passed... :MAIN.PASS run '${folder:certification}/Closeds' '${arg:1}' embedded echo.passfail 'SUMMARY' 'pass' return 'pass' ; ; Ruh-roh... :MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'fail - ${sts:} ${ret:}' run '${folder:certification}/Closeds' '${arg:1}' embedded echo.passfail 'SUMMARY' 'fail' setglobal '${arg:2}' 'fail' return 'fail' ================================================ FILE: twaincs/source/twaincscert/source/data/certification/100 - TWAIN Direct Badge/Certification.tc ================================================ ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; TWAIN Direct Badge ; Check if TWAIN Direct is supported by the driver. This is a badge, meaning that failure will not ; invalidate scanner certification. Instead, passage will add TWAIN Direct support to the cert. ; ; Arguments ; arg:1 - TW_IDENTITY.ProductName of scanner to test ; arg:2 - global to set on fail ; ; Globals ; g_localcertifyresult - global to report to caller on fail ; ; Locals ; twidentity.productname - product name of scanner to test ; globaltosetonfail - name says it all ; ; Returns ; (none) ; ; History ; 1.0 - initial release ; 1.1 - add scanning so msg_settask and twei_twaindirect can be tested ; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Initialize stuff, load tables if not already done for us... ; echo.titlesuite 'TWAIN Direct Badge v1.1 17-Sep-2020' echo.yellow '*************************************************************************************' echo.yellow '*** This tests the TWAIN Direct Badge. Skipping or failing means the driver ***' echo.yellow '*** does not support this functionality. It does not prevent certification. ***' echo.yellow '*************************************************************************************' ; setlocal twidentity.productname '${arg:1}' setlocal globaltosetonfail '${arg:2}' setglobal g_localcertifyresult 'pass' ; assume success ; if '${get:TW_ARRAY.ItemType}' != '' goto MAIN.LOADTABLES.SKIP run '${folder:certification}/LoadTables' :MAIN.LOADTABLES.SKIP ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Run the tests... ; call CERTIFY '${folder:certification}/Opends' '${get:twidentity.productname}' 'g_localcertifyresult' 'embedded' if '${get:g_localcertifyresult}' == 'fail' goto MAIN.CLOSEDS ; call CERTIFY 'TWAIN Direct Badge' '${get:twidentity.productname}' 'g_localcertifyresult' call CERTIFY 'DAT_IMAGEMEMFILEXFER' '${get:twidentity.productname}' 'g_localcertifyresult' '${folder:parent}' ; :MAIN.CLOSEDS call CERTIFY '${folder:certification}/Closeds' '${get:twidentity.productname}' 'g_localcertifyresult' 'embedded' ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Summary and cleanup... ; ; Did we pass? (do an extra check) if '${get:g_localcertifyresult}' == 'skip' goto MAIN.SKIP if '${get:g_localcertifyresult}' != 'pass' goto MAIN.ERROR echo '' echo.passfail 'BADGE SUMMARY' 'pass' return 'pass' ; ; Skip... :MAIN.SKIP echo '' echo.passfail 'BADGE SUMMARY' 'skip' setglobal '${get:globaltosetonfail}' 'skip' return 'fail' ; ; Ruh-roh... :MAIN.ERROR echo '' echo.passfail 'BADGE SUMMARY' 'fail' setglobal '${get:globaltosetonfail}' 'fail' return 'fail' ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Function: Certify ; arg:1 - script to run ; arg:2 - TW_IDENTITY.ProductName of scanner to test ; arg:3 - global value to update on fail ; arg:4 - embeded flag for open/close, or folder for DAT_IMAGE*XFER calls ; returns: (none) ; :CERTIFY ; ; If a failure has occurred on a previous test, skip the rest of the tests, ; except for closing, that would be bad... if '${arg:1}' ~contains 'Closeds' goto CERTIFY.RUN if '${get:${arg:3}}' == 'skip' goto CERTIFY.SKIP if '${get:${arg:3}}' == 'fail' goto CERTIFY.FAIL ; ; Run the test... :CERTIFY.RUN run '${arg:1}' '${arg:2}' '${arg:4}' if '${ret:}' == 'skip' goto CERTIFY.SKIP if '${ret:}' != 'pass' goto CERTIFY.FAIL return 'pass' ; ; Handle skipping, set the global so we have a record... :CERTIFY.SKIP setglobal '${arg:3}' 'skip' return 'skip' ; ; Handle failure, set the global so we have a record... :CERTIFY.FAIL setglobal '${arg:3}' 'fail' return 'fail' ================================================ FILE: twaincs/source/twaincscert/source/data/certification/100 - TWAIN Direct Badge/DAT_EXTIMAGEINFO.tc ================================================ ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; DAT_EXTIMAGEINFO ; Check the return values from DAT_EXTIMAGEINFO to make sure the TWAIN Direct ; metadata is properly reported. ; ; Here's the basic flow: ; DAT_EXTIMAGEINFO ; confirm that we have TWEI_TWAINDIRECTMETADATA ; confirm a sheet with no patchcodes ; TW_INFO[0].ReturnCode values TWRC_DATANOTAVAILABLE ; confirm a sheet with one patch code ; all TW_INFO[0].ReturnCode values are TWRC_SUCCESS ; all TW_INFO[0].ItemType values match the spec ; all TW_INFO[0].NumItems equals 1 ; all TW_INFO[0].Item handle contains one of the TWPCH_* values ; ; Arguments ; arg:1 - indent the passfail text ; arg:2 - base filename (no extension) ; ; Globals ; (none) ; ; Locals ; name - current test being done ; indent - indent the passfail text ; twaindirectmetadata - the twain direct data ; ; Returns ; pass/fail ; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Get the extended image info, save the data to 'twaindirectmetadata'. ; setlocal indent '${arg:1} ' setlocal name 'dg_image/dat_extimageinfo/msg_get TWEI_TWAINDIRECTMETADATA' dsmentry src ds dg_image dat_extimageinfo msg_get '1,TWEI_TWAINDIRECTMETADATA,0,0,0,0' if '${sts:}' != 'SUCCESS' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' setlocal twaindirectmetadata '${ret:}' filewrite '${arg:2}_extimageinfo.txt' '${get:patchcodedata}' ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Confirm that we got back all the twain direct extimageinfo data... ; setlocal name 'Found TWEI_TWAINDIRECTMETADATA' if ',${get:twaindirectmetadata},' !contains 'TWEI_TWAINDIRECTMETADATA' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Start validating the contents of TWEI_TWAINDIRECTMETADATA, which is TW_INFO[0], ; we expect to find the correct id and TWRC_SUCCESS... setlocal name 'TW_INFO[0].InfoID is TWEI_TWAINDIRECTMETADATA' if '${getindex:twaindirectmetadata:${get:TW_INFO.InfoID}}' != 'TWEI_TWAINDIRECTMETADATA' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' ; setlocal name 'TW_INFO[0].ReturnCode is TWRC_SUCCESS' if '${getindex:twaindirectmetadata:${get:TW_INFO.ReturnCode}}' != 'TWRC_SUCCESS' goto MAIN.ERROR.ECHOPASSFAIL ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Process TWRC_SUCCESS... ; :MAIN.TWINFO.SUCCESS setlocal name 'TW_INFO[0].ReturnCode is TWRC_SUCCESS' echo.passfail '${get:indent}${get:name}' 'pass' ; setlocal name 'TW_INFO[0].ItemType is TWTY_HANDLE' if '${getindex:twaindirectmetadata:${get:TW_INFO.ItemType}}' != 'TWTY_HANDLE' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' ; setlocal name 'TW_INFO[0].NumItems is 1' if '${getindex:twaindirectmetadata:${get:TW_INFO.NumItems}}' != '1' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' ; setlocal name 'TW_INFO[0].Item contains metadata' if '${gethandle:${getindex:twaindirectmetadata:${get:TW_INFO.Item}}:TWTY_HANDLE:-1}' !contains 'metadata' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' echo ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Summary and cleanup... ; ; We passed... :MAIN.PASS return 'pass' ; ; Ruh-roh... :MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'fail - ${sts:} ${ret:}' return 'fail' ================================================ FILE: twaincs/source/twaincscert/source/data/certification/100 - TWAIN Direct Badge/DAT_IMAGEMEMFILEXFER.tc ================================================ ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; DAT_IMAGEMEMFILEXFER ; This test issues multiple image transfer sessions using DAT_IMAGEMEMFILEXFER. It is performed ; for all available image sources (unspecified, flatbed and/or ADF). Only one image is transferred ; per session. ; ; We follow the capability ordering, so the loops take the form: ; set ICAP_XFERMECH TWSX_MEMFILE ; foreach CAP_FEEDERENABLED ; foreach ICAP_PIXELTYPE ; scan ; end ; end ; ; Arguments ; arg:1 - ignore ; arg:2 - test name for the image folder ; ; Globals ; (none) ; ; Locals ; name - current test being done ; indent - indent the passfail text ; imagememxfer - result of DAT_IMAGEMEMXFER call ; setupmemxfer.preferred - preferred field from DAT_SETUPMEMXFER call ; ; image.count - count of images from 1 ; image.folder - folder to put the images in ; image.prefix - adf or fb ; ; Returns ; pass/fail ; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Initialize... ; echo.titletest 'DAT_IMAGEMEMFILEXFER' setlocal indent '' setlocal image.pointer '0' setlocal image.count '0' setlocal image.folder '${folder:certimages}/${arg:2}/DAT_IMAGEMEMFILEXFER' setlocal image.prefix 'fb' setlocal task.handle '0' setlocal reply.handle '0' ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Clean the image folder for this test... ; image cleanfolder '${get:image.folder}' ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; MSG_RESETALL ; If return code is not TWRC_SUCCESS, end with an error ; setlocal name 'MSG_RESETALL' dsmentry src ds dg_control dat_capability msg_resetall '0,0,0,0' if '${sts:}' != 'SUCCESS' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Set ICAP_XFERMECH to TWSX_MEMFILE... ; setlocal name 'ICAP_XFERMECH MSG_SET TWSX_MEMFILE' dsmentry src ds dg_control dat_capability msg_set 'ICAP_XFERMECH,TWON_ONEVALUE,TWTY_UINT16,TWSX_MEMFILE' if '${sts:}' != 'SUCCESS' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Set CAP_IMAGEFILEFORMAT to TWFF_PDFRASTER... ; setlocal name 'ICAP_IMAGEFILEFORMAT MSG_SET TWFF_PDFRASTER' dsmentry src ds dg_control dat_capability msg_set 'ICAP_IMAGEFILEFORMAT,TWON_ONEVALUE,TWTY_UINT32,TWFF_PDFRASTER' if '${sts:}' != 'SUCCESS' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Lists of things we'll be checking with tasks... ; setlocal source.index -1 setlocal source.list 'any,flatbed,adf' ; setlocal pixelformat.index -1 setlocal pixelformat.list 'any,bw1,gray8,rgb24' ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Select the source, when we run out, we're done... ; :MAIN.SOURCE.NEXT increment source.index ${get:source.index} 1 setlocal source.value ${getindex:source.list:${get:source.index}} if '${get:source.value}' == '' goto MAIN.PASS ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Select the pixelformat, when we run out, go to the next source... ; :MAIN.PIXELFORMAT.NEXT increment pixelformat.index ${get:pixelformat.index} 1 setlocal pixelformat.value ${getindex:pixelformat.list:${get:pixelformat.index}} if '${get:pixelformat.value}' == '' goto MAIN.SOURCE.NEXT ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Get the preferred size for memory transfers, and allocate ; a pointer for the memory transfers... ; setlocal indent ' ' setlocal name 'dg_control/dat_setupmemxfer/msg_get' dsmentry src ds dg_control dat_setupmemxfer msg_get '0,0,0' if '${sts:}' != 'SUCCESS' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' ; setlocal name 'TW_SETUPMEMXFER.Preferred > 0' setlocal setupmemxfer.preferred '${ret:${get:TW_SETUPMEMXFER.Preferred}}' if '${get:setupmemxfer.preferred}' <= '0' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' ; setlocal name 'allocate pointer for ${get:setupmemxfer.preferred} bytes' free pointer image.pointer ; for the last loop allocate pointer image.pointer '${get:setupmemxfer.preferred}' if '${get:image.pointer}' == '0' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Set DAT_SETUPFILEXFER to TWFF_PDFRASTER... ; setlocal name 'dg_control/dat_setupfilexfer/msg_set TWFF_PDFRASTER' dsmentry src null dg_control dat_setupfilexfer msg_set 'file,TWFF_PDFRASTER,0' if '${sts:}' != 'SUCCESS' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Check for paper in the feeder... ; dsmentry src ds dg_control dat_capability msg_getcurrent 'CAP_FEEDERLOADED,0,0,0' if '${sts:}' != 'SUCCESS' goto MAIN.FEEDERLOADED.DONE if '${ret:${get:TW_ONEVALUE.Item}}' ~~ 'TRUE' goto MAIN.FEEDERLOADED.DONE echo.prompt echo.prompt "Place paper in the scanner's feeder." pause '(press the ENTER key when ready to continue)' :MAIN.FEEDERLOADED.DONE ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Build the task... ; setlocal task.string '' setlocal task.string '${get:task.string}{"actions":[' setlocal task.string '${get:task.string}{"action":"encryptionProfiles","encryptionProfiles":[{"name":"","profile":""}]},' setlocal task.string '${get:task.string}{"action":"configure","streams":[{"sources":[{"source":"${get:source.value}","pixelFormats":[{"pixelFormat":"${get:pixelformat.value}","attributes":[{"attribute":"compression","values":[{"value":"autoVersion1"}]},{"attribute":"numberOfSheets","values":[{"value":1}]}]}]}]}]}' setlocal task.string '${get:task.string}]}' setlocal task.bytes '${getbytes:task.string:utf8}' ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Send the task to the scanner... ; setlocal name 'dg_control/dat_twaindirect/msg_settask ${get:source} ${get:pixelformat}' allocate handle task.handle '${get:task.bytes}' copybytes utf8handle task.string ${get:task.handle} ${get:task.bytes} ; dsmentry src ds dg_control dat_twaindirect msg_settask '${sizeof:TW_TWAINDIRECT},0,${get:task.handle},${get:task.bytes},0,0' if '${sts:}' != 'SUCCESS' goto MAIN.ERROR.ECHOPASSFAIL setlocal reply.twtwaindirect '${ret:}' echo.passfail '${get:indent}${get:name}' 'pass' ; setlocal reply.handle '${getindex:reply.twtwaindirect:${get:TW_TWAINDIRECT.Receive}} setlocal reply.bytes '${getindex:reply.twtwaindirect:${get:TW_TWAINDIRECT.ReceiveSize}} copybytes handleutf8 ${get:reply.handle} ${get:reply.bytes} reply.string ; free handle task.handle free handle reply.handle ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Check the reply for success... ; setlocal name 'Check encryptionProfiles for success' if '${get:reply.string}' !~contains '{"action":"encryptionProfiles","results":{"success":true}' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' ; setlocal name 'Check configure for success' if '${get:reply.string}' !~contains '{"action":"configure","results":{"success":true}' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Start scanning... ; setlocal name 'dg_control/dat_userinterface/msg_enableds' wait reset dsmentry src null dg_control dat_userinterface msg_enableds '0,0' if '${sts:}' != 'SUCCESS' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Wait for MSG_XFERREADY, if we don't see it then scoot... ; setlocal name 'wait ${get:sys_waittimeout} seconds for MSG_XFERREADY' wait '${get:sys_waittimeout}000' if '${ret:}' !~contains 'msg_xferready' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Do a memory file transfer... ; This little song and dance with the states is so that we can ; start the transfer in state 6 with each new image, but switch ; to state 7 if we need multiple calls to capture the current ; image... ; ; The saved images will be in TIFF format, which includes TIFF ; JPEG (the better form, where a simple TIFF header is added). ; increment image.count '${get:image.count}' 1 image free memfileimage ; :MAIN.IMAGEMEMFILEXFER.NEXT setlocal name 'dg_image/dat_imagememfilexfer/msg_get' dsmentry src ds dg_image dat_imagememfilexfer msg_get '0,0,0,0,0,0,0,9,${get:setupmemxfer.preferred},${get:image.pointer}' setlocal imagememxfer '${ret:}' if '${sts:}' == 'XFERDONE' goto MAIN.IMAGEMEMFILEXFER.XFERDONE if '${sts:}' != 'SUCCESS' goto MAIN.ERROR.ECHOPASSFAIL ; echo.passfail '${get:indent}${get:name} SUCCESS' 'pass' image append memfileimage '${get:imagememxfer}' goto MAIN.IMAGEMEMFILEXFER.NEXT ; :MAIN.IMAGEMEMFILEXFER.XFERDONE echo.passfail '${get:indent}${get:name} XFERDONE' 'pass' image append memfileimage '${get:imagememxfer}' image save memfileimage memfile '${get:image.folder}/${get:image.prefix}${format:D6|${get:image.count}}' echo.passfail '${get:indent}image <${ret:}>' 'pass' image free memfileimage ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; DAT_EXTIMAGEINFO ; Check the twaindirect metadata... ; run DAT_EXTIMAGEINFO '${get:indent}' '${get:image.folder}/adf${format:D6|${get:image.count}}' if '${ret:}' != 'pass' goto MAIN.ERROR.FAIL ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; End the transfer, see if we're done... ; setlocal name 'dg_control/dat_pendingxfers/msg_endxfer' dsmentry src ds dg_control dat_pendingxfers msg_endxfer '0,0' if '${sts:}' != 'SUCCESS' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' if '${ret:${get:TW_PENDINGXFERS.Count}}' != '0' goto MAIN.IMAGEMEMFILEXFER.NEXT ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; We're out of images, so disable and go back up to ; do the next ICAP_PIXELTYPE... ; setlocal name 'dg_control/dat_userinterface/msg_disableds' dsmentry src ds dg_control dat_userinterface msg_disableds '0,0' if '${sts:}' != 'SUCCESS' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' goto MAIN.PIXELFORMAT.NEXT ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Summary and cleanup... ; ; We passed... :MAIN.PASS echo.passfail 'SUMMARY' 'pass' image free memfileimage free pointer image.pointer return 'pass' ; ; Ruh-roh... :MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'fail - ${sts:} ${ret:}' echo.passfail 'SUMMARY' 'fail' image free memfileimage free pointer image.pointer return 'fail' ; ; Ruh-roh... :MAIN.ERROR.FAIL echo.passfail 'SUMMARY' 'fail' image free memfileimage free pointer image.pointer return 'fail' ================================================ FILE: twaincs/source/twaincscert/source/data/certification/100 - TWAIN Direct Badge/TWAIN Direct Badge.tc ================================================ ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; TWAIN Direct Badge ; These tests match those found in the TwainDirect.OnTwain/ProcessSwordTask/TwainInquiry function, ; in the section that determines if a driver has DeviceRegister.TwainDirectSupport.Driver support. ; ; While some of these tests are redundent in light of prior testing, the complete suite will be ; done to keep in sync with the TWAIN Direct code. ; ; ************************************************************************ ; ** ** ; ** DO NOT MODIFY THE TESTS HERE, UNLESS THEY HAVE BEEN UPDATED IN THE ** ; ** 'TwainDirect.OnTwain/ProcessSwordTask/TwainInquiry' FUNCTION. ** ; ** ** ; ************************************************************************ ; ; Arguments ; arg:1 - TW_IDENTITY.ProductName of scanner to test ; ; Globals ; (none) ; ; Locals ; certifyresult - track if we fail ; ; Returns ; pass/fail ; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Initialize... ; setlocal certifyresult 'pass' ; assume we'll pass ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Check if this driver claims support for TWAIN Direct... ; setlocal name 'DG_CONTROL|DAT_TWAINDIRECT found in CAP_SUPPORTEDDATS' dsmentry src ds dg_control dat_capability msg_getcurrent 'CAP_SUPPORTEDDATS,0,0,0' if '${sts:}' != 'SUCCESS' goto MAIN.SUPPORTEDDATS.FAIL if ',${ret:},' !~contains ',DG_CONTROL|DAT_TWAINDIRECT,' goto MAIN.SUPPORTEDDATS.SKIP echo.passfail '${get:name}' 'pass' goto MAIN.SUPPORTEDATS.DONE ; :MAIN.SUPPORTEDDATS.SKIP echo.passfail '${get:name}' 'skip' setlocal certifyresult 'skip' goto MAIN.DONE ; :MAIN.SUPPORTEDDATS.FAIL echo.passfail '${get:name}' 'fail - ${sts:} ${ret:}' setlocal certifyresult 'fail' goto MAIN.DONE ; :MAIN.SUPPORTEDATS.DONE ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; CAP_DEVICEONLINE must be TRUE ; setlocal name 'CAP_DEVICEONLINE is TRUE' dsmentry src ds dg_control dat_capability msg_getcurrent 'CAP_DEVICEONLINE,0,0,0' if '${sts:}' != 'SUCCESS' goto MAIN.DEVICEONLINE.FAIL if ',${ret:},' !~contains ',TRUE,' goto MAIN.DEVICEONLINE.FAIL echo.passfail '${get:name}' 'pass' goto MAIN.DEVICEONLINE.DONE ; :MAIN.DEVICEONLINE.FAIL echo.passfail '${get:name}' 'fail - ${sts:} ${ret:}' setlocal certifyresult 'fail' :MAIN.DEVICEONLINE.DONE ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; CAP_UICONTROLLABLE must be TRUE ; setlocal name 'CAP_UICONTROLLABLE is TRUE' dsmentry src ds dg_control dat_capability msg_getcurrent 'CAP_UICONTROLLABLE,0,0,0' if '${sts:}' != 'SUCCESS' goto MAIN.UICONTROLLABLE.FAIL if ',${ret:},' !~contains ',TRUE,' goto MAIN.UICONTROLLABLE.FAIL echo.passfail '${get:name}' 'pass' goto MAIN.UICONTROLLABLE.DONE ; :MAIN.UICONTROLLABLE.FAIL echo.passfail '${get:name}' 'fail - ${sts:} ${ret:}' setlocal certifyresult 'fail' :MAIN.UICONTROLLABLE.DONE ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; DAT_EXTIMAGEINFO supported ; setlocal name 'DAT_EXTIMAGEINFO supported' dsmentry src ds dg_control dat_capability msg_get 'CAP_SUPPORTEDDATS,0,0,0' if '${sts:}' != 'SUCCESS' goto MAIN.EXTIMAGEINFO.FAIL if ',${ret:},' !~contains ',DG_IMAGE|DAT_EXTIMAGEINFO,' goto MAIN.EXTIMAGEINFO.FAIL echo.passfail '${get:name}' 'pass' goto MAIN.EXTIMAGEINFO.DONE ; :MAIN.EXTIMAGEINFO.FAIL echo.passfail '${get:name}' 'fail - ${sts:} ${ret:}' setlocal certifyresult 'fail' :MAIN.EXTIMAGEINFO.DONE ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; TWEI_TWAINDIRECTMETADATA supported ; setlocal name 'TWEI_TWAINDIRECTMETADATA supported' dsmentry src ds dg_control dat_capability msg_get 'ICAP_SUPPORTEDEXTIMAGEINFO,0,0,0' if '${sts:}' != 'SUCCESS' goto MAIN.TWAINDIRECTMETADATA.FAIL if ',${ret:},' !~contains ',TWEI_TWAINDIRECTMETADATA,' goto MAIN.TWAINDIRECTMETADATA.FAIL echo.passfail '${get:name}' 'pass' goto MAIN.TWAINDIRECTMETADATA.DONE ; :MAIN.TWAINDIRECTMETADATA.FAIL echo.passfail '${get:name}' 'fail - ${sts:} ${ret:}' setlocal certifyresult 'fail' :MAIN.TWAINDIRECTMETADATA.DONE ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; TWSX_MEMFILE supported ; setlocal name 'TWSX_MEMFILE supported' dsmentry src ds dg_control dat_capability msg_get 'ICAP_XFERMECH,0,0,0' if '${sts:}' != 'SUCCESS' goto MAIN.MEMFILE.FAIL if ',${ret:},' !~contains ',TWSX_MEMFILE,' goto MAIN.MEMFILE.FAIL echo.passfail '${get:name}' 'pass' goto MAIN.MEMFILE.DONE ; :MAIN.MEMFILE.FAIL echo.passfail '${get:name}' 'fail - ${sts:} ${ret:}' setlocal certifyresult 'fail' :MAIN.MEMFILE.DONE ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; TWFF_PDFRASTER supported ; setlocal name 'TWFF_PDFRASTER supported' dsmentry src ds dg_control dat_capability msg_get 'ICAP_IMAGEFILEFORMAT,0,0,0' if '${sts:}' != 'SUCCESS' goto MAIN.PDFRASTER.FAIL if ',${ret:},' !~contains ',TWFF_PDFRASTER,' goto MAIN.PDFRASTER.FAIL echo.passfail '${get:name}' 'pass' goto MAIN.PDFRASTER.DONE ; :MAIN.PDFRASTER.FAIL echo.passfail '${get:name}' 'fail - ${sts:} ${ret:}' setlocal certifyresult 'fail' :MAIN.PDFRASTER.DONE ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; DG_CONTROL/DAT_PENDINGXFERS/MSG_RESET supported ; setlocal name 'DG_CONTROL/DAT_PENDINGXFERS/MSG_RESET supported' dsmentry src ds dg_control dat_pendingxfers msg_reset '0,0' if '${sts:}' != 'SEQERROR' goto MAIN.RESET.FAIL echo.passfail '${get:name}' 'pass' goto MAIN.RESET.DONE ; :MAIN.RESET.FAIL echo.passfail '${get:name}' 'fail - ${sts:} ${ret:}' setlocal certifyresult 'fail' :MAIN.RESET.DONE ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; ADF check, skip if no ADF ; setlocal name 'ADF check' dsmentry src ds dg_control dat_capability msg_get 'CAP_FEEDERENABLED,0,0,0' if '${sts:}' != 'SUCCESS' goto MAIN.ADFCHECK.FAIL if ',${ret:},' !~contains ',TRUE,' goto MAIN.ADFCHECK.SKIP ; dsmentry src ds dg_control dat_capability msg_set 'CAP_FEEDERENABLED,TWON_ONEVALUE,TWTY_BOOL,TRUE' if '${sts:}' != 'SUCCESS' goto MAIN.ADFCHECK.FAIL echo.passfail '${get:name}' 'pass' goto MAIN.ADFCHECK.DONE ; :MAIN.ADFCHECK.FAIL echo.passfail '${get:name}' 'fail - ${sts:} ${ret:}' setlocal certifyresult 'fail' goto MAIN.DONE ; :MAIN.ADFCHECK.SKIP echo.passfail '${get:name}' 'skip' goto MAIN.DONE :MAIN.ADFCHECK.DONE ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; DG_CONTROL/DAT_PENDINGXFERS/MSG_STOPFEEDER supported ; setlocal name 'DG_CONTROL/DAT_PENDINGXFERS/MSG_STOPFEEDER supported' dsmentry src ds dg_control dat_pendingxfers msg_stopfeeder '0,0' if '${sts:}' != 'SEQERROR' goto MAIN.STOPFEEDER.FAIL echo.passfail '${get:name}' 'pass' goto MAIN.STOPFEEDER.DONE ; :MAIN.STOPFEEDER.FAIL echo.passfail '${get:name}' 'fail - ${sts:} ${ret:}' setlocal certifyresult 'fail' :MAIN.STOPFEEDER.DONE ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; CAP_PAPERDETECTABLE must be TRUE ; setlocal name 'CAP_PAPERDETECTABLE is TRUE' dsmentry src ds dg_control dat_capability msg_getcurrent 'CAP_PAPERDETECTABLE,0,0,0' if '${sts:}' != 'SUCCESS' goto MAIN.PAPERDETECTABLE.FAIL if ',${ret:},' !~contains ',TRUE,' goto MAIN.PAPERDETECTABLE.FAIL echo.passfail '${get:name}' 'pass' goto MAIN.PAPERDETECTABLE.DONE ; :MAIN.PAPERDETECTABLE.FAIL echo.passfail '${get:name}' 'fail - ${sts:} ${ret:}' setlocal certifyresult 'fail' :MAIN.PAPERDETECTABLE.DONE ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; All done... ; :MAIN.DONE return '${get:certifyresult}' ================================================ FILE: twaincs/source/twaincscert/source/data/certification/110 - Printing Badge/Certification.tc ================================================ ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Printing Badge ; Check if Printing is supported by the driver. This is a badge, failure does not ; invalidate scanner certification. Passage adds Printing support to the cert. ; ; Printing is complex. This badge checks that a driver allows the basic ability to ; print on a document. It does not require all the possible printing features ; described by TWAIN. ; ; Arguments ; arg:1 - TW_IDENTITY.ProductName of scanner to test ; arg:2 - global to set on fail ; ; Globals ; g_localcertifyresult - global to report to caller on fail ; ; Locals ; twidentity.productname - product name of scanner to test ; globaltosetonfail - name says it all ; ; Returns ; (none) ; ; History ; 1.0 - initial release ; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Initialize stuff, load tables if not already done for us... ; echo.titlesuite 'Printing Badge v1.0 17-Sep-2021' echo.yellow '*************************************************************************************' echo.yellow '*** This tests the Printing Badge. Skipping or failing means the driver does ***' echo.yellow '*** not support this functionality. It does not prevent certification. ***' echo.yellow '*************************************************************************************' ; setlocal twidentity.productname '${arg:1}' setlocal globaltosetonfail '${arg:2}' setglobal g_localcertifyresult 'pass' ; assume success ; if '${get:TW_ARRAY.ItemType}' != '' goto MAIN.LOADTABLES.SKIP run '${folder:certification}/LoadTables' :MAIN.LOADTABLES.SKIP ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Run the tests... ; call CERTIFY '${folder:certification}/Opends' '${get:twidentity.productname}' 'g_localcertifyresult' 'embedded' if '${get:g_localcertifyresult}' == 'fail' goto MAIN.CLOSEDS ; call CERTIFY 'Printing Badge' '${get:twidentity.productname}' 'g_localcertifyresult' call CERTIFY 'DAT_IMAGENATIVEXFER' '${get:twidentity.productname}' 'g_localcertifyresult' '${folder:parent}' call CERTIFY 'DAT_IMAGEMEMXFER' '${get:twidentity.productname}' 'g_localcertifyresult' '${folder:parent}' call CERTIFY 'DAT_IMAGEFILEXFER' '${get:twidentity.productname}' 'g_localcertifyresult' '${folder:parent}' call CERTIFY 'DAT_IMAGEMEMFILEXFER' '${get:twidentity.productname}' 'g_localcertifyresult' '${folder:parent}' ; :MAIN.CLOSEDS call CERTIFY '${folder:certification}/Closeds' '${get:twidentity.productname}' 'g_localcertifyresult' 'embedded' ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Summary and cleanup... ; ; Did we pass? (do an extra check) if '${get:g_localcertifyresult}' == 'skip' goto MAIN.SKIP if '${get:g_localcertifyresult}' != 'pass' goto MAIN.ERROR echo '' echo.passfail 'BADGE SUMMARY' 'pass' return 'pass' ; ; Unsupported... :MAIN.SKIP echo '' echo.passfail 'BADGE SUMMARY' 'skip' setglobal '${get:globaltosetonfail}' 'skip' return 'skip' ; ; Ruh-roh... :MAIN.ERROR echo '' echo.passfail 'BADGE SUMMARY' 'fail' setglobal '${get:globaltosetonfail}' 'fail' return 'fail' ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Function: Certify ; arg:1 - script to run ; arg:2 - TW_IDENTITY.ProductName of scanner to test ; arg:3 - global value to update on fail ; arg:4 - embeded flag for open/close, or folder for DAT_IMAGE*XFER calls ; returns: (none) ; :CERTIFY ; ; If a failure has occurred on a previous test, skip the rest of the tests, ; except for closing, that would be bad... if '${arg:1}' ~contains 'Closeds' goto CERTIFY.RUN if '${get:${arg:3}}' == 'skip' goto CERTIFY.SKIP if '${get:${arg:3}}' == 'fail' goto CERTIFY.FAIL ; ; Run the test... :CERTIFY.RUN run '${arg:1}' '${arg:2}' '${arg:4}' if '${ret:}' == 'skip' goto CERTIFY.SKIP if '${ret:}' != 'pass' goto CERTIFY.FAIL return 'pass' ; ; Handle skipping, set the global so we have a record... :CERTIFY.SKIP setglobal '${arg:3}' 'skip' return 'skip' ; ; Handle failure, set the global so we have a record... :CERTIFY.FAIL setglobal '${arg:3}' 'fail' return 'fail' ================================================ FILE: twaincs/source/twaincscert/source/data/certification/110 - Printing Badge/DAT_EXTIMAGEINFO.tc ================================================ ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; DAT_EXTIMAGEINFO ; Check the return values from DAT_EXTIMAGEINFO to make sure the printer ; metadata is being properly reported. ; ; Here's the basic flow: ; DAT_EXTIMAGEINFO ; confirm that we have the following TWEI_PRINTER* items ; TWEI_PRINTERTEXT ; TWEI_PRINTER ; ; Arguments ; arg:1 - indent the passfail text ; arg:2 - base filename (no extension) ; arg:3 - expected value for TWEI_PRINTER ; ; Locals ; printerdata - the return value from DAT_EXTIMAGEINFO ; name - current test being done ; indent - indent the passfail text ; twinfo.infoid.index - index to TW_INFO[n].infoid from the start of barcodedata ; twinfo.itemtype.index - index to TW_INFO[n].itemtype from the start of barcodedata ; twinfo.numitems.index - index to TW_INFO[n].numitems from the start of barcodedata ; twinfo.returncode.index - index to TW_INFO[n].returncode from the start of barcodedata ; twinfo.item.index - index to TW_INFO[n].item from the start of barcodedata ; ; Returns ; pass or fail ; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Get the extended image info, save the data to 'printerdata'. ; setlocal indent '${arg:1} ' setlocal name 'dg_image/dat_extimageinfo/msg_get TWEI_PRINTER/TWEI_PRINTERTEXT' dsmentry src ds dg_image dat_extimageinfo msg_get '2,TWEI_PRINTER,0,0,0,0,TWEI_PRINTERTEXT,0,0,0,0' if '${sts:}' != 'SUCCESS' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' setlocal printerdata '${ret:}' filewrite '${arg:2}_extimageinfo.txt' '${get:printerdata}' ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Confirm that we got back all the printer extimageinfo data... ; setlocal name 'Found TWEI_PRINTER' if '${get:printerdata}' !contains ',TWEI_PRINTER,' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' setlocal name 'Found TWEI_PRINTERTEXT' if '${get:printerdata}' !contains ',TWEI_PRINTERTEXT,' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Init our TWINFO indecies for TW_INFO[0]... ; setlocal twinfo.infoid.index '${get:TW_INFO.InfoID}' setlocal twinfo.itemtype.index '${get:TW_INFO.ItemType}' setlocal twinfo.numitems.index '${get:TW_INFO.NumItems}' setlocal twinfo.returncode.index '${get:TW_INFO.ReturnCode}' setlocal twinfo.item.index '${get:TW_INFO.Item}' ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Validate the contents of TWEI_PRINTER, which is in TW_INFO[0]... ; setlocal name 'TW_INFO[0].InfoID is TWEI_PRINTER' if '${getindex:printerdata:${get:twinfo.infoid.index}}' != 'TWEI_PRINTER' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' ; setlocal name 'TW_INFO[0].ItemType is TWTY_UINT16' if '${getindex:printerdata:${get:twinfo.itemtype.index}}' != 'TWTY_UINT16' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' ; setlocal name 'TW_INFO[0].NumItems is 1' if '${getindex:printerdata:${get:twinfo.numitems.index}}' != '1' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' ; setlocal name 'TW_INFO[0].ReturnCode is TWRC_SUCCESS' if '${getindex:printerdata:${get:twinfo.returncode.index}}' != 'TWRC_SUCCESS' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' ; setlocal name 'TW_INFO[0].Item is ${arg:3}' if '${gettwei:TWEI_PRINTER:${getindex:printerdata:${get:twinfo.item.index}}}' != '${arg:3}' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Increment our TWINFO indecies for TW_INFO[1]... ; increment twinfo.infoid.index '${get:twinfo.infoid.index}' 5 ; skip to the InfoID in the next TW_INFO increment twinfo.itemtype.index '${get:twinfo.itemtype.index}' 5 ; skip to the InfoID in the next TW_INFO increment twinfo.numitems.index '${get:twinfo.numitems.index}' 5 ; skip to the NumItems in the next TW_INFO increment twinfo.returncode.index '${get:twinfo.returncode.index}' 5 ; skip to the ReturnCode in the next TW_INFO increment twinfo.item.index '${get:twinfo.item.index}' 5 ; skip to the ReturnCode in the next TW_INFO ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Validate the contents of TWEI_PRINTERTEXT, which is in TW_INFO[1]... ; setlocal name 'TW_INFO[1].InfoID is TWEI_PRINTERTEXT' if '${getindex:printerdata:${get:twinfo.infoid.index}}' != 'TWEI_PRINTERTEXT' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' ; setlocal name 'TW_INFO[1].ItemType is TWTY_STR255' if '${getindex:printerdata:${get:twinfo.itemtype.index}}' != 'TWTY_STR255' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' ; setlocal name 'TW_INFO[1].NumItems is 1' if '${getindex:printerdata:${get:twinfo.numitems.index}}' != '1' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' ; setlocal name 'TW_INFO[1].ReturnCode is TWRC_SUCCESS' if '${getindex:printerdata:${get:twinfo.returncode.index}}' != 'TWRC_SUCCESS' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' ; ; The printer text is behind a handle... setlocal handle ${getindex:printerdata:${get:twinfo.item.index}} setlocal printertext '${gethandle:${get:handle}:TWTY_STR255:0}' ; setlocal name 'TW_INFO[1].Item contains "TWAIN" (${get:printertext})' if '${get:printertext}' !contains 'TWAIN' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' ; setlocal name 'TW_INFO[1].Item contains "TEST" (${get:printertext})' if '${get:printertext}' !contains 'TEST' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' ; free handle handle ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Summary and cleanup... ; ; We passed... :MAIN.PASS return 'pass' ; ; Ruh-roh... :MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'fail - ${sts:} ${ret:}' return 'fail' ================================================ FILE: twaincs/source/twaincscert/source/data/certification/110 - Printing Badge/DAT_IMAGEFILEXFER.tc ================================================ ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; DAT_IMAGEFILEXFER ; This test scans one sheet of paper for the default pixeltype. An ADF ; is required to pass this test, but that was already been tested before ; we got to this function. ; ; Here's the basic flow: ; SetCapabilities ; start scanning ; while images ; transfer image ; DAT_EXTIMAGEINFO ; end image ; end ; end scanning ; verify the results ; ; The test passes if: ; - all of the capabilities can be set ; - TWEI_PRINTER matches CAP_PRINTER ; - TWEI_PRINTERSTRING starts with 'TWAIN' and ends with 'TEST' ; ; Arguments ; arg:1 - TW_IDENTITY.ProductName of scanner to test ; arg:2 - test name for the image folder ; ; Globals ; g_capprinter - value of CAP_PRINTER, used to check TWEI_PRINTER ; ; Locals ; name - current test being done ; indent - indent the passfail text ; twimageinfo.compression - compression for current image ; image.count - count of images from 1 ; image.folder - folder to put the images in ; ; Returns ; pass or fail ; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; If not supported, quietly leave... ; if '${get:g_xfermech}' ~contains 'TWSX_FILE' goto MAIN.CONTINUE return 'pass' :MAIN.CONTINUE ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Initialize... ; echo.titletest 'DAT_IMAGEFILEXFER' ; setlocal indent '' setlocal image.count '0' setlocal image.folder '${folder:certimages}/${arg:2}/DAT_IMAGEFILEXFER' setlocal image.showname '' ; setglobal g_capprinter '' ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Prompt the user... ; echo.prompt echo.prompt "Scanning will take place during this test. There will be no" echo.prompt "need to press any button on the TWAIN user interface to start" echo.prompt "the scanner. A progress indicator may appear during scanning." echo.prompt echo.prompt "Place 1 sheet in the scanner's feeder. The scanner will print" echo.prompt "text on this sheet." echo.prompt pause '(press the ENTER key when ready to continue)' echo.prompt ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Clean the image folder for this test... ; image cleanfolderandmeta '${get:image.folder}' ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; SetCapabilities ; This resets the driver and sets all the capabilities we need for the test. ; If its return code is not 'pass', end with an error ; run SetCapabilities 'TWSX_FILE' '${get:indent}' g_capprinter if '${ret:}' != 'pass' goto MAIN.ERROR.FAIL ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Check for paper in the feeder, prompt the user if we don't find any... ; dsmentry src ds dg_control dat_capability msg_getcurrent 'CAP_FEEDERLOADED,0,0,0' if '${sts:}' != 'SUCCESS' goto MAIN.FEEDERLOADED.DONE if '${ret:${get:TW_ONEVALUE.Item}}' ~~ 'TRUE' goto MAIN.FEEDERLOADED.DONE echo.prompt echo.prompt "Place paper in the scanner's feeder." pause '(press the ENTER key when ready to continue)' :MAIN.FEEDERLOADED.DONE ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Start scanning... ; setlocal name 'dg_control/dat_userinterface/msg_enableds' wait reset dsmentry src null dg_control dat_userinterface msg_enableds '0,0' if '${sts:}' != 'SUCCESS' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Wait for MSG_XFERREADY, if we don't see it then scoot... ; setlocal name 'wait ${get:sys_waittimeout} seconds for MSG_XFERREADY' wait '${get:sys_waittimeout}000' if '${ret:}' !~contains 'msg_xferready' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Get information about the image... ; :MAIN.IMAGEINFO.NEXT setlocal name 'dg_image/dat_imageinfo/msg_get' dsmentry src ds dg_image dat_imageinfo msg_get '0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0' if '${sts:}' != 'SUCCESS' goto MAIN.ERROR.ECHOPASSFAIL setlocal twimageinfo.compression '${ret:${get:index.twimageinfo.compression}}' echo.passfail '${get:indent}${get:name}' 'pass' ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Set up the file transfer... ; increment image.count '${get:image.count}' 1 if '${get:twimageinfo.compression}' == 'JPEG' goto MAIN.SETUPFILEXFER.JPEG setlocal image.showname 'DAT_IMAGEFILEXFER/adf${format:D6|${get:image.count}}.tif' setlocal twsetupfilexfer.filename '${get:image.folder}/adf${format:D6|${get:image.count}}.tif' setlocal twsetupfilexfer.format 'TWFF_TIFF' goto MAIN.SETUPFILEXFER :MAIN.SETUPFILEXFER.JPEG setlocal image.showname 'DAT_IMAGEFILEXFER/adf${format:D6|${get:image.count}}.jpg' setlocal twsetupfilexfer.filename '${get:image.folder}/adf${format:D6|${get:image.count}}.jpg' setlocal twsetupfilexfer.format 'TWFF_JFIF' :MAIN.SETUPFILEXFER setlocal name 'dg_control/dat_setupfilexfer/msg_set' dsmentry src ds dg_control dat_setupfilexfer msg_set '"${get:twsetupfilexfer.filename}",${get:twsetupfilexfer.format},0' if '${sts:}' != 'SUCCESS' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Transfer the image... ; setlocal name 'dg_image/dat_imagefilexfer/msg_get' dsmentry src ds dg_image dat_imagefilexfer msg_get null if '${sts:}' != 'XFERDONE' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' echo.passfail '${get:indent}image <${get:image.showname}>' 'pass' ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; DAT_EXTIMAGEINFO ; Check the printer metadata... ; run DAT_EXTIMAGEINFO '${get:indent}' '${get:image.folder}/adf${format:D6|${get:image.count}}' ${get:g_capprinter} if '${ret:}' != 'pass' goto MAIN.ERROR.FAIL ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; End the transfer, see if we're done... ; setlocal name 'dg_control/dat_pendingxfers/msg_endxfer' dsmentry src ds dg_control dat_pendingxfers msg_endxfer '0,0' if '${sts:}' != 'SUCCESS' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' if '${ret:${get:TW_PENDINGXFERS.Count}}' != '0' goto MAIN.IMAGEINFO.NEXT ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; We're out of images, so disable... ; setlocal name 'dg_control/dat_userinterface/msg_disableds' dsmentry src ds dg_control dat_userinterface msg_disableds '0,0' if '${sts:}' != 'SUCCESS' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Summary and cleanup... ; ; We passed... :MAIN.PASS echo.passfail 'SUMMARY' 'pass' return 'pass' ; ; Ruh-roh... :MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'fail - ${sts:} ${ret:}' echo.passfail 'SUMMARY' 'fail' rollback state4 return 'fail' ; ; Ruh-roh... :MAIN.ERROR.FAIL echo.passfail 'SUMMARY' 'fail' rollback state4 return 'fail' ================================================ FILE: twaincs/source/twaincscert/source/data/certification/110 - Printing Badge/DAT_IMAGEMEMFILEXFER.tc ================================================ ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; DAT_IMAGEMEMFILEXFER ; This test scans one sheet of paper for the default pixeltype. An ADF ; is required to pass this test, but that was already been tested before ; we got to this function. ; ; Here's the basic flow: ; SetCapabilities ; start scanning ; while images ; transfer image ; DAT_EXTIMAGEINFO ; end image ; end ; end scanning ; verify the results ; ; The test passes if: ; - all of the capabilities can be set ; - TWEI_PRINTER matches CAP_PRINTER ; - TWEI_PRINTERSTRING starts with 'TWAIN' and ends with 'TEST' ; ; Arguments ; arg:1 - TW_IDENTITY.ProductName of scanner to test ; arg:2 - test name for the image folder ; ; Globals ; g_capprinter - value of CAP_PRINTER, used to check TWEI_PRINTER ; ; Locals ; name - current test being done ; indent - indent the passfail text ; imagememxfer - result of DAT_IMAGEMEMXFER call ; setupmemxfer.preferred - preferred field from DAT_SETUPMEMXFER call ; image.count - count of images from 1 ; image.folder - folder to put the images in ; ; Returns ; pass/fail ; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; If not supported, quietly leave... ; if '${get:g_xfermech}' ~contains 'TWSX_MEMFILE' goto MAIN.CONTINUE return 'pass' :MAIN.CONTINUE ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Initialize... ; echo.titletest 'DAT_IMAGEMEMFILEXFER' ; setlocal indent '' setlocal image.pointer '0' setlocal image.count '0' setlocal image.folder '${folder:certimages}/${arg:2}/DAT_IMAGEMEMFILEXFER' ; setglobal g_capprinter '' ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Prompt the user... ; echo.prompt echo.prompt "Scanning will take place during this test. There will be no" echo.prompt "need to press any button on the TWAIN user interface to start" echo.prompt "the scanner. A progress indicator may appear during scanning." echo.prompt echo.prompt "Place 1 sheet in the scanner's feeder. The scanner will print" echo.prompt "text on this sheet." echo.prompt pause '(press the ENTER key when ready to continue)' echo.prompt ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Clean the image folder for this test... ; image cleanfolderandmeta '${get:image.folder}' ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; SetCapabilities ; This resets the driver and sets all the capabilities we need for the test. ; If its return code is not 'pass', end with an error ; run SetCapabilities 'TWSX_MEMFILE' '${get:indent}' g_capprinter if '${ret:}' != 'pass' goto MAIN.ERROR.FAIL ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Check for paper in the feeder, prompt the user if we don't find any... ; dsmentry src ds dg_control dat_capability msg_getcurrent 'CAP_FEEDERLOADED,0,0,0' if '${sts:}' != 'SUCCESS' goto MAIN.FEEDERLOADED.DONE if '${ret:${get:TW_ONEVALUE.Item}}' ~~ 'TRUE' goto MAIN.FEEDERLOADED.DONE echo.prompt echo.prompt "Place paper in the scanner's feeder." pause '(press the ENTER key when ready to continue)' :MAIN.FEEDERLOADED.DONE ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Get the preferred size for memory transfers, and allocate ; a pointer for the memory transfers... ; setlocal indent ' ' setlocal name 'dg_control/dat_setupmemxfer/msg_get' dsmentry src ds dg_control dat_setupmemxfer msg_get '0,0,0' if '${sts:}' != 'SUCCESS' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' ; setlocal name 'TW_SETUPMEMXFER.Preferred > 0' setlocal setupmemxfer.preferred '${ret:${get:TW_SETUPMEMXFER.Preferred}}' if '${get:setupmemxfer.preferred}' <= '0' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' ; setlocal name 'allocate pointer for ${get:setupmemxfer.preferred} bytes' free pointer image.pointer ; for the last loop allocate pointer image.pointer '${get:setupmemxfer.preferred}' if '${get:image.pointer}' == '0' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Set DAT_SETUPFILEXFER to TWFF_TIFF ; setlocal name 'dg_control/dat_setupfilexfer/msg_set TWFF_TIFF' dsmentry src null dg_control dat_setupfilexfer msg_set 'file,TWFF_TIFF,0' if '${sts:}' != 'SUCCESS' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Start scanning... ; setlocal name 'dg_control/dat_userinterface/msg_enableds' wait reset dsmentry src null dg_control dat_userinterface msg_enableds '0,0' if '${sts:}' != 'SUCCESS' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Wait for MSG_XFERREADY, if we don't see it then scoot... ; setlocal name 'wait ${get:sys_waittimeout} seconds for MSG_XFERREADY' wait '${get:sys_waittimeout}000' if '${ret:}' !~contains 'msg_xferready' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Do a memory file transfer... ; This little song and dance with the states is so that we can ; start the transfer in state 6 with each new image, but switch ; to state 7 if we need multiple calls to capture the current ; image... ; ; The saved images will be in TIFF format, which includes TIFF ; JPEG (the better form, where a simple TIFF header is added). ; increment image.count '${get:image.count}' 1 image free memfileimage ; :MAIN.IMAGEMEMFILEXFER.NEXT setlocal name 'dg_image/dat_imagememxfer/msg_get' dsmentry src ds dg_image dat_imagememfilexfer msg_get '0,0,0,0,0,0,0,9,${get:setupmemxfer.preferred},${get:image.pointer}' setlocal imagememxfer '${ret:}' if '${sts:}' == 'XFERDONE' goto MAIN.IMAGEMEMFILEXFER.XFERDONE if '${sts:}' != 'SUCCESS' goto MAIN.ERROR.ECHOPASSFAIL ; echo.passfail '${get:indent}${get:name} SUCCESS' 'pass' image append memfileimage '${get:imagememxfer}' goto MAIN.IMAGEMEMFILEXFER.NEXT ; :MAIN.IMAGEMEMFILEXFER.XFERDONE echo.passfail '${get:indent}${get:name} XFERDONE' 'pass' ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Append the last strip transferred, and save the image... ; image append memfileimage '${get:imagememxfer}' image save memfileimage memfile '${get:image.folder}/adf${format:D6|${get:image.count}}' echo.passfail '${get:indent}image <${ret:}>' 'pass' image free memfileimage ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; DAT_EXTIMAGEINFO ; Check the printer metadata... ; run DAT_EXTIMAGEINFO '${get:indent}' '${get:image.folder}/adf${format:D6|${get:image.count}}' ${get:g_capprinter} if '${ret:}' != 'pass' goto MAIN.ERROR.FAIL ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; End the transfer, see if we're done... ; setlocal name 'dg_control/dat_pendingxfers/msg_endxfer' dsmentry src ds dg_control dat_pendingxfers msg_endxfer '0,0' if '${sts:}' != 'SUCCESS' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' increment image.count '${get:image.count}' 1 if '${ret:${get:TW_PENDINGXFERS.Count}}' != '0' goto MAIN.IMAGEMEMFILEXFER.NEXT ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; We're out of images, so disable... ; setlocal name 'dg_control/dat_userinterface/msg_disableds' dsmentry src ds dg_control dat_userinterface msg_disableds '0,0' if '${sts:}' != 'SUCCESS' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Summary and cleanup... ; ; We passed... :MAIN.PASS image free memfileimage free pointer image.pointer echo.passfail 'SUMMARY' 'pass' return 'pass' ; ; Ruh-roh... :MAIN.ERROR.ECHOPASSFAIL image free memfileimage free pointer image.pointer echo.passfail '${get:indent}${get:name}' 'fail - ${sts:} ${ret:}' echo.passfail 'SUMMARY' 'fail' rollback state4 return 'fail' ; ; Ruh-roh... :MAIN.ERROR.FAIL image free memfileimage free pointer image.pointer echo.passfail 'SUMMARY' 'fail' rollback state4 return 'fail' ================================================ FILE: twaincs/source/twaincscert/source/data/certification/110 - Printing Badge/DAT_IMAGEMEMXFER.tc ================================================ ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; DAT_IMAGEMEMXFER ; This test scans one sheet of paper for the default pixeltype. An ADF ; is required to pass this test, but that was already been tested before ; we got to this function. ; ; Here's the basic flow: ; SetCapabilities ; start scanning ; while images ; transfer image ; DAT_EXTIMAGEINFO ; end image ; end ; end scanning ; verify the results ; ; The test passes if: ; - all of the capabilities can be set ; - TWEI_PRINTER matches CAP_PRINTER ; - TWEI_PRINTERSTRING starts with 'TWAIN' and ends with 'TEST' ; ; Arguments ; arg:1 - TW_IDENTITY.ProductName of scanner to test ; arg:2 - test name for the image folder ; ; Globals ; g_capprinter - value of CAP_PRINTER, used to check TWEI_PRINTER ; ; Locals ; name - current test being done ; indent - indent the passfail text ; imageinfo - metadata for the current image ; imagememxfer - result of DAT_IMAGEMEMXFER call ; setupmemxfer.preferred - preferred field from DAT_SETUPMEMXFER call ; image.count - count of images from 1 ; image.folder - folder to put the images in ; ; Returns ; pass/fail ; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Initialize... ; echo.titletest 'DAT_IMAGEMEMXFER' ; setlocal indent '' setlocal image.pointer '0' setlocal image.count '0' setlocal image.folder '${folder:certimages}/${arg:2}/DAT_IMAGEMEMXFER' ; setglobal g_capprinter '' ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Prompt the user... ; echo.prompt echo.prompt "Scanning will take place during this test. There will be no" echo.prompt "need to press any button on the TWAIN user interface to start" echo.prompt "the scanner. A progress indicator may appear during scanning." echo.prompt echo.prompt "Place 1 sheet in the scanner's feeder. The scanner will print" echo.prompt "text on this sheet." echo.prompt pause '(press the ENTER key when ready to continue)' echo.prompt ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Clean the image folder for this test... ; image cleanfolderandmeta '${get:image.folder}' ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; SetCapabilities ; This resets the driver and sets all the capabilities we need for the test. ; If its return code is not 'pass', end with an error ; run SetCapabilities 'TWSX_MEMORY' '${get:indent}' g_capprinter if '${ret:}' != 'pass' goto MAIN.ERROR.FAIL ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Check for paper in the feeder, prompt the user if we don't find any... ; dsmentry src ds dg_control dat_capability msg_getcurrent 'CAP_FEEDERLOADED,0,0,0' if '${sts:}' != 'SUCCESS' goto MAIN.FEEDERLOADED.DONE if '${ret:${get:TW_ONEVALUE.Item}}' ~~ 'TRUE' goto MAIN.FEEDERLOADED.DONE echo.prompt echo.prompt "Place paper in the scanner's feeder." pause '(press the ENTER key when ready to continue)' :MAIN.FEEDERLOADED.DONE ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Get the preferred size for memory transfers, and allocate ; a pointer for the memory transfers... ; setlocal indent ' ' setlocal name 'dg_control/dat_setupmemxfer/msg_get' dsmentry src ds dg_control dat_setupmemxfer msg_get '0,0,0' if '${sts:}' != 'SUCCESS' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' ; setlocal name 'TW_SETUPMEMXFER.Preferred > 0' setlocal setupmemxfer.preferred '${ret:${get:TW_SETUPMEMXFER.Preferred}}' if '${get:setupmemxfer.preferred}' <= '0' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' ; setlocal name 'allocate pointer for ${get:setupmemxfer.preferred} bytes' free pointer image.pointer ; for the last loop allocate pointer image.pointer '${get:setupmemxfer.preferred}' if '${get:image.pointer}' == '0' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Start scanning... ; setlocal name 'dg_control/dat_userinterface/msg_enableds' wait reset dsmentry src null dg_control dat_userinterface msg_enableds '0,0' if '${sts:}' != 'SUCCESS' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Wait for MSG_XFERREADY, if we don't see it then scoot... ; setlocal name 'wait ${get:sys_waittimeout} seconds for MSG_XFERREADY' wait '${get:sys_waittimeout}000' if '${ret:}' !~contains 'msg_xferready' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Do a memory transfer... ; This little song and dance with the states is so that we can ; start the transfer in state 6 with each new image, but switch ; to state 7 if we need multiple calls to capture the current ; image... ; ; The saved images will be in TIFF format, which includes TIFF ; JPEG (the better form, where a simple TIFF header is added). ; increment image.count '${get:image.count}' 1 image free memimage ; :MAIN.IMAGEMEMXFER.NEXT setlocal name 'dg_image/dat_imagememxfer/msg_get' dsmentry src ds dg_image dat_imagememxfer msg_get '0,0,0,0,0,0,0,9,${get:setupmemxfer.preferred},${get:image.pointer}' setlocal imagememxfer '${ret:}' if '${sts:}' == 'XFERDONE' goto MAIN.IMAGEMEMXFER.XFERDONE if '${sts:}' != 'SUCCESS' goto MAIN.ERROR.ECHOPASSFAIL ; echo.passfail '${get:indent}${get:name} SUCCESS' 'pass' image append memimage '${get:imagememxfer}' goto MAIN.IMAGEMEMXFER.NEXT ; :MAIN.IMAGEMEMXFER.XFERDONE echo.passfail '${get:indent}${get:name} XFERDONE' 'pass' ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; We need image info to make sense of this data... ; setlocal name 'dg_image/dat_imageinfo/msg_get' dsmentry src ds dg_image dat_imageinfo msg_get '0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0' setlocal imageinfo '${ret:}' if '${sts:}' != 'SUCCESS' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Append the last strip transferred, and save the image... ; image append memimage '${get:imagememxfer}' image addheader memimage '${get:imageinfo}' image save memimage memory '${get:image.folder}/adf${format:D6|${get:image.count}}' echo.passfail '${get:indent}image <${ret:}>' 'pass' image free memimage ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; DAT_EXTIMAGEINFO ; Check the printer metadata... ; run DAT_EXTIMAGEINFO '${get:indent}' '${get:image.folder}/adf${format:D6|${get:image.count}}' ${get:g_capprinter} if '${ret:}' != 'pass' goto MAIN.ERROR.FAIL ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; End the transfer, see if we're done. If not, go back ; to MAIN.IMAGENATIVEXFER.NEXT for another image... ; setlocal name 'dg_control/dat_pendingxfers/msg_endxfer' dsmentry src ds dg_control dat_pendingxfers msg_endxfer '0,0' if '${sts:}' != 'SUCCESS' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' increment image.count '${get:image.count}' 1 if '${ret:${get:TW_PENDINGXFERS.Count}}' != '0' goto MAIN.IMAGEMEMXFER.NEXT ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; We're out of images, so disable... ; setlocal name 'dg_control/dat_userinterface/msg_disableds' dsmentry src ds dg_control dat_userinterface msg_disableds '0,0' if '${sts:}' != 'SUCCESS' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Summary and cleanup... ; ; We passed... :MAIN.PASS image free memimage free pointer image.pointer echo.passfail 'SUMMARY' 'pass' return 'pass' ; ; Ruh-roh... :MAIN.ERROR.ECHOPASSFAIL image free memimage free pointer image.pointer echo.passfail '${get:indent}${get:name}' 'fail - ${sts:} ${ret:}' echo.passfail 'SUMMARY' 'fail' rollback state4 return 'fail' ; ; Ruh-roh... :MAIN.ERROR.FAIL image free memimage free pointer image.pointer echo.passfail 'SUMMARY' 'fail' rollback state4 return 'fail' ================================================ FILE: twaincs/source/twaincscert/source/data/certification/110 - Printing Badge/DAT_IMAGENATIVEXFER.tc ================================================ ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; DAT_IMAGENATIVEXFER ; This test scans one sheet of paper for the default pixeltype. An ADF ; is required to pass this test, but that was already been tested before ; we got to this function. ; ; Here's the basic flow: ; SetCapabilities ; start scanning ; while images ; transfer image ; DAT_EXTIMAGEINFO ; end image ; end ; end scanning ; verify the results ; ; The test passes if: ; - all of the capabilities can be set ; - TWEI_PRINTER matches CAP_PRINTER ; - TWEI_PRINTERSTRING starts with 'TWAIN' and ends with 'TEST' ; ; Arguments ; arg:1 - ignore ; arg:2 - test name for the image folder ; ; Globals ; g_capprinter - value of CAP_PRINTER, used to check TWEI_PRINTER ; ; Locals ; name - current test being done ; indent - indent the passfail text ; image.handle - native handle ; image.count - count of images from 1 ; image.folder - folder to put the images in ; ; Returns ; pass/fail ; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Initialize... ; echo.titletest 'DAT_IMAGENATIVEXFER' ; setlocal indent '' setlocal image.handle '0' setlocal image.count '1' setlocal image.folder '${folder:certimages}/${arg:2}/DAT_IMAGENATIVEXFER' ; setglobal g_capprinter '' ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Prompt the user... ; echo.prompt echo.prompt "Scanning will take place during this test. There will be no" echo.prompt "need to press any button on the TWAIN user interface to start" echo.prompt "the scanner. A progress indicator may appear during scanning." echo.prompt echo.prompt "Place 1 sheet in the scanner's feeder. The scanner will print" echo.prompt "text on this sheet." echo.prompt pause '(press the ENTER key when ready to continue)' echo.prompt ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Clean the image folder for this test... ; image cleanfolderandmeta '${get:image.folder}' ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; SetCapabilities ; This resets the driver and sets all the capabilities we need for the test. ; If its return code is not 'pass', end with an error ; run SetCapabilities 'TWSX_NATIVE' '${get:indent}' 'g_capprinter' if '${ret:}' != 'pass' goto MAIN.ERROR.FAIL ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Check for paper in the feeder, prompt the user if we don't find any... ; dsmentry src ds dg_control dat_capability msg_getcurrent 'CAP_FEEDERLOADED,0,0,0' if '${sts:}' != 'SUCCESS' goto MAIN.FEEDERLOADED.DONE if '${ret:${get:TW_ONEVALUE.Item}}' ~~ 'TRUE' goto MAIN.FEEDERLOADED.DONE echo.prompt echo.prompt "Place paper in the scanner's feeder." pause '(press the ENTER key when ready to continue)' :MAIN.FEEDERLOADED.DONE ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Start scanning... ; setlocal indent ' ' setlocal name 'dg_control/dat_userinterface/msg_enableds' wait reset dsmentry src null dg_control dat_userinterface msg_enableds '0,0' if '${sts:}' != 'SUCCESS' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Wait for MSG_XFERREADY, if we don't see it then scoot... ; setlocal name 'wait ${get:sys_waittimeout} seconds for MSG_XFERREADY' wait '${get:sys_waittimeout}000' if '${ret:}' !~contains 'msg_xferready' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Do a native transfer... ; :MAIN.IMAGENATIVEXFER.NEXT setlocal indent ' ' setlocal name 'dg_control/dat_imagenativexfer/msg_get' dsmentry src ds dg_image dat_imagenativexfer msg_get '0' setlocal image.handle '${ret:}' if '${sts:}' != 'XFERDONE' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Save the image... ; image save image.handle native '${get:image.folder}/adf${format:D6|${get:image.count}}' echo.passfail '${get:indent}image <${ret:}>' 'pass' free handle image.handle ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; DAT_EXTIMAGEINFO ; Check the printer metadata... ; run DAT_EXTIMAGEINFO '${get:indent}' '${get:image.folder}/adf${format:D6|${get:image.count}}' ${get:g_capprinter} if '${ret:}' != 'pass' goto MAIN.ERROR.FAIL ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; End the transfer, see if we're done. If not, go back ; to MAIN.IMAGENATIVEXFER.NEXT for another image... ; setlocal name 'dg_control/dat_pendingxfers/msg_endxfer' dsmentry src ds dg_control dat_pendingxfers msg_endxfer '0,0' if '${sts:}' != 'SUCCESS' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' increment image.count '${get:image.count}' 1 ; count the image if '${ret:${get:TW_PENDINGXFERS.Count}}' != '0' goto MAIN.IMAGENATIVEXFER.NEXT ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; We're out of images, so disable... ; setlocal name 'dg_control/dat_userinterface/msg_disableds' dsmentry src ds dg_control dat_userinterface msg_disableds '0,0' if '${sts:}' != 'SUCCESS' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Summary and cleanup... ; ; We passed... :MAIN.PASS free handle image.handle echo.passfail 'SUMMARY' 'pass' return 'pass' ; ; Ruh-roh... :MAIN.ERROR.ECHOPASSFAIL free handle image.handle echo.passfail '${get:indent}${get:name}' 'fail - ${sts:} ${ret:}' echo.passfail 'SUMMARY' 'fail' rollback state4 return 'fail' ; ; Ruh-roh... :MAIN.ERROR.FAIL free handle image.handle echo.passfail 'SUMMARY' 'fail' rollback state4 return 'fail' ================================================ FILE: twaincs/source/twaincscert/source/data/certification/110 - Printing Badge/Printing Badge.tc ================================================ ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Printing Badge ; These tests establish the minimum requirements for a TWAIN driver to claim that is has printing ; support. To pass the driver must support the following capabilites: ; CAP_PRINTERENABLED ; CAP_PRINTER ; CAP_PRINTERMODE ; CAP_PRINTERSTRING ; CAP_PRINTERINDEX ; CAP_PRINTERSUFFIX ; CAP_PRINTERVERTICALOFFSET ; ; And the following extended image info items: ; TWEI_PRINTERTEXT ; TWEI_PRINTER ; ; Arguments ; (none) ; ; Globals ; (none) ; ; Locals ; name - name of a test ; certifyresult - track if we fail ; ; Returns ; pass/fail ; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Initialize... ; setlocal certifyresult 'pass' ; assume we'll pass, this is our return value ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Reset to a known state, this is mandatory... ; setlocal name 'MSG_RESETALL' dsmentry src ds dg_control dat_capability msg_resetall '0,0,0,0' if '${sts:}' != 'SUCCESS' goto MAIN.MSG_RESETALL.FAIL echo.passfail '${get:name}' 'pass' goto MAIN.MSG_RESETALL.DONE ; :MAIN.MSG_RESETALL.FAIL echo.passfail '${get:name}' 'skip - ${sts:} ${ret:}' setlocal certifyresult 'fail' goto MAIN.DONE :MAIN.MSG_RESETALL.DONE ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; CAP_PRINTERENABLED must be supported, and must offer both TRUE ; and FALSE, and must currently be FALSE (as a result of MSG_RESETALL, ; otherwise skip it all... ; setlocal name 'CAP_PRINTERENBLED is supported' dsmentry src ds dg_control dat_capability msg_get 'CAP_PRINTERENABLED,0,0,0' if '${sts:}' != 'SUCCESS' goto MAIN.CAP_PRINTERENABLEDSUPPORTED.SKIP if ',${ret:},' !~contains ',TRUE,' goto MAIN.CAP_PRINTERENABLEDSUPPORTED.SKIP if ',${ret:},' !~contains ',FALSE,' goto MAIN.CAP_PRINTERENABLEDSUPPORTED.SKIP echo.passfail '${get:name}' 'pass' goto MAIN.CAP_PRINTERENABLEDSUPPORTED.DONE ; :MAIN.CAP_PRINTERENABLEDSUPPORTED.SKIP echo.passfail '${get:name}' 'skip - ${sts:} ${ret:}' setlocal certifyresult 'skip' goto MAIN.DONE :MAIN.CAP_PRINTERENABLEDSUPPORTED.DONE ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; CAP_SUPPORTEDCAPS: check that all required capabilities are reported ; setlocal name 'CAP_SUPPORTEDCAPS MSG_GET' dsmentry src ds dg_control dat_capability msg_get 'CAP_SUPPORTEDCAPS,0,0,0' if '${sts:}' != 'SUCCESS' goto MAIN.CAP_SUPPORTEDCAPS.FAIL echo.passfail '${get:name}' 'pass' ; setlocal name 'CAP_SUPPORTEDCAPS CAP_PRINTERENABLED found' if ',${ret:},' !~contains ',CAP_PRINTERENABLED,' goto MAIN.CAP_SUPPORTEDCAPS.FAIL echo.passfail '${get:name}' 'pass' ; setlocal name 'CAP_SUPPORTEDCAPS CAP_PRINTER found' if ',${ret:},' !~contains ',CAP_PRINTER,' goto MAIN.CAP_SUPPORTEDCAPS.FAIL echo.passfail '${get:name}' 'pass' ; setlocal name 'CAP_SUPPORTEDCAPS CAP_PRINTERMODE found' if ',${ret:},' !~contains ',CAP_PRINTERMODE,' goto MAIN.CAP_SUPPORTEDCAPS.FAIL echo.passfail '${get:name}' 'pass' ; setlocal name 'CAP_SUPPORTEDCAPS CAP_PRINTERSTRING found' if ',${ret:},' !~contains ',CAP_PRINTERSTRING,' goto MAIN.CAP_SUPPORTEDCAPS.FAIL echo.passfail '${get:name}' 'pass' ; setlocal name 'CAP_SUPPORTEDCAPS CAP_PRINTERINDEX found' if ',${ret:},' !~contains ',CAP_PRINTERINDEX,' goto MAIN.CAP_SUPPORTEDCAPS.FAIL echo.passfail '${get:name}' 'pass' ; setlocal name 'CAP_SUPPORTEDCAPS CAP_PRINTERSUFFIX found' if ',${ret:},' !~contains ',CAP_PRINTERSUFFIX,' goto MAIN.CAP_SUPPORTEDCAPS.FAIL echo.passfail '${get:name}' 'pass' ; setlocal name 'CAP_SUPPORTEDCAPS CAP_PRINTERVERTICALOFFSET found' if ',${ret:},' !~contains ',CAP_PRINTERVERTICALOFFSET,' goto MAIN.CAP_SUPPORTEDCAPS.FAIL echo.passfail '${get:name}' 'pass' goto MAIN.CAP_SUPPORTEDCAPS.DONE ; :MAIN.CAP_SUPPORTEDCAPS.FAIL echo.passfail '${get:name}' 'fail - ${sts:} ${ret:}' setlocal certifyresult 'fail' goto MAIN.DONE :MAIN.CAP_SUPPORTEDCAPS.DONE ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; ICAP_SUPPORTEDEXTIMAGEINFO: check that all metadata is reported ; setlocal name 'ICAP_SUPPORTEDEXTIMAGEINFO MSG_GET' dsmentry src ds dg_control dat_capability msg_get 'ICAP_SUPPORTEDEXTIMAGEINFO,0,0,0' if '${sts:}' != 'SUCCESS' goto MAIN.ICAP_SUPPORTEDEXTIMAGEINFO.FAIL echo.passfail '${get:name}' 'pass' ; setlocal name 'ICAP_SUPPORTEDEXTIMAGEINFO TWEI_PRINTERTEXT found' if ',${ret:},' !~contains ',TWEI_PRINTERTEXT,' goto MAIN.ICAP_SUPPORTEDEXTIMAGEINFO.FAIL echo.passfail '${get:name}' 'pass' ; setlocal name 'ICAP_SUPPORTEDEXTIMAGEINFO TWEI_PRINTER found' if ',${ret:},' !~contains ',TWEI_PRINTER,' goto MAIN.ICAP_SUPPORTEDEXTIMAGEINFO.FAIL echo.passfail '${get:name}' 'pass' goto MAIN.ICAP_SUPPORTEDEXTIMAGEINFO.DONE ; :MAIN.ICAP_SUPPORTEDEXTIMAGEINFO.FAIL echo.passfail '${get:name}' 'fail - ${sts:} ${ret:}' setlocal certifyresult 'fail' :MAIN.ICAP_SUPPORTEDEXTIMAGEINFO.DONE ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; ICAP_XFERMECH: get the xfermech so we know which tests to run ; setlocal name 'ICAP_XFERMECH MSG_GET' dsmentry src ds dg_control dat_capability msg_get 'ICAP_XFERMECH,0,0,0' if '${sts:}' != 'SUCCESS' goto MAIN.ICAP_XFERMECH.FAIL echo.passfail '${get:name}' 'pass' setglobal g_xfermech '${ret:} goto MAIN.ICAP_XFERMECH.DONE ; :MAIN.ICAP_XFERMECH.FAIL echo.passfail '${get:name}' 'fail - ${sts:} ${ret:}' setlocal certifyresult 'fail' :MAIN.ICAP_XFERMECH.DONE ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; All done... ; :MAIN.DONE return '${get:certifyresult}' ================================================ FILE: twaincs/source/twaincscert/source/data/certification/110 - Printing Badge/SetCapabilities.tc ================================================ ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; SetCapabilities ; Reset the driver's capabilites, and then set capabilities for this test. Note that one can only ; get this badge for the ADF. This is a production mode feature, so we're not testing the flatbed. ; Printing performs two main tasks: it endorses a sheet of paper to confirm it passed through the ; scanner, and the string printed on the sheet of paper may allow the user to find the corresponding ; image, if it's printed before the image is scanned. ; ; We follow the capability ordering: ; MSG_RESETALL ; set ICAP_XFERMECH.....................${arg:1} ; set CAP_FEEDERENABLED.................TRUE ; set CAP_XFERCOUNT.....................1 ; set ICAP_EXTIMAGEINFO.................TRUE ; set CAP_PRINTERENABLED................TRUE ; set CAP_PRINTER.......................TWPR_IMPRINTERTOPBEFORE, TWPR_IMPRINTERTOPAFTER, ; TWPR_IMPRINTERBOTTOMBEFORE,or TWPR_IMPRINTERBOTTOMAFTER ; set CAP_PRINTERMODE...................TWPM_COMPOUNDSTRING ; set CAP_PRINTERSTRING.................TWAIN ; set CAP_PRINTERINDEX..................TWAIN ; set CAP_PRINTERSUFFIX.................TWAIN ; set CAP_PRINTERVERTICALOFFSET.........set to its max value ; ; The test passes if all operations return TWRC_SUCCESS. ; ; Arguments ; arg:1 - TWSX_* value for ICAP_XFERMECH ; arg:2 - value of caller's indent ; arg:3 - global variable to store the CAP_PRINTER value ; ; Locals ; capprintervariable - global variable to store the CAP_PRINTER value ; indent - indent the passfail text ; name - name of the current test ; twsx - TWSX_* value for ICAP_XFERMECH ; ; Returns ; pass or fail ; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Initialize... ; setlocal twsx '${arg:1}' setlocal indent '${arg:2}' setlocal capprintervariable '${arg:3}' ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; MSG_RESETALL ; If return code is not TWRC_SUCCESS, end with an error ; setlocal name 'MSG_RESETALL' dsmentry src ds dg_control dat_capability msg_resetall '0,0,0,0' if '${sts:}' != 'SUCCESS' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Set ICAP_XFERMECH... ; setlocal name 'ICAP_XFERMECH MSG_SET ${get:twsx}' dsmentry src ds dg_control dat_capability msg_set 'ICAP_XFERMECH,TWON_ONEVALUE,TWTY_UINT16,${get:twsx}' if '${sts:}' != 'SUCCESS' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Set CAP_FEEDERENABLED to TRUE ; setlocal name 'CAP_FEEDERENABLED MSG_SET TRUE' dsmentry src ds dg_control dat_capability msg_set 'CAP_FEEDERENABLED,TWON_ONEVALUE,TWTY_BOOL,TRUE' if '${sts:}' != 'SUCCESS' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Set CAP_XFERCOUNT to 1 ; setlocal name 'CAP_XFERCOUNT MSG_SET 1' dsmentry src ds dg_control dat_capability msg_set 'CAP_XFERCOUNT,TWON_ONEVALUE,TWTY_INT16,1' if '${sts:}' != 'SUCCESS' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Set ICAP_EXTIMAGEINFO to TRUE ; setlocal name 'ICAP_EXTIMAGEINFO MSG_SET TRUE' dsmentry src ds dg_control dat_capability msg_set 'ICAP_EXTIMAGEINFO,TWON_ONEVALUE,TWTY_BOOL,TRUE' if '${sts:}' != 'SUCCESS' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; CAP_PRINTERENABLED must currently be FALSE ; setlocal name 'CAP_PRINTERENBLED resets to FALSE' dsmentry src ds dg_control dat_capability msg_getcurrent 'CAP_PRINTERENABLED,0,0,0' if '${sts:}' != 'SUCCESS' goto MAIN.ERROR.ECHOPASSFAIL if ',${ret:},' !~contains ',FALSE,' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; CAP_PRINTERENABLED set to TRUE ; setlocal name 'CAP_PRINTERENBLED set to TRUE' dsmentry src ds dg_control dat_capability msg_set 'CAP_PRINTERENABLED,TWON_ONEVALUE,TWTY_BOOL,TRUE' if '${sts:}' != 'SUCCESS' goto MAIN.ERROR.ECHOPASSFAIL dsmentry src ds dg_control dat_capability msg_getcurrent 'CAP_PRINTERENABLED,0,0,0' if '${sts:}' != 'SUCCESS' goto MAIN.ERROR.ECHOPASSFAIL if ',${ret:},' !~contains ',TRUE,' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; CAP_PRINTER must be supported with at least one of the printer values, ; squirrel away the value in the global argument stored in capprintervariable ; setlocal name 'CAP_PRINTER is supported' dsmentry src ds dg_control dat_capability msg_getcurrent 'CAP_PRINTER,0,0,0' if '${sts:}' != 'SUCCESS' goto MAIN.ERROR.ECHOPASSFAIL if ',${ret:},' ~contains ',TWPR_IMPRINTERTOPBEFORE,' goto MAIN.PRINTER.PASS if ',${ret:},' ~contains ',TWPR_IMPRINTERTOPAFTER,' goto MAIN.PRINTER.PASS if ',${ret:},' ~contains ',TWPR_IMPRINTERBOTTOMBEFORE,' goto MAIN.PRINTER.PASS if ',${ret:},' ~contains ',TWPR_IMPRINTERBOTTOMAFTER,' goto MAIN.PRINTER.PASS goto MAIN.ERROR.ECHOPASSFAIL ; ; Save the value so we can set it later... :MAIN.PRINTER.PASS setglobal ${get:capprintervariable} ${ret:${get:TW_ONEVALUE.Item}} echo.passfail '${get:indent}${get:name}' 'pass (${get:${get:capprintervariable}})' ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; CAP_PRINTERMODE must be supported, and allow TWPM_COMPOUNDSTRING ; setlocal name 'CAP_PRINTERMODE is supported' dsmentry src ds dg_control dat_capability msg_set 'CAP_PRINTERMODE,TWON_ONEVALUE,TWTY_UINT16,TWPM_COMPOUNDSTRING' if '${sts:}' != 'SUCCESS' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; CAP_PRINTERSTRING must be supported, and allow setting to 'TWAIN'... ; setlocal name 'CAP_PRINTERSTRING is supported' dsmentry src ds dg_control dat_capability msg_set 'CAP_PRINTERSTRING,TWON_ONEVALUE,TWTY_STR255,TWAIN' if '${sts:}' != 'SUCCESS' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; CAP_PRINTERINDEX must be supported, and allow setting to 1... ; setlocal name 'CAP_PRINTERINDEX is supported' dsmentry src ds dg_control dat_capability msg_set 'CAP_PRINTERINDEX,TWON_ONEVALUE,TWTY_UINT32,1' if '${sts:}' != 'SUCCESS' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; CAP_PRINTERSUFFIX must be supported, and allow setting to 'TEST'... ; setlocal name 'CAP_PRINTERSUFFIX is supported' dsmentry src ds dg_control dat_capability msg_set 'CAP_PRINTERSUFFIX,TWON_ONEVALUE,TWTY_STR255,TEST' if '${sts:}' != 'SUCCESS' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; CAP_PRINTERVERTICALOFFSET must be supported, and allow setting to the current value... ; setlocal name 'CAP_PRINTERVERTICALOFFSET is supported' dsmentry src ds dg_control dat_capability msg_getcurrent 'CAP_PRINTERVERTICALOFFSET' if '${sts:}' != 'SUCCESS' goto MAIN.ERROR.ECHOPASSFAIL dsmentry src ds dg_control dat_capability msg_set 'CAP_PRINTERVERTICALOFFSET,TWON_ONEVALUE,TWTY_FIX32,${ret:${get:TW_ONEVALUE.Item}}' if '${sts:}' != 'SUCCESS' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Summary and cleanup... ; ; We passed... :MAIN.PASS return 'pass' ; ; Skip this item... :MAIN.SKIP echo.passfail '${get:name}' 'skip - ${sts:} ${ret:}' return 'skip' ; ; Ruh-roh... :MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'fail - ${sts:} ${ret:}' return 'fail' ================================================ FILE: twaincs/source/twaincscert/source/data/certification/120 - Patch Code Badge/Certification.tc ================================================ ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Patch Code Badge ; Check if Patch Code is supported by the driver. This is a badge, failure does not ; invalidate scanner certification. Passage adds Patch Code support to the cert. ; ; Arguments ; arg:1 - TW_IDENTITY.ProductName of scanner to test ; arg:2 - global to set on fail ; ; Globals ; g_localcertifyresult - global to report to caller on fail ; g_xfermech - transfer mechanism currently in use ; ; Locals ; twidentity.productname - product name of scanner to test ; globaltosetonfail - name says it all ; ; Returns ; (none) ; ; History ; 1.0 - initial release ; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Initialize stuff, load tables if not already done for us... ; echo.titlesuite 'Patch Code Badge v1.0 17-Sep-2021' echo.yellow '*************************************************************************************' echo.yellow '*** This tests the Patch Code Badge. Skipping or failing means the driver does ***' echo.yellow '*** not support this functionality. It does not prevent certification. ***' echo.yellow '*************************************************************************************' ; setlocal twidentity.productname '${arg:1}' setlocal globaltosetonfail '${arg:2}' setglobal g_localcertifyresult 'pass' ; assume success setglobal g_xfermech '' ; this will be set later ; if '${get:TW_ARRAY.ItemType}' != '' goto MAIN.LOADTABLES.SKIP run '${folder:certification}/LoadTables' :MAIN.LOADTABLES.SKIP ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Run the tests... ; call CERTIFY '${folder:certification}/Opends' '${get:twidentity.productname}' 'g_localcertifyresult' 'embedded' if '${get:g_localcertifyresult}' == 'fail' goto MAIN.CLOSEDS ; call CERTIFY 'Patch Code Badge' '${get:twidentity.productname}' 'g_localcertifyresult' call CERTIFY 'DAT_IMAGENATIVEXFER' '${get:twidentity.productname}' 'g_localcertifyresult' '${folder:parent}' call CERTIFY 'DAT_IMAGEMEMXFER' '${get:twidentity.productname}' 'g_localcertifyresult' '${folder:parent}' call CERTIFY 'DAT_IMAGEFILEXFER' '${get:twidentity.productname}' 'g_localcertifyresult' '${folder:parent}' call CERTIFY 'DAT_IMAGEMEMFILEXFER' '${get:twidentity.productname}' 'g_localcertifyresult' '${folder:parent}' ; :MAIN.CLOSEDS call CERTIFY '${folder:certification}/Closeds' '${get:twidentity.productname}' 'g_localcertifyresult' 'embedded' ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Summary and cleanup... ; ; Did we pass? (do an extra check) if '${get:g_localcertifyresult}' == 'skip' goto MAIN.SKIP if '${get:g_localcertifyresult}' != 'pass' goto MAIN.ERROR echo '' echo.passfail 'BADGE SUMMARY' 'pass' return 'pass' ; ; Unsupported... :MAIN.SKIP echo '' echo.passfail 'BADGE SUMMARY' 'skip' setglobal '${get:globaltosetonfail}' 'skip' return 'skip' ; ; Ruh-roh... :MAIN.ERROR echo '' echo.passfail 'BADGE SUMMARY' 'fail' setglobal '${get:globaltosetonfail}' 'fail' return 'fail' ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Function: Certify ; arg:1 - script to run ; arg:2 - TW_IDENTITY.ProductName of scanner to test ; arg:3 - global value to update on fail ; arg:4 - embeded flag for open/close, or folder for DAT_IMAGE*XFER calls ; returns: (none) ; :CERTIFY ; ; If a failure has occurred on a previous test, skip the rest of the tests, ; except for closing, that would be bad... if '${arg:1}' ~contains 'Closeds' goto CERTIFY.RUN if '${get:${arg:3}}' == 'skip' goto CERTIFY.SKIP if '${get:${arg:3}}' == 'fail' goto CERTIFY.FAIL ; ; Run the test... :CERTIFY.RUN run '${arg:1}' '${arg:2}' '${arg:4}' if '${ret:}' == 'skip' goto CERTIFY.SKIP if '${ret:}' != 'pass' goto CERTIFY.FAIL return 'pass' ; ; Handle skipping, set the global so we have a record... :CERTIFY.SKIP setglobal '${arg:3}' 'skip' return 'skip' ; ; Handle failure, set the global so we have a record... :CERTIFY.FAIL setglobal '${arg:3}' 'fail' return 'fail' ================================================ FILE: twaincs/source/twaincscert/source/data/certification/120 - Patch Code Badge/DAT_EXTIMAGEINFO.tc ================================================ ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; DAT_EXTIMAGEINFO ; Check the return values from DAT_EXTIMAGEINFO to make sure the patch code ; metadata is properly reported. ; ; Here's the basic flow: ; DAT_EXTIMAGEINFO ; confirm that we have TWEI_PATCHCODE ; confirm a sheet with no patchcodes ; TW_INFO[0].ReturnCode values TWRC_DATANOTAVAILABLE ; confirm a sheet with one patch code ; all TW_INFO[0].ReturnCode values are TWRC_SUCCESS ; all TW_INFO[0].ItemType values match the spec ; all TW_INFO[0].NumItems equals 1 ; all TW_INFO[0].Item handle contains one of the TWPCH_* values ; ; The test passes if: ; - g_patchcodecount.none >= 1 ; and (g_patchcodecount.one >= 1) ; ; Arguments ; arg:1 - indent the passfail text ; arg:2 - base filename (no extension) ; ; Globals ; g_patchcodecount.none - increment if no patchcodes are found ; g_patchcodecount.one - increment if one patchcodes is found ; ; Locals ; patchcodecount - the number of patchcodes found on the image ; patchcodedata - the return value from DAT_EXTIMAGEINFO ; name - current test being done ; indent - indent the passfail text ; twinfo.infoid.index - index to TW_INFO[n].infoid from the start of patchcodedata ; twinfo.itemtype.index - index to TW_INFO[n].itemtype from the start of patchcodedata ; twinfo.numitems.index - index to TW_INFO[n].numitems from the start of patchcodedata ; twinfo.returncode.index - index to TW_INFO[n].returncode from the start of patchcodedata ; twinfo.item.index - index to TW_INFO[n].item from the start of patchcodedata ; ; Returns ; pass/fail ; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Get the extended image info, save the data to 'patchcodedata'. ; setlocal indent '${arg:1} ' setlocal name 'dg_image/dat_extimageinfo/msg_get TWEI_PATCHCODE' dsmentry src ds dg_image dat_extimageinfo msg_get '1,TWEI_PATCHCODE,0,0,0,0' if '${sts:}' != 'SUCCESS' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' setlocal patchcodedata '${ret:}' filewrite '${arg:2}_extimageinfo.txt' '${get:patchcodedata}' ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Confirm that we got back all the patch code extimageinfo data... ; setlocal name 'Found TWEI_PATCHCODE' if ',${get:patchcodedata},' !contains 'TWEI_PATCHCODE' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Start validating the contents of TWEI_PATCHCODE, which is TW_INFO[0], ; we expect to find the correct id and either TWRC_SUCCESS or TWRC_DATANOTAVAILABLE... setlocal name 'TW_INFO[0].InfoID is TWEI_PATCHCODE' if '${getindex:patchcodedata:${get:TW_INFO.InfoID}}' != 'TWEI_PATCHCODE' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' ; setlocal name 'TW_INFO[0].ReturnCode is TWRC_SUCCESS or TWRC_DATANOTAVAILABLE' if '${getindex:patchcodedata:${get:TW_INFO.ReturnCode}}' == 'TWRC_SUCCESS' goto MAIN.TWINFO.SUCCESS if '${getindex:patchcodedata:${get:TW_INFO.ReturnCode}}' == 'TWRC_DATANOTAVAILABLE' goto MAIN.TWINFO.NODATAFOUND goto MAIN.ERROR.ECHOPASSFAIL ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Process TWRC_SUCCESS... ; :MAIN.TWINFO.SUCCESS setlocal name 'TW_INFO[0].ReturnCode is TWRC_SUCCESS' echo.passfail '${get:indent}${get:name}' 'pass' ; setlocal name 'TW_INFO[0].ItemType is TWTY_UINT16' if '${getindex:patchcodedata:${get:TW_INFO.ItemType}}' != 'TWTY_UINT16' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' ; setlocal name 'TW_INFO[0].NumItems is 1' if '${getindex:patchcodedata:${get:TW_INFO.NumItems}}' != '1' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' ; ; setlocal tweipatchcode '${gettwei:TWEI_PATCHCODE:${getindex:patchcodedata:${get:TW_INFO.Item}}}' setlocal name 'TW_INFO[0].Item is a TWPCH_PATCH1 value' if '${get:tweipatchcode}' == 'TWPCH_PATCH1' goto MAIN.TWINFO.SUCCESS.INCREMENT setlocal name 'TW_INFO[0].Item is a TWPCH_PATCH2 value' if '${get:tweipatchcode}' == 'TWPCH_PATCH2' goto MAIN.TWINFO.SUCCESS.INCREMENT setlocal name 'TW_INFO[0].Item is a TWPCH_PATCH3 value' if '${get:tweipatchcode}' == 'TWPCH_PATCH3' goto MAIN.TWINFO.SUCCESS.INCREMENT setlocal name 'TW_INFO[0].Item is a TWPCH_PATCH4 value' if '${get:tweipatchcode}' == 'TWPCH_PATCH4' goto MAIN.TWINFO.SUCCESS.INCREMENT setlocal name 'TW_INFO[0].Item is a TWPCH_PATCH6 value' if '${get:tweipatchcode}' == 'TWPCH_PATCH6' goto MAIN.TWINFO.SUCCESS.INCREMENT setlocal name 'TW_INFO[0].Item is a TWPCH_PATCHT value' if '${get:tweipatchcode}' == 'TWPCH_PATCHT' goto MAIN.TWINFO.SUCCESS.INCREMENT setlocal name 'TW_INFO[0].Item is an unrecognized ${getindex:patchcodedata:${get:TW_INFO.Item}} value' goto MAIN.ERROR.ECHOPASSFAIL ; :MAIN.TWINFO.SUCCESS.INCREMENT echo.passfail '${get:indent}${get:name}' 'pass' increment g_patchcodecount.one ${get:g_patchcodecount.one} 1 goto MAIN.PASS ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Process TWRC_DATANOTAVAILABLE... ; :MAIN.TWINFO.NODATAFOUND setlocal name 'TW_INFO[0].ReturnCode is TWRC_DATANOTAVAILABLE' echo.passfail '${get:indent}${get:name}' 'pass' ; increment g_patchcodecount.none ${get:g_patchcodecount.none} 1 goto MAIN.PASS ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Summary and cleanup... ; ; We passed... :MAIN.PASS return 'pass' ; ; Ruh-roh... :MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'fail - ${sts:} ${ret:}' return 'fail' ================================================ FILE: twaincs/source/twaincscert/source/data/certification/120 - Patch Code Badge/DAT_IMAGEFILEXFER.tc ================================================ ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; DAT_IMAGEFILEXFER ; This test scans two sheets of paper for the default pixeltype. An ADF ; is required to pass this test, but that was already been checked before ; we got to this function. The two sheets are as follows but don't have ; to be in any special order: ; ; - one without any patch codes, which must report TWRC_DATANOTAVAILABLE ; ; - one with a single patch code, which must report TWRC_SUCCESS for the ; TWEI_PATCHCODE ; ; Here's the basic flow: ; SetCapabilities ; start scanning ; while images ; transfer image ; DAT_EXTIMAGEINFO ; end image ; end ; end scanning ; verify the results ; ; The test passes if: ; - g_patchcodecount.none >= 1 ; and (g_patchcodecount.one >= 1) ; ; Arguments ; arg:1 - ignore ; arg:2 - test name for the image folder ; ; Globals ; g_patchcodecount.none - increment if no patch codes are found ; g_patchcodecount.one - increment if one patch code is found ; ; Locals ; name - current test being done ; indent - indent the passfail text ; twimageinfo.compression - compression for current image ; ; image.count - count of images from 1 ; image.folder - folder to put the images in ; ; Returns ; pass/fail ; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; If not supported, quietly leave... ; if '${get:g_xfermech}' ~contains 'TWSX_FILE' goto MAIN.CONTINUE return 'pass' :MAIN.CONTINUE ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Initialize... ; echo.titletest 'DAT_IMAGEFILEXFER' ; setlocal indent '' setlocal image.count '0' setlocal image.folder '${folder:certimages}/${arg:2}/DAT_IMAGEFILEXFER' setlocal image.showname '' ; setglobal g_patchcodecount.none '0' setglobal g_patchcodecount.one '0' ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Clean the image folder for this test... ; image cleanfolderandmeta '${get:image.folder}' ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; SetCapabilities ; This resets the driver and sets all the capabilities we need for the test. ; If its return code is not 'pass', end with an error ; run SetCapabilities 'TWSX_FILE' '${get:indent}' if '${ret:}' != 'pass' goto MAIN.ERROR.FAIL ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Prompt the user... ; echo.prompt echo.prompt "Scanning will take place during this test. There will be no" echo.prompt "need to press any button on the TWAIN user interface to start" echo.prompt "the scanner. A progress indicator may appear during scanning." echo.prompt echo.prompt "Place at least 2 sheets in the scanner's feeder in no particular echo.prompt "order: at least one sheet has no patch codes, and one has a" echo.prompt "single patch code that the scanner is known to recognize." echo.prompt pause '(press the ENTER key when ready to continue)' echo.prompt ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Start scanning... ; :MAIN.USERINTERFACE setlocal name 'dg_control/dat_userinterface/msg_enableds' wait reset dsmentry src null dg_control dat_userinterface msg_enableds '0,0' if '${sts:}' != 'SUCCESS' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Wait for MSG_XFERREADY, if we don't see it then scoot... ; setlocal name 'wait ${get:sys_waittimeout} seconds for MSG_XFERREADY' wait '${get:sys_waittimeout}000' if '${ret:}' !~contains 'msg_xferready' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Get information about the image... ; :MAIN.IMAGEINFO.NEXT setlocal name 'dg_image/dat_imageinfo/msg_get' dsmentry src ds dg_image dat_imageinfo msg_get '0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0' if '${sts:}' != 'SUCCESS' goto MAIN.ERROR.ECHOPASSFAIL setlocal twimageinfo.compression '${ret:${get:index.twimageinfo.compression}}' echo.passfail '${get:indent}${get:name}' 'pass' ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Set up the file transfer... ; increment image.count '${get:image.count}' 1 if '${get:twimageinfo.compression}' == 'JPEG' goto MAIN.SETUPFILEXFER.JPEG setlocal image.showname 'DAT_IMAGEFILEXFER/adf${format:D6|${get:image.count}}.tif' setlocal twsetupfilexfer.filename '${get:image.folder}/adf${format:D6|${get:image.count}}.tif' setlocal twsetupfilexfer.format 'TWFF_TIFF' goto MAIN.SETUPFILEXFER :MAIN.SETUPFILEXFER.JPEG setlocal image.showname 'DAT_IMAGEFILEXFER/adf${format:D6|${get:image.count}}.jpg' setlocal twsetupfilexfer.filename '${get:image.folder}/adf${format:D6|${get:image.count}}.jpg' setlocal twsetupfilexfer.format 'TWFF_JFIF' :MAIN.SETUPFILEXFER setlocal name 'dg_control/dat_setupfilexfer/msg_set' dsmentry src ds dg_control dat_setupfilexfer msg_set '"${get:twsetupfilexfer.filename}",${get:twsetupfilexfer.format},0' if '${sts:}' != 'SUCCESS' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Transfer the image... ; setlocal name 'dg_image/dat_imagefilexfer/msg_get' dsmentry src ds dg_image dat_imagefilexfer msg_get null if '${sts:}' != 'XFERDONE' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' echo.passfail '${get:indent}image <${get:image.showname}>' 'pass' ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; DAT_EXTIMAGEINFO ; Check the patch code metadata... ; run DAT_EXTIMAGEINFO '${get:indent}' '${get:image.folder}/adf${format:D6|${get:image.count}}' if '${ret:}' != 'pass' goto MAIN.ERROR.FAIL ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; End the transfer, see if we're done... ; setlocal name 'dg_control/dat_pendingxfers/msg_endxfer' dsmentry src ds dg_control dat_pendingxfers msg_endxfer '0,0' if '${sts:}' != 'SUCCESS' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' if '${ret:${get:TW_PENDINGXFERS.Count}}' != '0' goto MAIN.IMAGEINFO.NEXT ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; We're out of images, so disable... ; setlocal name 'dg_control/dat_userinterface/msg_disableds' dsmentry src ds dg_control dat_userinterface msg_disableds '0,0' if '${sts:}' != 'SUCCESS' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Check to see if we passed. We need one or more sheets of paper with no patch codes, ; and one or more sheets with one patch code. ; setlocal name 'Final Check: detected sheets with 0 patch codes if '${get:g_patchcodecount.none}' < '1' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' ; setlocal name 'Final Check: detected sheets with 1 patch code' if '${get:g_patchcodecount.one}' < '1' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Summary and cleanup... ; ; We passed... :MAIN.PASS echo.passfail 'SUMMARY' 'pass' return 'pass' ; ; Ruh-roh... :MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'fail - ${sts:} ${ret:}' echo.passfail 'SUMMARY' 'fail' rollback state4 return 'fail' ; ; Ruh-roh... :MAIN.ERROR.FAIL echo.passfail 'SUMMARY' 'fail' rollback state4 return 'fail' ================================================ FILE: twaincs/source/twaincscert/source/data/certification/120 - Patch Code Badge/DAT_IMAGEMEMFILEXFER.tc ================================================ ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; DAT_IMAGEMEMFILEXFER ; This test scans two sheets of paper for the default pixeltype. An ADF ; is required to pass this test, but that was already been checked before ; we got to this function. The two sheets are as follows but don't have ; to be in any special order: ; ; - one without any patch codes, which must report TWRC_DATANOTAVAILABLE ; ; - one with a single patch code, which must report TWRC_SUCCESS for ; TWEI_PATCHCODE ; ; Here's the basic flow: ; SetCapabilities ; start scanning ; while images ; transfer image ; DAT_EXTIMAGEINFO ; end image ; end ; end scanning ; verify the results ; ; The test passes if: ; - g_patchcodecount.none >= 1 ; and (g_patchcodecount.one >= 1) ; ; Arguments ; arg:1 - ignore ; arg:2 - test name for the image folder ; ; Globals ; g_patchcodecount.none - increment if nopatchcodes are found ; g_patchcodecount.one - increment if one patchcode is found ; ; Locals ; name - current test being done ; indent - indent the passfail text ; imagememxfer - result of DAT_IMAGEMEMXFER call ; setupmemxfer.preferred - preferred field from DAT_SETUPMEMXFER call ; ; image.count - count of images from 1 ; image.folder - folder to put the images in ; ; Returns ; pass or fail ; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; If not supported, quietly leave... ; if '${get:g_xfermech}' ~contains 'TWSX_MEMFILE' goto MAIN.CONTINUE return 'pass' :MAIN.CONTINUE ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Initialize... ; echo.titletest 'DAT_IMAGEMEMFILEXFER' ; setlocal indent '' setlocal image.pointer '0' setlocal image.count '0' setlocal image.folder '${folder:certimages}/${arg:2}/DAT_IMAGEMEMFILEXFER' ; setglobal g_patchcodecount.none '0' setglobal g_patchcodecount.one '0' ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Clean the image folder for this test... ; image cleanfolderandmeta '${get:image.folder}' ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; SetCapabilities ; This resets the driver and sets all the capabilities we need for the test. ; If its return code is not 'pass', end with an error ; run SetCapabilities 'TWSX_MEMFILE' '${get:indent}' if '${ret:}' != 'pass' goto MAIN.ERROR.FAIL ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Get the preferred size for memory transfers, and allocate ; a pointer for the memory transfers... ; setlocal indent ' ' setlocal name 'dg_control/dat_setupmemxfer/msg_get' dsmentry src ds dg_control dat_setupmemxfer msg_get '0,0,0' if '${sts:}' != 'SUCCESS' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' ; setlocal name 'TW_SETUPMEMXFER.Preferred > 0' setlocal setupmemxfer.preferred '${ret:${get:TW_SETUPMEMXFER.Preferred}}' if '${get:setupmemxfer.preferred}' <= '0' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' ; setlocal name 'allocate pointer for ${get:setupmemxfer.preferred} bytes' free pointer image.pointer ; for the last loop allocate pointer image.pointer '${get:setupmemxfer.preferred}' if '${get:image.pointer}' == '0' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Set DAT_SETUPFILEXFER to TWFF_TIFF ; setlocal name 'dg_control/dat_setupfilexfer/msg_set TWFF_TIFF' dsmentry src null dg_control dat_setupfilexfer msg_set 'file,TWFF_TIFF,0' if '${sts:}' != 'SUCCESS' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Prompt the user... ; echo.prompt echo.prompt "Scanning will take place during this test. There will be no" echo.prompt "need to press any button on the TWAIN user interface to start" echo.prompt "the scanner. A progress indicator may appear during scanning." echo.prompt echo.prompt "Place at least 2 sheets in the scanner's feeder in no particular echo.prompt "order: at least one sheet has no patch codes, and one has a" echo.prompt "single patch code that the scanner is known to recognize." echo.prompt pause '(press the ENTER key when ready to continue)' echo.prompt ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Start scanning... ; :MAIN.USERINTERFACE setlocal name 'dg_control/dat_userinterface/msg_enableds' wait reset dsmentry src null dg_control dat_userinterface msg_enableds '0,0' if '${sts:}' != 'SUCCESS' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Wait for MSG_XFERREADY, if we don't see it then scoot... ; setlocal name 'wait ${get:sys_waittimeout} seconds for MSG_XFERREADY' wait '${get:sys_waittimeout}000' if '${ret:}' !~contains 'msg_xferready' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Do a memory file transfer... ; This little song and dance with the states is so that we can ; start the transfer in state 6 with each new image, but switch ; to state 7 if we need multiple calls to capture the current ; image... ; ; The saved images will be in TIFF format, which includes TIFF ; JPEG (the better form, where a simple TIFF header is added). ; increment image.count '${get:image.count}' 1 image free memfileimage ; :MAIN.IMAGEMEMFILEXFER.NEXT setlocal name 'dg_image/dat_imagememxfer/msg_get' dsmentry src ds dg_image dat_imagememfilexfer msg_get '0,0,0,0,0,0,0,9,${get:setupmemxfer.preferred},${get:image.pointer}' setlocal imagememxfer '${ret:}' if '${sts:}' == 'XFERDONE' goto MAIN.IMAGEMEMFILEXFER.XFERDONE if '${sts:}' != 'SUCCESS' goto MAIN.ERROR.ECHOPASSFAIL ; echo.passfail '${get:indent}${get:name} SUCCESS' 'pass' image append memfileimage '${get:imagememxfer}' goto MAIN.IMAGEMEMFILEXFER.NEXT ; :MAIN.IMAGEMEMFILEXFER.XFERDONE echo.passfail '${get:indent}${get:name} XFERDONE' 'pass' image append memfileimage '${get:imagememxfer}' image save memfileimage memfile '${get:image.folder}/adf${format:D6|${get:image.count}}' echo.passfail '${get:indent}image <${ret:}>' 'pass' image free memfileimage ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; DAT_EXTIMAGEINFO ; Check the patch code metadata... ; run DAT_EXTIMAGEINFO '${get:indent}' '${get:image.folder}/adf${format:D6|${get:image.count}}' if '${ret:}' != 'pass' goto MAIN.ERROR.FAIL ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; End the transfer, see if we're done... ; setlocal name 'dg_control/dat_pendingxfers/msg_endxfer' dsmentry src ds dg_control dat_pendingxfers msg_endxfer '0,0' if '${sts:}' != 'SUCCESS' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' increment image.count '${get:image.count}' 1 if '${ret:${get:TW_PENDINGXFERS.Count}}' != '0' goto MAIN.IMAGEMEMFILEXFER.NEXT ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; We're out of images, so disable... ; setlocal name 'dg_control/dat_userinterface/msg_disableds' dsmentry src ds dg_control dat_userinterface msg_disableds '0,0' if '${sts:}' != 'SUCCESS' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Check to see if we passed. We need one or more sheets of paper with no patch codes, ; and one or more sheets with one patch code. ; setlocal name 'Final Check: detected sheets with 0 patch codes if '${get:g_patchcodecount.none}' < '1' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' ; setlocal name 'Final Check: detected sheets with 1 patch code' if '${get:g_patchcodecount.one}' < '1' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Summary and cleanup... ; ; We passed... :MAIN.PASS image free memfileimage free pointer image.pointer echo.passfail 'SUMMARY' 'pass' return 'pass' ; ; Ruh-roh... :MAIN.ERROR.ECHOPASSFAIL image free memfileimage free pointer image.pointer echo.passfail '${get:indent}${get:name}' 'fail - ${sts:} ${ret:}' echo.passfail 'SUMMARY' 'fail' rollback state4 return 'fail' ; ; Ruh-roh... :MAIN.ERROR.FAIL image free memfileimage free pointer image.pointer echo.passfail 'SUMMARY' 'fail' rollback state4 return 'fail' ================================================ FILE: twaincs/source/twaincscert/source/data/certification/120 - Patch Code Badge/DAT_IMAGEMEMXFER.tc ================================================ ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; DAT_IMAGEMEMXFER ; This test scans two sheets of paper for the default pixeltype. An ADF ; is required to pass this test, but that was already been checked before ; we got to this function. The two sheets are as follows but don't have ; to be in any special order: ; ; - one without any patch codes, which must report TWRC_DATANOTAVAILABLE ; ; - one with a single patch code, which must report TWRC_SUCCESS for ; TWEI_PATCHCODE ; ; Here's the basic flow: ; SetCapabilities ; start scanning ; while images ; transfer image ; DAT_EXTIMAGEINFO ; end image ; end ; end scanning ; verify the results ; ; The test passes if: ; - g_patchcodecount.none >= 1 ; and (g_patchcodecount.one >= 1) ; ; Arguments ; arg:1 - ignore ; arg:2 - test name for the image folder ; ; Globals ; g_patchcodecount.none - increment if no patchcodes are found ; g_patchcodecount.one - increment if one patchcode is found ; ; Locals ; name - current test being done ; indent - indent the passfail text ; imageinfo - metadata for the current image ; imagememxfer - result of DAT_IMAGEMEMXFER call ; setupmemxfer.preferred - preferred field from DAT_SETUPMEMXFER call ; ; image.count - count of images from 1 ; image.folder - folder to put the images in ; ; Returns ; pass/fail ; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Initialize... ; echo.titletest 'DAT_IMAGEMEMXFER' ; setlocal indent '' setlocal image.pointer '0' setlocal image.count '0' setlocal image.folder '${folder:certimages}/${arg:2}/DAT_IMAGEMEMXFER' ; setglobal g_patchcodecount.none '0' setglobal g_patchcodecount.one '0' ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Clean the image folder for this test... ; image cleanfolderandmeta '${get:image.folder}' ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; SetCapabilities ; This resets the driver and sets all the capabilities we need for the test. ; If its return code is not 'pass', end with an error ; run SetCapabilities 'TWSX_MEMORY' '${get:indent}' if '${ret:}' != 'pass' goto MAIN.ERROR.FAIL ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Get the preferred size for memory transfers, and allocate ; a pointer for the memory transfers... ; setlocal indent ' ' setlocal name 'dg_control/dat_setupmemxfer/msg_get' dsmentry src ds dg_control dat_setupmemxfer msg_get '0,0,0' if '${sts:}' != 'SUCCESS' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' ; setlocal name 'TW_SETUPMEMXFER.Preferred > 0' setlocal setupmemxfer.preferred '${ret:${get:TW_SETUPMEMXFER.Preferred}}' if '${get:setupmemxfer.preferred}' <= '0' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' ; setlocal name 'allocate pointer for ${get:setupmemxfer.preferred} bytes' free pointer image.pointer ; for the last loop allocate pointer image.pointer '${get:setupmemxfer.preferred}' if '${get:image.pointer}' == '0' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Prompt the user... ; echo.prompt echo.prompt "Scanning will take place during this test. There will be no" echo.prompt "need to press any button on the TWAIN user interface to start" echo.prompt "the scanner. A progress indicator may appear during scanning." echo.prompt echo.prompt "Place at least 2 sheets in the scanner's feeder in no particular echo.prompt "order: at least one sheet has no patch codes, and one has a" echo.prompt "single patch code that the scanner is known to recognize." echo.prompt pause '(press the ENTER key when ready to continue)' echo.prompt ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Start scanning... ; :MAIN.USERINTERFACE setlocal name 'dg_control/dat_userinterface/msg_enableds' wait reset dsmentry src null dg_control dat_userinterface msg_enableds '0,0' if '${sts:}' != 'SUCCESS' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Wait for MSG_XFERREADY, if we don't see it then scoot... ; setlocal name 'wait ${get:sys_waittimeout} seconds for MSG_XFERREADY' wait '${get:sys_waittimeout}000' if '${ret:}' !~contains 'msg_xferready' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Do a memory transfer... ; This little song and dance with the states is so that we can ; start the transfer in state 6 with each new image, but switch ; to state 7 if we need multiple calls to capture the current ; image... ; ; The saved images will be in TIFF format, which includes TIFF ; JPEG (the better form, where a simple TIFF header is added). ; increment image.count '${get:image.count}' 1 image free memimage ; :MAIN.IMAGEMEMXFER.NEXT setlocal name 'dg_image/dat_imagememxfer/msg_get' dsmentry src ds dg_image dat_imagememxfer msg_get '0,0,0,0,0,0,0,9,${get:setupmemxfer.preferred},${get:image.pointer}' setlocal imagememxfer '${ret:}' if '${sts:}' == 'XFERDONE' goto MAIN.IMAGEMEMXFER.XFERDONE if '${sts:}' != 'SUCCESS' goto MAIN.ERROR.ECHOPASSFAIL ; echo.passfail '${get:indent}${get:name} SUCCESS' 'pass' image append memimage '${get:imagememxfer}' goto MAIN.IMAGEMEMXFER.NEXT ; :MAIN.IMAGEMEMXFER.XFERDONE echo.passfail '${get:indent}${get:name} XFERDONE' 'pass' ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; We need image info to make sense of this data... ; setlocal name 'dg_image/dat_imageinfo/msg_get' dsmentry src ds dg_image dat_imageinfo msg_get '0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0' setlocal imageinfo '${ret:}' if '${sts:}' != 'SUCCESS' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Save the image... ; image append memimage '${get:imagememxfer}' image addheader memimage '${get:imageinfo}' image save memimage memory '${get:image.folder}/adf${format:D6|${get:image.count}}' echo.passfail '${get:indent}image <${ret:}>' 'pass' image free memimage ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; DAT_EXTIMAGEINFO ; Check the patch code metadata... ; run DAT_EXTIMAGEINFO '${get:indent}' '${get:image.folder}/adf${format:D6|${get:image.count}}' if '${ret:}' != 'pass' goto MAIN.ERROR.FAIL ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; End the transfer, see if we're done... ; setlocal name 'dg_control/dat_pendingxfers/msg_endxfer' dsmentry src ds dg_control dat_pendingxfers msg_endxfer '0,0' if '${sts:}' != 'SUCCESS' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' increment image.count '${get:image.count}' 1 if '${ret:${get:TW_PENDINGXFERS.Count}}' != '0' goto MAIN.IMAGEMEMXFER.NEXT ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; We're out of images, so disable... ; setlocal name 'dg_control/dat_userinterface/msg_disableds' dsmentry src ds dg_control dat_userinterface msg_disableds '0,0' if '${sts:}' != 'SUCCESS' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Check to see if we passed. We need one or more sheets of paper with no patch codes, ; and one or more sheets with one patch code. ; setlocal name 'Final Check: detected sheets with 0 patch codes if '${get:g_patchcodecount.none}' < '1' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' ; setlocal name 'Final Check: detected sheets with 1 patch code' if '${get:g_patchcodecount.one}' < '1' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Summary and cleanup... ; ; We passed... :MAIN.PASS image free memimage free pointer image.pointer echo.passfail 'SUMMARY' 'pass' return 'pass' ; ; Ruh-roh... :MAIN.ERROR.ECHOPASSFAIL image free memimage free pointer image.pointer echo.passfail '${get:indent}${get:name}' 'fail - ${sts:} ${ret:}' echo.passfail 'SUMMARY' 'fail' rollback state4 return 'fail' ; ; Ruh-roh... :MAIN.ERROR.FAIL image free memimage free pointer image.pointer echo.passfail 'SUMMARY' 'fail' rollback state4 return 'fail' ================================================ FILE: twaincs/source/twaincscert/source/data/certification/120 - Patch Code Badge/DAT_IMAGENATIVEXFER.tc ================================================ ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; DAT_IMAGENATIVEXFER ; This test scans two sheets of paper for the default pixeltype. An ADF ; is required to pass this test, but that was already been checked before ; we got to this function. The two sheets are as follows but don't have ; to be in any special order: ; ; - one without any patch codes, which must report TWRC_DATANOTAVAILABLE ; ; - one with a single patch code, which must report TWRC_SUCCESS for ; TWEI_PATCHCODE ; ; Here's the basic flow: ; SetCapabilities ; start scanning ; while images ; transfer image ; DAT_EXTIMAGEINFO ; end image ; end ; end scanning ; verify the results ; ; The test passes if: ; - g_patchcodecount.none >= 1 ; and (g_patchcodecount.one >= 1) ; ; Arguments ; arg:1 - ignore ; arg:2 - test name for the image folder ; ; Globals ; g_patchcodecount.none - increment if no patchcodes are found ; g_patchcodecount.one - increment if one patchcode is found ; ; Locals ; name - current test being done ; indent - indent the passfail text ; image.handle - native handle ; image.count - count of images from 1 ; image.folder - folder to put the images in ; ; Returns ; pass/fail ; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Initialize... ; echo.titletest 'DAT_IMAGENATIVEXFER' ; setlocal indent '' setlocal image.handle '0' setlocal image.count '1' setlocal image.folder '${folder:certimages}/${arg:2}/DAT_IMAGENATIVEXFER' ; setglobal g_patchcodecount.none '0' setglobal g_patchcodecount.one '0' ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Prompt the user... ; echo.prompt echo.prompt "Scanning will take place during this test. There will be no" echo.prompt "need to press any button on the TWAIN user interface to start" echo.prompt "the scanner. A progress indicator may appear during scanning." echo.prompt echo.prompt "Place at least 2 sheets in the scanner's feeder in no particular echo.prompt "order: at least one sheet has no patch codes, and one has a" echo.prompt "single patch code that the scanner is known to recognize." echo.prompt pause '(press the ENTER key when ready to continue)' echo.prompt ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Clean the image folder for this test... ; image cleanfolderandmeta '${get:image.folder}' ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; SetCapabilities ; This resets the driver and sets all the capabilities we need for the test. ; If its return code is not 'pass', end with an error ; run SetCapabilities 'TWSX_NATIVE' '${get:indent}' if '${ret:}' != 'pass' goto MAIN.ERROR.FAIL ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Check for paper in the feeder, prompt the user if we don't find any... ; :MAIN.FEEDERLOADED dsmentry src ds dg_control dat_capability msg_getcurrent 'CAP_FEEDERLOADED,0,0,0' if '${sts:}' != 'SUCCESS' goto MAIN.FEEDERLOADED.DONE if '${ret:${get:TW_ONEVALUE.Item}}' ~~ 'TRUE' goto MAIN.FEEDERLOADED.DONE echo.prompt echo.prompt "Place paper in the scanner's feeder." pause '(press the ENTER key when ready to continue)' :MAIN.FEEDERLOADED.DONE ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Start scanning... ; setlocal indent ' ' setlocal name 'dg_control/dat_userinterface/msg_enableds' wait reset dsmentry src null dg_control dat_userinterface msg_enableds '0,0' if '${sts:}' != 'SUCCESS' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Wait for MSG_XFERREADY, if we don't see it then scoot... ; setlocal name 'wait ${get:sys_waittimeout} seconds for MSG_XFERREADY' wait '${get:sys_waittimeout}000' if '${ret:}' !~contains 'msg_xferready' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Do a native transfer... ; :MAIN.IMAGENATIVEXFER.NEXT setlocal indent ' ' setlocal name 'dg_control/dat_imagenativexfer/msg_get' dsmentry src ds dg_image dat_imagenativexfer msg_get '0' setlocal image.handle '${ret:}' if '${sts:}' != 'XFERDONE' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' image save image.handle native '${get:image.folder}/adf${format:D6|${get:image.count}}' echo.passfail '${get:indent}image <${ret:}>' 'pass' free handle image.handle ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; DAT_EXTIMAGEINFO ; Check the patch code metadata... ; run DAT_EXTIMAGEINFO '${get:indent}' '${get:image.folder}/adf${format:D6|${get:image.count}}' if '${ret:}' != 'pass' goto MAIN.ERROR.FAIL ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; End the transfer, see if we're done. If not, go back ; to MAIN.IMAGENATIVEXFER.NEXT for another image... ; :MAIN.PENDINGXFERS setlocal name 'dg_control/dat_pendingxfers/msg_endxfer' dsmentry src ds dg_control dat_pendingxfers msg_endxfer '0,0' if '${sts:}' != 'SUCCESS' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' increment image.count '${get:image.count}' 1 ; count the image if '${ret:${get:TW_PENDINGXFERS.Count}}' != '0' goto MAIN.IMAGENATIVEXFER.NEXT ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; We're out of images, so disable... ; setlocal name 'dg_control/dat_userinterface/msg_disableds' dsmentry src ds dg_control dat_userinterface msg_disableds '0,0' if '${sts:}' != 'SUCCESS' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Check to see if we passed. We need one or more sheets of paper with no patch codes, ; and one or more sheets with one patch code. ; setlocal name 'Final Check: detected ${get:g_patchcodecount.none} image(s) with no patch codes if '${get:g_patchcodecount.none}' < '1' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' ; setlocal name 'Final Check: detected ${get:g_patchcodecount.one} image(s) with a patch code' if '${get:g_patchcodecount.one}' < '1' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Summary and cleanup... ; ; We passed... :MAIN.PASS free handle image.handle echo.passfail 'SUMMARY' 'pass' return 'pass' ; ; Ruh-roh... :MAIN.ERROR.ECHOPASSFAIL free handle image.handle echo.passfail '${get:indent}${get:name}' 'fail - ${sts:} ${ret:}' echo.passfail 'SUMMARY' 'fail' rollback state4 return 'fail' ; ; Ruh-roh... :MAIN.ERROR.FAIL free handle image.handle echo.passfail 'SUMMARY' 'fail' rollback state4 return 'fail' ================================================ FILE: twaincs/source/twaincscert/source/data/certification/120 - Patch Code Badge/Patch Code Badge.tc ================================================ ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Barcode Badge ; These tests establish the minimum requirements for a TWAIN driver to claim it supports patch ; codes. It focuses on the ability to turn patch code detection on and off, identifying which ; patch codes are supported, and making sure patch code metadata is reported. ; ; Arguments ; (none) ; ; Globals ; g_xfermech - transfer mechanism currently in use ; g_capsupportedcaps - list of supported capabilities ; ; Locals ; name - name of a test ; certifyresult - status we're going to return ; ; Returns ; pass/fail ; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Initialize... ; setlocal certifyresult 'pass' ; assume we'll pass, this is our return value ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Reset the driver's capabilities, this is mandatory... ; setlocal name 'MSG_RESETALL' dsmentry src ds dg_control dat_capability msg_resetall '0,0,0,0' if '${sts:}' != 'SUCCESS' goto MAIN.MSG_RESETALL.FAIL echo.passfail '${get:name}' 'pass' goto MAIN.MSG_RESETALL.DONE ; :MAIN.MSG_RESETALL.FAIL echo.passfail '${get:name}' 'skip - ${sts:} ${ret:}' setlocal certifyresult 'fail' goto MAIN.DONE :MAIN.MSG_RESETALL.DONE ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; ICAP_PATCHCODEDETECTIONENABLED must be supported, and must offer both TRUE ; and FALSE, and must currently be FALSE (as a result of MSG_RESETALL, otherwise ; skip it all... ; setlocal name 'ICAP_PATCHCODEDETECTIONENABLED is supported' dsmentry src ds dg_control dat_capability msg_get 'ICAP_PATCHCODEDETECTIONENABLED,0,0,0' if '${sts:}' != 'SUCCESS' goto MAIN.ICAP_PATCHCODEDETECTIONENABLEDSUPPORTED.SKIP if ',${ret:},' !~contains ',TRUE,' goto MAIN.ICAP_PATCHCODEDETECTIONENABLEDSUPPORTED.SKIP if ',${ret:},' !~contains ',FALSE,' goto MAIN.ICAP_PATCHCODEDETECTIONENABLEDSUPPORTED.SKIP echo.passfail '${get:name}' 'pass' goto MAIN.ICAP_PATCHCODEDETECTIONENABLEDSUPPORTED.DONE ; :MAIN.ICAP_PATCHCODEDETECTIONENABLEDSUPPORTED.SKIP echo.passfail '${get:name}' 'skip - ${sts:} ${ret:}' setlocal certifyresult 'skip' goto MAIN.DONE :MAIN.ICAP_PATCHCODEDETECTIONENABLEDSUPPORTED.DONE ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; CAP_SUPPORTEDCAPS: check that all required capabilities are reported ; We're not requiring the presence of ICAP_PATCHCODEMAXRETRIES or ; ICAP_PATCHCODETIMEOUT. If present it's assumed the driver will default ; these to meaningful values that support the best chance of detecting ; a patch code. ; setlocal name 'CAP_SUPPORTEDCAPS MSG_GET' dsmentry src ds dg_control dat_capability msg_get 'CAP_SUPPORTEDCAPS,0,0,0' if '${sts:}' != 'SUCCESS' goto MAIN.CAP_SUPPORTEDCAPS.FAIL setglobal g_capsupportedcaps '${ret:}' echo.passfail '${get:name}' 'pass' ; setlocal name 'CAP_SUPPORTEDCAPS ICAP_PATCHCODEDETECTIONENABLED found' if ',${get:g_capsupportedcaps},' !~contains ',ICAP_PATCHCODEDETECTIONENABLED,' goto MAIN.CAP_SUPPORTEDCAPS.FAIL echo.passfail '${get:name}' 'pass' ; setlocal name 'CAP_SUPPORTEDCAPS ICAP_PATCHCODEMAXSEARCHPRIORITIES found' if ',${get:g_capsupportedcaps},' !~contains ',ICAP_PATCHCODEMAXSEARCHPRIORITIES,' goto MAIN.CAP_SUPPORTEDCAPS.FAIL echo.passfail '${get:name}' 'pass' ; setlocal name 'CAP_SUPPORTEDCAPS ICAP_PATCHCODESEARCHMODE found' if ',${get:g_capsupportedcaps},' !~contains ',ICAP_PATCHCODESEARCHMODE,' goto MAIN.CAP_SUPPORTEDCAPS.FAIL echo.passfail '${get:name}' 'pass' ; setlocal name 'CAP_SUPPORTEDCAPS ICAP_PATCHCODESEARCHPRIORITIES found' if ',${get:g_capsupportedcaps},' !~contains ',ICAP_PATCHCODESEARCHPRIORITIES,' goto MAIN.CAP_SUPPORTEDCAPS.FAIL echo.passfail '${get:name}' 'pass' ; setlocal name 'CAP_SUPPORTEDCAPS ICAP_SUPPORTEDPATCHCODETYPES found' if ',${get:g_capsupportedcaps},' !~contains ',ICAP_SUPPORTEDPATCHCODETYPES,' goto MAIN.CAP_SUPPORTEDCAPS.FAIL echo.passfail '${get:name}' 'pass' ; goto MAIN.CAP_SUPPORTEDCAPS.DONE :MAIN.CAP_SUPPORTEDCAPS.FAIL echo.passfail '${get:name}' 'fail - ${sts:} ${get:g_capsupportedcaps}' setlocal certifyresult 'fail' goto MAIN.DONE :MAIN.CAP_SUPPORTEDCAPS.DONE ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; ICAP_SUPPORTEDEXTIMAGEINFO: check that all metadata is reported ; setlocal name 'ICAP_SUPPORTEDEXTIMAGEINFO MSG_GET' dsmentry src ds dg_control dat_capability msg_get 'ICAP_SUPPORTEDEXTIMAGEINFO,0,0,0' if '${sts:}' != 'SUCCESS' goto MAIN.ICAP_SUPPORTEDEXTIMAGEINFO.FAIL echo.passfail '${get:name}' 'pass' ; setlocal name 'ICAP_SUPPORTEDEXTIMAGEINFO TWEI_PATCHCODE found' if ',${ret:},' !~contains ',TWEI_PATCHCODE,' goto MAIN.ICAP_SUPPORTEDEXTIMAGEINFO.FAIL echo.passfail '${get:name}' 'pass' ; goto MAIN.ICAP_SUPPORTEDEXTIMAGEINFO.DONE :MAIN.ICAP_SUPPORTEDEXTIMAGEINFO.FAIL echo.passfail '${get:name}' 'fail - ${sts:} ${ret:}' setlocal certifyresult 'fail' :MAIN.ICAP_SUPPORTEDEXTIMAGEINFO.DONE ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; ICAP_PATCHCODEDETECTIONENABLED must currently be FALSE ; setlocal name 'ICAP_PATCHCODEDETECTIONENABLED resets to FALSE' dsmentry src ds dg_control dat_capability msg_getcurrent 'ICAP_PATCHCODEDETECTIONENABLED,0,0,0' if '${sts:}' != 'SUCCESS' goto MAIN.ICAP_PATCHCODEDETECTIONENABLEDFALSE.FAIL if ',${ret:},' !~contains ',FALSE,' goto MAIN.ICAP_PATCHCODEDETECTIONENABLEDFALSE.FAIL echo.passfail '${get:name}' 'pass' goto MAIN.ICAP_PATCHCODEDETECTIONENABLEDFALSE.DONE ; :MAIN.ICAP_PATCHCODEDETECTIONENABLEDFALSE.FAIL echo.passfail '${get:name}' 'skip - ${sts:} ${ret:}' setlocal certifyresult 'fail' goto MAIN.DONE :MAIN.ICAP_PATCHCODEDETECTIONENABLEDFALSE.DONE ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; ICAP_PATCHCODEDETECTIONENABLED set to TRUE ; setlocal name 'ICAP_PATCHCODEDETECTIONENABLED set to TRUE' dsmentry src ds dg_control dat_capability msg_set 'ICAP_PATCHCODEDETECTIONENABLED,TWON_ONEVALUE,TWTY_BOOL,TRUE' if '${sts:}' != 'SUCCESS' goto MAIN.ICAP_PATCHCODEDETECTIONENABLEDTRUE.FAIL dsmentry src ds dg_control dat_capability msg_getcurrent 'ICAP_PATCHCODEDETECTIONENABLED,0,0,0' if '${sts:}' != 'SUCCESS' goto MAIN.ICAP_PATCHCODEDETECTIONENABLEDTRUE.FAIL if ',${ret:},' !~contains ',TRUE,' goto MAIN.ICAP_PATCHCODEDETECTIONENABLEDTRUE.FAIL echo.passfail '${get:name}' 'pass' goto MAIN.ICAP_PATCHCODEDETECTIONENABLEDTRUE.DONE ; :MAIN.ICAP_PATCHCODEDETECTIONENABLEDTRUE.FAIL echo.passfail '${get:name}' 'skip - ${sts:} ${ret:}' setlocal certifyresult 'fail' goto MAIN.DONE :MAIN.ICAP_PATCHCODEDETECTIONENABLEDTRUE.DONE ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Get ICAP_XFERMECH... ; setlocal name 'ICAP_XFERMECH MSG_GET' dsmentry src ds dg_control dat_capability msg_get 'ICAP_XFERMECH,0,0,0' if '${sts:}' == 'SUCCESS' goto MAIN.ICAP_XFERMECH.DONE echo.passfail '${get:name}' 'fail - ${sts:} ${ret:}' setlocal certifyresult 'fail' goto MAIN.DONE ; :MAIN.ICAP_XFERMECH.DONE setglobal g_xfermech '${ret:}' ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; All done... ; :MAIN.DONE return '${get:certifyresult}' ================================================ FILE: twaincs/source/twaincscert/source/data/certification/120 - Patch Code Badge/SetCapabilities.tc ================================================ ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; SetCapabilities ; Reset the driver's capabilites, and then set capabilities for this test. Note that one can only ; get this badge for the ADF. This is a production mode feature, so we're not testing the flatbed. ; ; We follow the capability ordering: ; MSG_RESETALL ; set ICAP_XFERMECH.......................${arg:1} ; set CAP_FEEDERENABLED...................TRUE ; set CAP_XFERCOUNT.......................-1 ; set ICAP_EXTIMAGEINFO...................TRUE ; set ICAP_PATCHCODETECTIONENABLED........TRUE ; set ICAP_PATCHCODESEARCHMODE............TWBD_HORZVERT, TWBD_VERTHORZ, TWBD_HORZ, or TWBD_VERT ; set ICAP_PATCHCODEMAXSEARCHPRIORITIES...set to its max value ; get ICAP_SUPPORTEDPATCHCODETYPES ; set ICAP_PATCHCODESEARCHPRIORITIES......set to first ICAP_PATCHCODEMAXSEARCHPRIORITIES of ICAP_SUPPORTEDPATCHCODETYPES ; ; The test passes if all operations return TWRC_SUCCESS. ; ; We are not testing ICAP_PATCHCODEMAXRETRIES or ICAP_PATCHCODETIMEOUT. We're going to assume that the driver's ; default values offer the best user experience. ICAP_PATCHCODETIMEOUT is especially problematic, since the ; spec doesn't tell us the units. ; ; Arguments ; arg:1 - TWSX_* value for ICAP_XFERMECH ; arg:2 - value of caller's indent ; ; Globals ; g_patchcodemaxsearchpriorities.max - maximum patchcodes we can get (max of ICAP_PATCHCODEMAXSEARCHPRIORITIES) ; g_capsupportedcaps - list of supported capabilities ; ; Locals ; patchcodesearchpriorities.itemlist - first ICAP_PATCHCODEMAXSEARCHPRIORITIES of ICAP_SUPPORTEDPATCHCODETYPES ; comma - used to construct the value for ICAP_PATCHCODESEARCHPRIORITIES ; indent - indent the passfail text ; name - name of the current test ; supportedpatchcodetypes.itemlist - return value from MSG_GET of ICAP_SUPPORTEDPATCHCODETYPES ; supportedpatchcodetypes.index - index counter for ICAP_SUPPORTEDPATCHCODETYPES ; supportedpatchcodetypes.lastindex - index of ICAP_PATCHCODEMAXSEARCHPRIORITIES item in ICAP_SUPPORTEDPATCHCODETYPES ; twsx - TWSX_* value for ICAP_XFERMECH ; ; Returns ; pass/fail ; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Initialize... ; setlocal twsx '${arg:1}' setlocal indent '${arg:2}' ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; MSG_RESETALL ; If return code is not TWRC_SUCCESS, end with an error ; setlocal name 'MSG_RESETALL' dsmentry src ds dg_control dat_capability msg_resetall '0,0,0,0' if '${sts:}' != 'SUCCESS' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Set ICAP_XFERMECH... ; setlocal name 'ICAP_XFERMECH MSG_SET ${get:twsx}' dsmentry src ds dg_control dat_capability msg_set 'ICAP_XFERMECH,TWON_ONEVALUE,TWTY_UINT16,${get:twsx}' if '${sts:}' != 'SUCCESS' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Set CAP_FEEDERENABLED to TRUE ; setlocal name 'CAP_FEEDERENABLED MSG_SET TRUE' dsmentry src ds dg_control dat_capability msg_set 'CAP_FEEDERENABLED,TWON_ONEVALUE,TWTY_BOOL,TRUE' if '${sts:}' != 'SUCCESS' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Set CAP_SHEETCOUNT to 7, this is enough to test all standard patch codes and ; one sheet with no patch code. The user can feed fewer sheets, as one as there ; is one with a patch code and one without a patch code... ; setlocal name 'CAP_SHEETCOUNT MSG_SET 7' dsmentry src ds dg_control dat_capability msg_set 'CAP_SHEETCOUNT,TWON_ONEVALUE,TWTY_INT16,7' if '${sts:}' != 'SUCCESS' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Set ICAP_EXTIMAGEINFO to TRUE ; setlocal name 'ICAP_EXTIMAGEINFO MSG_SET TRUE' dsmentry src ds dg_control dat_capability msg_set 'ICAP_EXTIMAGEINFO,TWON_ONEVALUE,TWTY_BOOL,TRUE' if '${sts:}' != 'SUCCESS' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Some scanners need image addressing on to detect patches, ; so if we detect that, enable it and set values for all ; of the fields... ; setlocal name 'Image Address skipped' if ',${get:g_capsupportedcaps},' !~contains 'CAP_IMAGEADDRESSENABLED' goto MAIN.IMAGEADDRESSENABLED.SKIP ; dsmentry src ds dg_control dat_capability msg_set 'CAP_IMAGEADDRESSENABLED,TWON_ONEVALUE,TWTY_BOOL,TRUE' if '${sts:}' != 'SUCCESS' goto MAIN.IMAGEADDRESSENABLED.SKIP ; dsmentry src ds dg_control dat_capability msg_set 'CAP_IAFIELDA_LEVEL,TWON_ONEVALUE,TWTY_UINT32,TWIA_FIXED' if '${sts:}' != 'SUCCESS' goto MAIN.IMAGEADDRESSENABLED.SKIP dsmentry src ds dg_control dat_capability msg_set 'CAP_IAFIELDB_LEVEL,TWON_ONEVALUE,TWTY_UINT32,TWIA_LEVEL3' if '${sts:}' != 'SUCCESS' goto MAIN.IMAGEADDRESSENABLED.SKIP dsmentry src ds dg_control dat_capability msg_set 'CAP_IAFIELDC_LEVEL,TWON_ONEVALUE,TWTY_UINT32,TWIA_LEVEL2' if '${sts:}' != 'SUCCESS' goto MAIN.IMAGEADDRESSENABLED.SKIP dsmentry src ds dg_control dat_capability msg_set 'CAP_IAFIELDD_LEVEL,TWON_ONEVALUE,TWTY_UINT32,TWIA_LEVEL1' if '${sts:}' != 'SUCCESS' goto MAIN.IMAGEADDRESSENABLED.SKIP ; dsmentry src ds dg_control dat_capability msg_set 'CAP_IAFIELDA_PRINTFORMAT,TWON_ONEVALUE,TWTY_STR32,#####' if '${sts:}' != 'SUCCESS' goto MAIN.IMAGEADDRESSENABLED.SKIP dsmentry src ds dg_control dat_capability msg_set 'CAP_IAFIELDB_PRINTFORMAT,TWON_ONEVALUE,TWTY_STR32,###' if '${sts:}' != 'SUCCESS' goto MAIN.IMAGEADDRESSENABLED.SKIP dsmentry src ds dg_control dat_capability msg_set 'CAP_IAFIELDC_PRINTFORMAT,TWON_ONEVALUE,TWTY_STR32,###' if '${sts:}' != 'SUCCESS' goto MAIN.IMAGEADDRESSENABLED.SKIP dsmentry src ds dg_control dat_capability msg_set 'CAP_IAFIELDD_PRINTFORMAT,TWON_ONEVALUE,TWTY_STR32,###' if '${sts:}' != 'SUCCESS' goto MAIN.IMAGEADDRESSENABLED.SKIP ; dsmentry src ds dg_control dat_capability msg_set 'CAP_IAFIELDA_VALUE,TWON_ONEVALUE,TWTY_STR32,FIXED' if '${sts:}' != 'SUCCESS' goto MAIN.IMAGEADDRESSENABLED.SKIP dsmentry src ds dg_control dat_capability msg_set 'CAP_IAFIELDB_VALUE,TWON_ONEVALUE,TWTY_STR32,300' if '${sts:}' != 'SUCCESS' goto MAIN.IMAGEADDRESSENABLED.SKIP dsmentry src ds dg_control dat_capability msg_set 'CAP_IAFIELDC_VALUE,TWON_ONEVALUE,TWTY_STR32,20' if '${sts:}' != 'SUCCESS' goto MAIN.IMAGEADDRESSENABLED.SKIP dsmentry src ds dg_control dat_capability msg_set 'CAP_IAFIELDD_VALUE,TWON_ONEVALUE,TWTY_STR32,1' if '${sts:}' != 'SUCCESS' goto MAIN.IMAGEADDRESSENABLED.SKIP ; setlocal name 'Image Address set' :MAIN.IMAGEADDRESSENABLED.SKIP echo.passfail '${get:indent}${get:name}' 'pass' ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Set ICAP_PATCHCODEDETECTIONENABLED to TRUE ; setlocal name 'ICAP_PATCHCODEDETECTIONENABLED MSG_SET TRUE' dsmentry src ds dg_control dat_capability msg_set 'ICAP_PATCHCODEDETECTIONENABLED,TWON_ONEVALUE,TWTY_BOOL,TRUE' if '${sts:}' != 'SUCCESS' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Try to set ICAP_PATCHCODESEARCHMODE to TWBD_HORZVERT, TWBD_VERTHORZ, TWBD_HORZ, or TWBD_VERT. ; Patch code sheets can have bars on all sides, so we're not requiring that any particular mode ; has to be supported. We just need one. ; setlocal name 'ICAP_PATCHCODESEARCHMODE MSG_SET TWBD_HORZVERT, TWBD_VERTHORZ, TWBD_HORZ, or TWBD_VERT' dsmentry src ds dg_control dat_capability msg_get 'ICAP_PATCHCODESEARCHMODE' if '${sts:}' != 'SUCCESS' goto MAIN.ERROR.ECHOPASSFAIL ; if '${ret:}' contains 'TWBD_HORZVERT' goto MAIN.ICAP_PATCHCODESEARCHMODE.TWBD_HORZVERT if '${ret:}' contains 'TWBD_VERTHORZ' goto MAIN.ICAP_PATCHCODESEARCHMODE.TWBD_VERTHORZ if '${ret:}' contains 'TWBD_VERT' goto MAIN.ICAP_PATCHCODESEARCHMODE.TWBD_VERT ; dsmentry src ds dg_control dat_capability msg_set 'ICAP_PATCHCODESEARCHMODE,TWON_ONEVALUE,TWTY_UINT16,TWBD_HORZ' if '${sts:}' != 'SUCCESS' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' goto MAIN.ICAP_PATCHCODESEARCHMODE.DONE ; :MAIN.ICAP_PATCHCODESEARCHMODE.TWBD_HORZVERT dsmentry src ds dg_control dat_capability msg_set 'ICAP_PATCHCODESEARCHMODE,TWON_ONEVALUE,TWTY_UINT16,TWBD_HORZVERT' if '${sts:}' != 'SUCCESS' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' goto MAIN.ICAP_PATCHCODESEARCHMODE.DONE ; :MAIN.ICAP_PATCHCODESEARCHMODE.TWBD_VERTHORZ dsmentry src ds dg_control dat_capability msg_set 'ICAP_PATCHCODESEARCHMODE,TWON_ONEVALUE,TWTY_UINT16,TWBD_VERTHORZ' if '${sts:}' != 'SUCCESS' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' goto MAIN.ICAP_PATCHCODESEARCHMODE.DONE ; :MAIN.ICAP_PATCHCODESEARCHMODE.TWBD_VERT dsmentry src ds dg_control dat_capability msg_set 'ICAP_PATCHCODESEARCHMODE,TWON_ONEVALUE,TWTY_UINT16,TWBD_VERT' if '${sts:}' != 'SUCCESS' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' goto MAIN.ICAP_PATCHCODESEARCHMODE.DONE ; :MAIN.ICAP_PATCHCODESEARCHMODE.DONE ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Try to set ICAP_PATCHCODEMAXSEARCHPRIORITIES to its maximum value... ; setlocal name 'ICAP_PATCHCODEMAXSEARCHPRIORITIES MSG_SET max value' dsmentry src ds dg_control dat_capability msg_get 'ICAP_PATCHCODEMAXSEARCHPRIORITIES' if '${sts:}' != 'SUCCESS' goto MAIN.ERROR.ECHOPASSFAIL setglobal g_patchcodemaxsearchpriorities.max '${ret:${get:TW_RANGE.MaxValue}}' dsmentry src ds dg_control dat_capability msg_set 'ICAP_PATCHCODEMAXSEARCHPRIORITIES,TWON_ONEVALUE,TWTY_UINT32,${get:g_patchcodemaxsearchpriorities.max}' if '${sts:}' != 'SUCCESS' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Get the ICAP_SUPPORTEDPATCHCODETYPES... ; setlocal name 'ICAP_SUPPORTEDPATCHCODETYPES MSG_GET' dsmentry src ds dg_control dat_capability msg_get 'ICAP_SUPPORTEDPATCHCODETYPES' if '${sts:}' != 'SUCCESS' goto MAIN.ERROR.ECHOPASSFAIL setlocal supportedpatchcodetypes.itemlist '${ret:}' echo.passfail '${get:indent}${get:name}' 'pass' ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Pare the ICAP_SUPPORTEDPATCHCODETYPES list down to the first ICAP_PATCHCODEMAXSEARCHPRIORITIES items, ; all of the standard patch codes should be supported, but we're not going to require that. ; setlocal comma '' setlocal name 'Get the first ${get:g_patchcodemaxsearchpriorities.max} from ICAP_SUPPORTEDPATCHCODETYPES' setlocal patchcodesearchpriorities.itemlist '' ; setlocal supportedpatchcodetypes.index '${get:TW_ARRAY.NumItems}' ; TW_ARRAY.ItemList - 1 increment supportedpatchcodetypes.lastindex '${get:supportedpatchcodetypes.index}' 1 ; first index increment supportedpatchcodetypes.lastindex '${get:supportedpatchcodetypes.lastindex}' ${get:g_patchcodemaxsearchpriorities.max} ; + g_patchcodemaxsearchpriorities.max ; :MAIN.PATCHCODESEARCHPRIORITIES.NEXT increment supportedpatchcodetypes.index '${get:supportedpatchcodetypes.index}' 1 if '${get:supportedpatchcodetypes.index}' > '${get:supportedpatchcodetypes.lastindex}' goto MAIN.PATCHCODESEARCHPRIORITIES.DONE setlocal patchcodesearchpriorities.value '${getindex:supportedpatchcodetypes.itemlist:${get:supportedpatchcodetypes.index}}' if '${get:patchcodesearchpriorities.value}' == '' goto MAIN.PATCHCODESEARCHPRIORITIES.DONE setlocal patchcodesearchpriorities.itemlist '${get:patchcodesearchpriorities.itemlist}${get:comma}${get:patchcodesearchpriorities.value}' setlocal comma ',' goto MAIN.PATCHCODESEARCHPRIORITIES.NEXT ; :MAIN.PATCHCODESEARCHPRIORITIES.DONE echo.passfail '${get:name}' 'pass' ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Set ICAP_PATCHCODESEARCHPRIORITIES to first g_patchcodemaxsearchpriorities.max ; of ICAP_SUPPORTEDPATCHCODETYPES... ; setlocal name 'ICAP_PATCHCODESEARCHPRIORITIES MSG_SET first ${get:g_patchcodemaxsearchpriorities.max} of ICAP_SUPPORTEDPATCHCODETYPES' dsmentry src ds dg_control dat_capability msg_set 'ICAP_PATCHCODESEARCHPRIORITIES,TWON_ARRAY,TWTY_UINT16,${get:g_patchcodemaxsearchpriorities.max},${get:patchcodesearchpriorities.itemlist}' if '${sts:}' != 'SUCCESS' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Summary and cleanup... ; ; We passed... :MAIN.PASS return 'pass' ; ; Ruh-roh... :MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'fail - ${sts:} ${ret:}' return 'fail' ================================================ FILE: twaincs/source/twaincscert/source/data/certification/120 - Patch Code Badge/_README.txt ================================================ Patch Codes can be found online. Here are some resources as of 19-Aug-2021 https://patchcode.kodakalaris.com/en/index.html http://www.alliancegroup.co.uk/patch-codes.htm If the links don't work, search for: Patch Code Samples Patch Code Creator Patch Code Generator Note that TWAIN only recognizes the following patches, ones other than these may be recognized by a TWAIN driver as a custom feature, but will not be recognized by the certification test. PATCH 1 PATCH 2 PATCH 3 PATCH 4 PATCH 6 PATCH T (transfer) ================================================ FILE: twaincs/source/twaincscert/source/data/certification/130 - Barcode Badge/Barcode Badge.tc ================================================ ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Barcode Badge ; These tests establish the minimum requirements for a TWAIN driver to claim that it has barcode ; support. It focuses on the ability to turn barcode detection on and off, identifying which ; barcodes are supported, and making sure barcode metadata is reported. ; ; Arguments ; arg:1 - TW_IDENTITY.ProductName of scanner to test ; ; Globals ; (none) ; ; Locals ; certifyresult - track if we fail ; ; Returns ; pass/fail ; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Initialize... ; setlocal certifyresult 'pass' ; assume we'll pass ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Reset to a known state... ; setlocal name 'MSG_RESETALL' dsmentry src ds dg_control dat_capability msg_resetall '0,0,0,0' if '${sts:}' != 'SUCCESS' goto MAIN.MSG_RESETALL.FAIL echo.passfail '${get:name}' 'pass' goto MAIN.MSG_RESETALL.DONE ; :MAIN.MSG_RESETALL.FAIL echo.passfail '${get:name}' 'skip - ${sts:} ${ret:}' setlocal certifyresult 'fail' goto MAIN.DONE :MAIN.MSG_RESETALL.DONE ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; ICAP_BARCODEDETECTIONENABLED must be supported, and must offer both TRUE ; and FALSE, and must currently be FALSE, otherwise skip it all ; setlocal name 'ICAP_BARCODEDETECTIONENABLED is supported' dsmentry src ds dg_control dat_capability msg_get 'ICAP_BARCODEDETECTIONENABLED,0,0,0' if '${sts:}' != 'SUCCESS' goto MAIN.ICAP_BARCODEDETECTIONENABLEDSUPPORTED.SKIP if ',${ret:},' !~contains ',TRUE,' goto MAIN.ICAP_BARCODEDETECTIONENABLEDSUPPORTED.SKIP if ',${ret:},' !~contains ',FALSE,' goto MAIN.ICAP_BARCODEDETECTIONENABLEDSUPPORTED.SKIP echo.passfail '${get:name}' 'pass' goto MAIN.ICAP_BARCODEDETECTIONENABLEDSUPPORTED.DONE ; :MAIN.ICAP_BARCODEDETECTIONENABLEDSUPPORTED.SKIP echo.passfail '${get:name}' 'skip - ${sts:} ${ret:}' setlocal certifyresult 'skip' goto MAIN.DONE :MAIN.ICAP_BARCODEDETECTIONENABLEDSUPPORTED.DONE ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; CAP_SUPPORTEDCAPS: check that all required capabilities are reported ; We're not requiring the presence of ICAP_BARCODEMAXRETRIES or ; ICAP_BARODETIMEOUT. If present it's assumed the driver will default ; these to meaningful values that support the best chance of detecting ; a barcode. ; setlocal name 'CAP_SUPPORTEDCAPS MSG_GET' dsmentry src ds dg_control dat_capability msg_get 'CAP_SUPPORTEDCAPS,0,0,0' if '${sts:}' != 'SUCCESS' goto MAIN.CAP_SUPPORTEDCAPS.FAIL echo.passfail '${get:name}' 'pass' ; setlocal name 'CAP_SUPPORTEDCAPS ICAP_BARCODEDETECTIONENABLED found' if ',${ret:},' !~contains ',ICAP_BARCODEDETECTIONENABLED,' goto MAIN.CAP_SUPPORTEDCAPS.FAIL echo.passfail '${get:name}' 'pass' ; setlocal name 'CAP_SUPPORTEDCAPS ICAP_BARCODEMAXSEARCHPRIORITIES found' if ',${ret:},' !~contains ',ICAP_BARCODEMAXSEARCHPRIORITIES,' goto MAIN.CAP_SUPPORTEDCAPS.FAIL echo.passfail '${get:name}' 'pass' ; setlocal name 'CAP_SUPPORTEDCAPS ICAP_BARCODESEARCHMODE found' if ',${ret:},' !~contains ',ICAP_BARCODESEARCHMODE,' goto MAIN.CAP_SUPPORTEDCAPS.FAIL echo.passfail '${get:name}' 'pass' ; setlocal name 'CAP_SUPPORTEDCAPS ICAP_BARCODESEARCHPRIORITIES found' if ',${ret:},' !~contains ',ICAP_BARCODESEARCHPRIORITIES,' goto MAIN.CAP_SUPPORTEDCAPS.FAIL echo.passfail '${get:name}' 'pass' ; setlocal name 'CAP_SUPPORTEDCAPS ICAP_SUPPORTEDBARCODETYPES found' if ',${ret:},' !~contains ',ICAP_SUPPORTEDBARCODETYPES,' goto MAIN.CAP_SUPPORTEDCAPS.FAIL echo.passfail '${get:name}' 'pass' ; goto MAIN.CAP_SUPPORTEDCAPS.DONE :MAIN.CAP_SUPPORTEDCAPS.FAIL echo.passfail '${get:name}' 'fail - ${sts:} ${ret:}' setlocal certifyresult 'fail' goto MAIN.DONE :MAIN.CAP_SUPPORTEDCAPS.DONE ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; ICAP_SUPPORTEDEXTIMAGEINFO: check that all metadata is reported ; setlocal name 'ICAP_SUPPORTEDEXTIMAGEINFO MSG_GET' dsmentry src ds dg_control dat_capability msg_get 'ICAP_SUPPORTEDEXTIMAGEINFO,0,0,0' if '${sts:}' != 'SUCCESS' goto MAIN.ICAP_SUPPORTEDEXTIMAGEINFO.FAIL echo.passfail '${get:name}' 'pass' ; setlocal name 'ICAP_SUPPORTEDEXTIMAGEINFO TWEI_BARCODECONFIDENCE found' if ',${ret:},' !~contains ',TWEI_BARCODECONFIDENCE,' goto MAIN.ICAP_SUPPORTEDEXTIMAGEINFO.FAIL echo.passfail '${get:name}' 'pass' ; setlocal name 'ICAP_SUPPORTEDEXTIMAGEINFO TWEI_BARCODECOUNT found' if ',${ret:},' !~contains ',TWEI_BARCODECOUNT,' goto MAIN.ICAP_SUPPORTEDEXTIMAGEINFO.FAIL echo.passfail '${get:name}' 'pass' ; setlocal name 'ICAP_SUPPORTEDEXTIMAGEINFO TWEI_BARCODEROTATION found' if ',${ret:},' !~contains ',TWEI_BARCODEROTATION,' goto MAIN.ICAP_SUPPORTEDEXTIMAGEINFO.FAIL echo.passfail '${get:name}' 'pass' ; setlocal name 'ICAP_SUPPORTEDEXTIMAGEINFO TWEI_BARCODETEXT2 found' if ',${ret:},' !~contains ',TWEI_BARCODETEXT2,' goto MAIN.ICAP_SUPPORTEDEXTIMAGEINFO.FAIL echo.passfail '${get:name}' 'pass' ; setlocal name 'ICAP_SUPPORTEDEXTIMAGEINFO TWEI_BARCODETEXTLENGTH found' if ',${ret:},' !~contains ',TWEI_BARCODETEXTLENGTH,' goto MAIN.ICAP_SUPPORTEDEXTIMAGEINFO.FAIL echo.passfail '${get:name}' 'pass' ; setlocal name 'ICAP_SUPPORTEDEXTIMAGEINFO TWEI_BARCODETYPE found' if ',${ret:},' !~contains ',TWEI_BARCODETYPE,' goto MAIN.ICAP_SUPPORTEDEXTIMAGEINFO.FAIL echo.passfail '${get:name}' 'pass' ; setlocal name 'ICAP_SUPPORTEDEXTIMAGEINFO TWEI_BARCODEX found' if ',${ret:},' !~contains ',TWEI_BARCODEX,' goto MAIN.ICAP_SUPPORTEDEXTIMAGEINFO.FAIL echo.passfail '${get:name}' 'pass' ; setlocal name 'ICAP_SUPPORTEDEXTIMAGEINFO TWEI_BARCODEY found' if ',${ret:},' !~contains ',TWEI_BARCODEY,' goto MAIN.ICAP_SUPPORTEDEXTIMAGEINFO.FAIL echo.passfail '${get:name}' 'pass' ; goto MAIN.ICAP_SUPPORTEDEXTIMAGEINFO.DONE :MAIN.ICAP_SUPPORTEDEXTIMAGEINFO.FAIL echo.passfail '${get:name}' 'fail - ${sts:} ${ret:}' setlocal certifyresult 'fail' :MAIN.ICAP_SUPPORTEDEXTIMAGEINFO.DONE ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; ICAP_BARCODEDETECTIONENABLED must currently be FALSE ; setlocal name 'ICAP_BARCODEDETECTIONENABLED resets to FALSE' dsmentry src ds dg_control dat_capability msg_getcurrent 'ICAP_BARCODEDETECTIONENABLED,0,0,0' if '${sts:}' != 'SUCCESS' goto MAIN.ICAP_BARCODEDETECTIONENABLEDFALSE.FAIL if ',${ret:},' !~contains ',FALSE,' goto MAIN.ICAP_BARCODEDETECTIONENABLEDFALSE.FAIL echo.passfail '${get:name}' 'pass' goto MAIN.ICAP_BARCODEDETECTIONENABLEDFALSE.DONE ; :MAIN.ICAP_BARCODEDETECTIONENABLEDFALSE.SKIP echo.passfail '${get:name}' 'skip - ${sts:} ${ret:}' setlocal certifyresult 'fail' goto MAIN.DONE :MAIN.ICAP_BARCODEDETECTIONENABLEDFALSE.DONE ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; ICAP_BARCODEDETECTIONENABLED set to TRUE ; setlocal name 'ICAP_BARCODEDETECTIONENABLED set to TRUE' dsmentry src ds dg_control dat_capability msg_set 'ICAP_BARCODEDETECTIONENABLED,TWON_ONEVALUE,TWTY_BOOL,TRUE' if '${sts:}' != 'SUCCESS' goto MAIN.ICAP_BARCODEDETECTIONENABLEDTRUE.FAIL dsmentry src ds dg_control dat_capability msg_getcurrent 'ICAP_BARCODEDETECTIONENABLED,0,0,0' if '${sts:}' != 'SUCCESS' goto MAIN.ICAP_BARCODEDETECTIONENABLEDTRUE.FAIL if ',${ret:},' !~contains ',TRUE,' goto MAIN.ICAP_BARCODEDETECTIONENABLEDTRUE.FAIL echo.passfail '${get:name}' 'pass' goto MAIN.ICAP_BARCODEDETECTIONENABLEDTRUE.DONE ; :MAIN.ICAP_BARCODEDETECTIONENABLEDTRUE.FAIL echo.passfail '${get:name}' 'skip - ${sts:} ${ret:}' setlocal certifyresult 'fail' goto MAIN.DONE :MAIN.ICAP_BARCODEDETECTIONENABLEDTRUE.DONE ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Get ICAP_XFERMECH... ; setlocal name 'ICAP_XFERMECH MSG_GET' dsmentry src ds dg_control dat_capability msg_get 'ICAP_XFERMECH,0,0,0' if '${sts:}' == 'SUCCESS' goto MAIN.ICAP_XFERMECH.DONE echo.passfail '${get:name}' 'fail - ${sts:} ${ret:}' setlocal certifyresult 'fail' goto MAIN.DONE ; :MAIN.ICAP_XFERMECH.DONE setglobal g_xfermech '${ret:}' ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; All done... ; :MAIN.DONE return '${get:certifyresult}' ================================================ FILE: twaincs/source/twaincscert/source/data/certification/130 - Barcode Badge/Certification.tc ================================================ ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Barcode Badge ; Check if Barcode is supported by the driver. This is a badge, meaning that failure will not ; invalidate scanner certification. Instead, passage will add Barcode support to the cert. ; ; Arguments ; arg:1 - TW_IDENTITY.ProductName of scanner to test ; arg:2 - global to set on fail ; ; Globals ; g_localcertifyresult - global to report to caller on fail ; g_xfermech - current transfer mechanism ; ; Locals ; twidentity.productname - product name of scanner to test ; globaltosetonfail - name says it all ; ; Returns ; (none) ; ; History ; 1.0 - initial release ; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Initialize stuff, load tables if not already done for us... ; echo.titlesuite 'Barcode Badge v1.0 17-Sep-2021' echo.yellow '*************************************************************************************' echo.yellow '*** This tests the Barcode Badge. Skipping or failing means the driver does ***' echo.yellow '*** not support this functionality. It does not prevent certification. ***' echo.yellow '*************************************************************************************' ; setlocal twidentity.productname '${arg:1}' setlocal globaltosetonfail '${arg:2}' setglobal g_localcertifyresult 'pass' ; assume success setglobal g_xfermech '' ; if '${get:TW_ARRAY.ItemType}' != '' goto MAIN.LOADTABLES.SKIP run '${folder:certification}/LoadTables' :MAIN.LOADTABLES.SKIP ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Run the tests... ; call CERTIFY '${folder:certification}/Opends' '${get:twidentity.productname}' 'g_localcertifyresult' 'embedded' if '${get:g_localcertifyresult}' == 'fail' goto MAIN.CLOSEDS ; call CERTIFY 'Barcode Badge' '${get:twidentity.productname}' 'g_localcertifyresult' call CERTIFY 'DAT_IMAGENATIVEXFER' '${get:twidentity.productname}' 'g_localcertifyresult' '${folder:parent}' call CERTIFY 'DAT_IMAGEMEMXFER' '${get:twidentity.productname}' 'g_localcertifyresult' '${folder:parent}' call CERTIFY 'DAT_IMAGEFILEXFER' '${get:twidentity.productname}' 'g_localcertifyresult' '${folder:parent}' call CERTIFY 'DAT_IMAGEMEMFILEXFER' '${get:twidentity.productname}' 'g_localcertifyresult' '${folder:parent}' ; :MAIN.CLOSEDS call CERTIFY '${folder:certification}/Closeds' '${get:twidentity.productname}' 'g_localcertifyresult 'embedded' ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Summary and cleanup... ; ; Did we pass? (do an extra check) if '${get:g_localcertifyresult}' == 'skip' goto MAIN.SKIP if '${get:g_localcertifyresult}' != 'pass' goto MAIN.ERROR echo '' echo.passfail 'BADGE SUMMARY' 'pass' return 'pass' ; ; Unsupported... :MAIN.SKIP echo '' echo.passfail 'BADGE SUMMARY' 'skip' setglobal '${get:globaltosetonfail}' 'skip' return 'skip' ; ; Ruh-roh... :MAIN.ERROR echo '' echo.passfail 'BADGE SUMMARY' 'fail' setglobal '${get:globaltosetonfail}' 'fail' return 'fail' ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Function: Certify ; arg:1 - script to run ; arg:2 - TW_IDENTITY.ProductName of scanner to test ; arg:3 - global value to update on fail ; arg:4 - embeded flag for open/close, or folder for DAT_IMAGE*XFER calls ; returns: (none) ; :CERTIFY ; ; If a failure has occurred on a previous test, skip the rest of the tests, ; except for closing, that would be bad... if '${arg:1}' ~contains 'Closeds' goto CERTIFY.RUN if '${get:${arg:3}}' == 'skip' goto CERTIFY.SKIP if '${get:${arg:3}}' == 'fail' goto CERTIFY.FAIL ; ; Run the test... :CERTIFY.RUN run '${arg:1}' '${arg:2}' '${arg:4}' if '${ret:}' == 'skip' goto CERTIFY.SKIP if '${ret:}' != 'pass' goto CERTIFY.FAIL return 'pass' ; ; Handle skipping, set the global so we have a record... :CERTIFY.SKIP setglobal '${arg:3}' 'skip' return 'skip' ; ; Handle failure, set the global so we have a record... :CERTIFY.FAIL setglobal '${arg:3}' 'fail' return 'fail' ================================================ FILE: twaincs/source/twaincscert/source/data/certification/130 - Barcode Badge/DAT_EXTIMAGEINFO.tc ================================================ ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; DAT_EXTIMAGEINFO ; Check the return values from DAT_EXTIMAGEINFO to make sure the barcode ; metadata is being properly reported. ; ; Here's the basic flow: ; DAT_EXTIMAGEINFO ; confirm that we have the following TWEI_BARCODE* items ; TWEI_BARCODECOUNT ; TWEI_BARCODECONFIDENCE ; TWEI_BARCODEROTATION ; TWEI_BARCODETYPE ; TWEI_BARCODEX ; TWEI_BARCODEY ; TWEI_BARCODETEXTLENGTH ; TWEI_BARCODETEXT2 ; confirm TWEI_BARCODECOUNT fields in TW_INFO[0] ; confirm a sheet with no barcodes (TWEI_BARCODECOUNT == 0) ; all TW_INFO[n].ReturnCode values TWRC_DATANOTAVAILABLE ; confirm a sheet with one barcode (TWEI_BARCODECOUNT == 1) ; all TW_INFO[n].ReturnCode values are TWRC_SUCCESS ; all TW_INFO[n].ItemType values match the spec ; all TW_INFO[n].NumItems match ICAP_BARCODECOUNT ; all TW_INFO[n].Item handle contains 'TWAIN-Barcode-Test' ; confirm a sheet with many barcodes (TWEI_BARCODECOUNT > 1) ; all TW_INFO[n].ReturnCode values are TWRC_SUCCESS ; all TW_INFO[n].ItemType values match the spec ; all TW_INFO[n].NumItems match ICAP_BARCODECOUNT ; all TW_INFO[n].Item handle points to array of handles, and each contains 'TWAIN-Barcode-Test' ; ; The test passes if: ; - g_barcodecount.none >= 1 ; and (((barcodemaxsearchpriorities.max > 1) and (g_barcodecount.one >= 1) and (g_barcodecount.many >= 1)) ; or ((barcodemaxsearchpriorities.max == 1) and (g_barcodecount.one >= 2) and (g_barcodecount.many == 0))) ; ; Arguments ; arg:1 - indent the passfail text ; arg:2 - base filename (no extension) ; ; Globals ; g_barcodecount.none - increment if no barcodes are found ; g_barcodecount.one - increment if one barcodes is found ; g_barcodecount.many - increment if many barcodes are found ; ; Locals ; barcodecount - the number of barcodes found on the image ; barcodedata - the return value from DAT_EXTIMAGEINFO ; barcodetext2.index - index into the current TWEI_BARCODETEXT2 value ; barcodetexthandle - barcodetext2.index handle from TW_INFO[n].Item array of handles ; barcodetextlength - one or more comma separated TWEI_BARCODETEXTLENGTH values, depending on TWEI_BARCODECOUNT ; barcodetextlength.index - index of the current TWEI_BARCODETEXTLENGTH value ; name - current test being done ; indent - indent the passfail text ; item - data from barcodetexthandle ; twinfo.infoid.index - index to TW_INFO[n].infoid from the start of barcodedata ; twinfo.itemtype.index - index to TW_INFO[n].itemtype from the start of barcodedata ; twinfo.numitems.index - index to TW_INFO[n].numitems from the start of barcodedata ; twinfo.returncode.index - index to TW_INFO[n].returncode from the start of barcodedata ; twinfo.item.index - index to TW_INFO[n].item from the start of barcodedata ; ; Returns ; pass/fail ; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Get the extended image info, save the data to 'barcodedata'. We've deliberately ; asked for TWEI_BARCODECOUNT first, and for TWEI_BARCODETEXTLENGTH before ; TWEI_BARCODETEXT2 to make it easier to parse the data we get back. You'll see ; why further below... ; setlocal indent '${arg:1} ' setlocal name 'dg_image/dat_extimageinfo/msg_get TWEI_BARCODE*' dsmentry src ds dg_image dat_extimageinfo msg_get '8,TWEI_BARCODECOUNT,0,0,0,0,TWEI_BARCODECONFIDENCE,0,0,0,0,TWEI_BARCODEROTATION,0,0,0,0,TWEI_BARCODETYPE,0,0,0,0,TWEI_BARCODEX,0,0,0,0,TWEI_BARCODEY,0,0,0,0,TWEI_BARCODETEXTLENGTH,0,0,0,0,TWEI_BARCODETEXT2,0,0,0,0' if '${sts:}' != 'SUCCESS' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' setlocal barcodedata '${ret:}' filewrite '${arg:2}_extimageinfo.txt' '${get:barcodedata}' ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Confirm that we got back all the barcode extimageinfo data... ; setlocal name 'Found TWEI_BARCODECOUNT' if '${get:barcodedata}' !contains 'TWEI_BARCODECOUNT' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' setlocal name 'Found TWEI_BARCODECONFIDENCE' if '${get:barcodedata}' !contains 'TWEI_BARCODECONFIDENCE' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' setlocal name 'Found TWEI_BARCODEROTATION' if '${get:barcodedata}' !contains 'TWEI_BARCODEROTATION' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' setlocal name 'Found TWEI_BARCODETYPE' if '${get:barcodedata}' !contains 'TWEI_BARCODETYPE' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' setlocal name 'Found TWEI_BARCODEX' if '${get:barcodedata}' !contains 'TWEI_BARCODEX' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' setlocal name 'Found TWEI_BARCODEY' if '${get:barcodedata}' !contains 'TWEI_BARCODEY' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' setlocal name 'Found TWEI_BARCODETEXTLENGTH' if '${get:barcodedata}' !contains 'TWEI_BARCODETEXTLENGTH' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' setlocal name 'Found TWEI_BARCODETEXT2' if '${get:barcodedata}' !contains 'TWEI_BARCODETEXT2' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Validate the contents of TWEI_BARCODECOUNT, which is TW_INFO[0]... ; setlocal name 'TW_INFO[0].InfoID is TWEI_BARCODECOUNT' if '${getindex:barcodedata:${get:TW_INFO.InfoID}}' != 'TWEI_BARCODECOUNT' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' ; setlocal name 'TW_INFO[0].ItemType is TWTY_UINT32' if '${getindex:barcodedata:${get:TW_INFO.ItemType}}' != 'TWTY_UINT32' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' ; setlocal name 'TW_INFO[0].NumItems is 1' if '${getindex:barcodedata:${get:TW_INFO.NumItems}}' != '1' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' ; setlocal name 'TW_INFO[0].ReturnCode is TWRC_SUCCESS' if '${getindex:barcodedata:${get:TW_INFO.ReturnCode}}' != 'TWRC_SUCCESS' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' ; setlocal barcodecount '${getindex:barcodedata:${get:TW_INFO.Item}}' ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Jump to the correct analysis section, depending on how many barcodes we detected ; in the first TW_INFO, which we expect to be TWEI_BARCODECOUNT, because that's where ; we put it... ; setlocal twinfo.infoid.index '${get:TW_INFO.InfoID}' setlocal twinfo.itemtype.index '${get:TW_INFO.ItemType}' setlocal twinfo.numitems.index '${get:TW_INFO.NumItems}' setlocal twinfo.returncode.index '${get:TW_INFO.ReturnCode}' setlocal twinfo.item.index '${get:TW_INFO.Item}' if '${getindex:barcodedata:${get:TW_INFO.Item}}' == '0' goto MAIN.NOBARCODES if '${getindex:barcodedata:${get:TW_INFO.Item}}' == '1' goto MAIN.ONEBARCODE goto MAIN.MANYBARCODES ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Validate what happens when we can't find a barcode, we're looking at the NumItems ; and the ReturnCodes for all of the TWEI_BARCODE* items. We expect the number of ; items to be 0 (matching the value of TWEI_BARCODECOUNT), and we expect the return ; code to be TWRC_DATANOTAVAILABLE... ; :MAIN.NOBARCODES increment g_barcodecount.none '${get:g_barcodecount.none}' 1 increment twinfo.infoid.index '${get:twinfo.infoid.index}' 5 ; skip to the InfoID in the next TW_INFO increment twinfo.itemtype.index '${get:twinfo.itemtype.index}' 5 ; skip to the InfoID in the next TW_INFO increment twinfo.numitems.index '${get:twinfo.numitems.index}' 5 ; skip to the NumItems in the next TW_INFO increment twinfo.returncode.index '${get:twinfo.returncode.index}' 5 ; skip to the ReturnCode in the next TW_INFO increment twinfo.item.index '${get:twinfo.item.index}' 5 ; skip to the ReturnCode in the next TW_INFO ; :MAIN.NOBARCODES.NEXT setlocal name 'No barcodes: '${getindex:barcodedata:${get:twinfo.infoid.index}}' if '${getindex:barcodedata:${get:twinfo.infoid.index}}' == '' goto MAIN.PASS ; out of items if '${getindex:barcodedata:${get:twinfo.numitems.index}}' != '0' goto MAIN.ERROR.ECHOPASSFAIL if '${getindex:barcodedata:${get:twinfo.returncode.index}}' != 'TWRC_DATANOTAVAILABLE' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' ; increment twinfo.infoid.index '${get:twinfo.infoid.index}' 5 ; skip to the InfoID in the next TW_INFO increment twinfo.itemtype.index '${get:twinfo.itemtype.index}' 5 ; skip to the InfoID in the next TW_INFO increment twinfo.numitems.index '${get:twinfo.numitems.index}' 5 ; skip to the NumItems in the next TW_INFO increment twinfo.returncode.index '${get:twinfo.returncode.index}' 5 ; skip to the ReturnCode in the next TW_INFO increment twinfo.item.index '${get:twinfo.item.index}' 5 ; skip to the ReturnCode in the next TW_INFO goto MAIN.NOBARCODES.NEXT ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Validate one barcode item, we're looking at the NumItems and the ReturnCodes ; for all of the TWEI_BARCODE* items. We expect the number of items to be 1 ; (matching the value of TWEI_BARCODECOUNT), and we expect the return code to ; be TWRC_SUCCESS. We expect all TWEI_BARCODE* itemtypes to be TWTY_UINT32, ; except for TWEI_BARCODETEXT2, which must be TWTY_HANDLE... ; :MAIN.ONEBARCODE increment g_barcodecount.one '${get:g_barcodecount.one}' 1 ; ; Increment to the next TW_INFO, this skips TW_INFO[0] for us, bail from the ; loop when we run out of items... :MAIN.ONEBARCODE.NEXT increment twinfo.infoid.index '${get:twinfo.infoid.index}' 5 ; skip to the InfoID in the next TW_INFO increment twinfo.itemtype.index '${get:twinfo.itemtype.index}' 5 ; skip to the InfoID in the next TW_INFO increment twinfo.numitems.index '${get:twinfo.numitems.index}' 5 ; skip to the NumItems in the next TW_INFO increment twinfo.returncode.index '${get:twinfo.returncode.index}' 5 ; skip to the ReturnCode in the next TW_INFO increment twinfo.item.index '${get:twinfo.item.index}' 5 ; skip to the ReturnCode in the next TW_INFO if '${getindex:barcodedata:${get:twinfo.infoid.index}}' == '' goto MAIN.PASS ; out of items ; ; Check NumItems... setlocal name 'One barcode: ${getindex:barcodedata:${get:twinfo.infoid.index}}.NumItems is TWEI_BARCODECOUNT' if '${getindex:barcodedata:${get:twinfo.numitems.index}}' != '${get:barcodecount}' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' ; ; Check ReturnCode... setlocal name 'One barcode: ${getindex:barcodedata:${get:twinfo.infoid.index}}.ReturnCode is TWRC_SUCCESS' if '${getindex:barcodedata:${get:twinfo.returncode.index}}' != 'TWRC_SUCCESS' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' ; ; Check ItemType for non-TWEI_BARCODETEXT2 stuff... if '${getindex:barcodedata:${get:twinfo.infoid.index}}' == 'TWEI_BARCODETEXT2' goto MAIN.ONEBARCODE.ITEMTYPE.BARCODETEXT2 setlocal name 'One barcode: ${getindex:barcodedata:${get:twinfo.infoid.index}}.ItemType is TWTY_UINT32' if '${getindex:barcodedata:${get:twinfo.itemtype.index}}' != 'TWTY_UINT32' MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' ; ; Get the length, when we see it... if '${getindex:barcodedata:${get:twinfo.infoid.index}}' != 'TWEI_BARCODETEXTLENGTH' goto MAIN.ONEBARCODE.NEXT setlocal barcodetextlength '${getindex:barcodedata:${get:twinfo.item.index}}' goto MAIN.ONEBARCODE.NEXT ; ; Check ItemType for TWEI_BARCODETEXT2... :MAIN.ONEBARCODE.ITEMTYPE.BARCODETEXT2 setlocal name 'One barcode: ${getindex:barcodedata:${get:twinfo.infoid.index}}.ItemType is TWTY_HANDLE' if '${getindex:barcodedata:${get:twinfo.itemtype.index}}' != 'TWTY_HANDLE' MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' ; ; Check Item for TWEI_BARCODETEXT2... :MAIN.ONEBARCODE.ITEMTYPE.BARCODETEXT2 setlocal name 'One barcode: ${getindex:barcodedata:${get:twinfo.infoid.index}}.Item contains TWAIN-Barcode-Test' if '${getindex:barcodedata:${get:twinfo.item.index}}' == '0' MAIN.ERROR.ECHOPASSFAIL setlocal item '${gethandle:${getindex:barcodedata:${get:twinfo.item.index}}:TWTY_HANDLE:${get:barcodetextlength}}' filewrite '${arg:2}_barcode.txt' '${get:item}' free handle item if '${get:item}' !~contains 'TWAIN-Barcode-Test' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' ; goto MAIN.ONEBARCODE.NEXT ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Validate many barcodes, we're looking at the NumItems and the ReturnCodes ; for all of the TWEI_BARCODE* items. We expect the number of items to be ; greater than 1 (matching the value of TWEI_BARCODECOUNT), and we expect the ; return code to be TWRC_SUCCESS. We expect all TWEI_BARCODE* itemtypes to be ; TWTY_UINT32, except for TWEI_BARCODETEXT2, which must be a TWTY_HANDLE ; pointing to an array of TWTY_HANDLES... ; :MAIN.MANYBARCODES increment g_barcodecount.many '${get:g_barcodecount.many}' 1 ; ; Increment to the next TW_INFO, this skips TW_INFO[0] for us, bail from the ; loop when we run out of items... :MAIN.MANYBARCODES.NEXT increment twinfo.infoid.index '${get:twinfo.infoid.index}' 5 ; skip to the InfoID in the next TW_INFO increment twinfo.itemtype.index '${get:twinfo.itemtype.index}' 5 ; skip to the InfoID in the next TW_INFO increment twinfo.numitems.index '${get:twinfo.numitems.index}' 5 ; skip to the NumItems in the next TW_INFO increment twinfo.returncode.index '${get:twinfo.returncode.index}' 5 ; skip to the ReturnCode in the next TW_INFO increment twinfo.item.index '${get:twinfo.item.index}' 5 ; skip to the ReturnCode in the next TW_INFO if '${getindex:barcodedata:${get:twinfo.infoid.index}}' == '' goto MAIN.PASS ; out of items ; ; Check NumItems... setlocal name 'Many barcodes: ${getindex:barcodedata:${get:twinfo.infoid.index}}.NumItems is TWEI_BARCODECOUNT' if '${getindex:barcodedata:${get:twinfo.numitems.index}}' != '${get:barcodecount}' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' ; ; Check ReturnCode... setlocal name 'Many barcodes: ${getindex:barcodedata:${get:twinfo.infoid.index}}.ReturnCode is TWRC_SUCCESS' if '${getindex:barcodedata:${get:twinfo.returncode.index}}' != 'TWRC_SUCCESS' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' ; ; Check ItemType for non-TWEI_BARCODETEXT2 stuff... if '${getindex:barcodedata:${get:twinfo.infoid.index}}' == 'TWEI_BARCODETEXT2' goto MAIN.MANYBARCODES.ITEMTYPE.BARCODETEXT2 setlocal name 'Many barcodes: ${getindex:barcodedata:${get:twinfo.infoid.index}}.ItemType is TWTY_UINT32' if '${getindex:barcodedata:${get:twinfo.itemtype.index}}' != 'TWTY_UINT32' MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' ; ; Get the length, when we see it, we're going to make a comma separated ; list of all the lengths... if '${getindex:barcodedata:${get:twinfo.infoid.index}}' != 'TWEI_BARCODETEXTLENGTH' goto MAIN.MANYBARCODES.NEXT setlocal barcodetextlength '' ; start empty setlocal barcodetextlength.index '0' ; index is at 0 setlocal comma '' ; no comma :MAIN.MANYBARCODES.BARCODETEXTLENGTH.NEXT setlocal barcodetextlength '${get:barcodetextlength}${get:comma}${gethandleindex:${getindex:barcodedata:${get:twinfo.item.index}}:${get:barcodetextlength.index}:TWTY_UINT32}' ; gethandleindex:handle:index:type setlocal comma ',' increment barcodetextlength.index ${get:barcodetextlength.index} 1 if '${get:barcodetextlength.index}' >= '${get:barcodecount}' goto MAIN.MANYBARCODES.NEXT ; out of items goto MAIN.MANYBARCODES.BARCODETEXTLENGTH.NEXT ; look into adding another barcodetextlength ; ; Check ItemType for TWEI_BARCODETEXT2... :MAIN.MANYBARCODES.ITEMTYPE.BARCODETEXT2 setlocal name 'Many barcodes: ${getindex:barcodedata:${get:twinfo.infoid.index}}.ItemType is TWTY_HANDLE' if '${getindex:barcodedata:${get:twinfo.itemtype.index}}' != 'TWTY_HANDLE' MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' ; ; Check Item for TWEI_BARCODETEXT2... :MAIN.MANYBARCODES.ITEM.BARCODETEXT2 setlocal barcodetext2.index '0' ; index starts at 0 ; ; Look here for every barcodetext2 indexed at 0 to (barcodecount-1) :MAIN.MANYBARCODES.ITEM.BARCODETEXT2.NEXT setlocal name 'Many barcodes: ${getindex:barcodedata:${get:twinfo.infoid.index}}.Item contains TWAIN-Barcode-Test' ; ; Yeah, okay, these two lines look like a bit of a mess. But honestly, it's not as insane as you might ; think. The first setlocal is going to memlock the TW_INFO[n].Item we're working on. Then it'll go in ; and pull out the handle at the current index (barcodetext.index). ; ; The second setlocal takes that handle, does a memlock on it, and extracts barcodetextlength bytes of ; data. barcodetextlength is an array, since each barcode can have a different size. setlocal barcodetexthandle '${gethandleindex:${getindex:barcodedata:${get:twinfo.item.index}}:${get:barcodetext2.index}:TWTY_HANDLE}' ; gethandleindex:handle:index:TWTY_HANDLE setlocal item '${gethandle:${get:barcodetexthandle}:TWTY_HANDLE:${getindex:barcodetextlength:${get:barcodetext2.index}}}' ; gethandle:handle:TWTY_HANDLE:length filewrite '${arg:2}_barcode_${get:barcodetext2.index}.txt' '${get:item}' ; ; The data needs to contain "TWAIN-Barcode-Test" (it can contain more stuff). If that passes, then ; increment our index and go back to MAIN.MANYBARCODES.ITEM.BARCODETEXT2.NEXT to process the next barcode... if '${get:item}' !~contains 'TWAIN-Barcode-Test' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' increment barcodetext2.index ${get:barcodetext2.index} 1 if '${get:barcodetext2.index}' >= '${get:barcodecount}' goto MAIN.MANYBARCODES.NEXT ; out of items goto MAIN.MANYBARCODES.ITEM.BARCODETEXT2.NEXT ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Summary and cleanup... ; ; We passed... :MAIN.PASS return 'pass' ; ; Ruh-roh... :MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'fail - ${sts:} ${ret:}' return 'fail' ================================================ FILE: twaincs/source/twaincscert/source/data/certification/130 - Barcode Badge/DAT_IMAGEFILEXFER.tc ================================================ ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; DAT_IMAGEFILEXFER ; This test scans three sheets of paper for the default pixeltype. An ADF ; is required to pass this test, but that was already been tested before ; we got to this function. The three sheets are as follows.but don't have ; to be in any special order: ; ; - one without any barcodes, which must report TWRC_DATANOTAVAILABLE ; ; - one with a single barcode, which must report TWRC_SUCCESS for all ; of the TWEI_BARCODE* items, and put the data in a TW_HANDLE ; ; - one with multiple barcodes; which must report TWRC_SUCCESS for all ; of the TWEI_BARCODE* items, and return a TW_HANDLE that contains ; an array of TW_HANDLE value, each of which points to barcode data; ; if the scanner cannot return multiple barcodes, it still passes ; ; Here's the basic flow: ; SetCapabilities ; start scanning ; while images ; transfer image ; DAT_EXTIMAGEINFO ; end image ; end ; end scanning ; verify the results ; ; The test passes if: ; - g_barcodecount.none >= 1 ; and (((barcodemaxsearchpriorities.max > 1) and (g_barcodecount.one >= 1) and (g_barcodecount.many >= 1)) ; or ((barcodemaxsearchpriorities.max == 1) and (g_barcodecount.one >= 2) and (g_barcodecount.many == 0))) ; ; Arguments ; arg:1 - TW_IDENTITY.ProductName of scanner to test ; arg:2 - test name for the image folder ; ; Globals ; g_barcodemaxsearchpriorities.max - maximum barcodes we can get ; g_barcodecount.none - increment if no barcodes are found ; g_barcodecount.one - increment if one barcodes is found ; g_barcodecount.many - increment if many barcodes are found ; ; Locals ; name - current test being done ; indent - indent the passfail text ; twimageinfo.compression - compression for current image ; ; image.count - count of images from 1 ; image.folder - folder to put the images in ; ; feederenabled.list - scanner's feederenabled values ; feederenabled.index - index of feederenabled values ; feederenabled.value - current feederenabled value ; ; pixeltype.list - scanner's pixeltype values for this feederenabled ; pixeltype.index - index of pixeltype values ; pixeltype.value - current pixeltype value ; ; Returns ; pass/fail ; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; If not supported, quietly leave... ; if '${get:g_xfermech}' ~contains 'TWSX_FILE' goto MAIN.CONTINUE return 'pass' :MAIN.CONTINUE ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Initialize... ; echo.titletest 'DAT_IMAGEFILEXFER' ; setlocal indent '' setlocal image.count '0' setlocal image.folder '${folder:certimages}/${arg:2}/DAT_IMAGEFILEXFER' setlocal image.showname '' ; setglobal g_barcodemaxsearchpriorities.max '0' setglobal g_barcodecount.none '0' setglobal g_barcodecount.one '0' setglobal g_barcodecount.many '0' ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Clean the image folder for this test... ; image cleanfolderandmeta '${get:image.folder}' ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; SetCapabilities ; This resets the driver and sets all the capabilities we need for the test. ; If its return code is not 'pass', end with an error ; run SetCapabilities 'TWSX_FILE' '${get:indent}' if '${ret:}' != 'pass' goto MAIN.ERROR.FAIL ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Prompt the user... ; echo.prompt echo.prompt "Scanning will take place during this test. There will be no" echo.prompt "need to press any button on the TWAIN user interface to start" echo.prompt "the scanner. A progress indicator may appear during scanning." echo.prompt echo.prompt "Place 3 sheets in the scanner's feeder in no particular order:" echo.prompt "one sheet has no barcodes, one has a single barcode that the" echo.prompt "scanner is known to recognize, and one has multiple barcodes" echo.prompt "that scanner is known to recognize. If the scanner is only" echo.prompt "able to see one barcode at a time it can still pass the test." echo.prompt pause '(press the ENTER key when ready to continue)' echo.prompt ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Start scanning... ; :MAIN.USERINTERFACE setlocal name 'dg_control/dat_userinterface/msg_enableds' wait reset dsmentry src null dg_control dat_userinterface msg_enableds '0,0' if '${sts:}' != 'SUCCESS' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Wait for MSG_XFERREADY, if we don't see it then scoot... ; setlocal name 'wait ${get:sys_waittimeout} seconds for MSG_XFERREADY' wait '${get:sys_waittimeout}000' if '${ret:}' !~contains 'msg_xferready' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Get information about the image... ; :MAIN.IMAGEINFO.NEXT setlocal name 'dg_image/dat_imageinfo/msg_get' dsmentry src ds dg_image dat_imageinfo msg_get '0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0' if '${sts:}' != 'SUCCESS' goto MAIN.ERROR.ECHOPASSFAIL setlocal twimageinfo.compression '${ret:${get:index.twimageinfo.compression}}' echo.passfail '${get:indent}${get:name}' 'pass' ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Set up the file transfer... ; increment image.count '${get:image.count}' 1 if '${get:twimageinfo.compression}' == 'JPEG' goto MAIN.SETUPFILEXFER.JPEG setlocal image.showname 'DAT_IMAGEFILEXFER/adf${format:D6|${get:image.count}}.tif' setlocal twsetupfilexfer.filename '${get:image.folder}/adf${format:D6|${get:image.count}}.tif' setlocal twsetupfilexfer.format 'TWFF_TIFF' goto MAIN.SETUPFILEXFER :MAIN.SETUPFILEXFER.JPEG setlocal image.showname 'DAT_IMAGEFILEXFER/adf${format:D6|${get:image.count}}.jpg' setlocal twsetupfilexfer.filename '${get:image.folder}/adf${format:D6|${get:image.count}}.jpg' setlocal twsetupfilexfer.format 'TWFF_JFIF' :MAIN.SETUPFILEXFER setlocal name 'dg_control/dat_setupfilexfer/msg_set' dsmentry src ds dg_control dat_setupfilexfer msg_set '"${get:twsetupfilexfer.filename}",${get:twsetupfilexfer.format},0' if '${sts:}' != 'SUCCESS' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Transfer the image... ; setlocal name 'dg_image/dat_imagefilexfer/msg_get' dsmentry src ds dg_image dat_imagefilexfer msg_get null if '${sts:}' != 'XFERDONE' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' echo.passfail '${get:indent}image <${get:image.showname}>' 'pass' ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; DAT_EXTIMAGEINFO ; Check the barcode metadata... ; run DAT_EXTIMAGEINFO '${get:indent}' '${get:image.folder}/adf${format:D6|${get:image.count}}' if '${ret:}' != 'pass' goto MAIN.ERROR.FAIL ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; End the transfer, see if we're done... ; setlocal name 'dg_control/dat_pendingxfers/msg_endxfer' dsmentry src ds dg_control dat_pendingxfers msg_endxfer '0,0' if '${sts:}' != 'SUCCESS' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' if '${ret:${get:TW_PENDINGXFERS.Count}}' != '0' goto MAIN.IMAGEINFO.NEXT ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; We're out of images, so disable... ; setlocal name 'dg_control/dat_userinterface/msg_disableds' dsmentry src ds dg_control dat_userinterface msg_disableds '0,0' if '${sts:}' != 'SUCCESS' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Check to see if we passed. We need one sheet of paper with no barcodes. Two or more sheets ; with one barcode, and no sheets with multiple barecodes if the maximum value of ; ICAP_BARCODEMAXSEARCHPRIORITIES is 1. And one or more sheets with one barcode, and one or ; more sheets with multiple barcodes of ICAP_BARCODEMAXSEARCHPRIORITIES is greater than 1. ; setlocal name 'Final Check: detected a sheet with 0 barcodes if '${get:g_barcodecount.none}' < '1' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' ; if '${get:g_barcodemaxsearchpriorities.max}' >= '2' goto MAIN.FINALCHECK.MANYBARCODES setlocal name 'Final Check: detected multiple sheets with 1 barcode' if '${get:g_barcodecount.one}' < '1' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' setlocal name 'Final Check: detected 0 sheets with many barcodes (not supported)' if '${get:g_barcodecount.many}' > '0' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' goto MAIN.FINALCHECK.DONE ; :MAIN.FINALCHECK.MANYBARCODES setlocal name 'Final Check: detected a sheet with 1 barcode' if '${get:g_barcodecount.one}' < '1' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' setlocal name 'Final Check: detected a sheet with many barcodes' if '${get:g_barcodecount.many}' < '1' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' :MAIN.FINALCHECK.DONE ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Summary and cleanup... ; ; We passed... :MAIN.PASS echo.passfail 'SUMMARY' 'pass' return 'pass' ; ; Ruh-roh... :MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'fail - ${sts:} ${ret:}' echo.passfail 'SUMMARY' 'fail' return 'fail' ; ; Ruh-roh... :MAIN.ERROR.FAIL echo.passfail 'SUMMARY' 'fail' return 'fail' ================================================ FILE: twaincs/source/twaincscert/source/data/certification/130 - Barcode Badge/DAT_IMAGEMEMFILEXFER.tc ================================================ ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; DAT_IMAGEMEMFILEXFER ; This test scans three sheets of paper for the default pixeltype. An ADF ; is required to pass this test, but that was already been tested before ; we got to this function. The three sheets are as follows.but don't have ; to be in any special order: ; ; - one without any barcodes, which must report TWRC_DATANOTAVAILABLE ; ; - one with a single barcode, which must report TWRC_SUCCESS for all ; of the TWEI_BARCODE* items, and put the data in a TW_HANDLE ; ; - one with multiple barcodes; which must report TWRC_SUCCESS for all ; of the TWEI_BARCODE* items, and return a TW_HANDLE that contains ; an array of TW_HANDLE value, each of which points to barcode data; ; if the scanner cannot return multiple barcodes, it still passes ; ; Here's the basic flow: ; SetCapabilities ; start scanning ; while images ; transfer image ; DAT_EXTIMAGEINFO ; end image ; end ; end scanning ; verify the results ; ; The test passes if: ; - g_barcodecount.none >= 1 ; and (((barcodemaxsearchpriorities.max > 1) and (g_barcodecount.one >= 1) and (g_barcodecount.many >= 1)) ; or ((barcodemaxsearchpriorities.max == 1) and (g_barcodecount.one >= 2) and (g_barcodecount.many == 0))) ; ; Arguments ; arg:1 - TW_IDENTITY.ProductName of scanner to test ; arg:2 - test name for the image folder ; ; Globals ; g_barcodemaxsearchpriorities.max - maximum barcodes we can get ; g_barcodecount.none - increment if no barcodes are found ; g_barcodecount.one - increment if one barcodes is found ; g_barcodecount.many - increment if many barcodes are found ; ; Locals ; name - current test being done ; indent - indent the passfail text ; imagememxfer - result of DAT_IMAGEMEMXFER call ; setupmemxfer.preferred - preferred field from DAT_SETUPMEMXFER call ; ; image.count - count of images from 1 ; image.folder - folder to put the images in ; ; feederenabled.list - scanner's feederenabled values ; feederenabled.index - index of feederenabled values ; feederenabled.value - current feederenabled value ; ; pixeltype.list - scanner's pixeltype values for this feederenabled ; pixeltype.index - index of pixeltype values ; pixeltype.value - current pixeltype value ; ; Returns ; pass/fail ; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; If not supported, quietly leave... ; if '${get:g_xfermech}' ~contains 'TWSX_MEMFILE' goto MAIN.CONTINUE return 'pass' :MAIN.CONTINUE ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Initialize... ; echo.titletest 'DAT_IMAGEMEMFILEXFER' ; setlocal indent '' setlocal image.pointer '0' setlocal image.count '0' setlocal image.folder '${folder:certimages}/${arg:2}/DAT_IMAGEMEMFILEXFER' ; setglobal g_barcodemaxsearchpriorities.max '0' setglobal g_barcodecount.none '0' setglobal g_barcodecount.one '0' setglobal g_barcodecount.many '0' ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Clean the image folder for this test... ; image cleanfolderandmeta '${get:image.folder}' ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; SetCapabilities ; This resets the driver and sets all the capabilities we need for the test. ; If its return code is not 'pass', end with an error ; run SetCapabilities 'TWSX_MEMFILE' '${get:indent}' if '${ret:}' != 'pass' goto MAIN.ERROR.FAIL ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Get the preferred size for memory transfers, and allocate ; a pointer for the memory transfers... ; setlocal indent ' ' setlocal name 'dg_control/dat_setupmemxfer/msg_get' dsmentry src ds dg_control dat_setupmemxfer msg_get '0,0,0' if '${sts:}' != 'SUCCESS' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' ; setlocal name 'TW_SETUPMEMXFER.Preferred > 0' setlocal setupmemxfer.preferred '${ret:${get:TW_SETUPMEMXFER.Preferred}}' if '${get:setupmemxfer.preferred}' <= '0' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' ; setlocal name 'allocate pointer for ${get:setupmemxfer.preferred} bytes' free pointer image.pointer ; for the last loop allocate pointer image.pointer '${get:setupmemxfer.preferred}' if '${get:image.pointer}' == '0' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Set DAT_SETUPFILEXFER to TWFF_TIFF ; setlocal name 'dg_control/dat_setupfilexfer/msg_set TWFF_TIFF' dsmentry src null dg_control dat_setupfilexfer msg_set 'file,TWFF_TIFF,0' if '${sts:}' != 'SUCCESS' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Prompt the user... ; echo.prompt echo.prompt "Scanning will take place during this test. There will be no" echo.prompt "need to press any button on the TWAIN user interface to start" echo.prompt "the scanner. A progress indicator may appear during scanning." echo.prompt echo.prompt "Place 3 sheets in the scanner's feeder in no particular order:" echo.prompt "one sheet has no barcodes, one has a single barcode that the" echo.prompt "scanner is known to recognize, and one has multiple barcodes" echo.prompt "that scanner is known to recognize. If the scanner is only" echo.prompt "able to see one barcode at a time it can still pass the test." echo.prompt pause '(press the ENTER key when ready to continue)' echo.prompt ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Start scanning... ; :MAIN.USERINTERFACE setlocal name 'dg_control/dat_userinterface/msg_enableds' wait reset dsmentry src null dg_control dat_userinterface msg_enableds '0,0' if '${sts:}' != 'SUCCESS' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Wait for MSG_XFERREADY, if we don't see it then scoot... ; setlocal name 'wait ${get:sys_waittimeout} seconds for MSG_XFERREADY' wait '${get:sys_waittimeout}000' if '${ret:}' !~contains 'msg_xferready' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Do a memory file transfer... ; This little song and dance with the states is so that we can ; start the transfer in state 6 with each new image, but switch ; to state 7 if we need multiple calls to capture the current ; image... ; ; The saved images will be in TIFF format, which includes TIFF ; JPEG (the better form, where a simple TIFF header is added). ; increment image.count '${get:image.count}' 1 image free memfileimage ; :MAIN.IMAGEMEMFILEXFER.NEXT setlocal name 'dg_image/dat_imagememxfer/msg_get' dsmentry src ds dg_image dat_imagememfilexfer msg_get '0,0,0,0,0,0,0,9,${get:setupmemxfer.preferred},${get:image.pointer}' setlocal imagememxfer '${ret:}' if '${sts:}' == 'XFERDONE' goto MAIN.IMAGEMEMFILEXFER.XFERDONE if '${sts:}' != 'SUCCESS' goto MAIN.ERROR.ECHOPASSFAIL ; echo.passfail '${get:indent}${get:name} SUCCESS' 'pass' image append memfileimage '${get:imagememxfer}' goto MAIN.IMAGEMEMFILEXFER.NEXT ; :MAIN.IMAGEMEMFILEXFER.XFERDONE echo.passfail '${get:indent}${get:name} XFERDONE' 'pass' image append memfileimage '${get:imagememxfer}' image save memfileimage memfile '${get:image.folder}/adf${format:D6|${get:image.count}}' echo.passfail '${get:indent}image <${ret:}>' 'pass' image free memfileimage ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; DAT_EXTIMAGEINFO ; Check the barcode metadata... ; run DAT_EXTIMAGEINFO '${get:indent}' '${get:image.folder}/adf${format:D6|${get:image.count}}' if '${ret:}' != 'pass' goto MAIN.ERROR.FAIL ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; End the transfer, see if we're done... ; setlocal name 'dg_control/dat_pendingxfers/msg_endxfer' dsmentry src ds dg_control dat_pendingxfers msg_endxfer '0,0' if '${sts:}' != 'SUCCESS' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' increment image.count '${get:image.count}' 1 if '${ret:${get:TW_PENDINGXFERS.Count}}' != '0' goto MAIN.IMAGEMEMFILEXFER.NEXT ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; We're out of images, so disable... ; setlocal name 'dg_control/dat_userinterface/msg_disableds' dsmentry src ds dg_control dat_userinterface msg_disableds '0,0' if '${sts:}' != 'SUCCESS' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Check to see if we passed. We need one sheet of paper with no barcodes. Two or more sheets ; with one barcode, and no sheets with multiple barecodes if the maximum value of ; ICAP_BARCODEMAXSEARCHPRIORITIES is 1. And one or more sheets with one barcode, and one or ; more sheets with multiple barcodes of ICAP_BARCODEMAXSEARCHPRIORITIES is greater than 1. ; setlocal name 'Final Check: detected a sheet with 0 barcodes if '${get:g_barcodecount.none}' < '1' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' ; if '${get:g_barcodemaxsearchpriorities.max}' >= '2' goto MAIN.FINALCHECK.MANYBARCODES setlocal name 'Final Check: detected multiple sheets with 1 barcode' if '${get:g_barcodecount.one}' < '1' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' setlocal name 'Final Check: detected 0 sheets with many barcodes (not supported)' if '${get:g_barcodecount.many}' > '0' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' goto MAIN.FINALCHECK.DONE ; :MAIN.FINALCHECK.MANYBARCODES setlocal name 'Final Check: detected a sheet with 1 barcode' if '${get:g_barcodecount.one}' < '1' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' setlocal name 'Final Check: detected a sheet with many barcodes' if '${get:g_barcodecount.many}' < '1' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' :MAIN.FINALCHECK.DONE ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Summary and cleanup... ; ; We passed... :MAIN.PASS image free memfileimage free pointer image.pointer echo.passfail 'SUMMARY' 'pass' return 'pass' ; ; Ruh-roh... :MAIN.ERROR.ECHOPASSFAIL image free memfileimage free pointer image.pointer echo.passfail '${get:indent}${get:name}' 'fail - ${sts:} ${ret:}' echo.passfail 'SUMMARY' 'fail' return 'fail' ; ; Ruh-roh... :MAIN.ERROR.FAIL image free memfileimage free pointer image.pointer echo.passfail 'SUMMARY' 'fail' return 'fail' ================================================ FILE: twaincs/source/twaincscert/source/data/certification/130 - Barcode Badge/DAT_IMAGEMEMXFER.tc ================================================ ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; DAT_IMAGEMEMXFER ; This test scans three sheets of paper for the default pixeltype. An ADF ; is required to pass this test, but that was already been tested before ; we got to this function. The three sheets are as follows.but don't have ; to be in any special order: ; ; - one without any barcodes, which must report TWRC_DATANOTAVAILABLE ; ; - one with a single barcode, which must report TWRC_SUCCESS for all ; of the TWEI_BARCODE* items, and put the data in a TW_HANDLE ; ; - one with multiple barcodes; which must report TWRC_SUCCESS for all ; of the TWEI_BARCODE* items, and return a TW_HANDLE that contains ; an array of TW_HANDLE value, each of which points to barcode data; ; if the scanner cannot return multiple barcodes, it still passes ; ; Here's the basic flow: ; SetCapabilities ; start scanning ; while images ; transfer image ; DAT_EXTIMAGEINFO ; end image ; end ; end scanning ; verify the results ; ; The test passes if: ; - g_barcodecount.none >= 1 ; and (((barcodemaxsearchpriorities.max > 1) and (g_barcodecount.one >= 1) and (g_barcodecount.many >= 1)) ; or ((barcodemaxsearchpriorities.max == 1) and (g_barcodecount.one >= 2) and (g_barcodecount.many == 0))) ; ; Arguments ; arg:1 - TW_IDENTITY.ProductName of scanner to test ; arg:2 - test name for the image folder ; ; Globals ; g_barcodemaxsearchpriorities.max - maximum barcodes we can get ; g_barcodecount.none - increment if no barcodes are found ; g_barcodecount.one - increment if one barcodes is found ; g_barcodecount.many - increment if many barcodes are found ; ; Locals ; name - current test being done ; indent - indent the passfail text ; imageinfo - metadata for the current image ; imagememxfer - result of DAT_IMAGEMEMXFER call ; setupmemxfer.preferred - preferred field from DAT_SETUPMEMXFER call ; ; image.count - count of images from 1 ; image.folder - folder to put the images in ; ; feederenabled.list - scanner's feederenabled values ; feederenabled.index - index of feederenabled values ; feederenabled.value - current feederenabled value ; ; pixeltype.list - scanner's pixeltype values for this feederenabled ; pixeltype.index - index of pixeltype values ; pixeltype.value - current pixeltype value ; ; Returns ; pass/fail ; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Initialize... ; echo.titletest 'DAT_IMAGEMEMXFER' ; setlocal indent '' setlocal image.pointer '0' setlocal image.count '0' setlocal image.folder '${folder:certimages}/${arg:2}/DAT_IMAGEMEMXFER' ; setglobal g_barcodemaxsearchpriorities.max '0' setglobal g_barcodecount.none '0' setglobal g_barcodecount.one '0' setglobal g_barcodecount.many '0' ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Clean the image folder for this test... ; image cleanfolderandmeta '${get:image.folder}' ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; SetCapabilities ; This resets the driver and sets all the capabilities we need for the test. ; If its return code is not 'pass', end with an error ; run SetCapabilities 'TWSX_MEMORY' '${get:indent}' if '${ret:}' != 'pass' goto MAIN.ERROR.FAIL ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Get the preferred size for memory transfers, and allocate ; a pointer for the memory transfers... ; setlocal indent ' ' setlocal name 'dg_control/dat_setupmemxfer/msg_get' dsmentry src ds dg_control dat_setupmemxfer msg_get '0,0,0' if '${sts:}' != 'SUCCESS' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' ; setlocal name 'TW_SETUPMEMXFER.Preferred > 0' setlocal setupmemxfer.preferred '${ret:${get:TW_SETUPMEMXFER.Preferred}}' if '${get:setupmemxfer.preferred}' <= '0' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' ; setlocal name 'allocate pointer for ${get:setupmemxfer.preferred} bytes' free pointer image.pointer ; for the last loop allocate pointer image.pointer '${get:setupmemxfer.preferred}' if '${get:image.pointer}' == '0' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Prompt the user... ; echo.prompt echo.prompt "Scanning will take place during this test. There will be no" echo.prompt "need to press any button on the TWAIN user interface to start" echo.prompt "the scanner. A progress indicator may appear during scanning." echo.prompt echo.prompt "Place 3 sheets in the scanner's feeder in no particular order:" echo.prompt "one sheet has no barcodes, one has a single barcode that the" echo.prompt "scanner is known to recognize, and one has multiple barcodes" echo.prompt "that scanner is known to recognize. If the scanner is only" echo.prompt "able to see one barcode at a time it can still pass the test." echo.prompt pause '(press the ENTER key when ready to continue)' echo.prompt ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Start scanning... ; :MAIN.USERINTERFACE setlocal name 'dg_control/dat_userinterface/msg_enableds' wait reset dsmentry src null dg_control dat_userinterface msg_enableds '0,0' if '${sts:}' != 'SUCCESS' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Wait for MSG_XFERREADY, if we don't see it then scoot... ; setlocal name 'wait ${get:sys_waittimeout} seconds for MSG_XFERREADY' wait '${get:sys_waittimeout}000' if '${ret:}' !~contains 'msg_xferready' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Do a memory transfer... ; This little song and dance with the states is so that we can ; start the transfer in state 6 with each new image, but switch ; to state 7 if we need multiple calls to capture the current ; image... ; ; The saved images will be in TIFF format, which includes TIFF ; JPEG (the better form, where a simple TIFF header is added). ; increment image.count '${get:image.count}' 1 image free memimage ; :MAIN.IMAGEMEMXFER.NEXT setlocal name 'dg_image/dat_imagememxfer/msg_get' dsmentry src ds dg_image dat_imagememxfer msg_get '0,0,0,0,0,0,0,9,${get:setupmemxfer.preferred},${get:image.pointer}' setlocal imagememxfer '${ret:}' if '${sts:}' == 'XFERDONE' goto MAIN.IMAGEMEMXFER.XFERDONE if '${sts:}' != 'SUCCESS' goto MAIN.ERROR.ECHOPASSFAIL ; echo.passfail '${get:indent}${get:name} SUCCESS' 'pass' image append memimage '${get:imagememxfer}' goto MAIN.IMAGEMEMXFER.NEXT ; :MAIN.IMAGEMEMXFER.XFERDONE echo.passfail '${get:indent}${get:name} XFERDONE' 'pass' ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; We need image info to make sense of this data... ; setlocal name 'dg_image/dat_imageinfo/msg_get' dsmentry src ds dg_image dat_imageinfo msg_get '0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0' setlocal imageinfo '${ret:}' if '${sts:}' != 'SUCCESS' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Save the image... ; image append memimage '${get:imagememxfer}' image addheader memimage '${get:imageinfo}' image save memimage memory '${get:image.folder}/adf${format:D6|${get:image.count}}' echo.passfail '${get:indent}image <${ret:}>' 'pass' image free memimage ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; DAT_EXTIMAGEINFO ; Check the barcode metadata... ; run DAT_EXTIMAGEINFO '${get:indent}' '${get:image.folder}/adf${format:D6|${get:image.count}}' if '${ret:}' != 'pass' goto MAIN.ERROR.FAIL ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; End the transfer, see if we're done... ; setlocal name 'dg_control/dat_pendingxfers/msg_endxfer' dsmentry src ds dg_control dat_pendingxfers msg_endxfer '0,0' if '${sts:}' != 'SUCCESS' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' increment image.count '${get:image.count}' 1 if '${ret:${get:TW_PENDINGXFERS.Count}}' != '0' goto MAIN.IMAGEMEMXFER.NEXT ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; We're out of images, so disable... ; setlocal name 'dg_control/dat_userinterface/msg_disableds' dsmentry src ds dg_control dat_userinterface msg_disableds '0,0' if '${sts:}' != 'SUCCESS' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Check to see if we passed. We need one sheet of paper with no barcodes. Two or more sheets ; with one barcode, and no sheets with multiple barecodes if the maximum value of ; ICAP_BARCODEMAXSEARCHPRIORITIES is 1. And one or more sheets with one barcode, and one or ; more sheets with multiple barcodes of ICAP_BARCODEMAXSEARCHPRIORITIES is greater than 1. ; setlocal name 'Final Check: detected a sheet with 0 barcodes if '${get:g_barcodecount.none}' < '1' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' ; if '${get:g_barcodemaxsearchpriorities.max}' >= '2' goto MAIN.FINALCHECK.MANYBARCODES setlocal name 'Final Check: detected multiple sheets with 1 barcode' if '${get:g_barcodecount.one}' < '1' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' setlocal name 'Final Check: detected 0 sheets with many barcodes (not supported)' if '${get:g_barcodecount.many}' > '0' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' goto MAIN.FINALCHECK.DONE ; :MAIN.FINALCHECK.MANYBARCODES setlocal name 'Final Check: detected a sheet with 1 barcode' if '${get:g_barcodecount.one}' < '1' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' setlocal name 'Final Check: detected a sheet with many barcodes' if '${get:g_barcodecount.many}' < '1' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' :MAIN.FINALCHECK.DONE ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Summary and cleanup... ; ; We passed... :MAIN.PASS image free memimage free pointer image.pointer echo.passfail 'SUMMARY' 'pass' return 'pass' ; ; Ruh-roh... :MAIN.ERROR.ECHOPASSFAIL image free memimage free pointer image.pointer echo.passfail '${get:indent}${get:name}' 'fail - ${sts:} ${ret:}' echo.passfail 'SUMMARY' 'fail' return 'fail' ; ; Ruh-roh... :MAIN.ERROR.FAIL image free memimage free pointer image.pointer echo.passfail 'SUMMARY' 'fail' return 'fail' ================================================ FILE: twaincs/source/twaincscert/source/data/certification/130 - Barcode Badge/DAT_IMAGENATIVEXFER.tc ================================================ ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; DAT_IMAGENATIVEXFER ; This test scans three sheets of paper for the default pixeltype. An ADF ; is required to pass this test, but that was already been tested before ; we got to this function. The three sheets are as follows.but don't have ; to be in any special order: ; ; - one without any barcodes, which must report TWRC_DATANOTAVAILABLE ; ; - one with a single barcode, which must report TWRC_SUCCESS for all ; of the TWEI_BARCODE* items, and put the data in a TW_HANDLE ; ; - one with multiple barcodes; which must report TWRC_SUCCESS for all ; of the TWEI_BARCODE* items, and return a TW_HANDLE that contains ; an array of TW_HANDLE value, each of which points to barcode data; ; if the scanner cannot return multiple barcodes, it still passes ; ; Here's the basic flow: ; SetCapabilities ; start scanning ; while images ; transfer image ; DAT_EXTIMAGEINFO ; end image ; end ; end scanning ; verify the results ; ; The test passes if: ; - g_barcodecount.none >= 1 ; and (((barcodemaxsearchpriorities.max > 1) and (g_barcodecount.one >= 1) and (g_barcodecount.many >= 1)) ; or ((barcodemaxsearchpriorities.max == 1) and (g_barcodecount.one >= 2) and (g_barcodecount.many == 0))) ; ; Arguments ; arg:1 - TW_IDENTITY.ProductName of scanner to test ; arg:2 - test name for the image folder ; ; Globals ; g_barcodemaxsearchpriorities.max - maximum barcodes we can get ; g_barcodecount.none - increment if no barcodes are found ; g_barcodecount.one - increment if one barcodes is found ; g_barcodecount.many - increment if many barcodes are found ; ; Locals ; name - current test being done ; indent - indent the passfail text ; image.handle - native handle ; image.count - count of images from 1 ; image.folder - folder to put the images in ; ; Returns ; pass/fail ; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Initialize... ; echo.titletest 'DAT_IMAGENATIVEXFER' ; setlocal indent '' setlocal image.handle '0' setlocal image.count '1' setlocal image.folder '${folder:certimages}/${arg:2}/DAT_IMAGENATIVEXFER' ; setglobal g_barcodemaxsearchpriorities.max '0' setglobal g_barcodecount.none '0' setglobal g_barcodecount.one '0' setglobal g_barcodecount.many '0' ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Prompt the user... ; echo.prompt echo.prompt "Scanning will take place during this test. There will be no" echo.prompt "need to press any button on the TWAIN user interface to start" echo.prompt "the scanner. A progress indicator may appear during scanning." echo.prompt echo.prompt "Place 3 sheets in the scanner's feeder in no particular order:" echo.prompt "one sheet has no barcodes, one has a single barcode that the" echo.prompt "scanner is known to recognize, and one has multiple barcodes" echo.prompt "that scanner is known to recognize. If the scanner is only" echo.prompt "able to see one barcode at a time it can still pass the test." echo.prompt pause '(press the ENTER key when ready to continue)' echo.prompt ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Clean the image folder for this test... ; image cleanfolderandmeta '${get:image.folder}' ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; SetCapabilities ; This resets the driver and sets all the capabilities we need for the test. ; If its return code is not 'pass', end with an error ; run SetCapabilities 'TWSX_NATIVE' '${get:indent}' if '${ret:}' != 'pass' goto MAIN.ERROR.FAIL ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Check for paper in the feeder, prompt the user if we don't find any... ; :MAIN.FEEDERLOADED dsmentry src ds dg_control dat_capability msg_getcurrent 'CAP_FEEDERLOADED,0,0,0' if '${sts:}' != 'SUCCESS' goto MAIN.FEEDERLOADED.DONE if '${ret:${get:TW_ONEVALUE.Item}}' ~~ 'TRUE' goto MAIN.FEEDERLOADED.DONE echo.prompt echo.prompt "Place paper in the scanner's feeder." pause '(press the ENTER key when ready to continue)' :MAIN.FEEDERLOADED.DONE ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Start scanning... ; setlocal indent ' ' setlocal name 'dg_control/dat_userinterface/msg_enableds' wait reset dsmentry src null dg_control dat_userinterface msg_enableds '0,0' if '${sts:}' != 'SUCCESS' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Wait for MSG_XFERREADY, if we don't see it then scoot... ; setlocal name 'wait ${get:sys_waittimeout} seconds for MSG_XFERREADY' wait '${get:sys_waittimeout}000' if '${ret:}' !~contains 'msg_xferready' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Do a native transfer... ; :MAIN.IMAGENATIVEXFER.NEXT setlocal indent ' ' setlocal name 'dg_control/dat_imagenativexfer/msg_get' dsmentry src ds dg_image dat_imagenativexfer msg_get '0' setlocal image.handle '${ret:}' if '${sts:}' != 'XFERDONE' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' image save image.handle native '${get:image.folder}/adf${format:D6|${get:image.count}}' echo.passfail '${get:indent}image <${ret:}>' 'pass' free handle image.handle ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; DAT_EXTIMAGEINFO ; Check the barcode metadata... ; run DAT_EXTIMAGEINFO '${get:indent}' '${get:image.folder}/adf${format:D6|${get:image.count}}' if '${ret:}' != 'pass' goto MAIN.ERROR.FAIL ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; End the transfer, see if we're done. If not, go back ; to MAIN.IMAGENATIVEXFER.NEXT for another image... ; :MAIN.PENDINGXFERS setlocal name 'dg_control/dat_pendingxfers/msg_endxfer' dsmentry src ds dg_control dat_pendingxfers msg_endxfer '0,0' if '${sts:}' != 'SUCCESS' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' increment image.count '${get:image.count}' 1 ; count the image if '${ret:${get:TW_PENDINGXFERS.Count}}' != '0' goto MAIN.IMAGENATIVEXFER.NEXT ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; We're out of images, so disable... ; setlocal name 'dg_control/dat_userinterface/msg_disableds' dsmentry src ds dg_control dat_userinterface msg_disableds '0,0' if '${sts:}' != 'SUCCESS' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Check to see if we passed. We need one sheet of paper with no barcodes. Two or more sheets ; with one barcode, and no sheets with multiple barecodes if the maximum value of ; ICAP_BARCODEMAXSEARCHPRIORITIES is 1. And one or more sheets with one barcode, and one or ; more sheets with multiple barcodes of ICAP_BARCODEMAXSEARCHPRIORITIES is greater than 1. ; setlocal name 'Final Check: detected a sheet with 0 barcodes if '${get:g_barcodecount.none}' < '1' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' ; if '${get:g_barcodemaxsearchpriorities.max}' >= '2' goto MAIN.FINALCHECK.MANYBARCODES setlocal name 'Final Check: detected multiple sheets with 1 barcode' if '${get:g_barcodecount.one}' < '1' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' setlocal name 'Final Check: detected 0 sheets with many barcodes (not supported)' if '${get:g_barcodecount.many}' > '0' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' goto MAIN.FINALCHECK.DONE ; :MAIN.FINALCHECK.MANYBARCODES setlocal name 'Final Check: detected a sheet with 1 barcode' if '${get:g_barcodecount.one}' < '1' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' setlocal name 'Final Check: detected a sheet with many barcodes' if '${get:g_barcodecount.many}' < '1' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' :MAIN.FINALCHECK.DONE ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Summary and cleanup... ; ; We passed... :MAIN.PASS free handle image.handle echo.passfail 'SUMMARY' 'pass' return 'pass' ; ; Ruh-roh... :MAIN.ERROR.ECHOPASSFAIL free handle image.handle echo.passfail '${get:indent}${get:name}' 'fail - ${sts:} ${ret:}' echo.passfail 'SUMMARY' 'fail' return 'fail' ; ; Ruh-roh... :MAIN.ERROR.FAIL free handle image.handle echo.passfail 'SUMMARY' 'fail' return 'fail' ================================================ FILE: twaincs/source/twaincscert/source/data/certification/130 - Barcode Badge/SetCapabilities.tc ================================================ ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; SetCapabilities ; Reset the driver's capabilites, and then set capabilities for this test. Note that one can only ; get this badge for the ADF. This is a production mode feature, so we're not testing the flatbed. ; ; We follow the capability ordering: ; MSG_RESETALL ; set ICAP_XFERMECH.....................${arg:1} ; set CAP_FEEDERENABLED.................TRUE ; set CAP_XFERCOUNT.....................-1 ; set ICAP_EXTIMAGEINFO.................TRUE ; set ICAP_BARCODETECTIONENABLED........TRUE ; set ICAP_BARCODESEARCHMODE............TWBD_HORZVERT, TWBD_VERTHORZ, TWBD_HORZ, or TWBD_VERT ; set ICAP_BARCODEMAXSEARCHPRIORITIES...set to its max value ; get ICAP_SUPPORTEDBARCODETYPES ; set ICAP_BARCODESEARCHPRIORITIES......set to first ICAP_BARCODEMAXSEARCHPRIORITIES of ICAP_SUPPORTEDBARCODETYPES ; ; The test passes if all operations return TWRC_SUCCESS. ; ; We are not testing ICAP_BARCODEMAXRETRIES or ICAP_BARCODETIMEOUT. We're going to assume that the driver's ; default values offer the best user experience. ICAP_BARCODETIMEOUT is especially problematic, since the ; spec doesn't tell use the units. We're also not testing TWEI_BARCODETEXT, since it was replaced by the better ; defined TWEI_BARCODETEXT2. ; ; Arguments ; arg:1 - TWSX_* value for ICAP_XFERMECH ; arg:2 - value of caller's indent ; ; Globals ; g_barcodemaxsearchpriorities.max - maximum barcodes we can get (max of ICAP_BARCODEMAXSEARCHPRIORITIES) ; ; Locals ; barcodesearchpriorities.itemlist - first ICAP_BARCODEMAXSEARCHPRIORITIES of ICAP_SUPPORTEDBARCODETYPES ; comma - used to construct the value for ICAP_BARCODESEARCHPRIORITIES ; indent - indent the passfail text ; name - name of the current test ; supportedbarcodetypes.itemlist - return value from MSG_GET of ICAP_SUPPORTEDBARCODETYPES ; supportedbarcodetypes.index - index counter for ICAP_SUPPORTEDBARCODETYPES ; supportedbarcodetypes.lastindex - index of ICAP_BARCODEMAXSEARCHPRIORITIES item in ICAP_SUPPORTEDBARCODETYPES ; twsx - TWSX_* value for ICAP_XFERMECH ; ; Returns ; pass/fail ; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Initialize... ; setlocal twsx '${arg:1}' setlocal indent '${arg:2}' ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; MSG_RESETALL ; If return code is not TWRC_SUCCESS, end with an error ; setlocal name 'MSG_RESETALL' dsmentry src ds dg_control dat_capability msg_resetall '0,0,0,0' if '${sts:}' != 'SUCCESS' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Set ICAP_XFERMECH... ; setlocal name 'ICAP_XFERMECH MSG_SET ${get:twsx}' dsmentry src ds dg_control dat_capability msg_set 'ICAP_XFERMECH,TWON_ONEVALUE,TWTY_UINT16,${get:twsx}' if '${sts:}' != 'SUCCESS' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Set CAP_FEEDERENABLED to TRUE ; setlocal name 'CAP_FEEDERENABLED MSG_SET TRUE' dsmentry src ds dg_control dat_capability msg_set 'CAP_FEEDERENABLED,TWON_ONEVALUE,TWTY_BOOL,TRUE' if '${sts:}' != 'SUCCESS' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Set CAP_XFERCOUNT to -1 ; setlocal name 'CAP_XFERCOUNT MSG_SET -1' dsmentry src ds dg_control dat_capability msg_set 'CAP_XFERCOUNT,TWON_ONEVALUE,TWTY_INT16,-1' if '${sts:}' != 'SUCCESS' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Set ICAP_EXTIMAGEINFO to TRUE ; setlocal name 'ICAP_EXTIMAGEINFO MSG_SET TRUE' dsmentry src ds dg_control dat_capability msg_set 'ICAP_EXTIMAGEINFO,TWON_ONEVALUE,TWTY_BOOL,TRUE' if '${sts:}' != 'SUCCESS' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Set ICAP_BARCODEDETECTIONENABLED to TRUE ; setlocal name 'ICAP_BARCODEDETECTIONENABLED MSG_SET TRUE' dsmentry src ds dg_control dat_capability msg_set 'ICAP_BARCODEDETECTIONENABLED,TWON_ONEVALUE,TWTY_BOOL,TRUE' if '${sts:}' != 'SUCCESS' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Try to set ICAP_BARCODESEARCHMODE to TWBD_HORZVERT, TWBD_VERTHORZ, TWBD_HORZ, or TWBD_VERT ; setlocal name 'ICAP_BARCODESEARCHMODE MSG_SET TWBD_HORZVERT, TWBD_VERTHORZ, TWBD_HORZ, or TWBD_VERT' dsmentry src ds dg_control dat_capability msg_get 'ICAP_BARCODESEARCHMODE' if '${sts:}' != 'SUCCESS' goto MAIN.ERROR.ECHOPASSFAIL ; if '${ret:}' contains 'TWBD_HORZVERT' goto MAIN.ICAP_BARCODESEARCHMODE.TWBD_HORZVERT if '${ret:}' contains 'TWBD_VERTHORZ' goto MAIN.ICAP_BARCODESEARCHMODE.TWBD_VERTHORZ if '${ret:}' contains 'TWBD_VERT' goto MAIN.ICAP_BARCODESEARCHMODE.TWBD_VERT ; dsmentry src ds dg_control dat_capability msg_set 'ICAP_BARCODESEARCHMODE,TWON_ONEVALUE,TWTY_UINT16,TWBD_HORZ' if '${sts:}' != 'SUCCESS' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' goto MAIN.ICAP_BARCODESEARCHMODE.DONE ; :MAIN.ICAP_BARCODESEARCHMODE.TWBD_HORZVERT dsmentry src ds dg_control dat_capability msg_set 'ICAP_BARCODESEARCHMODE,TWON_ONEVALUE,TWTY_UINT16,TWBD_HORZVERT' if '${sts:}' != 'SUCCESS' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' goto MAIN.ICAP_BARCODESEARCHMODE.DONE ; :MAIN.ICAP_BARCODESEARCHMODE.TWBD_VERTHORZ dsmentry src ds dg_control dat_capability msg_set 'ICAP_BARCODESEARCHMODE,TWON_ONEVALUE,TWTY_UINT16,TWBD_VERTHORZ' if '${sts:}' != 'SUCCESS' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' goto MAIN.ICAP_BARCODESEARCHMODE.DONE ; :MAIN.ICAP_BARCODESEARCHMODE.TWBD_VERT dsmentry src ds dg_control dat_capability msg_set 'ICAP_BARCODESEARCHMODE,TWON_ONEVALUE,TWTY_UINT16,TWBD_VERT' if '${sts:}' != 'SUCCESS' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' goto MAIN.ICAP_BARCODESEARCHMODE.DONE ; :MAIN.ICAP_BARCODESEARCHMODE.DONE ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Try to set ICAP_BARCODEMAXSEARCHPRIORITIES to its maximum value... ; setlocal name 'ICAP_BARCODEMAXSEARCHPRIORITIES MSG_SET max value' dsmentry src ds dg_control dat_capability msg_get 'ICAP_BARCODEMAXSEARCHPRIORITIES' if '${sts:}' != 'SUCCESS' goto MAIN.ERROR.ECHOPASSFAIL setglobal g_barcodemaxsearchpriorities.max '${ret:${get:TW_RANGE.MaxValue}}' dsmentry src ds dg_control dat_capability msg_set 'ICAP_BARCODEMAXSEARCHPRIORITIES,TWON_ONEVALUE,TWTY_UINT32,${get:g_barcodemaxsearchpriorities.max}' if '${sts:}' != 'SUCCESS' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Get the ICAP_SUPPORTEDBARCODETYPES... ; setlocal name 'ICAP_SUPPORTEDBARCODETYPES MSG_GET' dsmentry src ds dg_control dat_capability msg_get 'ICAP_SUPPORTEDBARCODETYPES' if '${sts:}' != 'SUCCESS' goto MAIN.ERROR.ECHOPASSFAIL setlocal supportedbarcodetypes.itemlist '${ret:}' echo.passfail '${get:indent}${get:name}' 'pass' ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Pare the ICAP_SUPPORTEDBARCODETYPES list down to the first ICAP_BARCODEMAXSEARCHPRIORITIES items ; setlocal comma '' setlocal name 'Get the first ${get:g_barcodemaxsearchpriorities.max} from ICAP_SUPPORTEDBARCODETYPES' setlocal barcodesearchpriorities.itemlist '' ; setlocal supportedbarcodetypes.index '${get:TW_ARRAY.NumItems}' ; TW_ARRAY.ItemList - 1 increment supportedbarcodetypes.lastindex '${get:supportedbarcodetypes.index}' 1 ; first index increment supportedbarcodetypes.lastindex '${get:supportedbarcodetypes.lastindex}' ${get:g_barcodemaxsearchpriorities.max} ; + g_barcodemaxsearchpriorities.max ; :MAIN.BARCODESEARCHPRIORITIES.NEXT increment supportedbarcodetypes.index '${get:supportedbarcodetypes.index}' 1 if '${get:supportedbarcodetypes.index}' > '${get:supportedbarcodetypes.lastindex}' goto MAIN.BARCODESEARCHPRIORITIES.DONE setlocal barcodesearchpriorities.value '${getindex:supportedbarcodetypes.itemlist:${get:supportedbarcodetypes.index}}' if '${get:barcodesearchpriorities.value}' == '' goto MAIN.BARCODESEARCHPRIORITIES.DONE setlocal barcodesearchpriorities.itemlist '${get:barcodesearchpriorities.itemlist}${get:comma}${get:barcodesearchpriorities.value}' setlocal comma ',' goto MAIN.BARCODESEARCHPRIORITIES.NEXT ; :MAIN.BARCODESEARCHPRIORITIES.DONE echo.passfail '${get:name}' 'pass' ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Set ICAP_BARCODESEARCHPRIORITIES to first g_barcodemaxsearchpriorities.max of ICAP_SUPPORTEDBARCODETYPES... ; setlocal name 'ICAP_BARCODESEARCHPRIORITIES MSG_SET first ${get:g_barcodemaxsearchpriorities.max} of ICAP_SUPPORTEDBARCODETYPES' dsmentry src ds dg_control dat_capability msg_set 'ICAP_BARCODESEARCHPRIORITIES,TWON_ARRAY,TWTY_UINT16,${get:g_barcodemaxsearchpriorities.max},${get:barcodesearchpriorities.itemlist}' if '${sts:}' != 'SUCCESS' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Summary and cleanup... ; ; We passed... :MAIN.PASS return 'pass' ; ; Ruh-roh... :MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'fail - ${sts:} ${ret:}' return 'fail' ================================================ FILE: twaincs/source/twaincscert/source/data/certification/140 - Image Address Badge/Certification.tc ================================================ ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Image Address Badge ; Check if Image Addressing is supported by the driver. This is a badge, failure does not ; invalidate scanner certification. Instead, passage adds Image Address support to the cert. ; ; The following are required: ; CAP_IAFIELDA_LEVEL, CAP_IAFIELDB_LEVEL, CAP_IAFIELDC_LEVEL, CAP_IAFIELDD_LEVEL ; CAP_IAFIELDA_PRINTFORMAT, CAP_IAFIELDB_PRINTFORMAT, CAP_IAFIELDC_PRINTFORMAT, CAP_IAFIELDD_PRINTFORMAT ; CAP_IAFIELDA_VALUE, CAP_IAFIELDB_VALUE, CAP_IAFIELDC_VALUE, CAP_IAFIELDD_VALUE ; TWEI_IALEVEL (values TWIA_FIXED, TWIA_LEVEL1, TWIA_LEVEL2, TWIA_LEVEL3) ; TWEI_IAFIELDA_VALUE, TWEI_IAFIELDA_VALUE, TWEI_IAFIELDA_VALUE, TWEI_IAFIELDA_VALUE ; ; If the scanner supports printing, the following are required: ; CAP_PRINTERMODE (value TWPM_IMAGEADDRESSSTRING) ; TWEI_PRINTERTEXT ; ; The following are optional, and only tested if present in the driver: ; CAP_IAFIELDE_LEVEL ; CAP_IAFIELDE_PRINTFORMAT ; CAP_IAFIELDE_VALUE ; TWEI_IALEVEL (value TWIA_LEVEL4) ; TWEI_IAFIELDE_VALUE ; ; Arguments ; arg:1 - TW_IDENTITY.ProductName of scanner to test ; arg:2 - global to set on fail ; ; Globals ; g_localcertifyresult - global to report to caller on fail ; ; Locals ; twidentity.productname - product name of scanner to test ; globaltosetonfail - name says it all ; ; Returns ; (none) ; ; History ; 1.0 - initial release ; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Initialize stuff, load tables if not already done for us... ; echo.titlesuite 'Image Address Badge v1.0 17-Sep-2021' echo.yellow '*************************************************************************************' echo.yellow '*** This tests the Image Address Badge. Skipping or failing means the driver ***' echo.yellow '*** does not support this functionality. It does not prevent certification. ***' echo.yellow '*************************************************************************************' ; setlocal twidentity.productname '${arg:1}' setlocal globaltosetonfail '${arg:2}' setglobal g_localcertifyresult 'pass' ; assume success ; if '${get:TW_ARRAY.ItemType}' != '' goto MAIN.LOADTABLES.SKIP run '${folder:certification}/LoadTables' :MAIN.LOADTABLES.SKIP ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Open the scanner driver, run the tests, close the scanner driver... ; call CERTIFY '${folder:certification}/Opends' '${get:twidentity.productname}' 'g_localcertifyresult' 'embedded' if '${get:g_localcertifyresult}' != 'pass' goto MAIN.CLOSEDS ; call CERTIFY 'Image Address Badge' '${get:twidentity.productname}' 'g_localcertifyresult' ; :MAIN.CLOSEDS call CERTIFY '${folder:certification}/Closeds' '${get:twidentity.productname}' 'g_localcertifyresult' 'embedded' ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Summary and cleanup... ; ; Did we pass? (do an extra check) if '${get:g_localcertifyresult}' == 'skip' goto MAIN.SKIP if '${get:g_localcertifyresult}' != 'pass' goto MAIN.ERROR echo '' echo.passfail 'BADGE SUMMARY' 'pass' return 'pass' ; ; Unsupported... :MAIN.SKIP echo '' echo.passfail 'BADGE SUMMARY' 'skip' setglobal '${get:globaltosetonfail}' 'skip' return 'skip' ; ; Ruh-roh... :MAIN.ERROR echo '' echo.passfail 'BADGE SUMMARY' 'fail' setglobal '${get:globaltosetonfail}' 'fail' return 'fail' ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Function: Certify ; arg:1 - script to run ; arg:2 - TW_IDENTITY.ProductName of scanner to test ; arg:3 - global value to update on fail ; arg:4 - embeded flag for open/close, or folder for DAT_IMAGE*XFER calls ; returns: (none) ; :CERTIFY ; ; If a failure has occurred on a previous test, skip the rest of the tests, ; except for closing, that would be bad... if '${arg:1}' ~contains 'Closeds' goto CERTIFY.RUN if '${get:${arg:3}}' == 'skip' goto CERTIFY.SKIP if '${get:${arg:3}}' == 'fail' goto CERTIFY.FAIL ; ; Run the test... :CERTIFY.RUN run '${arg:1}' '${arg:2}' '${arg:4}' if '${ret:}' == 'skip' goto CERTIFY.SKIP if '${ret:}' != 'pass' goto CERTIFY.FAIL return 'pass' ; ; Handle skipping, set the global so we have a record... :CERTIFY.SKIP setglobal '${arg:3}' 'skip' return 'skip' ; ; Handle failure, set the global so we have a record... :CERTIFY.FAIL setglobal '${arg:3}' 'fail' return 'fail' ================================================ FILE: twaincs/source/twaincscert/source/data/certification/140 - Image Address Badge/DAT_EXTIMAGEINFO.tc ================================================ ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; DAT_EXTIMAGEINFO ; Check the return values from DAT_EXTIMAGEINFO to make sure the image address ; metadata is being properly reported. ; ; Here's the basic flow: ; DAT_EXTIMAGEINFO ; confirm that we have the following TWEI_IA* items ; TWEI_IAFIELDA_VALUE ; TWEI_IAFIELDB_VALUE ; TWEI_IAFIELDC_VALUE ; TWEI_IAFIELDD_VALUE ; TWEI_IAFIELDE_VALUE (optional) ; TWEI_IALEVEL ; ; Arguments ; arg:1 - indent the passfail text ; arg:2 - base filename (no extension) ; arg:3 - TWEI_IAFIELD*_VALUE (can be empty is none) ; arg:4 - fixed field value, if any ; arg:5 - expected number of fields ; ; Locals ; imageaddressdata - the return value from DAT_EXTIMAGEINFO ; name - current test being done ; indent - indent the passfail text ; basefilename - used to store the extended image info into a file ; fieldfieldname - TWEI_IAFIELD*_VALUE (can be empty is none) ; fieldfieldvalue - fixed field value, if any ; totalfields - total fields we expect to see, all others must have no data ; twinfo.infoid.index - index to TW_INFO[n].infoid from the start of barcodedata ; twinfo.itemtype.index - index to TW_INFO[n].itemtype from the start of barcodedata ; twinfo.numitems.index - index to TW_INFO[n].numitems from the start of barcodedata ; twinfo.returncode.index - index to TW_INFO[n].returncode from the start of barcodedata ; twinfo.item.index - index to TW_INFO[n].item from the start of barcodedata ; ; Returns ; pass/fail ; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Squirrel away the arguments... ; setlocal indent '${arg:1} ' setlocal basefilename '${arg:2}' setlocal fixedfieldname '${arg:3}' setlocal fixedfieldvalue '${arg:4}' setlocal totalfields '${arg:5}' ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Get the extended image info, save the data to 'imageaddressdata'. ; setlocal name 'dg_image/dat_extimageinfo/msg_get TWEI_IA*' dsmentry src ds dg_image dat_extimageinfo msg_get '6,TWEI_IALEVEL,0,0,0,0,TWEI_IAFIELDA_VALUE,0,0,0,0,TWEI_IAFIELDB_VALUE,0,0,0,0,TWEI_IAFIELDC_VALUE,0,0,0,0,TWEI_IAFIELDD_VALUE,0,0,0,0,TWEI_IAFIELDE_VALUE,0,0,0,0' if '${sts:}' != 'SUCCESS' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' setlocal imageaddressdata '${ret:}' filewrite '${arg:2}_extimageinfo.txt' '${get:imageaddressdata}' ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Confirm that we got back all the image address extimageinfo fields, ; this doesn't mean they all have data, but they all must be present... ; setlocal name 'Found TWEI_IALEVEL' if '${get:imageaddressdata}' !contains ',TWEI_IALEVEL,' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' setlocal name 'Found TWEI_IAFIELDA_VALUE' if '${get:imageaddressdata}' !contains ',TWEI_IAFIELDA_VALUE,' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' setlocal name 'Found TWEI_IAFIELDB_VALUE' if '${get:imageaddressdata}' !contains ',TWEI_IAFIELDB_VALUE,' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' setlocal name 'Found TWEI_IAFIELDC_VALUE' if '${get:imageaddressdata}' !contains ',TWEI_IAFIELDC_VALUE,' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' setlocal name 'Found TWEI_IAFIELDD_VALUE' if '${get:imageaddressdata}' !contains ',TWEI_IAFIELDD_VALUE,' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' setlocal name 'Found TWEI_IAFIELDE_VALUE' if '${get:imageaddressdata}' !contains ',TWEI_IAFIELDE_VALUE,' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Init our TWINFO indecies for TW_INFO[0]... ; setlocal twinfo.infoid.index '${get:TW_INFO.InfoID}' setlocal twinfo.itemtype.index '${get:TW_INFO.ItemType}' setlocal twinfo.numitems.index '${get:TW_INFO.NumItems}' setlocal twinfo.returncode.index '${get:TW_INFO.ReturnCode}' setlocal twinfo.item.index '${get:TW_INFO.Item}' ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Validate the contents of TWEI_IALEVEL, which is in TW_INFO[0]... ; setlocal name 'TW_INFO[0].InfoID is TWEI_IALEVEL' if '${getindex:imageaddressdata:${get:twinfo.infoid.index}}' != 'TWEI_IALEVEL' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' ; setlocal name 'TW_INFO[0].ItemType is TWTY_UINT16' if '${getindex:imageaddressdata:${get:twinfo.itemtype.index}}' != 'TWTY_UINT16' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' ; setlocal name 'TW_INFO[0].NumItems is 1' if '${getindex:imageaddressdata:${get:twinfo.numitems.index}}' != '1' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' ; setlocal name 'TW_INFO[0].ReturnCode is TWRC_SUCCESS' if '${getindex:imageaddressdata:${get:twinfo.returncode.index}}' != 'TWRC_SUCCESS' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' ; setlocal name 'TW_INFO[0].Item is one of the TWIA_LEVEL# values' if '${gettwei:TWEI_IALEVEL:${getindex:imageaddressdata:${get:twinfo.item.index}}}' == 'TWIA_LEVEL1' goto MAIN.TWEI_LEVEL.DONE if '${gettwei:TWEI_IALEVEL:${getindex:imageaddressdata:${get:twinfo.item.index}}}' == 'TWIA_LEVEL2' goto MAIN.TWEI_LEVEL.DONE if '${gettwei:TWEI_IALEVEL:${getindex:imageaddressdata:${get:twinfo.item.index}}}' == 'TWIA_LEVEL3' goto MAIN.TWEI_LEVEL.DONE if '${gettwei:TWEI_IALEVEL:${getindex:imageaddressdata:${get:twinfo.item.index}}}' == 'TWIA_LEVEL4' goto MAIN.TWEI_LEVEL.DONE goto MAIN.ERROR.ECHOPASSFAIL :MAIN.TWEI_LEVEL.DONE echo.passfail '${get:indent}${get:name}' 'pass' ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Initialize for the loop that'll go through the values. ; iafieldindex is the index into iafieldvalue ; iafieldvalue is the array of fields we'll be checking ; setlocal iafieldindex 0 setlocal iafieldvalue 'PLACEHOLDER,TWEI_IAFIELDA_VALUE,TWEI_IAFIELDB_VALUE,TWEI_IAFIELDC_VALUE,TWEI_IAFIELDD_VALUE,TWEI_IAFIELDE_VALUE' ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Increment our TWINFO indecies for TW_INFO[n]... ; :MAIN.TWINFO.NEXT increment iafieldindex '${get:iafieldindex}' 1 increment twinfo.infoid.index '${get:twinfo.infoid.index}' 5 ; skip to the InfoID in the next TW_INFO increment twinfo.itemtype.index '${get:twinfo.itemtype.index}' 5 ; skip to the InfoID in the next TW_INFO increment twinfo.numitems.index '${get:twinfo.numitems.index}' 5 ; skip to the NumItems in the next TW_INFO increment twinfo.returncode.index '${get:twinfo.returncode.index}' 5 ; skip to the ReturnCode in the next TW_INFO increment twinfo.item.index '${get:twinfo.item.index}' 5 ; skip to the ReturnCode in the next TW_INFO if '${getindex:iafieldvalue:${get:iafieldindex}}' == '' goto MAIN.TWINFO.DONE ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Validate the contents of TWEI_IAFIELD*_VALUE, which is in TW_INFO[n]... ; Anything less than or equal to the total number of fields must report ; TWRC_SUCCESS, all others must report TWRC_DATANOTAVAILABLE... ; setlocal name 'TW_INFO[${get:iafieldindex}].InfoID is ${getindex:iafieldvalue:${get:iafieldindex}}' if '${getindex:imageaddressdata:${get:twinfo.infoid.index}}' != '${getindex:iafieldvalue:${get:iafieldindex}}' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' ; ; totalfields indicates the number of iafields we negotiated with a level ; other than TWIA_UNUSED, so we require a status of success from them. if '${get:iafieldindex}' <= '${get:totalfields}' goto MAIN.TWINFO.FIELDHASDATA ; ; TWEI_IAFIELDE_VALUE is a special case, jump there when we detect it. ; For the other fields we require a status return of TWRC_DATANOTAVAILABLE ; if the field is currently disabled. if '${getindex:iafieldvalue:${get:iafieldindex}}' == 'TWEI_IAFIELDE_VALUE' goto MAIN.TWINFO.TWEI_IAFIELDE_VALUE setlocal name 'TW_INFO[${get:iafieldindex}].ReturnCode is TWRC_DATANOTAVAILABLE' if '${getindex:imageaddressdata:${get:twinfo.returncode.index}}' != 'TWRC_DATANOTAVAILABLE' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' goto MAIN.TWINFO.DONE ; ; Support for TWEI_IAFIELDE_VALUE is optional, so it's okay for it to ; return a value of either TWRC_DATANOTAVAILABLE or TWRC_INFONOTSUPPORTED. :MAIN.TWINFO.TWEI_IAFIELDE_VALUE setlocal name 'TW_INFO[${get:iafieldindex}].ReturnCode is TWRC_DATANOTAVAILABLE or TWRC_INFONOTSUPPORTED' if '${getindex:imageaddressdata:${get:twinfo.returncode.index}}' == 'TWRC_DATANOTAVAILABLE' goto MAIN.TWINFO.FIELDHASNODATA if '${getindex:imageaddressdata:${get:twinfo.returncode.index}}' == 'TWRC_INFONOTSUPPORTED' goto MAIN.TWINFO.FIELDHASNODATA goto MAIN.ERROR.ECHOPASSFAIL :MAIN.TWINFO.FIELDHASNODATA echo.passfail '${get:indent}${get:name}' 'pass' goto MAIN.TWINFO.DONE ; ; If we got here we expect valid data, check each of the TW_INFO fields... :MAIN.TWINFO.FIELDHASDATA setlocal name 'TW_INFO[${get:iafieldindex}].ReturnCode is TWRC_SUCCESS' if '${getindex:imageaddressdata:${get:twinfo.returncode.index}}' != 'TWRC_SUCCESS' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' ; setlocal name 'TW_INFO[${get:iafieldindex}].ItemType is TWTY_STR32' if '${getindex:imageaddressdata:${get:twinfo.itemtype.index}}' != 'TWTY_STR32' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' ; setlocal name 'TW_INFO[${get:iafieldindex}].NumItems is 1' if '${getindex:imageaddressdata:${get:twinfo.numitems.index}}' != '1' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' ; ; The image address value text is behind a handle... setlocal handle ${getindex:imageaddressdata:${get:twinfo.item.index}} setlocal fieldavalue '${gethandle:${get:handle}:TWTY_STR32:0}' ; ; Do this test if the field we're working on matches fixedfieldname, ; we want to make sure the string we set it to comes back to us... if '${getindex:imageaddressdata:${get:twinfo.itemtype.index}}' != '${get:fixedfieldname}' goto MAIN.TWINFO.NEXT setlocal name 'TW_INFO[${get:iafieldindex}].Item contains "${get:fixedfieldvalue}" (${get:printertext})' if '${get:printertext}' !contains '${get:fixedfieldvalue}' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' ; free handle handle goto MAIN.TWINFO.NEXT :MAIN.TWINFO.DONE ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Summary and cleanup... ; ; We passed... :MAIN.PASS return 'pass' ; ; Ruh-roh... :MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'fail - ${sts:} ${ret:}' return 'fail' ================================================ FILE: twaincs/source/twaincscert/source/data/certification/140 - Image Address Badge/DAT_IMAGEFILEXFER.tc ================================================ ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; DAT_IMAGEFILEXFER ; This test scans one sheet of paper for the default pixeltype. An ADF is required to pass this test, ; but that was already been confirmed before we got to this function. We're going to set the driver, ; scan a sheet of paper, and check the TWEI_* values. ; ; Here's the basic flow: ; SetCapabilities ; start scanning ; while images ; transfer image ; DAT_EXTIMAGEINFO ; end image ; end ; end scanning ; verify the results ; ; The test passes if: ; - all of the CAP_IAFIELD*_* capabilities can be set ; - scanning is successful ; - the TWEI_IALEVEL and TWEI_IAFIELD*_VALUE field are correctly set ; - if printing is supported, CAP_PRINTERMODE can be set and ; CAP_PRINTERTEXT contains the correct value ; ; Arguments ; arg:1 - test name for the image folder ; arg:2 - TWEI_IAFIELD*_VALUE containing fixed field (can be empty if none) ; arg:3 - fielda image address settings 'twia,printformat,value' ; arg:4 - fieldb image address settings 'twia,printformat,value' ; arg:5 - fieldc image address settings 'twia,printformat,value' ; arg:6 - fieldd image address settings 'twia,printformat,value' ; arg:7 - fielde image address settings 'twia,printformat,value' ; ; Globals ; (none) ; ; Locals ; name - current test being done ; indent - indent the passfail text ; twimageinfo.compression - compression for current image ; image.count - count of images from 1 ; image.folder - folder to put the images in ; totalfields - total value image address fields ; ; Returns ; pass/fail ; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Initialize... ; setlocal fixedfieldname '${arg:2}' setlocal fielda '${arg:3}' ; check argindex down below setlocal fieldb '${arg:4}' setlocal fieldc '${arg:5}' setlocal fieldd '${arg:6}' setlocal fielde '${arg:7}' ; setlocal indent '' setlocal image.count '1' setlocal image.folder '${folder:certimages}/${arg:1}/DAT_IMAGEFILEXFER' setlocal image.showname '' ; ; Figure out how many iafields have data, and get the fixed field value, ; if any. We're use them to check the TWEI_* values... setlocal totalfields 0 ; assume no fields setlocal argindex 2 ; first ia field argument - 1 setlocal fixedfieldvalue '' ; assume we don't have a value :MAIN.PARSE.NEXT increment argindex ${get:argindex} 1 if '${arg:${get:argindex}}' == '' goto MAIN.PARSE.DONE ; ran out of arguments if '${arg:${get:argindex}}' ~contains 'TWIA_UNUSED' goto MAIN.PARSE.NEXT ; skip unused fields if '${getindex:TWEI_IAFIELDA_VALUE,TWEI_IAFIELDB_VALUE,TWEI_IAFIELDC_VALUE,TWEI_IAFIELDD_VALUE,TWEI_IAFIELDE_VALUE:${get:argindex}}' != '${get:fixedfieldname}' goto MAIN.PARSE.NOTFIXED setlocal fixedfieldvalue '${getindex:${arg:${get:argindex}}:2}' :MAIN.PARSE.NOTFIXED increment totalfields ${get:totalfields} 1 goto MAIN.PARSE.NEXT :MAIN.PARSE.DONE ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Clean the image folder for this test... ; image cleanfolderandmeta '${get:image.folder}' ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; SetCapabilities ; This resets the driver and sets all the capabilities we need for the test. ; If its return code is not 'pass', end with an error ; run SetCapabilities 'TWSX_FILE' '${get:indent}' '${get:totalfields}' '${get:fielda}' '${get:fieldb}' '${get:fieldc}' '${get:fieldd}' '${get:fielde}' setlocal returnvalue ${ret:} if '${ret:}' != 'skip' goto MAIN.SETCAPABILITES.CHECKPASS goto MAIN.SETCAPABILITES.DONE ; :MAIN.SETCAPABILITES.CHECKPASS if '${get:returnvalue}' != 'pass' goto MAIN.ERROR.FAIL :MAIN.SETCAPABILITES.DONE ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Check for paper in the feeder, prompt the user if we don't find any... ; dsmentry src ds dg_control dat_capability msg_getcurrent 'CAP_FEEDERLOADED,0,0,0' if '${sts:}' != 'SUCCESS' goto MAIN.FEEDERLOADED.DONE if '${ret:${get:TW_ONEVALUE.Item}}' ~~ 'TRUE' goto MAIN.FEEDERLOADED.DONE echo.prompt echo.prompt "Place paper in the scanner's feeder." pause '(press the ENTER key when ready to continue)' :MAIN.FEEDERLOADED.DONE ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Start scanning... ; setlocal name 'dg_control/dat_userinterface/msg_enableds' wait reset dsmentry src null dg_control dat_userinterface msg_enableds '0,0' if '${sts:}' != 'SUCCESS' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Wait for MSG_XFERREADY, if we don't see it then scoot... ; setlocal name 'wait ${get:sys_waittimeout} seconds for MSG_XFERREADY' wait '${get:sys_waittimeout}000' if '${ret:}' !~contains 'msg_xferready' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Get information about the image... ; :MAIN.IMAGEINFO.NEXT setlocal name 'dg_image/dat_imageinfo/msg_get' dsmentry src ds dg_image dat_imageinfo msg_get '0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0' if '${sts:}' != 'SUCCESS' goto MAIN.ERROR.ECHOPASSFAIL setlocal twimageinfo.compression '${ret:${get:index.twimageinfo.compression}}' echo.passfail '${get:indent}${get:name}' 'pass' ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Set up the file transfer... ; increment image.count '${get:image.count}' 1 if '${get:twimageinfo.compression}' == 'JPEG' goto MAIN.SETUPFILEXFER.JPEG setlocal image.showname 'DAT_IMAGEFILEXFER/adf${format:D6|${get:image.count}}.tif' setlocal twsetupfilexfer.filename '${get:image.folder}/adf${format:D6|${get:image.count}}.tif' setlocal twsetupfilexfer.format 'TWFF_TIFF' goto MAIN.SETUPFILEXFER :MAIN.SETUPFILEXFER.JPEG setlocal image.showname 'DAT_IMAGEFILEXFER/adf${format:D6|${get:image.count}}.jpg' setlocal twsetupfilexfer.filename '${get:image.folder}/adf${format:D6|${get:image.count}}.jpg' setlocal twsetupfilexfer.format 'TWFF_JFIF' :MAIN.SETUPFILEXFER setlocal name 'dg_control/dat_setupfilexfer/msg_set' dsmentry src ds dg_control dat_setupfilexfer msg_set '"${get:twsetupfilexfer.filename}",${get:twsetupfilexfer.format},0' if '${sts:}' != 'SUCCESS' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Transfer the image... ; setlocal name 'dg_image/dat_imagefilexfer/msg_get' dsmentry src ds dg_image dat_imagefilexfer msg_get null if '${sts:}' != 'XFERDONE' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' echo.passfail '${get:indent}image <${get:image.showname}>' 'pass' ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; DAT_EXTIMAGEINFO ; Check the printer metadata... ; run DAT_EXTIMAGEINFO '${get:indent}' '${get:image.folder}/adf${format:D6|${get:image.count}}' '${get:fixedfieldname}' '${get:fixedfieldvalue}' '${get:totalfields}' if '${ret:}' != 'pass' goto MAIN.ERROR.FAIL ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; End the transfer, see if we're done. If not, go back ; to MAIN.IMAGEINFO.NEXT for another image... ; setlocal name 'dg_control/dat_pendingxfers/msg_endxfer' dsmentry src ds dg_control dat_pendingxfers msg_endxfer '0,0' if '${sts:}' != 'SUCCESS' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' increment image.count '${get:image.count}' 1 ; count the image if '${ret:${get:TW_PENDINGXFERS.Count}}' != '0' goto MAIN.IMAGEINFO.NEXT ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; We're out of images, so disable... ; setlocal name 'dg_control/dat_userinterface/msg_disableds' dsmentry src ds dg_control dat_userinterface msg_disableds '0,0' if '${sts:}' != 'SUCCESS' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Summary and cleanup... ; ; We passed... :MAIN.PASS echo.passfail 'SUMMARY' 'pass' return 'pass' ; ; Skip is allowed for CAP_IAFIELDE_*... :MAIN.SKIP echo.passfail 'SUMMARY' 'skip' return 'skip' ; ; Ruh-roh... :MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'fail - ${sts:} ${ret:}' echo.passfail 'SUMMARY' 'fail' rollback state4 return 'fail' ; ; Ruh-roh... :MAIN.ERROR.FAIL echo.passfail 'SUMMARY' 'fail' rollback state4 return 'fail' ================================================ FILE: twaincs/source/twaincscert/source/data/certification/140 - Image Address Badge/DAT_IMAGEMEMFILEXFER.tc ================================================ ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; DAT_IMAGEMEMFILEXFER ; This test scans one sheet of paper for the default pixeltype. An ADF is required to pass this test, ; but that was already been confirmed before we got to this function. We're going to set the driver, ; scan a sheet of paper, and check the TWEI_* values. ; ; Here's the basic flow: ; SetCapabilities ; start scanning ; while images ; transfer image ; DAT_EXTIMAGEINFO ; end image ; end ; end scanning ; verify the results ; ; The test passes if: ; - all of the CAP_IAFIELD*_* capabilities can be set ; - scanning is successful ; - the TWEI_IALEVEL and TWEI_IAFIELD*_VALUE field are correctly set ; - if printing is supported, CAP_PRINTERMODE can be set and ; CAP_PRINTERTEXT contains the correct value ; ; Arguments ; arg:1 - test name for the image folder ; arg:2 - TWEI_IAFIELD*_VALUE containing fixed field (can be empty if none) ; arg:3 - fielda image address settings 'twia,printformat,value' ; arg:4 - fieldb image address settings 'twia,printformat,value' ; arg:5 - fieldc image address settings 'twia,printformat,value' ; arg:6 - fieldd image address settings 'twia,printformat,value' ; arg:7 - fielde image address settings 'twia,printformat,value' ; ; Globals ; (none) ; ; Locals ; name - current test being done ; indent - indent the passfail text ; imagememxfer - result of DAT_IMAGEMEMXFER call ; setupmemxfer.preferred - preferred field from DAT_SETUPMEMXFER call ; image.count - count of images from 1 ; image.folder - folder to put the images in ; totalfields - total value image address fields ; ; Returns ; pass/fail ; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Initialize... ; setlocal fixedfieldname '${arg:2}' setlocal fielda '${arg:3}' ; check argindex down below setlocal fieldb '${arg:4}' setlocal fieldc '${arg:5}' setlocal fieldd '${arg:6}' setlocal fielde '${arg:7}' ; setlocal indent '' setlocal image.pointer '0' setlocal image.count '1' setlocal image.folder '${folder:certimages}/${arg:1}/DAT_IMAGEMEMFILEXFER' ; ; Figure out how many iafields have data, and get the fixed field value, ; if any. We're use them to check the TWEI_* values... setlocal totalfields 0 ; assume no fields setlocal argindex 2 ; first ia field argument - 1 setlocal fixedfieldvalue '' ; assume we don't have a value :MAIN.PARSE.NEXT increment argindex ${get:argindex} 1 if '${arg:${get:argindex}}' == '' goto MAIN.PARSE.DONE ; ran out of arguments if '${arg:${get:argindex}}' ~contains 'TWIA_UNUSED' goto MAIN.PARSE.NEXT ; skip unused fields if '${getindex:TWEI_IAFIELDA_VALUE,TWEI_IAFIELDB_VALUE,TWEI_IAFIELDC_VALUE,TWEI_IAFIELDD_VALUE,TWEI_IAFIELDE_VALUE:${get:argindex}}' != '${get:fixedfieldname}' goto MAIN.PARSE.NOTFIXED setlocal fixedfieldvalue '${getindex:${arg:${get:argindex}}:2}' :MAIN.PARSE.NOTFIXED increment totalfields ${get:totalfields} 1 goto MAIN.PARSE.NEXT :MAIN.PARSE.DONE ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Clean the image folder for this test... ; image cleanfolderandmeta '${get:image.folder}' ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; SetCapabilities ; This resets the driver and sets all the capabilities we need for the test. ; If its return code is not 'pass', end with an error ; run SetCapabilities 'TWSX_MEMFILE' '${get:indent}' '${get:totalfields}' '${get:fielda}' '${get:fieldb}' '${get:fieldc}' '${get:fieldd}' '${get:fielde}' setlocal returnvalue ${ret:} if '${ret:}' != 'skip' goto MAIN.SETCAPABILITES.CHECKPASS goto MAIN.SETCAPABILITES.DONE ; :MAIN.SETCAPABILITES.CHECKPASS if '${get:returnvalue}' != 'pass' goto MAIN.ERROR.FAIL :MAIN.SETCAPABILITES.DONE ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Check for paper in the feeder, prompt the user if we don't find any... ; dsmentry src ds dg_control dat_capability msg_getcurrent 'CAP_FEEDERLOADED,0,0,0' if '${sts:}' != 'SUCCESS' goto MAIN.FEEDERLOADED.DONE if '${ret:${get:TW_ONEVALUE.Item}}' ~~ 'TRUE' goto MAIN.FEEDERLOADED.DONE echo.prompt echo.prompt "Place paper in the scanner's feeder." pause '(press the ENTER key when ready to continue)' :MAIN.FEEDERLOADED.DONE ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Get the preferred size for memory transfers, and allocate ; a pointer for the memory transfers... ; setlocal indent ' ' setlocal name 'dg_control/dat_setupmemxfer/msg_get' dsmentry src ds dg_control dat_setupmemxfer msg_get '0,0,0' if '${sts:}' != 'SUCCESS' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' ; setlocal name 'TW_SETUPMEMXFER.Preferred > 0' setlocal setupmemxfer.preferred '${ret:${get:TW_SETUPMEMXFER.Preferred}}' if '${get:setupmemxfer.preferred}' <= '0' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' ; setlocal name 'allocate pointer for ${get:setupmemxfer.preferred} bytes' free pointer image.pointer ; for the last loop allocate pointer image.pointer '${get:setupmemxfer.preferred}' if '${get:image.pointer}' == '0' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Start scanning... ; setlocal name 'dg_control/dat_userinterface/msg_enableds' wait reset dsmentry src null dg_control dat_userinterface msg_enableds '0,0' if '${sts:}' != 'SUCCESS' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Wait for MSG_XFERREADY, if we don't see it then scoot... ; setlocal name 'wait ${get:sys_waittimeout} seconds for MSG_XFERREADY' wait '${get:sys_waittimeout}000' if '${ret:}' !~contains 'msg_xferready' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Get information about the image... ; :MAIN.IMAGEINFO.NEXT setlocal name 'dg_image/dat_imageinfo/msg_get' dsmentry src ds dg_image dat_imageinfo msg_get '0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0' if '${sts:}' != 'SUCCESS' goto MAIN.ERROR.ECHOPASSFAIL setlocal twimageinfo.compression '${ret:${get:index.twimageinfo.compression}}' echo.passfail '${get:indent}${get:name}' 'pass' ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Set up the memory file transfer... ; increment image.count '${get:image.count}' 1 if '${get:twimageinfo.compression}' == 'JPEG' goto MAIN.SETUPFILEXFER.JPEG setlocal image.showname 'DAT_IMAGEFILEXFER/adf${format:D6|${get:image.count}}.tif' setlocal twsetupfilexfer.filename '${get:image.folder}/adf${format:D6|${get:image.count}}.tif' setlocal twsetupfilexfer.format 'TWFF_TIFF' goto MAIN.SETUPFILEXFER :MAIN.SETUPFILEXFER.JPEG setlocal image.showname 'DAT_IMAGEFILEXFER/adf${format:D6|${get:image.count}}.jpg' setlocal twsetupfilexfer.filename '${get:image.folder}/adf${format:D6|${get:image.count}}.jpg' setlocal twsetupfilexfer.format 'TWFF_JFIF' :MAIN.SETUPFILEXFER setlocal name 'dg_control/dat_setupfilexfer/msg_set' dsmentry src ds dg_control dat_setupfilexfer msg_set '"${get:twsetupfilexfer.filename}",${get:twsetupfilexfer.format},0' if '${sts:}' != 'SUCCESS' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Do a memory file transfer... ; This little song and dance with the states is so that we can ; start the transfer in state 6 with each new image, but switch ; to state 7 if we need multiple calls to capture the current ; image... ; ; The saved images will be in TIFF format, which includes TIFF ; JPEG (the better form, where a simple TIFF header is added). ; increment image.count '${get:image.count}' 1 image free memfileimage ; :MAIN.IMAGEMEMFILEXFER.NEXT setlocal name 'dg_image/dat_imagememxfer/msg_get' dsmentry src ds dg_image dat_imagememfilexfer msg_get '0,0,0,0,0,0,0,9,${get:setupmemxfer.preferred},${get:image.pointer}' setlocal imagememxfer '${ret:}' if '${sts:}' == 'XFERDONE' goto MAIN.IMAGEMEMFILEXFER.XFERDONE if '${sts:}' != 'SUCCESS' goto MAIN.ERROR.ECHOPASSFAIL ; echo.passfail '${get:indent}${get:name} SUCCESS' 'pass' image append memfileimage '${get:imagememxfer}' goto MAIN.IMAGEMEMFILEXFER.NEXT ; :MAIN.IMAGEMEMFILEXFER.XFERDONE echo.passfail '${get:indent}${get:name} XFERDONE' 'pass' ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Append the last strip transferred, and save the image... ; image append memfileimage '${get:imagememxfer}' image save memfileimage memfile '${get:twsetupfilexfer.filename}' echo.passfail '${get:indent}image <${ret:}>' 'pass' image free memfileimage ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; DAT_EXTIMAGEINFO ; Check the printer metadata... ; run DAT_EXTIMAGEINFO '${get:indent}' '${get:image.folder}/adf${format:D6|${get:image.count}}' '${get:fixedfieldname}' '${get:fixedfieldvalue}' '${get:totalfields}' if '${ret:}' != 'pass' goto MAIN.ERROR.FAIL ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; End the transfer, see if we're done... ; setlocal name 'dg_control/dat_pendingxfers/msg_endxfer' dsmentry src ds dg_control dat_pendingxfers msg_endxfer '0,0' if '${sts:}' != 'SUCCESS' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' increment image.count '${get:image.count}' 1 if '${ret:${get:TW_PENDINGXFERS.Count}}' != '0' goto MAIN.IMAGEMEMFILEXFER.NEXT ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; We're out of images, so disable... ; setlocal name 'dg_control/dat_userinterface/msg_disableds' dsmentry src ds dg_control dat_userinterface msg_disableds '0,0' if '${sts:}' != 'SUCCESS' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Summary and cleanup... ; ; We passed... :MAIN.PASS image free memfileimage echo.passfail 'SUMMARY' 'pass' return 'pass' ; ; Skip is allowed for CAP_IAFIELDE_*... :MAIN.SKIP image free memfileimage echo.passfail 'SUMMARY' 'skip' return 'skip' ; ; Ruh-roh... :MAIN.ERROR.ECHOPASSFAIL image free memfileimage echo.passfail '${get:indent}${get:name}' 'fail - ${sts:} ${ret:}' echo.passfail 'SUMMARY' 'fail' rollback state4 return 'fail' ; ; Ruh-roh... :MAIN.ERROR.FAIL image free memfileimage echo.passfail 'SUMMARY' 'fail' rollback state4 return 'fail' ================================================ FILE: twaincs/source/twaincscert/source/data/certification/140 - Image Address Badge/DAT_IMAGEMEMXFER.tc ================================================ ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; DAT_IMAGEMEMXFER ; This test scans one sheet of paper for the default pixeltype. An ADF is required to pass this test, ; but that was already been confirmed before we got to this function. We're going to set the driver, ; scan a sheet of paper, and check the TWEI_* values. ; ; Here's the basic flow: ; SetCapabilities ; start scanning ; while images ; transfer image ; DAT_EXTIMAGEINFO ; end image ; end ; end scanning ; verify the results ; ; The test passes if: ; - all of the CAP_IAFIELD*_* capabilities can be set ; - scanning is successful ; - the TWEI_IALEVEL and TWEI_IAFIELD*_VALUE field are correctly set ; - if printing is supported, CAP_PRINTERMODE can be set and ; CAP_PRINTERTEXT contains the correct value ; ; Arguments ; arg:1 - test name for the image folder ; arg:2 - TWEI_IAFIELD*_VALUE containing fixed field (can be empty if none) ; arg:3 - fielda image address settings 'twia,printformat,value' ; arg:4 - fieldb image address settings 'twia,printformat,value' ; arg:5 - fieldc image address settings 'twia,printformat,value' ; arg:6 - fieldd image address settings 'twia,printformat,value' ; arg:7 - fielde image address settings 'twia,printformat,value' ; ; Globals ; (none) ; ; Locals ; name - current test being done ; indent - indent the passfail text ; imageinfo - metadata for the current image ; imagememxfer - result of DAT_IMAGEMEMXFER call ; setupmemxfer.preferred - preferred field from DAT_SETUPMEMXFER call ; image.count - count of images from 1 ; image.folder - folder to put the images in ; totalfields - total value image address fields ; ; Returns ; pass/fail ; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Initialize... ; setlocal fixedfieldname '${arg:2}' setlocal fielda '${arg:3}' ; check argindex down below setlocal fieldb '${arg:4}' setlocal fieldc '${arg:5}' setlocal fieldd '${arg:6}' setlocal fielde '${arg:7}' ; setlocal indent '' setlocal image.pointer '0' setlocal image.count '0' setlocal image.folder '${folder:certimages}/${arg:1}/DAT_IMAGEMEMXFER' ; ; Figure out how many iafields have data, and get the fixed field value, ; if any. We're use them to check the TWEI_* values... setlocal totalfields 0 ; assume no fields setlocal argindex 2 ; first ia field argument - 1 setlocal fixedfieldvalue '' ; assume we don't have a value :MAIN.PARSE.NEXT increment argindex ${get:argindex} 1 if '${arg:${get:argindex}}' == '' goto MAIN.PARSE.DONE ; ran out of arguments if '${arg:${get:argindex}}' ~contains 'TWIA_UNUSED' goto MAIN.PARSE.NEXT ; skip unused fields if '${getindex:TWEI_IAFIELDA_VALUE,TWEI_IAFIELDB_VALUE,TWEI_IAFIELDC_VALUE,TWEI_IAFIELDD_VALUE,TWEI_IAFIELDE_VALUE:${get:argindex}}' != '${get:fixedfieldname}' goto MAIN.PARSE.NOTFIXED setlocal fixedfieldvalue '${getindex:${arg:${get:argindex}}:2}' :MAIN.PARSE.NOTFIXED increment totalfields ${get:totalfields} 1 goto MAIN.PARSE.NEXT :MAIN.PARSE.DONE ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Clean the image folder for this test... ; image cleanfolderandmeta '${get:image.folder}' ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; SetCapabilities ; This resets the driver and sets all the capabilities we need for the test. ; If its return code is not 'pass', end with an error ; run SetCapabilities 'TWSX_MEMORY' '${get:indent}' '${get:totalfields}' '${get:fielda}' '${get:fieldb}' '${get:fieldc}' '${get:fieldd}' '${get:fielde}' setlocal returnvalue ${ret:} if '${ret:}' != 'skip' goto MAIN.SETCAPABILITES.CHECKPASS goto MAIN.SETCAPABILITES.DONE ; :MAIN.SETCAPABILITES.CHECKPASS if '${get:returnvalue}' != 'pass' goto MAIN.ERROR.FAIL :MAIN.SETCAPABILITES.DONE ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Check for paper in the feeder, prompt the user if we don't find any... ; dsmentry src ds dg_control dat_capability msg_getcurrent 'CAP_FEEDERLOADED,0,0,0' if '${sts:}' != 'SUCCESS' goto MAIN.FEEDERLOADED.DONE if '${ret:${get:TW_ONEVALUE.Item}}' ~~ 'TRUE' goto MAIN.FEEDERLOADED.DONE echo.prompt echo.prompt "Place paper in the scanner's feeder." pause '(press the ENTER key when ready to continue)' :MAIN.FEEDERLOADED.DONE ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Get the preferred size for memory transfers, and allocate ; a pointer for the memory transfers... ; setlocal indent ' ' setlocal name 'dg_control/dat_setupmemxfer/msg_get' dsmentry src ds dg_control dat_setupmemxfer msg_get '0,0,0' if '${sts:}' != 'SUCCESS' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' ; setlocal name 'TW_SETUPMEMXFER.Preferred > 0' setlocal setupmemxfer.preferred '${ret:${get:TW_SETUPMEMXFER.Preferred}}' if '${get:setupmemxfer.preferred}' <= '0' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' ; setlocal name 'allocate pointer for ${get:setupmemxfer.preferred} bytes' free pointer image.pointer ; for the last loop allocate pointer image.pointer '${get:setupmemxfer.preferred}' if '${get:image.pointer}' == '0' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Start scanning... ; setlocal name 'dg_control/dat_userinterface/msg_enableds' wait reset dsmentry src null dg_control dat_userinterface msg_enableds '0,0' if '${sts:}' != 'SUCCESS' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Wait for MSG_XFERREADY, if we don't see it then scoot... ; setlocal name 'wait ${get:sys_waittimeout} seconds for MSG_XFERREADY' wait '${get:sys_waittimeout}000' if '${ret:}' !~contains 'msg_xferready' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Do a memory transfer... ; This little song and dance with the states is so that we can ; start the transfer in state 6 with each new image, but switch ; to state 7 if we need multiple calls to capture the current ; image... ; ; The saved images will be in TIFF format, which includes TIFF ; JPEG (the better form, where a simple TIFF header is added). ; increment image.count '${get:image.count}' 1 image free memimage ; :MAIN.IMAGEMEMXFER.NEXT setlocal name 'dg_image/dat_imagememxfer/msg_get' dsmentry src ds dg_image dat_imagememxfer msg_get '0,0,0,0,0,0,0,9,${get:setupmemxfer.preferred},${get:image.pointer}' setlocal imagememxfer '${ret:}' if '${sts:}' == 'XFERDONE' goto MAIN.IMAGEMEMXFER.XFERDONE if '${sts:}' != 'SUCCESS' goto MAIN.ERROR.ECHOPASSFAIL ; echo.passfail '${get:indent}${get:name} SUCCESS' 'pass' image append memimage '${get:imagememxfer}' goto MAIN.IMAGEMEMXFER.NEXT ; :MAIN.IMAGEMEMXFER.XFERDONE echo.passfail '${get:indent}${get:name} XFERDONE' 'pass' ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; We need image info to make sense of this data... ; setlocal name 'dg_image/dat_imageinfo/msg_get' dsmentry src ds dg_image dat_imageinfo msg_get '0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0' setlocal imageinfo '${ret:}' if '${sts:}' != 'SUCCESS' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Append the last strip transferred, and save the image... ; image append memimage '${get:imagememxfer}' image addheader memimage '${get:imageinfo}' image save memimage memory '${get:image.folder}/adf${format:D6|${get:image.count}}' echo.passfail '${get:indent}image <${ret:}>' 'pass' image free memimage ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; DAT_EXTIMAGEINFO ; Check the printer metadata... ; run DAT_EXTIMAGEINFO '${get:indent}' '${get:image.folder}/adf${format:D6|${get:image.count}}' '${get:fixedfieldname}' '${get:fixedfieldvalue}' '${get:totalfields}' if '${ret:}' != 'pass' goto MAIN.ERROR.FAIL ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; End the transfer, see if we're done. If not, go back ; to MAIN.IMAGENATIVEXFER.NEXT for another image... ; setlocal name 'dg_control/dat_pendingxfers/msg_endxfer' dsmentry src ds dg_control dat_pendingxfers msg_endxfer '0,0' if '${sts:}' != 'SUCCESS' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' increment image.count '${get:image.count}' 1 if '${ret:${get:TW_PENDINGXFERS.Count}}' != '0' goto MAIN.IMAGEMEMXFER.NEXT ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; We're out of images, so disable... ; setlocal name 'dg_control/dat_userinterface/msg_disableds' dsmentry src ds dg_control dat_userinterface msg_disableds '0,0' if '${sts:}' != 'SUCCESS' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Summary and cleanup... ; ; We passed... :MAIN.PASS image free memimage echo.passfail 'SUMMARY' 'pass' return 'pass' ; ; Skip is allowed for CAP_IAFIELDE_*... :MAIN.SKIP image free memimage echo.passfail 'SUMMARY' 'skip' return 'skip' ; ; Ruh-roh... :MAIN.ERROR.ECHOPASSFAIL image free memimage echo.passfail '${get:indent}${get:name}' 'fail - ${sts:} ${ret:}' echo.passfail 'SUMMARY' 'fail' rollback state4 return 'fail' ; ; Ruh-roh... :MAIN.ERROR.FAIL image free memimage echo.passfail 'SUMMARY' 'fail' rollback state4 return 'fail' ================================================ FILE: twaincs/source/twaincscert/source/data/certification/140 - Image Address Badge/DAT_IMAGENATIVEXFER.tc ================================================ ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; DAT_IMAGENATIVEXFER ; This test scans one sheet of paper for the default pixeltype. An ADF is required to pass this test, ; but that was already been confirmed before we got to this function. We're going to set the driver, ; scan a sheet of paper, and check the TWEI_* values. ; ; Here's the basic flow: ; SetCapabilities ; start scanning ; while images ; transfer image ; DAT_EXTIMAGEINFO ; end image ; end ; end scanning ; ; The test passes if: ; - all of the CAP_IAFIELD*_* capabilities can be set ; - scanning is successful ; - the TWEI_IALEVEL and TWEI_IAFIELD*_VALUE field are correctly set ; - if printing is supported, CAP_PRINTERMODE can be set and ; CAP_PRINTERTEXT contains the correct value ; ; Arguments ; arg:1 - test name for the image folder ; arg:2 - TWEI_IAFIELD*_VALUE containing fixed field (can be empty if none) ; arg:3 - fielda image address settings 'twia,printformat,value' ; arg:4 - fieldb image address settings 'twia,printformat,value' ; arg:5 - fieldc image address settings 'twia,printformat,value' ; arg:6 - fieldd image address settings 'twia,printformat,value' ; arg:7 - fielde image address settings 'twia,printformat,value' ; ; Globals ; (none) ; ; Locals ; name - current test being done ; indent - indent the passfail text ; image.handle - native handle ; image.count - count of images from 1 ; image.folder - folder to put the images in ; totalfields - total value image address fields ; ; Returns ; pass/fail ; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Initialize... ; setlocal fixedfieldname '${arg:2}' setlocal fielda '${arg:3}' ; check argindex down below setlocal fieldb '${arg:4}' setlocal fieldc '${arg:5}' setlocal fieldd '${arg:6}' setlocal fielde '${arg:7}' ; setlocal indent '' setlocal image.handle '0' setlocal image.count '1' setlocal image.folder '${folder:certimages}/${arg:1}/DAT_IMAGENATIVEXFER' ; ; Figure out how many iafields have data, and get the fixed field value, ; if any. We're use them to check the TWEI_* values... setlocal totalfields 0 ; assume no fields setlocal argindex 2 ; first ia field argument - 1 setlocal fixedfieldvalue '' ; assume we don't have a value :MAIN.PARSE.NEXT increment argindex ${get:argindex} 1 if '${arg:${get:argindex}}' == '' goto MAIN.PARSE.DONE ; ran out of arguments if '${arg:${get:argindex}}' ~contains 'TWIA_UNUSED' goto MAIN.PARSE.NEXT ; skip unused fields if '${getindex:TWEI_IAFIELDA_VALUE,TWEI_IAFIELDB_VALUE,TWEI_IAFIELDC_VALUE,TWEI_IAFIELDD_VALUE,TWEI_IAFIELDE_VALUE:${get:argindex}}' != '${get:fixedfieldname}' goto MAIN.PARSE.NOTFIXED setlocal fixedfieldvalue '${getindex:${arg:${get:argindex}}:2}' :MAIN.PARSE.NOTFIXED increment totalfields ${get:totalfields} 1 goto MAIN.PARSE.NEXT :MAIN.PARSE.DONE ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Clean the image folder for this test... ; image cleanfolderandmeta '${get:image.folder}' ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; SetCapabilities ; This resets the driver and sets all the capabilities we need for the test. ; If its return code is not 'pass', end with an error ; run SetCapabilities 'TWSX_NATIVE' '${get:indent}' '${get:totalfields}' '${get:fielda}' '${get:fieldb}' '${get:fieldc}' '${get:fieldd}' '${get:fielde}' setlocal returnvalue ${ret:} if '${ret:}' != 'skip' goto MAIN.SETCAPABILITES.CHECKPASS goto MAIN.SETCAPABILITES.DONE ; :MAIN.SETCAPABILITES.CHECKPASS if '${get:returnvalue}' != 'pass' goto MAIN.ERROR.FAIL :MAIN.SETCAPABILITES.DONE ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Check for paper in the feeder, prompt the user if we don't find any... ; dsmentry src ds dg_control dat_capability msg_getcurrent 'CAP_FEEDERLOADED,0,0,0' if '${sts:}' != 'SUCCESS' goto MAIN.FEEDERLOADED.DONE if '${ret:${get:TW_ONEVALUE.Item}}' ~~ 'TRUE' goto MAIN.FEEDERLOADED.DONE echo.prompt echo.prompt "Place paper in the scanner's feeder." pause '(press the ENTER key when ready to continue)' :MAIN.FEEDERLOADED.DONE ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Start scanning... ; setlocal indent ' ' setlocal name 'dg_control/dat_userinterface/msg_enableds' wait reset dsmentry src null dg_control dat_userinterface msg_enableds '${get:showui},0' if '${sts:}' != 'SUCCESS' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Wait for MSG_XFERREADY, if we don't see it then scoot... ; setlocal name 'wait ${get:sys_waittimeout} seconds for MSG_XFERREADY' wait '${get:sys_waittimeout}000' if '${ret:}' !~contains 'msg_xferready' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Do a native transfer... ; :MAIN.IMAGENATIVEXFER.NEXT setlocal indent ' ' setlocal name 'dg_control/dat_imagenativexfer/msg_get' dsmentry src ds dg_image dat_imagenativexfer msg_get '0' setlocal image.handle '${ret:}' if '${sts:}' != 'XFERDONE' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Save the image... ; image save image.handle native '${get:image.folder}/adf${format:D6|${get:image.count}}' echo.passfail '${get:indent}image <${ret:}>' 'pass' free handle image.handle ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; DAT_EXTIMAGEINFO ; Check the printer metadata... ; run DAT_EXTIMAGEINFO '${get:indent}' '${get:image.folder}/adf${format:D6|${get:image.count}}' '${get:fixedfieldname}' '${get:fixedfieldvalue}' '${get:totalfields}' if '${ret:}' != 'pass' goto MAIN.ERROR.FAIL ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; End the transfer, see if we're done. If not, go back ; to MAIN.IMAGENATIVEXFER.NEXT for another image... ; setlocal name 'dg_control/dat_pendingxfers/msg_endxfer' dsmentry src ds dg_control dat_pendingxfers msg_endxfer '0,0' if '${sts:}' != 'SUCCESS' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' increment image.count '${get:image.count}' 1 ; count the image if '${ret:${get:TW_PENDINGXFERS.Count}}' != '0' goto MAIN.IMAGENATIVEXFER.NEXT ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; We're out of images, so disable... ; setlocal name 'dg_control/dat_userinterface/msg_disableds' dsmentry src ds dg_control dat_userinterface msg_disableds '0,0' if '${sts:}' != 'SUCCESS' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Summary and cleanup... ; ; We passed... :MAIN.PASS free handle image.handle echo.passfail 'SUMMARY' 'pass' return 'pass' ; ; Skip is allowed for CAP_IAFIELDE_*... :MAIN.SKIP free handle image.handle echo.passfail 'SUMMARY' 'skip' return 'skip' ; ; Ruh-roh... :MAIN.ERROR.ECHOPASSFAIL free handle image.handle echo.passfail '${get:indent}${get:name}' 'fail - ${sts:} ${ret:}' echo.passfail 'SUMMARY' 'fail' rollback state4 return 'fail' ; ; Ruh-roh... :MAIN.ERROR.FAIL free handle image.handle echo.passfail 'SUMMARY' 'fail' rollback state4 return 'fail' ================================================ FILE: twaincs/source/twaincscert/source/data/certification/140 - Image Address Badge/Image Address Badge.tc ================================================ ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Image Address Badge ; This script tests the minimum requirements for a TWAIN driver to support image addressing. ; ; Arguments ; arg:1 - TW_IDENTITY.ProductName of scanner to test ; ; Globals ; g_supportedcaps - return from MSG_GET CAP_SUPPORTEDCAPS ; ; Locals ; certifyresult - track if we fail ; ; Returns ; pass/fail ; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Initialize... ; setlocal certifyresult 'pass' ; assume we'll pass ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Reset to a known state... ; setlocal name 'MSG_RESETALL' dsmentry src ds dg_control dat_capability msg_resetall '0,0,0,0' if '${sts:}' != 'SUCCESS' goto MAIN.MSGRESETALL.FAIL echo.passfail '${get:name}' 'pass' goto MAIN.MSGRESETALL.DONE ; :MAIN.MSGRESETALL.FAIL echo.passfail '${get:name}' 'skip - ${sts:} ${ret:}' setlocal certifyresult 'fail' goto MAIN.DONE :MAIN.MSGRESETALL.DONE ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; CAP_IMAGEADDRESSENABLED must be supported, and must offer both TRUE ; and FALSE, and must currently be FALSE, otherwise skip it all ; setlocal name 'CAP_IMAGEADDRESSENABLED is supported' dsmentry src ds dg_control dat_capability msg_get 'CAP_IMAGEADDRESSENABLED,0,0,0' if '${sts:}' != 'SUCCESS' goto MAIN.CAP_IMAGEADDRESSENABLEDSUPPORTED.SKIP if ',${ret:},' !~contains ',TRUE,' goto MAIN.CAP_IMAGEADDRESSENABLEDSUPPORTED.SKIP if ',${ret:},' !~contains ',FALSE,' goto MAIN.CAP_IMAGEADDRESSENABLEDSUPPORTED.SKIP echo.passfail '${get:name}' 'pass' goto MAIN.CAP_IMAGEADDRESSENABLEDSUPPORTED.DONE ; :MAIN.CAP_IMAGEADDRESSENABLEDSUPPORTED.SKIP echo.passfail '${get:name}' 'skip - ${sts:} ${ret:}' setlocal certifyresult 'skip' goto MAIN.DONE :MAIN.CAP_IMAGEADDRESSENABLEDSUPPORTED.DONE ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; CAP_SUPPORTEDCAPS: check that all required capabilities are reported, we're ; not looking for CAP_IAFIELDE_* capabilities, since they're not required... ; setlocal name 'CAP_SUPPORTEDCAPS MSG_GET' dsmentry src ds dg_control dat_capability msg_get 'CAP_SUPPORTEDCAPS,0,0,0' if '${sts:}' != 'SUCCESS' goto MAIN.CAP_SUPPORTEDCAPS.FAIL setglobal g_supportedcaps '${ret:}' echo.passfail '${get:name}' 'pass' ; setlocal name 'CAP_SUPPORTEDCAPS CAP_IMAGEADDRESSENABLED found' if ',${get:g_supportedcaps},' !~contains ',CAP_IMAGEADDRESSENABLED,' goto MAIN.CAP_SUPPORTEDCAPS.FAIL echo.passfail '${get:name}' 'pass' ; setlocal name 'CAP_SUPPORTEDCAPS CAP_IAFIELDA_LASTPAGE found' if ',${get:g_supportedcaps},' !~contains ',CAP_IAFIELDA_LASTPAGE,' goto MAIN.CAP_SUPPORTEDCAPS.FAIL echo.passfail '${get:name}' 'pass' setlocal name 'CAP_SUPPORTEDCAPS CAP_IAFIELDB_LASTPAGE found' if ',${get:g_supportedcaps},' !~contains ',CAP_IAFIELDB_LASTPAGE,' goto MAIN.CAP_SUPPORTEDCAPS.FAIL echo.passfail '${get:name}' 'pass' setlocal name 'CAP_SUPPORTEDCAPS CAP_IAFIELDC_LASTPAGE found' if ',${get:g_supportedcaps},' !~contains ',CAP_IAFIELDC_LASTPAGE,' goto MAIN.CAP_SUPPORTEDCAPS.FAIL echo.passfail '${get:name}' 'pass' setlocal name 'CAP_SUPPORTEDCAPS CAP_IAFIELDD_LASTPAGE found' if ',${get:g_supportedcaps},' !~contains ',CAP_IAFIELDD_LASTPAGE,' goto MAIN.CAP_SUPPORTEDCAPS.FAIL echo.passfail '${get:name}' 'pass' ; setlocal name 'CAP_SUPPORTEDCAPS CAP_IAFIELDA_LEVEL found' if ',${get:g_supportedcaps},' !~contains ',CAP_IAFIELDA_LEVEL,' goto MAIN.CAP_SUPPORTEDCAPS.FAIL echo.passfail '${get:name}' 'pass' setlocal name 'CAP_SUPPORTEDCAPS CAP_IAFIELDB_LEVEL found' if ',${get:g_supportedcaps},' !~contains ',CAP_IAFIELDB_LEVEL,' goto MAIN.CAP_SUPPORTEDCAPS.FAIL echo.passfail '${get:name}' 'pass' setlocal name 'CAP_SUPPORTEDCAPS CAP_IAFIELDC_LEVEL found' if ',${get:g_supportedcaps},' !~contains ',CAP_IAFIELDC_LEVEL,' goto MAIN.CAP_SUPPORTEDCAPS.FAIL echo.passfail '${get:name}' 'pass' setlocal name 'CAP_SUPPORTEDCAPS CAP_IAFIELDD_LEVEL found' if ',${get:g_supportedcaps},' !~contains ',CAP_IAFIELDD_LEVEL,' goto MAIN.CAP_SUPPORTEDCAPS.FAIL echo.passfail '${get:name}' 'pass' ; setlocal name 'CAP_SUPPORTEDCAPS CAP_IAFIELDA_PRINTFORMAT found' if ',${get:g_supportedcaps},' !~contains ',CAP_IAFIELDA_PRINTFORMAT,' goto MAIN.CAP_SUPPORTEDCAPS.FAIL echo.passfail '${get:name}' 'pass' setlocal name 'CAP_SUPPORTEDCAPS CAP_IAFIELDB_PRINTFORMAT found' if ',${get:g_supportedcaps},' !~contains ',CAP_IAFIELDB_PRINTFORMAT,' goto MAIN.CAP_SUPPORTEDCAPS.FAIL echo.passfail '${get:name}' 'pass' setlocal name 'CAP_SUPPORTEDCAPS CAP_IAFIELDC_PRINTFORMAT found' if ',${get:g_supportedcaps},' !~contains ',CAP_IAFIELDC_PRINTFORMAT,' goto MAIN.CAP_SUPPORTEDCAPS.FAIL echo.passfail '${get:name}' 'pass' setlocal name 'CAP_SUPPORTEDCAPS CAP_IAFIELDD_PRINTFORMAT found' if ',${get:g_supportedcaps},' !~contains ',CAP_IAFIELDD_PRINTFORMAT,' goto MAIN.CAP_SUPPORTEDCAPS.FAIL echo.passfail '${get:name}' 'pass' ; setlocal name 'CAP_SUPPORTEDCAPS CAP_IAFIELDA_VALUE found' if ',${get:g_supportedcaps},' !~contains ',CAP_IAFIELDA_VALUE,' goto MAIN.CAP_SUPPORTEDCAPS.FAIL echo.passfail '${get:name}' 'pass' setlocal name 'CAP_SUPPORTEDCAPS CAP_IAFIELDB_VALUE found' if ',${get:g_supportedcaps},' !~contains ',CAP_IAFIELDB_VALUE,' goto MAIN.CAP_SUPPORTEDCAPS.FAIL echo.passfail '${get:name}' 'pass' setlocal name 'CAP_SUPPORTEDCAPS CAP_IAFIELDC_VALUE found' if ',${get:g_supportedcaps},' !~contains ',CAP_IAFIELDC_VALUE,' goto MAIN.CAP_SUPPORTEDCAPS.FAIL echo.passfail '${get:name}' 'pass' setlocal name 'CAP_SUPPORTEDCAPS CAP_IAFIELDD_VALUE found' if ',${get:g_supportedcaps},' !~contains ',CAP_IAFIELDD_VALUE,' goto MAIN.CAP_SUPPORTEDCAPS.FAIL echo.passfail '${get:name}' 'pass' ; goto MAIN.CAP_SUPPORTEDCAPS.DONE :MAIN.CAP_SUPPORTEDCAPS.FAIL echo.passfail '${get:name}' 'fail - ${sts:} ${ret:}' setlocal certifyresult 'fail' goto MAIN.DONE :MAIN.CAP_SUPPORTEDCAPS.DONE ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; ICAP_SUPPORTEDEXTIMAGEINFO: check that all metadata is supported. We're not ; checking for TWEI_IAFIELDE_VALUE, since it's not required... ; setlocal name 'ICAP_SUPPORTEDEXTIMAGEINFO MSG_GET' dsmentry src ds dg_control dat_capability msg_get 'ICAP_SUPPORTEDEXTIMAGEINFO,0,0,0' setlocal icapsupportedextimageinfo '${ret:}' if '${sts:}' != 'SUCCESS' goto MAIN.ICAP_SUPPORTEDEXTIMAGEINFO.FAIL echo.passfail '${get:name}' 'pass' ; setlocal name 'ICAP_SUPPORTEDEXTIMAGEINFO TWEI_IALEVEL found' if ',${get:icapsupportedextimageinfo},' !~contains ',TWEI_IALEVEL,' goto MAIN.ICAP_SUPPORTEDEXTIMAGEINFO.FAIL echo.passfail '${get:name}' 'pass' ; setlocal name 'ICAP_SUPPORTEDEXTIMAGEINFO TWEI_IAFIELDA_VALUE found' if ',${get:icapsupportedextimageinfo},' !~contains ',TWEI_IAFIELDA_VALUE,' goto MAIN.ICAP_SUPPORTEDEXTIMAGEINFO.FAIL echo.passfail '${get:name}' 'pass' setlocal name 'ICAP_SUPPORTEDEXTIMAGEINFO TWEI_IAFIELDB_VALUE found' if ',${get:icapsupportedextimageinfo},' !~contains ',TWEI_IAFIELDB_VALUE,' goto MAIN.ICAP_SUPPORTEDEXTIMAGEINFO.FAIL echo.passfail '${get:name}' 'pass' setlocal name 'ICAP_SUPPORTEDEXTIMAGEINFO TWEI_IAFIELDC_VALUE found' if ',${get:icapsupportedextimageinfo},' !~contains ',TWEI_IAFIELDC_VALUE,' goto MAIN.ICAP_SUPPORTEDEXTIMAGEINFO.FAIL echo.passfail '${get:name}' 'pass' setlocal name 'ICAP_SUPPORTEDEXTIMAGEINFO TWEI_IAFIELDD_VALUE found' if ',${get:icapsupportedextimageinfo},' !~contains ',TWEI_IAFIELDD_VALUE,' goto MAIN.ICAP_SUPPORTEDEXTIMAGEINFO.FAIL echo.passfail '${get:name}' 'pass' goto MAIN.ICAP_SUPPORTEDEXTIMAGEINFO.DONE ; :MAIN.ICAP_SUPPORTEDEXTIMAGEINFO.FAIL echo.passfail '${get:name}' 'fail - ${sts:} ${ret:}' setlocal certifyresult 'fail' :MAIN.ICAP_SUPPORTEDEXTIMAGEINFO.DONE ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; CAP_IMAGEADDRESSENABLED resets to FALSE... ; setlocal name 'CAP_IMAGEADDRESSENABLED resets to FALSE' dsmentry src ds dg_control dat_capability msg_reset 'CAP_IMAGEADDRESSENABLED,0,0,0' if '${sts:}' != 'SUCCESS' goto MAIN.CAP_IMAGEADDRESSENABLEDFALSE.SKIP if ',${ret:},' !~contains ',FALSE,' goto MAIN.CAP_IMAGEADDRESSENABLEDFALSE.SKIP echo.passfail '${get:name}' 'pass' ; goto MAIN.CAP_IMAGEADDRESSENABLEDFALSE.DONE :MAIN.CAP_IMAGEADDRESSENABLEDFALSE.SKIP echo.passfail '${get:name}' 'skip - ${sts:} ${ret:}' setlocal certifyresult 'fail' goto MAIN.DONE :MAIN.CAP_IMAGEADDRESSENABLEDFALSE.DONE ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; CAP_IMAGEADDRESSENABLED set to TRUE... ; setlocal name 'CAP_IMAGEADDRESSENABLED set to TRUE' dsmentry src ds dg_control dat_capability msg_set 'CAP_IMAGEADDRESSENABLED,TWON_ONEVALUE,TWTY_BOOL,TRUE' if '${sts:}' != 'SUCCESS' goto MAIN.CAP_IMAGEADDRESSENABLEDTRUE.FAIL dsmentry src ds dg_control dat_capability msg_getcurrent 'CAP_IMAGEADDRESSENABLED,0,0,0' if '${sts:}' != 'SUCCESS' goto MAIN.CAP_IMAGEADDRESSENABLEDTRUE.FAIL if ',${ret:},' !~contains ',TRUE,' goto MAIN.CAP_IMAGEADDRESSENABLEDTRUE.FAIL echo.passfail '${get:name}' 'pass' ; goto MAIN.CAP_IMAGEADDRESSENABLEDTRUE.DONE :MAIN.CAP_IMAGEADDRESSENABLEDTRUE.FAIL echo.passfail '${get:name}' 'skip - ${sts:} ${ret:}' setlocal certifyresult 'fail' goto MAIN.DONE :MAIN.CAP_IMAGEADDRESSENABLEDTRUE.DONE ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Figure out which transfers we're checking... ; setlocal name 'get ICAP_XFERMECH' dsmentry src ds dg_control dat_capability msg_get 'ICAP_XFERMECH,0,0,0' if '${sts:}' != 'SUCCESS' goto MAIN.ERROR echo.passfail '${get:name}' 'pass' setlocal xfermech.enum '${ret:}' ; setlocal xfermech.total 0 ; total supported transfers ; ; Turn twsx_* values into dat_image*xfer values... if ',${get:xfermech.enum},' !~contains ',TWSX_NATIVE,' goto MAIN.ERROR ; mandatory setlocal xfermech.list 'DAT_IMAGENATIVEXFER' increment xfermech.total ${get:xfermech.total} 1 ; if ',${get:xfermech.enum},' !~contains ',TWSX_MEMORY,' goto MAIN.ERROR ; mandatory setlocal xfermech.list '${get:xfermech.list},DAT_IMAGEMEMXFER' increment xfermech.total ${get:xfermech.total} 1 ; if ',${get:xfermech.enum},' !~contains ',TWSX_FILE,' goto MAIN.XFERMECH.SKIPFILE setlocal xfermech.list '${get:xfermech.list},DAT_IMAGEFILEXFER' increment xfermech.total ${get:xfermech.total} 1 :MAIN.XFERMECH.SKIPFILE ; if ',${get:xfermech.enum},' !~contains ',TWSX_MEMFILE,' goto MAIN.XFERMECH.SKIPMEMFILE setlocal xfermech.list '${get:xfermech.list},DAT_IMAGEMEMFILEXFER' increment xfermech.total ${get:xfermech.total} 1 :MAIN.XFERMECH.SKIPMEMFILE ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; We need at least 8 sheets of paper, 10 if the driver supports CAP_IAFIELDE_LEVEL. ; Multiply that by the number of transfers we'll be doing. ; setlocal sheets.onexfer 8 if ',${get:g_supportedcaps},' !~contains ',CAP_IAFIELDE_LEVEL,' goto MAIN.8SHEETSONLY increment sheets.onexfer ${get:sheets.onexfer} 2 :MAIN.8SHEETSONLY multiply sheets ${get:sheets.onexfer} ${get:xfermech.total} ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Prompt the user... ; echo.prompt echo.prompt "Scanning will take place now. A progress indicator may appear, but no other echo.prompt "interaction should be needed." echo.prompt echo.prompt "Place ${get:sheets} sheets in the scanner's feeder. The scanner may print text" echo.prompt "on them. If the feeder cannot accept ${get:sheets} sheets, put in as many" echo.prompt "multiples of ${get:sheets.onexfer} sheets that it can handle. The script will prompt" echo.prompt "for more if needed." echo.prompt pause '(press the ENTER key when ready to continue)' echo.prompt ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; We'll loop here over each of the transfers... ; setlocal xfermech.index -1 ; one less than the first index for xfermech.list :MAIN.XFERMECH.NEXT increment xfermech.index ${get:xfermech.index} 1 setlocal xfermech.value '${getindex:xfermech.list:${get:xfermech.index}}' if '${get:xfermech.value}' == '' goto MAIN.XFERMECH.DONE ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Test image address level 1 with fixed field, confirm support for 0 and no padding... ; echo.titletest '${get:xfermech.value} Set IA: FIXED.0001' 1 call CERTIFY '${get:xfermech.value}' '${folder:parent}' 'TWEI_IAFIELDA_VALUE' 'TWIA_FIXED,#####,FIXED' 'TWIA_LEVEL1,0000,1' 'TWIA_UNUSED,,' 'TWIA_UNUSED,,' 'TWIA_UNUSED,,' if '${ret:}' != 'pass' goto MAIN.ERROR ; echo.titletest '${get:xfermech.value} Set IA: FIXED.1' 1 call CERTIFY '${get:xfermech.value}' '${folder:parent}' 'TWEI_IAFIELDA_VALUE' 'TWIA_FIXED,#####,FIXED' 'TWIA_LEVEL1,####,1' 'TWIA_UNUSED,,' 'TWIA_UNUSED,,' 'TWIA_UNUSED,,' if '${ret:}' != 'pass' goto MAIN.ERROR ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Test image address level 2 with fixed field, confirm support for 0 and no padding... ; echo.titletest '${get:xfermech.value} Set IA: FIXED.0020.0001' 1 call CERTIFY '${get:xfermech.value}' '${folder:parent}' 'TWEI_IAFIELDA_VALUE' 'TWIA_FIXED,#####,FIXED' 'TWIA_LEVEL2,0000,20' 'TWIA_LEVEL1,0000,1' 'TWIA_UNUSED,,' 'TWIA_UNUSED,,' if '${ret:}' != 'pass' goto MAIN.ERROR ; echo.titletest '${get:xfermech.value} Set IA: FIXED.20.1' 1 call CERTIFY '${get:xfermech.value}' '${folder:parent}' 'TWEI_IAFIELDA_VALUE' 'TWIA_FIXED,#####,FIXED' 'TWIA_LEVEL2,####,20' 'TWIA_LEVEL1,####,1' 'TWIA_UNUSED,,' 'TWIA_UNUSED,,' if '${ret:}' != 'pass' goto MAIN.ERROR ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Test image address level 3 with fixed field, confirm support for 0 and no padding... ; echo.titletest '${get:xfermech.value} Set IA: FIXED.0300.0020.0001' 1 call CERTIFY '${get:xfermech.value}' '${folder:parent}' 'TWEI_IAFIELDA_VALUE' 'TWIA_FIXED,#####,FIXED' 'TWIA_LEVEL3,0000,300' 'TWIA_LEVEL2,0000,20' 'TWIA_LEVEL1,0000,1' 'TWIA_UNUSED,,' if '${ret:}' != 'pass' goto MAIN.ERROR ; echo.titletest '${get:xfermech.value} Set IA: FIXED.300.20.1' 1 call CERTIFY '${get:xfermech.value}' '${folder:parent}' 'TWEI_IAFIELDA_VALUE' 'TWIA_FIXED,#####,FIXED' 'TWIA_LEVEL3,####,300' 'TWIA_LEVEL2,####,20' 'TWIA_LEVEL1,####,1' 'TWIA_UNUSED,,' if '${ret:}' != 'pass' goto MAIN.ERROR ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Test image address level 4 with fixed field (skip if TWIA_LEVEL4 is not supported), ; confirm support for 0 and no padding... ; if ',${get:icapsupportedextimageinfo},' !~contains 'TWIA_LEVEL4' goto MAIN.LEVEL4.SKIP echo.titletest '${get:xfermech.value} Set IA: FIXED.4000.0300.0020.0001' 1 call CERTIFY '${get:xfermech.value}' '${folder:parent}' 'TWEI_IAFIELDA_VALUE' 'TWIA_FIXED,#####,FIXED' 'TWIA_LEVEL4,0000,4000' 'TWIA_LEVEL3,0000,300' 'TWIA_LEVEL2,0000,20' 'TWIA_LEVEL1,0000,1' if '${ret:}' != 'pass' goto MAIN.ERROR ; echo.titletest '${get:xfermech.value} Set IA: FIXED.4000.300.20.1' 1 call CERTIFY '${get:xfermech.value}' '${folder:parent}' 'TWEI_IAFIELDA_VALUE' 'TWIA_FIXED,#####,FIXED' 'TWIA_LEVEL4,####,4000' 'TWIA_LEVEL3,####,300' 'TWIA_LEVEL2,####,20' 'TWIA_LEVEL1,####,1' if '${ret:}' != 'pass' goto MAIN.ERROR :MAIN.LEVEL4.SKIP ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Next transfer mechanism... ; goto MAIN.XFERMECH.NEXT :MAIN.XFERMECH.DONE ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; All done... ; :MAIN.DONE echo " " return '${get:certifyresult}' ; :MAIN.ERROR echo.passfail '${get:name}' 'fail' echo " " return '${get:certifyresult}' ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Function: Certify ; ; Arguments ; arg:1 - name of the script to run ; arg:2 - name of test (used for files) ; arg:3 - TWEI_IAFIELD*_VALUE containing the fixed field (can be empty if none) ; arg:4 - fielda settings (level,printformat,value) ; arg:5 - fieldb settings (level,printformat,value) ; arg:6 - fieldc settings (level,printformat,value) ; arg:7 - fieldd settings (level,printformat,value) ; arg:8 - fielde settings (level,printformat,value) ; ; Returns ; pass/fail ; :CERTIFY ; run '${arg:1}' '${arg:2}' '${arg:3}' '${arg:4}' '${arg:5}' '${arg:6}' '${arg:7}' '${arg:8}' if '${ret:}' != 'pass' goto CERTIFY.FAIL return 'pass' ; :CERTIFY.FAIL setlocal certifyresult 'fail' return 'fail' ================================================ FILE: twaincs/source/twaincscert/source/data/certification/140 - Image Address Badge/SetCapabilities.tc ================================================ ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; SetCapabilities ; Reset the driver's capabilites, and then set capabilities for this test. Note that one can only ; get this badge for the ADF. This is a production mode feature, so we're not testing the flatbed. ; Image Addressing allows us to track and catagorize images in a batch. ; ; We follow the capability ordering: ; MSG_RESETALL ; set ICAP_XFERMECH.....................${arg:1} ; set CAP_FEEDERENABLED.................TRUE ; set CAP_XFERCOUNT.....................1 ; set ICAP_EXTIMAGEINFO.................TRUE ; set CAP_IMAGEADDRESSENABLED...........TRUE ; set CAP_IAFIELD*_LEVEL................TWIA_* ; set CAP_IAFIELD*_PRINTFORMAT..........0's or #'s ; set CAP_IAFIELD*_VALUE................'IA-' for fixed field or numbers ; if CAP_PRINTERENABLED is supported ; set CAP_PRINTERENABLED.............TRUE ; set CAP_PRINTERMODE................TWPM_IMAGEADDRESSSTRING ; set CAP_PRINTERSTRING..............'PRINT' ; set CAP_PRINTERSUFFIX..............'TEST' ; end ; ; The test passes if all operations return TWRC_SUCCESS. ; ; Arguments ; arg:1 - TWSX_* value for ICAP_XFERMECH ; arg:2 - value of caller's indent ; arg:3 - total fields in use (detects if field e is active) ; arg:4 - field A level,printformat,value (ex: 'twia_fixed,###,IA-') ; arg:5 - field B level,printformat,value (ex: 'twia_level4,000,1') ; arg:6 - field C level,printformat,value (ex: 'twia_level3,000,1') ; arg:7 - field D level,printformat,value (ex: 'twia_level2,000,1') ; arg:8 - field E level,printformat,value (ex: 'twia_level1,000,1') ; ; Locals ; indent - indent the passfail text ; name - name of the current test ; twsx - TWSX_* value for ICAP_XFERMECH ; totalfields - total fields in use (0 - 5) ; fielda - field A ; fieldb - field B ; fieldc - field C ; fieldd - field D ; fielde - field E ; ; Returns ; pass/fail ; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Initialize... ; setlocal twsx '${arg:1}' setlocal indent '${arg:2}' setlocal totalfields '${arg:3}' setlocal fielda '${arg:4}' setlocal fieldb '${arg:5}' setlocal fieldc '${arg:6}' setlocal fieldd '${arg:7}' setlocal fielde '${arg:8}' ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; MSG_RESETALL ; If return code is not TWRC_SUCCESS, end with an error ; setlocal name 'MSG_RESETALL' dsmentry src ds dg_control dat_capability msg_resetall '0,0,0,0' if '${sts:}' != 'SUCCESS' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Set ICAP_XFERMECH... ; setlocal name 'ICAP_XFERMECH MSG_SET ${get:twsx}' dsmentry src ds dg_control dat_capability msg_set 'ICAP_XFERMECH,TWON_ONEVALUE,TWTY_UINT16,${get:twsx}' if '${sts:}' != 'SUCCESS' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Set CAP_FEEDERENABLED to TRUE ; setlocal name 'CAP_FEEDERENABLED MSG_SET TRUE' dsmentry src ds dg_control dat_capability msg_set 'CAP_FEEDERENABLED,TWON_ONEVALUE,TWTY_BOOL,TRUE' if '${sts:}' != 'SUCCESS' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Set CAP_XFERCOUNT to 1 ; setlocal name 'CAP_XFERCOUNT MSG_SET 1' dsmentry src ds dg_control dat_capability msg_set 'CAP_XFERCOUNT,TWON_ONEVALUE,TWTY_INT16,1' if '${sts:}' != 'SUCCESS' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Set ICAP_EXTIMAGEINFO to TRUE ; setlocal name 'ICAP_EXTIMAGEINFO MSG_SET TRUE' dsmentry src ds dg_control dat_capability msg_set 'ICAP_EXTIMAGEINFO,TWON_ONEVALUE,TWTY_BOOL,TRUE' if '${sts:}' != 'SUCCESS' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; CAP_IMAGEADDRESSENABLED resets to FALSE ; setlocal name 'CAP_IMAGEADDRESSENABLED resets to FALSE' dsmentry src ds dg_control dat_capability msg_reset 'CAP_IMAGEADDRESSENABLED,0,0,0' if '${sts:}' != 'SUCCESS' goto MAIN.ERROR.ECHOPASSFAIL if ',${ret:},' !~contains ',FALSE,' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; CAP_IMAGEADDRESSENABLED set to TRUE ; setlocal name 'CAP_IMAGEADDRESSENABLED set to TRUE' dsmentry src ds dg_control dat_capability msg_set 'CAP_IMAGEADDRESSENABLED,TWON_ONEVALUE,TWTY_BOOL,TRUE' if '${sts:}' != 'SUCCESS' goto MAIN.ERROR.ECHOPASSFAIL dsmentry src ds dg_control dat_capability msg_getcurrent 'CAP_IMAGEADDRESSENABLED,0,0,0' if '${sts:}' != 'SUCCESS' goto MAIN.ERROR.ECHOPASSFAIL if ',${ret:},' !~contains ',TRUE,' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Set the image address capabilities... ; call SET_IMAGEADDRESS_LEVEL '${get:indent}' '${getindex:fielda:0}' '${getindex:fieldb:0}' '${getindex:fieldc:0}' '${getindex:fieldd:0}' '${getindex:fielde:0}' if '${ret:}' == 'skip' goto MAIN.SKIP if '${ret:}' != 'pass' goto MAIN.ERROR call SET_IMAGEADDRESS_PRINTFORMAT '${get:indent}' '${getindex:fielda:1}' '${getindex:fieldb:1}' '${getindex:fieldc:1}' '${getindex:fieldd:1}' '${getindex:fielde:1}' if '${ret:}' == 'skip' goto MAIN.SKIP if '${ret:}' != 'pass' goto MAIN.ERROR call SET_IMAGEADDRESS_VALUE '${get:indent}' '${getindex:fielda:2}' '${getindex:fieldb:2}' '${getindex:fieldc:2}' '${getindex:fieldd:2}' '${getindex:fielde:2}' if '${ret:}' == 'skip' goto MAIN.SKIP if '${ret:}' != 'pass' goto MAIN.ERROR ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Set the printer capabilites, if supported... ; if ',${get:g_supportedcaps},' !~contains ',CAP_PRINTERENABLED,' goto MAIN.CAP_PRINTERENABLED.SKIP ; setlocal name 'CAP_PRINTERENABLED MSG_SET TRUE' dsmentry src ds dg_control dat_capability msg_set 'CAP_PRINTERENABLED,TWON_ONEVALUE,TWTY_BOOL,TRUE' if '${sts:}' != 'SUCCESS' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' ; setlocal name 'CAP_PRINTERMODE MSG_SET TWPM_IMAGEADDRESSSTRING' dsmentry src ds dg_control dat_capability msg_set 'CAP_PRINTERMODE,TWON_ONEVALUE,TWTY_UINT16,TWPM_IMAGEADDRESSSTRING' if '${sts:}' != 'SUCCESS' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' ; setlocal name 'CAP_PRINTERSTRING MSG_SET "PRINT"' dsmentry src ds dg_control dat_capability msg_set 'CAP_PRINTERSTRING,TWON_ONEVALUE,TWTY_STR255,PRINT' if '${sts:}' != 'SUCCESS' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' ; setlocal name 'CAP_PRINTERSUFFIX MSG_SET "TEST"' dsmentry src ds dg_control dat_capability msg_set 'CAP_PRINTERSUFFIX,TWON_ONEVALUE,TWTY_STR255,TEST' if '${sts:}' != 'SUCCESS' goto MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'pass' ; :MAIN.CAP_PRINTERENABLED.SKIP ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Summary and cleanup... ; ; We passed... :MAIN.PASS return 'pass' ; ; Skip this item... :MAIN.SKIP return 'skip' ; ; Ruh-roh... :MAIN.ERROR.ECHOPASSFAIL echo.passfail '${get:indent}${get:name}' 'fail - ${sts:} ${ret:}' :MAIN.ERROR return 'fail' ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Function: SET_IMAGEADDRESS_LEVEL ; Set the image address levels based on the arguments passed in. Return 'skip' if a field isn't ; supported (not tested for fields A, B, C and D). Otherwise it's pass or fail. Arguments are ; TWIA_LEVEL_* values. ; ; Arguments ; arg:1 - indent ; arg:2 - field A ; arg:3 - field B ; arg:4 - field C ; arg:5 - field D ; arg:6 - field E ; ; Globals ; g_supportedcaps - return from MSG_GET CAP_SUPPORTEDCAPS in 'Image Address Badge.tc' ; ; Locals ; indent - offset the output ; name - name of the test ; fielda - level for fielda ; fieldb - level for fieldb ; fieldc - level for fieldc ; fieldd - level for fieldd ; fielde - level for fielde ; ; Returns ; pass/fail ; :SET_IMAGEADDRESS_LEVEL ; ; Init stuff... setlocal indent '${arg:1}' setlocal fielda '${arg:2}' setlocal fieldb '${arg:3}' setlocal fieldc '${arg:4}' setlocal fieldd '${arg:5}' setlocal fielde '${arg:6}' ; ; Set FIELD A (must have this) setlocal name 'Set CAP_IAFIELDA_LEVEL to <${get:fielda}>' if '${get:fielda}' == '' goto SET_IMAGEADDRESS_LEVEL.FAIL ; have to have this argument if ',${get:g_supportedcaps},' !~contains ',CAP_IAFIELDA_LEVEL,' goto SET_IMAGEADDRESS_LEVEL.FAIL dsmentry src ds dg_control dat_capability msg_set 'CAP_IAFIELDA_LEVEL,TWON_ONEVALUE,TWTY_UINT16,${get:fielda}' if '${sts:}' == 'BADVALUE' goto SET_IMAGEADDRESS_LEVEL.FAIL if '${sts:}' != 'SUCCESS' goto SET_IMAGEADDRESS_LEVEL.FAIL echo.passfail '${get:indent}${get:name}' 'pass' ; ; Set FIELD B (must have this) setlocal name 'Set CAP_IAFIELDB_LEVEL to <${get:fieldb}>' if '${get:fieldb}' == '' goto SET_IMAGEADDRESS_LEVEL.PASS ; optional argument if ',${get:g_supportedcaps},' !~contains ',CAP_IAFIELDB_LEVEL,' goto SET_IMAGEADDRESS_LEVEL.FAIL dsmentry src ds dg_control dat_capability msg_set 'CAP_IAFIELDB_LEVEL,TWON_ONEVALUE,TWTY_UINT16,${get:fieldb}' if '${sts:}' == 'BADVALUE' goto SET_IMAGEADDRESS_LEVEL.FAIL if '${sts:}' != 'SUCCESS' goto SET_IMAGEADDRESS_LEVEL.FAIL echo.passfail '${get:indent}${get:name}' 'pass' ; ; Set FIELD C (must have this) setlocal name 'Set CAP_IAFIELDC_LEVEL to <${get:fieldc}>' if '${get:fieldc}' == '' goto SET_IMAGEADDRESS_LEVEL.PASS ; optional argument if ',${get:g_supportedcaps},' !~contains ',CAP_IAFIELDC_LEVEL,' goto SET_IMAGEADDRESS_LEVEL.FAIL dsmentry src ds dg_control dat_capability msg_set 'CAP_IAFIELDC_LEVEL,TWON_ONEVALUE,TWTY_UINT16,${get:fieldc}' if '${sts:}' == 'BADVALUE' goto SET_IMAGEADDRESS_LEVEL.FAIL if '${sts:}' != 'SUCCESS' goto SET_IMAGEADDRESS_LEVEL.FAIL echo.passfail '${get:indent}${get:name}' 'pass' ; ; Set FIELD D (must have this) setlocal name 'Set CAP_IAFIELDD_LEVEL to <${get:fieldd}>' if '${get:fieldd}' == '' goto SET_IMAGEADDRESS_LEVEL.PASS ; optional argument if ',${get:g_supportedcaps},' !~contains ',CAP_IAFIELDD_LEVEL,' goto SET_IMAGEADDRESS_LEVEL.FAIL dsmentry src ds dg_control dat_capability msg_set 'CAP_IAFIELDD_LEVEL,TWON_ONEVALUE,TWTY_UINT16,${get:fieldd}' if '${sts:}' == 'BADVALUE' goto SET_IMAGEADDRESS_LEVEL.FAIL if '${sts:}' != 'SUCCESS' goto SET_IMAGEADDRESS_LEVEL.FAIL echo.passfail '${get:indent}${get:name}' 'pass' ; ; Set FIELD E (optional) setlocal name 'Set CAP_IAFIELDE_LEVEL to <${get:fielde}>' if '${get:fielde}' == '' goto SET_IMAGEADDRESS_LEVEL.PASS ; optional argument if ',${get:g_supportedcaps},' !~contains ',CAP_IAFIELDE_LEVEL,' goto SET_IMAGEADDRESS_LEVEL.PASS dsmentry src ds dg_control dat_capability msg_set 'CAP_IAFIELDE_LEVEL,TWON_ONEVALUE,TWTY_UINT16,${get:fielde}' if '${sts:}' == 'BADVALUE' goto SET_IMAGEADDRESS_LEVEL.FAIL if '${sts:}' != 'SUCCESS' goto SET_IMAGEADDRESS_LEVEL.FAIL echo.passfail '${get:indent}${get:name}' 'pass' ; :SET_IMAGEADDRESS_LEVEL.PASS return 'pass' ; :SET_IMAGEADDRESS_LEVEL.FAIL setglobal '${arg:3}' 'fail' echo.passfail '${get:indent}${get:name}' 'fail' return 'fail' ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Function: SET_IMAGEADDRESS_PRINTFORMAT ; Set the image address print format based on the arguments passed in. Return 'skip' if a field isn't ; supported (not tested for fields A, B, C and D). Otherwise it's pass or fail. Arguments are strings ; of either #'s or 0's... ; ; Arguments ; arg:1 - indent ; arg:2 - field A ; arg:3 - field B ; arg:4 - field C ; arg:5 - field D ; arg:6 - field E ; ; Globals ; g_supportedcaps - return from MSG_GET CAP_SUPPORTEDCAPS in 'Image Address Badge.tc' ; ; Locals ; indent - offset the output ; name - name of the test ; fielda - printformat for fielda ; fieldb - printformat for fieldb ; fieldc - printformat for fieldc ; fieldd - printformat for fieldd ; fielde - printformat for fielde ; ; Returns ; pass/fail/skip ; :SET_IMAGEADDRESS_PRINTFORMAT ; ; Init stuff... setlocal indent '${arg:1}' setlocal fielda '${arg:2}' setlocal fieldb '${arg:3}' setlocal fieldc '${arg:4}' setlocal fieldd '${arg:5}' setlocal fielde '${arg:6}' ; ; Set FIELD A (must have this) setlocal name 'Set CAP_IAFIELDA_PRINTFORMAT to <${get:fielda}>' if '${get:fielda}' == '' goto SET_IMAGEADDRESS_PRINTFORMAT.FAIL ; have to have this argument if ',${get:g_supportedcaps},' !~contains ',CAP_IAFIELDA_PRINTFORMAT,' goto SET_IMAGEADDRESS_PRINTFORMAT.FAIL dsmentry src ds dg_control dat_capability msg_set 'CAP_IAFIELDA_PRINTFORMAT,TWON_ONEVALUE,TWTY_STR32,${get:fielda}' if '${sts:}' != 'SUCCESS' goto SET_IMAGEADDRESS_PRINTFORMAT.FAIL echo.passfail '${get:indent}${get:name}' 'pass' ; ; Set FIELD B (must have this) setlocal name 'Set CAP_IAFIELDB_PRINTFORMAT to <${get:fieldb}>' if '${get:fieldb}' == '' goto SET_IMAGEADDRESS_PRINTFORMAT.PASS ; optional argument if ',${get:g_supportedcaps},' !~contains ',CAP_IAFIELDB_PRINTFORMAT,' goto SET_IMAGEADDRESS_PRINTFORMAT.FAIL dsmentry src ds dg_control dat_capability msg_set 'CAP_IAFIELDB_PRINTFORMAT,TWON_ONEVALUE,TWTY_STR32,${get:fieldb}' if '${sts:}' != 'SUCCESS' goto SET_IMAGEADDRESS_PRINTFORMAT.FAIL echo.passfail '${get:indent}${get:name}' 'pass' ; ; Set FIELD C (must have this) setlocal name 'Set CAP_IAFIELDC_PRINTFORMAT to <${get:fieldc}>' if '${get:fieldc}' == '' goto SET_IMAGEADDRESS_PRINTFORMAT.PASS ; optional argument if ',${get:g_supportedcaps},' !~contains ',CAP_IAFIELDC_PRINTFORMAT,' goto SET_IMAGEADDRESS_PRINTFORMAT.FAIL dsmentry src ds dg_control dat_capability msg_set 'CAP_IAFIELDC_PRINTFORMAT,TWON_ONEVALUE,TWTY_STR32,${get:fieldc}' if '${sts:}' != 'SUCCESS' goto SET_IMAGEADDRESS_PRINTFORMAT.FAIL echo.passfail '${get:indent}${get:name}' 'pass' ; ; Set FIELD D (must have this) setlocal name 'Set CAP_IAFIELDD_PRINTFORMAT to <${get:fieldd}>' if '${get:fieldd}' == '' goto SET_IMAGEADDRESS_PRINTFORMAT.PASS ; optional argument if ',${get:g_supportedcaps},' !~contains ',CAP_IAFIELDD_PRINTFORMAT,' goto SET_IMAGEADDRESS_PRINTFORMAT.FAIL dsmentry src ds dg_control dat_capability msg_set 'CAP_IAFIELDD_PRINTFORMAT,TWON_ONEVALUE,TWTY_STR32,${get:fieldd}' if '${sts:}' != 'SUCCESS' goto SET_IMAGEADDRESS_PRINTFORMAT.FAIL echo.passfail '${get:indent}${get:name}' 'pass' ; ; Set FIELD E (optional) setlocal name 'Set CAP_IAFIELDE_PRINTFORMAT to <${get:fielde}>' if '${get:fielde}' == '' goto SET_IMAGEADDRESS_PRINTFORMAT.PASS ; optional argument if ',${get:g_supportedcaps},' !~contains ',CAP_IAFIELDE_PRINTFORMAT,' goto SET_IMAGEADDRESS_PRINTFORMAT.PASS dsmentry src ds dg_control dat_capability msg_set 'CAP_IAFIELDE_PRINTFORMAT,TWON_ONEVALUE,TWTY_STR32,${get:fielde}' if '${sts:}' != 'SUCCESS' goto SET_IMAGEADDRESS_PRINTFORMAT.FAIL echo.passfail '${get:indent}${get:name}' 'pass' ; :SET_IMAGEADDRESS_PRINTFORMAT.PASS return 'pass' ; :SET_IMAGEADDRESS_PRINTFORMAT.FAIL setglobal '${arg:3}' 'fail' echo.passfail '${get:indent}${get:name}' 'fail' return 'fail' ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Function: SET_IMAGEADDRESS_VALUE ; Set the image address value based on the arguments passed in. Return 'skip' if a field isn't ; supported (not tested for fields A, B, C and D). Otherwise it's pass or fail. Arguments are ; strings... ; ; Arguments ; arg:1 - indent ; arg:2 - field A ; arg:3 - field B ; arg:4 - field C ; arg:5 - field D ; arg:6 - field E ; ; Globals ; g_supportedcaps - return from MSG_GET CAP_SUPPORTEDCAPS in 'Image Address Badge.tc' ; ; Locals ; indent - offset the output ; name - name of the test ; fielda - value for fielda ; fieldb - value for fieldb ; fieldc - value for fieldc ; fieldd - value for fieldd ; fielde - value for fielde ; ; Returns ; pass/fail/skip ; :SET_IMAGEADDRESS_VALUE ; ; Init stuff... setlocal indent '${arg:1}' setlocal fielda '${arg:2}' setlocal fieldb '${arg:3}' setlocal fieldc '${arg:4}' setlocal fieldd '${arg:5}' setlocal fielde '${arg:6}' ; ; Set FIELD A (must have this) setlocal name 'Set CAP_IAFIELDA_VALUE to <${get:fielda}>' if '${get:fielda}' == '' goto SET_IMAGEADDRESS_VALUE.FAIL ; have to have this argument if ',${get:g_supportedcaps},' !~contains ',CAP_IAFIELDA_VALUE,' goto SET_IMAGEADDRESS_VALUE.FAIL dsmentry src ds dg_control dat_capability msg_set 'CAP_IAFIELDA_VALUE,TWON_ONEVALUE,TWTY_STR32,${get:fielda}' if '${sts:}' != 'SUCCESS' goto SET_IMAGEADDRESS_VALUE.FAIL echo.passfail '${get:indent}${get:name}' 'pass' ; ; Set FIELD B (must have this) setlocal name 'Set CAP_IAFIELDB_VALUE to <${get:fieldb}>' if '${get:fieldb}' == '' goto SET_IMAGEADDRESS_VALUE.PASS ; optional argument if ',${get:g_supportedcaps},' !~contains ',CAP_IAFIELDB_VALUE,' goto SET_IMAGEADDRESS_VALUE.FAIL dsmentry src ds dg_control dat_capability msg_set 'CAP_IAFIELDB_VALUE,TWON_ONEVALUE,TWTY_STR32,${get:fieldb}' if '${sts:}' != 'SUCCESS' goto SET_IMAGEADDRESS_VALUE.FAIL echo.passfail '${get:indent}${get:name}' 'pass' ; ; Set FIELD C (must have this) setlocal name 'Set CAP_IAFIELDC_VALUE to <${get:fieldc}>' if '${get:fieldc}' == '' goto SET_IMAGEADDRESS_VALUE.PASS ; optional argument if ',${get:g_supportedcaps},' !~contains ',CAP_IAFIELDC_VALUE,' goto SET_IMAGEADDRESS_VALUE.FAIL dsmentry src ds dg_control dat_capability msg_set 'CAP_IAFIELDC_VALUE,TWON_ONEVALUE,TWTY_STR32,${get:fieldc}' if '${sts:}' != 'SUCCESS' goto SET_IMAGEADDRESS_VALUE.FAIL echo.passfail '${get:indent}${get:name}' 'pass' ; ; Set FIELD D (must have this) setlocal name 'Set CAP_IAFIELDD_VALUE to <${get:fieldd}>' if '${get:fieldd}' == '' goto SET_IMAGEADDRESS_VALUE.PASS ; optional argument if ',${get:g_supportedcaps},' !~contains ',CAP_IAFIELDD_VALUE,' goto SET_IMAGEADDRESS_VALUE.FAIL dsmentry src ds dg_control dat_capability msg_set 'CAP_IAFIELDD_VALUE,TWON_ONEVALUE,TWTY_STR32,${get:fieldd}' if '${sts:}' != 'SUCCESS' goto SET_IMAGEADDRESS_VALUE.FAIL echo.passfail '${get:indent}${get:name}' 'pass' ; ; Set FIELD E (optional) setlocal name 'Set CAP_IAFIELDE_VALUE to <${get:fielde}>' if '${get:fielde}' == '' goto SET_IMAGEADDRESS_VALUE.PASS ; optional argument if ',${get:g_supportedcaps},' !~contains ',CAP_IAFIELDE_VALUE,' goto SET_IMAGEADDRESS_VALUE.PASS dsmentry src ds dg_control dat_capability msg_set 'CAP_IAFIELDE_VALUE,TWON_ONEVALUE,TWTY_UINT16,${get:fielde}' if '${sts:}' != 'SUCCESS' goto SET_IMAGEADDRESS_VALUE.FAIL echo.passfail '${get:indent}${get:name}' 'pass' ; :SET_IMAGEADDRESS_VALUE.PASS return 'pass' ; :SET_IMAGEADDRESS_VALUE.FAIL setglobal '${arg:3}' 'fail' echo.passfail '${get:indent}${get:name}' 'fail' return 'fail' ================================================ FILE: twaincs/source/twaincscert/source/data/certification/Certification.tc ================================================ ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; TWAIN Certification Script ; Run all tests needed to pass TWAIN self-certification. ; ; Arguments ; arg:1 - TW_IDENTITY.ProductName of scanner to test ; arg:2 - TW_IDENTITY.Version.Major + '.' + TW_IDENTITY.Version.Minor ; arg:3 - comma separated list of: all, barcode, imageaddress, patcode, or imagsaddress ; ; Globals ; g_certifyresult - pass/fail result of all standard tests ; g_certifytwaindirect - pass/fail result of twain direct badge ; g_certifyprinting - pass/fail result of printing badge ; g_certifypatchcode - pass/fail result of patch code badge ; g_certifybarcode - pass/fail result of barcode badge ; g_certifyimageaddress - pass/fail result of image address badge ; ; Locals ; badges - badges to check ; title - script info ; twidentity.productname - product name of scanner to test ; ; Returns ; pass or fail ; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Initialize stuff... ; setlocal title 'TWAIN Certification Script v1.1 02-Sep-2021' setlocal twidentity.productname '${arg:1}' setlocal twidentity.version '${arg:2}' setlocal badges '${arg:3}' setglobal g_certifyresult 'pass' setglobal g_certifytwaindirect '' setglobal g_certifyprinting '' setglobal g_certifypatchcode '' setglobal g_certifybarcode '' setglobal g_certifyimageaddress '' ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Initialize our report... ; report initialize '${get:twidentity.productname}' call ECHOANDLOG info '${get:title}' call ECHOANDLOG info '~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~' call ECHOANDLOG info 'operating system is ${platform:}' call ECHOANDLOG info 'program is ${program:}' call ECHOANDLOG info 'started at ${localtime:yyyy-MM-dd/hh:mm:ss}' ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Load our global tables... ; run '${folder:certification}/LoadTables' ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Run all the mains tests... ; call RUNCERTIFICATION '010 - TWAIN Standard Capability Tests' '${get:twidentity.productname}' g_certifyresult call RUNCERTIFICATION '020 - Vendor Custom Capability Tests' '${get:twidentity.productname}' g_certifyresult call RUNCERTIFICATION '030 - Status Return Tests' '${get:twidentity.productname}' g_certifyresult call RUNCERTIFICATION '040 - Stress Tests' '${get:twidentity.productname}' g_certifyresult call RUNCERTIFICATION '050 - Non-UI Image Transfer Tests' '${get:twidentity.productname}' g_certifyresult call RUNCERTIFICATION '060 - UI Image Transfer Tests' '${get:twidentity.productname}' g_certifyresult call RUNCERTIFICATION '070 - CAP_XFERCOUNT Tests' '${get:twidentity.productname}' g_certifyresult call RUNCERTIFICATION '080 - Version Tests' '${get:twidentity.productname}' g_certifyresult call RUNCERTIFICATION '090 - Verify Values for MSG_OPENDS, MSG_RESET, and MSG_RESETALL' '${get:twidentity.productname}' g_certifyresult ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Do the badges... ; ; TWAIN Direct... if ',${get:badges},' ~contains ',all,' goto MAIN.BADGE.TWAINDIRECT if ',${get:badges},' ~contains ',twaindirect,' goto MAIN.BADGE.TWAINDIRECT goto MAIN.BADGE.TWAINDIRECT.SKIP :MAIN.BADGE.TWAINDIRECT call RUNCERTIFICATION '100 - TWAIN Direct Badge' '${get:twidentity.productname}' g_certifytwaindirect :MAIN.BADGE.TWAINDIRECT.SKIP ; ; Printing... if ',${get:badges},' ~contains ',all,' goto MAIN.BADGE.PRINTING if ',${get:badges},' ~contains ',printing,' goto MAIN.BADGE.PRINTING goto MAIN.BADGE.PRINTING.SKIP :MAIN.BADGE.PRINTING call RUNCERTIFICATION '110 - Printing Badge' '${get:twidentity.productname}' g_certifyprinting :MAIN.BADGE.PRINTING.SKIP ; ; Patch Code... if ',${get:badges},' ~contains ',all,' goto MAIN.BADGE.PATCHCODE if ',${get:badges},' ~contains ',patchcode,' goto MAIN.BADGE.PATCHCODE goto MAIN.BADGE.PATCHCODE.SKIP :MAIN.BADGE.PATCHCODE call RUNCERTIFICATION '120 - Patch Code Badge' '${get:twidentity.productname}' g_certifypatchcode :MAIN.BADGE.PATCHCODE.SKIP ; ; Barcode... if ',${get:badges},' ~contains ',all,' goto MAIN.BADGE.BARCODE if ',${get:badges},' ~contains ',barcode,' goto MAIN.BADGE.BARCODE goto MAIN.BADGE.BARCODE.SKIP :MAIN.BADGE.BARCODE call RUNCERTIFICATION '130 - Barcode Badge' '${get:twidentity.productname}' g_certifybarcode :MAIN.BADGE.BARCODE.SKIP ; ; Image Address... if ',${get:badges},' ~contains ',all,' goto MAIN.BADGE.IMAGEADDRESS if ',${get:badges},' ~contains ',imageaddress,' goto MAIN.BADGE.IMAGEADDRESS goto MAIN.BADGE.IMAGEADDRESS.SKIP :MAIN.BADGE.IMAGEADDRESS call RUNCERTIFICATION '140 - Image Address Badge' '${get:twidentity.productname}' g_certifyimageaddress :MAIN.BADGE.IMAGEADDRESS.SKIP ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; How did we do? ; if '${get:g_certifyresult}' != 'pass' goto MAIN.FAIL call ECHOANDLOG info call ECHOANDLOG info call ECHOANDLOG info call ECHOANDLOG info 'ended at ${localtime:yyyy-MM-dd/hh:mm:ss}' call ECHOANDLOG info '**************************************' call ECHOANDLOG info 'The scanner passed TWAIN Certification' ; if '${get:g_certifytwaindirect}' != 'pass' goto MAIN.TWAINDIRECT.CERTIFY.SKIP call ECHOANDLOG info 'Badge: TWAIN Direct' :MAIN.TWAINDIRECT.CERTIFY.SKIP ; if '${get:g_certifyprinting}' != 'pass' goto MAIN.PRINTING.CERTIFY.SKIP call ECHOANDLOG info 'Badge: Printing' :MAIN.PRINTING.CERTIFY.SKIP ; if '${get:g_certifypatchcode}' != 'pass' goto MAIN.PATCHCODE.CERTIFY.SKIP call ECHOANDLOG info 'Badge: Patch Code' :MAIN.PATCHCODE.CERTIFY.SKIP ; if '${get:g_certifybarcode}' != 'pass' goto MAIN.BARCODE.CERTIFY.SKIP call ECHOANDLOG info 'Badge: Barcode' :MAIN.BARCODE.CERTIFY.SKIP ; if '${get:g_certifyimageaddress}' != 'pass' goto MAIN.IMAGEADDRESS.CERTIFY.SKIP call ECHOANDLOG info 'Badge: Image Address' :MAIN.IMAGEADDRESS.CERTIFY.SKIP ; call ECHOANDLOG info '**************************************' report save echo 'report saved to ${report:}' return 'pass' ; :MAIN.FAIL call ECHOANDLOG error call ECHOANDLOG error call ECHOANDLOG error call ECHOANDLOG error 'ended at ${localtime:yyyy-MM-dd/hh:mm:ss}' call ECHOANDLOG error '********************************************' call ECHOANDLOG error 'The scanner did not pass TWAIN Certification' call ECHOANDLOG error '********************************************' report save echo 'report saved to ${report:}' return 'fail' ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Function: RunCertification ; arg:1 - folder to run in ; arg:2 - TW_IDENTITY.ProductName of scanner to test ; arg:3 - global value to update on fail ; returns: (none) ; :RUNCERTIFICATION ; setglobal ${arg:3} 'pass' ; assume pass cd '${folder:certification}/${arg:1}' run Certification '${arg:2}' '${arg:3}' cd '${folder:certification}' return 'pass' ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Function: Certify ; arg:1 - script to run ; arg:2 - TW_IDENTITY.ProductName of scanner to test ; arg:3 - global value to update on fail ; returns: (none) ; :CERTIFY ; run '${arg:1}' '${arg:2}' if '${ret:}' != 'pass' goto CERTIFY.FAIL return 'pass' ; :CERTIFY.FAIL setglobal '${arg:3}' 'fail' return 'fail' ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Function: EchoAndLog ; arg:1 - severity (normal, info, error) ; arg:2 - text ; returns: (none) ; :ECHOANDLOG ; if '${arg:1}' == 'info' goto ECHOANDLOG.INFO echo.red '${arg:2}' log error '#${arg:2}' return :ECHOANDLOG.INFO echo.green '${arg:2}' log info '#${arg:2}' :ECHOANDLOG.ERROR return ================================================ FILE: twaincs/source/twaincscert/source/data/certification/Closeds.tc ================================================ ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Closeds ; Open the requested TWAIN driver... ; ; Arguments ; arg:1 - TW_IDENTITY.ProductName of scanner to test ; arg:2 - set to 'embedded', to limit messages ; arg:3 - indent padding for embedded ; ; Globals ; (none) ; ; Locals ; closedsresult - pass/fail for the close ; embedded - try to fit into the flow of other echo.passfail stuff ; indent - indenting for echo.passfail ; ; Returns ; pass or fail ; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Initialize... ; if '${arg:2}' == 'embedded' goto MAIN.TITLE.SKIP echo.titletest 'Closeds' :MAIN.TITLE.SKIP setlocal closedsresult 'pass' setlocal indent '' setlocal embedded '${arg:2}' if '${get:embedded}' != 'embedded' goto MAIN.SKIP.INDENT setlocal indent '${arg:3}' :MAIN.SKIP.INDENT ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Rewind the driver, close and unload the DSM... ; setlocal name 'dg_control/dat_pendingxfers/msg_endxfer' if '${state:}' < '7' goto REWIND.6 dsmentry src ds dg_control dat_pendingxfers msg_endxfer '0,0' if '${sts:}' == 'SUCCESS' goto REWIND.7.SUCCESS echo.passfail '${get:indent}${get:name}' 'fail' setlocal closedsresult 'fail' goto REWIND.6 :REWIND.7.SUCCESS echo.passfail '${get:indent}${get:name}' 'pass' ; :REWIND.6 setlocal name 'dg_control/dat_pendingxfers/msg_reset' if '${state:}' < '6' goto REWIND.5 dsmentry src ds dg_control dat_pendingxfers msg_reset '0,0' if '${sts:}' == 'SUCCESS' goto REWIND.6.SUCCESS echo.passfail '${get:indent}${get:name}' 'fail' setlocal closedsresult 'fail' goto REWIND.5 :REWIND.6.SUCCESS echo.passfail '${get:indent}${get:name}' 'pass' ; :REWIND.5 setlocal name 'dg_control/dat_userinterface/msg_disableds' if '${state:}' < '5' goto REWIND.4 dsmentry src null dg_control dat_userinterface msg_disableds '0,0' if '${sts:}' == 'SUCCESS' goto REWIND.5.SUCCESS echo.passfail '${get:indent}${get:name}' 'fail' setlocal closedsresult 'fail' goto REWIND.4 :REWIND.5.SUCCESS echo.passfail '${get:indent}${get:name}' 'pass' ; :REWIND.4 setlocal name 'dg_control/dat_identity/msg_closeds' if '${state:}' < '4' goto REWIND.3 dsmentry src null dg_control dat_identity msg_closeds '${ds:}' if '${sts:}' == 'SUCCESS' goto REWIND.4.SUCCESS echo.passfail '${get:indent}${get:name}' 'fail' setlocal closedsresult 'fail' goto REWIND.3 :REWIND.4.SUCCESS echo.passfail '${get:indent}${get:name}' 'pass' ; :REWIND.3 setlocal name 'dg_control/dat_parent/msg_closedsm' if '${state:}' < '3' goto REWIND.2 dsmentry src null dg_control dat_parent msg_closedsm hwnd if '${sts:}' == 'SUCCESS' goto REWIND.3.SUCCESS echo.passfail '${get:indent}${get:name}' 'fail' setlocal closedsresult 'fail' goto REWIND.2 :REWIND.3.SUCCESS echo.passfail '${get:indent}${get:name}' 'pass' ; :REWIND.2 setlocal name 'dsmunload' if '${state:}' < '2' goto REWIND.1 dsmunload echo.passfail '${get:indent}${get:name}' 'pass' ; :REWIND.1 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Summary and cleanup... ; if '${get:closedsresult}' == 'pass' goto MAIN.PASS if '${get:embedded}' == 'embedded' goto MAIN.ERROR.SKIPSUMMARY echo.passfail 'SUMMARY' 'fail' :MAIN.ERROR.SKIPSUMMARY return 'fail' ; :MAIN.PASS if '${get:embedded}' == 'embedded' goto MAIN.PASS.SKIPSUMMARY echo.passfail 'SUMMARY' 'pass' :MAIN.PASS.SKIPSUMMARY return 'pass' ================================================ FILE: twaincs/source/twaincscert/source/data/certification/LoadTables.tc ================================================ ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Tables ; Load common values used globally ; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Stuff to load... ; call LOADCAPABILITYTABLE call LOADTWSTRUCTTABLE return ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Function: LOADTWSTRUCTTABLE ; Loads indecies we use to look into TW_* structures... ; :LOADTWSTRUCTTABLE ; ; These index off TW_CAPABILITY, which is why they don't start at 0... setglobal TW_ARRAY.ItemType 2 setglobal TW_ARRAY.NumItems 3 setglobal TW_ARRAY.ItemList 4 ; setglobal TW_CAPABILITY.Cap 0 setglobal TW_CAPABILITY.ConType 1 ; setglobal TW_CUSTOMDSDATA.InfoLength 0 setglobal TW_CUSTOMDSDATA.hData 1 ; setglobal TW_DEVICEEVENT.Event 0 setglobal TW_DEVICEEVENT.DeviceName 1 setglobal TW_DEVICEEVENT.BatteryMinutes 2 setglobal TW_DEVICEEVENT.BatteryPercentage 3 setglobal TW_DEVICEEVENT.PowerSupply 4 setglobal TW_DEVICEEVENT.XResolution 5 setglobal TW_DEVICEEVENT.YResolution 6 setglobal TW_DEVICEEVENT.FlashUsed2 7 setglobal TW_DEVICEEVENT.AutomaticCapture 8 setglobal TW_DEVICEEVENT.TimeBeforeFirstCapture 9 setglobal TW_DEVICEEVENT.TimeBetweenCaptures 10 ; ; These index off TW_CAPABILITY, which is why they don't start at 0... setglobal TW_ENUMERATION.ItemType 2 setglobal TW_ENUMERATION.NumItems 3 setglobal TW_ENUMERATION.CurrentIndex 4 setglobal TW_ENUMERATION.DefaultIndex 5 setglobal TW_ENUMERATION.ItemList 6 ; setglobal TW_EXTIMAGEINFO.NumInfos 0 setglobal TW_EXTIMAGEINFO.Info 1 ; setglobal TW_FILESYSTEM.InputName 0 setglobal TW_FILESYSTEM.OutputName 1 setglobal TW_FILESYSTEM.Context 2 setglobal TW_FILESYSTEM.Recursive 3 ; union #1 setglobal TW_FILESYSTEM.Subdirectories 3 ; union #1 setglobal TW_FILESYSTEM.FileType 4 ; union #2 setglobal TW_FILESYSTEM.FileSystemType 4 ; union #2 setglobal TW_FILESYSTEM.Size 5 setglobal TW_FILESYSTEM.CreateTimeDate 6 setglobal TW_FILESYSTEM.ModifiedTimeDate 7 setglobal TW_FILESYSTEM.FreeSpace 8 setglobal TW_FILESYSTEM.NewImageSize 9 setglobal TW_FILESYSTEM.NumberOfFiles 10 setglobal TW_FILESYSTEM.NumberOfSnippets 11 setglobal TW_FILESYSTEM.DeviceGroupMask 12 setglobal TW_FILESYSTEM.Reserved 13 ; setglobal TW_IDENTITY.Id 0 setglobal TW_IDENTITY.Version.MajorNum 1 setglobal TW_IDENTITY.Version.MinorNum 2 setglobal TW_IDENTITY.Version.Language 3 setglobal TW_IDENTITY.Version.Country 4 setglobal TW_IDENTITY.Version.Info 5 setglobal TW_IDENTITY.ProtocolMajor 6 setglobal TW_IDENTITY.ProtocolMinor 7 setglobal TW_IDENTITY.SupportedGroups 8 setglobal TW_IDENTITY.Manufacturer 9 setglobal TW_IDENTITY.ProductFamily 10 setglobal TW_IDENTITY.ProductName 11 ; setglobal TW_IMAGEINFO.XResolution 0 setglobal TW_IMAGEINFO.YResolution 1 setglobal TW_IMAGEINFO.ImageWidth 2 setglobal TW_IMAGEINFO.ImageHeight 3 setglobal TW_IMAGEINFO.SamplesPerPixel 4 setglobal TW_IMAGEINFO.BitsPerSample 5 ; 8 elements in this one setglobal TW_IMAGEINFO.BitsPerPixel 13 setglobal TW_IMAGEINFO.Planar 14 setglobal TW_IMAGEINFO.PixelType 15 setglobal TW_IMAGEINFO.Compression 16 ; setglobal TW_IMAGELAYOUT.Frame.Left 0 setglobal TW_IMAGELAYOUT.Frame.Top 1 setglobal TW_IMAGELAYOUT.Frame.Right 2 setglobal TW_IMAGELAYOUT.Frame.Bottom 3 setglobal TW_IMAGELAYOUT.Frame.DocumentNumber 4 setglobal TW_IMAGELAYOUT.Frame.PageNumber 5 setglobal TW_IMAGELAYOUT.Frame.FrameNumber 6 ; ; These index off TW_EXTIMAGEINFO, which is why they don't start at 0... setglobal TW_INFO.InfoID 1 setglobal TW_INFO.ItemType 2 setglobal TW_INFO.NumItems 3 setglobal TW_INFO.ReturnCode 4 setglobal TW_INFO.Item 5 ; setglobal TW_METRICS.SizeOf 0 setglobal TW_METRICS.ImageCount 1 setglobal TW_METRICS.SheetCount 2 ; ; These index off TW_CAPABILITY, which is why they don't start at 0... setglobal TW_ONEVALUE.ItemType 2 setglobal TW_ONEVALUE.Item 3 ; setglobal TW_PENDINGXFERS.Count 0 setglobal TW_PENDINGXFERS.Reserved 1 setglobal TW_PENDINGXFERS.TW_JOBCONTROL.EOJ 2 ; macOS only ; ; These index off TW_CAPABILITY, which is why they don't start at 0... setglobal TW_RANGE.ItemType 2 setglobal TW_RANGE.MinValue 3 setglobal TW_RANGE.MaxValue 4 setglobal TW_RANGE.StepSize 5 setglobal TW_RANGE.DefaultValue 6 setglobal TW_RANGE.CurrentValue 7 ; setglobal TW_SETUPFILEXFER.FileName 0 setglobal TW_SETUPFILEXFER.Format 1 setglobal TW_SETUPFILEXFER.VRefNum 2 ; setglobal TW_SETUPMEMXFER.MinBufSize 0 setglobal TW_SETUPMEMXFER.MaxBufSize 1 setglobal TW_SETUPMEMXFER.Preferred 2 ; setglobal TW_STATUS.ConditionCode 0 setglobal TW_STATUS.Data 1 setglobal TW_STATUS.Reserved 1 ; whatever >.< ; setglobal TW_STATUSUTF8.Status.ConditionCode 0 setglobal TW_STATUSUTF8.Status.Data 1 setglobal TW_STATUSUTF8.Status.Reserved 1 ; see above setglobal TW_STATUSUTF8.Size 2 setglobal TW_STATUSUTF8.UTF8string 3 ; setglobal TW_TWAINDIRECT.SizeOf 0 setglobal TW_TWAINDIRECT.CommunicationManager 1 setglobal TW_TWAINDIRECT.Send 2 setglobal TW_TWAINDIRECT.SendSize 3 setglobal TW_TWAINDIRECT.Receive 4 setglobal TW_TWAINDIRECT.ReceiveSize 5 ; setglobal TW_USERINTERFACE.ShowUI 0 setglobal TW_USERINTERFACE.ModalUI 1 setglobal TW_USERINTERFACE.hParent 2 ; return ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Function: LOADCAPABILITYTABLE ; Loads stuff we need to confirm about each known capability, we'll skip the ; g_ prefix for these items. Note the use of sys_capabilitytable, this will ; record the names of all the capabilities for us, so we can access them in ; any script... ; :LOADCAPABILITYTABLE ; setrecord on 'sys_capabilitytable' '.Flags' '.Flags' ; setglobal ACAP_XFERMECH.ConType TWON_ENUMERATION,TWON_ONEVALUE setglobal ACAP_XFERMECH.ItemType TWTY_UINT16 setglobal ACAP_XFERMECH.ValueAfterOpen TWSX_NATIVE setglobal ACAP_XFERMECH.ValueAfterReset TWSX_NATIVE setglobal ACAP_XFERMECH.Flags '' ; setglobal CAP_ALARMS.ConType TWON_ARRAY setglobal CAP_ALARMS.ItemType TWTY_UINT16 setglobal CAP_ALARMS.ValueAfterOpen UNDEFINED setglobal CAP_ALARMS.ValueAfterReset UNDEFINED setglobal CAP_ALARMS.Flags '' ; setglobal CAP_ALARMVOLUME.ConType TWON_RANGE,TWON_ONEVALUE setglobal CAP_ALARMVOLUME.ItemType TWTY_INT32 setglobal CAP_ALARMVOLUME.ValueAfterOpen UNDEFINED setglobal CAP_ALARMVOLUME.ValueAfterReset UNDEFINED setglobal CAP_ALARMVOLUME.Flags '' ; setglobal CAP_AUTHOR.ConType TWON_ONEVALUE setglobal CAP_AUTHOR.ItemType TWTY_STR128 setglobal CAP_AUTHOR.ValueAfterOpen '' setglobal CAP_AUTHOR.ValueAfterReset '' setglobal CAP_AUTHOR.Flags '' ; setglobal CAP_AUTOFEED.ConType TWON_ENUMERATION setglobal CAP_AUTOFEED.ItemType TWTY_BOOL setglobal CAP_AUTOFEED.ValueAfterOpen UNDEFINED setglobal CAP_AUTOFEED.ValueAfterReset TRUE setglobal CAP_AUTOFEED.Flags '' ; setglobal CAP_AUTOMATICCAPTURE.ConType TWON_RANGE,TWON_ONEVALUE setglobal CAP_AUTOMATICCAPTURE.ItemType TWTY_INT32 setglobal CAP_AUTOMATICCAPTURE.ValueAfterOpen 0 setglobal CAP_AUTOMATICCAPTURE.ValueAfterReset 0 setglobal CAP_AUTOMATICCAPTURE.Flags '' ; setglobal CAP_AUTOMATICSENSEMEDIUM.ConType TWON_ENUMERATION setglobal CAP_AUTOMATICSENSEMEDIUM.ItemType TWTY_BOOL setglobal CAP_AUTOMATICSENSEMEDIUM.ValueAfterOpen UNDEFINED setglobal CAP_AUTOMATICSENSEMEDIUM.ValueAfterReset UNDEFINED setglobal CAP_AUTOMATICSENSEMEDIUM.Flags '' ; setglobal CAP_AUTOSCAN.ConType TWON_ENUMERATION setglobal CAP_AUTOSCAN.ItemType TWTY_BOOL setglobal CAP_AUTOSCAN.ValueAfterOpen UNDEFINED setglobal CAP_AUTOSCAN.ValueAfterReset TRUE setglobal CAP_AUTOSCAN.Flags '' ; setglobal CAP_BATTERYMINUTES.ConType TWON_ONEVALUE setglobal CAP_BATTERYMINUTES.ItemType TWTY_INT32 setglobal CAP_BATTERYMINUTES.ValueAfterOpen UNEDFINED setglobal CAP_BATTERYMINUTES.ValueAfterReset UNEDFINED setglobal CAP_BATTERYMINUTES.Flags '' ; setglobal CAP_BATTERYPERCENTAGE.ConType TWON_ONEVALUE setglobal CAP_BATTERYPERCENTAGE.ItemType TWTY_INT16 setglobal CAP_BATTERYPERCENTAGE.ValueAfterOpen UNDEFINED setglobal CAP_BATTERYPERCENTAGE.ValueAfterReset UNDEFINED setglobal CAP_BATTERYPERCENTAGE.Flags '' ; setglobal CAP_CAMERAENABLED.ConType TWON_ENUMERATION setglobal CAP_CAMERAENABLED.ItemType TWTY_BOOL setglobal CAP_CAMERAENABLED.ValueAfterOpen UNDEFINED setglobal CAP_CAMERAENABLED.ValueAfterReset UNDEFINED setglobal CAP_CAMERAENABLED.Flags '' ; setglobal CAP_CAMERAORDER.ConType TWON_ARRAY setglobal CAP_CAMERAORDER.ItemType TWTY_UINT16 setglobal CAP_CAMERAORDER.ValueAfterOpen UNDEFINED setglobal CAP_CAMERAORDER.ValueAfterReset UNDEFINED setglobal CAP_CAMERAORDER.Flags '' ; setglobal CAP_CAMERAPREVIEWUI.ConType TWON_ENUMERATION setglobal CAP_CAMERAPREVIEWUI.ItemType TWTY_BOOL setglobal CAP_CAMERAPREVIEWUI.ValueAfterOpen UNDEFINED setglobal CAP_CAMERAPREVIEWUI.ValueAfterReset UNDEFINED setglobal CAP_CAMERAPREVIEWUI.Flags '' ; setglobal CAP_CAMERASIDE.ConType TWON_ENUMERATION,TWON_ONEVALUE setglobal CAP_CAMERASIDE.ItemType TWTY_UINT16 setglobal CAP_CAMERASIDE.ValueAfterOpen UNDEFINED setglobal CAP_CAMERASIDE.ValueAfterReset UNDEFINED ; should be TWCS_BOTH, but need a solution for ADF vs Flatbed setglobal CAP_CAMERASIDE.Flags '' ; setglobal CAP_CAPTION.ConType TWON_ONEVALUE setglobal CAP_CAPTION.ItemType TWTY_STR255 setglobal CAP_CAPTION.ValueAfterOpen '' setglobal CAP_CAPTION.ValueAfterReset '' setglobal CAP_CAPTION.Flags '' ; setglobal CAP_CLEARBUFFERS.ConType TWON_ENUMERATION,TWON_ONEVALUE setglobal CAP_CLEARBUFFERS.ItemType TWTY_BOOL setglobal CAP_CLEARBUFFERS.ValueAfterOpen UNDEFINED setglobal CAP_CLEARBUFFERS.ValueAfterReset UNDEFINED setglobal CAP_CLEARBUFFERS.Flags 'deprecated' ; setglobal CAP_CLEARPAGE.ConType TWON_ENUMERATION setglobal CAP_CLEARPAGE.ItemType TWTY_BOOL setglobal CAP_CLEARPAGE.ValueAfterOpen FALSE setglobal CAP_CLEARPAGE.ValueAfterReset FALSE setglobal CAP_CLEARPAGE.Flags '' ; setglobal CAP_CUSTOMDSDATA.ConType TWON_ENUMERATION setglobal CAP_CUSTOMDSDATA.ItemType TWTY_BOOL setglobal CAP_CUSTOMDSDATA.ValueAfterOpen UNDEFINED setglobal CAP_CUSTOMDSDATA.ValueAfterReset UNDEFINED setglobal CAP_CUSTOMDSDATA.Flags '' ; setglobal CAP_CUSTOMINTERFACEGUID.ConType TWON_ONEVALUE setglobal CAP_CUSTOMINTERFACEGUID.ItemType TWTY_STR255 setglobal CAP_CUSTOMINTERFACEGUID.ValueAfterOpen UNDEFINED setglobal CAP_CUSTOMINTERFACEGUID.ValueAfterReset UNDEFINED setglobal CAP_CUSTOMINTERFACEGUID.Flags '' ; setglobal CAP_DEVICEEVENT.ConType TWON_ARRAY setglobal CAP_DEVICEEVENT.ItemType TWTY_UINT16 setglobal CAP_DEVICEEVENT.ValueAfterOpen UNDEFINED setglobal CAP_DEVICEEVENT.ValueAfterReset '' setglobal CAP_DEVICEEVENT.Flags '' ; setglobal CAP_DEVICEONLINE.ConType TWON_ENUMERATION setglobal CAP_DEVICEONLINE.ItemType TWTY_BOOL setglobal CAP_DEVICEONLINE.ValueAfterOpen UNDEFINED setglobal CAP_DEVICEONLINE.ValueAfterReset UNDEFINED setglobal CAP_DEVICEONLINE.Flags 'mandatory' ; setglobal CAP_DEVICETIMEDATE.ConType TWON_ONEVALUE setglobal CAP_DEVICETIMEDATE.ItemType TWTY_STR32 setglobal CAP_DEVICETIMEDATE.ValueAfterOpen UNDEFINED setglobal CAP_DEVICETIMEDATE.ValueAfterReset UNDEFINED setglobal CAP_DEVICETIMEDATE.Flags '' ; setglobal CAP_DOUBLEFEEDDETECTION.ConType TWON_ARRAY setglobal CAP_DOUBLEFEEDDETECTION.ItemType TWTY_UINT16 setglobal CAP_DOUBLEFEEDDETECTION.ValueAfterOpen UNDEFINED setglobal CAP_DOUBLEFEEDDETECTION.ValueAfterReset '' setglobal CAP_DOUBLEFEEDDETECTION.Flags '' ; setglobal CAP_DOUBLEFEEDDETECTIONLENGTH.ConType TWON_RANGE setglobal CAP_DOUBLEFEEDDETECTIONLENGTH.ItemType TWTY_FIX32 setglobal CAP_DOUBLEFEEDDETECTIONLENGTH.ValueAfterOpen UNDEFINED setglobal CAP_DOUBLEFEEDDETECTIONLENGTH.ValueAfterReset UNDEFINED setglobal CAP_DOUBLEFEEDDETECTIONLENGTH.Flags '' ; setglobal CAP_DOUBLEFEEDDETECTIONRESPONSE.ConType TWON_ARRAY setglobal CAP_DOUBLEFEEDDETECTIONRESPONSE.ItemType TWTY_UINT16 setglobal CAP_DOUBLEFEEDDETECTIONRESPONSE.ValueAfterOpen UNDEFINED setglobal CAP_DOUBLEFEEDDETECTIONRESPONSE.ValueAfterReset UNDEFINED setglobal CAP_DOUBLEFEEDDETECTIONRESPONSE.Flags '' ; setglobal CAP_DOUBLEFEEDDETECTIONSENSITIVITY.ConType TWON_ENUMERATION setglobal CAP_DOUBLEFEEDDETECTIONSENSITIVITY.ItemType TWTY_UINT16 setglobal CAP_DOUBLEFEEDDETECTIONSENSITIVITY.ValueAfterOpen UNDEFINED setglobal CAP_DOUBLEFEEDDETECTIONSENSITIVITY.ValueAfterReset UNDEFINED setglobal CAP_DOUBLEFEEDDETECTIONSENSITIVITY.Flags '' ; setglobal CAP_DUPLEX.ConType TWON_ONEVALUE setglobal CAP_DUPLEX.ItemType TWTY_UINT16 setglobal CAP_DUPLEX.ValueAfterOpen UNDEFINED setglobal CAP_DUPLEX.ValueAfterReset UNDEFINED setglobal CAP_DUPLEX.Flags '' ; setglobal CAP_DUPLEXENABLED.ConType TWON_ENUMERATION setglobal CAP_DUPLEXENABLED.ItemType TWTY_BOOL setglobal CAP_DUPLEXENABLED.ValueAfterOpen UNDEFINED setglobal CAP_DUPLEXENABLED.ValueAfterReset UNDEFINED setglobal CAP_DUPLEXENABLED.Flags '' ; setglobal CAP_ENABLEDSUIONLY.ConType TWON_ENUMERATION setglobal CAP_ENABLEDSUIONLY.ItemType TWTY_BOOL setglobal CAP_ENABLEDSUIONLY.ValueAfterOpen UNDEFINED setglobal CAP_ENABLEDSUIONLY.ValueAfterReset UNDEFINED setglobal CAP_ENABLEDSUIONLY.Flags '' ; setglobal CAP_ENDORSER.ConType TWON_RANGE setglobal CAP_ENDORSER.ItemType TWTY_UINT32 setglobal CAP_ENDORSER.ValueAfterOpen UNDEFINED setglobal CAP_ENDORSER.ValueAfterReset 1 setglobal CAP_ENDORSER.Flags '' ; setglobal CAP_EXTENDEDCAPS.ConType TWON_ARRAY setglobal CAP_EXTENDEDCAPS.ItemType TWTY_UINT16 setglobal CAP_EXTENDEDCAPS.ValueAfterOpen UNDEFINED setglobal CAP_EXTENDEDCAPS.ValueAfterReset UNDEFINED setglobal CAP_EXTENDEDCAPS.Flags '' ; setglobal CAP_FEEDERALIGNMENT.ConType TWON_ENUMERATION,TWON_ONEVALUE setglobal CAP_FEEDERALIGNMENT.ItemType TWTY_UINT16 setglobal CAP_FEEDERALIGNMENT.ValueAfterOpen UNDEFINED setglobal CAP_FEEDERALIGNMENT.ValueAfterReset UNDEFINED setglobal CAP_FEEDERALIGNMENT.Flags '' ; setglobal CAP_FEEDERENABLED.ConType TWON_ENUMERATION setglobal CAP_FEEDERENABLED.ItemType TWTY_BOOL setglobal CAP_FEEDERENABLED.ValueAfterOpen UNDEFINED setglobal CAP_FEEDERENABLED.ValueAfterReset UNDEFINED setglobal CAP_FEEDERENABLED.Flags '' ; setglobal CAP_FEEDERLOADED.ConType TWON_ENUMERATION setglobal CAP_FEEDERLOADED.ItemType TWTY_BOOL setglobal CAP_FEEDERLOADED.ValueAfterOpen UNDEFINED setglobal CAP_FEEDERLOADED.ValueAfterReset UNDEFINED setglobal CAP_FEEDERLOADED.Flags '' ; setglobal CAP_FEEDERORDER.ConType TWON_ENUMERATION,TWON_ONEVALUE setglobal CAP_FEEDERORDER.ItemType TWTY_UINT16 setglobal CAP_FEEDERORDER.ValueAfterOpen UNDEFINED setglobal CAP_FEEDERORDER.ValueAfterReset UNDEFINED setglobal CAP_FEEDERORDER.Flags '' ; setglobal CAP_FEEDERPOCKET.ConType TWON_ARRAY setglobal CAP_FEEDERPOCKET.ItemType TWTY_UINT16 setglobal CAP_FEEDERPOCKET.ValueAfterOpen UNDEFINED setglobal CAP_FEEDERPOCKET.ValueAfterReset UNDEFINED setglobal CAP_FEEDERPOCKET.Flags '' ; setglobal CAP_FEEDERPREP.ConType TWON_ENUMERATION,TWON_ONEVALUE setglobal CAP_FEEDERPREP.ItemType TWTY_BOOL setglobal CAP_FEEDERPREP.ValueAfterOpen UNDEFINED setglobal CAP_FEEDERPREP.ValueAfterReset FALSE setglobal CAP_FEEDERPREP.Flags '' ; setglobal CAP_FEEDPAGE.ConType TWON_ENUMERATION setglobal CAP_FEEDPAGE.ItemType TWTY_BOOL setglobal CAP_FEEDPAGE.ValueAfterOpen UNDEFINED setglobal CAP_FEEDPAGE.ValueAfterReset UNDEFINED setglobal CAP_FEEDPAGE.Flags '' ; setglobal CAP_IAFIELDA_LASTPAGE.ConType TWON_ONEVALUE setglobal CAP_IAFIELDA_LASTPAGE.ItemType TWTY_STR32 setglobal CAP_IAFIELDA_LASTPAGE.ValueAfterOpen UNDEFINED setglobal CAP_IAFIELDA_LASTPAGE.ValueAfterReset UNDEFINED setglobal CAP_IAFIELDA_LASTPAGE.Flags '' ; setglobal CAP_IAFIELDB_LASTPAGE.ConType TWON_ONEVALUE setglobal CAP_IAFIELDB_LASTPAGE.ItemType TWTY_STR32 setglobal CAP_IAFIELDB_LASTPAGE.ValueAfterOpen UNDEFINED setglobal CAP_IAFIELDB_LASTPAGE.ValueAfterReset UNDEFINED setglobal CAP_IAFIELDB_LASTPAGE.Flags '' ; setglobal CAP_IAFIELDC_LASTPAGE.ConType TWON_ONEVALUE setglobal CAP_IAFIELDC_LASTPAGE.ItemType TWTY_STR32 setglobal CAP_IAFIELDC_LASTPAGE.ValueAfterOpen UNDEFINED setglobal CAP_IAFIELDC_LASTPAGE.ValueAfterReset UNDEFINED setglobal CAP_IAFIELDC_LASTPAGE.Flags '' ; setglobal CAP_IAFIELDD_LASTPAGE.ConType TWON_ONEVALUE setglobal CAP_IAFIELDD_LASTPAGE.ItemType TWTY_STR32 setglobal CAP_IAFIELDD_LASTPAGE.ValueAfterOpen UNDEFINED setglobal CAP_IAFIELDD_LASTPAGE.ValueAfterReset UNDEFINED setglobal CAP_IAFIELDD_LASTPAGE.Flags '' ; setglobal CAP_IAFIELDE_LASTPAGE.ConType TWON_ONEVALUE setglobal CAP_IAFIELDE_LASTPAGE.ItemType TWTY_STR32 setglobal CAP_IAFIELDE_LASTPAGE.ValueAfterOpen UNDEFINED setglobal CAP_IAFIELDE_LASTPAGE.ValueAfterReset UNDEFINED setglobal CAP_IAFIELDE_LASTPAGE.Flags '' ; setglobal CAP_IAFIELDA_LEVEL.ConType TWON_ENUMERATION setglobal CAP_IAFIELDA_LEVEL.ItemType TWTY_UINT16 setglobal CAP_IAFIELDA_LEVEL.ValueAfterOpen UNDEFINED setglobal CAP_IAFIELDA_LEVEL.ValueAfterReset TWIA_UNUSED setglobal CAP_IAFIELDA_LEVEL.Flags '' ; setglobal CAP_IAFIELDB_LEVEL.ConType TWON_ENUMERATION setglobal CAP_IAFIELDB_LEVEL.ItemType TWTY_UINT16 setglobal CAP_IAFIELDB_LEVEL.ValueAfterOpen UNDEFINED setglobal CAP_IAFIELDB_LEVEL.ValueAfterReset TWIA_UNUSED setglobal CAP_IAFIELDB_LEVEL.Flags '' ; setglobal CAP_IAFIELDC_LEVEL.ConType TWON_ENUMERATION setglobal CAP_IAFIELDC_LEVEL.ItemType TWTY_UINT16 setglobal CAP_IAFIELDC_LEVEL.ValueAfterOpen UNDEFINED setglobal CAP_IAFIELDC_LEVEL.ValueAfterReset TWIA_UNUSED setglobal CAP_IAFIELDC_LEVEL.Flags '' ; setglobal CAP_IAFIELDD_LEVEL.ConType TWON_ENUMERATION setglobal CAP_IAFIELDD_LEVEL.ItemType TWTY_UINT16 setglobal CAP_IAFIELDD_LEVEL.ValueAfterOpen UNDEFINED setglobal CAP_IAFIELDD_LEVEL.ValueAfterReset TWIA_UNUSED setglobal CAP_IAFIELDD_LEVEL.Flags '' ; setglobal CAP_IAFIELDE_LEVEL.ConType TWON_ENUMERATION setglobal CAP_IAFIELDE_LEVEL.ItemType TWTY_UINT16 setglobal CAP_IAFIELDE_LEVEL.ValueAfterOpen UNDEFINED setglobal CAP_IAFIELDE_LEVEL.ValueAfterReset TWIA_UNUSED setglobal CAP_IAFIELDE_LEVEL.Flags '' ; setglobal CAP_IAFIELDA_PRINTFORMAT.ConType TWON_ONEVALUE setglobal CAP_IAFIELDA_PRINTFORMAT.ItemType TWTY_STR32 setglobal CAP_IAFIELDA_PRINTFORMAT.ValueAfterOpen UNDEFINED setglobal CAP_IAFIELDA_PRINTFORMAT.ValueAfterReset UNDEFINED setglobal CAP_IAFIELDA_PRINTFORMAT.Flags '' ; setglobal CAP_IAFIELDB_PRINTFORMAT.ConType TWON_ONEVALUE setglobal CAP_IAFIELDB_PRINTFORMAT.ItemType TWTY_STR32 setglobal CAP_IAFIELDB_PRINTFORMAT.ValueAfterOpen UNDEFINED setglobal CAP_IAFIELDB_PRINTFORMAT.ValueAfterReset UNDEFINED setglobal CAP_IAFIELDB_PRINTFORMAT.Flags '' ; setglobal CAP_IAFIELDC_PRINTFORMAT.ConType TWON_ONEVALUE setglobal CAP_IAFIELDC_PRINTFORMAT.ItemType TWTY_STR32 setglobal CAP_IAFIELDC_PRINTFORMAT.ValueAfterOpen UNDEFINED setglobal CAP_IAFIELDC_PRINTFORMAT.ValueAfterReset UNDEFINED setglobal CAP_IAFIELDC_PRINTFORMAT.Flags '' ; setglobal CAP_IAFIELDD_PRINTFORMAT.ConType TWON_ONEVALUE setglobal CAP_IAFIELDD_PRINTFORMAT.ItemType TWTY_STR32 setglobal CAP_IAFIELDD_PRINTFORMAT.ValueAfterOpen UNDEFINED setglobal CAP_IAFIELDD_PRINTFORMAT.ValueAfterReset UNDEFINED setglobal CAP_IAFIELDD_PRINTFORMAT.Flags '' ; setglobal CAP_IAFIELDE_PRINTFORMAT.ConType TWON_ONEVALUE setglobal CAP_IAFIELDE_PRINTFORMAT.ItemType TWTY_STR32 setglobal CAP_IAFIELDE_PRINTFORMAT.ValueAfterOpen UNDEFINED setglobal CAP_IAFIELDE_PRINTFORMAT.ValueAfterReset UNDEFINED setglobal CAP_IAFIELDE_PRINTFORMAT.Flags '' ; setglobal CAP_IAFIELDA_VALUE.ConType TWON_ONEVALUE setglobal CAP_IAFIELDA_VALUE.ItemType TWTY_STR32 setglobal CAP_IAFIELDA_VALUE.ValueAfterOpen UNDEFINED setglobal CAP_IAFIELDA_VALUE.ValueAfterReset UNDEFINED setglobal CAP_IAFIELDA_VALUE.Flags '' ; setglobal CAP_IAFIELDB_VALUE.ConType TWON_ONEVALUE setglobal CAP_IAFIELDB_VALUE.ItemType TWTY_STR32 setglobal CAP_IAFIELDB_VALUE.ValueAfterOpen UNDEFINED setglobal CAP_IAFIELDB_VALUE.ValueAfterReset UNDEFINED setglobal CAP_IAFIELDB_VALUE.Flags '' ; setglobal CAP_IAFIELDC_VALUE.ConType TWON_ONEVALUE setglobal CAP_IAFIELDC_VALUE.ItemType TWTY_STR32 setglobal CAP_IAFIELDC_VALUE.ValueAfterOpen UNDEFINED setglobal CAP_IAFIELDC_VALUE.ValueAfterReset UNDEFINED setglobal CAP_IAFIELDC_VALUE.Flags '' ; setglobal CAP_IAFIELDD_VALUE.ConType TWON_ONEVALUE setglobal CAP_IAFIELDD_VALUE.ItemType TWTY_STR32 setglobal CAP_IAFIELDD_VALUE.ValueAfterOpen UNDEFINED setglobal CAP_IAFIELDD_VALUE.ValueAfterReset UNDEFINED setglobal CAP_IAFIELDD_VALUE.Flags '' ; setglobal CAP_IAFIELDE_VALUE.ConType TWON_ONEVALUE setglobal CAP_IAFIELDE_VALUE.ItemType TWTY_STR32 setglobal CAP_IAFIELDE_VALUE.ValueAfterOpen UNDEFINED setglobal CAP_IAFIELDE_VALUE.ValueAfterReset UNDEFINED setglobal CAP_IAFIELDE_VALUE.Flags '' ; setglobal CAP_IMAGEADDRESSENABLED.ConType TWON_ENUMERATION setglobal CAP_IMAGEADDRESSENABLED.ItemType TWTY_BOOL setglobal CAP_IMAGEADDRESSENABLED.ValueAfterOpen UNDEFINED setglobal CAP_IMAGEADDRESSENABLED.ValueAfterReset FALSE setglobal CAP_IMAGEADDRESSENABLED.Flags '' ; setglobal CAP_INDICATORS.ConType TWON_ENUMERATION setglobal CAP_INDICATORS.ItemType TWTY_BOOL setglobal CAP_INDICATORS.ValueAfterOpen TRUE setglobal CAP_INDICATORS.ValueAfterReset TRUE setglobal CAP_INDICATORS.Flags '' ; setglobal CAP_INDICATORSMODE.ConType TWON_ARRAY setglobal CAP_INDICATORSMODE.ItemType TWTY_UINT16 setglobal CAP_INDICATORSMODE.ValueAfterOpen UNDEFINED setglobal CAP_INDICATORSMODE.ValueAfterReset UNDEFINED setglobal CAP_INDICATORSMODE.Flags '' ; setglobal CAP_JOBCONTROL.ConType TWON_ENUMERATION,TWON_ONEVALUE setglobal CAP_JOBCONTROL.ItemType TWTY_UINT16 setglobal CAP_JOBCONTROL.ValueAfterOpen UNDEFINED setglobal CAP_JOBCONTROL.ValueAfterReset TWJC_NONE setglobal CAP_JOBCONTROL.Flags '' ; setglobal CAP_LANGUAGE.ConType TWON_ENUMERATION,TWON_ONEVALUE setglobal CAP_LANGUAGE.ItemType TWTY_UINT16 setglobal CAP_LANGUAGE.ValueAfterOpen UNDEFINED setglobal CAP_LANGUAGE.ValueAfterReset UNDEFINED setglobal CAP_LANGUAGE.Flags '' ; setglobal CAP_MAXBATCHBUFFERS.ConType TWON_RANGE,TWON_ONEVALUE setglobal CAP_MAXBATCHBUFFERS.ItemType TWTY_UINT32 setglobal CAP_MAXBATCHBUFFERS.ValueAfterOpen UNDEFINED setglobal CAP_MAXBATCHBUFFERS.ValueAfterReset UNDEFINED setglobal CAP_MAXBATCHBUFFERS.Flags '' ; setglobal CAP_MICRENABLED.ConType TWON_ENUMERATION setglobal CAP_MICRENABLED.ItemType TWTY_BOOL setglobal CAP_MICRENABLED.ValueAfterOpen UNDEFINED setglobal CAP_MICRENABLED.ValueAfterReset FALSE setglobal CAP_MICRENABLED.Flags '' ; setglobal CAP_PAGEMULTIREACQUIRE.ConType TWON_ENUMERATION,TWON_ONEVALUE setglobal CAP_PAGEMULTIREACQUIRE.ItemType TWTY_BOOL setglobal CAP_PAGEMULTIREACQUIRE.ValueAfterOpen UNDEFINED setglobal CAP_PAGEMULTIREACQUIRE.ValueAfterReset UNDEFINED setglobal CAP_PAGEMULTIREACQUIRE.Flags 'deprecated' ; setglobal CAP_PAPERBINDING.ConType TWON_ENUMERATION setglobal CAP_PAPERBINDING.ItemType TWTY_UINT16 setglobal CAP_PAPERBINDING.ValueAfterOpen UNDEFINED setglobal CAP_PAPERBINDING.ValueAfterReset UNDEFINED setglobal CAP_PAPERBINDING.Flags 'deprecated' ; setglobal CAP_PAPERDETECTABLE.ConType TWON_ENUMERATION setglobal CAP_PAPERDETECTABLE.ItemType TWTY_BOOL setglobal CAP_PAPERDETECTABLE.ValueAfterOpen UNDEFINED setglobal CAP_PAPERDETECTABLE.ValueAfterReset UNDEFINED setglobal CAP_PAPERDETECTABLE.Flags '' ; setglobal CAP_PAPERHANDLING.ConType TWON_ARRAY setglobal CAP_PAPERHANDLING.ItemType TWTY_UINT16 setglobal CAP_PAPERHANDLING.ValueAfterOpen UNDEFINED setglobal CAP_PAPERHANDLING.ValueAfterReset TWPH_NORMAL setglobal CAP_PAPERHANDLING.Flags '' ; setglobal CAP_PASSTHRU.ConType TWON_ENUMERATION,TWON_ONEVALUE setglobal CAP_PASSTHRU.ItemType TWTY_BOOL setglobal CAP_PASSTHRU.ValueAfterOpen UNDEFINED setglobal CAP_PASSTHRU.ValueAfterReset UNDEFINED setglobal CAP_PASSTHRU.Flags 'deprecated' ; setglobal CAP_POWERSAVETIME.ConType TWON_RANGE setglobal CAP_POWERSAVETIME.ItemType TWTY_INT32 setglobal CAP_POWERSAVETIME.ValueAfterOpen UNDEFINED setglobal CAP_POWERSAVETIME.ValueAfterReset UNDEFINED setglobal CAP_POWERSAVETIME.Flags '' ; setglobal CAP_POWERSUPPLY.ConType TWON_ENUMERATION,TWON_ONEVALUE setglobal CAP_POWERSUPPLY.ItemType TWTY_UINT16 setglobal CAP_POWERSUPPLY.ValueAfterOpen UNDEFINED setglobal CAP_POWERSUPPLY.ValueAfterReset UNDEFINED setglobal CAP_POWERSUPPLY.Flags '' ; setglobal CAP_PRINTER.ConType TWON_ENUMERATION,TWON_ONEVALUE setglobal CAP_PRINTER.ItemType TWTY_UINT16 setglobal CAP_PRINTER.ValueAfterOpen UNDEFINED setglobal CAP_PRINTER.ValueAfterReset UNDEFINED setglobal CAP_PRINTER.Flags '' ; setglobal CAP_PRINTERENABLED.ConType TWON_ENUMERATION setglobal CAP_PRINTERENABLED.ItemType TWTY_BOOL setglobal CAP_PRINTERENABLED.ValueAfterOpen UNDEFINED setglobal CAP_PRINTERENABLED.ValueAfterReset FALSE setglobal CAP_PRINTERENABLED.Flags '' ; setglobal CAP_PRINTERCHARROTATION.ConType TWON_ENUMERATION,TWON_RANGE,TWON_ONEVALUE setglobal CAP_PRINTERCHARROTATION.ItemType TWTY_UINT32 setglobal CAP_PRINTERCHARROTATION.ValueAfterOpen UNDEFINED setglobal CAP_PRINTERCHARROTATION.ValueAfterReset 0 setglobal CAP_PRINTERCHARROTATION.Flags '' ; setglobal CAP_PRINTERFONTSTYLE.ConType TWON_ARRAY setglobal CAP_PRINTERFONTSTYLE.ItemType TWTY_UINT16 setglobal CAP_PRINTERFONTSTYLE.ValueAfterOpen UNDEFINED setglobal CAP_PRINTERFONTSTYLE.ValueAfterReset TWPF_NORMAL setglobal CAP_PRINTERFONTSTYLE.Flags '' ; setglobal CAP_PRINTERINDEX.ConType TWON_RANGE,TWON_ONEVALUE setglobal CAP_PRINTERINDEX.ItemType TWTY_UINT32 setglobal CAP_PRINTERINDEX.ValueAfterOpen UNDEFINED setglobal CAP_PRINTERINDEX.ValueAfterReset UNDEFINED setglobal CAP_PRINTERINDEX.Flags '' ; setglobal CAP_PRINTERINDEXLEADCHAR.ConType TWON_ENUMERATION,TWON_ONEVALUE setglobal CAP_PRINTERINDEXLEADCHAR.ItemType TWTY_STR32 setglobal CAP_PRINTERINDEXLEADCHAR.ValueAfterOpen UNDEFINED setglobal CAP_PRINTERINDEXLEADCHAR.ValueAfterReset UNDEFINED setglobal CAP_PRINTERINDEXLEADCHAR.Flags '' ; setglobal CAP_PRINTERINDEXMAXVALUE.ConType TWON_ENUMERATION,TWON_RANGE,TWON_ONEVALUE setglobal CAP_PRINTERINDEXMAXVALUE.ItemType TWTY_UINT32 setglobal CAP_PRINTERINDEXMAXVALUE.ValueAfterOpen UNDEFINED setglobal CAP_PRINTERINDEXMAXVALUE.ValueAfterReset 0 setglobal CAP_PRINTERINDEXMAXVALUE.Flags '' ; setglobal CAP_PRINTERINDEXNUMDIGITS.ConType TWON_ENUMERATION,TWON_RANGE,TWON_ONEVALUE setglobal CAP_PRINTERINDEXNUMDIGITS.ItemType TWTY_UINT32 setglobal CAP_PRINTERINDEXNUMDIGITS.ValueAfterOpen UNDEFINED setglobal CAP_PRINTERINDEXNUMDIGITS.ValueAfterReset 0 setglobal CAP_PRINTERINDEXNUMDIGITS.Flags '' ; setglobal CAP_PRINTERINDEXSTEP.ConType TWON_ENUMERATION,TWON_RANGE,TWON_ONEVALUE setglobal CAP_PRINTERINDEXSTEP.ItemType TWTY_UINT32 setglobal CAP_PRINTERINDEXSTEP.ValueAfterOpen UNDEFINED setglobal CAP_PRINTERINDEXSTEP.ValueAfterReset 1 setglobal CAP_PRINTERINDEXSTEP.Flags '' ; setglobal CAP_PRINTERINDEXTRIGGER.ConType TWON_ARRAY setglobal CAP_PRINTERINDEXTRIGGER.ItemType TWTY_UINT16 setglobal CAP_PRINTERINDEXTRIGGER.ValueAfterOpen UNDEFINED setglobal CAP_PRINTERINDEXTRIGGER.ValueAfterReset TWCT_PAGE setglobal CAP_PRINTERINDEXTRIGGER.Flags '' ; setglobal CAP_PRINTERMODE.ConType TWON_ENUMERATION,TWON_ONEVALUE setglobal CAP_PRINTERMODE.ItemType TWTY_UINT16 setglobal CAP_PRINTERMODE.ValueAfterOpen UNDEFINED setglobal CAP_PRINTERMODE.ValueAfterReset UNDEFINED setglobal CAP_PRINTERMODE.Flags '' ; setglobal CAP_PRINTERSTRING.ConType TWON_ENUMERATION,TWON_ONEVALUE setglobal CAP_PRINTERSTRING.ItemType TWTY_STR255 setglobal CAP_PRINTERSTRING.ValueAfterOpen UNDEFINED setglobal CAP_PRINTERSTRING.ValueAfterReset UNDEFINED setglobal CAP_PRINTERSTRING.Flags '' ; setglobal CAP_PRINTERSTRINGPREVIEW.ConType TWON_ARRAY setglobal CAP_PRINTERSTRINGPREVIEW.ItemType TWTY_STR255 setglobal CAP_PRINTERSTRINGPREVIEW.ValueAfterOpen UNDEFINED setglobal CAP_PRINTERSTRINGPREVIEW.ValueAfterReset UNDEFINED setglobal CAP_PRINTERSTRINGPREVIEW.Flags '' ; setglobal CAP_PRINTERSUFFIX.ConType TWON_ONEVALUE setglobal CAP_PRINTERSUFFIX.ItemType TWTY_STR255 setglobal CAP_PRINTERSUFFIX.ValueAfterOpen UNDEFINED setglobal CAP_PRINTERSUFFIX.ValueAfterReset UNDEFINED setglobal CAP_PRINTERSUFFIX.Flags '' ; setglobal CAP_PRINTERVERTICALOFFSET.ConType TWON_RANGE,TWON_ONEVALUE setglobal CAP_PRINTERVERTICALOFFSET.ItemType TWTY_FIX32 setglobal CAP_PRINTERVERTICALOFFSET.ValueAfterOpen UNDEFINED setglobal CAP_PRINTERVERTICALOFFSET.ValueAfterReset UNDEFINED setglobal CAP_PRINTERVERTICALOFFSET.Flags '' ; setglobal CAP_REACQUIREALLOWED.ConType TWON_ENUMERATION setglobal CAP_REACQUIREALLOWED.ItemType TWTY_BOOL setglobal CAP_REACQUIREALLOWED.ValueAfterOpen UNDEFINED setglobal CAP_REACQUIREALLOWED.ValueAfterReset UNDEFINED setglobal CAP_REACQUIREALLOWED.Flags '' ; setglobal CAP_REWINDPAGE.ConType TWON_ENUMERATION setglobal CAP_REWINDPAGE.ItemType TWTY_BOOL setglobal CAP_REWINDPAGE.ValueAfterOpen FALSE setglobal CAP_REWINDPAGE.ValueAfterReset FALSE setglobal CAP_REWINDPAGE.Flags '' ; setglobal CAP_SEGMENTED.ConType TWON_ENUMERATION,TWON_ONEVALUE setglobal CAP_SEGMENTED.ItemType TWTY_UINT16 setglobal CAP_SEGMENTED.ValueAfterOpen UNDEFINED setglobal CAP_SEGMENTED.ValueAfterReset FALSE setglobal CAP_SEGMENTED.Flags '' ; setglobal CAP_SERIALNUMBER.ConType TWON_ONEVALUE setglobal CAP_SERIALNUMBER.ItemType TWTY_STR255 setglobal CAP_SERIALNUMBER.ValueAfterOpen UNDEFINED setglobal CAP_SERIALNUMBER.ValueAfterReset UNDEFINED setglobal CAP_SERIALNUMBER.Flags '' ; setglobal CAP_SHEETCOUNT.ConType TWON_RANGE,TWON_ONEVALUE setglobal CAP_SHEETCOUNT.ItemType TWTY_UINT32 setglobal CAP_SHEETCOUNT.ValueAfterOpen 0 setglobal CAP_SHEETCOUNT.ValueAfterReset 0 setglobal CAP_SHEETCOUNT.Flags '' ; setglobal CAP_SUPPORTEDCAPS.ConType TWON_ARRAY setglobal CAP_SUPPORTEDCAPS.ItemType TWTY_UINT16 setglobal CAP_SUPPORTEDCAPS.ValueAfterOpen UNDEFINED setglobal CAP_SUPPORTEDCAPS.ValueAfterReset UNDEFINED setglobal CAP_SUPPORTEDCAPS.Flags 'mandatory' ; setglobal CAP_SUPPORTEDCAPSEXT.ConType TWON_ARRAY setglobal CAP_SUPPORTEDCAPSEXT.ItemType TWTY_UINT16 setglobal CAP_SUPPORTEDCAPSEXT.ValueAfterOpen UNDEFINED setglobal CAP_SUPPORTEDCAPSEXT.ValueAfterReset UNDEFINED setglobal CAP_SUPPORTEDCAPSEXT.Flags 'deprecated' ; setglobal CAP_SUPPORTEDCAPSSEGMENTUNIQUE.ConType TWON_ARRAY setglobal CAP_SUPPORTEDCAPSSEGMENTUNIQUE.ItemType TWTY_UINT16 setglobal CAP_SUPPORTEDCAPSSEGMENTUNIQUE.ValueAfterOpen UNDEFINED setglobal CAP_SUPPORTEDCAPSSEGMENTUNIQUE.ValueAfterReset UNDEFINED setglobal CAP_SUPPORTEDCAPSSEGMENTUNIQUE.Flags '' ; setglobal CAP_SUPPORTEDDATS.ConType TWON_ARRAY setglobal CAP_SUPPORTEDDATS.ItemType TWTY_UINT32 setglobal CAP_SUPPORTEDDATS.ValueAfterOpen UNDEFINED setglobal CAP_SUPPORTEDDATS.ValueAfterReset UNDEFINED setglobal CAP_SUPPORTEDDATS.Flags 'mandatory' ; setglobal CAP_TIMEBEFOREFIRSTCAPTURE.ConType TWON_RANGE,TWON_ONEVALUE setglobal CAP_TIMEBEFOREFIRSTCAPTURE.ItemType TWTY_INT32 setglobal CAP_TIMEBEFOREFIRSTCAPTURE.ValueAfterOpen 0 setglobal CAP_TIMEBEFOREFIRSTCAPTURE.ValueAfterReset 0 setglobal CAP_TIMEBEFOREFIRSTCAPTURE.Flags '' ; setglobal CAP_TIMEBETWEENCAPTURES.ConType TWON_RANGE,TWON_ONEVALUE setglobal CAP_TIMEBETWEENCAPTURES.ItemType TWTY_INT32 setglobal CAP_TIMEBETWEENCAPTURES.ValueAfterOpen 0 setglobal CAP_TIMEBETWEENCAPTURES.ValueAfterReset 0 setglobal CAP_TIMEBETWEENCAPTURES.Flags '' ; setglobal CAP_TIMEDATE.ConType TWON_ONEVALUE setglobal CAP_TIMEDATE.ItemType TWTY_STR32 setglobal CAP_TIMEDATE.ValueAfterOpen UNDEFINED setglobal CAP_TIMEDATE.ValueAfterReset UNDEFINED setglobal CAP_TIMEDATE.Flags 'notstate4' ; setglobal CAP_THUMBNAILSENABLED.ConType TWON_ENUMERATION setglobal CAP_THUMBNAILSENABLED.ItemType TWTY_BOOL setglobal CAP_THUMBNAILSENABLED.ValueAfterOpen FALSE setglobal CAP_THUMBNAILSENABLED.ValueAfterReset FALSE setglobal CAP_THUMBNAILSENABLED.Flags '' ; setglobal CAP_UICONTROLLABLE.ConType TWON_ENUMERATION setglobal CAP_UICONTROLLABLE.ItemType TWTY_BOOL setglobal CAP_UICONTROLLABLE.ValueAfterOpen TRUE ; mandatory for all sources setglobal CAP_UICONTROLLABLE.ValueAfterReset UNDEFINED setglobal CAP_UICONTROLLABLE.Flags 'mandatory' ; setglobal CAP_XFERCOUNT.ConType TWON_RANGE,TWON_ONEVALUE setglobal CAP_XFERCOUNT.ItemType TWTY_INT16 setglobal CAP_XFERCOUNT.ValueAfterOpen -1 setglobal CAP_XFERCOUNT.ValueAfterReset -1 setglobal CAP_XFERCOUNT.Flags 'mandatory' ; setglobal ICAP_AUTOBRIGHT.ConType TWON_ENUMERATION setglobal ICAP_AUTOBRIGHT.ItemType TWTY_BOOL setglobal ICAP_AUTOBRIGHT.ValueAfterOpen UNDEFINED setglobal ICAP_AUTOBRIGHT.ValueAfterReset FALSE setglobal ICAP_AUTOBRIGHT.Flags '' ; setglobal ICAP_AUTODISCARDBLANKPAGES.ConType TWON_RANGE,TWON_ONEVALUE setglobal ICAP_AUTODISCARDBLANKPAGES.ItemType TWTY_INT32 setglobal ICAP_AUTODISCARDBLANKPAGES.ValueAfterOpen UNDEFINED setglobal ICAP_AUTODISCARDBLANKPAGES.ValueAfterReset -2 ; TWBP_DISABLE setglobal ICAP_AUTODISCARDBLANKPAGES.Flags '' ; setglobal ICAP_AUTOMATICBORDERDETECTION.ConType TWON_ENUMERATION setglobal ICAP_AUTOMATICBORDERDETECTION.ItemType TWTY_BOOL setglobal ICAP_AUTOMATICBORDERDETECTION.ValueAfterOpen UNDEFINED setglobal ICAP_AUTOMATICBORDERDETECTION.ValueAfterReset UNDEFINED setglobal ICAP_AUTOMATICBORDERDETECTION.Flags '' ; setglobal ICAP_AUTOMATICCOLORENABLED.ConType TWON_ENUMERATION setglobal ICAP_AUTOMATICCOLORENABLED.ItemType TWTY_BOOL setglobal ICAP_AUTOMATICCOLORENABLED.ValueAfterOpen UNDEFINED setglobal ICAP_AUTOMATICCOLORENABLED.ValueAfterReset FALSE setglobal ICAP_AUTOMATICCOLORENABLED.Flags '' ; setglobal ICAP_AUTOMATICCOLORNONCOLORPIXELTYPE.ConType TWON_ENUMERATION,TWON_ONEVALUE setglobal ICAP_AUTOMATICCOLORNONCOLORPIXELTYPE.ItemType TWTY_UINT16 setglobal ICAP_AUTOMATICCOLORNONCOLORPIXELTYPE.ValueAfterOpen UNDEFINED setglobal ICAP_AUTOMATICCOLORNONCOLORPIXELTYPE.ValueAfterReset TWPT_BW setglobal ICAP_AUTOMATICCOLORNONCOLORPIXELTYPE.Flags '' ; setglobal ICAP_AUTOMATICCROPUSESFRAME.ConType TWON_ENUMERATION setglobal ICAP_AUTOMATICCROPUSESFRAME.ItemType TWTY_BOOL setglobal ICAP_AUTOMATICCROPUSESFRAME.ValueAfterOpen UNDEFINED setglobal ICAP_AUTOMATICCROPUSESFRAME.ValueAfterReset UNDEFINED setglobal ICAP_AUTOMATICCROPUSESFRAME.Flags '' ; setglobal ICAP_AUTOMATICDESKEW.ConType TWON_ENUMERATION setglobal ICAP_AUTOMATICDESKEW.ItemType TWTY_BOOL setglobal ICAP_AUTOMATICDESKEW.ValueAfterOpen UNDEFINED setglobal ICAP_AUTOMATICDESKEW.ValueAfterReset UNDEFINED setglobal ICAP_AUTOMATICDESKEW.Flags '' ; setglobal ICAP_AUTOMATICLENGTHDETECTION.ConType TWON_ENUMERATION setglobal ICAP_AUTOMATICLENGTHDETECTION.ItemType TWTY_BOOL setglobal ICAP_AUTOMATICLENGTHDETECTION.ValueAfterOpen UNDEFINED setglobal ICAP_AUTOMATICLENGTHDETECTION.ValueAfterReset UNDEFINED setglobal ICAP_AUTOMATICLENGTHDETECTION.Flags '' ; setglobal ICAP_AUTOMATICROTATE.ConType TWON_ENUMERATION setglobal ICAP_AUTOMATICROTATE.ItemType TWTY_BOOL setglobal ICAP_AUTOMATICROTATE.ValueAfterOpen UNDEFINED setglobal ICAP_AUTOMATICROTATE.ValueAfterReset FALSE setglobal ICAP_AUTOMATICROTATE.Flags '' ; setglobal ICAP_AUTOSIZE.ConType TWON_ENUMERATION,TWON_ONEVALUE setglobal ICAP_AUTOSIZE.ItemType TWTY_UINT16 setglobal ICAP_AUTOSIZE.ValueAfterOpen UNDEFINED setglobal ICAP_AUTOSIZE.ValueAfterReset TWAS_NONE setglobal ICAP_AUTOSIZE.Flags '' ; setglobal ICAP_BARCODEDETECTIONENABLED.ConType TWON_ENUMERATION setglobal ICAP_BARCODEDETECTIONENABLED.ItemType TWTY_BOOL setglobal ICAP_BARCODEDETECTIONENABLED.ValueAfterOpen UNDEFINED setglobal ICAP_BARCODEDETECTIONENABLED.ValueAfterReset FALSE setglobal ICAP_BARCODEDETECTIONENABLED.Flags '' ; setglobal ICAP_BARCODEMAXRETRIES.ConType TWON_ENUMERATION,TWON_RANGE,TWON_ONEVALUE setglobal ICAP_BARCODEMAXRETRIES.ItemType TWTY_UINT32 setglobal ICAP_BARCODEMAXRETRIES.ValueAfterOpen UNDEFINED setglobal ICAP_BARCODEMAXRETRIES.ValueAfterReset UNDEFINED setglobal ICAP_BARCODEMAXRETRIES.Flags '' ; setglobal ICAP_BARCODEMAXSEARCHPRIORITIES.ConType TWON_ENUMERATION,TWON_RANGE,TWON_ONEVALUE setglobal ICAP_BARCODEMAXSEARCHPRIORITIES.ItemType TWTY_UINT32 setglobal ICAP_BARCODEMAXSEARCHPRIORITIES.ValueAfterOpen UNDEFINED setglobal ICAP_BARCODEMAXSEARCHPRIORITIES.ValueAfterOpen UNDEFINED setglobal ICAP_BARCODEMAXSEARCHPRIORITIES.Flags '' ; setglobal ICAP_BARCODESEARCHMODE.ConType TWON_ENUMERATION,TWON_ONEVALUE setglobal ICAP_BARCODESEARCHMODE.ItemType TWTY_UINT16 setglobal ICAP_BARCODESEARCHMODE.ValueAfterOpen UNDEFINED setglobal ICAP_BARCODESEARCHMODE.ValueAfterReset UNDEFINED setglobal ICAP_BARCODESEARCHMODE.Flags '' ; setglobal ICAP_BARCODESEARCHPRIORITIES.ConType TWON_ARRAY setglobal ICAP_BARCODESEARCHPRIORITIES.ItemType TWTY_UINT16 setglobal ICAP_BARCODESEARCHPRIORITIES.ValueAfterOpen UNDEFINED setglobal ICAP_BARCODESEARCHPRIORITIES.ValueAfterReset UNDEFINED setglobal ICAP_BARCODESEARCHPRIORITIES.Flags '' ; setglobal ICAP_BARCODETIMEOUT.ConType TWON_ENUMERATION,TWON_RANGE,TWON_ONEVALUE setglobal ICAP_BARCODETIMEOUT.ItemType TWTY_UINT32 setglobal ICAP_BARCODETIMEOUT.ValueAfterOpen UNDEFINED setglobal ICAP_BARCODETIMEOUT.ValueAfterReset UNDEFINED setglobal ICAP_BARCODETIMEOUT.Flags '' ; setglobal ICAP_BITDEPTH.ConType TWON_ENUMERATION,TWON_ONEVALUE setglobal ICAP_BITDEPTH.ItemType TWTY_UINT16 setglobal ICAP_BITDEPTH.ValueAfterOpen UNDEFINED setglobal ICAP_BITDEPTH.ValueAfterReset UNDEFINED setglobal ICAP_BITDEPTH.Flags 'mandatory' ; setglobal ICAP_BITDEPTHREDUCTION.ConType TWON_ENUMERATION,TWON_ONEVALUE setglobal ICAP_BITDEPTHREDUCTION.ItemType TWTY_UINT16 setglobal ICAP_BITDEPTHREDUCTION.ValueAfterOpen UNDEFINED setglobal ICAP_BITDEPTHREDUCTION.ValueAfterReset UNDEFINED setglobal ICAP_BITDEPTHREDUCTION.Flags '' ; setglobal ICAP_BITORDER.ConType TWON_ENUMERATION,TWON_ONEVALUE setglobal ICAP_BITORDER.ItemType TWTY_UINT16 setglobal ICAP_BITORDER.ValueAfterOpen UNDEFINED ; spec says TWBO_LSBFIRST, but who ever used this? setglobal ICAP_BITORDER.ValueAfterReset UNDEFINED ; spec says TWBO_LSBFIRST, but who ever used this? setglobal ICAP_BITORDER.Flags 'mandatory' ; setglobal ICAP_BITORDERCODES.ConType TWON_ENUMERATION,TWON_ONEVALUE setglobal ICAP_BITORDERCODES.ItemType TWTY_UINT16 setglobal ICAP_BITORDERCODES.ValueAfterOpen UNDEFINED setglobal ICAP_BITORDERCODES.ValueAfterReset UNDEFINED setglobal ICAP_BITORDERCODES.Flags '' ; setglobal ICAP_BRIGHTNESS.ConType TWON_ENUMERATION,TWON_RANGE,TWON_ONEVALUE setglobal ICAP_BRIGHTNESS.ItemType TWTY_FIX32 setglobal ICAP_BRIGHTNESS.ValueAfterOpen UNDEFINED setglobal ICAP_BRIGHTNESS.ValueAfterReset 0 setglobal ICAP_BRIGHTNESS.Flags '' ; setglobal ICAP_CCITTKFACTOR.ConType TWON_RANGE,TWON_ONEVALUE setglobal ICAP_CCITTKFACTOR.ItemType TWTY_UINT16 setglobal ICAP_CCITTKFACTOR.ValueAfterOpen UNDEFINED setglobal ICAP_CCITTKFACTOR.ValueAfterReset 4 setglobal ICAP_CCITTKFACTOR.Flags '' ; setglobal ICAP_COLORMANAGEMENTENABLED.ConType TWON_ENUMERATION,TWON_ONEVALUE setglobal ICAP_COLORMANAGEMENTENABLED.ItemType TWTY_UINT16 setglobal ICAP_COLORMANAGEMENTENABLED.ValueAfterOpen TRUE setglobal ICAP_COLORMANAGEMENTENABLED.ValueAfterReset TRUE setglobal ICAP_COLORMANAGEMENTENABLED.Flags '' ; setglobal ICAP_COMPRESSION.ConType TWON_ENUMERATION,TWON_ONEVALUE setglobal ICAP_COMPRESSION.ItemType TWTY_UINT16 setglobal ICAP_COMPRESSION.ValueAfterOpen UNDEFINED setglobal ICAP_COMPRESSION.ValueAfterReset TWCP_NONE setglobal ICAP_COMPRESSION.Flags 'mandatory' ; setglobal ICAP_CONTRAST.ConType TWON_ENUMERATION,TWON_RANGE,TWON_ONEVALUE setglobal ICAP_CONTRAST.ItemType TWTY_FIX32 setglobal ICAP_CONTRAST.ValueAfterOpen UNDEFINED setglobal ICAP_CONTRAST.ValueAfterReset 0 setglobal ICAP_CONTRAST.Flags '' ; setglobal ICAP_CUSTHALFTONE.ConType TWON_ARRAY setglobal ICAP_CUSTHALFTONE.ItemType TWTY_UINT8 setglobal ICAP_CUSTHALFTONE.ValueAfterOpen UNDEFINED setglobal ICAP_CUSTHALFTONE.ValueAfterReset UNDEFINED setglobal ICAP_CUSTHALFTONE.Flags '' ; setglobal ICAP_EXPOSURETIME.ConType TWON_ENUMERATION,TWON_RANGE,TWON_ONEVALUE setglobal ICAP_EXPOSURETIME.ItemType TWTY_FIX32 setglobal ICAP_EXPOSURETIME.ValueAfterOpen UNDEFINED setglobal ICAP_EXPOSURETIME.ValueAfterReset UNDEFINED setglobal ICAP_EXPOSURETIME.Flags '' ; setglobal ICAP_EXTIMAGEINFO.ConType TWON_ENUMERATION setglobal ICAP_EXTIMAGEINFO.ItemType TWTY_BOOL setglobal ICAP_EXTIMAGEINFO.ValueAfterOpen UNDEFINED setglobal ICAP_EXTIMAGEINFO.ValueAfterReset TRUE setglobal ICAP_EXTIMAGEINFO.Flags '' ; setglobal ICAP_FEEDERTYPE.ConType TWON_ENUMERATION,TWON_ONEVALUE setglobal ICAP_FEEDERTYPE.ItemType TWTY_UINT16 setglobal ICAP_FEEDERTYPE.ValueAfterOpen UNDEFINED setglobal ICAP_FEEDERTYPE.ValueAfterReset UNDEFINED setglobal ICAP_FEEDERTYPE.Flags '' ; setglobal ICAP_FILMTYPE.ConType TWON_ENUMERATION setglobal ICAP_FILMTYPE.ItemType TWTY_UINT16 setglobal ICAP_FILMTYPE.ValueAfterOpen UNDEFINED setglobal ICAP_FILMTYPE.ValueAfterReset UNDEFINED setglobal ICAP_FILMTYPE.Flags '' ; setglobal ICAP_FILTER.ConType TWON_ARRAY,TWON_ONEVALUE setglobal ICAP_FILTER.ItemType TWTY_UINT16 setglobal ICAP_FILTER.ValueAfterOpen UNDEFINED setglobal ICAP_FILTER.ValueAfterReset '' setglobal ICAP_FILTER.Flags '' ; setglobal ICAP_FLASHUSED2.ConType TWON_ENUMERATION,TWON_ONEVALUE setglobal ICAP_FLASHUSED2.ItemType TWTY_UINT16 setglobal ICAP_FLASHUSED2.ValueAfterOpen UNDEFINED setglobal ICAP_FLASHUSED2.ValueAfterReset UNDEFINED setglobal ICAP_FLASHUSED2.Flags '' ; setglobal ICAP_FLIPROTATION.ConType TWON_ENUMERATION,TWON_ONEVALUE setglobal ICAP_FLIPROTATION.ItemType TWTY_UINT16 setglobal ICAP_FLIPROTATION.ValueAfterOpen UNDEFINED setglobal ICAP_FLIPROTATION.ValueAfterReset TWFR_BOOK setglobal ICAP_FLIPROTATION.Flags '' ; setglobal ICAP_FRAMES.ConType TWON_ENUMERATION,TWON_ONEVALUE setglobal ICAP_FRAMES.ItemType TWTY_FRAME setglobal ICAP_FRAMES.ValueAfterOpen UNDEFINED setglobal ICAP_FRAMES.ValueAfterReset UNDEFINED setglobal ICAP_FRAMES.Flags '' ; setglobal ICAP_GAMMA.ConType TWON_RANGE,TWON_ONEVALUE setglobal ICAP_GAMMA.ItemType TWTY_FIX32 setglobal ICAP_GAMMA.ValueAfterOpen UNDEFINED setglobal ICAP_GAMMA.ValueAfterReset UNDEFINED setglobal ICAP_GAMMA.Flags '' ; setglobal ICAP_HALFTONES.ConType TWON_ENUMERATION,TWON_ONEVALUE setglobal ICAP_HALFTONES.ItemType TWTY_STR32 setglobal ICAP_HALFTONES.ValueAfterOpen UNDEFINED setglobal ICAP_HALFTONES.ValueAfterReset UNDEFINED setglobal ICAP_HALFTONES.Flags '' ; setglobal ICAP_HIGHLIGHT.ConType TWON_ENUMERATION,TWON_RANGE,TWON_ONEVALUE setglobal ICAP_HIGHLIGHT.ItemType TWTY_FIX32 setglobal ICAP_HIGHLIGHT.ValueAfterOpen UNDEFINED setglobal ICAP_HIGHLIGHT.ValueAfterReset 255 setglobal ICAP_HIGHLIGHT.Flags '' ; setglobal ICAP_ICCPROFILE.ConType TWON_ENUMERATION,TWON_ONEVALUE setglobal ICAP_ICCPROFILE.ItemType TWTY_UINT16 setglobal ICAP_ICCPROFILE.ValueAfterOpen UNDEFINED setglobal ICAP_ICCPROFILE.ValueAfterReset UNDEFINED setglobal ICAP_ICCPROFILE.Flags '' ; setglobal ICAP_IMAGEDATASET.ConType TWON_ENUMERATION,TWON_RANGE,TWON_ONEVALUE setglobal ICAP_IMAGEDATASET.ItemType TWTY_UINT32 setglobal ICAP_IMAGEDATASET.ValueAfterOpen UNDEFINED setglobal ICAP_IMAGEDATASET.ValueAfterReset UNDEFINED setglobal ICAP_IMAGEDATASET.Flags '' ; setglobal ICAP_IMAGEFILEFORMAT.ConType TWON_ENUMERATION,TWON_ONEVALUE setglobal ICAP_IMAGEFILEFORMAT.ItemType TWTY_UINT16 setglobal ICAP_IMAGEFILEFORMAT.ValueAfterOpen UNDEFINED setglobal ICAP_IMAGEFILEFORMAT.ValueAfterReset UNDEFINED setglobal ICAP_IMAGEFILEFORMAT.Flags '' ; setglobal ICAP_IMAGEFILTER.ConType TWON_ENUMERATION,TWON_ONEVALUE setglobal ICAP_IMAGEFILTER.ItemType TWTY_UINT16 setglobal ICAP_IMAGEFILTER.ValueAfterOpen UNDEFINED setglobal ICAP_IMAGEFILTER.ValueAfterReset UNDEFINED setglobal ICAP_IMAGEFILTER.Flags '' ; setglobal ICAP_IMAGEMERGE.ConType TWON_ENUMERATION,TWON_ONEVALUE setglobal ICAP_IMAGEMERGE.ItemType TWTY_UINT16 setglobal ICAP_IMAGEMERGE.ValueAfterOpen UNDEFINED setglobal ICAP_IMAGEMERGE.ValueAfterReset TWIM_NONE setglobal ICAP_IMAGEMERGE.Flags '' ; setglobal ICAP_IMAGEMERGEHEIGHTTHRESHOLD.ConType TWON_RANGE,TWON_ONEVALUE setglobal ICAP_IMAGEMERGEHEIGHTTHRESHOLD.ItemType TWTY_FIX32 setglobal ICAP_IMAGEMERGEHEIGHTTHRESHOLD.ValueAfterOpen UNDEFINED setglobal ICAP_IMAGEMERGEHEIGHTTHRESHOLD.ValueAfterReset 0 setglobal ICAP_IMAGEMERGEHEIGHTTHRESHOLD.Flags '' ; setglobal ICAP_JPEGPIXELTYPE.ConType TWON_ENUMERATION,TWON_ONEVALUE setglobal ICAP_JPEGPIXELTYPE.ItemType TWTY_UINT16 setglobal ICAP_JPEGPIXELTYPE.ValueAfterOpen UNDEFINED setglobal ICAP_JPEGPIXELTYPE.ValueAfterReset UNDEFINED setglobal ICAP_JPEGPIXELTYPE.Flags '' ; setglobal ICAP_JPEGQUALITY.ConType TWON_ENUMERATION,TWON_RANGE,TWON_ONEVALUE setglobal ICAP_JPEGQUALITY.ItemType TWTY_INT16 setglobal ICAP_JPEGQUALITY.ValueAfterOpen UNDEFINED setglobal ICAP_JPEGQUALITY.ValueAfterReset UNDEFINED setglobal ICAP_JPEGQUALITY.Flags '' ; setglobal ICAP_JPEGSUBSAMPLING.ConType TWON_ENUMERATION setglobal ICAP_JPEGSUBSAMPLING.ItemType TWTY_UINT16 setglobal ICAP_JPEGSUBSAMPLING.ValueAfterOpen UNDEFINED setglobal ICAP_JPEGSUBSAMPLING.ValueAfterReset UNDEFINED setglobal ICAP_JPEGSUBSAMPLING.Flags '' ; setglobal ICAP_LAMPSTATE.ConType TWON_ENUMERATION setglobal ICAP_LAMPSTATE.ItemType TWTY_BOOL setglobal ICAP_LAMPSTATE.ValueAfterOpen UNDEFINED setglobal ICAP_LAMPSTATE.ValueAfterReset UNDEFINED setglobal ICAP_LAMPSTATE.Flags '' ; setglobal ICAP_LIGHTPATH.ConType TWON_ENUMERATION,TWON_ONEVALUE setglobal ICAP_LIGHTPATH.ItemType TWTY_UINT16 setglobal ICAP_LIGHTPATH.ValueAfterOpen UNDEFINED setglobal ICAP_LIGHTPATH.ValueAfterReset UNDEFINED setglobal ICAP_LIGHTPATH.Flags '' ; setglobal ICAP_LIGHTSOURCE.ConType TWON_ENUMERATION,TWON_ONEVALUE setglobal ICAP_LIGHTSOURCE.ItemType TWTY_UINT16 setglobal ICAP_LIGHTSOURCE.ValueAfterOpen UNDEFINED setglobal ICAP_LIGHTSOURCE.ValueAfterReset UNDEFINED setglobal ICAP_LIGHTSOURCE.Flags '' ; setglobal ICAP_MAXFRAMES.ConType TWON_RANGE,TWON_ONEVALUE setglobal ICAP_MAXFRAMES.ItemType TWTY_UINT16 setglobal ICAP_MAXFRAMES.ValueAfterOpen UNDEFINED setglobal ICAP_MAXFRAMES.ValueAfterReset UNDEFINED setglobal ICAP_MAXFRAMES.Flags '' ; setglobal ICAP_MINIMUMHEIGHT.ConType TWON_ONEVALUE setglobal ICAP_MINIMUMHEIGHT.ItemType TWTY_FIX32 setglobal ICAP_MINIMUMHEIGHT.ValueAfterOpen UNDEFINED setglobal ICAP_MINIMUMHEIGHT.ValueAfterReset UNDEFINED setglobal ICAP_MINIMUMHEIGHT.Flags '' ; setglobal ICAP_MINIMUMWIDTH.ConType TWON_ONEVALUE setglobal ICAP_MINIMUMWIDTH.ItemType TWTY_FIX32 setglobal ICAP_MINIMUMWIDTH.ValueAfterOpen UNDEFINED setglobal ICAP_MINIMUMWIDTH.ValueAfterReset UNDEFINED setglobal ICAP_MINIMUMWIDTH.Flags '' ; setglobal ICAP_MIRROR.ConType TWON_ENUMERATION,TWON_ONEVALUE setglobal ICAP_MIRROR.ItemType TWTY_UINT16 setglobal ICAP_MIRROR.ValueAfterOpen UNDEFINED setglobal ICAP_MIRROR.ValueAfterReset TWMR_NONE setglobal ICAP_MIRROR.Flags '' ; setglobal ICAP_NOISEFILTER.ConType TWON_ENUMERATION,TWON_ONEVALUE setglobal ICAP_NOISEFILTER.ItemType TWTY_UINT16 setglobal ICAP_NOISEFILTER.ValueAfterOpen UNDEFINED setglobal ICAP_NOISEFILTER.ValueAfterReset UNDEFINED setglobal ICAP_NOISEFILTER.Flags '' ; setglobal ICAP_ORIENTATION.ConType TWON_ENUMERATION,TWON_ONEVALUE setglobal ICAP_ORIENTATION.ItemType TWTY_UINT16 setglobal ICAP_ORIENTATION.ValueAfterOpen UNDEFINED setglobal ICAP_ORIENTATION.ValueAfterReset TWOR_ROT0|TWOR_PORTRAIT setglobal ICAP_ORIENTATION.Flags '' ; setglobal ICAP_OVERSCAN.ConType TWON_ENUMERATION,TWON_ONEVALUE setglobal ICAP_OVERSCAN.ItemType TWTY_UINT16 setglobal ICAP_OVERSCAN.ValueAfterOpen UNDEFINED setglobal ICAP_OVERSCAN.ValueAfterReset TWOV_NONE setglobal ICAP_OVERSCAN.Flags '' ; setglobal ICAP_PATCHCODEDETECTIONENABLED.ConType TWON_ENUMERATION setglobal ICAP_PATCHCODEDETECTIONENABLED.ItemType TWTY_BOOL setglobal ICAP_PATCHCODEDETECTIONENABLED.ValueAfterOpen UNDEFINED setglobal ICAP_PATCHCODEDETECTIONENABLED.ValueAfterReset FALSE setglobal ICAP_PATCHCODEDETECTIONENABLED.Flags '' ; setglobal ICAP_PATCHCODEMAXRETRIES.ConType TWON_ENUMERATION,TWON_RANGE,TWON_ONEVALUE setglobal ICAP_PATCHCODEMAXRETRIES.ItemType TWTY_UINT32 setglobal ICAP_PATCHCODEMAXRETRIES.ValueAfterOpen UNDEFINED setglobal ICAP_PATCHCODEMAXRETRIES.ValueAfterReset UNDEFINED setglobal ICAP_PATCHCODEMAXRETRIES.Flags '' ; setglobal ICAP_PATCHCODEMAXSEARCHPRIORITIES.ConType TWON_ENUMERATION,TWON_RANGE,TWON_ONEVALUE setglobal ICAP_PATCHCODEMAXSEARCHPRIORITIES.ItemType TWTY_UINT32 setglobal ICAP_PATCHCODEMAXSEARCHPRIORITIES.ValueAfterOpen UNDEFINED setglobal ICAP_PATCHCODEMAXSEARCHPRIORITIES.ValueAfterReset UNDEFINED setglobal ICAP_PATCHCODEMAXSEARCHPRIORITIES.Flags '' ; setglobal ICAP_PATCHCODESEARCHMODE.ConType TWON_ENUMERATION,TWON_ONEVALUE setglobal ICAP_PATCHCODESEARCHMODE.ItemType TWTY_UINT16 setglobal ICAP_PATCHCODESEARCHMODE.ValueAfterOpen UNDEFINED setglobal ICAP_PATCHCODESEARCHMODE.ValueAfterReset UNDEFINED setglobal ICAP_PATCHCODESEARCHMODE.Flags '' ; setglobal ICAP_PATCHCODESEARCHPRIORITIES.ConType TWON_ARRAY setglobal ICAP_PATCHCODESEARCHPRIORITIES.ItemType TWTY_UINT16 setglobal ICAP_PATCHCODESEARCHPRIORITIES.ValueAfterOpen UNDEFINED setglobal ICAP_PATCHCODESEARCHPRIORITIES.ValueAfterReset UNDEFINED setglobal ICAP_PATCHCODESEARCHPRIORITIES.Flags '' ; setglobal ICAP_PATCHCODETIMEOUT.ConType TWON_ENUMERATION,TWON_RANGE,TWON_ONEVALUE setglobal ICAP_PATCHCODETIMEOUT.ItemType TWTY_UINT32 setglobal ICAP_PATCHCODETIMEOUT.ValueAfterOpen UNDEFINED setglobal ICAP_PATCHCODETIMEOUT.ValueAfterReset UNDEFINED setglobal ICAP_PATCHCODETIMEOUT.Flags '' ; setglobal ICAP_PHYSICALHEIGHT.ConType TWON_ONEVALUE setglobal ICAP_PHYSICALHEIGHT.ItemType TWTY_FIX32 setglobal ICAP_PHYSICALHEIGHT.ValueAfterOpen UNDEFINED setglobal ICAP_PHYSICALHEIGHT.ValueAfterReset UNDEFINED setglobal ICAP_PHYSICALHEIGHT.Flags 'mandatory' ; setglobal ICAP_PHYSICALWIDTH.ConType TWON_ONEVALUE setglobal ICAP_PHYSICALWIDTH.ItemType TWTY_FIX32 setglobal ICAP_PHYSICALWIDTH.ValueAfterOpen UNDEFINED setglobal ICAP_PHYSICALWIDTH.ValueAfterReset UNDEFINED setglobal ICAP_PHYSICALWIDTH.Flags 'mandatory' ; setglobal ICAP_PIXELFLAVOR.ConType TWON_ENUMERATION,TWON_ONEVALUE setglobal ICAP_PIXELFLAVOR.ItemType TWTY_UINT16 setglobal ICAP_PIXELFLAVOR.ValueAfterOpen UNDEFINED setglobal ICAP_PIXELFLAVOR.ValueAfterReset TWPF_CHOCOLATE setglobal ICAP_PIXELFLAVOR.Flags 'mandatory' ; setglobal ICAP_PIXELFLAVORCODES.ConType TWON_ENUMERATION,TWON_ONEVALUE setglobal ICAP_PIXELFLAVORCODES.ItemType TWTY_UINT16 setglobal ICAP_PIXELFLAVORCODES.ValueAfterOpen UNDEFINED setglobal ICAP_PIXELFLAVORCODES.ValueAfterReset TWPF_CHOCOLATE setglobal ICAP_PIXELFLAVORCODES.Flags '' ; setglobal ICAP_PIXELTYPE.ConType TWON_ENUMERATION,TWON_ONEVALUE setglobal ICAP_PIXELTYPE.ItemType TWTY_UINT16 setglobal ICAP_PIXELTYPE.ValueAfterOpen UNDEFINED setglobal ICAP_PIXELTYPE.ValueAfterReset UNDEFINED setglobal ICAP_PIXELTYPE.Flags 'mandatory' ; setglobal ICAP_PLANARCHUNKY.ConType TWON_ENUMERATION,TWON_ONEVALUE setglobal ICAP_PLANARCHUNKY.ItemType TWTY_UINT16 setglobal ICAP_PLANARCHUNKY.ValueAfterOpen UNDEFINED setglobal ICAP_PLANARCHUNKY.ValueAfterReset UNDEFINED setglobal ICAP_PLANARCHUNKY.Flags 'mandatory' ; setglobal ICAP_ROTATION.ConType TWON_ENUMERATION,TWON_RANGE,TWON_ONEVALUE setglobal ICAP_ROTATION.ItemType TWTY_FIX32 setglobal ICAP_ROTATION.ValueAfterOpen UNDEFINED setglobal ICAP_ROTATION.ValueAfterReset 0 setglobal ICAP_ROTATION.Flags '' ; setglobal ICAP_SHADOW.ConType TWON_ENUMERATION,TWON_RANGE,TWON_ONEVALUE setglobal ICAP_SHADOW.ItemType TWTY_FIX32 setglobal ICAP_SHADOW.ValueAfterOpen UNDEFINED setglobal ICAP_SHADOW.ValueAfterReset 0 setglobal ICAP_SHADOW.Flags '' ; setglobal ICAP_SUPPORTEDBARCODETYPES.ConType TWON_ARRAY setglobal ICAP_SUPPORTEDBARCODETYPES.ItemType TWTY_UINT16 setglobal ICAP_SUPPORTEDBARCODETYPES.ValueAfterOpen UNDEFINED setglobal ICAP_SUPPORTEDBARCODETYPES.ValueAfterReset UNDEFINED setglobal ICAP_SUPPORTEDBARCODETYPES.Flags '' ; setglobal ICAP_SUPPORTEDEXTIMAGEINFO.ConType TWON_ARRAY setglobal ICAP_SUPPORTEDEXTIMAGEINFO.ItemType TWTY_UINT16 setglobal ICAP_SUPPORTEDEXTIMAGEINFO.ValueAfterOpen UNDEFINED setglobal ICAP_SUPPORTEDEXTIMAGEINFO.ValueAfterReset UNDEFINED setglobal ICAP_SUPPORTEDEXTIMAGEINFO.Flags '' ; setglobal ICAP_SUPPORTEDPATCHCODETYPES.ConType TWON_ARRAY setglobal ICAP_SUPPORTEDPATCHCODETYPES.ItemType TWTY_UINT16 setglobal ICAP_SUPPORTEDPATCHCODETYPES.ValueAfterOpen UNDEFINED setglobal ICAP_SUPPORTEDPATCHCODETYPES.ValueAfterReset UNDEFINED setglobal ICAP_SUPPORTEDPATCHCODETYPES.Flags '' ; setglobal ICAP_SUPPORTEDSIZES.ConType TWON_ENUMERATION,TWON_ONEVALUE setglobal ICAP_SUPPORTEDSIZES.ItemType TWTY_UINT16 setglobal ICAP_SUPPORTEDSIZES.ValueAfterOpen UNDEFINED setglobal ICAP_SUPPORTEDSIZES.ValueAfterReset UNDEFINED setglobal ICAP_SUPPORTEDSIZES.Flags '' ; setglobal ICAP_THRESHOLD.ConType TWON_ENUMERATION,TWON_RANGE,TWON_ONEVALUE setglobal ICAP_THRESHOLD.ItemType TWTY_FIX32 setglobal ICAP_THRESHOLD.ValueAfterOpen UNDEFINED setglobal ICAP_THRESHOLD.ValueAfterReset 128 setglobal ICAP_THRESHOLD.Flags '' ; setglobal ICAP_TILES.ConType TWON_ENUMERATION setglobal ICAP_TILES.ItemType TWTY_BOOL setglobal ICAP_TILES.ValueAfterOpen FALSE setglobal ICAP_TILES.ValueAfterReset FALSE setglobal ICAP_TILES.Flags '' ; setglobal ICAP_TIMEFILL.ConType TWON_RANGE,TWON_ONEVALUE setglobal ICAP_TIMEFILL.ItemType TWTY_UINT16 setglobal ICAP_TIMEFILL.ValueAfterOpen UNDEFINED setglobal ICAP_TIMEFILL.ValueAfterReset 1 setglobal ICAP_TIMEFILL.Flags '' ; setglobal ICAP_UNDEFINEDIMAGESIZE.ConType TWON_ENUMERATION setglobal ICAP_UNDEFINEDIMAGESIZE.ItemType TWTY_BOOL setglobal ICAP_UNDEFINEDIMAGESIZE.ValueAfterOpen FALSE setglobal ICAP_UNDEFINEDIMAGESIZE.ValueAfterReset FALSE setglobal ICAP_UNDEFINEDIMAGESIZE.Flags '' ; setglobal ICAP_UNITS.ConType TWON_ENUMERATION,TWON_ONEVALUE setglobal ICAP_UNITS.ItemType TWTY_UINT16 setglobal ICAP_UNITS.ValueAfterOpen TWUN_INCHES setglobal ICAP_UNITS.ValueAfterReset TWUN_INCHES setglobal ICAP_UNITS.Flags 'mandatory' ; setglobal ICAP_XFERMECH.ConType TWON_ENUMERATION setglobal ICAP_XFERMECH.ItemType TWTY_UINT16 setglobal ICAP_XFERMECH.ValueAfterOpen TWSX_NATIVE setglobal ICAP_XFERMECH.ValueAfterReset TWSX_NATIVE setglobal ICAP_XFERMECH.Flags 'mandatory' ; setglobal ICAP_XNATIVERESOLUTION.ConType TWON_ENUMERATION,TWON_ONEVALUE setglobal ICAP_XNATIVERESOLUTION.ItemType TWTY_FIX32 setglobal ICAP_XNATIVERESOLUTION.ValueAfterOpen UNDEFINED setglobal ICAP_XNATIVERESOLUTION.ValueAfterReset UNDEFINED setglobal ICAP_XNATIVERESOLUTION.Flags 'mandatory' ; setglobal ICAP_XRESOLUTION.ConType TWON_ENUMERATION,TWON_RANGE,TWON_ONEVALUE setglobal ICAP_XRESOLUTION.ItemType TWTY_FIX32 setglobal ICAP_XRESOLUTION.ValueAfterOpen UNDEFINED setglobal ICAP_XRESOLUTION.ValueAfterReset UNDEFINED setglobal ICAP_XRESOLUTION.Flags 'mandatory' ; setglobal ICAP_XSCALING.ConType TWON_ENUMERATION,TWON_RANGE,TWON_ONEVALUE setglobal ICAP_XSCALING.ItemType TWTY_FIX32 setglobal ICAP_XSCALING.ValueAfterOpen UNDEFINED setglobal ICAP_XSCALING.ValueAfterReset 1 setglobal ICAP_XSCALING.Flags '' ; setglobal ICAP_YNATIVERESOLUTION.ConType TWON_ENUMERATION,TWON_ONEVALUE setglobal ICAP_YNATIVERESOLUTION.ItemType TWTY_FIX32 setglobal ICAP_YNATIVERESOLUTION.ValueAfterOpen UNDEFINED setglobal ICAP_YNATIVERESOLUTION.ValueAfterReset UNDEFINED setglobal ICAP_YNATIVERESOLUTION.Flags 'mandatory' ; setglobal ICAP_YRESOLUTION.ConType TWON_ENUMERATION,TWON_RANGE,TWON_ONEVALUE setglobal ICAP_YRESOLUTION.ItemType TWTY_FIX32 setglobal ICAP_YRESOLUTION.ValueAfterOpen UNDEFINED setglobal ICAP_YRESOLUTION.ValueAfterReset UNDEFINED setglobal ICAP_YRESOLUTION.Flags 'mandatory' ; setglobal ICAP_YSCALING.ConType TWON_ENUMERATION,TWON_RANGE,TWON_ONEVALUE setglobal ICAP_YSCALING.ItemType TWTY_FIX32 setglobal ICAP_YSCALING.ValueAfterOpen UNDEFINED setglobal ICAP_YSCALING.ValueAfterReset 1 setglobal ICAP_YSCALING.Flags '' ; setglobal ICAP_ZOOMFACTOR.ConType TWON_ENUMERATION,TWON_RANGE,TWON_ONEVALUE setglobal ICAP_ZOOMFACTOR.ItemType TWTY_INT16 setglobal ICAP_ZOOMFACTOR.ValueAfterOpen UNDEFINED setglobal ICAP_ZOOMFACTOR.ValueAfterReset 0 setglobal ICAP_ZOOMFACTOR.Flags '' ; setrecord off ; return ================================================ FILE: twaincs/source/twaincscert/source/data/certification/Opends.tc ================================================ ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Opends ; Open the requested TWAIN driver, with additional dsmload options ; ; Arguments ; arg:1 - TW_IDENTITY.ProductName of scanner to test ; arg:2 - set to 'embedded', to limit messages ; arg:3 - indent padding for embedded ; arg:4 - dsmoption #1 ; arg:5 - dsmoption #2 ; arg:6 - dsmoption #3 ; arg:7 - dsmoption #4 ; arg:8 - dsmoption #5 ; arg:9 - dsmoption #6 ; arg:10 - dsmoption #7 ; arg:11 - dsmoption #8 ; arg:12 - dsmoption #9 ; arg:13 - dsmoption #10 ; arg:14 - dsmoption #11 ; arg:15 - dsmoption #12 ; arg:16 - dsmoption #13 ; ; Globals ; (none) ; ; Locals ; embedded - try to fit into the flow of other echo.passfail stuff ; indent - indenting for echo.passfail ; ; Returns ; pass or fail ; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Initialize... ; if '${arg:2}' == 'embedded' goto MAIN.TITLE.SKIP echo.titletest 'Opends' :MAIN.TITLE.SKIP setlocal embedded '${arg:2}' setlocal indent '${arg:3}' if '${get:TW_ARRAY.ItemType}' != '' goto MAIN.LOADTABLES.SKIP run '${folder:certification}/LoadTables' :MAIN.LOADTABLES.SKIP ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Load and open the DSM... ; setlocal name 'dsmload ${arg:4} ${arg:5} ${arg:6} ${arg:7} ${arg:8} ${arg:9} ${arg:10} ${arg:11} ${arg:12} ${arg:13} ${arg:14} ${arg:15} ${arg:16}' dsmload '${arg:4}' '${arg:5}' '${arg:6}' '${arg:7}' '${arg:8}' '${arg:9}' '${arg:10}' '${arg:11}' '${arg:12}' '${arg:13}' '${arg:14}' '${arg:15}' '${arg:16}' dsmentry src null dg_control dat_parent msg_opendsm hwnd if '${sts:}' != 'SUCCESS' goto MAIN.ERROR echo.passfail '${get:indent}${get:name}' 'pass' echo.passfail '${get:indent}using ${dsm:}' 'pass' ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; If the DF_APP2|DF_DSM2 flag is set, then call DAT_ENTRYPOINT... ; if '${app:${get:TW_IDENTITY.SupportedGroups}}' & '0x30000000' != '0x30000000' goto MAIN.ENTRYPOINT.SKIP setlocal name 'dg_control/dat_entrypoint/msg_get' dsmentry src null dg_control dat_entrypoint msg_get '0,0,0,0,0,0' if '${sts:}' != 'SUCCESS' goto MAIN.ERROR echo.passfail '${get:indent}${get:name}' 'pass' :MAIN.ENTRYPOINT.SKIP ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Open the driver... ; setlocal name 'dg_control/dat_identity/msg_opends <${arg:1}>' dsmentry src null dg_control dat_identity msg_opends '0,0,0,0,0,,0,0,0x0,,,${arg:1}' if '${sts:}' != 'SUCCESS' goto MAIN.ERROR ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Summary and cleanup... ; if '${get:embedded}' == 'embedded' goto MAIN.PASS.EMBEDDED echo.passfail '${get:name}' 'pass' echo.passfail 'SUMMARY' 'pass' return 'pass' ; ; Ruh-roh... :MAIN.ERROR if '${get:embedded}' == 'embedded' goto MAIN.ERROR.EMBEDDED echo.passfail '${get:name}' 'fail - ${sts:} '${ret:}' echo.passfail 'SUMMARY' 'fail' return 'fail' ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Enbedded summary and cleanup... ; :MAIN.PASS.EMBEDDED echo.passfail '${get:indent}${get:name}' 'pass' return 'pass' ; ; Ruh-roh... :MAIN.ERROR.EMBEDDED echo.passfail '${get:indent}${get:name}' 'fail - ${sts:} '${ret:}' return 'fail' ================================================ FILE: twaincs/source/twaincscert/source/data/certification/__README.md ================================================ These are the scripts for doing the certification tests. This folder will be deleted and rewritten by the certify command, so don't put anything in here you care about. These have been designed such that it's possible to use the run command on any "Certification.tc" file. If doing diagnostic work, bear in mind that it may be helpful to go into the "Certification.tc" files to comment out tests you're not interested in running, or use a goto to skip over tests. The 'echo' command is your friend. You can learn a lot from it. Or you can use the 'verbose' option to get the program to hork out everything going on. The 'runv' command will show all of the TWAIN commands that are issued during the test. ================================================ FILE: twaincs/source/twaincscert/source/data/scripts/LoadTables.tc ================================================ ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Tables ; Load common values used globally ; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Stuff to load... ; call LOADCAPABILITYTABLE call LOADTWSTRUCTTABLE return ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Function: LOADTWSTRUCTTABLE ; Loads indecies we use to look into TW_* structures... ; :LOADTWSTRUCTTABLE ; ; These index off TW_CAPABILITY, which is why they don't start at 0... setglobal TW_ARRAY.ItemType 2 setglobal TW_ARRAY.NumItems 3 setglobal TW_ARRAY.ItemList 4 ; setglobal TW_CAPABILITY.Cap 0 setglobal TW_CAPABILITY.ConType 1 ; setglobal TW_CUSTOMDSDATA.InfoLength 0 setglobal TW_CUSTOMDSDATA.hData 1 ; setglobal TW_DEVICEEVENT.Event 0 setglobal TW_DEVICEEVENT.DeviceName 1 setglobal TW_DEVICEEVENT.BatteryMinutes 2 setglobal TW_DEVICEEVENT.BatteryPercentage 3 setglobal TW_DEVICEEVENT.PowerSupply 4 setglobal TW_DEVICEEVENT.XResolution 5 setglobal TW_DEVICEEVENT.YResolution 6 setglobal TW_DEVICEEVENT.FlashUsed2 7 setglobal TW_DEVICEEVENT.AutomaticCapture 8 setglobal TW_DEVICEEVENT.TimeBeforeFirstCapture 9 setglobal TW_DEVICEEVENT.TimeBetweenCaptures 10 ; ; These index off TW_CAPABILITY, which is why they don't start at 0... setglobal TW_ENUMERATION.ItemType 2 setglobal TW_ENUMERATION.NumItems 3 setglobal TW_ENUMERATION.CurrentIndex 4 setglobal TW_ENUMERATION.DefaultIndex 5 setglobal TW_ENUMERATION.ItemList 6 ; setglobal TW_EXTIMAGEINFO.NumInfos 0 setglobal TW_EXTIMAGEINFO.Info 1 ; setglobal TW_FILESYSTEM.InputName 0 setglobal TW_FILESYSTEM.OutputName 1 setglobal TW_FILESYSTEM.Context 2 setglobal TW_FILESYSTEM.Recursive 3 ; union #1 setglobal TW_FILESYSTEM.Subdirectories 3 ; union #1 setglobal TW_FILESYSTEM.FileType 4 ; union #2 setglobal TW_FILESYSTEM.FileSystemType 4 ; union #2 setglobal TW_FILESYSTEM.Size 5 setglobal TW_FILESYSTEM.CreateTimeDate 6 setglobal TW_FILESYSTEM.ModifiedTimeDate 7 setglobal TW_FILESYSTEM.FreeSpace 8 setglobal TW_FILESYSTEM.NewImageSize 9 setglobal TW_FILESYSTEM.NumberOfFiles 10 setglobal TW_FILESYSTEM.NumberOfSnippets 11 setglobal TW_FILESYSTEM.DeviceGroupMask 12 setglobal TW_FILESYSTEM.Reserved 13 ; setglobal TW_IDENTITY.Id 0 setglobal TW_IDENTITY.Version.MajorNum 1 setglobal TW_IDENTITY.Version.MinorNum 2 setglobal TW_IDENTITY.Version.Language 3 setglobal TW_IDENTITY.Version.Country 4 setglobal TW_IDENTITY.Version.Info 5 setglobal TW_IDENTITY.ProtocolMajor 6 setglobal TW_IDENTITY.ProtocolMinor 7 setglobal TW_IDENTITY.SupportedGroups 8 setglobal TW_IDENTITY.Manufacturer 9 setglobal TW_IDENTITY.ProductFamily 10 setglobal TW_IDENTITY.ProductName 11 ; setglobal TW_IMAGEINFO.XResolution 0 setglobal TW_IMAGEINFO.YResolution 1 setglobal TW_IMAGEINFO.ImageWidth 2 setglobal TW_IMAGEINFO.ImageHeight 3 setglobal TW_IMAGEINFO.SamplesPerPixel 4 setglobal TW_IMAGEINFO.BitsPerSample 5 ; 8 elements in this one setglobal TW_IMAGEINFO.BitsPerPixel 13 setglobal TW_IMAGEINFO.Planar 14 setglobal TW_IMAGEINFO.PixelType 15 setglobal TW_IMAGEINFO.Compression 16 ; setglobal TW_IMAGELAYOUT.Frame.Left 0 setglobal TW_IMAGELAYOUT.Frame.Top 1 setglobal TW_IMAGELAYOUT.Frame.Right 2 setglobal TW_IMAGELAYOUT.Frame.Bottom 3 setglobal TW_IMAGELAYOUT.Frame.DocumentNumber 4 setglobal TW_IMAGELAYOUT.Frame.PageNumber 5 setglobal TW_IMAGELAYOUT.Frame.FrameNumber 6 ; ; These index off TW_EXTIMAGEINFO, which is why they don't start at 0... setglobal TW_INFO.InfoID 1 setglobal TW_INFO.ItemType 2 setglobal TW_INFO.NumItems 3 setglobal TW_INFO.ReturnCode 4 setglobal TW_INFO.Item 5 ; setglobal TW_METRICS.SizeOf 0 setglobal TW_METRICS.ImageCount 1 setglobal TW_METRICS.SheetCount 2 ; ; These index off TW_CAPABILITY, which is why they don't start at 0... setglobal TW_ONEVALUE.ItemType 2 setglobal TW_ONEVALUE.Item 3 ; setglobal TW_PENDINGXFERS.Count 0 setglobal TW_PENDINGXFERS.Reserved 1 setglobal TW_PENDINGXFERS.TW_JOBCONTROL.EOJ 2 ; macOS only ; ; These index off TW_CAPABILITY, which is why they don't start at 0... setglobal TW_RANGE.ItemType 2 setglobal TW_RANGE.MinValue 3 setglobal TW_RANGE.MaxValue 4 setglobal TW_RANGE.StepSize 5 setglobal TW_RANGE.DefaultValue 6 setglobal TW_RANGE.CurrentValue 7 ; setglobal TW_SETUPFILEXFER.FileName 0 setglobal TW_SETUPFILEXFER.Format 1 setglobal TW_SETUPFILEXFER.VRefNum 2 ; setglobal TW_SETUPMEMXFER.MinBufSize 0 setglobal TW_SETUPMEMXFER.MaxBufSize 1 setglobal TW_SETUPMEMXFER.Preferred 2 ; setglobal TW_STATUS.ConditionCode 0 setglobal TW_STATUS.Data 1 setglobal TW_STATUS.Reserved 1 ; whatever >.< ; setglobal TW_STATUSUTF8.Status.ConditionCode 0 setglobal TW_STATUSUTF8.Status.Data 1 setglobal TW_STATUSUTF8.Status.Reserved 1 ; see above setglobal TW_STATUSUTF8.Size 2 setglobal TW_STATUSUTF8.UTF8string 3 ; setglobal TW_TWAINDIRECT.SizeOf 0 setglobal TW_TWAINDIRECT.CommunicationManager 1 setglobal TW_TWAINDIRECT.Send 2 setglobal TW_TWAINDIRECT.SendSize 3 setglobal TW_TWAINDIRECT.Receive 4 setglobal TW_TWAINDIRECT.ReceiveSize 5 ; setglobal TW_USERINTERFACE.ShowUI 0 setglobal TW_USERINTERFACE.ModalUI 1 setglobal TW_USERINTERFACE.hParent 2 ; return ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Function: LOADCAPABILITYTABLE ; Loads stuff we need to confirm about each known capability, we'll skip the ; g_ prefix for these items. Note the use of sys_capabilitytable, this will ; record the names of all the capabilities for us, so we can access them in ; any script... ; :LOADCAPABILITYTABLE ; setrecord on 'sys_capabilitytable' '.Flags' '.Flags' ; setglobal ACAP_XFERMECH.ConType TWON_ENUMERATION,TWON_ONEVALUE setglobal ACAP_XFERMECH.ItemType TWTY_UINT16 setglobal ACAP_XFERMECH.ValueAfterOpen TWSX_NATIVE setglobal ACAP_XFERMECH.ValueAfterReset TWSX_NATIVE setglobal ACAP_XFERMECH.Flags '' ; setglobal CAP_ALARMS.ConType TWON_ARRAY setglobal CAP_ALARMS.ItemType TWTY_UINT16 setglobal CAP_ALARMS.ValueAfterOpen UNDEFINED setglobal CAP_ALARMS.ValueAfterReset UNDEFINED setglobal CAP_ALARMS.Flags '' ; setglobal CAP_ALARMVOLUME.ConType TWON_RANGE,TWON_ONEVALUE setglobal CAP_ALARMVOLUME.ItemType TWTY_INT32 setglobal CAP_ALARMVOLUME.ValueAfterOpen UNDEFINED setglobal CAP_ALARMVOLUME.ValueAfterReset UNDEFINED setglobal CAP_ALARMVOLUME.Flags '' ; setglobal CAP_AUTHOR.ConType TWON_ONEVALUE setglobal CAP_AUTHOR.ItemType TWTY_STR128 setglobal CAP_AUTHOR.ValueAfterOpen '' setglobal CAP_AUTHOR.ValueAfterReset '' setglobal CAP_AUTHOR.Flags '' ; setglobal CAP_AUTOFEED.ConType TWON_ENUMERATION setglobal CAP_AUTOFEED.ItemType TWTY_BOOL setglobal CAP_AUTOFEED.ValueAfterOpen UNDEFINED setglobal CAP_AUTOFEED.ValueAfterReset TRUE setglobal CAP_AUTOFEED.Flags '' ; setglobal CAP_AUTOMATICCAPTURE.ConType TWON_RANGE,TWON_ONEVALUE setglobal CAP_AUTOMATICCAPTURE.ItemType TWTY_INT32 setglobal CAP_AUTOMATICCAPTURE.ValueAfterOpen 0 setglobal CAP_AUTOMATICCAPTURE.ValueAfterReset 0 setglobal CAP_AUTOMATICCAPTURE.Flags '' ; setglobal CAP_AUTOMATICSENSEMEDIUM.ConType TWON_ENUMERATION setglobal CAP_AUTOMATICSENSEMEDIUM.ItemType TWTY_BOOL setglobal CAP_AUTOMATICSENSEMEDIUM.ValueAfterOpen UNDEFINED setglobal CAP_AUTOMATICSENSEMEDIUM.ValueAfterReset UNDEFINED setglobal CAP_AUTOMATICSENSEMEDIUM.Flags '' ; setglobal CAP_AUTOSCAN.ConType TWON_ENUMERATION setglobal CAP_AUTOSCAN.ItemType TWTY_BOOL setglobal CAP_AUTOSCAN.ValueAfterOpen UNDEFINED setglobal CAP_AUTOSCAN.ValueAfterReset TRUE setglobal CAP_AUTOSCAN.Flags '' ; setglobal CAP_BATTERYMINUTES.ConType TWON_ONEVALUE setglobal CAP_BATTERYMINUTES.ItemType TWTY_INT32 setglobal CAP_BATTERYMINUTES.ValueAfterOpen UNEDFINED setglobal CAP_BATTERYMINUTES.ValueAfterReset UNEDFINED setglobal CAP_BATTERYMINUTES.Flags '' ; setglobal CAP_BATTERYPERCENTAGE.ConType TWON_ONEVALUE setglobal CAP_BATTERYPERCENTAGE.ItemType TWTY_INT16 setglobal CAP_BATTERYPERCENTAGE.ValueAfterOpen UNDEFINED setglobal CAP_BATTERYPERCENTAGE.ValueAfterReset UNDEFINED setglobal CAP_BATTERYPERCENTAGE.Flags '' ; setglobal CAP_CAMERAENABLED.ConType TWON_ENUMERATION setglobal CAP_CAMERAENABLED.ItemType TWTY_BOOL setglobal CAP_CAMERAENABLED.ValueAfterOpen UNDEFINED setglobal CAP_CAMERAENABLED.ValueAfterReset UNDEFINED setglobal CAP_CAMERAENABLED.Flags '' ; setglobal CAP_CAMERAORDER.ConType TWON_ARRAY setglobal CAP_CAMERAORDER.ItemType TWTY_UINT16 setglobal CAP_CAMERAORDER.ValueAfterOpen UNDEFINED setglobal CAP_CAMERAORDER.ValueAfterReset UNDEFINED setglobal CAP_CAMERAORDER.Flags '' ; setglobal CAP_CAMERAPREVIEWUI.ConType TWON_ENUMERATION setglobal CAP_CAMERAPREVIEWUI.ItemType TWTY_BOOL setglobal CAP_CAMERAPREVIEWUI.ValueAfterOpen UNDEFINED setglobal CAP_CAMERAPREVIEWUI.ValueAfterReset UNDEFINED setglobal CAP_CAMERAPREVIEWUI.Flags '' ; setglobal CAP_CAMERASIDE.ConType TWON_ENUMERATION,TWON_ONEVALUE setglobal CAP_CAMERASIDE.ItemType TWTY_UINT16 setglobal CAP_CAMERASIDE.ValueAfterOpen UNDEFINED setglobal CAP_CAMERASIDE.ValueAfterReset UNDEFINED ; should be TWCS_BOTH, but need a solution for ADF vs Flatbed setglobal CAP_CAMERASIDE.Flags '' ; setglobal CAP_CAPTION.ConType TWON_ONEVALUE setglobal CAP_CAPTION.ItemType TWTY_STR255 setglobal CAP_CAPTION.ValueAfterOpen '' setglobal CAP_CAPTION.ValueAfterReset '' setglobal CAP_CAPTION.Flags '' ; setglobal CAP_CLEARBUFFERS.ConType TWON_ENUMERATION,TWON_ONEVALUE setglobal CAP_CLEARBUFFERS.ItemType TWTY_BOOL setglobal CAP_CLEARBUFFERS.ValueAfterOpen UNDEFINED setglobal CAP_CLEARBUFFERS.ValueAfterReset UNDEFINED setglobal CAP_CLEARBUFFERS.Flags 'deprecated' ; setglobal CAP_CLEARPAGE.ConType TWON_ENUMERATION setglobal CAP_CLEARPAGE.ItemType TWTY_BOOL setglobal CAP_CLEARPAGE.ValueAfterOpen FALSE setglobal CAP_CLEARPAGE.ValueAfterReset FALSE setglobal CAP_CLEARPAGE.Flags '' ; setglobal CAP_CUSTOMDSDATA.ConType TWON_ENUMERATION setglobal CAP_CUSTOMDSDATA.ItemType TWTY_BOOL setglobal CAP_CUSTOMDSDATA.ValueAfterOpen UNDEFINED setglobal CAP_CUSTOMDSDATA.ValueAfterReset UNDEFINED setglobal CAP_CUSTOMDSDATA.Flags '' ; setglobal CAP_CUSTOMINTERFACEGUID.ConType TWON_ONEVALUE setglobal CAP_CUSTOMINTERFACEGUID.ItemType TWTY_STR255 setglobal CAP_CUSTOMINTERFACEGUID.ValueAfterOpen UNDEFINED setglobal CAP_CUSTOMINTERFACEGUID.ValueAfterReset UNDEFINED setglobal CAP_CUSTOMINTERFACEGUID.Flags '' ; setglobal CAP_DEVICEEVENT.ConType TWON_ARRAY setglobal CAP_DEVICEEVENT.ItemType TWTY_UINT16 setglobal CAP_DEVICEEVENT.ValueAfterOpen UNDEFINED setglobal CAP_DEVICEEVENT.ValueAfterReset '' setglobal CAP_DEVICEEVENT.Flags '' ; setglobal CAP_DEVICEONLINE.ConType TWON_ENUMERATION setglobal CAP_DEVICEONLINE.ItemType TWTY_BOOL setglobal CAP_DEVICEONLINE.ValueAfterOpen UNDEFINED setglobal CAP_DEVICEONLINE.ValueAfterReset UNDEFINED setglobal CAP_DEVICEONLINE.Flags 'mandatory' ; setglobal CAP_DEVICETIMEDATE.ConType TWON_ONEVALUE setglobal CAP_DEVICETIMEDATE.ItemType TWTY_STR32 setglobal CAP_DEVICETIMEDATE.ValueAfterOpen UNDEFINED setglobal CAP_DEVICETIMEDATE.ValueAfterReset UNDEFINED setglobal CAP_DEVICETIMEDATE.Flags '' ; setglobal CAP_DOUBLEFEEDDETECTION.ConType TWON_ARRAY setglobal CAP_DOUBLEFEEDDETECTION.ItemType TWTY_UINT16 setglobal CAP_DOUBLEFEEDDETECTION.ValueAfterOpen UNDEFINED setglobal CAP_DOUBLEFEEDDETECTION.ValueAfterReset '' setglobal CAP_DOUBLEFEEDDETECTION.Flags '' ; setglobal CAP_DOUBLEFEEDDETECTIONLENGTH.ConType TWON_RANGE setglobal CAP_DOUBLEFEEDDETECTIONLENGTH.ItemType TWTY_FIX32 setglobal CAP_DOUBLEFEEDDETECTIONLENGTH.ValueAfterOpen UNDEFINED setglobal CAP_DOUBLEFEEDDETECTIONLENGTH.ValueAfterReset UNDEFINED setglobal CAP_DOUBLEFEEDDETECTIONLENGTH.Flags '' ; setglobal CAP_DOUBLEFEEDDETECTIONRESPONSE.ConType TWON_ARRAY setglobal CAP_DOUBLEFEEDDETECTIONRESPONSE.ItemType TWTY_UINT16 setglobal CAP_DOUBLEFEEDDETECTIONRESPONSE.ValueAfterOpen UNDEFINED setglobal CAP_DOUBLEFEEDDETECTIONRESPONSE.ValueAfterReset UNDEFINED setglobal CAP_DOUBLEFEEDDETECTIONRESPONSE.Flags '' ; setglobal CAP_DOUBLEFEEDDETECTIONSENSITIVITY.ConType TWON_ENUMERATION setglobal CAP_DOUBLEFEEDDETECTIONSENSITIVITY.ItemType TWTY_UINT16 setglobal CAP_DOUBLEFEEDDETECTIONSENSITIVITY.ValueAfterOpen UNDEFINED setglobal CAP_DOUBLEFEEDDETECTIONSENSITIVITY.ValueAfterReset UNDEFINED setglobal CAP_DOUBLEFEEDDETECTIONSENSITIVITY.Flags '' ; setglobal CAP_DUPLEX.ConType TWON_ONEVALUE setglobal CAP_DUPLEX.ItemType TWTY_UINT16 setglobal CAP_DUPLEX.ValueAfterOpen UNDEFINED setglobal CAP_DUPLEX.ValueAfterReset UNDEFINED setglobal CAP_DUPLEX.Flags '' ; setglobal CAP_DUPLEXENABLED.ConType TWON_ENUMERATION setglobal CAP_DUPLEXENABLED.ItemType TWTY_BOOL setglobal CAP_DUPLEXENABLED.ValueAfterOpen UNDEFINED setglobal CAP_DUPLEXENABLED.ValueAfterReset UNDEFINED setglobal CAP_DUPLEXENABLED.Flags '' ; setglobal CAP_ENABLEDSUIONLY.ConType TWON_ENUMERATION setglobal CAP_ENABLEDSUIONLY.ItemType TWTY_BOOL setglobal CAP_ENABLEDSUIONLY.ValueAfterOpen UNDEFINED setglobal CAP_ENABLEDSUIONLY.ValueAfterReset UNDEFINED setglobal CAP_ENABLEDSUIONLY.Flags '' ; setglobal CAP_ENDORSER.ConType TWON_RANGE setglobal CAP_ENDORSER.ItemType TWTY_UINT32 setglobal CAP_ENDORSER.ValueAfterOpen UNDEFINED setglobal CAP_ENDORSER.ValueAfterReset 1 setglobal CAP_ENDORSER.Flags '' ; setglobal CAP_EXTENDEDCAPS.ConType TWON_ARRAY setglobal CAP_EXTENDEDCAPS.ItemType TWTY_UINT16 setglobal CAP_EXTENDEDCAPS.ValueAfterOpen UNDEFINED setglobal CAP_EXTENDEDCAPS.ValueAfterReset UNDEFINED setglobal CAP_EXTENDEDCAPS.Flags '' ; setglobal CAP_FEEDERALIGNMENT.ConType TWON_ENUMERATION,TWON_ONEVALUE setglobal CAP_FEEDERALIGNMENT.ItemType TWTY_UINT16 setglobal CAP_FEEDERALIGNMENT.ValueAfterOpen UNDEFINED setglobal CAP_FEEDERALIGNMENT.ValueAfterReset UNDEFINED setglobal CAP_FEEDERALIGNMENT.Flags '' ; setglobal CAP_FEEDERENABLED.ConType TWON_ENUMERATION setglobal CAP_FEEDERENABLED.ItemType TWTY_BOOL setglobal CAP_FEEDERENABLED.ValueAfterOpen UNDEFINED setglobal CAP_FEEDERENABLED.ValueAfterReset UNDEFINED setglobal CAP_FEEDERENABLED.Flags '' ; setglobal CAP_FEEDERLOADED.ConType TWON_ENUMERATION setglobal CAP_FEEDERLOADED.ItemType TWTY_BOOL setglobal CAP_FEEDERLOADED.ValueAfterOpen UNDEFINED setglobal CAP_FEEDERLOADED.ValueAfterReset UNDEFINED setglobal CAP_FEEDERLOADED.Flags '' ; setglobal CAP_FEEDERORDER.ConType TWON_ENUMERATION,TWON_ONEVALUE setglobal CAP_FEEDERORDER.ItemType TWTY_UINT16 setglobal CAP_FEEDERORDER.ValueAfterOpen UNDEFINED setglobal CAP_FEEDERORDER.ValueAfterReset UNDEFINED setglobal CAP_FEEDERORDER.Flags '' ; setglobal CAP_FEEDERPOCKET.ConType TWON_ARRAY setglobal CAP_FEEDERPOCKET.ItemType TWTY_UINT16 setglobal CAP_FEEDERPOCKET.ValueAfterOpen UNDEFINED setglobal CAP_FEEDERPOCKET.ValueAfterReset UNDEFINED setglobal CAP_FEEDERPOCKET.Flags '' ; setglobal CAP_FEEDERPREP.ConType TWON_ENUMERATION,TWON_ONEVALUE setglobal CAP_FEEDERPREP.ItemType TWTY_BOOL setglobal CAP_FEEDERPREP.ValueAfterOpen UNDEFINED setglobal CAP_FEEDERPREP.ValueAfterReset FALSE setglobal CAP_FEEDERPREP.Flags '' ; setglobal CAP_FEEDPAGE.ConType TWON_ENUMERATION setglobal CAP_FEEDPAGE.ItemType TWTY_BOOL setglobal CAP_FEEDPAGE.ValueAfterOpen UNDEFINED setglobal CAP_FEEDPAGE.ValueAfterReset UNDEFINED setglobal CAP_FEEDPAGE.Flags '' ; setglobal CAP_IAFIELDA_LASTPAGE.ConType TWON_ONEVALUE setglobal CAP_IAFIELDA_LASTPAGE.ItemType TWTY_STR32 setglobal CAP_IAFIELDA_LASTPAGE.ValueAfterOpen UNDEFINED setglobal CAP_IAFIELDA_LASTPAGE.ValueAfterReset UNDEFINED setglobal CAP_IAFIELDA_LASTPAGE.Flags '' ; setglobal CAP_IAFIELDB_LASTPAGE.ConType TWON_ONEVALUE setglobal CAP_IAFIELDB_LASTPAGE.ItemType TWTY_STR32 setglobal CAP_IAFIELDB_LASTPAGE.ValueAfterOpen UNDEFINED setglobal CAP_IAFIELDB_LASTPAGE.ValueAfterReset UNDEFINED setglobal CAP_IAFIELDB_LASTPAGE.Flags '' ; setglobal CAP_IAFIELDC_LASTPAGE.ConType TWON_ONEVALUE setglobal CAP_IAFIELDC_LASTPAGE.ItemType TWTY_STR32 setglobal CAP_IAFIELDC_LASTPAGE.ValueAfterOpen UNDEFINED setglobal CAP_IAFIELDC_LASTPAGE.ValueAfterReset UNDEFINED setglobal CAP_IAFIELDC_LASTPAGE.Flags '' ; setglobal CAP_IAFIELDD_LASTPAGE.ConType TWON_ONEVALUE setglobal CAP_IAFIELDD_LASTPAGE.ItemType TWTY_STR32 setglobal CAP_IAFIELDD_LASTPAGE.ValueAfterOpen UNDEFINED setglobal CAP_IAFIELDD_LASTPAGE.ValueAfterReset UNDEFINED setglobal CAP_IAFIELDD_LASTPAGE.Flags '' ; setglobal CAP_IAFIELDE_LASTPAGE.ConType TWON_ONEVALUE setglobal CAP_IAFIELDE_LASTPAGE.ItemType TWTY_STR32 setglobal CAP_IAFIELDE_LASTPAGE.ValueAfterOpen UNDEFINED setglobal CAP_IAFIELDE_LASTPAGE.ValueAfterReset UNDEFINED setglobal CAP_IAFIELDE_LASTPAGE.Flags '' ; setglobal CAP_IAFIELDA_LEVEL.ConType TWON_ENUMERATION setglobal CAP_IAFIELDA_LEVEL.ItemType TWTY_UINT16 setglobal CAP_IAFIELDA_LEVEL.ValueAfterOpen UNDEFINED setglobal CAP_IAFIELDA_LEVEL.ValueAfterReset TWIA_UNUSED setglobal CAP_IAFIELDA_LEVEL.Flags '' ; setglobal CAP_IAFIELDB_LEVEL.ConType TWON_ENUMERATION setglobal CAP_IAFIELDB_LEVEL.ItemType TWTY_UINT16 setglobal CAP_IAFIELDB_LEVEL.ValueAfterOpen UNDEFINED setglobal CAP_IAFIELDB_LEVEL.ValueAfterReset TWIA_UNUSED setglobal CAP_IAFIELDB_LEVEL.Flags '' ; setglobal CAP_IAFIELDC_LEVEL.ConType TWON_ENUMERATION setglobal CAP_IAFIELDC_LEVEL.ItemType TWTY_UINT16 setglobal CAP_IAFIELDC_LEVEL.ValueAfterOpen UNDEFINED setglobal CAP_IAFIELDC_LEVEL.ValueAfterReset TWIA_UNUSED setglobal CAP_IAFIELDC_LEVEL.Flags '' ; setglobal CAP_IAFIELDD_LEVEL.ConType TWON_ENUMERATION setglobal CAP_IAFIELDD_LEVEL.ItemType TWTY_UINT16 setglobal CAP_IAFIELDD_LEVEL.ValueAfterOpen UNDEFINED setglobal CAP_IAFIELDD_LEVEL.ValueAfterReset TWIA_UNUSED setglobal CAP_IAFIELDD_LEVEL.Flags '' ; setglobal CAP_IAFIELDE_LEVEL.ConType TWON_ENUMERATION setglobal CAP_IAFIELDE_LEVEL.ItemType TWTY_UINT16 setglobal CAP_IAFIELDE_LEVEL.ValueAfterOpen UNDEFINED setglobal CAP_IAFIELDE_LEVEL.ValueAfterReset TWIA_UNUSED setglobal CAP_IAFIELDE_LEVEL.Flags '' ; setglobal CAP_IAFIELDA_PRINTFORMAT.ConType TWON_ONEVALUE setglobal CAP_IAFIELDA_PRINTFORMAT.ItemType TWTY_STR32 setglobal CAP_IAFIELDA_PRINTFORMAT.ValueAfterOpen UNDEFINED setglobal CAP_IAFIELDA_PRINTFORMAT.ValueAfterReset UNDEFINED setglobal CAP_IAFIELDA_PRINTFORMAT.Flags '' ; setglobal CAP_IAFIELDB_PRINTFORMAT.ConType TWON_ONEVALUE setglobal CAP_IAFIELDB_PRINTFORMAT.ItemType TWTY_STR32 setglobal CAP_IAFIELDB_PRINTFORMAT.ValueAfterOpen UNDEFINED setglobal CAP_IAFIELDB_PRINTFORMAT.ValueAfterReset UNDEFINED setglobal CAP_IAFIELDB_PRINTFORMAT.Flags '' ; setglobal CAP_IAFIELDC_PRINTFORMAT.ConType TWON_ONEVALUE setglobal CAP_IAFIELDC_PRINTFORMAT.ItemType TWTY_STR32 setglobal CAP_IAFIELDC_PRINTFORMAT.ValueAfterOpen UNDEFINED setglobal CAP_IAFIELDC_PRINTFORMAT.ValueAfterReset UNDEFINED setglobal CAP_IAFIELDC_PRINTFORMAT.Flags '' ; setglobal CAP_IAFIELDD_PRINTFORMAT.ConType TWON_ONEVALUE setglobal CAP_IAFIELDD_PRINTFORMAT.ItemType TWTY_STR32 setglobal CAP_IAFIELDD_PRINTFORMAT.ValueAfterOpen UNDEFINED setglobal CAP_IAFIELDD_PRINTFORMAT.ValueAfterReset UNDEFINED setglobal CAP_IAFIELDD_PRINTFORMAT.Flags '' ; setglobal CAP_IAFIELDE_PRINTFORMAT.ConType TWON_ONEVALUE setglobal CAP_IAFIELDE_PRINTFORMAT.ItemType TWTY_STR32 setglobal CAP_IAFIELDE_PRINTFORMAT.ValueAfterOpen UNDEFINED setglobal CAP_IAFIELDE_PRINTFORMAT.ValueAfterReset UNDEFINED setglobal CAP_IAFIELDE_PRINTFORMAT.Flags '' ; setglobal CAP_IAFIELDA_VALUE.ConType TWON_ONEVALUE setglobal CAP_IAFIELDA_VALUE.ItemType TWTY_STR32 setglobal CAP_IAFIELDA_VALUE.ValueAfterOpen UNDEFINED setglobal CAP_IAFIELDA_VALUE.ValueAfterReset UNDEFINED setglobal CAP_IAFIELDA_VALUE.Flags '' ; setglobal CAP_IAFIELDB_VALUE.ConType TWON_ONEVALUE setglobal CAP_IAFIELDB_VALUE.ItemType TWTY_STR32 setglobal CAP_IAFIELDB_VALUE.ValueAfterOpen UNDEFINED setglobal CAP_IAFIELDB_VALUE.ValueAfterReset UNDEFINED setglobal CAP_IAFIELDB_VALUE.Flags '' ; setglobal CAP_IAFIELDC_VALUE.ConType TWON_ONEVALUE setglobal CAP_IAFIELDC_VALUE.ItemType TWTY_STR32 setglobal CAP_IAFIELDC_VALUE.ValueAfterOpen UNDEFINED setglobal CAP_IAFIELDC_VALUE.ValueAfterReset UNDEFINED setglobal CAP_IAFIELDC_VALUE.Flags '' ; setglobal CAP_IAFIELDD_VALUE.ConType TWON_ONEVALUE setglobal CAP_IAFIELDD_VALUE.ItemType TWTY_STR32 setglobal CAP_IAFIELDD_VALUE.ValueAfterOpen UNDEFINED setglobal CAP_IAFIELDD_VALUE.ValueAfterReset UNDEFINED setglobal CAP_IAFIELDD_VALUE.Flags '' ; setglobal CAP_IAFIELDE_VALUE.ConType TWON_ONEVALUE setglobal CAP_IAFIELDE_VALUE.ItemType TWTY_STR32 setglobal CAP_IAFIELDE_VALUE.ValueAfterOpen UNDEFINED setglobal CAP_IAFIELDE_VALUE.ValueAfterReset UNDEFINED setglobal CAP_IAFIELDE_VALUE.Flags '' ; setglobal CAP_IMAGEADDRESSENABLED.ConType TWON_ENUMERATION setglobal CAP_IMAGEADDRESSENABLED.ItemType TWTY_BOOL setglobal CAP_IMAGEADDRESSENABLED.ValueAfterOpen UNDEFINED setglobal CAP_IMAGEADDRESSENABLED.ValueAfterReset FALSE setglobal CAP_IMAGEADDRESSENABLED.Flags '' ; setglobal CAP_INDICATORS.ConType TWON_ENUMERATION setglobal CAP_INDICATORS.ItemType TWTY_BOOL setglobal CAP_INDICATORS.ValueAfterOpen TRUE setglobal CAP_INDICATORS.ValueAfterReset TRUE setglobal CAP_INDICATORS.Flags '' ; setglobal CAP_INDICATORSMODE.ConType TWON_ARRAY setglobal CAP_INDICATORSMODE.ItemType TWTY_UINT16 setglobal CAP_INDICATORSMODE.ValueAfterOpen UNDEFINED setglobal CAP_INDICATORSMODE.ValueAfterReset UNDEFINED setglobal CAP_INDICATORSMODE.Flags '' ; setglobal CAP_JOBCONTROL.ConType TWON_ENUMERATION,TWON_ONEVALUE setglobal CAP_JOBCONTROL.ItemType TWTY_UINT16 setglobal CAP_JOBCONTROL.ValueAfterOpen UNDEFINED setglobal CAP_JOBCONTROL.ValueAfterReset TWJC_NONE setglobal CAP_JOBCONTROL.Flags '' ; setglobal CAP_LANGUAGE.ConType TWON_ENUMERATION,TWON_ONEVALUE setglobal CAP_LANGUAGE.ItemType TWTY_UINT16 setglobal CAP_LANGUAGE.ValueAfterOpen UNDEFINED setglobal CAP_LANGUAGE.ValueAfterReset UNDEFINED setglobal CAP_LANGUAGE.Flags '' ; setglobal CAP_MAXBATCHBUFFERS.ConType TWON_RANGE,TWON_ONEVALUE setglobal CAP_MAXBATCHBUFFERS.ItemType TWTY_UINT32 setglobal CAP_MAXBATCHBUFFERS.ValueAfterOpen UNDEFINED setglobal CAP_MAXBATCHBUFFERS.ValueAfterReset UNDEFINED setglobal CAP_MAXBATCHBUFFERS.Flags '' ; setglobal CAP_MICRENABLED.ConType TWON_ENUMERATION setglobal CAP_MICRENABLED.ItemType TWTY_BOOL setglobal CAP_MICRENABLED.ValueAfterOpen UNDEFINED setglobal CAP_MICRENABLED.ValueAfterReset FALSE setglobal CAP_MICRENABLED.Flags '' ; setglobal CAP_PAGEMULTIREACQUIRE.ConType TWON_ENUMERATION,TWON_ONEVALUE setglobal CAP_PAGEMULTIREACQUIRE.ItemType TWTY_BOOL setglobal CAP_PAGEMULTIREACQUIRE.ValueAfterOpen UNDEFINED setglobal CAP_PAGEMULTIREACQUIRE.ValueAfterReset UNDEFINED setglobal CAP_PAGEMULTIREACQUIRE.Flags 'deprecated' ; setglobal CAP_PAPERBINDING.ConType TWON_ENUMERATION setglobal CAP_PAPERBINDING.ItemType TWTY_UINT16 setglobal CAP_PAPERBINDING.ValueAfterOpen UNDEFINED setglobal CAP_PAPERBINDING.ValueAfterReset UNDEFINED setglobal CAP_PAPERBINDING.Flags 'deprecated' ; setglobal CAP_PAPERDETECTABLE.ConType TWON_ENUMERATION setglobal CAP_PAPERDETECTABLE.ItemType TWTY_BOOL setglobal CAP_PAPERDETECTABLE.ValueAfterOpen UNDEFINED setglobal CAP_PAPERDETECTABLE.ValueAfterReset UNDEFINED setglobal CAP_PAPERDETECTABLE.Flags '' ; setglobal CAP_PAPERHANDLING.ConType TWON_ARRAY setglobal CAP_PAPERHANDLING.ItemType TWTY_UINT16 setglobal CAP_PAPERHANDLING.ValueAfterOpen UNDEFINED setglobal CAP_PAPERHANDLING.ValueAfterReset TWPH_NORMAL setglobal CAP_PAPERHANDLING.Flags '' ; setglobal CAP_PASSTHRU.ConType TWON_ENUMERATION,TWON_ONEVALUE setglobal CAP_PASSTHRU.ItemType TWTY_BOOL setglobal CAP_PASSTHRU.ValueAfterOpen UNDEFINED setglobal CAP_PASSTHRU.ValueAfterReset UNDEFINED setglobal CAP_PASSTHRU.Flags 'deprecated' ; setglobal CAP_POWERSAVETIME.ConType TWON_RANGE setglobal CAP_POWERSAVETIME.ItemType TWTY_INT32 setglobal CAP_POWERSAVETIME.ValueAfterOpen UNDEFINED setglobal CAP_POWERSAVETIME.ValueAfterReset UNDEFINED setglobal CAP_POWERSAVETIME.Flags '' ; setglobal CAP_POWERSUPPLY.ConType TWON_ENUMERATION,TWON_ONEVALUE setglobal CAP_POWERSUPPLY.ItemType TWTY_UINT16 setglobal CAP_POWERSUPPLY.ValueAfterOpen UNDEFINED setglobal CAP_POWERSUPPLY.ValueAfterReset UNDEFINED setglobal CAP_POWERSUPPLY.Flags '' ; setglobal CAP_PRINTER.ConType TWON_ENUMERATION,TWON_ONEVALUE setglobal CAP_PRINTER.ItemType TWTY_UINT16 setglobal CAP_PRINTER.ValueAfterOpen UNDEFINED setglobal CAP_PRINTER.ValueAfterReset UNDEFINED setglobal CAP_PRINTER.Flags '' ; setglobal CAP_PRINTERENABLED.ConType TWON_ENUMERATION setglobal CAP_PRINTERENABLED.ItemType TWTY_BOOL setglobal CAP_PRINTERENABLED.ValueAfterOpen UNDEFINED setglobal CAP_PRINTERENABLED.ValueAfterReset FALSE setglobal CAP_PRINTERENABLED.Flags '' ; setglobal CAP_PRINTERCHARROTATION.ConType TWON_ENUMERATION,TWON_RANGE,TWON_ONEVALUE setglobal CAP_PRINTERCHARROTATION.ItemType TWTY_UINT32 setglobal CAP_PRINTERCHARROTATION.ValueAfterOpen UNDEFINED setglobal CAP_PRINTERCHARROTATION.ValueAfterReset 0 setglobal CAP_PRINTERCHARROTATION.Flags '' ; setglobal CAP_PRINTERFONTSTYLE.ConType TWON_ARRAY setglobal CAP_PRINTERFONTSTYLE.ItemType TWTY_UINT16 setglobal CAP_PRINTERFONTSTYLE.ValueAfterOpen UNDEFINED setglobal CAP_PRINTERFONTSTYLE.ValueAfterReset TWPF_NORMAL setglobal CAP_PRINTERFONTSTYLE.Flags '' ; setglobal CAP_PRINTERINDEX.ConType TWON_RANGE,TWON_ONEVALUE setglobal CAP_PRINTERINDEX.ItemType TWTY_UINT32 setglobal CAP_PRINTERINDEX.ValueAfterOpen UNDEFINED setglobal CAP_PRINTERINDEX.ValueAfterReset UNDEFINED setglobal CAP_PRINTERINDEX.Flags '' ; setglobal CAP_PRINTERINDEXLEADCHAR.ConType TWON_ENUMERATION,TWON_ONEVALUE setglobal CAP_PRINTERINDEXLEADCHAR.ItemType TWTY_STR32 setglobal CAP_PRINTERINDEXLEADCHAR.ValueAfterOpen UNDEFINED setglobal CAP_PRINTERINDEXLEADCHAR.ValueAfterReset UNDEFINED setglobal CAP_PRINTERINDEXLEADCHAR.Flags '' ; setglobal CAP_PRINTERINDEXMAXVALUE.ConType TWON_ENUMERATION,TWON_RANGE,TWON_ONEVALUE setglobal CAP_PRINTERINDEXMAXVALUE.ItemType TWTY_UINT32 setglobal CAP_PRINTERINDEXMAXVALUE.ValueAfterOpen UNDEFINED setglobal CAP_PRINTERINDEXMAXVALUE.ValueAfterReset 0 setglobal CAP_PRINTERINDEXMAXVALUE.Flags '' ; setglobal CAP_PRINTERINDEXNUMDIGITS.ConType TWON_ENUMERATION,TWON_RANGE,TWON_ONEVALUE setglobal CAP_PRINTERINDEXNUMDIGITS.ItemType TWTY_UINT32 setglobal CAP_PRINTERINDEXNUMDIGITS.ValueAfterOpen UNDEFINED setglobal CAP_PRINTERINDEXNUMDIGITS.ValueAfterReset 0 setglobal CAP_PRINTERINDEXNUMDIGITS.Flags '' ; setglobal CAP_PRINTERINDEXSTEP.ConType TWON_ENUMERATION,TWON_RANGE,TWON_ONEVALUE setglobal CAP_PRINTERINDEXSTEP.ItemType TWTY_UINT32 setglobal CAP_PRINTERINDEXSTEP.ValueAfterOpen UNDEFINED setglobal CAP_PRINTERINDEXSTEP.ValueAfterReset 1 setglobal CAP_PRINTERINDEXSTEP.Flags '' ; setglobal CAP_PRINTERINDEXTRIGGER.ConType TWON_ARRAY setglobal CAP_PRINTERINDEXTRIGGER.ItemType TWTY_UINT16 setglobal CAP_PRINTERINDEXTRIGGER.ValueAfterOpen UNDEFINED setglobal CAP_PRINTERINDEXTRIGGER.ValueAfterReset TWCT_PAGE setglobal CAP_PRINTERINDEXTRIGGER.Flags '' ; setglobal CAP_PRINTERMODE.ConType TWON_ENUMERATION,TWON_ONEVALUE setglobal CAP_PRINTERMODE.ItemType TWTY_UINT16 setglobal CAP_PRINTERMODE.ValueAfterOpen UNDEFINED setglobal CAP_PRINTERMODE.ValueAfterReset UNDEFINED setglobal CAP_PRINTERMODE.Flags '' ; setglobal CAP_PRINTERSTRING.ConType TWON_ENUMERATION,TWON_ONEVALUE setglobal CAP_PRINTERSTRING.ItemType TWTY_STR255 setglobal CAP_PRINTERSTRING.ValueAfterOpen UNDEFINED setglobal CAP_PRINTERSTRING.ValueAfterReset UNDEFINED setglobal CAP_PRINTERSTRING.Flags '' ; setglobal CAP_PRINTERSTRINGPREVIEW.ConType TWON_ARRAY setglobal CAP_PRINTERSTRINGPREVIEW.ItemType TWTY_STR255 setglobal CAP_PRINTERSTRINGPREVIEW.ValueAfterOpen UNDEFINED setglobal CAP_PRINTERSTRINGPREVIEW.ValueAfterReset UNDEFINED setglobal CAP_PRINTERSTRINGPREVIEW.Flags '' ; setglobal CAP_PRINTERSUFFIX.ConType TWON_ONEVALUE setglobal CAP_PRINTERSUFFIX.ItemType TWTY_STR255 setglobal CAP_PRINTERSUFFIX.ValueAfterOpen UNDEFINED setglobal CAP_PRINTERSUFFIX.ValueAfterReset UNDEFINED setglobal CAP_PRINTERSUFFIX.Flags '' ; setglobal CAP_PRINTERVERTICALOFFSET.ConType TWON_RANGE,TWON_ONEVALUE setglobal CAP_PRINTERVERTICALOFFSET.ItemType TWTY_FIX32 setglobal CAP_PRINTERVERTICALOFFSET.ValueAfterOpen UNDEFINED setglobal CAP_PRINTERVERTICALOFFSET.ValueAfterReset UNDEFINED setglobal CAP_PRINTERVERTICALOFFSET.Flags '' ; setglobal CAP_REACQUIREALLOWED.ConType TWON_ENUMERATION setglobal CAP_REACQUIREALLOWED.ItemType TWTY_BOOL setglobal CAP_REACQUIREALLOWED.ValueAfterOpen UNDEFINED setglobal CAP_REACQUIREALLOWED.ValueAfterReset UNDEFINED setglobal CAP_REACQUIREALLOWED.Flags '' ; setglobal CAP_REWINDPAGE.ConType TWON_ENUMERATION setglobal CAP_REWINDPAGE.ItemType TWTY_BOOL setglobal CAP_REWINDPAGE.ValueAfterOpen FALSE setglobal CAP_REWINDPAGE.ValueAfterReset FALSE setglobal CAP_REWINDPAGE.Flags '' ; setglobal CAP_SEGMENTED.ConType TWON_ENUMERATION,TWON_ONEVALUE setglobal CAP_SEGMENTED.ItemType TWTY_UINT16 setglobal CAP_SEGMENTED.ValueAfterOpen UNDEFINED setglobal CAP_SEGMENTED.ValueAfterReset FALSE setglobal CAP_SEGMENTED.Flags '' ; setglobal CAP_SERIALNUMBER.ConType TWON_ONEVALUE setglobal CAP_SERIALNUMBER.ItemType TWTY_STR255 setglobal CAP_SERIALNUMBER.ValueAfterOpen UNDEFINED setglobal CAP_SERIALNUMBER.ValueAfterReset UNDEFINED setglobal CAP_SERIALNUMBER.Flags '' ; setglobal CAP_SHEETCOUNT.ConType TWON_RANGE,TWON_ONEVALUE setglobal CAP_SHEETCOUNT.ItemType TWTY_UINT32 setglobal CAP_SHEETCOUNT.ValueAfterOpen 0 setglobal CAP_SHEETCOUNT.ValueAfterReset 0 setglobal CAP_SHEETCOUNT.Flags '' ; setglobal CAP_SUPPORTEDCAPS.ConType TWON_ARRAY setglobal CAP_SUPPORTEDCAPS.ItemType TWTY_UINT16 setglobal CAP_SUPPORTEDCAPS.ValueAfterOpen UNDEFINED setglobal CAP_SUPPORTEDCAPS.ValueAfterReset UNDEFINED setglobal CAP_SUPPORTEDCAPS.Flags 'mandatory' ; setglobal CAP_SUPPORTEDCAPSEXT.ConType TWON_ARRAY setglobal CAP_SUPPORTEDCAPSEXT.ItemType TWTY_UINT16 setglobal CAP_SUPPORTEDCAPSEXT.ValueAfterOpen UNDEFINED setglobal CAP_SUPPORTEDCAPSEXT.ValueAfterReset UNDEFINED setglobal CAP_SUPPORTEDCAPSEXT.Flags 'deprecated' ; setglobal CAP_SUPPORTEDCAPSSEGMENTUNIQUE.ConType TWON_ARRAY setglobal CAP_SUPPORTEDCAPSSEGMENTUNIQUE.ItemType TWTY_UINT16 setglobal CAP_SUPPORTEDCAPSSEGMENTUNIQUE.ValueAfterOpen UNDEFINED setglobal CAP_SUPPORTEDCAPSSEGMENTUNIQUE.ValueAfterReset UNDEFINED setglobal CAP_SUPPORTEDCAPSSEGMENTUNIQUE.Flags '' ; setglobal CAP_SUPPORTEDDATS.ConType TWON_ARRAY setglobal CAP_SUPPORTEDDATS.ItemType TWTY_UINT32 setglobal CAP_SUPPORTEDDATS.ValueAfterOpen UNDEFINED setglobal CAP_SUPPORTEDDATS.ValueAfterReset UNDEFINED setglobal CAP_SUPPORTEDDATS.Flags 'mandatory' ; setglobal CAP_TIMEBEFOREFIRSTCAPTURE.ConType TWON_RANGE,TWON_ONEVALUE setglobal CAP_TIMEBEFOREFIRSTCAPTURE.ItemType TWTY_INT32 setglobal CAP_TIMEBEFOREFIRSTCAPTURE.ValueAfterOpen 0 setglobal CAP_TIMEBEFOREFIRSTCAPTURE.ValueAfterReset 0 setglobal CAP_TIMEBEFOREFIRSTCAPTURE.Flags '' ; setglobal CAP_TIMEBETWEENCAPTURES.ConType TWON_RANGE,TWON_ONEVALUE setglobal CAP_TIMEBETWEENCAPTURES.ItemType TWTY_INT32 setglobal CAP_TIMEBETWEENCAPTURES.ValueAfterOpen 0 setglobal CAP_TIMEBETWEENCAPTURES.ValueAfterReset 0 setglobal CAP_TIMEBETWEENCAPTURES.Flags '' ; setglobal CAP_TIMEDATE.ConType TWON_ONEVALUE setglobal CAP_TIMEDATE.ItemType TWTY_STR32 setglobal CAP_TIMEDATE.ValueAfterOpen UNDEFINED setglobal CAP_TIMEDATE.ValueAfterReset UNDEFINED setglobal CAP_TIMEDATE.Flags 'notstate4' ; setglobal CAP_THUMBNAILSENABLED.ConType TWON_ENUMERATION setglobal CAP_THUMBNAILSENABLED.ItemType TWTY_BOOL setglobal CAP_THUMBNAILSENABLED.ValueAfterOpen FALSE setglobal CAP_THUMBNAILSENABLED.ValueAfterReset FALSE setglobal CAP_THUMBNAILSENABLED.Flags '' ; setglobal CAP_UICONTROLLABLE.ConType TWON_ENUMERATION setglobal CAP_UICONTROLLABLE.ItemType TWTY_BOOL setglobal CAP_UICONTROLLABLE.ValueAfterOpen TRUE ; mandatory for all sources setglobal CAP_UICONTROLLABLE.ValueAfterReset UNDEFINED setglobal CAP_UICONTROLLABLE.Flags 'mandatory' ; setglobal CAP_XFERCOUNT.ConType TWON_RANGE,TWON_ONEVALUE setglobal CAP_XFERCOUNT.ItemType TWTY_INT16 setglobal CAP_XFERCOUNT.ValueAfterOpen -1 setglobal CAP_XFERCOUNT.ValueAfterReset -1 setglobal CAP_XFERCOUNT.Flags 'mandatory' ; setglobal ICAP_AUTOBRIGHT.ConType TWON_ENUMERATION setglobal ICAP_AUTOBRIGHT.ItemType TWTY_BOOL setglobal ICAP_AUTOBRIGHT.ValueAfterOpen UNDEFINED setglobal ICAP_AUTOBRIGHT.ValueAfterReset FALSE setglobal ICAP_AUTOBRIGHT.Flags '' ; setglobal ICAP_AUTODISCARDBLANKPAGES.ConType TWON_RANGE,TWON_ONEVALUE setglobal ICAP_AUTODISCARDBLANKPAGES.ItemType TWTY_INT32 setglobal ICAP_AUTODISCARDBLANKPAGES.ValueAfterOpen UNDEFINED setglobal ICAP_AUTODISCARDBLANKPAGES.ValueAfterReset -2 ; TWBP_DISABLE setglobal ICAP_AUTODISCARDBLANKPAGES.Flags '' ; setglobal ICAP_AUTOMATICBORDERDETECTION.ConType TWON_ENUMERATION setglobal ICAP_AUTOMATICBORDERDETECTION.ItemType TWTY_BOOL setglobal ICAP_AUTOMATICBORDERDETECTION.ValueAfterOpen UNDEFINED setglobal ICAP_AUTOMATICBORDERDETECTION.ValueAfterReset UNDEFINED setglobal ICAP_AUTOMATICBORDERDETECTION.Flags '' ; setglobal ICAP_AUTOMATICCOLORENABLED.ConType TWON_ENUMERATION setglobal ICAP_AUTOMATICCOLORENABLED.ItemType TWTY_BOOL setglobal ICAP_AUTOMATICCOLORENABLED.ValueAfterOpen UNDEFINED setglobal ICAP_AUTOMATICCOLORENABLED.ValueAfterReset FALSE setglobal ICAP_AUTOMATICCOLORENABLED.Flags '' ; setglobal ICAP_AUTOMATICCOLORNONCOLORPIXELTYPE.ConType TWON_ENUMERATION,TWON_ONEVALUE setglobal ICAP_AUTOMATICCOLORNONCOLORPIXELTYPE.ItemType TWTY_UINT16 setglobal ICAP_AUTOMATICCOLORNONCOLORPIXELTYPE.ValueAfterOpen UNDEFINED setglobal ICAP_AUTOMATICCOLORNONCOLORPIXELTYPE.ValueAfterReset TWPT_BW setglobal ICAP_AUTOMATICCOLORNONCOLORPIXELTYPE.Flags '' ; setglobal ICAP_AUTOMATICCROPUSESFRAME.ConType TWON_ENUMERATION setglobal ICAP_AUTOMATICCROPUSESFRAME.ItemType TWTY_BOOL setglobal ICAP_AUTOMATICCROPUSESFRAME.ValueAfterOpen UNDEFINED setglobal ICAP_AUTOMATICCROPUSESFRAME.ValueAfterReset UNDEFINED setglobal ICAP_AUTOMATICCROPUSESFRAME.Flags '' ; setglobal ICAP_AUTOMATICDESKEW.ConType TWON_ENUMERATION setglobal ICAP_AUTOMATICDESKEW.ItemType TWTY_BOOL setglobal ICAP_AUTOMATICDESKEW.ValueAfterOpen UNDEFINED setglobal ICAP_AUTOMATICDESKEW.ValueAfterReset UNDEFINED setglobal ICAP_AUTOMATICDESKEW.Flags '' ; setglobal ICAP_AUTOMATICLENGTHDETECTION.ConType TWON_ENUMERATION setglobal ICAP_AUTOMATICLENGTHDETECTION.ItemType TWTY_BOOL setglobal ICAP_AUTOMATICLENGTHDETECTION.ValueAfterOpen UNDEFINED setglobal ICAP_AUTOMATICLENGTHDETECTION.ValueAfterReset UNDEFINED setglobal ICAP_AUTOMATICLENGTHDETECTION.Flags '' ; setglobal ICAP_AUTOMATICROTATE.ConType TWON_ENUMERATION setglobal ICAP_AUTOMATICROTATE.ItemType TWTY_BOOL setglobal ICAP_AUTOMATICROTATE.ValueAfterOpen UNDEFINED setglobal ICAP_AUTOMATICROTATE.ValueAfterReset FALSE setglobal ICAP_AUTOMATICROTATE.Flags '' ; setglobal ICAP_AUTOSIZE.ConType TWON_ENUMERATION,TWON_ONEVALUE setglobal ICAP_AUTOSIZE.ItemType TWTY_UINT16 setglobal ICAP_AUTOSIZE.ValueAfterOpen UNDEFINED setglobal ICAP_AUTOSIZE.ValueAfterReset TWAS_NONE setglobal ICAP_AUTOSIZE.Flags '' ; setglobal ICAP_BARCODEDETECTIONENABLED.ConType TWON_ENUMERATION setglobal ICAP_BARCODEDETECTIONENABLED.ItemType TWTY_BOOL setglobal ICAP_BARCODEDETECTIONENABLED.ValueAfterOpen UNDEFINED setglobal ICAP_BARCODEDETECTIONENABLED.ValueAfterReset FALSE setglobal ICAP_BARCODEDETECTIONENABLED.Flags '' ; setglobal ICAP_BARCODEMAXRETRIES.ConType TWON_ENUMERATION,TWON_RANGE,TWON_ONEVALUE setglobal ICAP_BARCODEMAXRETRIES.ItemType TWTY_UINT32 setglobal ICAP_BARCODEMAXRETRIES.ValueAfterOpen UNDEFINED setglobal ICAP_BARCODEMAXRETRIES.ValueAfterReset UNDEFINED setglobal ICAP_BARCODEMAXRETRIES.Flags '' ; setglobal ICAP_BARCODEMAXSEARCHPRIORITIES.ConType TWON_ENUMERATION,TWON_RANGE,TWON_ONEVALUE setglobal ICAP_BARCODEMAXSEARCHPRIORITIES.ItemType TWTY_UINT32 setglobal ICAP_BARCODEMAXSEARCHPRIORITIES.ValueAfterOpen UNDEFINED setglobal ICAP_BARCODEMAXSEARCHPRIORITIES.ValueAfterOpen UNDEFINED setglobal ICAP_BARCODEMAXSEARCHPRIORITIES.Flags '' ; setglobal ICAP_BARCODESEARCHMODE.ConType TWON_ENUMERATION,TWON_ONEVALUE setglobal ICAP_BARCODESEARCHMODE.ItemType TWTY_UINT16 setglobal ICAP_BARCODESEARCHMODE.ValueAfterOpen UNDEFINED setglobal ICAP_BARCODESEARCHMODE.ValueAfterReset UNDEFINED setglobal ICAP_BARCODESEARCHMODE.Flags '' ; setglobal ICAP_BARCODESEARCHPRIORITIES.ConType TWON_ARRAY setglobal ICAP_BARCODESEARCHPRIORITIES.ItemType TWTY_UINT16 setglobal ICAP_BARCODESEARCHPRIORITIES.ValueAfterOpen UNDEFINED setglobal ICAP_BARCODESEARCHPRIORITIES.ValueAfterReset UNDEFINED setglobal ICAP_BARCODESEARCHPRIORITIES.Flags '' ; setglobal ICAP_BARCODETIMEOUT.ConType TWON_ENUMERATION,TWON_RANGE,TWON_ONEVALUE setglobal ICAP_BARCODETIMEOUT.ItemType TWTY_UINT32 setglobal ICAP_BARCODETIMEOUT.ValueAfterOpen UNDEFINED setglobal ICAP_BARCODETIMEOUT.ValueAfterReset UNDEFINED setglobal ICAP_BARCODETIMEOUT.Flags '' ; setglobal ICAP_BITDEPTH.ConType TWON_ENUMERATION,TWON_ONEVALUE setglobal ICAP_BITDEPTH.ItemType TWTY_UINT16 setglobal ICAP_BITDEPTH.ValueAfterOpen UNDEFINED setglobal ICAP_BITDEPTH.ValueAfterReset UNDEFINED setglobal ICAP_BITDEPTH.Flags 'mandatory' ; setglobal ICAP_BITDEPTHREDUCTION.ConType TWON_ENUMERATION,TWON_ONEVALUE setglobal ICAP_BITDEPTHREDUCTION.ItemType TWTY_UINT16 setglobal ICAP_BITDEPTHREDUCTION.ValueAfterOpen UNDEFINED setglobal ICAP_BITDEPTHREDUCTION.ValueAfterReset UNDEFINED setglobal ICAP_BITDEPTHREDUCTION.Flags '' ; setglobal ICAP_BITORDER.ConType TWON_ENUMERATION,TWON_ONEVALUE setglobal ICAP_BITORDER.ItemType TWTY_UINT16 setglobal ICAP_BITORDER.ValueAfterOpen UNDEFINED ; spec says TWBO_LSBFIRST, but who ever used this? setglobal ICAP_BITORDER.ValueAfterReset UNDEFINED ; spec says TWBO_LSBFIRST, but who ever used this? setglobal ICAP_BITORDER.Flags 'mandatory' ; setglobal ICAP_BITORDERCODES.ConType TWON_ENUMERATION,TWON_ONEVALUE setglobal ICAP_BITORDERCODES.ItemType TWTY_UINT16 setglobal ICAP_BITORDERCODES.ValueAfterOpen UNDEFINED setglobal ICAP_BITORDERCODES.ValueAfterReset UNDEFINED setglobal ICAP_BITORDERCODES.Flags '' ; setglobal ICAP_BRIGHTNESS.ConType TWON_ENUMERATION,TWON_RANGE,TWON_ONEVALUE setglobal ICAP_BRIGHTNESS.ItemType TWTY_FIX32 setglobal ICAP_BRIGHTNESS.ValueAfterOpen UNDEFINED setglobal ICAP_BRIGHTNESS.ValueAfterReset 0 setglobal ICAP_BRIGHTNESS.Flags '' ; setglobal ICAP_CCITTKFACTOR.ConType TWON_RANGE,TWON_ONEVALUE setglobal ICAP_CCITTKFACTOR.ItemType TWTY_UINT16 setglobal ICAP_CCITTKFACTOR.ValueAfterOpen UNDEFINED setglobal ICAP_CCITTKFACTOR.ValueAfterReset 4 setglobal ICAP_CCITTKFACTOR.Flags '' ; setglobal ICAP_COLORMANAGEMENTENABLED.ConType TWON_ENUMERATION,TWON_ONEVALUE setglobal ICAP_COLORMANAGEMENTENABLED.ItemType TWTY_UINT16 setglobal ICAP_COLORMANAGEMENTENABLED.ValueAfterOpen TRUE setglobal ICAP_COLORMANAGEMENTENABLED.ValueAfterReset TRUE setglobal ICAP_COLORMANAGEMENTENABLED.Flags '' ; setglobal ICAP_COMPRESSION.ConType TWON_ENUMERATION,TWON_ONEVALUE setglobal ICAP_COMPRESSION.ItemType TWTY_UINT16 setglobal ICAP_COMPRESSION.ValueAfterOpen UNDEFINED setglobal ICAP_COMPRESSION.ValueAfterReset TWCP_NONE setglobal ICAP_COMPRESSION.Flags 'mandatory' ; setglobal ICAP_CONTRAST.ConType TWON_ENUMERATION,TWON_RANGE,TWON_ONEVALUE setglobal ICAP_CONTRAST.ItemType TWTY_FIX32 setglobal ICAP_CONTRAST.ValueAfterOpen UNDEFINED setglobal ICAP_CONTRAST.ValueAfterReset 0 setglobal ICAP_CONTRAST.Flags '' ; setglobal ICAP_CUSTHALFTONE.ConType TWON_ARRAY setglobal ICAP_CUSTHALFTONE.ItemType TWTY_UINT8 setglobal ICAP_CUSTHALFTONE.ValueAfterOpen UNDEFINED setglobal ICAP_CUSTHALFTONE.ValueAfterReset UNDEFINED setglobal ICAP_CUSTHALFTONE.Flags '' ; setglobal ICAP_EXPOSURETIME.ConType TWON_ENUMERATION,TWON_RANGE,TWON_ONEVALUE setglobal ICAP_EXPOSURETIME.ItemType TWTY_FIX32 setglobal ICAP_EXPOSURETIME.ValueAfterOpen UNDEFINED setglobal ICAP_EXPOSURETIME.ValueAfterReset UNDEFINED setglobal ICAP_EXPOSURETIME.Flags '' ; setglobal ICAP_EXTIMAGEINFO.ConType TWON_ENUMERATION setglobal ICAP_EXTIMAGEINFO.ItemType TWTY_BOOL setglobal ICAP_EXTIMAGEINFO.ValueAfterOpen UNDEFINED setglobal ICAP_EXTIMAGEINFO.ValueAfterReset TRUE setglobal ICAP_EXTIMAGEINFO.Flags '' ; setglobal ICAP_FEEDERTYPE.ConType TWON_ENUMERATION,TWON_ONEVALUE setglobal ICAP_FEEDERTYPE.ItemType TWTY_UINT16 setglobal ICAP_FEEDERTYPE.ValueAfterOpen UNDEFINED setglobal ICAP_FEEDERTYPE.ValueAfterReset UNDEFINED setglobal ICAP_FEEDERTYPE.Flags '' ; setglobal ICAP_FILMTYPE.ConType TWON_ENUMERATION setglobal ICAP_FILMTYPE.ItemType TWTY_UINT16 setglobal ICAP_FILMTYPE.ValueAfterOpen UNDEFINED setglobal ICAP_FILMTYPE.ValueAfterReset UNDEFINED setglobal ICAP_FILMTYPE.Flags '' ; setglobal ICAP_FILTER.ConType TWON_ARRAY,TWON_ONEVALUE setglobal ICAP_FILTER.ItemType TWTY_UINT16 setglobal ICAP_FILTER.ValueAfterOpen UNDEFINED setglobal ICAP_FILTER.ValueAfterReset '' setglobal ICAP_FILTER.Flags '' ; setglobal ICAP_FLASHUSED2.ConType TWON_ENUMERATION,TWON_ONEVALUE setglobal ICAP_FLASHUSED2.ItemType TWTY_UINT16 setglobal ICAP_FLASHUSED2.ValueAfterOpen UNDEFINED setglobal ICAP_FLASHUSED2.ValueAfterReset UNDEFINED setglobal ICAP_FLASHUSED2.Flags '' ; setglobal ICAP_FLIPROTATION.ConType TWON_ENUMERATION,TWON_ONEVALUE setglobal ICAP_FLIPROTATION.ItemType TWTY_UINT16 setglobal ICAP_FLIPROTATION.ValueAfterOpen UNDEFINED setglobal ICAP_FLIPROTATION.ValueAfterReset TWFR_BOOK setglobal ICAP_FLIPROTATION.Flags '' ; setglobal ICAP_FRAMES.ConType TWON_ENUMERATION,TWON_ONEVALUE setglobal ICAP_FRAMES.ItemType TWTY_FRAME setglobal ICAP_FRAMES.ValueAfterOpen UNDEFINED setglobal ICAP_FRAMES.ValueAfterReset UNDEFINED setglobal ICAP_FRAMES.Flags '' ; setglobal ICAP_GAMMA.ConType TWON_RANGE,TWON_ONEVALUE setglobal ICAP_GAMMA.ItemType TWTY_FIX32 setglobal ICAP_GAMMA.ValueAfterOpen UNDEFINED setglobal ICAP_GAMMA.ValueAfterReset UNDEFINED setglobal ICAP_GAMMA.Flags '' ; setglobal ICAP_HALFTONES.ConType TWON_ENUMERATION,TWON_ONEVALUE setglobal ICAP_HALFTONES.ItemType TWTY_STR32 setglobal ICAP_HALFTONES.ValueAfterOpen UNDEFINED setglobal ICAP_HALFTONES.ValueAfterReset UNDEFINED setglobal ICAP_HALFTONES.Flags '' ; setglobal ICAP_HIGHLIGHT.ConType TWON_ENUMERATION,TWON_RANGE,TWON_ONEVALUE setglobal ICAP_HIGHLIGHT.ItemType TWTY_FIX32 setglobal ICAP_HIGHLIGHT.ValueAfterOpen UNDEFINED setglobal ICAP_HIGHLIGHT.ValueAfterReset 255 setglobal ICAP_HIGHLIGHT.Flags '' ; setglobal ICAP_ICCPROFILE.ConType TWON_ENUMERATION,TWON_ONEVALUE setglobal ICAP_ICCPROFILE.ItemType TWTY_UINT16 setglobal ICAP_ICCPROFILE.ValueAfterOpen UNDEFINED setglobal ICAP_ICCPROFILE.ValueAfterReset UNDEFINED setglobal ICAP_ICCPROFILE.Flags '' ; setglobal ICAP_IMAGEDATASET.ConType TWON_ENUMERATION,TWON_RANGE,TWON_ONEVALUE setglobal ICAP_IMAGEDATASET.ItemType TWTY_UINT32 setglobal ICAP_IMAGEDATASET.ValueAfterOpen UNDEFINED setglobal ICAP_IMAGEDATASET.ValueAfterReset UNDEFINED setglobal ICAP_IMAGEDATASET.Flags '' ; setglobal ICAP_IMAGEFILEFORMAT.ConType TWON_ENUMERATION,TWON_ONEVALUE setglobal ICAP_IMAGEFILEFORMAT.ItemType TWTY_UINT16 setglobal ICAP_IMAGEFILEFORMAT.ValueAfterOpen UNDEFINED setglobal ICAP_IMAGEFILEFORMAT.ValueAfterReset UNDEFINED setglobal ICAP_IMAGEFILEFORMAT.Flags '' ; setglobal ICAP_IMAGEFILTER.ConType TWON_ENUMERATION,TWON_ONEVALUE setglobal ICAP_IMAGEFILTER.ItemType TWTY_UINT16 setglobal ICAP_IMAGEFILTER.ValueAfterOpen UNDEFINED setglobal ICAP_IMAGEFILTER.ValueAfterReset UNDEFINED setglobal ICAP_IMAGEFILTER.Flags '' ; setglobal ICAP_IMAGEMERGE.ConType TWON_ENUMERATION,TWON_ONEVALUE setglobal ICAP_IMAGEMERGE.ItemType TWTY_UINT16 setglobal ICAP_IMAGEMERGE.ValueAfterOpen UNDEFINED setglobal ICAP_IMAGEMERGE.ValueAfterReset TWIM_NONE setglobal ICAP_IMAGEMERGE.Flags '' ; setglobal ICAP_IMAGEMERGEHEIGHTTHRESHOLD.ConType TWON_RANGE,TWON_ONEVALUE setglobal ICAP_IMAGEMERGEHEIGHTTHRESHOLD.ItemType TWTY_FIX32 setglobal ICAP_IMAGEMERGEHEIGHTTHRESHOLD.ValueAfterOpen UNDEFINED setglobal ICAP_IMAGEMERGEHEIGHTTHRESHOLD.ValueAfterReset 0 setglobal ICAP_IMAGEMERGEHEIGHTTHRESHOLD.Flags '' ; setglobal ICAP_JPEGPIXELTYPE.ConType TWON_ENUMERATION,TWON_ONEVALUE setglobal ICAP_JPEGPIXELTYPE.ItemType TWTY_UINT16 setglobal ICAP_JPEGPIXELTYPE.ValueAfterOpen UNDEFINED setglobal ICAP_JPEGPIXELTYPE.ValueAfterReset UNDEFINED setglobal ICAP_JPEGPIXELTYPE.Flags '' ; setglobal ICAP_JPEGQUALITY.ConType TWON_ENUMERATION,TWON_RANGE,TWON_ONEVALUE setglobal ICAP_JPEGQUALITY.ItemType TWTY_INT16 setglobal ICAP_JPEGQUALITY.ValueAfterOpen UNDEFINED setglobal ICAP_JPEGQUALITY.ValueAfterReset UNDEFINED setglobal ICAP_JPEGQUALITY.Flags '' ; setglobal ICAP_JPEGSUBSAMPLING.ConType TWON_ENUMERATION setglobal ICAP_JPEGSUBSAMPLING.ItemType TWTY_UINT16 setglobal ICAP_JPEGSUBSAMPLING.ValueAfterOpen UNDEFINED setglobal ICAP_JPEGSUBSAMPLING.ValueAfterReset UNDEFINED setglobal ICAP_JPEGSUBSAMPLING.Flags '' ; setglobal ICAP_LAMPSTATE.ConType TWON_ENUMERATION setglobal ICAP_LAMPSTATE.ItemType TWTY_BOOL setglobal ICAP_LAMPSTATE.ValueAfterOpen UNDEFINED setglobal ICAP_LAMPSTATE.ValueAfterReset UNDEFINED setglobal ICAP_LAMPSTATE.Flags '' ; setglobal ICAP_LIGHTPATH.ConType TWON_ENUMERATION,TWON_ONEVALUE setglobal ICAP_LIGHTPATH.ItemType TWTY_UINT16 setglobal ICAP_LIGHTPATH.ValueAfterOpen UNDEFINED setglobal ICAP_LIGHTPATH.ValueAfterReset UNDEFINED setglobal ICAP_LIGHTPATH.Flags '' ; setglobal ICAP_LIGHTSOURCE.ConType TWON_ENUMERATION,TWON_ONEVALUE setglobal ICAP_LIGHTSOURCE.ItemType TWTY_UINT16 setglobal ICAP_LIGHTSOURCE.ValueAfterOpen UNDEFINED setglobal ICAP_LIGHTSOURCE.ValueAfterReset UNDEFINED setglobal ICAP_LIGHTSOURCE.Flags '' ; setglobal ICAP_MAXFRAMES.ConType TWON_RANGE,TWON_ONEVALUE setglobal ICAP_MAXFRAMES.ItemType TWTY_UINT16 setglobal ICAP_MAXFRAMES.ValueAfterOpen UNDEFINED setglobal ICAP_MAXFRAMES.ValueAfterReset UNDEFINED setglobal ICAP_MAXFRAMES.Flags '' ; setglobal ICAP_MINIMUMHEIGHT.ConType TWON_ONEVALUE setglobal ICAP_MINIMUMHEIGHT.ItemType TWTY_FIX32 setglobal ICAP_MINIMUMHEIGHT.ValueAfterOpen UNDEFINED setglobal ICAP_MINIMUMHEIGHT.ValueAfterReset UNDEFINED setglobal ICAP_MINIMUMHEIGHT.Flags '' ; setglobal ICAP_MINIMUMWIDTH.ConType TWON_ONEVALUE setglobal ICAP_MINIMUMWIDTH.ItemType TWTY_FIX32 setglobal ICAP_MINIMUMWIDTH.ValueAfterOpen UNDEFINED setglobal ICAP_MINIMUMWIDTH.ValueAfterReset UNDEFINED setglobal ICAP_MINIMUMWIDTH.Flags '' ; setglobal ICAP_MIRROR.ConType TWON_ENUMERATION,TWON_ONEVALUE setglobal ICAP_MIRROR.ItemType TWTY_UINT16 setglobal ICAP_MIRROR.ValueAfterOpen UNDEFINED setglobal ICAP_MIRROR.ValueAfterReset TWMR_NONE setglobal ICAP_MIRROR.Flags '' ; setglobal ICAP_NOISEFILTER.ConType TWON_ENUMERATION,TWON_ONEVALUE setglobal ICAP_NOISEFILTER.ItemType TWTY_UINT16 setglobal ICAP_NOISEFILTER.ValueAfterOpen UNDEFINED setglobal ICAP_NOISEFILTER.ValueAfterReset UNDEFINED setglobal ICAP_NOISEFILTER.Flags '' ; setglobal ICAP_ORIENTATION.ConType TWON_ENUMERATION,TWON_ONEVALUE setglobal ICAP_ORIENTATION.ItemType TWTY_UINT16 setglobal ICAP_ORIENTATION.ValueAfterOpen UNDEFINED setglobal ICAP_ORIENTATION.ValueAfterReset TWOR_ROT0|TWOR_PORTRAIT setglobal ICAP_ORIENTATION.Flags '' ; setglobal ICAP_OVERSCAN.ConType TWON_ENUMERATION,TWON_ONEVALUE setglobal ICAP_OVERSCAN.ItemType TWTY_UINT16 setglobal ICAP_OVERSCAN.ValueAfterOpen UNDEFINED setglobal ICAP_OVERSCAN.ValueAfterReset TWOV_NONE setglobal ICAP_OVERSCAN.Flags '' ; setglobal ICAP_PATCHCODEDETECTIONENABLED.ConType TWON_ENUMERATION setglobal ICAP_PATCHCODEDETECTIONENABLED.ItemType TWTY_BOOL setglobal ICAP_PATCHCODEDETECTIONENABLED.ValueAfterOpen UNDEFINED setglobal ICAP_PATCHCODEDETECTIONENABLED.ValueAfterReset FALSE setglobal ICAP_PATCHCODEDETECTIONENABLED.Flags '' ; setglobal ICAP_PATCHCODEMAXRETRIES.ConType TWON_ENUMERATION,TWON_RANGE,TWON_ONEVALUE setglobal ICAP_PATCHCODEMAXRETRIES.ItemType TWTY_UINT32 setglobal ICAP_PATCHCODEMAXRETRIES.ValueAfterOpen UNDEFINED setglobal ICAP_PATCHCODEMAXRETRIES.ValueAfterReset UNDEFINED setglobal ICAP_PATCHCODEMAXRETRIES.Flags '' ; setglobal ICAP_PATCHCODEMAXSEARCHPRIORITIES.ConType TWON_ENUMERATION,TWON_RANGE,TWON_ONEVALUE setglobal ICAP_PATCHCODEMAXSEARCHPRIORITIES.ItemType TWTY_UINT32 setglobal ICAP_PATCHCODEMAXSEARCHPRIORITIES.ValueAfterOpen UNDEFINED setglobal ICAP_PATCHCODEMAXSEARCHPRIORITIES.ValueAfterReset UNDEFINED setglobal ICAP_PATCHCODEMAXSEARCHPRIORITIES.Flags '' ; setglobal ICAP_PATCHCODESEARCHMODE.ConType TWON_ENUMERATION,TWON_ONEVALUE setglobal ICAP_PATCHCODESEARCHMODE.ItemType TWTY_UINT16 setglobal ICAP_PATCHCODESEARCHMODE.ValueAfterOpen UNDEFINED setglobal ICAP_PATCHCODESEARCHMODE.ValueAfterReset UNDEFINED setglobal ICAP_PATCHCODESEARCHMODE.Flags '' ; setglobal ICAP_PATCHCODESEARCHPRIORITIES.ConType TWON_ARRAY setglobal ICAP_PATCHCODESEARCHPRIORITIES.ItemType TWTY_UINT16 setglobal ICAP_PATCHCODESEARCHPRIORITIES.ValueAfterOpen UNDEFINED setglobal ICAP_PATCHCODESEARCHPRIORITIES.ValueAfterReset UNDEFINED setglobal ICAP_PATCHCODESEARCHPRIORITIES.Flags '' ; setglobal ICAP_PATCHCODETIMEOUT.ConType TWON_ENUMERATION,TWON_RANGE,TWON_ONEVALUE setglobal ICAP_PATCHCODETIMEOUT.ItemType TWTY_UINT32 setglobal ICAP_PATCHCODETIMEOUT.ValueAfterOpen UNDEFINED setglobal ICAP_PATCHCODETIMEOUT.ValueAfterReset UNDEFINED setglobal ICAP_PATCHCODETIMEOUT.Flags '' ; setglobal ICAP_PHYSICALHEIGHT.ConType TWON_ONEVALUE setglobal ICAP_PHYSICALHEIGHT.ItemType TWTY_FIX32 setglobal ICAP_PHYSICALHEIGHT.ValueAfterOpen UNDEFINED setglobal ICAP_PHYSICALHEIGHT.ValueAfterReset UNDEFINED setglobal ICAP_PHYSICALHEIGHT.Flags 'mandatory' ; setglobal ICAP_PHYSICALWIDTH.ConType TWON_ONEVALUE setglobal ICAP_PHYSICALWIDTH.ItemType TWTY_FIX32 setglobal ICAP_PHYSICALWIDTH.ValueAfterOpen UNDEFINED setglobal ICAP_PHYSICALWIDTH.ValueAfterReset UNDEFINED setglobal ICAP_PHYSICALWIDTH.Flags 'mandatory' ; setglobal ICAP_PIXELFLAVOR.ConType TWON_ENUMERATION,TWON_ONEVALUE setglobal ICAP_PIXELFLAVOR.ItemType TWTY_UINT16 setglobal ICAP_PIXELFLAVOR.ValueAfterOpen UNDEFINED setglobal ICAP_PIXELFLAVOR.ValueAfterReset TWPF_CHOCOLATE setglobal ICAP_PIXELFLAVOR.Flags 'mandatory' ; setglobal ICAP_PIXELFLAVORCODES.ConType TWON_ENUMERATION,TWON_ONEVALUE setglobal ICAP_PIXELFLAVORCODES.ItemType TWTY_UINT16 setglobal ICAP_PIXELFLAVORCODES.ValueAfterOpen UNDEFINED setglobal ICAP_PIXELFLAVORCODES.ValueAfterReset TWPF_CHOCOLATE setglobal ICAP_PIXELFLAVORCODES.Flags '' ; setglobal ICAP_PIXELTYPE.ConType TWON_ENUMERATION,TWON_ONEVALUE setglobal ICAP_PIXELTYPE.ItemType TWTY_UINT16 setglobal ICAP_PIXELTYPE.ValueAfterOpen UNDEFINED setglobal ICAP_PIXELTYPE.ValueAfterReset UNDEFINED setglobal ICAP_PIXELTYPE.Flags 'mandatory' ; setglobal ICAP_PLANARCHUNKY.ConType TWON_ENUMERATION,TWON_ONEVALUE setglobal ICAP_PLANARCHUNKY.ItemType TWTY_UINT16 setglobal ICAP_PLANARCHUNKY.ValueAfterOpen UNDEFINED setglobal ICAP_PLANARCHUNKY.ValueAfterReset UNDEFINED setglobal ICAP_PLANARCHUNKY.Flags 'mandatory' ; setglobal ICAP_ROTATION.ConType TWON_ENUMERATION,TWON_RANGE,TWON_ONEVALUE setglobal ICAP_ROTATION.ItemType TWTY_FIX32 setglobal ICAP_ROTATION.ValueAfterOpen UNDEFINED setglobal ICAP_ROTATION.ValueAfterReset 0 setglobal ICAP_ROTATION.Flags '' ; setglobal ICAP_SHADOW.ConType TWON_ENUMERATION,TWON_RANGE,TWON_ONEVALUE setglobal ICAP_SHADOW.ItemType TWTY_FIX32 setglobal ICAP_SHADOW.ValueAfterOpen UNDEFINED setglobal ICAP_SHADOW.ValueAfterReset 0 setglobal ICAP_SHADOW.Flags '' ; setglobal ICAP_SUPPORTEDBARCODETYPES.ConType TWON_ARRAY setglobal ICAP_SUPPORTEDBARCODETYPES.ItemType TWTY_UINT16 setglobal ICAP_SUPPORTEDBARCODETYPES.ValueAfterOpen UNDEFINED setglobal ICAP_SUPPORTEDBARCODETYPES.ValueAfterReset UNDEFINED setglobal ICAP_SUPPORTEDBARCODETYPES.Flags '' ; setglobal ICAP_SUPPORTEDEXTIMAGEINFO.ConType TWON_ARRAY setglobal ICAP_SUPPORTEDEXTIMAGEINFO.ItemType TWTY_UINT16 setglobal ICAP_SUPPORTEDEXTIMAGEINFO.ValueAfterOpen UNDEFINED setglobal ICAP_SUPPORTEDEXTIMAGEINFO.ValueAfterReset UNDEFINED setglobal ICAP_SUPPORTEDEXTIMAGEINFO.Flags '' ; setglobal ICAP_SUPPORTEDPATCHCODETYPES.ConType TWON_ARRAY setglobal ICAP_SUPPORTEDPATCHCODETYPES.ItemType TWTY_UINT16 setglobal ICAP_SUPPORTEDPATCHCODETYPES.ValueAfterOpen UNDEFINED setglobal ICAP_SUPPORTEDPATCHCODETYPES.ValueAfterReset UNDEFINED setglobal ICAP_SUPPORTEDPATCHCODETYPES.Flags '' ; setglobal ICAP_SUPPORTEDSIZES.ConType TWON_ENUMERATION,TWON_ONEVALUE setglobal ICAP_SUPPORTEDSIZES.ItemType TWTY_UINT16 setglobal ICAP_SUPPORTEDSIZES.ValueAfterOpen UNDEFINED setglobal ICAP_SUPPORTEDSIZES.ValueAfterReset UNDEFINED setglobal ICAP_SUPPORTEDSIZES.Flags '' ; setglobal ICAP_THRESHOLD.ConType TWON_ENUMERATION,TWON_RANGE,TWON_ONEVALUE setglobal ICAP_THRESHOLD.ItemType TWTY_FIX32 setglobal ICAP_THRESHOLD.ValueAfterOpen UNDEFINED setglobal ICAP_THRESHOLD.ValueAfterReset 128 setglobal ICAP_THRESHOLD.Flags '' ; setglobal ICAP_TILES.ConType TWON_ENUMERATION setglobal ICAP_TILES.ItemType TWTY_BOOL setglobal ICAP_TILES.ValueAfterOpen FALSE setglobal ICAP_TILES.ValueAfterReset FALSE setglobal ICAP_TILES.Flags '' ; setglobal ICAP_TIMEFILL.ConType TWON_RANGE,TWON_ONEVALUE setglobal ICAP_TIMEFILL.ItemType TWTY_UINT16 setglobal ICAP_TIMEFILL.ValueAfterOpen UNDEFINED setglobal ICAP_TIMEFILL.ValueAfterReset 1 setglobal ICAP_TIMEFILL.Flags '' ; setglobal ICAP_UNDEFINEDIMAGESIZE.ConType TWON_ENUMERATION setglobal ICAP_UNDEFINEDIMAGESIZE.ItemType TWTY_BOOL setglobal ICAP_UNDEFINEDIMAGESIZE.ValueAfterOpen FALSE setglobal ICAP_UNDEFINEDIMAGESIZE.ValueAfterReset FALSE setglobal ICAP_UNDEFINEDIMAGESIZE.Flags '' ; setglobal ICAP_UNITS.ConType TWON_ENUMERATION,TWON_ONEVALUE setglobal ICAP_UNITS.ItemType TWTY_UINT16 setglobal ICAP_UNITS.ValueAfterOpen TWUN_INCHES setglobal ICAP_UNITS.ValueAfterReset TWUN_INCHES setglobal ICAP_UNITS.Flags 'mandatory' ; setglobal ICAP_XFERMECH.ConType TWON_ENUMERATION setglobal ICAP_XFERMECH.ItemType TWTY_UINT16 setglobal ICAP_XFERMECH.ValueAfterOpen TWSX_NATIVE setglobal ICAP_XFERMECH.ValueAfterReset TWSX_NATIVE setglobal ICAP_XFERMECH.Flags 'mandatory' ; setglobal ICAP_XNATIVERESOLUTION.ConType TWON_ENUMERATION,TWON_ONEVALUE setglobal ICAP_XNATIVERESOLUTION.ItemType TWTY_FIX32 setglobal ICAP_XNATIVERESOLUTION.ValueAfterOpen UNDEFINED setglobal ICAP_XNATIVERESOLUTION.ValueAfterReset UNDEFINED setglobal ICAP_XNATIVERESOLUTION.Flags 'mandatory' ; setglobal ICAP_XRESOLUTION.ConType TWON_ENUMERATION,TWON_RANGE,TWON_ONEVALUE setglobal ICAP_XRESOLUTION.ItemType TWTY_FIX32 setglobal ICAP_XRESOLUTION.ValueAfterOpen UNDEFINED setglobal ICAP_XRESOLUTION.ValueAfterReset UNDEFINED setglobal ICAP_XRESOLUTION.Flags 'mandatory' ; setglobal ICAP_XSCALING.ConType TWON_ENUMERATION,TWON_RANGE,TWON_ONEVALUE setglobal ICAP_XSCALING.ItemType TWTY_FIX32 setglobal ICAP_XSCALING.ValueAfterOpen UNDEFINED setglobal ICAP_XSCALING.ValueAfterReset 1 setglobal ICAP_XSCALING.Flags '' ; setglobal ICAP_YNATIVERESOLUTION.ConType TWON_ENUMERATION,TWON_ONEVALUE setglobal ICAP_YNATIVERESOLUTION.ItemType TWTY_FIX32 setglobal ICAP_YNATIVERESOLUTION.ValueAfterOpen UNDEFINED setglobal ICAP_YNATIVERESOLUTION.ValueAfterReset UNDEFINED setglobal ICAP_YNATIVERESOLUTION.Flags 'mandatory' ; setglobal ICAP_YRESOLUTION.ConType TWON_ENUMERATION,TWON_RANGE,TWON_ONEVALUE setglobal ICAP_YRESOLUTION.ItemType TWTY_FIX32 setglobal ICAP_YRESOLUTION.ValueAfterOpen UNDEFINED setglobal ICAP_YRESOLUTION.ValueAfterReset UNDEFINED setglobal ICAP_YRESOLUTION.Flags 'mandatory' ; setglobal ICAP_YSCALING.ConType TWON_ENUMERATION,TWON_RANGE,TWON_ONEVALUE setglobal ICAP_YSCALING.ItemType TWTY_FIX32 setglobal ICAP_YSCALING.ValueAfterOpen UNDEFINED setglobal ICAP_YSCALING.ValueAfterReset 1 setglobal ICAP_YSCALING.Flags '' ; setglobal ICAP_ZOOMFACTOR.ConType TWON_ENUMERATION,TWON_RANGE,TWON_ONEVALUE setglobal ICAP_ZOOMFACTOR.ItemType TWTY_INT16 setglobal ICAP_ZOOMFACTOR.ValueAfterOpen UNDEFINED setglobal ICAP_ZOOMFACTOR.ValueAfterReset 0 setglobal ICAP_ZOOMFACTOR.Flags '' ; setrecord off ; return ================================================ FILE: twaincs/source/twaincscert/source/data/scripts/__README.md ================================================ These are convenience scripts that can be used for interactively exploring data sources. Files delivered by the tool may overwrite any changes made by the user. So be careful. Keep a backup copy of new or updated scripts someplace safe. ================================================ FILE: twaincs/source/twaincscert/source/data/scripts/cap_supportedcaps.tc ================================================ ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; CAP_SUPPORTEDCAPS v1.0 14-Jan-2020 ; returns: pass or fail ; ; Test CAP_SUPPORTEDCAPS... ; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Get ; dsmentry src ds dg_control dat_capability msg_get cap_supportedcaps if '${sts:}' != 'SUCCESS' goto MAIN.FAIL echo '${ret:}' ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Bye-bye... ; return pass ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Bye-bye... ; :MAIN.FAIL echo 'Fail...${sts:}' return fail ================================================ FILE: twaincs/source/twaincscert/source/data/scripts/capget.tc ================================================ ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Capget v1.0 14-Jan-2020 ; ${arg:1} - capability to msg_get ; ${arg:2} - (optional) override for msg_get ; returns: pass or fail ; ; Do a MSG_GET on a capability... ; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Figure out which msg to use... ; setlocal capget.msg 'msg_get' if '${arg:2}' == '' goto MAIN.GET setlocal capget.msg '${arg:2}' ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Get ; :MAIN.GET dsmentry src ds dg_control dat_capability '${get:capget.msg}' '${arg:1}' if '${sts:}' != 'SUCCESS' goto MAIN.FAIL echo '${ret:}' ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Bye-bye... ; return pass ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Bye-bye... ; :MAIN.FAIL echo 'Fail...${sts:}' return fail ================================================ FILE: twaincs/source/twaincscert/source/data/scripts/close.tc ================================================ ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Close v1.0 31-Jan-2020 ; returns: (none) ; ; Close and unload the DSM... ; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Rewind the driver, close and unload the DSM... ; if '${state:}' < '7' goto REWIND.6 dsmentry src ds dg_control dat_pendingxfers msg_endxfer '0,0' ; :REWIND.6 if '${state:}' < '6' goto REWIND.5 dsmentry src ds dg_control dat_pendingxfers msg_reset '0,0' ; :REWIND.5 if '${state:}' < '5' goto REWIND.4 dsmentry src ds dg_control dat_userinterface msg_disableds '0,0' ; :REWIND.4 if '${state:}' < '4' goto REWIND.3 dsmentry src null dg_control dat_identity msg_closeds '${ds:}' ; :REWIND.3 if '${state:}' < '3' goto REWIND.2 dsmentry src null dg_control dat_parent msg_closedsm hwnd ; :REWIND.2 if '${state:}' < '2' goto REWIND.1 dsmunload :REWIND.1 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Bye-bye... ; return ================================================ FILE: twaincs/source/twaincscert/source/data/scripts/copybytes.tc ================================================ ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; CopyBytes ; Test that copybytes is working... ; ; Arguments ; (non) ; ; Globals ; (none) ; ; Locals ; test.bytes - number of bytes in the handle ; test.handle - the allocated handle ; test.src - string we start with ; test.dst - string we end up with ; ; Returns ; pass/fail ; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Allocate two handles, and create a test string... ; setlocal test.bytes 100 allocate handle test.handle ${get:test.bytes} setlocal test.src "this is a bit of text we'll copy in and out of the handle..." ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Copy from the src string into the handle... ; copybytes utf8handle test.src ${get:test.handle} ${get:test.bytes} ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Copy from the handle into the dst string... ; copybytes handleutf8 ${get:test.handle} ${get:test.bytes} test.dst ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Show the result... ; echo 'src=<${get:test.src}>' echo 'dst=<${get:test.dst}>' ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Bye-bye... ; free handle test.handle return pass ================================================ FILE: twaincs/source/twaincscert/source/data/scripts/datget.tc ================================================ ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Datget v1.0 14-Jan-2020 ; ${arg:1} - dg to use ; ${arg:2} - dat to use ; ${arg:3} - (optional) override for msg_get ; returns: pass or fail ; ; Do a MSG_GET on a capability... ; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Usage (gotta have at least two arguments) ; if '${arg:2}' != '' goto MAIN.GETARGS echo 'datget dg dat [msg]' goto MAIN.PASS ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Figure out which msg to use... ; :MAIN.GETARGS setlocal capget.msg 'msg_get' if '${arg:3}' == '' goto MAIN.GET setlocal capget.msg '${arg:3}' ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Get ; :MAIN.GET dsmentry src ds '${arg:1}' '${arg:2}' '${get:capget.msg}' undefined if '${sts:}' != 'SUCCESS' goto MAIN.FAIL echo '${ret:}' ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Bye-bye... ; :MAIN.PASS return pass ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Bye-bye... ; :MAIN.FAIL echo 'Fail...${sts:}' return fail ================================================ FILE: twaincs/source/twaincscert/source/data/scripts/extimageinfo.tc ================================================ ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Extimageinfo ; Get the TW_EXTIMAGEINFO for this image, must be called in state 7 ; ; Arguments ; arg:1 - global variable to put the return data into ; arg:2 - CSV list of TWEI_* values to get ; ; Globals ; (none) ; ; Locals ; twextimageinfo - numinfos and array of structures ; twextimageinfo.numinfos - counter ; twextimageinfo.twinfo - array of tw_info structures ; comma - CSV seperator ; tweilist - CSV list of TWEI_* values to get ; ; Returns ; pass or fail ; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Init stuff... ; setlocal twextimageinfo '0' setlocal twextimageinfo.numinfos '0' setlocal twextimageinfo.twinfo '' setlocal comma '' setlocal tweilist '${arg:2}' ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Walk the TWE_* values... ; if '${arg:${get:twextimageinfo.numinfos}}' == '' goto MAIN.DATEXTIMAGEINGO :MAIN.NEXTTWINFO setlocal twei '${getindex:tweilist:${get:twextimageinfo.numinfos}}' ; next item if '${get:twei}' == '' goto MAIN.SETTWEXTIMAGEINFO ; we've exhausted the list setlocal twextimageinfo.twinfo '${get:twextimageinfo.twinfo}${get:comma}${get:twei},0,0,0,0' ; build the data increment twextimageinfo.numinfos '${get:twextimageinfo.numinfos}' '1' ; increment for the next item setlocal comma ',' ; turn on comma goto MAIN.NEXTTWINFO ; next twei :MAIN.SETTWEXTIMAGEINFO setlocal twextimageinfo '${get:twextimageinfo.numinfos},${get:twextimageinfo.twinfo}' ; build the final data ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Send the command... ; :MAIN.DATEXTIMAGEINGO dsmentry src ds dg_image dat_extimageinfo msg_get '${get:twextimageinfo}' echo.progress 'extimageinfo/get' '${sts:} - ${ret:}' if '${sts:}' != 'SUCCESS' goto MAIN.FAIL ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; We've passed... ; :MAIN.PASS setglobal '${arg:1}' '${ret:}' return 'pass' ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; We've run into a problem... ; :MAIN.FAIL echo.progress 'ERROR' '${sts:}' return 'fail' ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; We're run into a problem... ; :MAIN.FAIL return 'fail' ================================================ FILE: twaincs/source/twaincscert/source/data/scripts/list.tc ================================================ ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Opends ; List all of the TWAIN drivers on the system for the current machine word, ; returning just the ProductName's... ; ; Arguments ; arg:1 - if set to full, the entire TW_IDENTITY is displayed ; ; Globals ; (none) ; ; Locals ; TW_IDENTITY.ProductName - index of the product name ; ; Returns ; pass or fail ; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; List v1.0 06-Mar-2020 ; returns: pass or fail ; ; List all of the TWAIN drivers on the system, returning just the ProductName's... ; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Init stuff... ; setlocal TW_IDENTITY.ProductName 11 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Load and open the DSM... ; dsmload dsmentry src null dg_control dat_parent msg_opendsm hwnd if '${sts:}' != 'SUCCESS' goto MAIN.FAIL ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Get the first TWAIN driver... ; dsmentry src null dg_control dat_identity msg_getfirst '0,0,0,ENGLISH_USA,USA,,0,0,0x0,,,' if '${sts:}' == 'ENDOFLIST' goto MAIN.CLOSE if '${sts:}' != 'SUCCESS' goto MAIN.FAIL if '${arg:1}' == 'full' goto MAIN.LISTFULL echo '${ret:${get:TW_IDENTITY.ProductName}}' ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Get the next TWAIN driver(s)... ; :MAIN.GETNEXT dsmentry src null dg_control dat_identity msg_getnext '0,0,0,ENGLISH_USA,USA,,0,0,0x0,,,' if '${sts:}' == 'ENDOFLIST' goto MAIN.CLOSE if '${sts:}' != 'SUCCESS' goto MAIN.FAIL if '${arg:1}' == 'full' goto MAIN.LISTFULL echo '${ret:${get:TW_IDENTITY.ProductName}}' goto MAIN.GETNEXT ; :MAIN.LISTFULL echo '${ret:}' goto MAIN.GETNEXT ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Close and unload the DSM... ; :MAIN.CLOSE dsmentry src null dg_control dat_parent msg_closedsm hwnd dsmunload ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Bye-bye... ; echo 'Done...' return pass ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Bye-bye... ; :MAIN.FAIL if '${state:}' < '2' goto MAIN.SKIPCLOSE dsmentry src null dg_control dat_parent msg_closedsm hwnd dsmunload :MAIN.SKIPCLOSE echo 'Done...' return fail ================================================ FILE: twaincs/source/twaincscert/source/data/scripts/open.tc ================================================ ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Open v1.0 14-Jan-2020 ; ${arg:1} - product name of scanner to open ; ${arg:2} - dsmload argument ; ${arg:3} - dsmload argument ; ${arg:4} - dsmload argument ; ${arg:5} - dsmload argument ; ${arg:6} - dsmload argument ; ${arg:7} - dsmload argument ; ${arg:8} - dsmload argument ; ${arg:9} - dsmload argument ; ${arg:10} - dsmload argument ; ${arg:11} - dsmload argument ; ${arg:12} - dsmload argument ; returns: pass or fail ; ; Open the specified driver... ; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Load the tables... ; if '${get:TW_ARRAY.ItemType}' != '' goto MAIN.LOADTABLES.SKIP run 'LoadTables' :MAIN.LOADTABLES.SKIP ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Load and open the DSM... ; dsmload '${arg:2}' '${arg:3}' '${arg:4}' '${arg:5}' '${arg:6}' '${arg:7}' '${arg:8}' '${arg:9}' '${arg:10}' '${arg:11}' '${arg:12}' dsmentry src null dg_control dat_parent msg_opendsm hwnd if '${sts:}' != 'SUCCESS' goto MAIN.FAIL ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; If the DF_APP2|DF_DSM2 flag is set, then call DAT_ENTRYPOINT... ; if '${app:${get:TW_IDENTITY.SupportedGroups}}' & '0x30000000' != '0x30000000' goto MAIN.ENTRYPOINT.SKIP dsmentry src null dg_control dat_entrypoint msg_get '0,0,0,0,0,0' if '${sts:}' != 'SUCCESS' goto MAIN.ERROR :MAIN.ENTRYPOINT.SKIP ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Open the driver... ; dsmentry src null dg_control dat_identity msg_opends '0,0,0,0,0,0,0,0,0x0,,,${arg:1}' if '${sts:}' != 'SUCCESS' goto MAIN.FAIL ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Bye-bye... ; return pass ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Bye-bye... ; :MAIN.FAIL echo 'Fail...${sts:}' return fail ================================================ FILE: twaincs/source/twaincscert/source/data/scripts/scanfile.tc ================================================ ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Scanfile ; Scan with DAT_IMAGEFILEXFER... ; ; Arguments ; arg:1 - TW_IDENTITY.ProductName of scanner to test ; arg:2 - dsmload argument ; arg:3 - dsmload argument ; arg:4 - dsmload argument ; arg:5 - dsmload argument ; arg:6 - dsmload argument ; arg:7 - dsmload argument ; arg:8 - dsmload argument ; arg:9 - dsmload argument ; arg:10 - dsmload argument ; arg:11 - dsmload argument ; arg:12 - dsmload argument ; ; Globals ; g_twextimageinfo - extended image info ; ; Locals ; cap_supportedcaps - list of supported capabilities ; icap_supportedextimageinfo - list of supported extending image info values ; image.count - count of images, starting at 1 ; image.folder - location of the images ; twainstate - pass/fail result of all tests ; ; Returns ; pass or fail ; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Init stuff... ; run 'LoadTables' setlocal cap_supportedcaps '' setlocal icap_supportedextimageinfo '' setlocal image.count '0' setlocal twainstate '0' setlocal image.folder '${folder:data}/images' setglobal g_twextimageinfo '' image cleanfolder '${get:image.folder}' ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Load and open the DSM... ; setlocal twainstate '1' dsmload '${arg:2}' '${arg:3}' '${arg:4}' '${arg:5}' '${arg:6}' '${arg:7}' '${arg:8}' '${arg:9}' '${arg:10}' '${arg:11}' '${arg:12}' echo.progress 'dsmload ${arg:2} ${arg:3} ${arg:4} ${arg:5} ${arg:6} ${arg:7} ${arg:8} ${arg:9} ${arg:10} ${arg:11} ${arg:12}' '${sts:}' setlocal twainstate '2' dsmentry src null dg_control dat_parent msg_opendsm hwnd echo.progress 'parent/opendsm' '${sts:}' if '${sts:}' != 'SUCCESS' goto MAIN.FAIL setlocal twainstate '3' ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; If the DF_APP2|DF_DSM2 flag is set, then call DAT_ENTRYPOINT... ; if '${app:${get:TW_IDENTITY.SupportedGroups}}' & '0x30000000' != '0x30000000' goto MAIN.ENTRYPOINT.SKIP dsmentry src null dg_control dat_entrypoint msg_get '0,0,0,0,0,0' echo.progress 'entrypoint/get' '${sts:} - ${ret:}' if '${sts:}' != 'SUCCESS' goto MAIN.ERROR :MAIN.ENTRYPOINT.SKIP ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Open the driver... ; dsmentry src null dg_control dat_identity msg_opends '0,0,0,0,0,,0,0,0x0,,,${arg:1}' setlocal twidentity '${ret:}' echo.progress 'identity/opends' '${sts:} - ${get:twidentity}' if '${sts:}' != 'SUCCESS' goto MAIN.FAIL setlocal twainstate '4' ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Get CAP_SUPPORTEDCAPS... ; dsmentry src ds dg_control dat_capability msg_get 'CAP_SUPPORTEDCAPS' echo.progress 'capability/get' '${sts:} - ${ret:}' if '${sts:}' != 'SUCCESS' goto MAIN.FAIL setlocal cap_supportedcaps '${ret:}' ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Set CAP_INDICATORS to TRUE... ; dsmentry src ds dg_control dat_capability msg_set 'CAP_INDICATORS,TWON_ONEVALUE,TWTY_BOOL,TRUE' echo.progress 'capability/set' '${sts:} - ${ret:}' if '${sts:}' != 'SUCCESS' goto MAIN.FAIL ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Set ICAP_XFERMECH to TWSX_FILE... ; dsmentry src ds dg_control dat_capability msg_set 'ICAP_XFERMECH,TWON_ONEVALUE,TWTY_UINT16,TWSX_FILE' echo.progress 'capability/set' '${sts:} - ${ret:}' if '${sts:}' != 'SUCCESS' goto MAIN.FAIL ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Get ICAP_SUPPORTEDEXTIMAGEINFO (we just want the array portion)... ; if '${get:cap_supportedcaps}' !~contains 'ICAP_SUPPORTEDEXTIMAGEINFO' goto MAIN.SKIPICAPSUPPORTEDEXTIMAGEINFO dsmentry src ds dg_control dat_capability msg_get 'ICAP_SUPPORTEDEXTIMAGEINFO' echo.progress 'capability/get' '${sts:} - ${ret:}' if '${sts:}' != 'SUCCESS' goto MAIN.FAIL setlocal ienum '4' setlocal comma '' :MAIN.NEXTEXTIMAGEINFO if '${ret:${get:ienum}}' == '' goto MAIN.SKIPICAPSUPPORTEDEXTIMAGEINFO setlocal icap_supportedextimageinfo '${get:icap_supportedextimageinfo}${get:comma}${ret:${get:ienum}}' increment ienum '${get:ienum}' 1 setlocal comma ',' goto MAIN.NEXTEXTIMAGEINFO :MAIN.SKIPICAPSUPPORTEDEXTIMAGEINFO ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Start scanning... ; wait reset dsmentry src ds dg_control dat_userinterface msg_enableds '0,0' echo.progress 'userinterface/enableds' '${sts:} - ${ret:}' if '${sts:}' != 'SUCCESS' goto MAIN.FAIL setlocal twainstate '5' ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Wait for MSG_XFERREADY, if we don't see it then scoot... ; wait 30000 echo.progress 'wait' '${ret:}' if '${ret:}' !~contains 'msg_xferready' goto MAIN.PASS ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Get information about the image... ; :MAIN.NEXTIMAGEINFO setlocal twainstate '6' dsmentry src ds dg_image dat_imageinfo msg_get '0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0' echo.progress 'imageinfo/get' '${sts:} - ${ret:}' if '${sts:}' != 'SUCCESS' goto MAIN.FAIL setlocal twimageinfo.compression '${ret:${get:index.twimageinfo.compression}}' ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Set up the file transfer... ; increment image.count '${get:image.count}' 1 if '${get:twimageinfo.compression}' == 'JPEG' goto MAIN.JPEG setlocal twsetupfilexfer.filename '${get:image.folder}/img${format:D6|${get:image.count}}.tif' setlocal twsetupfilexfer.format 'TWFF_TIFF' goto MAIN.SETUPFILEXFER :MAIN.JPEG setlocal twsetupfilexfer.filename '${get:image.folder}/img${format:D6|${get:image.count}}.jpg' setlocal twsetupfilexfer.format 'TWFF_JFIF' :MAIN.SETUPFILEXFER dsmentry src ds dg_control dat_setupfilexfer msg_set '"${get:twsetupfilexfer.filename}",${get:twsetupfilexfer.format},0' echo.progress 'setupfilexfer/get' '${sts:} - ${ret:}' if '${sts:}' != 'SUCCESS' goto MAIN.FAIL ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Transfer the image... ; dsmentry src ds dg_image dat_imagefilexfer msg_get null echo.progress 'imagefilexfer/get' '${sts:}' if '${sts:}' != 'XFERDONE' goto MAIN.FAIL setlocal twainstate '7' ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Get more info about the image (if we can)... ; if '${get:icap_supportedextimageinfo}' == '' goto MAIN.SKIPEXTIMAGEINFO run 'extimageinfo' 'g_twextimageinfo' '${get:icap_supportedextimageinfo}' if '${ret:}' != 'pass' goto MAIN.FAIL :MAIN.SKIPEXTIMAGEINFO ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; End the transfer, see if we're done... ; dsmentry src ds dg_control dat_pendingxfers msg_endxfer '0,0' echo.progress 'pendingxfers/endxfer' '${sts:} - ${ret:}' if '${sts:}' != 'SUCCESS' goto MAIN.FAIL if '${ret:${get:TW_PENDINGXFERS.Count}}' != '0' goto MAIN.NEXTIMAGEINFO setlocal twainstate '5' ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; We've passed... ; :MAIN.PASS setlocal main.result pass goto MAIN.EXIT ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; We've run into a problem... ; :MAIN.FAIL echo.progress 'ERROR' '${sts:}' setlocal main.result fail goto MAIN.EXIT ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Rewind the driver, close and unload the DSM, return... ; :MAIN.EXIT call TWAIN.REWIND '${get:twainstate}' '${get:twidentity}' return '${get:main.result}' ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Function: Rewind from any TWAIN state... ; arg:1 - twainstate ; arg:2 - twidentity ; returns: (nothing) ; :TWAIN.REWIND ; setlocal twainstate '${arg:1}' if '${get:twainstate}' < '7' goto REWIND.6 dsmentry src ds dg_control dat_pendingxfers msg_endxfer '0,0' echo.progress 'pendingxfers/endxfer' '${sts:}' setlocal twainstate '6' :REWIND.6 if '${get:twainstate}' < '6' goto REWIND.5 dsmentry src ds dg_control dat_pendingxfers msg_reset '0,0' echo.progress 'pendingxfers/reset' '${sts:}' setlocal twainstate '5' :REWIND.5 if '${get:twainstate}' < '5' goto REWIND.4 dsmentry src ds dg_control dat_userinterface msg_disableds '0,0' echo.progress 'userinterface/disableds' '${sts:}' setlocal twainstate '4' :REWIND.4 if '${get:twainstate}' < '4' goto REWIND.3 dsmentry src null dg_control dat_identity msg_closeds '${arg:2}' echo.progress 'identity/closeds' '${sts:}' setlocal twainstate '3' :REWIND.3 if '${get:twainstate}' < '3' goto REWIND.2 dsmentry src null dg_control dat_parent msg_closedsm hwnd echo.progress 'parent/closedsm' '${sts:}' setlocal twainstate '2' :REWIND.2 if '${get:twainstate}' < '2' goto REWIND.1 dsmunload echo 'dsmunload' setlocal twainstate '1' :REWIND.1 return ${get:twainstate}' ================================================ FILE: twaincs/source/twaincscert/source/data/scripts/scanmemfile.tc ================================================ ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Scanfile ; Scan with DAT_IMAGEMEMFILEXFER... ; ; Arguments ; arg:1 - TW_IDENTITY.ProductName of scanner to test ; arg:2 - dsmload argument ; arg:3 - dsmload argument ; arg:4 - dsmload argument ; arg:5 - dsmload argument ; arg:6 - dsmload argument ; arg:7 - dsmload argument ; arg:8 - dsmload argument ; arg:9 - dsmload argument ; arg:10 - dsmload argument ; arg:11 - dsmload argument ; arg:12 - dsmload argument ; ; Globals ; (none) ; ; Locals ; image.pointer - pointer to memory allocated for transfers ; image.count - count of images, starting at 1 ; image.folder - location of the images ; twidentity - the scanner we opened ; twainstate - pass/fail result of all tests ; ; Returns ; pass or fail ; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Init stuff... ; run 'LoadTables' setlocal image.pointer '0' setlocal image.count '0' setlocal image.folder '${folder:data}/images' setlocal twidentity '' setlocal twainstate '0' image cleanfolder '${get:image.folder}' ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Load and open the DSM... ; setlocal twainstate '1' dsmload '${arg:2}' '${arg:3}' '${arg:4}' '${arg:5}' '${arg:6}' '${arg:7}' '${arg:8}' '${arg:9}' '${arg:10}' '${arg:11}' '${arg:12}' echo.progress 'dsmload ${arg:2} ${arg:3} ${arg:4} ${arg:5} ${arg:6} ${arg:7} ${arg:8} ${arg:9} ${arg:10} ${arg:11} ${arg:12}' '${sts:}' setlocal twainstate '2' dsmentry src null dg_control dat_parent msg_opendsm hwnd echo.progress 'parent/opendsm' '${sts:}' if '${sts:}' != 'SUCCESS' goto MAIN.FAIL setlocal twainstate '3' ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; If the DF_APP2|DF_DSM2 flag is set, then call DAT_ENTRYPOINT... ; if '${app:${get:TW_IDENTITY.SupportedGroups}}' & '0x30000000' != '0x30000000' goto MAIN.ENTRYPOINT.SKIP dsmentry src null dg_control dat_entrypoint msg_get '0,0,0,0,0,0' echo.progress 'entrypoint/get' '${sts:} - ${ret:}' if '${sts:}' != 'SUCCESS' goto MAIN.ERROR :MAIN.ENTRYPOINT.SKIP ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Open the driver... ; dsmentry src null dg_control dat_identity msg_opends '0,0,0,0,0,,0,0,0x0,,,${arg:1}' setlocal twidentity '${ret:}' echo.progress 'identity/opends' '${sts:} - ${get:twidentity}' if '${sts:}' != 'SUCCESS' goto MAIN.FAIL setlocal twainstate '4' ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Set CAP_INDICATORS to TRUE... ; dsmentry src ds dg_control dat_capability msg_set 'CAP_INDICATORS,TWON_ONEVALUE,TWTY_BOOL,TRUE' echo.progress 'capability/set' '${sts:} - ${ret:}' if '${sts:}' != 'SUCCESS' goto MAIN.FAIL ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Set ICAP_XFERMECH to TWSX_MEMFILE... ; dsmentry src ds dg_control dat_capability msg_set 'ICAP_XFERMECH,TWON_ONEVALUE,TWTY_UINT16,TWSX_MEMFILE' echo.progress 'capability/set' '${sts:} - ${ret:}' if '${sts:}' != 'SUCCESS' goto MAIN.FAIL ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Set ICAP_PIXELTYPE to TWPT_RGB, if we can... ; dsmentry src ds dg_control dat_capability msg_get 'ICAP_PIXELTYPE,0,0,0' echo.progress 'capability/get' '${sts:} - ${ret:}' if '${sts:}' != 'SUCCESS' goto MAIN.FAIL if '${ret:}' !~contains 'TWPT_RGB' goto MAIN.PIXELTYPE.SKIP dsmentry src ds dg_control dat_capability msg_set 'ICAP_PIXELTYPE,TWON_ONEVALUE,TWTY_UINT16,TWPT_RGB' echo.progress 'capability/set' '${sts:} - ${ret:}' if '${sts:}' != 'SUCCESS' goto MAIN.FAIL :MAIN.PIXELTYPE.SKIP ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Set ICAP_COMPRESSION to TWCP_JPEG ; dsmentry src ds dg_control dat_capability msg_set 'ICAP_COMPRESSION,TWON_ONEVALUE,TWTY_UINT16,TWCP_JPEG' echo.progress 'capability/set' '${sts:} - ${ret:}' if '${sts:}' != 'SUCCESS' goto MAIN.FAIL ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Get the preferred size for memory transfers, and allocate ; a pointer for the memory transfers... ; dsmentry src ds dg_control dat_setupmemxfer msg_get '0,0,0' echo.progress 'setupmemxfer/get' '${sts:} - ${ret:}' if '${sts:}' != 'SUCCESS' goto MAIN.FAIL setlocal twsetupmemxfer.preferred '${ret:${get:TW_SETUPMEMXFER.Preferred}}' if '${get:twsetupmemxfer.preferred}' <= '0' goto MAIN.FAIL allocate pointer image.pointer '${get:twsetupmemxfer.preferred}' echo.progress 'allocate pointer' '${get:image.pointer} size=${get:twsetupmemxfer.preferred}' if '${get:image.pointer}' == '0' goto MAIN.FAIL ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Set DAT_SETUPFILEXFER to TWFF_TIFF ; dsmentry src null dg_control dat_setupfilexfer msg_set 'file,TWFF_TIFF,0' echo.progress 'capability/set' '${sts:} - ${ret:}' if '${sts:}' != 'SUCCESS' goto MAIN.FAIL ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Start scanning... ; wait reset dsmentry src ds dg_control dat_userinterface msg_enableds '0,0' echo.progress 'userinterface/enableds' '${sts:} - ${ret:}' if '${sts:}' != 'SUCCESS' goto MAIN.FAIL setlocal twainstate '5' ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Wait for MSG_XFERREADY, if we don't see it then scoot... ; wait 30000 echo.progress 'wait' '${ret:}' if '${ret:}' !~contains 'msg_xferready' goto MAIN.PASS ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Do a memory file transfer... ; This little song and dance with the states is so that we can ; start the transfer in state 6 with each new image, but switch ; to state 7 if we need multiple calls to capture the current ; image... ; ; The saved images will be in TIFF format, which includes TIFF ; JPEG (the better form, where a simple TIFF header is added). ; :MAIN.NEXTIMAGEMEMFILEXFER.STATE6 setlocal twainstate '6' increment image.count '${get:image.count}' 1 image free memfileimage goto MAIN.NEXTIMAGEMEMFILEXFER :MAIN.NEXTIMAGEMEMFILEXFER.STATE7 setlocal twainstate '7' ; :MAIN.NEXTIMAGEMEMFILEXFER dsmentry src ds dg_image dat_imagememfilexfer msg_get '0,0,0,0,0,0,0,9,${get:twsetupmemxfer.preferred},${get:image.pointer}' echo.progress 'imagememxfer/get' '${sts:} - ${ret:}' if '${sts:}' == 'XFERDONE' goto MAIN.NEXTIMAGEMEMFILEXFER.XFERDONE if '${sts:}' != 'SUCCESS' goto MAIN.FAIL image append memfileimage '${ret:}' goto MAIN.NEXTIMAGEMEMFILEXFER.STATE7 :MAIN.NEXTIMAGEMEMFILEXFER.XFERDONE image append memfileimage '${ret:}' image save memfileimage memfile '${get:image.folder}/img${format:D6|${get:image.count}}' setlocal twainstate '7' ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; End the transfer, see if we're done... ; dsmentry src ds dg_control dat_pendingxfers msg_endxfer '0,0' echo.progress 'pendingxfers/endxfer' '${sts:} - ${ret:}' if '${sts:}' != 'SUCCESS' goto MAIN.FAIL if '${ret:${get:TW_PENDINGXFERS.Count}}' != '0' goto MAIN.NEXTIMAGEMEMFILEXFER.STATE6 image free memfileimage setlocal twainstate '5' ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; We've passed... ; :MAIN.PASS setlocal main.result pass goto MAIN.EXIT ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; We've run into a problem... ; :MAIN.FAIL echo.progress 'ERROR' '${sts:}' image free memfileimage setlocal main.result fail goto MAIN.EXIT ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Rewind the driver, close and unload the DSM, return... ; :MAIN.EXIT free pointer image.pointer call TWAIN.REWIND '${get:twainstate}' '${get:twidentity}' return '${get:main.result}' ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Function: Rewind from any TWAIN state... ; arg:1 - twainstate ; arg:2 - twidentity ; returns: (nothing) ; :TWAIN.REWIND ; setlocal twainstate '${arg:1}' if '${get:twainstate}' < '7' goto REWIND.6 dsmentry src ds dg_control dat_pendingxfers msg_endxfer '0,0' echo.progress 'pendingxfers/endxfer' '${sts:}' setlocal twainstate '6' :REWIND.6 if '${get:twainstate}' < '6' goto REWIND.5 dsmentry src ds dg_control dat_pendingxfers msg_reset '0,0' echo.progress 'pendingxfers/reset' '${sts:}' setlocal twainstate '5' :REWIND.5 if '${get:twainstate}' < '5' goto REWIND.4 dsmentry src ds dg_control dat_userinterface msg_disableds '0,0' echo.progress 'userinterface/disableds' '${sts:}' setlocal twainstate '4' :REWIND.4 if '${get:twainstate}' < '4' goto REWIND.3 dsmentry src null dg_control dat_identity msg_closeds '${arg:2}' echo.progress 'identity/closeds' '${sts:}' setlocal twainstate '3' :REWIND.3 if '${get:twainstate}' < '3' goto REWIND.2 dsmentry src null dg_control dat_parent msg_closedsm hwnd echo.progress 'parent/closedsm' '${sts:}' setlocal twainstate '2' :REWIND.2 if '${get:twainstate}' < '2' goto REWIND.1 dsmunload echo 'dsmunload' setlocal twainstate '1' :REWIND.1 return ${get:twainstate}' ================================================ FILE: twaincs/source/twaincscert/source/data/scripts/scanmemory.tc ================================================ ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Scanfile ; Scan with DAT_IMAGEMEMXFER... ; ; Arguments ; arg:1 - TW_IDENTITY.ProductName of scanner to test ; arg:2 - dsmload argument ; arg:3 - dsmload argument ; arg:4 - dsmload argument ; arg:5 - dsmload argument ; arg:6 - dsmload argument ; arg:7 - dsmload argument ; arg:8 - dsmload argument ; arg:9 - dsmload argument ; arg:10 - dsmload argument ; arg:11 - dsmload argument ; arg:12 - dsmload argument ; ; Globals ; (none) ; ; Locals ; image.pointer - pointer to memory allocated for transfers ; image.count - count of images, starting at 1 ; image.folder - location of the images ; twainstate - pass/fail result of all tests ; ; Returns ; pass or fail ; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Init stuff... ; run 'LoadTables' setlocal image.pointer '0' setlocal image.count '0' setlocal image.folder '${folder:data}/images' setlocal twainstate '0' image cleanfolder '${get:image.folder}' ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Load and open the DSM... ; setlocal twainstate '1' dsmload '${arg:2}' '${arg:3}' '${arg:4}' '${arg:5}' '${arg:6}' '${arg:7}' '${arg:8}' '${arg:9}' '${arg:10}' '${arg:11}' '${arg:12}' echo.progress 'dsmload ${arg:2} ${arg:3} ${arg:4} ${arg:5} ${arg:6} ${arg:7} ${arg:8} ${arg:9} ${arg:10} ${arg:11} ${arg:12}' '${sts:}' setlocal twainstate '2' dsmentry src null dg_control dat_parent msg_opendsm hwnd echo.progress 'parent/opendsm' '${sts:}' if '${sts:}' != 'SUCCESS' goto MAIN.FAIL setlocal twainstate '3' ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; If the DF_APP2|DF_DSM2 flag is set, then call DAT_ENTRYPOINT... ; if '${app:${get:TW_IDENTITY.SupportedGroups}}' & '0x30000000' != '0x30000000' goto MAIN.ENTRYPOINT.SKIP dsmentry src null dg_control dat_entrypoint msg_get '0,0,0,0,0,0' echo.progress 'entrypoint/get' '${sts:} - ${ret:}' if '${sts:}' != 'SUCCESS' goto MAIN.ERROR :MAIN.ENTRYPOINT.SKIP ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Open the driver... ; dsmentry src null dg_control dat_identity msg_opends '0,0,0,0,0,,0,0,0x0,,,${arg:1}' setlocal twidentity '${ret:}' echo.progress 'identity/opends' '${sts:} - ${get:twidentity}' if '${sts:}' != 'SUCCESS' goto MAIN.FAIL setlocal twainstate '4' ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Set CAP_INDICATORS to TRUE... ; dsmentry src ds dg_control dat_capability msg_set 'CAP_INDICATORS,TWON_ONEVALUE,TWTY_BOOL,TRUE' echo.progress 'capability/set' '${sts:} - ${ret:}' if '${sts:}' != 'SUCCESS' goto MAIN.FAIL ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Set ICAP_XFERMECH to TWSX_MEMORY... ; dsmentry src ds dg_control dat_capability msg_set 'ICAP_XFERMECH,TWON_ONEVALUE,TWTY_UINT16,TWSX_MEMORY' echo.progress 'capability/set' '${sts:} - ${ret:}' if '${sts:}' != 'SUCCESS' goto MAIN.FAIL ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Set ICAP_PIXELTYPE to TWPT_RGB (if we can) ; dsmentry src ds dg_control dat_capability msg_get 'ICAP_PIXELTYPE,0,0,0' echo.progress 'capability/get' '${sts:} - ${ret:}' if '${sts:}' != 'SUCCESS' goto MAIN.FAIL if '${ret:}' !~contains 'TWPT_RGB' goto MAIN.PIXELTYPE.SKIP dsmentry src ds dg_control dat_capability msg_set 'ICAP_PIXELTYPE,TWON_ONEVALUE,TWTY_UINT16,TWPT_RGB' echo.progress 'capability/set' '${sts:} - ${ret:}' if '${sts:}' != 'SUCCESS' goto MAIN.FAIL :MAIN.PIXELTYPE.SKIP ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Set ICAP_COMPRESSION to TWCP_JPEG ; dsmentry src ds dg_control dat_capability msg_set 'ICAP_COMPRESSION,TWON_ONEVALUE,TWTY_UINT16,TWCP_NONE' echo.progress 'capability/set' '${sts:} - ${ret:}' if '${sts:}' != 'SUCCESS' goto MAIN.FAIL ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Get the preferred size for memory transfers, and allocate ; a pointer for the memory transfers... ; dsmentry src ds dg_control dat_setupmemxfer msg_get '0,0,0' echo.progress 'setupmemxfer/get' '${sts:} - ${ret:}' if '${sts:}' != 'SUCCESS' goto MAIN.FAIL setlocal twsetupmemxfer.preferred '${ret:${get:TW_SETUPMEMXFER.Preferred}}' if '${get:twsetupmemxfer.preferred}' <= '0' goto MAIN.FAIL allocate pointer image.pointer '${get:twsetupmemxfer.preferred}' echo.progress 'allocate pointer' '${get:image.pointer} size=${get:twsetupmemxfer.preferred}' if '${get:image.pointer}' == '0' goto MAIN.FAIL ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Start scanning... ; wait reset dsmentry src ds dg_control dat_userinterface msg_enableds '0,0' echo.progress 'userinterface/enableds' '${sts:} - ${ret:}' if '${sts:}' != 'SUCCESS' goto MAIN.FAIL setlocal twainstate '5' ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Wait for MSG_XFERREADY, if we don't see it then scoot... ; wait 30000 echo.progress 'wait' '${ret:}' if '${ret:}' !~contains 'msg_xferready' goto MAIN.PASS ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Do a memory transfer... ; This little song and dance with the states is so that we can ; start the transfer in state 6 with each new image, but switch ; to state 7 if we need multiple calls to capture the current ; image... ; :MAIN.NEXTIMAGEMEMXFER.STATE6 setlocal twainstate '6' increment image.count '${get:image.count}' 1 image free memimage goto MAIN.NEXTIMAGEMEMXFER :MAIN.NEXTIMAGEMEMXFER.STATE7 setlocal twainstate '7' ; :MAIN.NEXTIMAGEMEMXFER dsmentry src ds dg_image dat_imagememxfer msg_get '0,0,0,0,0,0,0,9,${get:twsetupmemxfer.preferred},${get:image.pointer}' echo.progress 'imagememxfer/get' '${sts:} - ${ret:}' if '${sts:}' == 'XFERDONE' goto MAIN.NEXTIMAGEMEMXFER.XFERDONE if '${sts:}' != 'SUCCESS' goto MAIN.FAIL image append memimage '${ret:}' goto MAIN.NEXTIMAGEMEMXFER.STATE7 :MAIN.NEXTIMAGEMEMXFER.XFERDONE image append memimage '${ret:}' setlocal twainstate '7' ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; We need image info to make sense of this data... ; dsmentry src ds dg_image dat_imageinfo msg_get '0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0' echo.progress 'imagememxfer/get' '${sts:} - ${ret:}' if '${sts:}' != 'SUCCESS' goto MAIN.FAIL image addheader memimage '${ret:}' image save memimage memory '${get:image.folder}/img${format:D6|${get:image.count}}' ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; End the transfer, see if we're done... ; dsmentry src ds dg_control dat_pendingxfers msg_endxfer '0,0' echo.progress 'pendingxfers/endxfer' '${sts:} - ${ret:}' if '${sts:}' != 'SUCCESS' goto MAIN.FAIL if '${ret:${get:TW_PENDINGXFERS.Count}}' != '0' goto MAIN.NEXTIMAGEMEMXFER.STATE6 image free memimage setlocal twainstate '5' ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; We've passed... ; :MAIN.PASS setlocal main.result pass goto MAIN.EXIT ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; We've run into a problem... ; :MAIN.FAIL echo.progress 'ERROR' '${sts:}' image free memimage setlocal main.result fail goto MAIN.EXIT ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Rewind the driver, close and unload the DSM, return... ; :MAIN.EXIT free pointer image.pointer call TWAIN.REWIND '${get:twainstate}' '${get:twidentity}' return '${get:main.result}' ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Function: Rewind from any TWAIN state... ; arg:1 - twainstate ; arg:2 - twidentity ; returns: (nothing) ; :TWAIN.REWIND ; setlocal twainstate '${arg:1}' if '${get:twainstate}' < '7' goto REWIND.6 dsmentry src ds dg_control dat_pendingxfers msg_endxfer '0,0' echo.progress 'pendingxfers/endxfer' '${sts:}' setlocal twainstate '6' :REWIND.6 if '${get:twainstate}' < '6' goto REWIND.5 dsmentry src ds dg_control dat_pendingxfers msg_reset '0,0' echo.progress 'pendingxfers/reset' '${sts:}' setlocal twainstate '5' :REWIND.5 if '${get:twainstate}' < '5' goto REWIND.4 dsmentry src ds dg_control dat_userinterface msg_disableds '0,0' echo.progress 'userinterface/disableds' '${sts:}' setlocal twainstate '4' :REWIND.4 if '${get:twainstate}' < '4' goto REWIND.3 dsmentry src null dg_control dat_identity msg_closeds '${arg:2}' echo.progress 'identity/closeds' '${sts:}' setlocal twainstate '3' :REWIND.3 if '${get:twainstate}' < '3' goto REWIND.2 dsmentry src null dg_control dat_parent msg_closedsm hwnd echo.progress 'parent/closedsm' '${sts:}' setlocal twainstate '2' :REWIND.2 if '${get:twainstate}' < '2' goto REWIND.1 dsmunload echo 'dsmunload' setlocal twainstate '1' :REWIND.1 return ${get:twainstate}' ================================================ FILE: twaincs/source/twaincscert/source/data/scripts/scannative.tc ================================================ ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Scanfile ; Scan with DAT_IMAGENATIVEXFER... ; ; Arguments ; arg:1 - TW_IDENTITY.ProductName of scanner to test ; arg:2 - dsmload argument ; arg:3 - dsmload argument ; arg:4 - dsmload argument ; arg:5 - dsmload argument ; arg:6 - dsmload argument ; arg:7 - dsmload argument ; arg:8 - dsmload argument ; arg:9 - dsmload argument ; arg:10 - dsmload argument ; arg:11 - dsmload argument ; arg:12 - dsmload argument ; ; Globals ; (none) ; ; Locals ; image.handle - handle to native transfer ; image.count - count of images, starting at 1 ; image.folder - location of the images ; twainstate - pass/fail result of all tests ; ; Returns ; pass or fail ; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Init stuff... ; run 'LoadTables' setlocal image.handle '0' setlocal image.count '0' setlocal image.folder '${folder:data}/images' setlocal twainstate '0' image cleanfolder '${get:image.folder}' ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Load and open the DSM... ; setlocal twainstate '1' dsmload '${arg:2}' '${arg:3}' '${arg:4}' '${arg:5}' '${arg:6}' '${arg:7}' '${arg:8}' '${arg:9}' '${arg:10}' '${arg:11}' '${arg:12}' echo.progress 'dsmload ${arg:2} ${arg:3} ${arg:4} ${arg:5} ${arg:6} ${arg:7} ${arg:8} ${arg:9} ${arg:10} ${arg:11} ${arg:12}' '${sts:}' setlocal twainstate '2' dsmentry src null dg_control dat_parent msg_opendsm hwnd echo.progress 'parent/opendsm' '${sts:}' if '${sts:}' != 'SUCCESS' goto MAIN.FAIL setlocal twainstate '3' ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; If the DF_APP2|DF_DSM2 flag is set, then call DAT_ENTRYPOINT... ; if '${app:${get:TW_IDENTITY.SupportedGroups}}' & '0x30000000' != '0x30000000' goto MAIN.ENTRYPOINT.SKIP dsmentry src null dg_control dat_entrypoint msg_get '0,0,0,0,0,0' echo.progress 'entrypoint/get' '${sts:} - ${ret:}' if '${sts:}' != 'SUCCESS' goto MAIN.ERROR :MAIN.ENTRYPOINT.SKIP ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Open the driver... ; dsmentry src null dg_control dat_identity msg_opends '0,0,0,0,0,,0,0,0x0,,,${arg:1}' setlocal twidentity '${ret:}' echo.progress 'identity/opends' '${sts:} - ${get:twidentity}' if '${sts:}' != 'SUCCESS' goto MAIN.FAIL setlocal twainstate '4' ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Set CAP_INDICATORS to TRUE... ; dsmentry src ds dg_control dat_capability msg_set 'CAP_INDICATORS,TWON_ONEVALUE,TWTY_BOOL,TRUE' echo.progress 'capability/set' '${sts:} - ${ret:}' if '${sts:}' != 'SUCCESS' goto MAIN.FAIL ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Set ICAP_XFERMECH to TWSX_NATIVE... ; dsmentry src null dg_control dat_capability msg_set 'ICAP_XFERMECH,TWON_ONEVALUE,TWTY_UINT16,TWSX_NATIVE' echo.progress 'capability/set' '${sts:} - ${ret:}' if '${sts:}' != 'SUCCESS' goto MAIN.FAIL ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Start scanning... ; wait reset dsmentry src null dg_control dat_userinterface msg_enableds '0,0' echo.progress 'userinterface/enableds' '${sts:} - ${ret:}' if '${sts:}' != 'SUCCESS' goto MAIN.FAIL setlocal twainstate '5' ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Wait for MSG_XFERREADY, if we don't see it then scoot... ; wait 30000 echo.progress 'wait' '${ret:}' if '${ret:}' !~contains 'msg_xferready' goto MAIN.PASS ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Do a native transfer... ; :MAIN.NEXTIMAGENATIVEXFER setlocal twainstate '6' increment image.count '${get:image.count}' 1 dsmentry src ds dg_image dat_imagenativexfer msg_get '0' setlocal image.handle '${ret:}' echo.progress 'imagenativexfer/get' '${sts:} - ${ret:}' if '${sts:}' != 'XFERDONE' goto MAIN.FAIL image save image.handle native '${get:image.folder}/img${format:D6|${get:image.count}}' free handle image.handle setlocal twainstate '7' ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; End the transfer, see if we're done... ; dsmentry src ds dg_control dat_pendingxfers msg_endxfer '0,0' echo.progress 'pendingxfers/endxfer' '${sts:} - ${ret:}' if '${sts:}' != 'SUCCESS' goto MAIN.FAIL if '${ret:${get:TW_PENDINGXFERS.Count}}' != '0' goto MAIN.NEXTIMAGENATIVEXFER setlocal twainstate '5' ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; We've passed... ; :MAIN.PASS setlocal main.result pass goto MAIN.EXIT ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; We've run into a problem... ; :MAIN.FAIL echo.progress 'ERROR' '${sts:}' setlocal main.result fail goto MAIN.EXIT ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Rewind the driver, close and unload the DSM, return... ; :MAIN.EXIT free handle image.handle call TWAIN.REWIND '${get:twainstate}' '${get:twidentity}' return '${get:main.result}' ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Function: Rewind from any TWAIN state... ; arg:1 - twainstate ; arg:2 - twidentity ; returns: (nothing) ; :TWAIN.REWIND ; setlocal twainstate '${arg:1}' if '${get:twainstate}' < '7' goto REWIND.6 dsmentry src ds dg_control dat_pendingxfers msg_endxfer '0,0' echo.progress 'pendingxfers/endxfer' '${sts:}' setlocal twainstate '6' :REWIND.6 if '${get:twainstate}' < '6' goto REWIND.5 dsmentry src ds dg_control dat_pendingxfers msg_reset '0,0' echo.progress 'pendingxfers/reset' '${sts:}' setlocal twainstate '5' :REWIND.5 if '${get:twainstate}' < '5' goto REWIND.4 dsmentry src ds dg_control dat_userinterface msg_disableds '0,0' echo.progress 'userinterface/disableds' '${sts:}' setlocal twainstate '4' :REWIND.4 if '${get:twainstate}' < '4' goto REWIND.3 dsmentry src null dg_control dat_identity msg_closeds '${arg:2}' echo.progress 'identity/closeds' '${sts:}' setlocal twainstate '3' :REWIND.3 if '${get:twainstate}' < '3' goto REWIND.2 dsmentry src null dg_control dat_parent msg_closedsm hwnd echo.progress 'parent/closedsm' '${sts:}' setlocal twainstate '2' :REWIND.2 if '${get:twainstate}' < '2' goto REWIND.1 dsmunload setlocal twainstate '1' :REWIND.1 return ${get:twainstate}' ================================================ FILE: twaincs/source/twaincscert/source/data/twaincscert.appdata.installed.txt ================================================ { "comment": [ "******************************************************************************", "rename this file to twaincert.appdata.txt, and remove the leading X from any", "values you want to use." ], "commentLogLevel": [ "******************************************************************************", "default: 0", "0 - only errors are reported", "these values are bits, add them together as needed, for instance, to get", "all logging data flushed to disk, use a value of 7", "1 - log informational messages", "2 - log verbose stuff, like HTML headers", "4 - flush to disk, use to help diagnose crashes" ], "XlogLevel": 3 } ================================================ FILE: twaincs/source/twaincscert/source/terminal.cs ================================================ /////////////////////////////////////////////////////////////////////////////////////// // // twaincscert.Program // // Our entry point. // /////////////////////////////////////////////////////////////////////////////////////// // Author Date Comment // M.McLaughlin 01-Jan-2020 Initial Release /////////////////////////////////////////////////////////////////////////////////////// // Copyright (C) 2020-2021 Kodak Alaris Inc. // // Permission is hereby granted, free of charge, to any person obtaining a // copy of this software and associated documentation files (the "Software"), // to deal in the Software without restriction, including without limitation // the rights to use, copy, modify, merge, publish, distribute, sublicense, // and/or sell copies of the Software, and to permit persons to whom the // Software is furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL // THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER // DEALINGS IN THE SOFTWARE. /////////////////////////////////////////////////////////////////////////////////////// // Helpers... using Microsoft.Win32.SafeHandles; using System; using System.Collections.Generic; using System.Diagnostics; using System.Diagnostics.CodeAnalysis; using System.Globalization; using System.IO; using System.IO.Compression; using System.Reflection; using System.Resources; using System.Runtime.InteropServices; using System.Security.Permissions; using System.Text; using System.Text.RegularExpressions; using System.Threading; using System.Windows.Forms; using TWAINWorkingGroup; namespace twaincscert { /// /// The certification object that we'll use to test and exercise functions /// for TWAIN Direct. /// public sealed class Terminal : IDisposable { // Public Methods #region Public Methods /// /// Initialize stuff... /// public Terminal(FormMain a_formmain) { // Pick some colors... if ((TWAIN.GetProcessor() == TWAIN.Processor.MIPS64EL) || (TWAIN.GetPlatform() == TWAIN.Platform.MACOSX)) { m_consolecolorDefault = ConsoleColor.Black; m_consolecolorBlue = ConsoleColor.DarkBlue; m_consolecolorGreen = ConsoleColor.DarkGreen; m_consolecolorRed = ConsoleColor.Red; m_consolecolorYellow = ConsoleColor.DarkYellow; } else { m_consolecolorDefault = ConsoleColor.Gray; m_consolecolorBlue = ConsoleColor.Cyan; m_consolecolorGreen = ConsoleColor.Green; m_consolecolorRed = ConsoleColor.Red; m_consolecolorYellow = ConsoleColor.Yellow; } // Make sure we have a console... m_streamreaderConsole = Interpreter.CreateConsole(); // Init stuff... m_blSilent = false; m_blSilentEvents = false; m_lkeyvalue = new List(); m_objectKeyValue = new object(); m_lcallstack = new List(); m_formmain = null; m_intptrHwnd = IntPtr.Zero; m_szSetRecordVariable = ""; m_szSetRecordFilter = ""; m_szSetRecordRemove = ""; m_szSetRecordData = ""; m_szTwainSelfCertFolder = ""; m_szSelfCertDataCertFolder = Path.Combine(Path.GetDirectoryName(Application.ExecutablePath), Path.Combine("data", "Certification")); if (a_formmain != null) { m_formmain = a_formmain; m_intptrHwnd = a_formmain.Handle; } // Set up the base stack with the program arguments, we know // this is the base stack for two reasons: first, it has no // script, and second, it's first... :) CallStack callstack = default(CallStack); callstack.functionarguments.aszCmd = Config.GetCommandLine(); m_lcallstack.Add(callstack); // Build our command table... m_ldispatchtable = new List(); // Discovery and Selection... m_ldispatchtable.Add(new Interpreter.DispatchTable(CmdHelp, new string[] { "help", "?" })); m_ldispatchtable.Add(new Interpreter.DispatchTable(CmdCertify, new string[] { "certify" })); m_ldispatchtable.Add(new Interpreter.DispatchTable(CmdQuit, new string[] { "ex", "exit", "q", "quit" })); m_ldispatchtable.Add(new Interpreter.DispatchTable(CmdStatus, new string[] { "status" })); // Dsmentry (all DG/DAT/MSG stuff comes here)... m_ldispatchtable.Add(new Interpreter.DispatchTable(CmdDsmEntry, new string[] { "dsmentry" })); m_ldispatchtable.Add(new Interpreter.DispatchTable(CmdDsmLoad, new string[] { "dsmload" })); m_ldispatchtable.Add(new Interpreter.DispatchTable(CmdDsmUnload, new string[] { "dsmunload" })); // Scripting... m_ldispatchtable.Add(new Interpreter.DispatchTable(CmdAllocate, new string[] { "allocate" })); m_ldispatchtable.Add(new Interpreter.DispatchTable(CmdCall, new string[] { "call" })); m_ldispatchtable.Add(new Interpreter.DispatchTable(CmdCd, new string[] { "cd", "pwd" })); m_ldispatchtable.Add(new Interpreter.DispatchTable(CmdClean, new string[] { "clean" })); m_ldispatchtable.Add(new Interpreter.DispatchTable(CmdCopyBytes, new string[] { "copybytes" })); m_ldispatchtable.Add(new Interpreter.DispatchTable(CmdDir, new string[] { "dir", "ls" })); m_ldispatchtable.Add(new Interpreter.DispatchTable(CmdEcho, new string[] { "echo" })); m_ldispatchtable.Add(new Interpreter.DispatchTable(CmdEchoBlue, new string[] { "echo.blue" })); m_ldispatchtable.Add(new Interpreter.DispatchTable(CmdEchoGreen, new string[] { "echo.green" })); m_ldispatchtable.Add(new Interpreter.DispatchTable(CmdEchoPassfail, new string[] { "echo.passfail" })); m_ldispatchtable.Add(new Interpreter.DispatchTable(CmdEchoProgress, new string[] { "echo.progress" })); m_ldispatchtable.Add(new Interpreter.DispatchTable(CmdEchoPrompt, new string[] { "echo.prompt" })); m_ldispatchtable.Add(new Interpreter.DispatchTable(CmdEchoRed, new string[] { "echo.red" })); m_ldispatchtable.Add(new Interpreter.DispatchTable(CmdEchoTitlesuite, new string[] { "echo.titlesuite" })); m_ldispatchtable.Add(new Interpreter.DispatchTable(CmdEchoTitletest, new string[] { "echo.titletest" })); m_ldispatchtable.Add(new Interpreter.DispatchTable(CmdEchoYellow, new string[] { "echo.yellow" })); m_ldispatchtable.Add(new Interpreter.DispatchTable(CmdFileWrite, new string[] { "filewrite" })); m_ldispatchtable.Add(new Interpreter.DispatchTable(CmdFree, new string[] { "free" })); m_ldispatchtable.Add(new Interpreter.DispatchTable(CmdGc, new string[] { "gc" })); m_ldispatchtable.Add(new Interpreter.DispatchTable(CmdGoto, new string[] { "goto" })); m_ldispatchtable.Add(new Interpreter.DispatchTable(CmdIf, new string[] { "if" })); m_ldispatchtable.Add(new Interpreter.DispatchTable(CmdImage, new string[] { "image" })); m_ldispatchtable.Add(new Interpreter.DispatchTable(CmdIncrement, new string[] { "increment" })); m_ldispatchtable.Add(new Interpreter.DispatchTable(CmdInput, new string[] { "input" })); m_ldispatchtable.Add(new Interpreter.DispatchTable(CmdLog, new string[] { "log" })); m_ldispatchtable.Add(new Interpreter.DispatchTable(CmdMultiply, new string[] { "multiply" })); m_ldispatchtable.Add(new Interpreter.DispatchTable(CmdPause, new string[] { "pause" })); m_ldispatchtable.Add(new Interpreter.DispatchTable(CmdReport, new string[] { "report" })); m_ldispatchtable.Add(new Interpreter.DispatchTable(CmdReturn, new string[] { "return" })); m_ldispatchtable.Add(new Interpreter.DispatchTable(CmdRollback, new string[] { "rollback" })); m_ldispatchtable.Add(new Interpreter.DispatchTable(CmdRun, new string[] { "run" })); m_ldispatchtable.Add(new Interpreter.DispatchTable(CmdRunv, new string[] { "runv" })); m_ldispatchtable.Add(new Interpreter.DispatchTable(CmdSaveImage, new string[] { "saveimage" })); m_ldispatchtable.Add(new Interpreter.DispatchTable(CmdSetGlobal, new string[] { "setglobal" })); m_ldispatchtable.Add(new Interpreter.DispatchTable(CmdSetLocal, new string[] { "setlocal" })); m_ldispatchtable.Add(new Interpreter.DispatchTable(CmdSetRecord, new string[] { "setrecord" })); m_ldispatchtable.Add(new Interpreter.DispatchTable(CmdSizes, new string[] { "sizes" })); m_ldispatchtable.Add(new Interpreter.DispatchTable(CmdSleep, new string[] { "sleep" })); m_ldispatchtable.Add(new Interpreter.DispatchTable(CmdVerbose, new string[] { "verbose" })); m_ldispatchtable.Add(new Interpreter.DispatchTable(CmdWait, new string[] { "wait" })); // Create our certification folder... if (!CreateTwainSelfCertDataFolder(false)) { DisplayRed("Couldn't create the data folder..."); Log.Error("Couldn't create the data folder..."); } // If we see a data folder in our working directory, we'll use that for // everything except certification... if (Directory.Exists("data")) { Directory.SetCurrentDirectory("data"); } // Otherwise, try for the "TWAIN Self Certification" folder... else { string szDataFolder = Path.Combine(m_szTwainSelfCertFolder, "data"); if (Directory.Exists(szDataFolder)) { Directory.SetCurrentDirectory(szDataFolder); } } // Give ourselves a convenient variable... SetVariable("sys_waittimeout", "60", 0, VariableScope.Global); // Say hi... Assembly assembly = typeof(Terminal).Assembly; AssemblyName assemblyname = assembly.GetName(); Version version = assemblyname.Version; DateTime datetime = new DateTime(2000, 1, 1).AddDays(version.Build).AddSeconds(version.MinorRevision * 2); string szSystem = "("; switch (TWAIN.GetPlatform()) { default: szSystem += "UNKNOWN-OS"; break; case TWAIN.Platform.WINDOWS: szSystem += "Windows"; break; case TWAIN.Platform.LINUX: szSystem += "Linux"; break; case TWAIN.Platform.MACOSX: szSystem += "macOS"; break; } switch (TWAIN.GetProcessor()) { default: szSystem += " UNKNOWN-PROCESSOR"; break; case TWAIN.Processor.X86: case TWAIN.Processor.X86_64: szSystem += " Intel"; break; case TWAIN.Processor.MIPS64EL: szSystem += " MIPSEL"; break; } switch (TWAIN.GetMachineWordBitSize()) { default: szSystem += " UNKNOWN-BITSIZE"; break; case 32: szSystem += " 32-bit"; break; case 64: szSystem += " 64-bit"; break; } szSystem += ")"; m_szBanner = "TWAIN Certification v" + version.Major + "." + version.Minor + " " + datetime.Day + "-" + datetime.ToString("MMM") + "-" + datetime.Year + " " + szSystem; Display(m_szBanner); Display("Enter \"certify\" to certify a scanner."); Display("Enter \"help\" for more info."); } /// /// Destructor... /// ~Terminal() { Dispose(false); } /// /// Cleanup... /// public void Dispose() { Dispose(true); GC.SuppressFinalize(this); } /// /// Get our TWAIN object... /// /// public TWAIN GetTwain() { return (m_twain); } /// /// Run the certification tool... /// public void Run() { string szPrompt = "tc"; Interpreter interpreter = new Interpreter(szPrompt + ">>> ", m_consolecolorDefault, m_consolecolorGreen); // If not windows we have to turn on echo... if (TWAINWorkingGroup.TWAIN.GetPlatform() != TWAIN.Platform.WINDOWS) { var typeSystemConsoleDriver = System.Type.GetType("System.ConsoleDriver"); if (typeSystemConsoleDriver != null) { var setecho = typeSystemConsoleDriver.GetMethod("SetEcho", BindingFlags.Static | BindingFlags.NonPublic); if (setecho != null) { setecho.Invoke(System.Console.In, new object[] { false }); setecho.Invoke(System.Console.In, new object[] { true }); } } } // Run until told to stop... while (true) { bool blDone; string szCmd; string[] aszCmd; // Prompt... szCmd = interpreter.Prompt(m_streamreaderConsole, ((m_twain == null) ? 1 : (int)m_twain.GetState())); // Tokenize... aszCmd = interpreter.Tokenize(szCmd); // Expansion of symbols... Expansion(default(Interpreter.FunctionArguments), ref aszCmd); // Dispatch... Interpreter.FunctionArguments functionarguments = default(Interpreter.FunctionArguments); functionarguments.aszCmd = aszCmd; blDone = interpreter.Dispatch(ref functionarguments, m_ldispatchtable); if (blDone) { return; } } } /// /// Monitor for DG_CONTROL / DAT_NULL / MSG_* stuff. Actually, we're /// just passing this down into TWAIN.CS, so it can keep track of /// things for us... /// /// Handle of window we're monitoring /// Message received /// Argument to message /// Another argument to message /// [SecurityPermissionAttribute(SecurityAction.LinkDemand, Flags = SecurityPermissionFlag.UnmanagedCode)] public bool PreFilterMessage ( IntPtr a_intptrHwnd, int a_iMsg, IntPtr a_intptrWparam, IntPtr a_intptrLparam ) { if (m_twain != null) { return (m_twain.PreFilterMessage(a_intptrHwnd, a_iMsg, a_intptrWparam, a_intptrLparam)); } return (true); } #endregion // Public Definitions #region Public Definitions /// /// The scope of a variable... /// public enum VariableScope { Auto = 0, Local = 1, Global = 2 } #endregion // Private Methods (DsmEntry) #region Private Methods (DsmEntry) /// /// Send a command to the currently loaded DSM... /// /// tokenized command and anything needed /// true to quit private bool CmdDsmEntry(ref Interpreter.FunctionArguments a_functionarguments) { TWAIN.DG dg = TWAIN.DG.MASK; TWAIN.DAT dat = TWAIN.DAT.NULL; TWAIN.MSG msg = TWAIN.MSG.NULL; CallStack callstack = m_lcallstack[m_lcallstack.Count - 1]; // Init stuff... a_functionarguments.iDg = 0; a_functionarguments.iDat = 0; a_functionarguments.iMsg = 0; a_functionarguments.sts = TWAIN.STS.BADPROTOCOL; a_functionarguments.szReturnValue = ""; // Validate at the top level... if (m_twain == null) { DisplayRed("***ERROR*** - dsmload wasn't run, so we is having no braims"); a_functionarguments.sts = TWAIN.STS.SEQERROR; return (false); } if (a_functionarguments.aszCmd.Length != 7) { DisplayRed("***ERROR*** - command needs 7 arguments: dsmentry src dst dg dat msg memref"); return (false); } // Look for Source... if (a_functionarguments.aszCmd[1] == "src") { } else { DisplayRed("Unrecognized src - <" + a_functionarguments.aszCmd[1] + ">"); return (false); } // Look for Destination... if (a_functionarguments.aszCmd[2] == "ds") { } else if (a_functionarguments.aszCmd[2] == "null") { } else { DisplayRed("Unrecognized dst - <" + a_functionarguments.aszCmd[2] + ">"); return (false); } // Look for DG... if (!a_functionarguments.aszCmd[3].ToLowerInvariant().StartsWith("dg_")) { DisplayRed("Unrecognized dg - <" + a_functionarguments.aszCmd[3] + ">"); return (false); } else { // Look for hex number (take anything)... if (a_functionarguments.aszCmd[3].ToLowerInvariant().StartsWith("dg_0x")) { if (!int.TryParse(a_functionarguments.aszCmd[3].ToLowerInvariant().Substring(3), NumberStyles.HexNumber, CultureInfo.InvariantCulture, out a_functionarguments.iDg)) { DisplayRed("Badly constructed dg - <" + a_functionarguments.aszCmd[3] + ">"); return (false); } } else { if (!Enum.TryParse(a_functionarguments.aszCmd[3].ToUpperInvariant().Substring(3), out dg)) { DisplayRed("Unrecognized dg - <" + a_functionarguments.aszCmd[3] + ">"); return (false); } a_functionarguments.iDg = (int)dg; } } // Look for DAT... if (!a_functionarguments.aszCmd[4].ToLowerInvariant().StartsWith("dat_")) { DisplayRed("Unrecognized dat - <" + a_functionarguments.aszCmd[4] + ">"); return (false); } else { // Look for hex number (take anything)... if (a_functionarguments.aszCmd[4].ToLowerInvariant().StartsWith("dat_0x")) { if (!int.TryParse(a_functionarguments.aszCmd[4].ToLowerInvariant().Substring(4), NumberStyles.HexNumber, CultureInfo.InvariantCulture, out a_functionarguments.iDat)) { DisplayRed("Badly constructed dat - <" + a_functionarguments.aszCmd[4] + ">"); return (false); } } else { if (!Enum.TryParse(a_functionarguments.aszCmd[4].ToUpperInvariant().Substring(4), out dat)) { DisplayRed("Unrecognized dat - <" + a_functionarguments.aszCmd[4] + ">"); return (false); } a_functionarguments.iDat = (int)dat; } } // Look for MSG... if (!a_functionarguments.aszCmd[5].ToLowerInvariant().StartsWith("msg_")) { DisplayRed("Unrecognized msg - <" + a_functionarguments.aszCmd[5] + ">"); return (false); } else { // Look for hex number (take anything)... if (a_functionarguments.aszCmd[5].ToLowerInvariant().StartsWith("msg_0x")) { if (!int.TryParse(a_functionarguments.aszCmd[5].ToLowerInvariant().Substring(4), NumberStyles.HexNumber, CultureInfo.InvariantCulture, out a_functionarguments.iMsg)) { DisplayRed("Badly constructed dat - <" + a_functionarguments.aszCmd[5] + ">"); return (false); } } else { if (!Enum.TryParse(a_functionarguments.aszCmd[5].ToUpperInvariant().Substring(4), out msg)) { DisplayRed("Unrecognized msg - <" + a_functionarguments.aszCmd[5] + ">"); return (false); } a_functionarguments.iMsg = (int)msg; } } // If this is issued directly by the user or runv is being used, let's // give more info... if (!m_blRunningScript || m_blVerbose) { CSV csv = new CSV(); foreach (string szCmd in a_functionarguments.aszCmd) { csv.Add(szCmd); } DisplayBlue("snd: " + csv.Get()); } // Send the command... switch (a_functionarguments.iDat) { // Ruh-roh, since we can't marshal it, we have to return an error, // it would be nice to have a solution for this, but that will need // a dynamic marshalling system... default: a_functionarguments.sts = TWAIN.STS.BADPROTOCOL; break; // DAT_AUDIOFILEXFER... case (int)TWAIN.DAT.AUDIOFILEXFER: { a_functionarguments.sts = m_twain.DatAudiofilexfer((TWAIN.DG)a_functionarguments.iDg, (TWAIN.MSG)a_functionarguments.iMsg); a_functionarguments.szReturnValue = ""; callstack.functionarguments.sts = a_functionarguments.sts; callstack.functionarguments.szReturnValue = a_functionarguments.szReturnValue; } break; // DAT_AUDIOINFO.. case (int)TWAIN.DAT.AUDIOINFO: { TWAIN.TW_AUDIOINFO twaudioinfo = default(TWAIN.TW_AUDIOINFO); a_functionarguments.sts = m_twain.DatAudioinfo((TWAIN.DG)a_functionarguments.iDg, (TWAIN.MSG)a_functionarguments.iMsg, ref twaudioinfo); a_functionarguments.szReturnValue = TWAIN.AudioinfoToCsv(twaudioinfo); callstack.functionarguments.sts = a_functionarguments.sts; callstack.functionarguments.szReturnValue = a_functionarguments.szReturnValue; } break; // DAT_AUDIONATIVEXFER.. case (int)TWAIN.DAT.AUDIONATIVEXFER: { IntPtr intptr = IntPtr.Zero; a_functionarguments.sts = m_twain.DatAudionativexfer((TWAIN.DG)a_functionarguments.iDg, (TWAIN.MSG)a_functionarguments.iMsg, ref intptr); a_functionarguments.szReturnValue = intptr.ToString(); callstack.functionarguments.sts = a_functionarguments.sts; callstack.functionarguments.szReturnValue = a_functionarguments.szReturnValue; } break; // DAT_CALLBACK... case (int)TWAIN.DAT.CALLBACK: { TWAIN.TW_CALLBACK twcallback = default(TWAIN.TW_CALLBACK); TWAIN.CsvToCallback(ref twcallback, a_functionarguments.aszCmd[6]); a_functionarguments.sts = m_twain.DatCallback((TWAIN.DG)a_functionarguments.iDg, (TWAIN.MSG)a_functionarguments.iMsg, ref twcallback); a_functionarguments.szReturnValue = TWAIN.CallbackToCsv(twcallback); callstack.functionarguments.sts = a_functionarguments.sts; callstack.functionarguments.szReturnValue = a_functionarguments.szReturnValue; } break; // DAT_CALLBACK2... case (int)TWAIN.DAT.CALLBACK2: { TWAIN.TW_CALLBACK2 twcallback2 = default(TWAIN.TW_CALLBACK2); TWAIN.CsvToCallback2(ref twcallback2, a_functionarguments.aszCmd[6]); a_functionarguments.sts = m_twain.DatCallback2((TWAIN.DG)a_functionarguments.iDg, (TWAIN.MSG)a_functionarguments.iMsg, ref twcallback2); a_functionarguments.szReturnValue = TWAIN.Callback2ToCsv(twcallback2); callstack.functionarguments.sts = a_functionarguments.sts; callstack.functionarguments.szReturnValue = a_functionarguments.szReturnValue; } break; // DAT_CAPABILITY... case (int)TWAIN.DAT.CAPABILITY: { // Skip symbols for msg_querysupport, otherwise 0 gets turned into false, also // if the command fails the return value is whatever was sent into us, which // matches the experience one should get with C/C++... string szStatus = ""; TWAIN.TW_CAPABILITY twcapability = default(TWAIN.TW_CAPABILITY); m_twain.CsvToCapability(ref twcapability, ref szStatus, a_functionarguments.aszCmd[6]); a_functionarguments.sts = m_twain.DatCapability((TWAIN.DG)a_functionarguments.iDg, (TWAIN.MSG)a_functionarguments.iMsg, ref twcapability); if ((a_functionarguments.sts == TWAIN.STS.SUCCESS) || (a_functionarguments.sts == TWAIN.STS.CHECKSTATUS)) { // Convert the data to CSV... a_functionarguments.szReturnValue = m_twain.CapabilityToCsv(twcapability, ((TWAIN.MSG)a_functionarguments.iMsg != TWAIN.MSG.QUERYSUPPORT)); // Free the handle if the driver created it... switch ((TWAIN.MSG)a_functionarguments.iMsg) { default: break; case TWAIN.MSG.GET: case TWAIN.MSG.GETCURRENT: case TWAIN.MSG.GETDEFAULT: case TWAIN.MSG.QUERYSUPPORT: case TWAIN.MSG.RESET: m_twain.DsmMemFree(ref twcapability.hContainer); break; } } else { a_functionarguments.szReturnValue = a_functionarguments.aszCmd[6]; } callstack.functionarguments.sts = a_functionarguments.sts; callstack.functionarguments.szReturnValue = a_functionarguments.szReturnValue; } break; // DAT_CIECOLOR.. case (int)TWAIN.DAT.CIECOLOR: { //TWAIN.TW_CIECOLOR twciecolor = default(TWAIN.TW_CIECOLOR); //a_functionarguments.sts = m_twain.DatCiecolor((TWAIN.DG)a_functionarguments.iDg, (TWAIN.MSG)a_functionarguments.iMsg, ref twciecolor); //a_functionarguments.szReturnValue = m_twain.CiecolorToCsv(twciecolor); //callstack.functionarguments.sts = a_functionarguments.sts; //callstack.functionarguments.szReturnValue = a_functionarguments.szReturnValue; } break; // DAT_CUSTOMDSDATA... case (int)TWAIN.DAT.CUSTOMDSDATA: { TWAIN.TW_CUSTOMDSDATA twcustomdsdata = default(TWAIN.TW_CUSTOMDSDATA); m_twain.CsvToCustomdsdata(ref twcustomdsdata, a_functionarguments.aszCmd[6]); a_functionarguments.sts = m_twain.DatCustomdsdata((TWAIN.DG)a_functionarguments.iDg, (TWAIN.MSG)a_functionarguments.iMsg, ref twcustomdsdata); a_functionarguments.szReturnValue = m_twain.CustomdsdataToCsv(twcustomdsdata); callstack.functionarguments.sts = a_functionarguments.sts; callstack.functionarguments.szReturnValue = a_functionarguments.szReturnValue; } break; // DAT_DEVICEEVENT... case (int)TWAIN.DAT.DEVICEEVENT: { TWAIN.TW_DEVICEEVENT twdeviceevent = default(TWAIN.TW_DEVICEEVENT); a_functionarguments.sts = m_twain.DatDeviceevent((TWAIN.DG)a_functionarguments.iDg, (TWAIN.MSG)a_functionarguments.iMsg, ref twdeviceevent); a_functionarguments.szReturnValue = TWAIN.DeviceeventToCsv(twdeviceevent); callstack.functionarguments.sts = a_functionarguments.sts; callstack.functionarguments.szReturnValue = a_functionarguments.szReturnValue; } break; // DAT_ENTRYPOINT... case (int)TWAIN.DAT.ENTRYPOINT: { TWAIN.TW_ENTRYPOINT twentrypoint = default(TWAIN.TW_ENTRYPOINT); twentrypoint.Size = (uint)Marshal.SizeOf(twentrypoint); a_functionarguments.sts = m_twain.DatEntrypoint((TWAIN.DG)a_functionarguments.iDg, (TWAIN.MSG)a_functionarguments.iMsg, ref twentrypoint); a_functionarguments.szReturnValue = TWAIN.EntrypointToCsv(twentrypoint); callstack.functionarguments.sts = a_functionarguments.sts; callstack.functionarguments.szReturnValue = a_functionarguments.szReturnValue; } break; // DAT_EVENT... case (int)TWAIN.DAT.EVENT: { TWAIN.TW_EVENT twevent = default(TWAIN.TW_EVENT); a_functionarguments.sts = m_twain.DatEvent((TWAIN.DG)a_functionarguments.iDg, (TWAIN.MSG)a_functionarguments.iMsg, ref twevent); a_functionarguments.szReturnValue = TWAIN.EventToCsv(twevent); callstack.functionarguments.sts = a_functionarguments.sts; callstack.functionarguments.szReturnValue = a_functionarguments.szReturnValue; } break; // DAT_EXTIMAGEINFO... case (int)TWAIN.DAT.EXTIMAGEINFO: { TWAIN.TW_EXTIMAGEINFO twextimageinfo = default(TWAIN.TW_EXTIMAGEINFO); TWAIN.CsvToExtimageinfo(ref twextimageinfo, a_functionarguments.aszCmd[6]); a_functionarguments.sts = m_twain.DatExtimageinfo((TWAIN.DG)a_functionarguments.iDg, (TWAIN.MSG)a_functionarguments.iMsg, ref twextimageinfo); a_functionarguments.szReturnValue = TWAIN.ExtimageinfoToCsv(twextimageinfo); callstack.functionarguments.sts = a_functionarguments.sts; callstack.functionarguments.szReturnValue = a_functionarguments.szReturnValue; } break; // DAT_FILESYSTEM... case (int)TWAIN.DAT.FILESYSTEM: { TWAIN.TW_FILESYSTEM twfilesystem = default(TWAIN.TW_FILESYSTEM); TWAIN.CsvToFilesystem(ref twfilesystem, a_functionarguments.aszCmd[6]); a_functionarguments.sts = m_twain.DatFilesystem((TWAIN.DG)a_functionarguments.iDg, (TWAIN.MSG)a_functionarguments.iMsg, ref twfilesystem); a_functionarguments.szReturnValue = TWAIN.FilesystemToCsv(twfilesystem); callstack.functionarguments.sts = a_functionarguments.sts; callstack.functionarguments.szReturnValue = a_functionarguments.szReturnValue; } break; // DAT_FILTER... case (int)TWAIN.DAT.FILTER: { //TWAIN.TW_FILTER twfilter = default(TWAIN.TW_FILTER); //m_twain.CsvToFilter(ref twfilter, a_functionarguments.aszCmd[6]); //a_functionarguments.sts = m_twain.DatFilter((TWAIN.DG)a_functionarguments.iDg, (TWAIN.MSG)a_functionarguments.iMsg, ref twfilter); //a_functionarguments.szReturnValue = m_twain.FilterToCsv(twfilter); //callstack.functionarguments.sts = a_functionarguments.sts; //callstack.functionarguments.szReturnValue = a_functionarguments.szReturnValue; } break; // DAT_GRAYRESPONSE... case (int)TWAIN.DAT.GRAYRESPONSE: { //TWAIN.TW_GRAYRESPONSE twgrayresponse = default(TWAIN.TW_GRAYRESPONSE); //m_twain.CsvToGrayresponse(ref twgrayresponse, a_functionarguments.aszCmd[6]); //a_functionarguments.sts = m_twain.DatGrayresponse((TWAIN.DG)a_functionarguments.iDg, (TWAIN.MSG)a_functionarguments.iMsg, ref twgrayresponse); //a_functionarguments.szReturnValue = m_twain.GrayresponseToCsv(twgrayresponse); //callstack.functionarguments.sts = a_functionarguments.sts; //callstack.functionarguments.szReturnValue = a_functionarguments.szReturnValue; } break; // DAT_ICCPROFILE... case (int)TWAIN.DAT.ICCPROFILE: { TWAIN.TW_MEMORY twmemory = default(TWAIN.TW_MEMORY); a_functionarguments.sts = m_twain.DatIccprofile((TWAIN.DG)a_functionarguments.iDg, (TWAIN.MSG)a_functionarguments.iMsg, ref twmemory); a_functionarguments.szReturnValue = TWAIN.IccprofileToCsv(twmemory); callstack.functionarguments.sts = a_functionarguments.sts; callstack.functionarguments.szReturnValue = a_functionarguments.szReturnValue; } break; // DAT_IDENTITY... case (int)TWAIN.DAT.IDENTITY: { TWAIN.TW_IDENTITY twidentity = default(TWAIN.TW_IDENTITY); TWAIN.CsvToIdentity(ref twidentity, a_functionarguments.aszCmd[6]); a_functionarguments.sts = m_twain.DatIdentity((TWAIN.DG)a_functionarguments.iDg, (TWAIN.MSG)a_functionarguments.iMsg, ref twidentity); a_functionarguments.szReturnValue = TWAIN.IdentityToCsv(twidentity); callstack.functionarguments.sts = a_functionarguments.sts; callstack.functionarguments.szReturnValue = a_functionarguments.szReturnValue; } break; // DAT_IMAGEFILEXFER... case (int)TWAIN.DAT.IMAGEFILEXFER: { a_functionarguments.sts = m_twain.DatImagefilexfer((TWAIN.DG)a_functionarguments.iDg, (TWAIN.MSG)a_functionarguments.iMsg); a_functionarguments.szReturnValue = ""; callstack.functionarguments.sts = a_functionarguments.sts; callstack.functionarguments.szReturnValue = a_functionarguments.szReturnValue; } break; // DAT_IMAGEINFO... case (int)TWAIN.DAT.IMAGEINFO: { TWAIN.TW_IMAGEINFO twimageinfo = default(TWAIN.TW_IMAGEINFO); TWAIN.CsvToImageinfo(ref twimageinfo, a_functionarguments.aszCmd[6]); a_functionarguments.sts = m_twain.DatImageinfo((TWAIN.DG)a_functionarguments.iDg, (TWAIN.MSG)a_functionarguments.iMsg, ref twimageinfo); a_functionarguments.szReturnValue = TWAIN.ImageinfoToCsv(twimageinfo); callstack.functionarguments.sts = a_functionarguments.sts; callstack.functionarguments.szReturnValue = a_functionarguments.szReturnValue; } break; // DAT_IMAGELAYOUT... case (int)TWAIN.DAT.IMAGELAYOUT: { TWAIN.TW_IMAGELAYOUT twimagelayout = default(TWAIN.TW_IMAGELAYOUT); TWAIN.CsvToImagelayout(ref twimagelayout, a_functionarguments.aszCmd[6]); a_functionarguments.sts = m_twain.DatImagelayout((TWAIN.DG)a_functionarguments.iDg, (TWAIN.MSG)a_functionarguments.iMsg, ref twimagelayout); a_functionarguments.szReturnValue = TWAIN.ImagelayoutToCsv(twimagelayout); callstack.functionarguments.sts = a_functionarguments.sts; callstack.functionarguments.szReturnValue = a_functionarguments.szReturnValue; } break; // DAT_IMAGEMEMFILEXFER... case (int)TWAIN.DAT.IMAGEMEMFILEXFER: { TWAIN.TW_IMAGEMEMXFER twimagememxfer = default(TWAIN.TW_IMAGEMEMXFER); TWAIN.CsvToImagememxfer(ref twimagememxfer, a_functionarguments.aszCmd[6]); a_functionarguments.sts = m_twain.DatImagememfilexfer((TWAIN.DG)a_functionarguments.iDg, (TWAIN.MSG)a_functionarguments.iMsg, ref twimagememxfer); a_functionarguments.szReturnValue = TWAIN.ImagememxferToCsv(twimagememxfer); callstack.functionarguments.sts = a_functionarguments.sts; callstack.functionarguments.szReturnValue = a_functionarguments.szReturnValue; } break; // DAT_IMAGEMEMXFER... case (int)TWAIN.DAT.IMAGEMEMXFER: { TWAIN.TW_IMAGEMEMXFER twimagememxfer = default(TWAIN.TW_IMAGEMEMXFER); TWAIN.CsvToImagememxfer(ref twimagememxfer, a_functionarguments.aszCmd[6]); a_functionarguments.sts = m_twain.DatImagememxfer((TWAIN.DG)a_functionarguments.iDg, (TWAIN.MSG)a_functionarguments.iMsg, ref twimagememxfer); a_functionarguments.szReturnValue = TWAIN.ImagememxferToCsv(twimagememxfer); callstack.functionarguments.sts = a_functionarguments.sts; callstack.functionarguments.szReturnValue = a_functionarguments.szReturnValue; } break; // DAT_IMAGENATIVEXFER... case (int)TWAIN.DAT.IMAGENATIVEXFER: { IntPtr intptrBitmapHandle = IntPtr.Zero; a_functionarguments.sts = m_twain.DatImagenativexferHandle((TWAIN.DG)a_functionarguments.iDg, (TWAIN.MSG)a_functionarguments.iMsg, ref intptrBitmapHandle); a_functionarguments.szReturnValue = intptrBitmapHandle.ToString(); callstack.functionarguments.sts = a_functionarguments.sts; callstack.functionarguments.szReturnValue = a_functionarguments.szReturnValue; } break; // DAT_JPEGCOMPRESSION... case (int)TWAIN.DAT.JPEGCOMPRESSION: { //TWAIN.TW_JPEGCOMPRESSION twjpegcompression = default(TWAIN.TW_JPEGCOMPRESSION); //m_twain.CsvToJpegcompression(ref twjpegcompression, a_functionarguments.aszCmd[6]); //a_functionarguments.sts = m_twain.DatJpegcompression((TWAIN.DG)a_functionarguments.iDg, (TWAIN.MSG)a_functionarguments.iMsg, ref twjpegcompression); //a_functionarguments.szReturnValue = m_twain.JpegcompressionToCsv(twjpegcompression); //callstack.functionarguments.sts = a_functionarguments.sts; //callstack.functionarguments.szReturnValue = a_functionarguments.szReturnValue; } break; // DAT_METRICS... case (int)TWAIN.DAT.METRICS: { TWAIN.TW_METRICS twmetrics = default(TWAIN.TW_METRICS); twmetrics.SizeOf = (uint)Marshal.SizeOf(twmetrics); a_functionarguments.sts = m_twain.DatMetrics((TWAIN.DG)a_functionarguments.iDg, (TWAIN.MSG)a_functionarguments.iMsg, ref twmetrics); a_functionarguments.szReturnValue = TWAIN.MetricsToCsv(twmetrics); callstack.functionarguments.sts = a_functionarguments.sts; callstack.functionarguments.szReturnValue = a_functionarguments.szReturnValue; } break; // DAT_PALETTE8... case (int)TWAIN.DAT.PALETTE8: { //TWAIN.TW_PALETTE8 twpalette8 = default(TWAIN.TW_PALETTE8); //m_twain.CsvToPalette8(ref twpalette8, a_functionarguments.aszCmd[6]); //a_functionarguments.sts = m_twain.DatPalette8((TWAIN.DG)a_functionarguments.iDg, (TWAIN.MSG)a_functionarguments.iMsg, ref twpalette8); //a_functionarguments.szReturnValue = m_twain.Palette8ToCsv(twpalette8); //callstack.functionarguments.sts = a_functionarguments.sts; //callstack.functionarguments.szReturnValue = a_functionarguments.szReturnValue; } break; // DAT_PARENT... case (int)TWAIN.DAT.PARENT: { a_functionarguments.sts = m_twain.DatParent((TWAIN.DG)a_functionarguments.iDg, (TWAIN.MSG)a_functionarguments.iMsg, ref m_intptrHwnd); } break; // DAT_PASSTHRU... case (int)TWAIN.DAT.PASSTHRU: { TWAIN.TW_PASSTHRU twpassthru = default(TWAIN.TW_PASSTHRU); TWAIN.CsvToPassthru(ref twpassthru, a_functionarguments.aszCmd[6]); a_functionarguments.sts = m_twain.DatPassthru((TWAIN.DG)a_functionarguments.iDg, (TWAIN.MSG)a_functionarguments.iMsg, ref twpassthru); a_functionarguments.szReturnValue = TWAIN.PassthruToCsv(twpassthru); callstack.functionarguments.sts = a_functionarguments.sts; callstack.functionarguments.szReturnValue = a_functionarguments.szReturnValue; } break; // DAT_PENDINGXFERS... case (int)TWAIN.DAT.PENDINGXFERS: { // Send the command... TWAIN.TW_PENDINGXFERS twpendingxfers = default(TWAIN.TW_PENDINGXFERS); a_functionarguments.sts = m_twain.DatPendingxfers((TWAIN.DG)a_functionarguments.iDg, (TWAIN.MSG)a_functionarguments.iMsg, ref twpendingxfers); a_functionarguments.szReturnValue = TWAIN.PendingxfersToCsv(twpendingxfers); callstack.functionarguments.sts = a_functionarguments.sts; callstack.functionarguments.szReturnValue = a_functionarguments.szReturnValue; // Clear the list, so the script writer doesn't have to (needed for when ShowUI is TRUE)... if (a_functionarguments.sts == TWAIN.STS.SUCCESS) { if ((a_functionarguments.iMsg == (int)TWAIN.MSG.RESET) || ((a_functionarguments.iMsg == (int)TWAIN.MSG.ENDXFER) && (twpendingxfers.Count == 0))) { lock (m_lmsgDatNull) { m_lmsgDatNull.Clear(); m_autoreseteventMsgDatNull.Reset(); } } } } break; // DAT_RGBRESPONSE... case (int)TWAIN.DAT.RGBRESPONSE: { //TWAIN.TW_RGBRESPONSE twrgbresponse = default(TWAIN.TW_RGBRESPONSE); //m_twain.CsvToRgbresponse(ref twrgbresponse, a_functionarguments.aszCmd[6]); //a_functionarguments.sts = m_twain.DatRgbresponse((TWAIN.DG)a_functionarguments.iDg, (TWAIN.MSG)a_functionarguments.iMsg, ref twrgbresponse); //a_functionarguments.szReturnValue = m_twain.RgbresponseToCsv(twrgbresponse); //callstack.functionarguments.sts = a_functionarguments.sts; //callstack.functionarguments.szReturnValue = a_functionarguments.szReturnValue; } break; // DAT_SETUPFILEXFER... case (int)TWAIN.DAT.SETUPFILEXFER: { TWAIN.TW_SETUPFILEXFER twsetupfilexfer = default(TWAIN.TW_SETUPFILEXFER); TWAIN.CsvToSetupfilexfer(ref twsetupfilexfer, a_functionarguments.aszCmd[6]); a_functionarguments.sts = m_twain.DatSetupfilexfer((TWAIN.DG)a_functionarguments.iDg, (TWAIN.MSG)a_functionarguments.iMsg, ref twsetupfilexfer); a_functionarguments.szReturnValue = TWAIN.SetupfilexferToCsv(twsetupfilexfer); callstack.functionarguments.sts = a_functionarguments.sts; callstack.functionarguments.szReturnValue = a_functionarguments.szReturnValue; } break; // DAT_SETUPMEMXFER... case (int)TWAIN.DAT.SETUPMEMXFER: { TWAIN.TW_SETUPMEMXFER twsetupmemxfer = default(TWAIN.TW_SETUPMEMXFER); a_functionarguments.sts = m_twain.DatSetupmemxfer((TWAIN.DG)a_functionarguments.iDg, (TWAIN.MSG)a_functionarguments.iMsg, ref twsetupmemxfer); a_functionarguments.szReturnValue = TWAIN.SetupmemxferToCsv(twsetupmemxfer); callstack.functionarguments.sts = a_functionarguments.sts; callstack.functionarguments.szReturnValue = a_functionarguments.szReturnValue; } break; // DAT_STATUS... case (int)TWAIN.DAT.STATUS: { TWAIN.TW_STATUS twstatus = default(TWAIN.TW_STATUS); a_functionarguments.sts = m_twain.DatStatus((TWAIN.DG)a_functionarguments.iDg, (TWAIN.MSG)a_functionarguments.iMsg, ref twstatus); a_functionarguments.szReturnValue = TWAIN.StatusToCsv(twstatus); callstack.functionarguments.sts = a_functionarguments.sts; callstack.functionarguments.szReturnValue = a_functionarguments.szReturnValue; } break; // DAT_STATUSUTF8... case (int)TWAIN.DAT.STATUSUTF8: { TWAIN.TW_STATUSUTF8 twstatusutf8 = default(TWAIN.TW_STATUSUTF8); a_functionarguments.sts = m_twain.DatStatusutf8((TWAIN.DG)a_functionarguments.iDg, (TWAIN.MSG)a_functionarguments.iMsg, ref twstatusutf8); a_functionarguments.szReturnValue = m_twain.Statusutf8ToCsv(twstatusutf8); callstack.functionarguments.sts = a_functionarguments.sts; callstack.functionarguments.szReturnValue = a_functionarguments.szReturnValue; } break; // DAT_TWAINDIRECT... case (int)TWAIN.DAT.TWAINDIRECT: { TWAIN.TW_TWAINDIRECT twtwaindirect = default(TWAIN.TW_TWAINDIRECT); TWAIN.CsvToTwaindirect(ref twtwaindirect, a_functionarguments.aszCmd[6]); a_functionarguments.sts = m_twain.DatTwaindirect((TWAIN.DG)a_functionarguments.iDg, (TWAIN.MSG)a_functionarguments.iMsg, ref twtwaindirect); a_functionarguments.szReturnValue = TWAIN.TwaindirectToCsv(twtwaindirect); callstack.functionarguments.sts = a_functionarguments.sts; callstack.functionarguments.szReturnValue = a_functionarguments.szReturnValue; } break; // DAT_USERINTERFACE... case (int)TWAIN.DAT.USERINTERFACE: { // Clear the list, so the script writer doesn't have to... if ((a_functionarguments.iMsg == (int)TWAIN.MSG.ENABLEDS) || (a_functionarguments.iMsg == (int)TWAIN.MSG.ENABLEDSUIONLY)) { lock (m_lmsgDatNull) { m_lmsgDatNull.Clear(); m_autoreseteventMsgDatNull.Reset(); } } // Send the command... TWAIN.TW_USERINTERFACE twuserinterface = default(TWAIN.TW_USERINTERFACE); m_twain.CsvToUserinterface(ref twuserinterface, a_functionarguments.aszCmd[6]); a_functionarguments.sts = m_twain.DatUserinterface((TWAIN.DG)a_functionarguments.iDg, (TWAIN.MSG)a_functionarguments.iMsg, ref twuserinterface); a_functionarguments.szReturnValue = TWAIN.UserinterfaceToCsv(twuserinterface); callstack.functionarguments.sts = a_functionarguments.sts; callstack.functionarguments.szReturnValue = a_functionarguments.szReturnValue; // Clear the list, so the script writer doesn't have to... if (a_functionarguments.sts == TWAIN.STS.SUCCESS) { if (a_functionarguments.iMsg == (int)TWAIN.MSG.DISABLEDS) { lock (m_lmsgDatNull) { m_lmsgDatNull.Clear(); m_autoreseteventMsgDatNull.Reset(); } } } } break; // DAT_XFERGROUP... case (int)TWAIN.DAT.XFERGROUP: { uint uXferGroup = 0; a_functionarguments.sts = m_twain.DatXferGroup((TWAIN.DG)a_functionarguments.iDg, (TWAIN.MSG)a_functionarguments.iMsg, ref uXferGroup); a_functionarguments.szReturnValue = string.Format("0x{0:X}", uXferGroup); callstack.functionarguments.sts = a_functionarguments.sts; callstack.functionarguments.szReturnValue = a_functionarguments.szReturnValue; } break; } // If this is issued directly by the user or runv is being used, let's // give more info... if (!m_blRunningScript || m_blVerbose) { DisplayBlue("rcv: " + a_functionarguments.szReturnValue); DisplayBlue("sts: " + a_functionarguments.sts); } // All done... return (false); } /// /// Load the DSM... /// /// tokenized command and anything needed /// true to quit private bool CmdDsmLoad(ref Interpreter.FunctionArguments a_functionarguments) { Assembly assembly = typeof(Terminal).Assembly; AssemblyName assemblyname = assembly.GetName(); Version version = assemblyname.Version; string szManufacturer = "TWAIN Working Group"; string szProductFamily = "TWAIN Open Source"; string szProductName = "TWAIN Certification"; UInt16 u16ProtocolMajor = (UInt16)TWAIN.TWON_PROTOCOL.MAJOR; UInt16 u16ProtocolMinor = (UInt16)TWAIN.TWON_PROTOCOL.MINOR; UInt32 u32SupportedGroups = ((int)TWAIN.DG.APP2 | (int)TWAIN.DG.CONTROL | (int)TWAIN.DG.IMAGE); TWAIN.TWCY twcy = TWAIN.TWCY.USA; string szInfo = "TWAIN Certification"; TWAIN.TWLG twlg = TWAIN.TWLG.ENGLISH; UInt16 u16MajorNum = (UInt16)version.Major; UInt16 u16MinorNum = (UInt16)version.Minor; bool blUseLegacyDSM = false; bool blUseCallbacks = false; TWAIN.DeviceEventCallback deviceeventcallback = DeviceEventCallback; TWAIN.ScanCallback scancallback = ScanCallbackTrigger; TWAIN.RunInUiThreadDelegate runinuithreaddelegate = null; IntPtr intptrHwnd = m_intptrHwnd; // Nope... if (m_twain != null) { return (false); } // Look for matches in the argument list... for (int aa = 0; aa < a_functionarguments.aszCmd.Length; aa++) { // Split it on the first '='... string[] aszKeyValue = a_functionarguments.aszCmd[aa].Split(new char[] { '=' }, 2); if (aszKeyValue.Length != 2) { continue; } // Dispatch... switch (aszKeyValue[0].ToLowerInvariant()) { default: DisplayRed("Unrecognized argument...<" + a_functionarguments.aszCmd[aa] + ">"); break; case "manufacturer": szManufacturer = aszKeyValue[1]; break; case "productfamily": szProductFamily = aszKeyValue[1]; break; case "productname": szProductName = aszKeyValue[1]; break; case "protocolmajor": UInt16.TryParse(aszKeyValue[1], out u16ProtocolMajor); break; case "protocolminor": UInt16.TryParse(aszKeyValue[1], out u16ProtocolMinor); break; case "supportedgroups": if (aszKeyValue[1].ToLowerInvariant().StartsWith("0x")) { UInt32.TryParse(aszKeyValue[1].Substring(2), NumberStyles.HexNumber, CultureInfo.InvariantCulture, out u32SupportedGroups); } else { UInt32.TryParse(aszKeyValue[1], out u32SupportedGroups); } break; case "twcy": Enum.TryParse(aszKeyValue[1], out twcy); break; case "info": szInfo = aszKeyValue[1]; break; case "twlg": Enum.TryParse(aszKeyValue[1], out twlg); break; case "majornum": UInt16.TryParse(aszKeyValue[1], out u16MajorNum); break; case "minornum": UInt16.TryParse(aszKeyValue[1], out u16MinorNum); break; case "uselegacydsm": bool.TryParse(aszKeyValue[1], out blUseLegacyDSM); break; case "usecallbacks": bool.TryParse(aszKeyValue[1], out blUseCallbacks); break; } } // Decide if we need a delegate... if (m_formmain != null) { runinuithreaddelegate = RunInUiThread; } // Instantiate TWAIN, and register ourselves... m_twain = new TWAIN ( szManufacturer, szProductFamily, szProductName, u16ProtocolMajor, u16ProtocolMinor, u32SupportedGroups, twcy, szInfo, twlg, u16MajorNum, u16MinorNum, blUseLegacyDSM, blUseCallbacks, deviceeventcallback, scancallback, runinuithreaddelegate, intptrHwnd ); // If verbose, display the app's identity... if (m_blVerbose) { TWAIN.TW_IDENTITY twidentity = default(TWAIN.TW_IDENTITY); TWAIN.CsvToIdentity(ref twidentity, m_twain.GetAppIdentity()); DisplayBlue("Application TW_IDENTITY.Id.................." + twidentity.Id); DisplayBlue("Application TW_IDENTITY.Version.MajorNum...." + twidentity.Version.MajorNum); DisplayBlue("Application TW_IDENTITY.Version.MinorNum...." + twidentity.Version.MinorNum); DisplayBlue("Application TW_IDENTITY.Version.Language...." + twidentity.Version.Language); DisplayBlue("Application TW_IDENTITY.Version.Country....." + twidentity.Version.Country); DisplayBlue("Application TW_IDENTITY.Version.Info........" + twidentity.Version.Info.Get()); DisplayBlue("Application TW_IDENTITY.ProtocolMajor......." + twidentity.ProtocolMajor); DisplayBlue("Application TW_IDENTITY.ProtocolMinor......." + twidentity.ProtocolMinor); DisplayBlue("Application TW_IDENTITY.SupportedGroups....." + twidentity.SupportedGroups); DisplayBlue("Application TW_IDENTITY.Manufacturer........" + twidentity.Manufacturer.Get()); DisplayBlue("Application TW_IDENTITY.ProductFamily......." + twidentity.ProductFamily.Get()); DisplayBlue("Application TW_IDENTITY.ProductName........." + twidentity.ProductName.Get()); } // All done... return (false); } /// /// Unload the DSM... /// /// tokenized command and anything needed /// true to quit private bool CmdDsmUnload(ref Interpreter.FunctionArguments a_functionarguments) { // Nope... if (m_twain == null) { return (false); } // Shut it down, make sure it's really gone... m_twain.Dispose(); GC.Collect(); m_twain = null; // All done... return (false); } /// /// Our callback for device events. This is where we catch and /// report that a device event has been detected. Obviously, /// we're not doing much with it. A real application would /// probably take some kind of action... /// /// TWAIN status private TWAIN.STS DeviceEventCallback() { TWAIN.STS sts; TWAIN.TW_DEVICEEVENT twdeviceevent; // Drain the event queue... while (true) { // Try to get an event... twdeviceevent = default(TWAIN.TW_DEVICEEVENT); sts = m_twain.DatDeviceevent(TWAIN.DG.CONTROL, TWAIN.MSG.GET, ref twdeviceevent); if (sts != TWAIN.STS.SUCCESS) { break; } } // Return a status, in case we ever need it for anything... return (TWAIN.STS.SUCCESS); } /// /// TWAIN needs help, if we want it to run stuff in our main /// UI thread... /// /// the code to run private void RunInUiThread(Action a_action) { RunInUiThread(m_formmain, a_action); } /// /// TWAIN needs help, if we want it to run stuff in our main /// UI thread... /// /// the control to run in /// the code to run static public void RunInUiThread(Object a_object, Action a_action) { Control control = (Control)a_object; if (control.InvokeRequired) { control.Invoke(new Terminal.RunInUiThreadDelegate(RunInUiThread), new object[] { a_object, a_action }); return; } a_action(); } /// /// Our scanning callback function. We appeal directly to the supporting /// TWAIN object. This way we don't have to maintain some kind of a loop /// inside of the application, which is the source of most problems that /// developers run into. /// /// While it looks scary at first, there's really not a lot going on in /// here. We do some sanity checks, we watch for certain kinds of events, /// we support the four methods of transferring images, and we dump out /// some meta-data about the transferred image. However, because it does /// look scary I dropped in some region pragmas to break things up... /// /// We're shutting down /// TWAIN status private TWAIN.STS ScanCallbackTrigger(bool a_blClosing) { m_formmain.BeginInvoke(new MethodInvoker(delegate { m_formmain.ScanCallbackEventHandler(this, new EventArgs()); })); return (TWAIN.STS.SUCCESS); } public TWAIN.STS ScanCallback(bool a_blClosing) { bool blIsMsgXferReady = false; // Scoot... if (m_twain == null) { return (TWAIN.STS.FAILURE); } // We're leaving... if (a_blClosing) { return (TWAIN.STS.SUCCESS); } // Collect DAT_NULL stuff... if (m_twain.IsMsgXferReady()) { lock (m_lmsgDatNull) { if (!m_lmsgDatNull.Contains(TWAIN.MSG.XFERREADY)) { m_lmsgDatNull.Add(TWAIN.MSG.XFERREADY); m_autoreseteventMsgDatNull.Set(); blIsMsgXferReady = true; } } } if (m_twain.IsMsgCloseDsReq()) { lock (m_lmsgDatNull) { if (!m_lmsgDatNull.Contains(TWAIN.MSG.CLOSEDSREQ)) { m_lmsgDatNull.Add(TWAIN.MSG.CLOSEDSREQ); m_autoreseteventMsgDatNull.Set(); } } } if (m_twain.IsMsgCloseDsOk()) { lock (m_lmsgDatNull) { if (!m_lmsgDatNull.Contains(TWAIN.MSG.CLOSEDSOK)) { m_lmsgDatNull.Add(TWAIN.MSG.CLOSEDSOK); m_autoreseteventMsgDatNull.Set(); } } } // We're waiting for that first image to show up, if we don't // see it, then return... if (!blIsMsgXferReady) { // If we're on Windows we need to send event requests to the driver... if (TWAIN.GetPlatform() == TWAIN.Platform.WINDOWS) { TWAIN.TW_EVENT twevent = default(TWAIN.TW_EVENT); twevent.pEvent = Marshal.AllocHGlobal(256); // over allocate for MSG structure if (twevent.pEvent != IntPtr.Zero) { m_twain.DatEvent(TWAIN.DG.CONTROL, TWAIN.MSG.PROCESSEVENT, ref twevent); Marshal.FreeHGlobal(twevent.pEvent); } } // Scoot... return (TWAIN.STS.SUCCESS); } // All done... return (TWAIN.STS.SUCCESS); } #endregion // Private Methods (commands) #region Private Methods (commands) /// /// Allocate a handle or a pointer, we'll get an IntPtr to it... /// /// tokenized command and anything needed /// true to quit private bool CmdAllocate(ref Interpreter.FunctionArguments a_functionarguments) { bool blResult; bool blGlobal; int iBytes; string szValue; UInt32 u32Bytes = 0; IntPtr intptr = IntPtr.Zero; CallStack callstack = m_lcallstack[m_lcallstack.Count - 1]; // Validate... if (a_functionarguments.aszCmd.Length != 4) { DisplayError("command needs 3 arguments", a_functionarguments); a_functionarguments.sts = TWAIN.STS.BADVALUE; a_functionarguments.szReturnValue = "0"; callstack.functionarguments.sts = a_functionarguments.sts; callstack.functionarguments.szReturnValue = a_functionarguments.szReturnValue; return (false); } // Get the size... if (!UInt32.TryParse(a_functionarguments.aszCmd[3], out u32Bytes)) { DisplayError("size is not a number <" + a_functionarguments.aszCmd[3] + ">", a_functionarguments); a_functionarguments.sts = TWAIN.STS.BADVALUE; a_functionarguments.szReturnValue = "0"; callstack.functionarguments.sts = a_functionarguments.sts; callstack.functionarguments.szReturnValue = a_functionarguments.szReturnValue; SetVariable(a_functionarguments.aszCmd[2], "0", 0, VariableScope.Local); return (false); } // A heaping helping of paranoia... blResult = GetVariable(a_functionarguments.aszCmd[2], 0, out szValue, out iBytes, out blGlobal, VariableScope.Local); if (blResult) { if (szValue != "0") { DisplayError("memory leak <" + a_functionarguments.aszCmd[2] + ">", a_functionarguments); } } // Allocate a handle... if (a_functionarguments.aszCmd[1].ToLowerInvariant() == "handle") { // Allocate the memory... intptr = m_twain.DsmMemAlloc(u32Bytes); if (intptr == IntPtr.Zero) { DisplayError("allocation failed <" + a_functionarguments.aszCmd[2] + ">", a_functionarguments); a_functionarguments.sts = TWAIN.STS.LOWMEMORY; a_functionarguments.szReturnValue = "0"; callstack.functionarguments.sts = a_functionarguments.sts; callstack.functionarguments.szReturnValue = a_functionarguments.szReturnValue; SetVariable(a_functionarguments.aszCmd[2], "0", 0, VariableScope.Local); return (false); } } // Allocate a pointer... else if (a_functionarguments.aszCmd[1].ToLowerInvariant() == "pointer") { intptr = Marshal.AllocHGlobal((IntPtr)u32Bytes); if (intptr == IntPtr.Zero) { DisplayError("allocation failed <" + a_functionarguments.aszCmd[2] + ">", a_functionarguments); a_functionarguments.sts = TWAIN.STS.LOWMEMORY; a_functionarguments.szReturnValue = "0"; callstack.functionarguments.sts = a_functionarguments.sts; callstack.functionarguments.szReturnValue = a_functionarguments.szReturnValue; SetVariable(a_functionarguments.aszCmd[2], "0", 0, VariableScope.Local); return (false); } } // Oops... else { DisplayError("unrecognized flag <" + a_functionarguments.aszCmd[1] + ">", a_functionarguments); a_functionarguments.sts = TWAIN.STS.BADVALUE; a_functionarguments.szReturnValue = "0"; callstack.functionarguments.sts = a_functionarguments.sts; callstack.functionarguments.szReturnValue = a_functionarguments.szReturnValue; return (false); } // All done... a_functionarguments.sts = TWAIN.STS.SUCCESS; a_functionarguments.szReturnValue = intptr.ToString(); callstack.functionarguments.sts = a_functionarguments.sts; callstack.functionarguments.szReturnValue = a_functionarguments.szReturnValue; SetVariable(a_functionarguments.aszCmd[2], intptr.ToString(), (int)u32Bytes, VariableScope.Local); return (false); } /// /// Call a function... /// /// tokenized command and anything needed /// true to quitFree private bool CmdCall(ref Interpreter.FunctionArguments a_functionarguments) { int iLine; string szLabel; // Validate... if ( (a_functionarguments.aszScript == null) || (a_functionarguments.aszScript.Length < 2) || (a_functionarguments.aszScript[0] == null) || (a_functionarguments.aszCmd == null) || (a_functionarguments.aszCmd.Length < 2) || (a_functionarguments.aszCmd[1] == null)) { return (false); } // Search for a match... szLabel = ":" + a_functionarguments.aszCmd[1]; for (iLine = 0; iLine < a_functionarguments.aszScript.Length; iLine++) { if (a_functionarguments.aszScript[iLine].Trim() == szLabel) { // We need this to go to the function... a_functionarguments.blGotoLabel = true; a_functionarguments.iLabelLine = iLine; // We need this to get back... CallStack callstack = default(CallStack); callstack.functionarguments = a_functionarguments; m_lcallstack.Add(callstack); return (false); } } // Ugh... DisplayError("function label not found: <" + szLabel + ">", a_functionarguments); return (false); } /// /// Show or set the current directory... /// /// tokenized command and anything needed /// true to quit private bool CmdCd(ref Interpreter.FunctionArguments a_functionarguments) { // No data... if ((a_functionarguments.aszCmd == null) || (a_functionarguments.aszCmd.Length < 2) || (a_functionarguments.aszCmd[1] == null) || (a_functionarguments.aszCmd[0].ToLowerInvariant() == "pwd")) { Display(Directory.GetCurrentDirectory(), true); return (false); } // Ruh-roh... if (!Directory.Exists(a_functionarguments.aszCmd[1])) { DisplayError("cd failed - path not found", a_functionarguments); return (false); } // Set the current directory... try { Directory.SetCurrentDirectory(a_functionarguments.aszCmd[1]); } catch (Exception exception) { DisplayError("cd failed - " + exception.Message, a_functionarguments); } // All done... return (false); } /// /// Clean the images folder... /// /// tokenized command and anything needed /// true to quit private bool CmdClean(ref Interpreter.FunctionArguments a_functionarguments) { // The images folder... string szImagesFolder = Path.Combine(Config.Get("writeFolder", null), "images"); // Delete the images folder... if (Directory.Exists(szImagesFolder)) { try { DirectoryInfo directoryinfo = new DirectoryInfo(szImagesFolder); foreach (System.IO.FileInfo file in directoryinfo.GetFiles()) file.Delete(); foreach (System.IO.DirectoryInfo subDirectory in directoryinfo.GetDirectories()) subDirectory.Delete(true); } catch (Exception exception) { DisplayError("couldn't delete <" + szImagesFolder + "> - " + exception.Message, a_functionarguments); return (false); } } // All done... return (false); } /// /// Copy string bytes in and out of unmanaged memory... /// /// tokenized command and anything needed /// true to quit private bool CmdCopyBytes(ref Interpreter.FunctionArguments a_functionarguments) { bool blGlobal; int iBytes; string szStringVariable; string szStringValue; IntPtr intptrHandle; IntPtr intptrPointer; UInt64 u64Handle; // Validate... if ((a_functionarguments.aszCmd == null) || (a_functionarguments.aszCmd.Length < 5) || (a_functionarguments.aszCmd[0] == null)) { DisplayError("copybytes needs five arguments", a_functionarguments); return (false); } // Figure out what we're copying in and out of... switch (a_functionarguments.aszCmd[1].ToLowerInvariant()) { // Eh? default: DisplayError("bad mode", a_functionarguments); return (false); // Copy from a handle to utf8, and then to a string... case "handleutf8": // Get the argument values... if (!UInt64.TryParse(a_functionarguments.aszCmd[2], out u64Handle)) { DisplayError("bad handle", a_functionarguments); return (false); } if (!int.TryParse(a_functionarguments.aszCmd[3], out iBytes)) { DisplayError("bad handle size", a_functionarguments); return (false); } intptrHandle = (IntPtr)u64Handle; szStringVariable = a_functionarguments.aszCmd[4]; // Do the copy... if ((intptrHandle != IntPtr.Zero) && (iBytes > 0)) { byte[] abValue = new byte[iBytes]; intptrPointer = m_twain.DsmMemLock(intptrHandle); if (intptrPointer == IntPtr.Zero) { DisplayError("DsmMemLock failed", a_functionarguments); return (false); } Marshal.Copy(intptrPointer, abValue, 0, iBytes); m_twain.DsmMemUnlock(intptrHandle); szStringValue = Encoding.UTF8.GetString(abValue); szStringValue = szStringValue.Replace("\0", ""); SetVariable(szStringVariable, szStringValue, 0); } return (false); // Copy from a string to utf8, and then to a handle... case "utf8handle": // Get the argument values... szStringVariable = a_functionarguments.aszCmd[2]; GetVariable(szStringVariable, -1, out szStringValue, out iBytes, out blGlobal); if (!UInt64.TryParse(a_functionarguments.aszCmd[3], out u64Handle)) { DisplayError("bad handle", a_functionarguments); return (false); } if (!int.TryParse(a_functionarguments.aszCmd[4], out iBytes)) { DisplayError("bad handle size", a_functionarguments); return (false); } intptrHandle = (IntPtr)u64Handle; // Do the copy... if ((szStringValue.Length > 0) && (intptrHandle != IntPtr.Zero) && (iBytes > 0)) { byte[] abValue = Encoding.UTF8.GetBytes(szStringValue); if (abValue.Length > iBytes) { DisplayError("handle is too small", a_functionarguments); return (false); } intptrPointer = m_twain.DsmMemLock(intptrHandle); if (intptrPointer == IntPtr.Zero) { DisplayError("DsmMemLock failed", a_functionarguments); return (false); } Marshal.Copy(abValue, 0, intptrPointer, abValue.Length); m_twain.DsmMemUnlock(intptrHandle); } return (false); } } /// /// Lists the files and folders in the current directory... /// /// tokenized command and anything needed /// true to quit private bool CmdDir(ref Interpreter.FunctionArguments a_functionarguments) { // Get the folders... string[] aszFolders = Directory.GetDirectories("."); if ((aszFolders != null) && (aszFolders.Length > 0)) { Array.Sort(aszFolders); foreach (string sz in aszFolders) { Display(sz.Replace(".\\","").Replace("./","") + Path.DirectorySeparatorChar); } } // Get the files... string[] aszFiles = Directory.GetFiles("."); if ((aszFiles != null) && (aszFiles.Length > 0)) { Array.Sort(aszFiles); foreach (string sz in aszFiles) { Display(sz.Replace(".\\", "").Replace("./", "")); } } // All done... return (false); } /// /// Echo text... /// /// tokenized command and anything needed /// true to quit private bool CmdEcho(ref Interpreter.FunctionArguments a_functionarguments) { return (CmdEchoColor(ref a_functionarguments, ConsoleColor.White)); } /// /// Echo text as blue... /// /// tokenized command and anything needed /// true to quit private bool CmdEchoBlue(ref Interpreter.FunctionArguments a_functionarguments) { return (CmdEchoColor(ref a_functionarguments, m_consolecolorBlue)); } /// /// Echo text as green... /// /// tokenized command and anything needed /// true to quit private bool CmdEchoGreen(ref Interpreter.FunctionArguments a_functionarguments) { return (CmdEchoColor(ref a_functionarguments, m_consolecolorGreen)); } /// /// Echo text as red... /// /// tokenized command and anything needed /// true to quit private bool CmdEchoRed(ref Interpreter.FunctionArguments a_functionarguments) { return (CmdEchoColor(ref a_functionarguments, m_consolecolorRed)); } /// /// Echo text as yellow... /// /// tokenized command and anything needed /// true to quit private bool CmdEchoYellow(ref Interpreter.FunctionArguments a_functionarguments) { return (CmdEchoColor(ref a_functionarguments, m_consolecolorYellow)); } /// /// Echo text as white... /// /// tokenized command and anything needed /// true to quit private bool CmdEchoColor(ref Interpreter.FunctionArguments a_functionarguments, ConsoleColor a_consolecolor) { int ii; string szLine = ""; string[] aszCmd; // No data... if ((a_functionarguments.aszCmd == null) || (a_functionarguments.aszCmd.Length < 2) || (a_functionarguments.aszCmd[0] == null)) { Display("", true); return (false); } // Copy the array... aszCmd = new string[a_functionarguments.aszCmd.Length]; Array.Copy(a_functionarguments.aszCmd, aszCmd, a_functionarguments.aszCmd.Length); // Expand the symbols... Expansion(a_functionarguments, ref aszCmd); // Turn it into a line... for (ii = 1; ii < aszCmd.Length; ii++) { szLine += ((szLine == "") ? "" : " ") + aszCmd[ii]; } // Spit it out... switch (a_consolecolor) { default: Display(szLine, true); break; case ConsoleColor.Blue: DisplayBlue(szLine, true); break; case ConsoleColor.Green: DisplayGreen(szLine, true); break; case ConsoleColor.Red: DisplayRed(szLine, true); break; case ConsoleColor.Yellow: DisplayYellow(szLine, true); break; } // All done... return (false); } /// /// Display a pass/fail message... /// /// tokenized command and anything needed /// true to quit private bool CmdEchoPassfail(ref Interpreter.FunctionArguments a_functionarguments) { string szLine; string szDots = ".........................................................................................................."; // No data... if ((a_functionarguments.aszCmd == null) || (a_functionarguments.aszCmd.Length < 3) || (a_functionarguments.aszCmd[0] == null)) { DisplayError("echo.passfail needs two arguments", a_functionarguments); return (false); } // Build the string... szLine = a_functionarguments.aszCmd[1].TrimEnd(); if ((szDots.Length - szLine.Length) > 0) { szLine += szDots.Substring(0, szDots.Length - szLine.Length); } else { szLine += "..."; } szLine += a_functionarguments.aszCmd[2]; // Spit it out... if (a_functionarguments.aszCmd[2].Contains("fail") || a_functionarguments.aszCmd[2].Contains("error")) { DisplayRed(szLine, true); } else if (a_functionarguments.aszCmd[2].Contains("warn")) { DisplayYellow(szLine, true); } else { Display(szLine, true); } // All done... return (false); } /// /// Display a progress message... /// /// tokenized command and anything needed /// true to quit private bool CmdEchoProgress(ref Interpreter.FunctionArguments a_functionarguments) { string szLine; string szDots = ".............................."; // No data... if ((a_functionarguments.aszCmd == null) || (a_functionarguments.aszCmd.Length < 3) || (a_functionarguments.aszCmd[0] == null)) { DisplayError("echo.progress needs two arguments", a_functionarguments); return (false); } // Build the string... szLine = a_functionarguments.aszCmd[1].TrimEnd(); if ((szDots.Length - szLine.Length) > 0) { szLine += szDots.Substring(0, szDots.Length - szLine.Length); } else { szLine += "..."; // mininum separation if we can't fit the left side in szDots } szLine += a_functionarguments.aszCmd[2]; // Spit it out... Display(szLine, true); // All done... return (false); } /// /// Echo text as red... /// /// tokenized command and anything needed /// true to quit private bool CmdEchoPrompt(ref Interpreter.FunctionArguments a_functionarguments) { return (CmdEchoColor(ref a_functionarguments, m_consolecolorGreen)); } /// /// Display a title suite message... /// /// tokenized command and anything needed /// true to quit private bool CmdEchoTitlesuite(ref Interpreter.FunctionArguments a_functionarguments) { string szStars = "**************************************************************************************************************"; // No data... if ((a_functionarguments.aszCmd == null) || (a_functionarguments.aszCmd.Length < 2) || (a_functionarguments.aszCmd[0] == null)) { DisplayError("echo.titlesuite needs one argument", a_functionarguments); return (false); } // Display it... DisplayYellow("", true); DisplayYellow("", true); DisplayYellow("", true); DisplayYellow(szStars, true); DisplayYellow(a_functionarguments.aszCmd[1], true); // All done... return (false); } /// /// Display a title test message... /// /// tokenized command and anything needed /// true to quit private bool CmdEchoTitletest(ref Interpreter.FunctionArguments a_functionarguments) { int ii; int iBlankLines = 3; // No data... if ((a_functionarguments.aszCmd == null) || (a_functionarguments.aszCmd.Length < 2) || (a_functionarguments.aszCmd[0] == null)) { DisplayError("echo.titletest needs one argument", a_functionarguments); return (false); } // Override the number of blank lines... if (a_functionarguments.aszCmd.Length >= 3) { int.TryParse(a_functionarguments.aszCmd[2], out iBlankLines); } // Display it... for (ii = 0; ii < iBlankLines; ii++) { DisplayYellow("", true); } DisplayYellow(a_functionarguments.aszCmd[1], true); // All done... return (false); } /// /// Write data to a file... /// /// tokenized command and anything needed /// true to quit private bool CmdFileWrite(ref Interpreter.FunctionArguments a_functionarguments) { string szFilename; string szValue; CallStack callstack = m_lcallstack[m_lcallstack.Count - 1]; // Validate... if (a_functionarguments.aszCmd.Length != 3) { DisplayError("command needs two arguments, file and value", a_functionarguments); return (false); } // Get the filename and the value... szFilename = a_functionarguments.aszCmd[1]; szValue = a_functionarguments.aszCmd[2]; // Write the value to the file... try { File.WriteAllText(szFilename, szValue); } catch { return (false); } // All done... return (false); } /// /// Free a handle or a pointer... /// /// tokenized command and anything needed /// true to quit private bool CmdFree(ref Interpreter.FunctionArguments a_functionarguments) { UInt64 u64IntPtr = 0; IntPtr intptr = IntPtr.Zero; CallStack callstack = m_lcallstack[m_lcallstack.Count - 1]; // Validate... if (a_functionarguments.aszCmd.Length != 3) { DisplayError("command needs 3 arguments", a_functionarguments); a_functionarguments.sts = TWAIN.STS.BADVALUE; a_functionarguments.szReturnValue = ""; callstack.functionarguments.sts = a_functionarguments.sts; callstack.functionarguments.szReturnValue = a_functionarguments.szReturnValue; return (false); } // Get the handle or pointer from the variable... bool blGlobal = false; KeyValue keyvalue = default(KeyValue); keyvalue.szKey = a_functionarguments.aszCmd[2]; if (!GetVariable(keyvalue.szKey, -1, out keyvalue.szValue, out keyvalue.iBytes, out blGlobal, VariableScope.Local)) { DisplayError("variable not found (make sure to set it to 0 at the top of the function)", a_functionarguments); a_functionarguments.sts = TWAIN.STS.BADVALUE; a_functionarguments.szReturnValue = ""; callstack.functionarguments.sts = a_functionarguments.sts; callstack.functionarguments.szReturnValue = a_functionarguments.szReturnValue; return (false); } // Get the value... if (!UInt64.TryParse(keyvalue.szValue, out u64IntPtr)) { a_functionarguments.sts = TWAIN.STS.BADVALUE; a_functionarguments.szReturnValue = "0"; callstack.functionarguments.sts = a_functionarguments.sts; callstack.functionarguments.szReturnValue = a_functionarguments.szReturnValue; return (false); } // If the value is non-zero, free it and clear the variable... if (u64IntPtr > 0) { if (a_functionarguments.aszCmd[1] == "handle") { intptr = (IntPtr)u64IntPtr; m_twain.DsmMemFree(ref intptr); } else if (a_functionarguments.aszCmd[1] == "pointer") { intptr = (IntPtr)u64IntPtr; Marshal.FreeHGlobal(intptr); } else { DisplayError("unrecognized flag <" + a_functionarguments.aszCmd[1] + ">", a_functionarguments); a_functionarguments.sts = TWAIN.STS.BADVALUE; a_functionarguments.szReturnValue = "0"; callstack.functionarguments.sts = a_functionarguments.sts; callstack.functionarguments.szReturnValue = a_functionarguments.szReturnValue; return (false); } } // All done (set the variable to 0)... a_functionarguments.sts = TWAIN.STS.SUCCESS; a_functionarguments.szReturnValue = ""; callstack.functionarguments.sts = a_functionarguments.sts; callstack.functionarguments.szReturnValue = a_functionarguments.szReturnValue; SetVariable(keyvalue.szKey, "0", 0, blGlobal ? VariableScope.Global : VariableScope.Local); return (false); } /// /// Garbage collection, used to freak out the system and catch /// bugs that linger in places, like the bonjour interface... /// /// tokenized command and anything needed /// true to quit private bool CmdGc(ref Interpreter.FunctionArguments a_functionarguments) { // Let's see if we can break things... GC.Collect(); // All done... return (false); } /// /// Goto the user... /// /// tokenized command and anything needed /// true to quit private bool CmdGoto(ref Interpreter.FunctionArguments a_functionarguments) { int iLine; string szLabel; // Validate... if ( (a_functionarguments.aszScript == null) || (a_functionarguments.aszScript.Length < 2) || (a_functionarguments.aszScript[0] == null) || (a_functionarguments.aszCmd == null) || (a_functionarguments.aszCmd.Length < 2) || (a_functionarguments.aszCmd[1] == null)) { return (false); } // Search for a match... szLabel = ":" + a_functionarguments.aszCmd[1]; for (iLine = 0; iLine < a_functionarguments.aszScript.Length; iLine++) { if (a_functionarguments.aszScript[iLine].Trim() == szLabel) { a_functionarguments.blGotoLabel = true; a_functionarguments.iLabelLine = iLine; return (false); } } // Ugh... DisplayError("goto label not found: <" + szLabel + ">", a_functionarguments); return (false); } /// /// Help the user... /// /// tokenized command and anything needed /// true to quit private bool CmdHelp(ref Interpreter.FunctionArguments a_functionarguments) { string szCommand; // Summary... if ((a_functionarguments.aszCmd == null) || (a_functionarguments.aszCmd.Length < 2) || (a_functionarguments.aszCmd[1] == null)) { Display(m_szBanner); Display(""); Display("Argumements in square brackets [] are optional, and don't have to be provided"); Display("to the command. Arguments in curly brackets must be provided."); Display(""); DisplayYellow("Overview"); Display("help intro......................................introduction to this program"); Display("help certification..............................certifying a scanner"); Display("help scripting..................................general discussion of scripting"); Display(""); DisplayYellow("Data Source Manager (DSM) commands"); Display("certify [productname] [verbose] [skipprompts]...certify a TWAIN driver"); Display("dsmload [args]..................................load the DSM"); Display("dsmunload.......................................unload the DSM"); Display("dsmentry........................................send a command to the DSM"); Display("help [command]..................................this text or info about a command"); Display("status..........................................status info for this program"); Display("wait [timeout]..................................wait for a DAT_NULL message"); Display("verbose [on|off|restore]........................verbosity of dsmentry"); Display(""); DisplayYellow("Scripting"); Display("allocate {flag} {variable} {size}...............allocate memory"); Display("call {label}....................................call function"); Display("cd [path].......................................shows or sets the current directory"); Display("clean...........................................clean the images folder"); Display("dir.............................................lists files and folders in the current directory"); Display("echo[.color] [text].............................echo text"); Display("echo.passfail {title} {result}..................echo test result in a tabular form"); Display("echo.progress {title} {result}..................echo progress in a tabular form"); Display("echo.prompt [text]..............................echo prior to using the input command"); Display("echo.titlesuite {title}.........................echo test suite"); Display("echo.titletest {title} [blank lines]............echo test title"); Display("filewrite {file} {value}........................write data to a file"); Display("free {flag} {variable}..........................free memory"); Display("goto {label}....................................jump to the :label in the script"); Display("if {item1} {operator} {item2} goto {label}......if statement"); Display("increment {dst} {src} [step]....................increment src by step and store in dst"); Display("input [text]....................................display text and wait for user input"); Display("json2xml {file|json}............................convert json formatted data to xml"); Display("log {info|warn|error,etc} text..................add a line to the log file"); Display("multiply {dst} {src} {multiplier}...............multiply src by multiplier and store in dst"); Display("pause [text]....................................display text and wait for ENTER key"); Display("pwd.............................................report the current working directory"); Display("report {initialize {driver}|save {folder}}......self certification report"); Display("return [status].................................return from call function"); Display("rollback [state#]...............................roll back to the desired state"); Display("run [script]....................................run a script"); Display("runv [script]...................................run a script verbosely"); Display("setglobal [key [value]].........................show, set, or delete global keys"); Display("setlocal [key [value]]..........................show, set, or delete local keys"); Display("sleep {milliseconds}............................pause the current thread"); return (false); } // Get the command... szCommand = a_functionarguments.aszCmd[1].ToLower(); // Overview #region Overview // Scripting... if ((szCommand == "intro")) { /////////0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789 DisplayYellow("INTRODUCTION TO THIS PROGRAM"); Display("The TWAIN Certification program is an interpreter that interacts with TWAIN scanners."); Display("It's main purpose is to run certification scripts testing compliance with the TWAIN"); Display("Specification. It can also be used to test individual TWAIN commands with a high"); Display("degree of granularity. User's should be prepared to snuggle up with a copy of the"); Display("TWAIN Specification if they want to get the most out of this program. The most current"); Display("version can be found at: https://twain.org"); Display(""); Display("For help with scripting enter 'help scripting'. It will also be instructive to look at the"); Display("certification scripts, which are extensive, and exercise most of this program's features."); Display(""); Display("For information about certifying scanners enter 'help certification'."); Display(""); Display("Commands that may be of special interest are (use help for more info):"); Display(" dsmload - load a DSM"); Display(" dsmunload - unload a DSM"); Display(" dsmentry - send a command to a DSM"); Display(" quit - exit from this program"); Display(" cd - change the current folder"); Display(" run [script] - with no arguments lists scripts, or run a script"); Display(""); Display("The command prompt includes what the certification tool regards as the current TWAIN state,"); Display("(ex: tw4>>>). It's important to remember that while this should match the TWAIN state in"); Display("the driver, there is no guarantee it is doing so."); return (false); } // Scripting... if ((szCommand == "certification") || (szCommand == "certify")) { /////////0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789 DisplayYellow("CERTIFYING A SCANNER"); Display("Certification is accomplished using scripts contained in the data/Certification folder. These"); Display("must be run for both 32-bit and 64-bit systems on all platforms supported by the driver."); Display(""); Display("The following command runs certification:"); Display(" certify [\"driver\"] [verbose] [skipprompts] [badges]"); Display(" Where,"); Display(" driver - the TW_IDENTITY.ProductName of a TWAIN driver"); Display(" verbose - if you want to see under the hood"); Display(" skipprompts - diagnostic, best used with simulators"); Display(" badges - all, barcode, imageaddress, patchcode, printing, twaindirect"); Display(""); Display("If no arguments are provided the command shows a list of the installed TWAIN driver and prompts"); Display("for which one to use. Follow the instructions to complete the process."); Display(""); Display("If debugging a problem the various scripts can be run separately. Manually run the Opends"); Display("script, and then the script you want to focus on. Or write a script that includes the items"); Display("that need testing. The output from verbose is included in the output file, so that can also"); Display("be a good place to start. Each of the badges comes with a certification script that can be"); Display("run standalone when diagnosing problems."); return (false); } // Scripting... if ((szCommand == "scripting")) { /////////0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789 DisplayYellow("GENERAL DISCUSSION OF SCRIPTING"); Display("The TWAIN Certification program is designed to test scanners. It looks at DAT objects. It's"); Display("script based to make it easier to manage the tests. Users can create and run their own tests,"); Display("such as extracting key items from an existing test to make it easier to debug."); Display(""); Display("The 'language' is not sophisticated. It supports a goto, a conditional goto, and a call and"); Display("run function. The set and increment commands manage variables. All of the TWAIN calls are"); Display("accessible, including some extras used to stress the system. Custom capabilities can be"); Display("accessed using numbers. Custom operations are not supported at this time (a flexible"); Display("marshalling system would be needed). The semicolon ';' is the comment indicator, it can appear"); Display("by itself or at the end of a line."); Display(""); Display("The most interesting part of the scripting support is variable expansion. Variables take the"); Display("form ${source:target} with the following available sources:"); Display(""); Display(" '${arg:[index:]target}'"); Display(" Expands an argument argument to run, runv, or call. A target of 0 is the name of the script"); Display(" or label; 1 - n accesses the rest of the arguments. An index can be specified to access any"); Display(" command in the stack, but only 0 is recommended to look at the last user command."); Display(""); Display(" '${app:[index]}'"); Display(" Complete TW_IDENTITY of the current application. Fields can be accessed with index."); Display(""); Display(" '${bits:}'"); Display(" 32 or 64."); Display(""); Display(" '${ds:[index]}'"); Display(" Complete TW_IDENTITY of the current scanner driver. Fields can be accessed with index."); Display(""); Display(" '${dsm:}'"); Display(" Full path to the current DSM, or an empty string if we don't currently have one."); Display(""); Display(" '${folder:target}'"); Display(" Resolves to the full path for a special folder indicated by target:"); Display(" certification - main certification folder"); Display(" certimages - folder to put images into"); Display(" data - data folder (in same folder as twaincscert.exe)"); Display(" desktop - user's desktop folder"); Display(" local - user's local temp folder"); Display(" parent - parent folder of the currently running script, or current folder"); Display(" pictures - user's pictures folder"); Display(" roaming - -user's roaming temp folder"); Display(""); Display(" '${format:specifier|value}'"); Display(" Formats the value according to the specifier."); Display(""); Display(" '${get:target}'"); Display(" The value last assigned to the target using the set command."); Display(""); Display(" '${getbytes:target:utf8}'"); Display(" Get the number of bytes when target is converted to UTF-8."); Display(""); Display(" '${gethandle:target:type:bytes}'"); Display(" Memlocks the target, and based on the type and the bytes converts the value to a string."); Display(" The lock is freed when done."); Display(""); Display(" '${gethandleindex:target:index:type}'"); Display(" Memlocks the target, and based on the type converts the value at the index"); Display(" to a string. The lock is freed when done."); Display(""); Display(" '${getindex:target:index}'"); Display(" Runs the target through CSV and returns the item at the requested index."); Display(""); Display(" '${gettwei:twei:target}'"); Display(" Look up a TWEI value in TWAINH.CS (ex: ${gettwei:TWEI_PIXELFLAVOR:TWPF_CHOCOLATE}. This"); Display(" is useful when processing data returned by DAT_EXTIMAGEINFO."); Display(""); Display(" '${localtime:[format]}'"); Display(" Returns the current local time using the DateTime format."); Display(""); Display(" '${platform:}'"); Display(" WINDOWS, LINUX, or MACOSX."); Display(""); Display(" '${program:}'"); Display(" Gets the name of the program running this script, its version, date, and machine word size."); Display(""); Display(" '${report:}'"); Display(" Full path to the generated self certification report (after 'report save command')."); Display(""); Display(" '${ret:[index]}'"); Display(" The value supplied to the return command that ended the last run, runv, or call. If an"); Display(" index is supplied the string is run through CSV and the indexed element is returned."); Display(""); Display(" '${sizeof:type}'"); Display(" Get the size of the item in bytes (ex: ${sizeof:TW_TWAINDIRECT})."); Display(""); Display(" '${state:}'"); Display(" The current TWAIN state (1 through 7)."); Display(""); Display(" '${sts:}'"); Display(" The TWAIN TWRC return code for the command. If the status was TWRC_FAILURE, this will"); Display(" contain the TWCC condition code."); Display(""); Display("Note that some tricks are allowed, one can do ${ret:${get:index}}, using the set and increment"); Display("increment commands to enumerate through all of the fields returned in a TW_* structure."); return (false); } #endregion // Data Source Manager (DSM) commands #region Data Source Manager (DSM) commands // Help... if ((szCommand == "help")) { DisplayYellow("HELP [COMMAND]"); Display("Provides assistence with command and their arguments. It does not"); Display("go into detail on TWAIN. Please read the Specification for more"); Display("information."); Display(""); Display("Curly brackets {} indicate mandatory arguments to a command. Square"); Display("brackets [] indicate optional arguments."); return (false); } // Dsmload... if ((szCommand == "dsmload")) { Assembly assembly = typeof(Terminal).Assembly; AssemblyName assemblyname = assembly.GetName(); Version version = assemblyname.Version; DisplayYellow("DSMLOAD"); Display("Load the Data Source Manager (DSM). This must be done before using"); Display("dsmentry. There are several arguments, which must be prefaced with"); Display("their name (format is name=value):"); Display(" manufacturer - tw_identity.Manufacturer (default='TWAIN Working Group')"); Display(" productfamily - tw_identity.ProductFamily (default='TWAIN Open Source')"); Display(" productname - tw_identity.ProductName (default='TWAIN Certification')"); Display(" protocolmajor - tw_identity.ProtocolMajor (default=TWON_PROTOCOLMAJOR)"); Display(" protocolminor - tw_identity.ProtocolMinor (default=TWON_PROTOCOLMINOR)"); Display(" supportedgroups - tw_identity.SupportedGroups (default=DG_APP2|DG_CONTROL|DG_IMAGE)"); Display(" twcy - tw_identity.Version.Country (default=TWCY_USA)"); Display(" info - tw_identity.Version.Info (default='TWAIN Certification')"); Display(" twlg - tw_identity.Version.Language (default=TWLG_ENGLISH)"); Display(" majornum - tw_identity.Version.MajorNum (default=" + version.Major + ")"); Display(" minornum - tw_identity.Version.MinorNum (default=" + version.Minor + ")"); Display(" uselegacydsm - true|false (default=false)"); Display(" usecallbacks - true|false (default=true, ignore if uselegacydsm is false)"); return (false); } // Dsmload... if ((szCommand == "dsmunload")) { DisplayYellow("DSMUNLOAD"); Display("Unload the Data Source Manager (DSM)."); return (false); } // Dsmentry... if ((szCommand == "dsmentry")) { DisplayYellow("DSMENTRY src dst dg dat msg memref"); Display("Send a command to the DSM with the following arguments:"); Display(" src - source of the message (this application)"); Display(" dst - destination, null for DSM commands, otherwise the Data Source"); Display(" dg - Data group (DG_*)"); Display(" dat - Data access type (DAT_*)"); Display(" msg - Message"); Display(" memref - the corresponding TW_* structure in CSV format"); Display(" "); Display("Most commands support MSG_GET which can be used to get a look at the"); Display("CSV format, which can be compared to the TW_* structure described in"); Display("the TWAIN Specification."); return (false); } // Verbose... if ((szCommand == "verbose [on|off|restore]")) { DisplayYellow("VERBOSE"); Display("Turns on verbosity output. Use this to see the dsmentry commmands"); Display("being generated by either the command line or scripts. It can be"); Display("turned on or off, or restored to the previous setting after being"); Display("set on or off. With no arguments it displays the current setting."); return (false); } // Wait... if ((szCommand == "wait [reset|timeout]")) { DisplayYellow("WAIT"); Display("Wait for a DSM_NULL message, such as MSG_XFERREADY. The message can"); Display("arrive through the message pump on Windows, or the callback system on"); Display("any of the platforms (assuming TWAINDSM is in use)."); Display(" "); Display("The reset argument clears any pending messages. It's recommended to"); Display("do this before calls transitioning to state 5."); Display(" "); Display("The timeout is optional. Specify it in milliseconds. If the timeout"); Display("is triggered the value of ${ret:} is 'timeout'."); Display(" "); Display("If one more messages are received they'll appear in ${ret:} as a comma"); Display("separated list (ex: 'MSG_XFERREADY')."); return (false); } // Quit... if ((szCommand == "quit")) { DisplayYellow("QUIT"); Display("Exit from this program."); return (false); } // Status... if ((szCommand == "status")) { DisplayYellow("STATUS"); Display("General information about the current operation of the program."); return (false); } #endregion // Scripting #region Scripting // Allocate... if ((szCommand == "allocate")) { DisplayYellow("ALLOCATE {HANDLE|POINTER} {VARIABLE} {SIZE}"); Display("Allocate a pointer or a handle of SIZE bytes and store the value in"); Display("the specified variable. On failure the value will be 0."); return (false); } // Call... else if ((szCommand == "call")) { DisplayYellow("CALL {FUNCTION [argument1 [argument2 [...]]}"); Display("Call a function with optional arguments. Check '${ret:} to see what the"); Display("function sent back with its RETURN command. The function must be prefixed"); Display("with a colon. For example..."); Display(" call XYZ"); Display(" ; the script will return here"); Display(" ..."); Display(" :XYZ"); Display(" return"); Display(""); Display("Gotos are easy to implement, and easy to script, but they can get out of"); Display("control fast. Keep functions small. And when doing a goto inside of a"); Display("function, use the function name as a prefix to help avoid reusing the same"); Display("label in more than one place. For example..."); Display(" call XYZ abc"); Display(" ; the script will return here"); Display(" ..."); Display(" :XYZ"); Display(" if '${arg:1}' == 'abc' goto XYZ.ABC"); Display(" return 'is not abc'"); Display(" :XYZ.ABC"); Display(" return 'is abc'"); return (false); } // Cd... if ((szCommand == "cd")) { DisplayYellow("CD [PATH]"); Display("Show the current directory. If a path is specified, change to that path."); return (false); } // Clean... if ((szCommand == "clean")) { DisplayYellow("CLEAN"); Display("Delete all files and folders in the images folder."); return (false); } // Dir... if ((szCommand == "dir")) { DisplayYellow("DIR"); Display("Directory command, lists files and folders in the current directory."); return (false); } // Echo... if ((szCommand == "echo")) { DisplayYellow("ECHO[.COLOR] [TEXT]"); Display("Echoes the text. If there is no text an empty line is echoed. The"); return (false); } // Echo.passfail... if ((szCommand == "echo.passfail")) { DisplayYellow("ECHO.PASSFAIL [TITLE] [RESULT]"); Display("Echoes the title and result in a long tabular format."); return (false); } // Echo.progress... if ((szCommand == "echo.progress")) { DisplayYellow("ECHO.PROGRESS [TITLE] [RESULT]"); Display("Echoes the title and result in a short tabular format."); return (false); } // Echo.progress... if ((szCommand == "echo.prompt")) { DisplayYellow("ECHO.PROMPT [TEXT]"); Display("Use prior to an input command."); return (false); } // Filewrite... if ((szCommand == "filewrite")) { DisplayYellow("FILEWRITE {FILE} {VALUE}"); Display("Write the value to a file."); return (false); } // Free... if ((szCommand == "free")) { DisplayYellow("FREE {HANDLE|POINTER} {VARIABLE}"); Display("Free a pointer or a handle in the specified variable. If it"); Display("is already 0, no action is taken. On success the variable is"); Display("set to 0."); return (false); } // Goto... if ((szCommand == "goto")) { DisplayYellow("GOTO {LABEL}"); Display("Jump to the specified label in the script. The label must be"); Display("prefixed with a colon. For example..."); Display(""); Display("Examples"); Display(" goto XYZ"); Display(" :XYZ"); return (false); } // If... if ((szCommand == "if")) { DisplayYellow("IF {ITEM1} {OPERATOR} {ITEM2} [OPERATOR2 ITEM3] GOTO {LABEL}"); Display("If the operator for ITEM1 and ITEM2 is true, then goto the"); Display("label. For the best experience get in the habit of putting"); Display("either single or double quotes around the items."); Display(""); Display("The & and | operators require the addition of a second operator"); Display("(== or !=)and a third item for comparison with the result of the"); Display("boolean operation."); Display(""); Display("Operators"); Display("==...........values are equal (case sensitive)"); Display("<............item1 is numerically less than item2"); Display("<=...........item1 is numerically less than or equal to item2"); Display(">............item1 is numerically greater than item2"); Display(">=...........item1 is numerically greater than or equal to item2"); Display("&............item1 AND item2 compared to item3"); Display("|............item1 OR item2 compared to item3"); Display("~~...........values are equal (case insensitive)"); Display("contains.....item2 is contained in item1 (case sensitive)"); Display("~contains....item2 is contained in item1 (case insensitive)"); Display("!=...........values are not equal (case sensitive)"); Display("!~...........values are not equal (case insensitive)"); Display("!contains....item2 is not contained in item1 (case sensitive)"); Display("!~contains...item2 is not contained in item1 (case sensitive)"); Display(""); Display("Items"); Display("See 'help scripting' for a list of the items that can be compared"); Display("in addition to literals."); Display(""); Display("Examples"); Display(" if '${sts:}' != 'SUCCESS' goto FAIL"); Display(" if '${get:value}' & '1' == '1' goto BITSET"); return (false); } // Image... if ((szCommand == "image")) { DisplayYellow("IMAGE {free} {variable}"); DisplayYellow("IMAGE {append} {variable} {TW_IMAGEMEMXFER}"); DisplayYellow("IMAGE {addheader} {variable} {TW_IMAGEINFO}"); DisplayYellow("IMAGE {delete} {folder}"); DisplayYellow("IMAGE {save} {variable} {native|memfile|memory} {filename}"); Display("Use image append to chain together data from one or more DAT_IMAGEMEMXFER"); Display("or DAT_IMAGEMEMFILEXFER calls. Use image free to free that memory when"); Display("done with it."); Display(""); Display("Use image save to save an image to disk. You can use the return value from"); Display("DAT_IMAGENATIVEXFER to save a .bmp bitmap file. If an extension isn't given"); Display("one will be provided: .bmp, .jpg, or .tif. Use image cleanfolder to specify"); Display("a folder where .bmp, .jpg, and .tif files will be removed."); Display(""); Display("Examples"); Display(" image append mymemoryimage '${get:twimagememxfer}'"); Display(" image addheader mymemoryimage '${get:twimageinfo}'"); Display(" image save mymemoryimage memfile ./myfile"); Display(" image free mymemoryimage"); Display(""); Display(" image save twmemref memfile ./myfile"); Display(""); Display(" image append mymemfileimage '${get:twimagememxfer}'"); Display(" image save mymemfileimage memfile ./myfile"); Display(" image free mymemfileimage"); Display(""); return (false); } // Increment... if ((szCommand == "increment")) { DisplayYellow("INCREMENT {DST} {SRC} [STEP]"); Display("Increments SRC by STEP and stores in DST. STEP defaults to 1."); return (false); } // Input... if ((szCommand == "input")) { DisplayYellow("INPUT [TITLE]"); Display("Echoes the text and waits for user input, which is complete when the ENTER"); Display("key is pressed. The input can be retrieved from ${ret:}"); return (false); } // Multiply... if ((szCommand == "multiply")) { DisplayYellow("MULTIPLY {DST} {SRC} {MULTIPLIER}"); Display("Multiplies SRC by MUTIPLIER and stores in DST."); return (false); } // Pause... if ((szCommand == "pause")) { DisplayYellow("PAUSE [TITLE]"); Display("Echoes the text and waits for the ENTER key to be pressed."); return (false); } // pwd... if ((szCommand == "pwd")) { DisplayYellow("PWD"); Display("Show the path to the current working directory."); return (false); } // Report... if ((szCommand == "report")) { DisplayYellow("REPORT {INITIALIZE | SAVE {FOLDER}}"); Display("Initialize or save a self certification report."); return (false); } // Return... if ((szCommand == "return")) { DisplayYellow("RETURN [DATA]"); Display("Return data from a call function or a script invoked with RUN or"); Display("RUNV. The caller examines this value with the '${ret:}' symbol."); return (false); } // Rollback if ((szCommand == "rollback")) { DisplayYellow("ROLLBACK [SCRIPT#]"); Display("With no argument it displays the current state. With an argument"); Display("it rolls back both the application and the driver to the desired"); Display("state. This should only be used when handling errors, to get back"); Display("to a known state. Otherwise it's better to use the normal TWAIN"); Display("calls to change state."); return (false); } // Run... if ((szCommand == "run")) { DisplayYellow("RUN [SCRIPT]"); Display("Runs the specified script. SCRIPT is the full path to the script"); Display("to be run. If a SCRIPT is not specified, the scripts in the"); Display("current folder are listed."); return (false); } // Run verbose... if ((szCommand == "runv")) { DisplayYellow("RUNV [SCRIPT]"); Display("Runs the specified script. SCRIPT is the full path to the script"); Display("to be run. If a SCRIPT is not specified, the scripts in the"); Display("current folder are listed. The script commands are displayed."); return (false); } // Set... if ((szCommand == "setglobal")) { DisplayYellow("SETGLOBAL {KEY} {VALUE}"); Display("Set a key to the specified value. If a KEY is not specified"); Display("all of the current keys are listed with their values. These"); Display("are global to all scripts. Use SETLOCAL when possible to"); Display("prevent names from colliding."); Display(""); Display("Values"); Display("See 'help scripting' for information about the kinds of values"); Display("that can be accessed in addition to simple literals."); return (false); } // Setlocal... if ((szCommand == "setlocal")) { DisplayYellow("SETLOCAL {KEY} {VALUE}"); Display("Set a key to the specified value. If a KEY is not specified"); Display("all of the current keys are listed with their values. This"); Display("key only exists in the context of the current function. So"); Display("it's safe to use the same value across invokations of 'call'"); Display("or run, they won't interfere with each other. Use SETGLOBAL"); Display("command for values global to all scripts."); Display(""); Display("Values"); Display("See 'help scripting' for information about the kinds of values"); Display("that can be accessed in addition to simple literals."); return (false); } // Sleep... if ((szCommand == "sleep")) { DisplayYellow("SLEEP {MILLISECONDS}"); Display("Pause the thread for the specified number of milliseconds."); return (false); } #endregion // Well, this ain't good... DisplayError("unrecognized command: " + a_functionarguments.aszCmd[1], a_functionarguments); // All done... return (false); } /// /// Certify a TWAIN driver... /// /// tokenized command and anything needed /// true to quit private bool CmdCertify(ref Interpreter.FunctionArguments a_functionarguments) { bool blDeveloper = false; bool blRunningScriptRestore = m_blRunningScript; bool blVerboseRestore = m_blVerbose; bool blTwainSuccess = false; string szBadges = ""; string szSelection = ""; Interpreter interpreter = new Interpreter("", m_consolecolorDefault, m_consolecolorGreen); // Gotta pretend we're in a script... m_blRunningScript = true; // Make sure skipprompts is off and badges is empty... SetVariable("g_skipprompts", "", 0, VariableScope.Global); SetVariable("g_badges", "", 0, VariableScope.Global); // If we have arguments, drop them in... if ((a_functionarguments.aszCmd != null) && (a_functionarguments.aszCmd.Length > 1) && (a_functionarguments.aszCmd[1] != null)) { for (int aa = 1; aa < a_functionarguments.aszCmd.Length; aa++) { if (a_functionarguments.aszCmd[aa].ToLowerInvariant() == "verbose") { m_blVerbose = true; } else if (a_functionarguments.aszCmd[aa].ToLowerInvariant() == "skipprompts") { SetVariable("g_skipprompts", "true", 0, VariableScope.Global); } else if (a_functionarguments.aszCmd[aa].ToLowerInvariant() == "all") { szBadges = "all"; } else if (a_functionarguments.aszCmd[aa].ToLowerInvariant() == "barcode") { if ((szBadges != "all") && !("," + szBadges + ",").Contains(",barcode,")) { szBadges += string.IsNullOrEmpty(szBadges) ? "barcode" : ",barcode"; } } else if (a_functionarguments.aszCmd[aa].ToLowerInvariant() == "imageaddress") { if ((szBadges != "all") && !("," + szBadges + ",").Contains(",imageaddress,")) { szBadges += string.IsNullOrEmpty(szBadges) ? "imageaddress" : ",imageaddress"; } } else if (a_functionarguments.aszCmd[aa].ToLowerInvariant() == "patchcode") { if ((szBadges != "all") && !("," + szBadges + ",").Contains(",patchcode,")) { szBadges += string.IsNullOrEmpty(szBadges) ? "patchcode" : ",patchcode"; } } else if (a_functionarguments.aszCmd[aa].ToLowerInvariant() == "printing") { if ((szBadges != "all") && !("," + szBadges + ",").Contains(",printing,")) { szBadges += string.IsNullOrEmpty(szBadges) ? "printing" : ",printing"; } } else if (a_functionarguments.aszCmd[aa].ToLowerInvariant() == "twaindirect") { if ((szBadges != "all") && !("," + szBadges + ",").Contains(",twaindirect,")) { szBadges += string.IsNullOrEmpty(szBadges) ? "twaindirect" : ",twaindirect"; } } else { szSelection = a_functionarguments.aszCmd[aa]; } } if (!string.IsNullOrEmpty(szBadges)) { SetVariable("g_badges", szBadges, 0, VariableScope.Global); } } // Tell the user the plan... DisplayYellow("TWAIN Certification"); // Refresh the scripts... Display(""); if (!CreateTwainSelfCertDataFolder(true)) { DisplayRed("Failed to refresh the certification scripts, try manually deleting the 'TWAIN Self Certification' folder on your desktop..."); m_blRunningScript = blRunningScriptRestore; m_blVerbose = blVerboseRestore; return (false); } // Developer warning, release or debug folder detected, but not under the releases folder... string szLocation = Assembly.GetEntryAssembly().Location; if ( !szLocation.Contains(Path.DirectorySeparatorChar + "releases" + Path.DirectorySeparatorChar) && (szLocation.Contains(Path.DirectorySeparatorChar + "Debug" + Path.DirectorySeparatorChar) || szLocation.Contains(Path.DirectorySeparatorChar + "Release" + Path.DirectorySeparatorChar))) { DisplayYellow(" Developer environment detected..."); blDeveloper = true; } Display(""); // Info... Display(" This tool certifies TWAIN drivers. To complete certification it must be run on."); Display(" all platforms supported by the driver: Windows, Linux, macOS for 32-bit and 64-bit."); Display(""); Display(" The tool will ask for some information and begin the test, which only takes a"); Display(" few minutes to complete. On success the tool provides instructions on how to"); Display(" submit information about a TWAIN driver that has passed certification."); // Pick a scanner (putting this in a block to make it easier to read)... bool blNeedSelection = string.IsNullOrEmpty(szSelection); { List aszDrivers = new List(); Interpreter.FunctionArguments functionarguments; // Load the DSM... functionarguments = new Interpreter.FunctionArguments(); functionarguments.aszCmd = new string[] { "dsmload" }; CmdDsmLoad(ref functionarguments); if (functionarguments.sts != TWAIN.STS.SUCCESS) { Display(""); DisplayRed("dsmload error..."); m_blRunningScript = blRunningScriptRestore; m_blVerbose = blVerboseRestore; return (false); } // Open the DSM... functionarguments = new Interpreter.FunctionArguments(); functionarguments.aszCmd = new string[] { "dsmentry", "src", "null", "dg_control", "dat_parent", "msg_opendsm", "hwnd" }; CmdDsmEntry(ref functionarguments); if (functionarguments.sts != TWAIN.STS.SUCCESS) { Display(""); DisplayRed("dsmopen error..."); m_blRunningScript = blRunningScriptRestore; m_blVerbose = blVerboseRestore; return (false); } // Walk the driver list... functionarguments = new Interpreter.FunctionArguments(); functionarguments.aszCmd = new string[] { "dsmentry", "src", "null", "dg_control", "dat_identity", "msg_getfirst", "0,0,0,0,0,,0,0,0x0,,," }; while (true) { // Ask for this item... CmdDsmEntry(ref functionarguments); if (functionarguments.sts != TWAIN.STS.SUCCESS) { break; } // Parse out the data... string[] aszTwidentity = CSV.Parse(functionarguments.szReturnValue); if (aszTwidentity.Length == 12) { // ProductName / Version.MajorVersion / Version.MinorVersion if (aszTwidentity[1].Length == 1) aszTwidentity[1] = "0" + aszTwidentity[1]; if (aszTwidentity[2].Length == 1) aszTwidentity[2] = "0" + aszTwidentity[2]; aszDrivers.Add("\"" + aszTwidentity[11] + "\"," + "(v" + aszTwidentity[1] + "." + aszTwidentity[2] + ")"); } // Next entry... functionarguments = new Interpreter.FunctionArguments(); functionarguments.aszCmd = new string[] { "dsmentry", "src", "null", "dg_control", "dat_identity", "msg_getnext", "0,0,0,0,0,,0,0,0x0,,," }; } // Close the DSM... functionarguments = new Interpreter.FunctionArguments(); functionarguments.aszCmd = new string[] { "dsmentry", "src", "null", "dg_control", "dat_parent", "msg_closedsm", "hwnd" }; CmdDsmEntry(ref functionarguments); // Unload the DSM... functionarguments = new Interpreter.FunctionArguments(); functionarguments.aszCmd = new string[] { "dsmunload" }; CmdDsmUnload(ref functionarguments); // Ruh-roh... if (aszDrivers.Count == 0) { Display(""); DisplayRed("No drivers found..."); m_blRunningScript = blRunningScriptRestore; m_blVerbose = blVerboseRestore; return (false); } // Sort it... aszDrivers.Sort(); // What we found... if (blNeedSelection) { Display(""); DisplayYellow("Available TWAIN Drivers:"); foreach (string szDriver in aszDrivers) { string[] aszDriver = CSV.Parse(szDriver); Display(" " + aszDriver[0] + " " + aszDriver[1]); } } // Ask for a scanner... bool blFound = false; if (blNeedSelection) { Display(""); Display("Please enter the name of a scanner from the list above (or quit"); Display("to get out). Partial names are okay, as long as they are unique:"); } while (true) { if (blNeedSelection) { interpreter.SetPrompt("certify driver>>> "); szSelection = interpreter.Prompt(m_streamreaderConsole, 0); } if ( (szSelection.ToLowerInvariant() == "quit") || (szSelection.ToLowerInvariant() == "q")) { szSelection = ""; m_blRunningScript = blRunningScriptRestore; m_blVerbose = blVerboseRestore; return (false); } if (!string.IsNullOrEmpty(szSelection)) { // Do ends with first so that we can properly find // stuff like 1000 vs 1000X... foreach (string szDriver in aszDrivers) { string[] aszDriver = CSV.Parse(szDriver); if (aszDriver[0].ToLowerInvariant().EndsWith(szSelection.ToLowerInvariant())) { szSelection = szDriver; blFound = true; break; } } // Otherwise go for contains... if (!blFound) { foreach (string szDriver in aszDrivers) { string[] aszDriver = CSV.Parse(szDriver); if (aszDriver[0].ToLowerInvariant().Contains(szSelection.ToLowerInvariant())) { szSelection = szDriver; blFound = true; break; } } } // If we found something, then scoot... if (blFound) { break; } // If the user gave szSelection to us as an argument, then bail... if (!blNeedSelection) { break; } } // If the user gave szSelection to us as an argument, then bail... if (blNeedSelection) { DisplayRed("ProductName not found: <" + szSelection + ">"); Display("Running the certify command without arguments shows a list of the available scanners."); szSelection = ""; m_blRunningScript = blRunningScriptRestore; m_blVerbose = blVerboseRestore; return (false); } } } // We're bailing... if (string.IsNullOrEmpty(szSelection)) { m_blRunningScript = blRunningScriptRestore; m_blVerbose = blVerboseRestore; return (false); } // Show the available badges so the user can pick one, if the user gave // the scanner on the command line, but not the badge, assume they don't // want to test any badges... if (string.IsNullOrEmpty(szBadges) && blNeedSelection) { // What we found... Display(""); DisplayYellow("Available TWAIN Badges:"); string[] aszBadges = "none,all,barcode,imageaddress,patchcode,printing,twaindirect".Split(new char[] { ',' }); foreach (string szBadge in aszBadges) { Display(" " + szBadge); } // Ask for a zero or more badges... Display(""); Display("Please enter a comma separated list with one or zero or more "); Display("badges from the list above (or quit to get out). Partial names"); Display("are okay as long as they are unique)"); while (true) { interpreter.SetPrompt("badges>>> "); szBadges = interpreter.Prompt(m_streamreaderConsole, 0); if ( (szBadges.ToLowerInvariant() == "quit") || (szBadges.ToLowerInvariant() == "q")) { szSelection = ""; // so we know we're quitting... szBadges = ""; m_blRunningScript = blRunningScriptRestore; m_blVerbose = blVerboseRestore; return (false); } szBadges = szBadges.Replace(" ", ""); if (szBadges.Length > 0) { string szFound = ""; string szResult = ""; // Turn whatever the user gave us into a valid list that we'll // use to update szBadges... foreach (string szBadge in szBadges.Split(new char[] { ',' })) { int iFound = 0; // Look for a match... foreach (string sz in aszBadges) { if (sz.StartsWith(szBadge)) { iFound += 1; szFound = sz; } } // If found isn't 1 we have a problem... if (iFound != 1) { szResult = ""; Display("Unrecognized or ambiguous badge name."); break; } // If it's none, scoot without a badge... if (szFound == "none") { szResult = "none"; break; } // If it's all, scoot with just all... if (szFound == "all") { szResult = "all"; break; } // We already have it... if (!string.IsNullOrEmpty(szResult) && ("," + szResult + ",").Contains("," + szFound + ",")) { continue; } // Add it to our list... szResult = szResult + (string.IsNullOrEmpty(szResult) ? szFound : "," + szFound); } // Grab the result, this is the badge list we'll go with... if (!string.IsNullOrEmpty(szResult)) { szBadges = szResult; if (szBadges == "none") { szBadges = ""; } break; } } } } // We're bailing... if (string.IsNullOrEmpty(szSelection)) { m_blRunningScript = blRunningScriptRestore; m_blVerbose = blVerboseRestore; return (false); } // Confirmation to proceed... Display(""); while (true) { // Parse and check the data... string[] aszDriver = CSV.Parse(szSelection); if (aszDriver.Length < 2) { DisplayRed("ProductName not found: <" + szSelection + ">"); Display("Running the certify command without arguments shows a list of the available scanners."); m_blRunningScript = blRunningScriptRestore; m_blVerbose = blVerboseRestore; return (false); } // Prompt the user to see if this is good... if (string.IsNullOrEmpty(szBadges)) { interpreter.SetPrompt("Certify '" + aszDriver[0] + " " + aszDriver[1] + "'" + " (yes/no)? "); } else { interpreter.SetPrompt("Certify '" + aszDriver[0] + " " + aszDriver[1] + "' with badges:" + szBadges + " (yes/no)? "); } string szAnswer = interpreter.Prompt(m_streamreaderConsole, 0); if (szAnswer.ToLowerInvariant().StartsWith("y")) { break; } else if (szAnswer.ToLowerInvariant().StartsWith("n")) { m_blRunningScript = blRunningScriptRestore; m_blVerbose = blVerboseRestore; return (false); } } // Let's do it! { string[] aszDriver = CSV.Parse(szSelection); m_szSelfCertDriverVersion = aszDriver[1]; Display(""); Display(""); Display(""); // If we're in the development tree, use the folder the binary is in... if (blDeveloper) { m_szSelfCertDataCertFolder = Path.Combine(Path.GetDirectoryName(Application.ExecutablePath), Path.Combine("data", "Certification")); Directory.SetCurrentDirectory(Path.GetDirectoryName(Application.ExecutablePath)); } // Otherwise use the 'Twain Self Certification' folder... else { m_szSelfCertDataCertFolder = Path.Combine(m_szTwainSelfCertFolder, Path.Combine("data", "Certification")); Directory.SetCurrentDirectory(m_szTwainSelfCertFolder); } // No joy... if (!Directory.Exists(m_szSelfCertDataCertFolder)) { Display(""); DisplayRed("Can't find our data/Certification folder, it should be in the"); DisplayRed("same folder as this application, or the current folder."); m_blRunningScript = blRunningScriptRestore; m_blVerbose = blVerboseRestore; m_szSelfCertDriverVersion = ""; return (false); } // Make a note of it... DisplayGreen("Using folder: " + m_szSelfCertDataCertFolder); Display(""); Display(""); Display(""); // Go there and fire up the intepreter... string szCurrentDirectory = Directory.GetCurrentDirectory(); Directory.SetCurrentDirectory(m_szSelfCertDataCertFolder); Interpreter.FunctionArguments functionarguments = new Interpreter.FunctionArguments(); functionarguments = new Interpreter.FunctionArguments(); if (m_blVerbose) { if (string.IsNullOrEmpty(szBadges)) { functionarguments.aszCmd = new string[4] { "runv", "certification", aszDriver[0], aszDriver[1] }; } else { functionarguments.aszCmd = new string[5] { "runv", "certification", aszDriver[0], aszDriver[1], szBadges }; } } else { if (string.IsNullOrEmpty(szBadges)) { functionarguments.aszCmd = new string[4] { "run", "certification", aszDriver[0], aszDriver[1] }; } else { functionarguments.aszCmd = new string[5] { "run", "certification", aszDriver[0], aszDriver[1], szBadges }; } } CmdRun(ref functionarguments); blTwainSuccess = (functionarguments.szReturnValue == "pass"); Directory.SetCurrentDirectory(szCurrentDirectory); } // Report successful results, and point the user to twaindirect.org... if (blTwainSuccess) { if (blDeveloper) { Display(""); Display(""); Display(""); DisplayYellow("TWAIN Certification passed..."); DisplayYellow("Developer environment detected..."); Display("Please rerun the latest released version of this program before submitting"); Display("the results. Users are free to confirm drivers on their own, so please"); Display("don't make changes to either the code or the script, unless that change is"); Display("part of an update that will be rolled into a new released version."); } else { Display(""); Display(""); Display(""); DisplayGreen("TWAIN Certification passed..."); Display("If you are the manufacturer of this driver, please go to the TWAIN website"); Display("at https://twain.org to register your scanner. There is a 'TWAIN Self"); Display("Certification' folder on your desktop that contains the report for this run."); Display("This information does not have to be sent, but it is suggested that you keep"); Display("a copy in your records."); } } // Report unsuccessful results, and point the user to twaindirect.org... else { Display(""); Display(""); Display(""); DisplayRed("TWAIN Certification failed..."); Display("Please refer to the log files in the 'TWAIN Self Certification' folder on your"); Display("desktop for additional information."); } // All done... m_blRunningScript = blRunningScriptRestore; m_blVerbose = blVerboseRestore; m_szSelfCertDriverVersion = ""; return (false); } /// /// Process an if-statement... /// /// tokenized command and anything needed /// true to quit private bool CmdIf(ref Interpreter.FunctionArguments a_functionarguments) { int iAction = 0; bool blDoAction = false; string szItem1 = ""; string szItem2 = ""; string szItem3 = ""; string szOperator = ""; string szOperator2 = ""; // Protection... if ((a_functionarguments.aszCmd == null) || (a_functionarguments.aszCmd.Length < 3) || (a_functionarguments.aszCmd[1] == null)) { DisplayError("badly formed if-statement", a_functionarguments); return (false); } // Get all of the stuff (logical operators need more)... if ( (a_functionarguments.aszCmd[2] == "&") || (a_functionarguments.aszCmd[2] == "|")) { if ((a_functionarguments.aszCmd == null) || (a_functionarguments.aszCmd.Length < 7) || (a_functionarguments.aszCmd[1] == null)) { DisplayError("badly formed if-statement", a_functionarguments); return (false); } szItem1 = a_functionarguments.aszCmd[1]; szOperator = a_functionarguments.aszCmd[2]; szItem2 = a_functionarguments.aszCmd[3]; szOperator2 = a_functionarguments.aszCmd[4]; szItem3 = a_functionarguments.aszCmd[5]; iAction = 6; } // Everybody else needs less stuff... else { if ((a_functionarguments.aszCmd == null) || (a_functionarguments.aszCmd.Length < 5) || (a_functionarguments.aszCmd[1] == null)) { DisplayError("badly formed if-statement", a_functionarguments); return (false); } szItem1 = a_functionarguments.aszCmd[1]; szOperator = a_functionarguments.aszCmd[2]; szItem2 = a_functionarguments.aszCmd[3]; iAction = 4; } // Items must match (case sensitive)... if (szOperator == "==") { if (szItem1 == szItem2) { blDoAction = true; } } // Items must match (case insensitive)... else if (szOperator == "~~") { if (szItem1.ToLowerInvariant() == szItem2.ToLowerInvariant()) { blDoAction = true; } } // Items must not match (case sensitive)... else if (szOperator == "!=") { if (szItem1 != szItem2) { blDoAction = true; } } // Items must not match (case insensitive)... else if (szOperator == "!~") { if (szItem1.ToLowerInvariant() != szItem2.ToLowerInvariant()) { blDoAction = true; } } // Item1 > Item2... else if (szOperator == ">") { int iItem1; int iItem2; if (!int.TryParse(szItem1, out iItem1)) { DisplayError("<" + szItem1 + "> > <" + szItem2 + "> is invalid", a_functionarguments); } else { if (!int.TryParse(szItem2, out iItem2)) { DisplayError("<" + szItem1 + "> > <" + szItem2 + "> is invalid", a_functionarguments); } else { if (iItem1 > iItem2) { blDoAction = true; } } } } // Item1 >= Item2... else if (szOperator == ">=") { int iItem1; int iItem2; if (!int.TryParse(szItem1, out iItem1)) { DisplayError("<" + szItem1 + "> >= <" + szItem2 + "> is invalid", a_functionarguments); } else { if (!int.TryParse(szItem2, out iItem2)) { DisplayError("<" + szItem1 + "> >= <" + szItem2 + "> is invalid", a_functionarguments); } else { if (iItem1 >= iItem2) { blDoAction = true; } } } } // Item1 < Item2... else if (szOperator == "<") { int iItem1; int iItem2; if (!int.TryParse(szItem1, out iItem1)) { DisplayError("<" + szItem1 + "> < <" + szItem2 + "> is invalid", a_functionarguments); } else { if (!int.TryParse(szItem2, out iItem2)) { DisplayError("<" + szItem1 + "> < <" + szItem2 + "> is invalid", a_functionarguments); } else { if (iItem1 < iItem2) { blDoAction = true; } } } } // Item1 <= Item2... else if (szOperator == "<=") { int iItem1; int iItem2; if (!int.TryParse(szItem1, out iItem1)) { DisplayError("<" + szItem1 + "> <= <" + szItem2 + "> is invalid", a_functionarguments); } else { if (!int.TryParse(szItem2, out iItem2)) { DisplayError("<" + szItem1 + "> <= <" + szItem2 + "> is invalid", a_functionarguments); } else { if (iItem1 <= iItem2) { blDoAction = true; } } } } // Bit-wise AND, always compared to a target... else if (szOperator == "&") { int iAnd = 0; int iItem1 = 0; int iItem2 = 0; int iItem3 = 0; bool blItem1 = false; bool blItem2 = false; bool blItem3 = false; if (szItem1.ToLowerInvariant().StartsWith("0x")) { blItem1 = int.TryParse(szItem1.Substring(2), NumberStyles.HexNumber, CultureInfo.InvariantCulture, out iItem1); } else { blItem1 = int.TryParse(szItem1, out iItem1); } if (szItem2.ToLowerInvariant().StartsWith("0x")) { blItem2 = int.TryParse(szItem2.Substring(2), NumberStyles.HexNumber, CultureInfo.InvariantCulture, out iItem2); } else { blItem2 = int.TryParse(szItem2, out iItem2); } if (szItem3.ToLowerInvariant().StartsWith("0x")) { blItem3 = int.TryParse(szItem3.Substring(2), NumberStyles.HexNumber, CultureInfo.InvariantCulture, out iItem3); } else { blItem3 = int.TryParse(szItem3, out iItem3); } if (!blItem1 || !blItem2 || !blItem3) { DisplayError("badly formed if-statement...", a_functionarguments); return (false); } iAnd = iItem1 & iItem2; if ((szOperator2 == "==") && (iAnd == iItem3)) { blDoAction = true; } else if ((szOperator2 == "!=") && (iAnd != iItem3)) { blDoAction = true; } else { blDoAction = false; } } // Bit-wise OR, always compared to a target... else if (szOperator == "|") { int iOr = 0; int iItem1 = 0; int iItem2 = 0; int iItem3 = 0; bool blItem1 = false; bool blItem2 = false; bool blItem3 = false; if (szItem1.ToLowerInvariant().StartsWith("0x")) { blItem1 = int.TryParse(szItem1.Substring(2), NumberStyles.HexNumber, CultureInfo.InvariantCulture, out iItem1); } else { blItem1 = int.TryParse(szItem1, out iItem1); } if (szItem2.ToLowerInvariant().StartsWith("0x")) { blItem2 = int.TryParse(szItem2.Substring(2), NumberStyles.HexNumber, CultureInfo.InvariantCulture, out iItem2); } else { blItem2 = int.TryParse(szItem2, out iItem2); } if (szItem3.ToLowerInvariant().StartsWith("0x")) { blItem3 = int.TryParse(szItem3.Substring(2), NumberStyles.HexNumber, CultureInfo.InvariantCulture, out iItem3); } else { blItem3 = int.TryParse(szItem3, out iItem3); } if (!blItem1 || !blItem2 || !blItem3) { DisplayError("badly formed if-statement", a_functionarguments); return (false); } iOr = iItem1 | iItem2; if ((szOperator2 == "==") && (iOr == iItem3)) { blDoAction = true; } else if ((szOperator2 == "!=") && (iOr != iItem3)) { blDoAction = true; } else { blDoAction = false; } } // Item1 must contain items2 (case sensitive)... else if (szOperator == "contains") { if (szItem1.Contains(szItem2)) { blDoAction = true; } } // Item1 must contain items2 (case insensitive)... else if (szOperator == "~contains") { if (szItem1.ToLowerInvariant().Contains(szItem2.ToLowerInvariant())) { blDoAction = true; } } // Item1 must not contain items2 (case sensitive)... else if (szOperator == "!contains") { if (!szItem1.Contains(szItem2)) { blDoAction = true; } } // Item1 must not contain items2 (case insensitive)... else if (szOperator == "!~contains") { if (!szItem1.ToLowerInvariant().Contains(szItem2.ToLowerInvariant())) { blDoAction = true; } } // Unrecognized operator... else { DisplayError("unrecognized operator: <" + szOperator + ">", a_functionarguments); return (false); } // We've been told to do the action... if (blDoAction) { // We're doing a goto... if (a_functionarguments.aszCmd[iAction].ToLowerInvariant() == "goto") { int iLine; string szLabel; // Validate... if ((a_functionarguments.aszCmd.Length < (iAction + 1)) || string.IsNullOrEmpty(a_functionarguments.aszCmd[iAction + 1])) { DisplayError("goto label is missing...", a_functionarguments); return (false); } // Find the label... szLabel = ":" + a_functionarguments.aszCmd[iAction + 1]; for (iLine = 0; iLine < a_functionarguments.aszScript.Length; iLine++) { if (a_functionarguments.aszScript[iLine].Trim() == szLabel) { a_functionarguments.blGotoLabel = true; a_functionarguments.iLabelLine = iLine; return (false); } } // Ugh... DisplayError("goto label not found: <" + szLabel + ">", a_functionarguments); return (false); } // We have no idea what we're doing... else { DisplayError("unrecognized action: <" + a_functionarguments.aszCmd[iAction] + ">", a_functionarguments); return (false); } } // All done... return (false); } /// /// Manage an image byte array for DAT_IMAGEMEMXFER or DAT_IMAGEMEMFILEXFER... /// /// tokenized command and anything needed /// true to quit private bool CmdImage(ref Interpreter.FunctionArguments a_functionarguments) { int iResult = 0; int iHeaderBytes; UInt64 u64Ptr = 0; IntPtr intptrPtr = IntPtr.Zero; bool blGlobal = false; byte[] abImage = null; string szFolder = ""; string szFilename = ""; KeyValue keyvalue = default(KeyValue); TWAIN.TW_IMAGEINFO twimageinfo = default(TWAIN.TW_IMAGEINFO); TWAIN.TW_IMAGEMEMXFER twimagememxfer = default(TWAIN.TW_IMAGEMEMXFER); // Validate... if (a_functionarguments.aszCmd.Length < 2) { DisplayError("must specify an action for the image command", a_functionarguments); return (false); } // Pick an action... switch (a_functionarguments.aszCmd[1].ToLowerInvariant()) { // Oops... default: DisplayError("unrecognized action", a_functionarguments); return (false); // Add a header to data (this is always going to be TIFF)... case "addheader": // Validate if (a_functionarguments.aszCmd.Length < 4) { DisplayError("must specify a variable and tw_imageinfo data", a_functionarguments); return (false); } // Validate... keyvalue.szKey = a_functionarguments.aszCmd[2]; if (!TWAIN.CsvToImageinfo(ref twimageinfo, a_functionarguments.aszCmd[3])) { DisplayError("invalid tw_imageinfo data <" + a_functionarguments.aszCmd[3] + ">", a_functionarguments); return (false); } // Find the local value for this key... GetVariable(keyvalue.szKey, -1, out keyvalue.szValue, out keyvalue.iBytes, out blGlobal, VariableScope.Local); // If we got a pointer if (!UInt64.TryParse(keyvalue.szValue, out u64Ptr)) { DisplayError("bad pointer <" + keyvalue.szValue + ">", a_functionarguments); return (false); } // Ruh-roh... if (u64Ptr == 0) { DisplayError("null pointer <" + a_functionarguments.aszCmd[2] + ">", a_functionarguments); return (false); } // The pointer to our raw image data... intptrPtr = (IntPtr)u64Ptr; // Bitonal uncompressed... if (((TWAIN.TWPT)twimageinfo.PixelType == TWAIN.TWPT.BW) && ((TWAIN.TWCP)twimageinfo.Compression == TWAIN.TWCP.NONE)) { TWAIN.TiffBitonalUncompressed tiffbitonaluncompressed; tiffbitonaluncompressed = new TWAIN.TiffBitonalUncompressed((uint)twimageinfo.ImageWidth, (uint)twimageinfo.ImageLength, (uint)twimageinfo.XResolution.Whole, (uint)keyvalue.iBytes); intptrPtr = Marshal.ReAllocHGlobal(intptrPtr, (IntPtr)(Marshal.SizeOf(tiffbitonaluncompressed) + keyvalue.iBytes)); TWAIN.MemMove((IntPtr)((UInt64)intptrPtr + (UInt64)Marshal.SizeOf(tiffbitonaluncompressed)), intptrPtr, keyvalue.iBytes); Marshal.StructureToPtr(tiffbitonaluncompressed, intptrPtr, true); SetVariable(keyvalue.szKey, keyvalue.szValue, (int)(Marshal.SizeOf(tiffbitonaluncompressed) + keyvalue.iBytes), VariableScope.Local); } // Bitonal GROUP4... else if (((TWAIN.TWPT)twimageinfo.PixelType == TWAIN.TWPT.BW) && ((TWAIN.TWCP)twimageinfo.Compression == TWAIN.TWCP.GROUP4)) { TWAIN.TiffBitonalG4 tiffbitonalg4; tiffbitonalg4 = new TWAIN.TiffBitonalG4((uint)twimageinfo.ImageWidth, (uint)twimageinfo.ImageLength, (uint)twimageinfo.XResolution.Whole, (uint)keyvalue.iBytes); intptrPtr = Marshal.ReAllocHGlobal(intptrPtr, (IntPtr)(Marshal.SizeOf(tiffbitonalg4) + keyvalue.iBytes)); TWAIN.MemMove((IntPtr)((UInt64)intptrPtr + (UInt64)Marshal.SizeOf(tiffbitonalg4)), intptrPtr, keyvalue.iBytes); Marshal.StructureToPtr(tiffbitonalg4, intptrPtr, true); SetVariable(keyvalue.szKey, keyvalue.szValue, (int)(Marshal.SizeOf(tiffbitonalg4) + keyvalue.iBytes), VariableScope.Local); } // Gray uncompressed... else if (((TWAIN.TWPT)twimageinfo.PixelType == TWAIN.TWPT.GRAY) && ((TWAIN.TWCP)twimageinfo.Compression == TWAIN.TWCP.NONE)) { TWAIN.TiffGrayscaleUncompressed tiffgrayscaleuncompressed; tiffgrayscaleuncompressed = new TWAIN.TiffGrayscaleUncompressed((uint)twimageinfo.ImageWidth, (uint)twimageinfo.ImageLength, (uint)twimageinfo.XResolution.Whole, (uint)keyvalue.iBytes); intptrPtr = Marshal.ReAllocHGlobal(intptrPtr, (IntPtr)(Marshal.SizeOf(tiffgrayscaleuncompressed) + keyvalue.iBytes)); TWAIN.MemMove((IntPtr)((UInt64)intptrPtr + (UInt64)Marshal.SizeOf(tiffgrayscaleuncompressed)), intptrPtr, keyvalue.iBytes); Marshal.StructureToPtr(tiffgrayscaleuncompressed, intptrPtr, true); SetVariable(keyvalue.szKey, keyvalue.szValue, (int)(Marshal.SizeOf(tiffgrayscaleuncompressed) + keyvalue.iBytes), VariableScope.Local); } // Gray JPEG... else if (((TWAIN.TWPT)twimageinfo.PixelType == TWAIN.TWPT.GRAY) && ((TWAIN.TWCP)twimageinfo.Compression == TWAIN.TWCP.JPEG)) { // No work to be done, we'll output JPEG... } // RGB uncompressed... else if (((TWAIN.TWPT)twimageinfo.PixelType == TWAIN.TWPT.RGB) && ((TWAIN.TWCP)twimageinfo.Compression == TWAIN.TWCP.NONE)) { TWAIN.TiffColorUncompressed tiffcoloruncompressed; tiffcoloruncompressed = new TWAIN.TiffColorUncompressed((uint)twimageinfo.ImageWidth, (uint)twimageinfo.ImageLength, (uint)twimageinfo.XResolution.Whole, (uint)keyvalue.iBytes); intptrPtr = Marshal.ReAllocHGlobal(intptrPtr, (IntPtr)(Marshal.SizeOf(tiffcoloruncompressed) + keyvalue.iBytes)); TWAIN.MemMove((IntPtr)((UInt64)intptrPtr + (UInt64)Marshal.SizeOf(tiffcoloruncompressed)), intptrPtr, keyvalue.iBytes); Marshal.StructureToPtr(tiffcoloruncompressed, intptrPtr, true); SetVariable(keyvalue.szKey, keyvalue.szValue, (int)(Marshal.SizeOf(tiffcoloruncompressed) + keyvalue.iBytes), VariableScope.Local); } // RGB JPEG... else if (((TWAIN.TWPT)twimageinfo.PixelType == TWAIN.TWPT.RGB) && ((TWAIN.TWCP)twimageinfo.Compression == TWAIN.TWCP.JPEG)) { // No work to be done, we'll output JPEG... } // Oh well... else { DisplayError("unsupported format <" + twimageinfo.PixelType + "," + twimageinfo.Compression + ">", a_functionarguments); return (false); } return (false); // Append (grow the memory)... case "append": // Validate if (a_functionarguments.aszCmd.Length < 4) { DisplayError("must specify a variable and tw_imagememxfer data", a_functionarguments); return (false); } // Validate... keyvalue.szKey = a_functionarguments.aszCmd[2]; if (!TWAIN.CsvToImagememxfer(ref twimagememxfer, a_functionarguments.aszCmd[3])) { DisplayError("invalid tw_imagememxfer data <" + a_functionarguments.aszCmd[3] + ">", a_functionarguments); return (false); } // Validate the pointer... if (twimagememxfer.Memory.TheMem == IntPtr.Zero) { DisplayError("null tw_imagememxfer.memory.themem data <" + a_functionarguments.aszCmd[3] + ">", a_functionarguments); return (false); } // Only do this bit if there's something to do... if (twimagememxfer.BytesWritten > 0) { keyvalue.szKey = a_functionarguments.aszCmd[2]; GetVariable(keyvalue.szKey, -1, out keyvalue.szValue, out keyvalue.iBytes, out blGlobal, VariableScope.Local); if (string.IsNullOrEmpty(keyvalue.szValue) || UInt64.TryParse(keyvalue.szValue, out u64Ptr)) { // We're starting fresh... if (u64Ptr == 0) { intptrPtr = Marshal.AllocHGlobal((int)twimagememxfer.BytesWritten + 65536); if (intptrPtr == IntPtr.Zero) { DisplayError("alloc failed <" + a_functionarguments.aszCmd[3] + ">", a_functionarguments); return (false); } TWAIN.MemCpy(intptrPtr, twimagememxfer.Memory.TheMem, (int)twimagememxfer.BytesWritten); SetVariable(keyvalue.szKey, intptrPtr.ToString(), (int)twimagememxfer.BytesWritten, VariableScope.Local); } // We're appending... else { intptrPtr = (IntPtr)u64Ptr; intptrPtr = Marshal.ReAllocHGlobal(intptrPtr, (IntPtr)(keyvalue.iBytes + (int)twimagememxfer.BytesWritten + 65536)); if (intptrPtr == IntPtr.Zero) { DisplayError("alloc failed <" + a_functionarguments.aszCmd[3] + ">", a_functionarguments); return (false); } TWAIN.MemCpy((IntPtr)((UInt64)intptrPtr + (UInt64)keyvalue.iBytes), twimagememxfer.Memory.TheMem, (int)twimagememxfer.BytesWritten); SetVariable(keyvalue.szKey, intptrPtr.ToString(), keyvalue.iBytes + (int)twimagememxfer.BytesWritten, VariableScope.Local); } } } return (false); // Cleanfolder... case "cleanfolder": // Validate if (a_functionarguments.aszCmd.Length != 3) { DisplayError("must specify 3 arguments", a_functionarguments); return (false); } szFolder = a_functionarguments.aszCmd[2]; if (!Directory.Exists(szFolder)) { try { Directory.CreateDirectory(szFolder); } catch { /* don't care */ } } else { string[] aszFiles = Directory.GetFiles(szFolder, "*.bmp"); foreach (string szFile in aszFiles) try { File.Delete(szFile); } catch { /* don't care */ } aszFiles = Directory.GetFiles(szFolder, "*.tif"); foreach (string szFile in aszFiles) try { File.Delete(szFile); } catch { /* don't care */ } aszFiles = Directory.GetFiles(szFolder, "*.jpg"); foreach (string szFile in aszFiles) try { File.Delete(szFile); } catch { /* don't care */ } aszFiles = Directory.GetFiles(szFolder, "*.pdf"); foreach (string szFile in aszFiles) try { File.Delete(szFile); } catch { /* don't care */ } } return (false); // Cleanfolderandmeta... case "cleanfolderandmeta": // Validate if (a_functionarguments.aszCmd.Length != 3) { DisplayError("must specify 3 arguments", a_functionarguments); return (false); } szFolder = a_functionarguments.aszCmd[2]; if (!Directory.Exists(szFolder)) { try { Directory.CreateDirectory(szFolder); } catch { /* don't care */ } } else { string[] aszFiles = Directory.GetFiles(szFolder, "*.bmp"); foreach (string szFile in aszFiles) try { File.Delete(szFile); } catch { /* don't care */ } aszFiles = Directory.GetFiles(szFolder, "*.tif"); foreach (string szFile in aszFiles) try { File.Delete(szFile); } catch { /* don't care */ } aszFiles = Directory.GetFiles(szFolder, "*.jpg"); foreach (string szFile in aszFiles) try { File.Delete(szFile); } catch { /* don't care */ } aszFiles = Directory.GetFiles(szFolder, "*.pdf"); foreach (string szFile in aszFiles) try { File.Delete(szFile); } catch { /* don't care */ } aszFiles = Directory.GetFiles(szFolder, "*.txt"); foreach (string szFile in aszFiles) try { File.Delete(szFile); } catch { /* don't care */ } } return (false); // Free... case "free": // Validate if (a_functionarguments.aszCmd.Length < 3) { DisplayError("must specify a variable for the image free command", a_functionarguments); return (false); } // Get the value... keyvalue.szKey = a_functionarguments.aszCmd[2]; GetVariable(keyvalue.szKey, -1, out keyvalue.szValue, out keyvalue.iBytes, out blGlobal, VariableScope.Local); // If we have a pointer, free it, and set the varible to 0... if (string.IsNullOrEmpty(keyvalue.szValue)) { SetVariable(keyvalue.szKey, "0", 0, VariableScope.Local); } else if (UInt64.TryParse(keyvalue.szValue, out u64Ptr)) { intptrPtr = (IntPtr)u64Ptr; if (intptrPtr != IntPtr.Zero) { Marshal.FreeHGlobal(intptrPtr); SetVariable(keyvalue.szKey, "0", 0, VariableScope.Local); } } else { DisplayError("bad pointer <" + keyvalue.szKey + "=" + keyvalue.szValue + ">", a_functionarguments); SetVariable(keyvalue.szKey, "0", 0, VariableScope.Local); } return (false); // Save... case "save": // Validate if (a_functionarguments.aszCmd.Length < 5) { DisplayError("must specify a variable, xfermech, and a filename for the image save command", a_functionarguments); return (false); } // More validating... if ((a_functionarguments.aszCmd[3].ToLowerInvariant() != "native") && (a_functionarguments.aszCmd[3].ToLowerInvariant() != "memfile") && (a_functionarguments.aszCmd[3].ToLowerInvariant() != "memory")) { DisplayError("unrecognized xfermech <" + a_functionarguments.aszCmd[3] + ">", a_functionarguments); return (false); } // Get the value... keyvalue.szKey = a_functionarguments.aszCmd[2]; GetVariable(keyvalue.szKey, -1, out keyvalue.szValue, out keyvalue.iBytes, out blGlobal, VariableScope.Local); // Validate the pointer... if (!UInt64.TryParse(keyvalue.szValue, out u64Ptr)) { DisplayError("bad pointer <" + keyvalue.szKey + ">", a_functionarguments); return (false); } if (u64Ptr == 0) { DisplayError("null pointer <" + keyvalue.szKey + ">", a_functionarguments); return (false); } // Make sure the folder exists... szFolder = a_functionarguments.aszCmd[4]; if (!Directory.Exists(Path.GetDirectoryName(szFolder))) { try { Directory.CreateDirectory(Path.GetDirectoryName(szFolder)); } catch { /* don't care */ } } // Okay, we're ready to save... intptrPtr = (IntPtr)u64Ptr; switch (a_functionarguments.aszCmd[3].ToLowerInvariant()) { default: case "native": abImage = m_twain.NativeToByteArray(intptrPtr, true, out iHeaderBytes); try { szFilename = szFolder; if (!Path.GetFileName(szFilename).Contains(".")) { szFilename += ".bmp"; } File.WriteAllBytes(szFilename, abImage); } catch (Exception exception) { DisplayError("image save failed <" + szFilename + "> - " + exception.Message, a_functionarguments); return (false); } break; case "memfile": case "memory": iResult = TWAIN.WriteImageFile(szFolder, intptrPtr, keyvalue.iBytes, out szFilename); if (iResult == -1) { DisplayError("image save failed <" + szFolder + ">", a_functionarguments); return (false); } break; } // Just the file and the DAT folder it's in... if (szFilename.Contains("\\DAT_")) { szFilename = szFilename.Substring(szFilename.IndexOf("\\DAT_")); if (szFilename.Contains("\\") || szFilename.Contains("/")) { szFilename = szFilename.Substring(szFilename.IndexOfAny(new char[] { '\\', '/' }) + 1); } a_functionarguments.szReturnValue = szFilename; } else if (szFilename.Contains("/DAT_")) { szFilename = szFilename.Substring(szFilename.IndexOf("/DAT_")); if (szFilename.Contains("\\") || szFilename.Contains("/")) { szFilename = szFilename.Substring(szFilename.IndexOfAny(new char[] { '\\', '/' }) + 1); } a_functionarguments.szReturnValue = szFilename; } else { a_functionarguments.szReturnValue = szFilename; } return (false); } } /// /// Increment a value and store it... /// /// tokenized command and anything needed /// true to quit private bool CmdIncrement(ref Interpreter.FunctionArguments a_functionarguments) { int iSrc; int iDst; int iStep = 1; // Validate... if ((a_functionarguments.aszCmd == null) || (a_functionarguments.aszCmd.Length < 3) || (a_functionarguments.aszCmd[1] == null)) { DisplayError("badly formed increment", a_functionarguments); return (false); } // Turn the source into a number... if (!int.TryParse(a_functionarguments.aszCmd[2], out iSrc)) { DisplayError("source is not a number", a_functionarguments); return (false); } // Get the step... if ((a_functionarguments.aszCmd.Length >= 4) && (a_functionarguments.aszCmd[3] != null)) { if (!int.TryParse(a_functionarguments.aszCmd[3], out iStep)) { DisplayError("step is not a number", a_functionarguments); return (false); } } // Increment the value... iDst = iSrc + iStep; // Gotta know if the value is local or global, local wins so we'll search there... bool blGlobal = true; if ((m_lcallstack.Count > 0) && (m_lcallstack[m_lcallstack.Count - 1].lkeyvalue != null)) { foreach (KeyValue keyvalue in m_lcallstack[m_lcallstack.Count - 1].lkeyvalue) { if (keyvalue.szKey == a_functionarguments.aszCmd[1]) { blGlobal = false; break; } } } // Store the value... Interpreter.FunctionArguments functionarguments = default(Interpreter.FunctionArguments); functionarguments.aszCmd = new string[3]; functionarguments.aszCmd[0] = blGlobal ? "setglobal" : "setlocal"; functionarguments.aszCmd[1] = a_functionarguments.aszCmd[1]; functionarguments.aszCmd[2] = iDst.ToString(); if (blGlobal) { CmdSetGlobal(ref functionarguments); } else { CmdSetLocal(ref functionarguments); } // All done... return (false); } /// /// Accept command input from the user. The data is returned in the /// ${ret:} variable. The first argument is a prompt, the rest of /// the arguments are optional, and indicate values that must be /// entered if the input command is going to return... /// /// tokenized command and anything needed /// true to quit private bool CmdInput(ref Interpreter.FunctionArguments a_functionarguments) { int ii; string szCmd = ""; string szPrompt = "enter input: "; List lszCommands = new List(); // Get the prompt... if ((a_functionarguments.aszCmd.Length >= 2) && (a_functionarguments.aszCmd[1] != null)) { szPrompt = a_functionarguments.aszCmd[1]; } // Get the commands... for (ii = 3; true; ii++) { if ((ii >= a_functionarguments.aszCmd.Length) || string.IsNullOrEmpty(a_functionarguments.aszCmd[ii - 1])) { break; } lszCommands.Add(a_functionarguments.aszCmd[ii - 1]); } // Loopy... Interpreter interpreter = new Interpreter(szPrompt, m_consolecolorDefault, m_consolecolorGreen); while (true) { // Get the command... szCmd = interpreter.Prompt(m_streamreaderConsole, ((m_twain == null) ? 1 : (int)m_twain.GetState())); // If we have no commands to compare it against, we're done... if (lszCommands.Count == 0) { break; } // Otherwise, we have to look for a match... bool blFound = false; foreach (string szCommand in lszCommands) { if (szCmd.ToLowerInvariant() == szCommand.ToLowerInvariant()) { blFound = true; break; } } // We got a match... if (blFound) { break; } } // Update the return value... CallStack callstack = m_lcallstack[m_lcallstack.Count - 1]; callstack.functionarguments.szReturnValue = szCmd; m_lcallstack[m_lcallstack.Count - 1] = callstack; // All done... return (false); } /// /// Quit... /// /// tokenized command and anything needed /// true to quit private bool CmdQuit(ref Interpreter.FunctionArguments a_functionarguments) { return (true); } /// /// Log text... /// /// tokenized command and anything needed /// true to quit private bool CmdLog(ref Interpreter.FunctionArguments a_functionarguments) { int ii; int iStart; string szSeverity; string szMessage; // If we have no arguments, then log a blank informational... if ((a_functionarguments.aszCmd == null) || (a_functionarguments.aszCmd.Length < 2) || (a_functionarguments.aszCmd[1] == null)) { Log.Info(""); return (false); } // Pick a severity... switch (a_functionarguments.aszCmd[1]) { default: szSeverity = "info"; iStart = 1; break; case "info": szSeverity = "info"; iStart = 2; break; case "warn": szSeverity = "warn"; iStart = 2; break; case "error": szSeverity = "error"; iStart = 2; break; case "verbose": szSeverity = "verbose"; iStart = 2; break; case "assert": szSeverity = "assert"; iStart = 2; break; } // Build the message... szMessage = ""; for (ii = iStart; ii < a_functionarguments.aszCmd.Length; ii++) { szMessage += (szMessage == "") ? a_functionarguments.aszCmd[ii] : " " + a_functionarguments.aszCmd[ii]; } // Log it... switch (szSeverity) { default: case "info": Log.Info(szMessage); break; case "warn": Log.Warn(szMessage); break; case "error": Log.Error(szMessage); break; case "verbose": Log.Verbose(szMessage); break; case "assert": Log.Assert(szMessage); break; } // All done... return (false); } /// /// Multiply a value and store it... /// /// tokenized command and anything needed /// true to quit private bool CmdMultiply(ref Interpreter.FunctionArguments a_functionarguments) { int iSrc; int iDst; float fMultiplier; // Validate... if ((a_functionarguments.aszCmd == null) || (a_functionarguments.aszCmd.Length < 4) || (a_functionarguments.aszCmd[1] == null)) { DisplayError("badly formed multiplier", a_functionarguments); return (false); } // Turn the source into a number... if (!int.TryParse(a_functionarguments.aszCmd[2], out iSrc)) { DisplayError("source is not a number", a_functionarguments); return (false); } // Turn the multiplier into a number... if (!float.TryParse(a_functionarguments.aszCmd[3], out fMultiplier)) { DisplayError("multiplier is not a number", a_functionarguments); return (false); } // Multiply the value... iDst = (int)((float)iSrc * fMultiplier); // Gotta know if the value is local or global, local wins so we'll search there... bool blGlobal = true; if ((m_lcallstack.Count > 0) && (m_lcallstack[m_lcallstack.Count - 1].lkeyvalue != null)) { foreach (KeyValue keyvalue in m_lcallstack[m_lcallstack.Count - 1].lkeyvalue) { if (keyvalue.szKey == a_functionarguments.aszCmd[1]) { blGlobal = false; break; } } } // Store the value... Interpreter.FunctionArguments functionarguments = default(Interpreter.FunctionArguments); functionarguments.aszCmd = new string[3]; functionarguments.aszCmd[0] = blGlobal ? "setglobal" : "setlocal"; functionarguments.aszCmd[1] = a_functionarguments.aszCmd[1]; functionarguments.aszCmd[2] = iDst.ToString(); if (blGlobal) { CmdSetGlobal(ref functionarguments); } else { CmdSetLocal(ref functionarguments); } // All done... return (false); } /// /// Pause until the user presses the enter key... /// /// tokenized command and anything needed /// true to quit private bool CmdPause(ref Interpreter.FunctionArguments a_functionarguments) { int ii; string szCmd = ""; string szPrompt = "(press ENTER to continue)"; List lszCommands = new List(); // Get the prompt... if ((a_functionarguments.aszCmd.Length >= 2) && (a_functionarguments.aszCmd[1] != null)) { szPrompt = a_functionarguments.aszCmd[1]; } // Get the commands... for (ii = 3; true; ii++) { if ((ii >= a_functionarguments.aszCmd.Length) || string.IsNullOrEmpty(a_functionarguments.aszCmd[ii - 1])) { break; } lszCommands.Add(a_functionarguments.aszCmd[ii - 1]); } // Wait for input... Interpreter interpreter = new Interpreter(szPrompt, m_consolecolorDefault, m_consolecolorGreen); szCmd = interpreter.Prompt(m_streamreaderConsole, ((m_twain == null) ? 1 : (int)m_twain.GetState()), true, false); // Update the return value... CallStack callstack = m_lcallstack[m_lcallstack.Count - 1]; callstack.functionarguments.szReturnValue = ""; m_lcallstack[m_lcallstack.Count - 1] = callstack; // All done... return (false); } /// /// Manage the self cert report... /// /// tokenized command and anything needed /// true to quit private bool CmdReport(ref Interpreter.FunctionArguments a_functionarguments) { // If we have no arguments, then log a complaint... if ((a_functionarguments.aszCmd == null) || (a_functionarguments.aszCmd.Length < 2) || (a_functionarguments.aszCmd[1] == null)) { DisplayError("please specify initialize or save", a_functionarguments); return (false); } // Clear... if (a_functionarguments.aszCmd[1].ToLowerInvariant() == "initialize") { string szFolder = ""; m_stringbuilderSelfCertReport = new StringBuilder(); m_szSelfCertReportPath = null; m_szSelfCertReportProductname = ""; if ((a_functionarguments.aszCmd.Length < 3) || (a_functionarguments.aszCmd[2] == null)) { DisplayError("please specify a driver productname", a_functionarguments); return (false); } m_szSelfCertReportProductname = a_functionarguments.aszCmd[2]; szFolder = Path.Combine(m_szTwainSelfCertFolder, Regex.Replace(m_szSelfCertReportProductname + m_szSelfCertDriverVersion, "[^.a-zA-Z0-9]", "_")); szFolder = Path.Combine(szFolder, TWAIN.GetPlatform() + "_" + TWAIN.GetMachineWordBitSize()); if (Directory.Exists(szFolder)) { try { Directory.Delete(szFolder, true); } catch { /* don't care */ } } } // Save file... else if (a_functionarguments.aszCmd[1].ToLowerInvariant() == "save") { string szFolder = ""; if (string.IsNullOrEmpty(m_szSelfCertReportProductname)) { DisplayError("'report initialize' must come before 'report save'...", a_functionarguments); return (false); } if ((a_functionarguments.aszCmd.Length >= 3) && (a_functionarguments.aszCmd[2] != null)) { szFolder = a_functionarguments.aszCmd[2]; } try { if (string.IsNullOrEmpty(szFolder)) { szFolder = Path.Combine(m_szTwainSelfCertFolder, Regex.Replace(m_szSelfCertReportProductname + m_szSelfCertDriverVersion, "[^.a-zA-Z0-9]", "_")); szFolder = Path.Combine(szFolder, TWAIN.GetPlatform() + "_" + TWAIN.GetMachineWordBitSize()); } if (!Directory.Exists(szFolder)) { Directory.CreateDirectory(szFolder); } m_szSelfCertReportPath = Path.Combine(szFolder, Regex.Replace(m_szSelfCertReportProductname + m_szSelfCertDriverVersion, "[^.a-zA-Z0-9]", "_")) + ".txt"; File.WriteAllText(m_szSelfCertReportPath, m_stringbuilderSelfCertReport.ToString()); } catch (Exception exception) { DisplayError("save threw exception: " + exception.Message, a_functionarguments); m_szSelfCertReportPath = null; return (false); } } // No idea... else { DisplayError("unrecognized commend: " + a_functionarguments.aszCmd[1], a_functionarguments); } // All done... return (false); } /// /// Return from the current function... /// /// tokenized command and anything needed /// true to quit private bool CmdReturn(ref Interpreter.FunctionArguments a_functionarguments) { CallStack callstack; // If we don't have anything on the stack, then scoot... if ((m_lcallstack == null) || (m_lcallstack.Count == 0)) { return (false); } // If this is the base of the stack, then return is a noop... if (m_lcallstack.Count == 1) { return (false); } // Make a copy of the last item (which we're about to delete)... callstack = m_lcallstack[m_lcallstack.Count - 1]; // Remove the last item... m_lcallstack.RemoveAt(m_lcallstack.Count - 1); // Set the line we want to jump back to... a_functionarguments.blGotoLabel = true; a_functionarguments.iLabelLine = callstack.functionarguments.iCurrentLine + 1; // Make a note of the return value for "ret:"... if ((a_functionarguments.aszCmd != null) && (a_functionarguments.aszCmd.Length > 1)) { callstack = m_lcallstack[m_lcallstack.Count - 1]; callstack.functionarguments.szReturnValue = a_functionarguments.aszCmd[1]; m_lcallstack[m_lcallstack.Count - 1] = callstack; } // All done... return (false); } /// /// With no arguments, show the current state. With an argument /// rollback to that state. This should only be used after an /// error condition to make it easier to get a script into a known /// state... /// /// tokenized command and anything needed /// true to quit private bool CmdRollback(ref Interpreter.FunctionArguments a_functionarguments) { string szState; string[] aszState; // No argument, show the current state... if ((a_functionarguments.aszCmd == null) || (a_functionarguments.aszCmd.Length < 2) || (a_functionarguments.aszCmd[1] == null)) { Display("Currently at: " + ((m_twain == null) ? "state0" : m_twain.GetState().ToString().Replace("S", "state"))); return (false); } // If we don't have m_twain, just scoot... if (m_twain == null) { return (false); } // Reduce whatever we got to just the state number, we'll take the // number, the enumeration, or state#... aszState = a_functionarguments.aszCmd[1].Split(new char[] { '.' }); szState = aszState[aszState.Length - 1]; // grab the last element szState = szState.ToLower().Replace("state", "").Replace("s", ""); // Rollback to the desired state... switch (szState) { default: break; case "1": m_twain.Rollback(TWAIN.STATE.S1, false); break; case "2": m_twain.Rollback(TWAIN.STATE.S2, false); break; case "3": m_twain.Rollback(TWAIN.STATE.S3, false); break; case "4": m_twain.Rollback(TWAIN.STATE.S4, false); break; case "5": m_twain.Rollback(TWAIN.STATE.S5, false); break; case "6": m_twain.Rollback(TWAIN.STATE.S6, false); break; } // All done... return (false); } /// /// With no arguments, list the scripts. With an argument, /// run the specified script. This one runs silent. /// /// tokenized command and anything needed /// true to quit private bool CmdRun(ref Interpreter.FunctionArguments a_functionarguments) { bool blSuccess; bool blSilent = m_blSilent; bool blSilentEvents = m_blSilentEvents; if (m_blVerbose) { m_blSilent = false; m_blSilentEvents = false; } else { m_blSilent = true; m_blSilentEvents = true; } blSuccess = CmdRunv(ref a_functionarguments); m_blSilent = blSilent; m_blSilentEvents = blSilentEvents; return (blSuccess); } /// /// With no arguments, list the scripts. With an argument, /// run the specified script. The one runs verbose. /// /// tokenized command and anything needed /// true to quit private bool CmdRunv(ref Interpreter.FunctionArguments a_functionarguments) { string szPrompt = "tc>>> "; string[] aszScript; string szScriptFile; int iCallStackCount; CallStack callstack; Interpreter interpreter; bool blVerboseRestore = m_blVerbose; // Be noisy... if ((a_functionarguments.aszCmd != null) && (a_functionarguments.aszCmd[0].ToLowerInvariant() == "runv")) { m_blVerbose = true; } // List... if ((a_functionarguments.aszCmd == null) || (a_functionarguments.aszCmd.Length < 2) || (a_functionarguments.aszCmd[1] == null)) { // Get the script files... string[] aszScriptFiles = Directory.GetFiles(".", "*.tc"); if ((aszScriptFiles == null) || (aszScriptFiles.Length == 0)) { DisplayError("no script files found", a_functionarguments); } // List what we found... Display("SCRIPT FILES"); foreach (string sz in aszScriptFiles) { Display(Path.GetFileNameWithoutExtension(sz), true); } // All done... m_blVerbose = blVerboseRestore; return (false); } // Make sure the file exists... szScriptFile = a_functionarguments.aszCmd[1]; if (!File.Exists(szScriptFile)) { szScriptFile = a_functionarguments.aszCmd[1] + ".tc"; if (!File.Exists(szScriptFile)) { DisplayError("script not found...<" + szScriptFile + ">", a_functionarguments); m_blVerbose = blVerboseRestore; return (false); } } szScriptFile = Path.GetFullPath(szScriptFile); // Read the file... try { aszScript = File.ReadAllLines(szScriptFile); } catch (Exception exception) { DisplayError("failed to read script...<" + szScriptFile + ">" + exception.Message, a_functionarguments); m_blVerbose = blVerboseRestore; return (false); } // Give ourselves an interpreter... interpreter = new Interpreter("", m_consolecolorDefault, m_consolecolorGreen); // Bump ourself up on the call stack, because we're really // working like a call. At this point we'll be running with // at least 2 items on the stack. If we drop down to 1 item // that's a hint that the return command was used to get out // of the script... callstack = default(CallStack); callstack.functionarguments = a_functionarguments; callstack.functionarguments.szScriptFile = szScriptFile; callstack.functionarguments.aszScript = aszScript; m_lcallstack.Add(callstack); iCallStackCount = m_lcallstack.Count; // Run each line in the script... int iLine = 0; bool blReturn = false; TWAIN.STS sts = TWAIN.STS.SUCCESS; string szReturnValue = ""; m_blRunningScript = true; while (iLine < aszScript.Length) { bool blDone; string szLine; string[] aszCmd; // Grab our line... szLine = aszScript[iLine]; // Show the command... if (!m_blSilent) { Display(szPrompt + szLine.Trim()); } // Tokenize... aszCmd = interpreter.Tokenize(szLine.Trim()); // Restore the last dsmentry status and value, if this isn't a dsmentry command, // we need this so we can examine the values in other commands... if ( (aszCmd[0] != "dsmentry") && (aszCmd[0] != "echo") && (aszCmd[0] != "goto") && (aszCmd[0] != "if") && (aszCmd[0] != "image") && (aszCmd[0] != "increment") && (aszCmd[0] != "log") && (aszCmd[0] != "multiply") && (aszCmd[0] != "setglobal") && (aszCmd[0] != "setlocal") && (aszCmd[0] != "sleep")) { callstack = m_lcallstack[m_lcallstack.Count - 1]; callstack.functionarguments.sts = sts; callstack.functionarguments.szReturnValue = szReturnValue; m_lcallstack[m_lcallstack.Count - 1] = callstack; } // Build our function arguments... Interpreter.FunctionArguments functionarguments = default(Interpreter.FunctionArguments); functionarguments.aszCmd = aszCmd; functionarguments.szScriptFile = szScriptFile; functionarguments.aszScript = aszScript; functionarguments.iCurrentLine = iLine; // Expansion of symbols... Expansion(functionarguments, ref aszCmd); // Dispatch... blDone = interpreter.Dispatch(ref functionarguments, m_ldispatchtable); if (blDone) { break; } // Squirrel this stuff away, not every command should override these // items, otherwise we can't test them... :) if ( (aszCmd[0] == "allocatehandle") || (aszCmd[0] == "allocatepointer") || (aszCmd[0] == "dsmentry") || (aszCmd[0] == "image") || (aszCmd[0] == "verbose") || (aszCmd[0] == "wait")) { sts = functionarguments.sts; szReturnValue = functionarguments.szReturnValue; if (m_lcallstack.Count > 0) { callstack = m_lcallstack[m_lcallstack.Count - 1]; callstack.functionarguments.sts = sts; callstack.functionarguments.szReturnValue = szReturnValue; m_lcallstack[m_lcallstack.Count - 1] = callstack; } } // Handle gotos... if (functionarguments.blGotoLabel) { iLine = functionarguments.iLabelLine; } // Otherwise, just increment... else { iLine += 1; } // If the count dropped, that's a sign we need to bail... if (m_lcallstack.Count < iCallStackCount) { blReturn = true; break; } } // Pop this item, and pass along the return value, but don't do it // if we detect that a return call was made in the script, because // it will have already popped the stack for us... if (!blReturn && (m_lcallstack.Count > 1)) { szReturnValue = m_lcallstack[m_lcallstack.Count - 1].functionarguments.szReturnValue; if (szReturnValue == null) { szReturnValue = ""; } m_lcallstack.RemoveAt(m_lcallstack.Count - 1); callstack = m_lcallstack[m_lcallstack.Count - 1]; callstack.functionarguments.szReturnValue = szReturnValue; m_lcallstack[m_lcallstack.Count - 1] = callstack; } // Handle the last item on the stack, so we can report how things turned out... else if (m_lcallstack.Count == 1) { a_functionarguments.szReturnValue = m_lcallstack[m_lcallstack.Count - 1].functionarguments.szReturnValue; } // All done... m_blRunningScript = false; m_blVerbose = blVerboseRestore; return (false); } /// /// Save an image to disk, used for DAT_IMAGEMEMFILEXFER, DAT_IMAGEMEMXFER, /// and DAT_IMAGENATIVEXFER. We don't need it for DAT_IMAGEFILEXFER... /// /// tokenized command and anything needed /// true to quit private bool CmdSaveImage(ref Interpreter.FunctionArguments a_functionarguments) { int iHeaderBytes; byte[] abImage; UInt64 u64Handle; // Basic sanity check... if ((a_functionarguments.aszCmd == null) || (a_functionarguments.aszCmd.Length < 2) || (a_functionarguments.aszCmd[1] == null)) { DisplayError("insufficient arguments, please see help for saveimage", a_functionarguments); return (false); } // Dispatch off the second argument... switch (a_functionarguments.aszCmd[1].ToLowerInvariant()) { // Oh dear... default: DisplayError("unrecognized type <" + a_functionarguments.aszCmd[1] + ">", a_functionarguments); return (false); // Memory transfer, we need the image file, pointer, byte size, and DAT_IMAGEINFO metadata... case "mem": if (a_functionarguments.aszCmd.Length < 6) { DisplayError("insufficient arguments, please see help for saveimage", a_functionarguments); return (false); } break; // Memory file transfer, we need the image file, pointer, and the byte size... case "memfile": if (a_functionarguments.aszCmd.Length < 5) { DisplayError("insufficient arguments, please see help for saveimage", a_functionarguments); return (false); } break; // Native transfer, we need the image file and the handle... case "native": if (a_functionarguments.aszCmd.Length < 4) { DisplayError("insufficient arguments, please see help for saveimage", a_functionarguments); return (false); } string szImageFile = a_functionarguments.aszCmd[2]; if (!UInt64.TryParse(a_functionarguments.aszCmd[3], out u64Handle)) { DisplayError("failed to convert the byte size", a_functionarguments); return (false); } // This beastie autodetects the image type... abImage = m_twain.NativeToByteArray((IntPtr)u64Handle, true, out iHeaderBytes); try { File.WriteAllBytes(szImageFile, abImage); } catch (Exception exception) { DisplayError("saveimage failed <" + szImageFile + "> - " + exception.Message, a_functionarguments); return (false); } break; } // All done... return (false); } /// /// With no arguments, list the keys with their values. With an argument, /// set the specified value. /// /// tokenized command and anything needed /// true to quit private bool CmdSetGlobal(ref Interpreter.FunctionArguments a_functionarguments) { return (CmdSetGlobal(ref a_functionarguments, false)); } private bool CmdSetGlobal(ref Interpreter.FunctionArguments a_functionarguments, bool a_blSysOnly) { // If we don't have any arguments, list what we have... if ((a_functionarguments.aszCmd == null) || (a_functionarguments.aszCmd.Length < 2) || (a_functionarguments.aszCmd[1] == null)) { lock (m_objectKeyValue) { // Hmmm... if (m_lkeyvalue.Count == 0) { DisplayError("no keys to list", a_functionarguments); return (false); } // Loopy... Display((a_blSysOnly ? "SYS " : "") + "KEY/VALUE PAIRS"); foreach (KeyValue keyvalue in m_lkeyvalue) { if (a_blSysOnly && !keyvalue.szKey.StartsWith("sys_")) { continue; } Display(keyvalue.szKey + "=<" + keyvalue.szValue + ">"); } } // All done... return (false); } // Set the variable in the global list... SetVariable(a_functionarguments.aszCmd[1], (a_functionarguments.aszCmd.Length < 3) || (a_functionarguments.aszCmd[2] == null) ? "" : a_functionarguments.aszCmd[2], 0, VariableScope.Global); // All done... return (false); } /// /// With no arguments, list the keys with their values. With an argument, /// set the specified value. All done in the context of the topmost item /// on the stack... /// /// tokenized command and anything needed /// true to quit private bool CmdSetLocal(ref Interpreter.FunctionArguments a_functionarguments) { CallStack callstack; // If we don't have a stack, add this to the global list... if (m_lcallstack.Count == 0) { CmdSetGlobal(ref a_functionarguments); return (false); } // This is what we'll be referencing... callstack = m_lcallstack[m_lcallstack.Count - 1]; if (callstack.lkeyvalue == null) { callstack.lkeyvalue = new List(); } // If we don't have any arguments, list what we have for the whole stack... if ((a_functionarguments.aszCmd == null) || (a_functionarguments.aszCmd.Length < 2) || (a_functionarguments.aszCmd[1] == null)) { int ii; // We got nothing... if (callstack.lkeyvalue.Count == 0) { DisplayError("no local keys to list", a_functionarguments); return (false); } // Loopy... Display("LOCAL KEY/VALUE PAIRS"); for (ii = m_lcallstack.Count - 1; ii >= 0; ii--) { Display(" STACK #" + ii); if ((m_lcallstack[ii].lkeyvalue == null) || (m_lcallstack[ii].lkeyvalue.Count == 0)) { Display(" (no local variables)" + ii); } else { foreach (KeyValue keyvalue in m_lcallstack[ii].lkeyvalue) { Display(" " + keyvalue.szKey + "=<" + keyvalue.szValue + ">"); } } } // All done... return (false); } // Set the variable in the local list... SetVariable(a_functionarguments.aszCmd[1], (a_functionarguments.aszCmd.Length < 3) || (a_functionarguments.aszCmd[2] == null) ? "" : a_functionarguments.aszCmd[2], 0, VariableScope.Local); // All done... return (false); } /// /// Record variables being set into another variable... /// /// tokenized command and anything needed /// true to quit private bool CmdSetRecord(ref Interpreter.FunctionArguments a_functionarguments) { // No data... if ((a_functionarguments.aszCmd == null) || (a_functionarguments.aszCmd.Length < 2) || (a_functionarguments.aszCmd[0] == null)) { DisplayError("setrecord needs arguments", a_functionarguments); return (false); } // Turn it off, and save the result... if (a_functionarguments.aszCmd[1].ToLowerInvariant() == "off") { if (!string.IsNullOrEmpty(m_szSetRecordVariable)) { SetVariable(m_szSetRecordVariable, m_szSetRecordData, 0, VariableScope.Global); } m_szSetRecordVariable = ""; m_szSetRecordFilter = ""; m_szSetRecordRemove = ""; m_szSetRecordData = ""; return (false); } // The only other valid option is on... if (a_functionarguments.aszCmd[1].ToLowerInvariant() != "on") { DisplayError("unrecognized argument", a_functionarguments); return (false); } // Validate... if ((a_functionarguments.aszCmd.Length < 3) || string.IsNullOrEmpty(a_functionarguments.aszCmd[2])) { DisplayError("setrecord on needs a variable name", a_functionarguments); return (false); } // Record the name... m_szSetRecordVariable = a_functionarguments.aszCmd[2]; m_szSetRecordData = ""; m_szSetRecordFilter = ""; m_szSetRecordRemove = ""; // Check if the caller asked for a filter... if ((a_functionarguments.aszCmd.Length < 4) || string.IsNullOrEmpty(a_functionarguments.aszCmd[3])) { return (false); } // Record the filter... m_szSetRecordFilter = a_functionarguments.aszCmd[3]; // Check if the caller asked for a substring to remove... if ((a_functionarguments.aszCmd.Length < 5) || string.IsNullOrEmpty(a_functionarguments.aszCmd[4])) { return (false); } // Record the remove string... m_szSetRecordRemove = a_functionarguments.aszCmd[4]; // All done... return (false); } /// /// Some info that may be helpful... /// /// tokenized command and anything needed /// true to quit private bool CmdSizes(ref Interpreter.FunctionArguments a_functionarguments) { Display("int........" + sizeof(int)); Display("intPtr....." + Marshal.SizeOf(typeof(IntPtr))); // All done... return (false); } /// /// Sleep some number of milliseconds... /// /// tokenized command and anything needed /// true to quit private bool CmdSleep(ref Interpreter.FunctionArguments a_functionarguments) { int iMilliseconds; // Get the milliseconds... if ((a_functionarguments.aszCmd == null) || (a_functionarguments.aszCmd.Length < 2) || !int.TryParse(a_functionarguments.aszCmd[1], out iMilliseconds)) { iMilliseconds = 0; } if (iMilliseconds < 0) { iMilliseconds = 0; } // Wait... Thread.Sleep(iMilliseconds); // All done... return (false); } /// /// Status of the program... /// /// tokenized command and anything needed /// true to quit private bool CmdStatus(ref Interpreter.FunctionArguments a_functionarguments) { // Platform... Display("Platform.................." + TWAINWorkingGroup.TWAIN.GetPlatform() + " (" + TWAINWorkingGroup.TWAIN.GetMachineWordBitSize() + "-bit)"); Display("Certification Folder......" + m_szTwainSelfCertFolder); Display("Current Folder............" + Directory.GetCurrentDirectory()); // DSM is not loaded... if (m_twain == null) { Display("DSM Path..................(not loaded)"); return (false); } // DSM in use... Display("DSM Path.................." + m_twain.GetDsmPath()); // State... Display("TWAIN State..............." + ((int)m_twain.GetState())); // If state 4 or higher, what is our driver? if (m_twain.GetState() >= TWAIN.STATE.S4) { Display("TWAIN Driver.............." + m_twain.GetDsIdentity()); } // List the system variables... Display(""); CmdSetGlobal(ref a_functionarguments, true); // All done... return (false); } /// /// Turn verbose on and off... /// /// tokenized command and anything needed /// true to quit private bool CmdVerbose(ref Interpreter.FunctionArguments a_functionarguments) { // Validate... if ((a_functionarguments.aszCmd == null) || (a_functionarguments.aszCmd.Length < 2)) { Display("verbose: " + (m_blVerbose ? "on" : "off")); return (false); } // Turn it on... if (a_functionarguments.aszCmd[1].ToLowerInvariant() == "on") { m_iSilentRestore = m_blSilent ? 1 : 2; m_iVerboseRestore = m_blVerbose ? 1 : 2; m_blSilent = false; m_blVerbose = true; return (false); } // Turn it off... if (a_functionarguments.aszCmd[1].ToLowerInvariant() == "off") { m_iVerboseRestore = m_blVerbose ? 1 : 2; if (m_iSilentRestore > 0) { m_blSilent = (m_iSilentRestore == 1) ? true : false; } m_blVerbose = false; return (false); } // Restore it... if (a_functionarguments.aszCmd[1].ToLowerInvariant() == "restore") { if (m_iSilentRestore > 0) { m_blSilent = (m_iSilentRestore == 1) ? true : false; } if (m_iVerboseRestore > 0) { m_blVerbose = (m_iVerboseRestore == 1) ? true : false; } return (false); } // Unrecognized argument... DisplayError("unrecognized argument", a_functionarguments); // All done... return (false); } /// /// Wait for one or more events with a timeout, or clear pending events... /// /// tokenized command and anything needed /// true to quit private bool CmdWait(ref Interpreter.FunctionArguments a_functionarguments) { int ii; int iMilliseconds = 0; CallStack callstack = m_lcallstack[m_lcallstack.Count - 1]; // Validate... if ((a_functionarguments.aszCmd == null) || (a_functionarguments.aszCmd.Length < 2)) { return (false); } // Examine all of the arguments... for (ii = 1; ii < a_functionarguments.aszCmd.Length; ii++) { // Clear pending messages... if (a_functionarguments.aszCmd[1].ToLowerInvariant() == "reset") { lock (m_lmsgDatNull) { m_lmsgDatNull.Clear(); m_autoreseteventMsgDatNull.Reset(); } a_functionarguments.szReturnValue = ""; callstack.functionarguments.szReturnValue = a_functionarguments.szReturnValue; return (false); } // A number is the timeout value... else if (int.TryParse(a_functionarguments.aszCmd[ii], out iMilliseconds)) { if (iMilliseconds < 0) { iMilliseconds = 0; } } } // Wait for a signal or a timeout... bool blSignaled; Stopwatch stopwatch = new Stopwatch(); stopwatch.Start(); blSignaled = m_autoreseteventMsgDatNull.WaitOne(iMilliseconds); if (!blSignaled) { a_functionarguments.szReturnValue = "timeout"; callstack.functionarguments.szReturnValue = a_functionarguments.szReturnValue; return (false); } // Build a list of what we got, take a snapshot so we // hold onto it for as little time as possible... List lmsgDatNull = null; a_functionarguments.szReturnValue = ""; lock (m_lmsgDatNull) { lmsgDatNull = new List(m_lmsgDatNull); } foreach (TWAIN.MSG msg in lmsgDatNull) { a_functionarguments.szReturnValue += (string.IsNullOrEmpty(a_functionarguments.szReturnValue) ? "" : ",") + "MSG_" + msg; } // Update the stack... callstack.functionarguments.szReturnValue = a_functionarguments.szReturnValue; // All done... return (false); } #endregion // Private Methods (certification) #region Private Methods (certification) /// /// Run the TWAIN Certification tests. /// private void TwainDirectCertification() { int iPass = 0; int iFail = 0; int iSkip = 0; int iTotal = 0; string szCertificationFolder; string[] aszCategories; // Find our cert stuff... szCertificationFolder = Path.Combine(Config.Get("writeFolder", ""), "tasks"); szCertificationFolder = Path.Combine(szCertificationFolder, "certification"); // Whoops...nothing to work with... if (!Directory.Exists(szCertificationFolder)) { DisplayError("cannot find certification folder:\n" + szCertificationFolder, new Interpreter.FunctionArguments()); return; } // Get the categories... aszCategories = Directory.GetDirectories(szCertificationFolder); if (aszCategories == null) { DisplayError("cannot find any certification categories:\n" + szCertificationFolder, new Interpreter.FunctionArguments()); return; } // Pass count... Log.Info("certification>>> PASS: " + iPass); // Fail count... Log.Info("certification>>> FAIL: " + iFail); // Skip count... Log.Info("certification>>> SKIP: " + iSkip); // Total count... Log.Info("certification>>> TOTAL: " + iTotal); } #endregion // Private Methods (misc) #region Private Methods (misc) /// /// Create or overwrite the data folder used for certification... /// private bool CreateTwainSelfCertDataFolder(bool a_blCertifying) { // Init stuff... bool blUpdate = false; string szOriginalFolder = Directory.GetCurrentDirectory(); m_szTwainSelfCertFolder = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.DesktopDirectory), "TWAIN Self Certification"); try { // Go somewhere else for a bit so we don't lock up the data folder... Directory.SetCurrentDirectory(Environment.GetFolderPath(Environment.SpecialFolder.DesktopDirectory)); // Do this if certifying, we always overwrite the files... if (a_blCertifying) { blUpdate = true; } // Otherwise only create or update if we can't find it, or if we // detect an older version... else { // Create our certification folder, if it doesn't exist... if (!Directory.Exists(m_szTwainSelfCertFolder)) { Directory.CreateDirectory(m_szTwainSelfCertFolder); } // If we don't have the version.txt file, we're updating... if (!File.Exists(Path.Combine(m_szTwainSelfCertFolder, "data", "version.txt"))) { blUpdate = true; } // Check if the data version is older than us... else { int iMajor = 0; int iMinor = 0; int iRevision = 0; int iBuild = 0; int iVersionTxt = 0; int iVersionCurrent = 0; // Get the assembly file version info from the data/version.txt file... string szVersionTxt = File.ReadAllText(Path.Combine(m_szTwainSelfCertFolder, "data", "version.txt")); szVersionTxt = szVersionTxt.Trim().Replace("\r", "").Replace("\n", ""); string[] aszVersionTxt = szVersionTxt.Split('.'); // Get our current version file version info... Assembly assembly = System.Reflection.Assembly.GetExecutingAssembly(); FileVersionInfo fileversioninfo = FileVersionInfo.GetVersionInfo(assembly.Location); string[] aszVersionCurrent = fileversioninfo.FileVersion.Split('.'); // Panic mode... if ((aszVersionTxt.Length != 4) || (aszVersionCurrent.Length != 4)) { blUpdate = true; } // Keep going... else { // Convert... if (int.TryParse(aszVersionTxt[0], out iMajor) && int.TryParse(aszVersionTxt[1], out iMinor) && int.TryParse(aszVersionTxt[2], out iRevision) && int.TryParse(aszVersionTxt[3], out iBuild)) { iVersionTxt = (iMajor * 1000000) + (iMinor * 10000) + (iRevision * 100) + iBuild; } if (int.TryParse(aszVersionCurrent[0], out iMajor) && int.TryParse(aszVersionCurrent[1], out iMinor) && int.TryParse(aszVersionCurrent[2], out iRevision) && int.TryParse(aszVersionCurrent[3], out iBuild)) { iVersionCurrent = (iMajor * 1000000) + (iMinor * 10000) + (iRevision * 100) + iBuild; } // Compare... if ((iVersionTxt <= 0) || (iVersionCurrent <= 0) || (iVersionTxt < iVersionCurrent)) { blUpdate = true; } } } } // We're creating or updating... if (blUpdate) { // Some info... Display((a_blCertifying ? " " : "") + "Creating/updating the TWAIN Self Certification data folder..."); Log.Info("Creating/updating the TWAIN Self Certification data folder..."); // Create our certification folder, if it doesn't exist... if (!Directory.Exists(m_szTwainSelfCertFolder)) { Directory.CreateDirectory(m_szTwainSelfCertFolder); } // Delete the temporary data folder, if it exists... string szDataTmp = Path.Combine(m_szTwainSelfCertFolder, "data.tmp"); if (Directory.Exists(szDataTmp)) { Directory.Delete(szDataTmp, true); } // Create our temporary data folder... if (!Directory.Exists(szDataTmp)) { string szDataZip = Path.Combine(szDataTmp, "data.zip"); Directory.CreateDirectory(szDataTmp); File.WriteAllBytes(szDataZip, twaincscert.Properties.Resources.data); ZipFile.ExtractToDirectory(szDataZip, szDataTmp); } // Copy the temporary data folder to the data folder... if (!CopyFolder(Path.Combine(m_szTwainSelfCertFolder, "data"), Path.Combine(szDataTmp, "data"))) { Log.Error("Couldn't merge the data folder..."); Directory.Delete(szDataTmp, true); Directory.SetCurrentDirectory(szOriginalFolder); return (false); } // Cleanup... Directory.Delete(szDataTmp, true); } } catch (Exception exception) { DisplayRed("Couldn't create or update the data folder - " + exception.Message); Log.Error("Couldn't create or update the data folder - " + exception.Message); Directory.SetCurrentDirectory(szOriginalFolder); return (false); } // All done... Directory.SetCurrentDirectory(szOriginalFolder); return (true); } /// /// Copy one folder to another... /// /// /// public bool CopyFolder(string a_szDst, string a_szSrc) { DirectoryInfo directoryinfoSrc = new DirectoryInfo(a_szSrc); DirectoryInfo directoryinfoDst = new DirectoryInfo(a_szDst); return (CopyAllFiles(directoryinfoDst, directoryinfoSrc)); } /// /// Copy files, with recursion... /// /// /// public bool CopyAllFiles(DirectoryInfo a_directoryinfoDst, DirectoryInfo a_directoryinfoSrc) { try { Directory.CreateDirectory(a_directoryinfoDst.FullName); // Copy each file into the new directory. foreach (FileInfo fileinfo in a_directoryinfoSrc.GetFiles()) { fileinfo.CopyTo(Path.Combine(a_directoryinfoDst.FullName, fileinfo.Name), true); } // Copy each subdirectory using recursion. foreach (DirectoryInfo directoryinfoSrcSubDir in a_directoryinfoSrc.GetDirectories()) { DirectoryInfo directoryinfoDstSubDir = a_directoryinfoDst.CreateSubdirectory(directoryinfoSrcSubDir.Name); CopyAllFiles(directoryinfoDstSubDir, directoryinfoSrcSubDir); } } catch (Exception exception) { Log.Error("copy failed - " + exception.Message); return (false); } // All done... return (true); } /// /// Display text (if allowed)... /// /// the text to display private void Display(string a_szText, bool a_blForce = false) { if (!m_blSilent || a_blForce) { Console.Out.WriteLine(a_szText); } if (m_stringbuilderSelfCertReport != null) { m_stringbuilderSelfCertReport.AppendLine(a_szText); } } /// /// Display text (if allowed)... /// /// the text to display private void DisplayBlue(string a_szText, bool a_blForce = false) { if (!m_blSilent || a_blForce) { if (Console.BackgroundColor == ConsoleColor.Black) { Console.ForegroundColor = m_consolecolorBlue; Console.Out.WriteLine(a_szText); Console.ForegroundColor = m_consolecolorDefault; } else { Console.Out.WriteLine(a_szText); } if (m_stringbuilderSelfCertReport != null) { m_stringbuilderSelfCertReport.AppendLine(a_szText); } } } /// /// Display text (if allowed)... /// /// the text to display private void DisplayGreen(string a_szText, bool a_blForce = false) { if (!m_blSilent || a_blForce) { if (Console.BackgroundColor == ConsoleColor.Black) { Console.ForegroundColor = m_consolecolorGreen; Console.Out.WriteLine(a_szText); Console.ForegroundColor = m_consolecolorDefault; } else { Console.Out.WriteLine(a_szText); } if (m_stringbuilderSelfCertReport != null) { m_stringbuilderSelfCertReport.AppendLine(a_szText); } } } /// /// Display text (if allowed)... /// /// the text to display private void DisplayRed(string a_szText, bool a_blForce = false) { if (!m_blSilent || a_blForce) { if (Console.BackgroundColor == ConsoleColor.Black) { Console.ForegroundColor = m_consolecolorRed; Console.Out.WriteLine(a_szText); Console.ForegroundColor = m_consolecolorDefault; } else { Console.Out.WriteLine(a_szText); } if (m_stringbuilderSelfCertReport != null) { m_stringbuilderSelfCertReport.AppendLine(a_szText); } } } /// /// Display text (if allowed)... /// /// the text to display private void DisplayYellow(string a_szText, bool a_blForce = false) { if (!m_blSilent || a_blForce) { if (Console.BackgroundColor == ConsoleColor.Black) { Console.ForegroundColor = m_consolecolorYellow; Console.Out.WriteLine(a_szText); Console.ForegroundColor = m_consolecolorDefault; } else { Console.Out.WriteLine(a_szText); } if (m_stringbuilderSelfCertReport != null) { m_stringbuilderSelfCertReport.AppendLine(a_szText); } } } /// /// Display an error message... /// /// the text to display private void DisplayError(string a_szText, Interpreter.FunctionArguments a_functionarguments) { string szMessage; if (string.IsNullOrEmpty(a_functionarguments.szScriptFile)) { szMessage = "ERROR: " + a_szText; } else { szMessage = "ERROR: " + a_szText + " ('" + a_functionarguments.szScriptFile + "' at line " + (a_functionarguments.iCurrentLine + 1) + ")"; } Console.Out.WriteLine(szMessage); if (m_stringbuilderSelfCertReport != null) { m_stringbuilderSelfCertReport.AppendLine(szMessage); } } /// /// Cleanup... /// /// true if we need to clean up managed resources internal void Dispose(bool a_blDisposing) { // Free managed resources... if (a_blDisposing) { if (m_autoreseteventMsgDatNull != null) { m_autoreseteventMsgDatNull.Dispose(); m_autoreseteventMsgDatNull = null; } if (m_autoreseteventScannerslist != null) { m_autoreseteventScannerslist.Dispose(); m_autoreseteventScannerslist = null; } if (m_twain != null) { m_twain.Dispose(); m_twain = null; } } } /// /// Expand symbols that we find in the tokenized strings. Symbols take the form /// ${source:key} where source can be one of the following: /// - the JSON text from the response to the last API command /// - the list maintains by the set command /// - the return value from the last run/runv or call in a script /// - the arguments to the program, run/runv or call in a script /// /// Symbols can be nests, for instance, if the first argument to a call /// is a JSON key, it can be expanded as: /// - ${rj:${arg:1}} /// /// tokenized string array to expand private void Expansion(Interpreter.FunctionArguments a_functionarguments, ref string[] a_aszCmd) { int ii; int iReferenceCount; int iCmd; int iIndexLeft; int iIndexRight; CallStack callstack; // Expansion... for (iCmd = 0; iCmd < a_aszCmd.Length; iCmd++) { // If we don't find an occurrance of ${ in the string, then we're done... if (!a_aszCmd[iCmd].Contains("${")) { continue; } // Find each outermost ${ in the string, meaning that if we have the // following ${rj:${arg:1}}${get:y} we only want to find the rj and // the get, the arg will be handled inside of the rj, so that means // we have to properly count our way to the closing } for rj... for (iIndexLeft = a_aszCmd[iCmd].IndexOf("${"); iIndexLeft >= 0; iIndexLeft = a_aszCmd[iCmd].IndexOf("${")) { string szSymbol; string szValue; string szKey = a_aszCmd[iCmd]; // Find the corresponding }... iIndexRight = -1; iReferenceCount = 0; for (ii = iIndexLeft + 2; ii < szKey.Length; ii++) { // Either exit or decrement our reference count... if (szKey[ii] == '}') { if (iReferenceCount == 0) { iIndexRight = ii; break; } iReferenceCount -= 1; } // Bump up the reference count... if ((szKey[ii] == '$') && ((ii + 1) < szKey.Length) && (szKey[ii + 1] == '{')) { iReferenceCount += 1; } } // If we didn't find a closing }, we're done... if (iIndexRight == -1) { break; } // This is our symbol... // 0123456789 // aa${rj:x}a // left index is 2, right index is 8, size is 7, so (r - l) + 1 szSymbol = szKey.Substring(iIndexLeft, (iIndexRight - iIndexLeft) + 1); // Expand the stuff to the right of the source, so if we have // ${rj:x} we'll get x back, but if we have ${rj:${arg:1}}, we'll // get the value of ${arg:1} back... if ( szSymbol.StartsWith("${arg:") || szSymbol.StartsWith("${app:") || szSymbol.StartsWith("${bits:") || szSymbol.StartsWith("${ds:") || szSymbol.StartsWith("${dsm:") || szSymbol.StartsWith("${folder:") || szSymbol.StartsWith("${format:") || szSymbol.StartsWith("${get:") || szSymbol.StartsWith("${getbytes:") || szSymbol.StartsWith("${gettwei:") || szSymbol.StartsWith("${gethandle:") || szSymbol.StartsWith("${gethandleindex:") || szSymbol.StartsWith("${getindex:") || szSymbol.StartsWith("${localtime:") || szSymbol.StartsWith("${platform:") || szSymbol.StartsWith("${program:") || szSymbol.StartsWith("${report:") || szSymbol.StartsWith("${ret:") || szSymbol.StartsWith("${sizeof:") || szSymbol.StartsWith("${state:") || szSymbol.StartsWith("${sts:")) { int iSymbolIndexLeft = szSymbol.IndexOf(":") + 1; int iSymbolIndexLength; string[] asz = new string[1]; asz[0] = szSymbol.Substring(0, szSymbol.Length - 1).Substring(iSymbolIndexLeft); iSymbolIndexLength = asz[0].Length; Expansion(a_functionarguments, ref asz); szSymbol = szSymbol.Remove(iSymbolIndexLeft, iSymbolIndexLength); szSymbol = szSymbol.Insert(iSymbolIndexLeft, asz[0]); } // Assume the worse... szValue = ""; // Get data from the top of the call stack... if (szSymbol.StartsWith("${arg:")) { if ((m_lcallstack != null) && (m_lcallstack.Count > 0)) { string szTarget = szSymbol.Substring(0, szSymbol.Length - 1).Substring(6); // If we have an index, use it to find our callstack. As a general rule // the only 'safe' index to use is 0, since that'll point to the last // command entered by the user. But fancier stuff is possible... if (szTarget.Contains(":")) { // Use the index info to get the right data... int iIndex; string szIndex = szTarget.Remove(szTarget.IndexOf(":")); if (int.TryParse(szIndex, out iIndex)) { iIndex += 1; // so we can have an index origin at 0... if (iIndex < 1) { iIndex = 1; } else if (iIndex >= m_lcallstack.Count) { iIndex = m_lcallstack.Count - 1; } } callstack = m_lcallstack[iIndex]; // Ditch the index info... szTarget = szTarget.Substring(szTarget.IndexOf(":") + 1); } // Use the top of the stack... else { callstack = m_lcallstack[m_lcallstack.Count - 1]; } // Return the number of arguments, wherever we ended up... if (szTarget == "#") { // Needs to be -2 to remove "call xxx" or "run xxx" from count... szValue = (callstack.functionarguments.aszCmd.Length - 2).ToString(); } // Return the requested argument, wherever we ended up, -1 gets the command... else { int iIndex; if (int.TryParse(szTarget, out iIndex)) { if ((callstack.functionarguments.aszCmd != null) && (iIndex >= -1) && ((iIndex + 1) < callstack.functionarguments.aszCmd.Length)) { szValue = callstack.functionarguments.aszCmd[iIndex + 1]; } } } } } // Get data from the application identity (indexible)... else if (szSymbol.StartsWith("${app:")) { if (m_twain == null) { szValue = "(dsm not loaded)"; } else if (szSymbol == "${app:}") { szValue = m_twain.GetAppIdentity(); } else { int iIndex = 0; if (int.TryParse(szSymbol.Replace("${app:", "").Replace("}", ""), out iIndex)) { string[] asz = CSV.Parse(m_twain.GetAppIdentity()); if ((iIndex < 0) || (iIndex >= asz.Length)) { szValue = ""; } else { szValue = asz[iIndex]; } } } } // Get number of bits in the machine word... else if (szSymbol.StartsWith("${bits:")) { szValue = TWAINWorkingGroup.TWAIN.GetMachineWordBitSize().ToString(); } // Get data from the data source (indexible)... else if (szSymbol.StartsWith("${ds:")) { if (m_twain == null) { szValue = "(dsm not loaded)"; } else if (szSymbol == "${ds:}") { szValue = m_twain.GetDsIdentity(); } else { int iIndex = 0; if (int.TryParse(szSymbol.Replace("${ds:", "").Replace("}", ""), out iIndex)) { string[] asz = CSV.Parse(m_twain.GetDsIdentity()); if ((iIndex < 0) || (iIndex >= asz.Length)) { szValue = ""; } else { szValue = asz[iIndex]; } } } } // Path to the DSM we're using (if any)... else if (szSymbol.StartsWith("${dsm:")) { if (m_twain != null) { szValue = m_twain.GetDsmPath(); } } // Special folders else if (szSymbol.StartsWith("${folder:")) { if (szSymbol == "${folder:certification}") { szValue = m_szSelfCertDataCertFolder; } else if (szSymbol == "${folder:certimages}") { if ((m_twain != null) && !string.IsNullOrEmpty(m_twain.GetDsIdentity())) { string[] aszDs = CSV.Parse(m_twain.GetDsIdentity()); if (aszDs.Length >= 12) { szValue = m_szTwainSelfCertFolder; szValue = Path.Combine(szValue, Regex.Replace(aszDs[11] + m_szSelfCertDriverVersion, "[^.a-zA-Z0-9]", "_")); szValue = Path.Combine(szValue, TWAIN.GetPlatform() + "_" + TWAIN.GetMachineWordBitSize()); } } } else if (szSymbol == "${folder:data}") { szValue = m_szTwainSelfCertFolder; } else if (szSymbol == "${folder:desktop}") { szValue = Environment.GetFolderPath(Environment.SpecialFolder.DesktopDirectory); } else if (szSymbol == "${folder:local}") { szValue = Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData); } else if (szSymbol == "${folder:parent}") { if (string.IsNullOrEmpty(a_functionarguments.szScriptFile)) { szValue = Directory.GetCurrentDirectory(); } else { szValue = Path.GetFileName(Path.GetDirectoryName(a_functionarguments.szScriptFile)); } } else if (szSymbol == "${folder:pictures}") { szValue = Environment.GetFolderPath(Environment.SpecialFolder.MyPictures); } else if (szSymbol == "${folder:roaming}") { szValue = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData); } else { // Not the most brilliant idea, but what the hell... szValue = szSymbol.Replace("${", "").Replace(":", "").Replace("}", ""); } } // Format the data using a specifier... else if (szSymbol.StartsWith("${format:")) { // Strip off ${...}, split specifier and value... string szFormat = szSymbol.Substring(0, szSymbol.Length - 1).Substring(9); string[] aszFormat = szFormat.Split(new char[] { '|' }, 2); if (aszFormat.Length >= 2) { // Assume it's a number... if (aszFormat[0].ToLowerInvariant().Contains("x") || aszFormat[0].ToLowerInvariant().Contains("d")) { int iValue = 0; int.TryParse(aszFormat[1], out iValue); szValue = string.Format("{0:" + aszFormat[0] + "}", iValue); } // Assume it's a string... else { szValue = string.Format("{0:" + aszFormat[0] + "}", aszFormat[1]); } } } // Use value as a GET key to get a value, we don't allow a null in this // case, it has to be an empty string. We search the local list first, // and if that fails go to the global list... else if (szSymbol.StartsWith("${get:")) { int iBytes = 0; bool blGlobal = false; // Strip off ${...} string szGet = szSymbol.Substring(0, szSymbol.Length - 1).Substring(6); if (szGet == "twain.state") { iBytes = 0; } // Get the value, if any... GetVariable(szGet, -1, out szValue, out iBytes, out blGlobal); } // Get the number of bytes in the string, right now the only encoding // we're doing this for is UTF-8. I could see adding the current one // as well (at least for Windows)... else if (szSymbol.StartsWith("${getbytes:")) { int iBytes = 0; bool blGlobal = false; byte[] abValue; string szValueLocal; // Assume zero... szValue = "0"; // Strip off ${...} string szGetBytes = szSymbol.Substring(0, szSymbol.Length - 1).Substring(11); // If we don't have an encoding, assume UTF-8... if (!szGetBytes.Contains(":")) { GetVariable(szGetBytes, -1, out szValueLocal, out iBytes, out blGlobal); if (!string.IsNullOrEmpty(szValueLocal)) { abValue = Encoding.UTF8.GetBytes(szValueLocal); szValue = abValue.Length.ToString(); } } // Handle UTF-8 else if (!szGetBytes.EndsWith(":uft8", StringComparison.InvariantCultureIgnoreCase)) { szGetBytes = szGetBytes.Remove(szGetBytes.IndexOf(":")); GetVariable(szGetBytes, -1, out szValueLocal, out iBytes, out blGlobal); if (!string.IsNullOrEmpty(szValueLocal)) { abValue = Encoding.UTF8.GetBytes(szValueLocal); szValue = abValue.Length.ToString(); } } // Ruh-roh, leaving this here to help with debugging breakpoints... else { szValue = "0"; } } // Format: ${gethandle:numeric handle:data type:bytes} // We only need bytes for TWTY_HANDLE, use 0 for all other types // Use -1 for NUL terminated strings // // Use value as a GET key to get a value, we don't allow a null in this // case, it has to be an empty string. We search the local list first, // and if that fails go to the global list. Once we have the value we // lock ts and extract the value based on the type. If the type is a // handle when we also need the number of bytes... else if (szSymbol.StartsWith("${gethandle:")) { // Strip off ${...} string szGet = szSymbol.Substring(0, szSymbol.Length - 1).Substring(12); string[] aszGet = szGet.Split(':'); // Are we good? We need gethandle:target:type:bytes... if (aszGet.Length == 3) { // Only keep going if we got a value and bytes... if (!string.IsNullOrEmpty(aszGet[0])) { ulong u64Handle; // Convert the value to an IntPtr... if (UInt64.TryParse(aszGet[0], out u64Handle)) { // Lock... int iDataBytes; byte[] abValue = null; IntPtr intptrPointer; IntPtr intptrHandle = (IntPtr)u64Handle; intptrPointer = m_twain.DsmMemLock(intptrHandle); // Okay, let's trigger off the type... switch (aszGet[1]) { default: szValue = ""; break; case "TWTY_INT8": abValue = new byte[1]; Marshal.Copy(intptrPointer, abValue, 0, 1); szValue = ((sbyte)abValue[0]).ToString(); break; case "TWTY_INT16": abValue = new byte[2]; Marshal.Copy(intptrPointer, abValue, 0, 2); szValue = BitConverter.ToInt16(abValue, 0).ToString(); break; case "TWTY_INT32": abValue = new byte[4]; Marshal.Copy(intptrPointer, abValue, 0, 4); szValue = BitConverter.ToInt32(abValue, 0).ToString(); break; case "TWTY_INT64": abValue = new byte[8]; Marshal.Copy(intptrPointer, abValue, 0, 8); szValue = BitConverter.ToInt64(abValue, 0).ToString(); break; case "TWTY_UINT8": abValue = new byte[1]; Marshal.Copy(intptrPointer, abValue, 0, 1); szValue = ((byte)abValue[0]).ToString(); break; case "TWTY_UINT16": abValue = new byte[2]; Marshal.Copy(intptrPointer, abValue, 0, 2); szValue = BitConverter.ToUInt16(abValue, 0).ToString(); break; case "TWTY_UINT32": abValue = new byte[4]; Marshal.Copy(intptrPointer, abValue, 0, 4); szValue = BitConverter.ToUInt32(abValue, 0).ToString(); break; case "TWTY_UINT64": abValue = new byte[8]; Marshal.Copy(intptrPointer, abValue, 0, 8); szValue = BitConverter.ToUInt64(abValue, 0).ToString(); break; case "TWTY_STR32": szValue = ""; iDataBytes = Marshal.SizeOf(typeof(TWAIN.TW_STR32)); abValue = new byte[iDataBytes]; Marshal.Copy(intptrPointer, abValue, 0, iDataBytes); szValue = Encoding.UTF8.GetString(abValue).Replace("\0", ""); break; case "TWTY_STR64": szValue = ""; iDataBytes = Marshal.SizeOf(typeof(TWAIN.TW_STR64)); abValue = new byte[iDataBytes]; Marshal.Copy(intptrPointer, abValue, 0, iDataBytes); szValue = Encoding.UTF8.GetString(abValue).Replace("\0", ""); break; case "TWTY_STR128": szValue = ""; iDataBytes = Marshal.SizeOf(typeof(TWAIN.TW_STR128)); abValue = new byte[iDataBytes]; Marshal.Copy(intptrPointer, abValue, 0, iDataBytes); szValue = Encoding.UTF8.GetString(abValue).Replace("\0", ""); break; case "TWTY_STR255": szValue = ""; iDataBytes = Marshal.SizeOf(typeof(TWAIN.TW_STR255)); abValue = new byte[iDataBytes]; Marshal.Copy(intptrPointer, abValue, 0, iDataBytes); szValue = Encoding.UTF8.GetString(abValue).Replace("\0", ""); break; case "TWTY_HANDLE": szValue = ""; if (int.TryParse(aszGet[2], out iDataBytes)) { // Handle NUL-terminated strings... if (iDataBytes == -1) { abValue = new byte[0x10000]; // try 64K, we're expecting a NUL Marshal.Copy(intptrPointer, abValue, 0, abValue.Length); szValue = Encoding.UTF8.GetString(abValue); if (szValue.IndexOf('\0') == -1) { abValue = new byte[0x100000]; // try 1MB, we're expecting a NUL Marshal.Copy(intptrPointer, abValue, 0, abValue.Length); szValue = Encoding.UTF8.GetString(abValue); } int iNul = szValue.IndexOf('\0'); if (iNul >= 0) { szValue = szValue.Remove(iNul); } } // Handle anything where we have a real non-zero size... else if (iDataBytes > 0) { abValue = new byte[iDataBytes]; Marshal.Copy(intptrPointer, abValue, 0, iDataBytes); szValue = Encoding.UTF8.GetString(abValue); } } break; } // Unlock... m_twain.DsmMemUnlock(intptrHandle); } } } } // Use value as a GET key to get a value, we don't allow a null in this // case, it has to be an empty string. We search the local list first, // and if that fails go to the global list. Once we have the value we // lock it and extract the value based on the type. We index into the // array. Note that we do not dig deeper into TW_HANDLE. The caller // has to get the handle at the index using this call, and then get the // data at that handle using gethandle. This is so that we done't hide // too much of what's going on from the scripts... else if (szSymbol.StartsWith("${gethandleindex:")) { // Strip off ${...} string szGet = szSymbol.Substring(0, szSymbol.Length - 1).Substring(17); string[] aszGet = szGet.Split(':'); // name:handle:index:type // Are we good? We need gethandleindex:target:index:type... if (aszGet.Length == 3) { // Only keep going if we got a value and bytes... if (!string.IsNullOrEmpty(aszGet[0])) { ulong u64Handle; // Get our index... int iIndex = -1; int.TryParse(aszGet[1], out iIndex); // Convert the value to an IntPtr, if we have a valid index... if ((iIndex >= 0) && UInt64.TryParse(aszGet[0], out u64Handle)) { // Lock... byte[] abValue = null; IntPtr intptrPointer; IntPtr intptrHandle = (IntPtr)u64Handle; intptrPointer = m_twain.DsmMemLock(intptrHandle); // Okay, let's trigger off the type... switch (aszGet[2]) { default: szValue = ""; break; case "TWTY_INT8": abValue = new byte[1 * (iIndex + 1)]; Marshal.Copy(intptrPointer, abValue, 0, 1 * (iIndex + 1)); szValue = ((sbyte)abValue[iIndex]).ToString(); break; case "TWTY_INT16": abValue = new byte[2 * (iIndex + 1)]; Marshal.Copy(intptrPointer, abValue, 0, 2 * (iIndex + 1)); szValue = BitConverter.ToInt16(abValue, 2 * iIndex).ToString(); break; case "TWTY_INT32": abValue = new byte[4 * (iIndex + 1)]; Marshal.Copy(intptrPointer, abValue, 0, 4 * (iIndex + 1)); szValue = BitConverter.ToInt32(abValue, 4 * iIndex).ToString(); break; case "TWTY_INT64": abValue = new byte[8 * (iIndex + 1)]; Marshal.Copy(intptrPointer, abValue, 0, 8 * (iIndex + 1)); szValue = BitConverter.ToInt64(abValue, 8 * iIndex).ToString(); break; case "TWTY_UINT8": abValue = new byte[1 * (iIndex + 1)]; Marshal.Copy(intptrPointer, abValue, 0, 1 * (iIndex + 1)); szValue = ((byte)abValue[iIndex]).ToString(); break; case "TWTY_UINT16": abValue = new byte[2 * (iIndex + 1)]; Marshal.Copy(intptrPointer, abValue, 0, 2 * (iIndex + 1)); szValue = BitConverter.ToUInt16(abValue, 2 * iIndex).ToString(); break; case "TWTY_UINT32": abValue = new byte[4 * (iIndex + 1)]; Marshal.Copy(intptrPointer, abValue, 0, 4 * (iIndex + 1)); szValue = BitConverter.ToUInt32(abValue, 4 * iIndex).ToString(); break; case "TWTY_UINT64": abValue = new byte[8 * (iIndex + 1)]; Marshal.Copy(intptrPointer, abValue, 0, 8 * (iIndex + 1)); szValue = BitConverter.ToUInt64(abValue, 8 * iIndex).ToString(); break; case "TWTY_STR32": break; case "TWTY_STR64": break; case "TWTY_STR128": break; case "TWTY_STR255": break; case "TWTY_HANDLE": szValue = ""; if (Marshal.SizeOf(typeof(IntPtr)) == 4) { abValue = new byte[4 * (iIndex + 1)]; Marshal.Copy(intptrPointer, abValue, 0, 4 * (iIndex + 1)); szValue = BitConverter.ToUInt32(abValue, 4 * iIndex).ToString(); } else { abValue = new byte[8 * (iIndex + 1)]; Marshal.Copy(intptrPointer, abValue, 0, 8 * (iIndex + 1)); szValue = BitConverter.ToUInt64(abValue, 8 * iIndex).ToString(); } break; } // Unlock... m_twain.DsmMemUnlock(intptrHandle); } } } } // Use value as a GET key to get a value, we don't allow a null in this // case, it has to be an empty string. CSV the value we get, and return // just the item indicated by the index. We search the local list // first, and if that fails go to the global list... else if (szSymbol.StartsWith("${getindex:")) { int iIndex = 0; int iBytes = 0; bool blGlobal = false; // Strip off ${...}, split name and index... string szGet = szSymbol.Substring(0, szSymbol.Length - 1).Substring(11); string[] aszGet = szGet.Split(':'); // Get the value, if any... if ((aszGet.Length > 1) && int.TryParse(aszGet[1], out iIndex)) { GetVariable(aszGet[0], iIndex, out szValue, out iBytes, out blGlobal); } } // Look up an enum value from TWAINH.CS... else if (szSymbol.StartsWith("${gettwei:")) { TWAIN.TWEI twei; // Strip off ${...} string szGetTwei = szSymbol.Substring(0, szSymbol.Length - 1).Substring(10); string[] aszGetTwei = szGetTwei.Split(':'); // Do the lookup... if (aszGetTwei.Length > 1) { if (Enum.TryParse(aszGetTwei[0].Replace("TWEI_", "").Replace("twei_", ""), out twei)) { szValue = TWAIN.CvtTweiValueToEnum(twei, aszGetTwei[1]); } } } // Access to the local time... else if (szSymbol.StartsWith("${localtime:")) { DateTime datetime = DateTime.Now; string szFormat = szSymbol.Substring(0, szSymbol.Length - 1).Substring(12); try { szValue = datetime.ToString(szFormat); } catch { szValue = datetime.ToString(); } } // Get the platform... else if (szSymbol.StartsWith("${platform:")) { szValue = TWAINWorkingGroup.TWAIN.GetPlatform().ToString(); } // Get the program, version, and machine word size (meant for display only)... else if (szSymbol.StartsWith("${program:")) { Assembly assembly = typeof(Terminal).Assembly; AssemblyName assemblyname = assembly.GetName(); Version version = assemblyname.Version; DateTime datetime = new DateTime(2000, 1, 1).AddDays(version.Build).AddSeconds(version.MinorRevision * 2); szValue = assemblyname.Name + " v" + version.Major + "." + version.Minor + " " + datetime.Day + "-" + datetime.ToString("MMM") + "-" + datetime.Year + " " + ((IntPtr.Size == 4) ? "(32-bit)" : "(64-bit)"); } // Full path to the self cert report (meant for display only)... else if (szSymbol.StartsWith("${report:")) { if (string.IsNullOrEmpty(m_szSelfCertReportPath)) { szValue = "(self cert file not specified)"; } else if (!File.Exists(m_szSelfCertReportPath)) { szValue = m_szSelfCertReportPath + " (not found)"; } else { szValue = m_szSelfCertReportPath; } } // Get data from the return value... else if (szSymbol.StartsWith("${ret:")) { callstack = m_lcallstack[m_lcallstack.Count - 1]; if (callstack.functionarguments.szReturnValue != null) { if (szSymbol == "${ret:}") { szValue = callstack.functionarguments.szReturnValue; } else { int iIndex = 0; if (int.TryParse(szSymbol.Replace("${ret:", "").Replace("}", ""), out iIndex)) { string[] asz = CSV.Parse(callstack.functionarguments.szReturnValue); if ((iIndex < 0) || (iIndex >= asz.Length)) { szValue = ""; } else { szValue = asz[iIndex]; } } } } } // Get the size of the type... else if (szSymbol.StartsWith("${sizeof:")) { szValue = "0"; string szType = szSymbol.Substring(0, szSymbol.Length - 1).Substring(9); // If there's no dot and it starts with TW, assume it's a TWAIN type... if (!szType.Contains(".") && szType.ToUpperInvariant().StartsWith("TW")) { szType = "TWAINWorkingGroup.TWAIN+" + szType.ToUpperInvariant() + ", TWAIN, Culture=neutral, PublicKeyToken=null"; } Type type = System.Type.GetType(szType); if (type != null) { szValue = Marshal.SizeOf(type).ToString(); } } // Get the TWAIN state... else if (szSymbol.StartsWith("${state:")) { if (m_twain == null) { szValue = "1"; } else { szValue = ((int)m_twain.GetState()).ToString(); } } // Get data from the TWAIN status... else if (szSymbol.StartsWith("${sts:")) { callstack = m_lcallstack[m_lcallstack.Count - 1]; szValue = callstack.functionarguments.sts.ToString(); } // Failsafe (we should catch all of these up above)... if (szValue == null) { szValue = ""; } // Replace the current contents with the expanded value... a_aszCmd[iCmd] = a_aszCmd[iCmd].Remove(iIndexLeft, (iIndexRight - iIndexLeft) + 1).Insert(iIndexLeft, szValue); } } } /// /// Get a variable from the local or global lists... /// /// key to find /// -1 for all, 0 - n for a CSV index /// value found /// bytes found /// true if global /// scope /// true if found private bool GetVariable(string a_szKey, int a_iIndex, out string a_szValue, out int a_iBytes, out bool a_blGlobal, VariableScope a_variablescope = VariableScope.Auto) { // Local check... if ((a_variablescope != VariableScope.Global) && (m_lcallstack.Count > 0) && (m_lcallstack[m_lcallstack.Count - 1].lkeyvalue != null)) { foreach (KeyValue keyvalue in m_lcallstack[m_lcallstack.Count - 1].lkeyvalue) { if (keyvalue.szKey == a_szKey) { if (a_iIndex == -1) { a_szValue = (keyvalue.szValue == null) ? "" : keyvalue.szValue; a_iBytes = keyvalue.iBytes; a_blGlobal = false; return (true); } else { string[] aszValue = CSV.Parse((keyvalue.szValue == null) ? "" : keyvalue.szValue); a_szValue = ((a_iIndex >= 0) && (a_iIndex < aszValue.Length)) ? aszValue[a_iIndex] : ""; a_iBytes = keyvalue.iBytes; a_blGlobal = false; return (true); } } } } // Global check... if (a_variablescope != VariableScope.Local) { lock (m_objectKeyValue) { if (m_lkeyvalue.Count >= 0) { foreach (KeyValue keyvalue in m_lkeyvalue) { if (keyvalue.szKey == a_szKey) { if (a_iIndex == -1) { a_szValue = (keyvalue.szValue == null) ? "" : keyvalue.szValue; a_iBytes = keyvalue.iBytes; a_blGlobal = true; return (true); } else { string[] aszValue = CSV.Parse((keyvalue.szValue == null) ? "" : keyvalue.szValue); a_szValue = ((a_iIndex >= 0) && (a_iIndex < aszValue.Length)) ? aszValue[a_iIndex] : ""; a_iBytes = keyvalue.iBytes; a_blGlobal = true; return (true); } } } } } } // No joy... a_szValue = ""; a_iBytes = 0; a_blGlobal = false; return (false); } /// /// Set a global or a local variable... /// /// key to set /// value to set /// bytes to set /// scope public void SetVariable(string a_szKey, string a_szValue, int a_iBytes, VariableScope a_variablescope = VariableScope.Auto) { int iKey; // Record stuff... if (!string.IsNullOrEmpty(m_szSetRecordVariable)) { string szKey = a_szKey; if (string.IsNullOrEmpty(m_szSetRecordFilter) || a_szKey.Contains(m_szSetRecordFilter)) { if (!string.IsNullOrEmpty(m_szSetRecordRemove)) { szKey = szKey.Replace(m_szSetRecordRemove, ""); } m_szSetRecordData += string.IsNullOrEmpty(m_szSetRecordData) ? szKey : ("," + szKey); } } // If automatic, check if we have a value in either list... if (a_variablescope == VariableScope.Auto) { string szValue; int iBytes; bool blGlobal; bool blFound = GetVariable(a_szKey, -1, out szValue, out iBytes, out blGlobal); // If not found, force local... if (!blFound) { a_variablescope = VariableScope.Local; } // Otherwise, force to what we found... else { a_variablescope = blGlobal ? VariableScope.Global : VariableScope.Local; } } // We're local if not-global, or if we don't have a stack... if ((a_variablescope == VariableScope.Local) || (m_lcallstack.Count == 0)) { CallStack callstack; // This is what we'll be referencing... callstack = m_lcallstack[m_lcallstack.Count - 1]; if (callstack.lkeyvalue == null) { callstack.lkeyvalue = new List(); } // Find the value for this key... for (iKey = 0; iKey < callstack.lkeyvalue.Count; iKey++) { if (callstack.lkeyvalue[iKey].szKey == a_szKey) { break; } } // If we have no value to set, then delete this item... if (string.IsNullOrEmpty(a_szValue)) { if (iKey < callstack.lkeyvalue.Count) { callstack.lkeyvalue.Remove(callstack.lkeyvalue[iKey]); m_lcallstack[m_lcallstack.Count - 1] = callstack; } return; } // Create a new keyvalue... KeyValue keyvalueNew = default(KeyValue); keyvalueNew.szKey = a_szKey; keyvalueNew.szValue = a_szValue; keyvalueNew.iBytes = a_iBytes; // If the key already exists, update its value... if (iKey < callstack.lkeyvalue.Count) { callstack.lkeyvalue[iKey] = keyvalueNew; m_lcallstack[m_lcallstack.Count - 1] = callstack; return; } // Otherwise, add it, and sort... callstack.lkeyvalue.Add(keyvalueNew); callstack.lkeyvalue.Sort(SortByKeyAscending); m_lcallstack[m_lcallstack.Count - 1] = callstack; // All done... return; } // Global: we need protection... lock (m_objectKeyValue) { // Find the value for this key... for (iKey = 0; iKey < m_lkeyvalue.Count; iKey++) { if (m_lkeyvalue[iKey].szKey == a_szKey) { break; } } // If we have no value to set, then delete this item... if (string.IsNullOrEmpty(a_szValue)) { if (iKey < m_lkeyvalue.Count) { m_lkeyvalue.Remove(m_lkeyvalue[iKey]); } return; } // Create a new keyvalue... KeyValue keyvalueNew = default(KeyValue); keyvalueNew.szKey = a_szKey; keyvalueNew.szValue = a_szValue; keyvalueNew.iBytes = a_iBytes; // If the key already exists, update its value... if (iKey < m_lkeyvalue.Count) { m_lkeyvalue[iKey] = keyvalueNew; return; } // Otherwise, add it, and sort... m_lkeyvalue.Add(keyvalueNew); m_lkeyvalue.Sort(SortByKeyAscending); } } /// /// A comparison operator for sorting keys in CmdSet... /// /// /// /// private int SortByKeyAscending(KeyValue a_keyvalue1, KeyValue a_keyvalue2) { return (a_keyvalue1.szKey.CompareTo(a_keyvalue2.szKey)); } /// /// Set the return value on the top callstack item... /// /// /// private void SetReturnValue(string a_szReturnValue) { if (m_lcallstack.Count < 1) return; CallStack callstack = m_lcallstack[m_lcallstack.Count - 1]; callstack.functionarguments.szReturnValue = a_szReturnValue; m_lcallstack[m_lcallstack.Count - 1] = callstack; } #endregion // Private Definitions #region Private Definitions /// /// Select the cloud import code we're working with... /// private enum CloudImport { Undefined, HazyBits } /// /// A key/value pair... /// private struct KeyValue { /// /// Our key... /// public string szKey; /// /// The key's value... /// public string szValue; /// /// The bytesize of value, only used when /// value is an IntPtr to memory... /// public int iBytes; } /// /// Call stack info... /// private struct CallStack { /// /// The arguments to this call... /// public Interpreter.FunctionArguments functionarguments; public List lkeyvalue; } #endregion // Private Attributes #region Private Attributes /// /// Our TWAIN object... /// private TWAIN m_twain; // The handle to our window... private FormMain m_formmain; private IntPtr m_intptrHwnd; /// /// Map commands to functions... /// private List m_ldispatchtable; /// /// Our console input...embiggened... /// private StreamReader m_streamreaderConsole; private ConsoleColor m_consolecolorDefault; private ConsoleColor m_consolecolorBlue; private ConsoleColor m_consolecolorGreen; private ConsoleColor m_consolecolorRed; private ConsoleColor m_consolecolorYellow; /// /// No output when this is true... /// private bool m_blSilent; private bool m_blSilentEvents; private bool m_blRunningScript; private bool m_blVerbose; private int m_iSilentRestore; private int m_iVerboseRestore; /// /// The list of key/value pairs created by the SET command... /// private List m_lkeyvalue; private object m_objectKeyValue; private string m_szSetRecordVariable; private string m_szSetRecordFilter; private string m_szSetRecordRemove; private string m_szSetRecordData; /// /// A last in first off stack of function calls... /// private List m_lcallstack; /// /// Our certification report, in glorious text... /// private StringBuilder m_stringbuilderSelfCertReport; private string m_szSelfCertReportPath; private string m_szSelfCertReportProductname; private string m_szTwainSelfCertFolder; private string m_szSelfCertDriverVersion; private string m_szSelfCertDataCertFolder; /// /// The opening banner (program, version, etc)... /// private string m_szBanner; /// /// List of scanners paired with us in a cloud... /// private AutoResetEvent m_autoreseteventScannerslist; /// /// We use this to run code in the context of the caller's UI thread... /// /// object (really a control) /// code to run public delegate void RunInUiThreadDelegate(Object a_object, Action a_action); /// /// The list of pending DAT_NULL events... /// private List m_lmsgDatNull = new List(); private AutoResetEvent m_autoreseteventMsgDatNull = new AutoResetEvent(false); #endregion } /// /// Our configuration object. We must be able to access this /// from anywhere in the code... /// public static class Config { // Public Methods... #region Public Methods... /// /// Get a value, if the value can't be found, return a default. We look /// for the item first in the command line arguments, then in the data /// read from the config file, and finally based on a small collection of /// keywords accessing static information. This way we can override the /// configuration at any point with a minimum of fuss. /// /// the item we're seeking /// the default if we don't find it /// the result public static string Get(string a_szKey, string a_szDefault) { // Try the command line first... if (ms_aszCommandLine != null) { string szKey = a_szKey + "="; foreach (string sz in ms_aszCommandLine) { if ((sz == a_szKey) || (sz == szKey)) { return (""); } if (sz.StartsWith(szKey)) { return (sz.Remove(0, szKey.Length)); } } } // Try the JSON... if (ms_jsonlookup != null) { string szValue; JsonLookup.EPROPERTYTYPE epropertytype; if (ms_jsonlookup.GetCheck(a_szKey, out szValue, out epropertytype, false)) { return (szValue); } } // Try the folders... if (a_szKey == "executablePath") { return (ms_szExecutablePath); } if (a_szKey == "executableName") { return (ms_szExecutableName); } if (a_szKey == "readFolder") { return (ms_szReadFolder); } if (a_szKey == "writeFolder") { return (ms_szWriteFolder); } // This is our default for the pfxFile, but only // if the user didn't override it with their own // default... if ((a_szKey == "pfxFile") && string.IsNullOrEmpty(a_szDefault)) { return (Path.Combine(Path.Combine(ms_szReadFolder, "data"), "certificate.p12")); } // All done... return (a_szDefault); } /// /// Get a long value, if the value can't be found, return a default... /// /// /// /// public static long Get(string a_szKey, long a_lDefault) { // Get the value... string szValue = Get(a_szKey, "@@@NOTFOUND@@@@"); // We didn't find it, use the default... if (szValue == "@@@NOTFOUND@@@@") { return (a_lDefault); } // Try to get the value... long lValue; if (long.TryParse(szValue, out lValue)) { return (lValue); } // No joy, use the default... return (a_lDefault); } /// /// Get a double value, if the value can't be found, return a default... /// /// /// /// public static double Get(string a_szKey, double a_dfDefault) { // Get the value... string szValue = Get(a_szKey, "@@@NOTFOUND@@@@"); // We didn't find it, use the default... if (szValue == "@@@NOTFOUND@@@@") { return (a_dfDefault); } // Try to get the value... double dfValue; if (double.TryParse(szValue, out dfValue)) { return (dfValue); } // No joy, use the default... return (a_dfDefault); } /// /// Return the command line passed into us... /// /// the command line public static string[] GetCommandLine() { return (ms_aszCommandLine); } /// /// Get a string from the supplied resource, return the key if we can't /// find the resource... /// /// resource to use /// key to lookup /// string we found, or the keyname public static string GetResource(ResourceManager a_resourcemanager, string a_szKey) { string szResult = ""; // Ruh-roh... if (a_resourcemanager == null) { return (a_szKey); } // Also, ruh-roh... try { szResult = a_resourcemanager.GetString(a_szKey); } catch { return (a_szKey); } if (string.IsNullOrEmpty(szResult)) { return (a_szKey); } // Got it... return (szResult); } /// /// Load the configuration object. We want to read in the /// configuaration data (in JSON format) and a list of the /// command line arguments. /// /// the fill path to the program using us /// key[=value] groupings /// a JSON file public static bool Load(string a_szExecutablePath, string[] a_aszCommandLine, string a_szConfigFile) { try { // Work out where our executable lives... ms_szExecutablePath = a_szExecutablePath; ms_szExecutableName = Path.GetFileNameWithoutExtension(ms_szExecutablePath); // The read folder is the path to the executable. This is where we're // going to find our appdata.txt file, which contains configuration // information that can be overridden by the user (assuming they have // rights to it). We'll put other readonly stuff here too, like the // certification tests... ms_szReadFolder = Path.GetDirectoryName(ms_szExecutablePath); // The write folder is the path to all of the the files we can update, // which includes image files, metadata, log files, registration/selection // files. This stuff is specific to a user, so by default we're going to // keep it in their %appdata%/TwainWorkingGroup/twaicscert/executablename folder... ms_szWriteFolder = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData); ms_szWriteFolder = Path.Combine(ms_szWriteFolder, "TwainWorkingGroup"); ms_szWriteFolder = Path.Combine(ms_szWriteFolder, ms_szExecutableName); // Store the command line... ms_aszCommandLine = a_aszCommandLine; // Load the config, we'll first look for a name decorated version // of the file (ex: TwainDirect.Scanner.appdata.txt) in the data // folder, and if that fails we'll try the same folder as the .exe, // if that fails we'll do just the name given to us... string szConfigFile = Path.Combine(Path.Combine(ms_szReadFolder, "data"), ms_szExecutableName + "." + a_szConfigFile); if (!File.Exists(szConfigFile)) { szConfigFile = Path.Combine(ms_szReadFolder, ms_szExecutableName + "." + a_szConfigFile); if (!File.Exists(szConfigFile)) { szConfigFile = Path.Combine(ms_szReadFolder, a_szConfigFile); } } if (File.Exists(szConfigFile)) { long a_lJsonErrorindex; string szConfig = File.ReadAllText(szConfigFile); ms_jsonlookup = new JsonLookup(); ms_jsonlookup.Load(szConfig, out a_lJsonErrorindex); } // Check if the user wants to override the read and write folders... ms_szReadFolder = Get("readFolder", ms_szReadFolder); ms_szWriteFolder = Get("writeFolder", ms_szWriteFolder); // Make sure we have a write folder... if (!Directory.Exists(ms_szWriteFolder)) { Directory.CreateDirectory(ms_szWriteFolder); } } catch { return (false); } // All done... return (true); } /// /// Return 32 or 64... /// /// 32 or 64 public static long GetMachineWordSize() { if (IntPtr.Size == 4) { return (32); } return (64); } /// /// Put a UAC shield on a button... /// public static void ElevateButton(IntPtr a_intptrHandle) { NativeMethods.SendMessage(a_intptrHandle, NativeMethods.BCM_SETSHIELD, IntPtr.Zero, IntPtr.Zero - 1); } #endregion // Private Attributes... #region Private Attributes /// /// The command line arguments... /// private static string[] ms_aszCommandLine = null; /// /// The JSON lookup object that contains any configuration data /// tht we want to access using a Get() command... /// private static JsonLookup ms_jsonlookup = null; /// /// The full path to our program... /// private static string ms_szExecutablePath; /// /// The base name, without extension of our program... /// private static string ms_szExecutableName; /// /// The readonly folder, which includes binaries and template /// files that are never updated by running code... /// private static string ms_szReadFolder; /// /// The writeable folder, which is where logs, temporary files, /// and configurable content is located... /// private static string ms_szWriteFolder; #endregion } /// /// Interpret and dispatch user commands... /// public sealed class Interpreter { // Public Methods #region Public Methods /// /// Our constructor... /// /// initialize the prompt public Interpreter(string a_szPrompt, ConsoleColor a_consolecolorDefault, ConsoleColor a_consolecolorPrompt) { // Our prompt... m_szPrompt = (string.IsNullOrEmpty(a_szPrompt) ? ">>>" : a_szPrompt); m_consolecolorDefault = a_consolecolorDefault; m_consolecolorPrompt = a_consolecolorPrompt; } /// /// Create a console on Windows... /// public static StreamReader CreateConsole() { // Make sure we have a console... if (TWAIN.GetPlatform() == TWAIN.Platform.WINDOWS) { // Get our console... NativeMethods.AllocConsole(); // Only do this junk if running under Visual Studio, note that we'll // lose color. So it goes... if (System.Diagnostics.Debugger.IsAttached) { var handle = NativeMethods.CreateFile ( "CONOUT$", NativeMethods.DesiredAccess.GenericWrite | NativeMethods.DesiredAccess.GenericWrite, NativeMethods.FileShare.Read | NativeMethods.FileShare.Write, IntPtr.Zero, NativeMethods.CreationDisposition.OpenExisting, NativeMethods.FileAttributes.Normal, IntPtr.Zero ); SafeFileHandle safefilehandle = new SafeFileHandle(handle, true); FileStream fileStream = new FileStream(safefilehandle, FileAccess.Write); StreamWriter streamwriterStdout = new StreamWriter(fileStream, Encoding.ASCII); streamwriterStdout.AutoFlush = true; Console.SetOut(streamwriterStdout); } } // And because life is hard, we need to up the size of standard input... StreamReader streamreaderConsole = new StreamReader(Console.OpenStandardInput(65536)); return (streamreaderConsole); } /// /// Get the desktop windows for Windows systems... /// /// public static IntPtr GetDesktopWindow() { // Get an hwnd... if (TWAIN.GetPlatform() == TWAIN.Platform.WINDOWS) { return (NativeMethods.GetDesktopWindow()); } else { return (IntPtr.Zero); } } /// /// Prompt for input, returning a string, if there's any data... /// /// the console to use /// twain state /// data captured public string Prompt(StreamReader a_streamreaderConsole, int a_iTwainState, bool a_blAllowEmptyLine = false, bool a_blEcho = false) { string szCmd; // Read in a line... while (true) { string szPrompt = m_szPrompt; if (a_iTwainState > 0) { szPrompt = szPrompt.Replace(">>>", a_iTwainState + ">>>"); } // Write out the prompt... if (Console.BackgroundColor == ConsoleColor.Black) { Console.ForegroundColor = m_consolecolorPrompt; Console.Out.Write(szPrompt); Console.ForegroundColor = m_consolecolorDefault; } else { Console.Out.Write(szPrompt); } // Read in a line... if (!Environment.OSVersion.ToString().Contains("Microsoft Windowsxxx")) { szCmd = (a_streamreaderConsole == null) ? Console.In.ReadLine() : a_streamreaderConsole.ReadLine(); if (string.IsNullOrEmpty(szCmd)) { if (a_blAllowEmptyLine) { break; } continue; } } else { szCmd = Console.ReadLine(); break; /* List lchLine = new List(); TextReader textreader = (a_streamreaderConsole == null) ? Console.In : a_streamreaderConsole; bool blTyping = true; while (blTyping) { ConsoleKeyInfo consolekeyinfo = Console.ReadKey(); int iCh = consolekeyinfo.KeyChar; // textreader.Read(); switch (iCh) { // A character... default: lchLine.Add((char)iCh); if (a_blEcho) { Console.Out.Write((char)iCh); } break; // Backspace and delete... case 0x08: case 0x7f: if (lchLine.Count > 0) { lchLine.RemoveAt(lchLine.Count - 1); if (a_blEcho) { Console.Out.Write('\b'); Console.Out.Write(' '); Console.Out.Write('\b'); } } break; // Newline and carriage return... case 0x0a: case 0x0d: Console.Out.Write((char)iCh); blTyping = false; break; } } szCmd = ""; foreach (char ch in lchLine) { szCmd += ch; } */ } // Trim whitespace... szCmd = szCmd.Trim(); if (string.IsNullOrEmpty(szCmd)) { if (!a_blAllowEmptyLine) { continue; } } // We must have data... break; } // All done... return (szCmd); } /// /// Change the prompt... /// /// new prompt public void SetPrompt(string a_szPrompt) { m_szPrompt = a_szPrompt; } /// /// Tokenize a string, with support for single quotes and double quotes. /// Inside the body of a quote the only thing can can be (or needs to be) /// escaped is the current quote token. The result is an array of strings... /// /// command to tokenize /// array of strings public string[] Tokenize(string a_szCmd) { int cc; int tt; char szQuote = (char)0; string[] aszTokens; // We're coming out of this with at least one token... aszTokens = new string[1]; tt = 0; // Validate... if (string.IsNullOrEmpty(a_szCmd)) { aszTokens[tt] = ""; return (aszTokens); } // Handle comments... if (a_szCmd[0] == ';') { aszTokens[tt] = ""; return (aszTokens); } // Skip over goto labels... if (a_szCmd[0] == ':') { aszTokens[tt] = ""; return (aszTokens); } // If we have no special characters, then we're done... if (a_szCmd.IndexOfAny(new char[] { ' ', '\t', '\'', '"' }) == -1) { aszTokens[tt] = a_szCmd; return (aszTokens); } // Devour leading whitespace... cc = 0; while ((cc < a_szCmd.Length) && ((a_szCmd[cc] == ' ') || (a_szCmd[cc] == '\t'))) { cc += 1; } // Loopy... while (cc < a_szCmd.Length) { // Handle single and double quotes... if ((a_szCmd[cc] == '\'') || (a_szCmd[cc] == '"')) { // Skip the quote... szQuote = a_szCmd[cc]; cc += 1; // Copy all of the string to the next unescaped single quote... while (cc < a_szCmd.Length) { // We found our terminator (don't copy it)... if (a_szCmd[cc] == szQuote) { szQuote = (char)0; cc += 1; break; } // We're escaping the quote... if ((cc + 1 < a_szCmd.Length) && (a_szCmd[cc] == '\\') && (a_szCmd[cc + 1] == szQuote)) { aszTokens[tt] += szQuote; cc += 1; } // Otherwise, just copy the character... else { aszTokens[tt] += a_szCmd[cc]; } // Next character... cc += 1; } } // Handle whitespace... else if ((a_szCmd[cc] == ' ') || (a_szCmd[cc] == '\t')) { // Devour all of the whitespace... while ((cc < a_szCmd.Length) && ((a_szCmd[cc] == ' ') || (a_szCmd[cc] == '\t'))) { cc += 1; } // If we have more data, prep for it... if (cc < a_szCmd.Length) { string[] asz = new string[aszTokens.Length + 1]; Array.Copy(aszTokens, asz, aszTokens.Length); asz[aszTokens.Length] = ""; aszTokens = asz; tt += 1; } } // Bail if we find an inline comment... else if ((szQuote == (char)0) && (a_szCmd[cc] == ';')) { Array.Resize(ref aszTokens, aszTokens.Length - 1); break; } // Anything else is data in the current token... else { aszTokens[tt] += a_szCmd[cc]; cc += 1; } // Next character., } // All done... return (aszTokens); } /// /// Dispatch a command... /// /// the arguments to the command /// dispatch table /// true if the program should exit public bool Dispatch(ref FunctionArguments a_functionarguments, List a_ldispatchtable) { string szCmd; // Apparently we got nothing, it's a noop... if ((a_functionarguments.aszCmd == null) || (a_functionarguments.aszCmd.Length == 0) || string.IsNullOrEmpty(a_functionarguments.aszCmd[0])) { return (false); } // Find the command... szCmd = a_functionarguments.aszCmd[0].ToLowerInvariant(); foreach (DispatchTable dispatchtable in a_ldispatchtable) { foreach (string sz in dispatchtable.m_aszCmd) { if (sz == szCmd) { return (dispatchtable.m_function(ref a_functionarguments)); } } } // No joy, make sure to lose the last transaction if the // user enters a bad command, so that we reduce the risk // of it be badly interpreted later on... if (string.IsNullOrEmpty(a_functionarguments.szScriptFile)) { Console.Out.WriteLine("command not found: " + a_functionarguments.aszCmd[0]); } else { Console.Out.WriteLine ( "command not found: " + a_functionarguments.aszCmd[0] + " ('" + a_functionarguments.szScriptFile + "' at line " + (a_functionarguments.iCurrentLine + 1) + ")" ); } return (false); } #endregion // Public Definitions #region Public Definitions public struct FunctionArguments { /// /// The tokenized command... /// public string[] aszCmd; /// /// The script we're running or null, used for /// commands like "goto"... /// public string szScriptFile; public string[] aszScript; /// /// True if we've been asked to jump to a label, /// which includes the index to go to... /// public bool blGotoLabel; public int iLabelLine; /// /// The command triplet... /// public int iDg; public int iDat; public int iMsg; /// /// The status return from the driver... /// public TWAIN.STS sts; /// /// The function value when returning from a call... /// public string szReturnValue; /// /// The current line in the script... /// public int iCurrentLine; } /// /// Function to call from the Dispatcher... /// /// arguments /// script or null /// true if the program should exit public delegate bool Function(ref FunctionArguments a_functionarguments); /// /// Map commands to functions... /// public class DispatchTable { /// /// Stock our entries... /// /// the function /// command variants for this function public DispatchTable(Function a_function, string[] a_aszCmd) { m_aszCmd = a_aszCmd; m_function = a_function; } /// /// Variations for this command... /// public string[] m_aszCmd; /// /// Function to call... /// public Function m_function; } #endregion // Private Attributes #region Private Attributes /// /// Our prompt... /// private string m_szPrompt; private ConsoleColor m_consolecolorDefault; private ConsoleColor m_consolecolorPrompt; #endregion } /// /// This is a simple JSON parser. It was written by staring at the JSON /// railroad diagrams and coding like a loon, and then stress testing it /// with a variety of real world strings. /// /// It makes no claims to being overly fast. It is relatively efficient /// insofar as it makes a single pass, doesn't munge the original string /// and creates a tree representing the data. /// /// It's main benefit is that it doesn't require a binding to a strongly /// typed class, so the data can be literally anything. And it supports /// a simple dotted notation for looking up content. Adding functions /// to allow for enumerating the data wouldn't be hard, but haven't been /// added at this time. /// /// Two functions do all the heavy lifting: /// /// bool Load(string a_szJson, out lResponseCharacterOffset) /// Causes the class to parse the JSON data and create an internal /// data structure for it. If a problem occurs it returns false and /// an index into the string showering where the badness occurred. /// /// string Get(string a_szKey) /// Returns a string for the item that was found. If you need to /// know the type, then use the GetCheck function. /// /// Here's some sample JSON: /// { /// "array": [ /// { /// "first": 1 /// }, /// { /// "second": { /// "third": 3 /// } /// } /// ] /// } /// /// To get the data for "third" we use the key: /// /// array[1].second.third /// /// As you might expect, if the property name has a dot or square /// brackets in it, that would cause a problem. This isn't an issue /// for how we plan to use it, but it would be possible to get /// around it if needed, by using a prefix delimiter in the lookup /// string. /// /// Clarity is a good thing, and hopefully this code is fairly simple to /// chug through. /// public sealed class JsonLookup { /////////////////////////////////////////////////////////////////////////////// // Public Methods... /////////////////////////////////////////////////////////////////////////////// #region Public Methods... /// /// Init stuff... /// public JsonLookup() { m_blStrictParsingRules = false; m_property = null; m_szJson = null; } /// /// Dump the contents of the property tree... /// /// the JSON string public string Dump() { if (m_lkeyvalueOverride == null) { m_lkeyvalueOverride = new List(); } return (DumpPrivate(m_property, 0, "", false)); } /// /// Does a find, and if the item is found, does a get... /// /// key to find /// array index to start at /// count of array elements to search /// value to return /// type of property that we've found /// log if key isn't found /// 0 - n on success, -1 on failure public int FindGet(string a_szKey, int a_iStartingIndex, int a_iCount, out string a_szValue, out EPROPERTYTYPE a_epropertytype, bool a_blLog) { bool blSuccess; int iIndex; int iIndexBrackets; string szKey; // Init stuff... a_szValue = ""; a_epropertytype = EPROPERTYTYPE.UNDEFINED; // Find the item... iIndex = FindKey(a_szKey, a_iStartingIndex, a_iCount); if (iIndex < 0) { return (iIndex); } // If we found it, then create the full key at this index... iIndexBrackets = a_szKey.IndexOf("[]."); if (iIndexBrackets < 0) { return (-1); } szKey = a_szKey.Substring(0, iIndexBrackets) + "[" + iIndex + "]." + a_szKey.Substring(iIndexBrackets + 3); // And get the data... blSuccess = GetCheck(szKey, out a_szValue, out a_epropertytype, a_blLog); if (!blSuccess) { return (-1); } // All done... return (iIndex); } /// /// Find a key in an array of objects. The JSON needs to take /// a form similar to: /// { "array":[ /// {"key1":data}, /// {"key2":data}, /// {"key3":data}, /// ... /// } /// In this case a search string could be: /// array[].key2 /// Where [] indicates the array to be enumerated, and key2 is /// the property name we're searching for. In the case of a /// rooted array like: /// [ /// {"key1":data}, /// {"key2":data}, /// {"key3":data}, /// ... /// ] /// Then the search string would be [].key2 /// /// key to find /// array index to start at /// count of array elements to search /// 0 - n on success, -1 on failure public int FindKey(string a_szKey, int a_iStartingIndex = 0, int a_iCount = 0) { bool blSuccess; int iCount; int iIndex; string szKey; string szKeyLeft; string szKeyRight; string szValue; EPROPERTYTYPE epropertytype; // Validate... if (string.IsNullOrEmpty(a_szKey) || (a_iStartingIndex < 0) || (a_iCount < 0)) { return (-1); } // The function is useless unless it can enumerate through an array, // so just bail if the user didn't ask for this... iIndex = a_szKey.IndexOf("[]."); if (iIndex == -1) { return (-1); } // Get the left and right sides of the key... szKeyLeft = a_szKey.Substring(0, iIndex); szKeyRight = a_szKey.Substring(iIndex + 3); // The left side can be empty, but not the right side... if (string.IsNullOrEmpty(szKeyRight)) { return (-1); } // The left side must be found, and it must be an array... blSuccess = GetCheck(szKeyLeft, out szValue, out epropertytype, false); if (!blSuccess || (epropertytype != EPROPERTYTYPE.ARRAY)) { return (-1); } // Figure out our endpoint in the array... if (a_iCount == 0) { iCount = int.MaxValue; } else { iCount = a_iStartingIndex + a_iCount; } // Okay, it's time to loop. We need to make sure the array item exists // before we look for the key, so this is a two step process... for (iIndex = a_iStartingIndex; iIndex < iCount; iIndex++) { // Build the array key... szKey = szKeyLeft + "[" + iIndex + "]"; // Does the array element exist? And is it an object? blSuccess = GetCheck(szKey, out szValue, out epropertytype, false); if (!blSuccess || (epropertytype != EPROPERTYTYPE.OBJECT)) { return (-1); } // Okay, try to get the full key... szKey += "." + szKeyRight; blSuccess = GetCheck(szKey, out szValue, out epropertytype, false); if (blSuccess) { return (iIndex); } } // No joy... return (-1); } /// /// Get the string associated with the key. This is a convenience /// function, because in most cases getting back a null string is /// enough, so we don't need a special boolean check... /// /// dotted key notation /// value to return /// string on success, else null public string Get(string a_szKey, bool a_blLog = true) { bool blSuccess; string szValue; EPROPERTYTYPE epropertytype; // Do the lookup... blSuccess = GetCheck(a_szKey, out szValue, out epropertytype, a_blLog); // We're good... if (blSuccess) { return (szValue); } // Ruh-roh... return (null); } /// /// Get the string associated with the key, and let us know how /// the lookup turned out... /// /// dotted key notation /// value to return /// type of property that we've found /// log if key isn't found /// true on success public bool GetCheck(string a_szKey, out string a_szValue, out EPROPERTYTYPE a_epropertytype, bool a_blLog) { string[] aszKey; string szIndex; string szBaseName; string szProperty; UInt32 kk; UInt32 uu; UInt32 u32Index; Property property; // Init... a_szValue = ""; a_epropertytype = EPROPERTYTYPE.UNDEFINED; // Validate... if ((a_szKey == null) || (m_property == null)) { Log.Error("GetCheck: null argument..."); return (false); } // If the key is empty, return the whole object... if (a_szKey.Length == 0) { a_szValue = m_szJson; a_epropertytype = m_property.epropertytype; return (true); } // Fully tokenize the key so we can look ahead when needed... aszKey = a_szKey.Split('.'); // Search, always skip the root if it's an object, // if it's an array we need to process it... property = m_property; if (property.epropertytype == EPROPERTYTYPE.OBJECT) { property = m_property.propertyChild; } for (kk = 0; kk < aszKey.Length; kk++) { // Extract the basename, in case we have an index... szBaseName = aszKey[kk]; if (szBaseName.Contains("[")) { szBaseName = szBaseName.Substring(0, szBaseName.IndexOf('[')); } // Look for a match among the siblings at this level... while (property != null) { GetProperty(property, out szProperty); if (szProperty == szBaseName) { break; } property = property.propertySibling; } // No joy... if (property == null) { if (a_blLog) { Log.Info("GetCheck: key not found..." + a_szKey); } return (false); } // If we found a value, then we're done... if ((property.epropertytype == EPROPERTYTYPE.STRING) || (property.epropertytype == EPROPERTYTYPE.NUMBER) || (property.epropertytype == EPROPERTYTYPE.BOOLEAN) || (property.epropertytype == EPROPERTYTYPE.NULL)) { // If there's more to the key, then we weren't successful... if ((kk + 1) < aszKey.Length) { if (a_blLog) { Log.Info("GetCheck: key not found..." + a_szKey); } return (false); } // Return what we found... return (GetValue(property, out a_szValue, out a_epropertytype)); } // We found an object... if (property.epropertytype == EPROPERTYTYPE.OBJECT) { // We've no more keys, so return the object... if ((kk + 1) >= aszKey.Length) { return (GetValue(property, out a_szValue, out a_epropertytype)); } // Otherwise, step into the object... property = property.propertyChild; continue; } // If we're an array, we need to walk the siblings of the child... if (property.epropertytype == EPROPERTYTYPE.ARRAY) { // If we don't have a '[' and this is the last key, return the whole thing... if (!aszKey[kk].Contains("[") && ((kk + 1) >= aszKey.Length)) { return (GetValue(property, out a_szValue, out a_epropertytype)); } // If we don't have a '[' and there is more to the key, we're in trouble... else if (!aszKey[kk].Contains("[") && ((kk + 1) < aszKey.Length)) { if (a_blLog) { Log.Info("GetCheck: key not found..." + a_szKey); } return (false); } // We must have a valid index in the key... szIndex = aszKey[kk].Substring(aszKey[kk].IndexOf('[')); if ((szIndex.Length < 3) || !szIndex.StartsWith("[") || !szIndex.EndsWith("]")) { if (a_blLog) { Log.Info("GetCheck: key not found..." + a_szKey); } return (false); } // Get the basename and look for a match... if (!UInt32.TryParse(szIndex.Substring(1, szIndex.Length - 2), out u32Index)) { if (a_blLog) { Log.Info("GetCheck: key not found..." + a_szKey); } return (false); } // Step into the child... property = property.propertyChild; if (property == null) { if (a_blLog) { Log.Info("GetCheck: key not found..." + a_szKey); } return (false); } // Walk the siblings in this child... for (uu = 0; uu < u32Index; uu++) { property = property.propertySibling; if (property == null) { if (a_blLog) { Log.Info("GetCheck: key not found..." + a_szKey); } return (false); } } // We've no more keys, so return the object... if ((kk + 1) >= aszKey.Length) { return (GetValue(property, out a_szValue, out a_epropertytype)); } // If the thing we hit is an object, then we need to step into it... if (property.epropertytype == EPROPERTYTYPE.OBJECT) { property = property.propertyChild; } // Otherwise, keep on looking... continue; } // Well, this was unexpected... Log.Info("GetCheck: unexpected error..." + a_szKey); return (false); } // All done... return (true); } /// /// Get the string associated with the key. This is a convenience /// function, because in most cases getting back a null string is /// enough, so we don't need a special boolean check. /// /// The caller of this function is expecting to get back JSON data /// in string form. We examine that data, looking for evidence /// that the strings are escaped, and if so, we unescape them. /// /// dotted key notation /// value to return /// string on success, else null public string GetJson(string a_szKey) { bool blSuccess; int iIndex; string szValue; EPROPERTYTYPE epropertytype; // Do the lookup... blSuccess = GetCheck(a_szKey, out szValue, out epropertytype, true); // No joy... if (!blSuccess) { return (null); } // Look for the first double-quote in the string, if the character // before it is a backslash, then we'll replace all of the \" with // ". By definition the " has to be in index 1 or higher for this // to make sense, so we can ignore index 0... iIndex = szValue.IndexOf('"'); if (iIndex >= 1) { if (szValue[iIndex - 1] == '\\') { szValue = szValue.Replace("\\\"", "\""); } } // Ruh-roh... return (szValue); } /// /// Get the property of the key, if not found we'll come back /// with undefined... /// /// dotted key notation /// type of the property public JsonLookup.EPROPERTYTYPE GetType(string a_szKey) { bool blSuccess; string szValue; JsonLookup.EPROPERTYTYPE epropertytype; // Do the lookup... blSuccess = GetCheck(a_szKey, out szValue, out epropertytype, true); // We're good... if (blSuccess) { return (epropertytype); } // Ruh-roh... return (JsonLookup.EPROPERTYTYPE.UNDEFINED); } /// /// Get the JSON data as XML. This is a simple name/value conversion... /// /// instead of o, use this as the name for the outermost tag /// the XML string public string GetXml(string a_szRootName = "") { return (GetXmlPrivate(m_property, a_szRootName, 0, "")); } /// /// Loads a JSON string... /// /// JSON string to parse /// index where error occurred, if return is false /// true on success public bool Load(string a_szJson, out long a_lJsonErrorindex) { bool blSuccess; UInt32 u32Json; // Init stuff... a_lJsonErrorindex = 0; // Free old content... Unload(); // We have no new data... if (a_szJson == null) { return (true); } // Make a copy of the string, in C# we'll work with the // index instead of pointers like we do in C/C++... u32Json = 0; m_szJson = a_szJson; // Parse the JSON and return... blSuccess = Deserialize(ref u32Json); if (!blSuccess) { a_lJsonErrorindex = u32Json; Unload(); } // All done... return (blSuccess); } /// /// Add an override for the Dump. A value of null can be used /// to "delete" an override. Overrides are only supported for /// boolean, null, number, and string. It would be possible to /// add support for array and object, but that seems a lot more /// risky, so I'm holding off for now. /// /// /// public void Override(string a_szKey, string a_szValue) { // Make sure we have our list... if (m_lkeyvalueOverride == null) { m_lkeyvalueOverride = new List(); } // If we already have this key, remove it... int iIndex = m_lkeyvalueOverride.FindIndex(item => item.szKey == a_szKey); if (iIndex >= 0) { m_lkeyvalueOverride.RemoveAt(iIndex); } // Add the new data to our list... if (a_szValue != null) { KeyValue keyvalue = new KeyValue(); keyvalue.szKey = a_szKey; keyvalue.szValue = a_szValue; m_lkeyvalueOverride.Add(keyvalue); } } #endregion /////////////////////////////////////////////////////////////////////////////// // Public Definitions... /////////////////////////////////////////////////////////////////////////////// #region Public Definitions... /// /// The kinds of data types we can get from the class... /// public enum EPROPERTYTYPE { UNDEFINED = 0, ARRAY = 1, OBJECT = 2, STRING = 3, BOOLEAN = 4, NUMBER = 5, NULL = 6, LAST }; #endregion /////////////////////////////////////////////////////////////////////////////// // Private Methods... /////////////////////////////////////////////////////////////////////////////// #region Private Methods... /// /// The control function for parsing the JSON string... /// /// JSON to parse /// true on success private bool Deserialize(ref UInt32 a_u32Json) { UInt32 u32Json = a_u32Json; // Validate... if (string.IsNullOrEmpty(m_szJson)) { Log.Error("Deserialize: null arguments..."); return (false); } // Initialize the first property as root... m_property = new Property(); // Clear any whitespace... if (!SkipWhitespace(ref u32Json)) { Log.Error("Deserialize: we ran out of data..."); a_u32Json = u32Json; return (false); } // We have an object... if (m_szJson[(int)u32Json] == '{') { // What we are... m_property.epropertytype = EPROPERTYTYPE.OBJECT; // We don't need a colon, we just go straight to looking for the object, // this function returns the closing curly bracket (if it finds it)... if (!ParseObject(m_property, ref u32Json)) { Log.Error("Deserialize: ParseObject failed..."); a_u32Json = u32Json; return (false); } } // Else we have an array... else if (m_szJson[(int)u32Json] == '[') { // What we are... m_property.epropertytype = EPROPERTYTYPE.ARRAY; // We don't need a colon, we just go straight to looking for the object, // this function returns the closing curly bracket (if it finds it)... if (!ParseArray(m_property, ref u32Json)) { Log.Error("Deserialize: ParseArray failed..."); a_u32Json = u32Json; return (false); } } // Else we have a problem... else { Log.Error("Deserialize: bad token..."); a_u32Json = u32Json; return (false); } // All of the remaining content can only be whitespace... if (SkipWhitespace(ref u32Json)) { Log.Error("Deserialize: found cruft..."); a_u32Json = u32Json; return (false); } // All done... a_u32Json = u32Json; return (true); } /// /// Diagnostic dump of the results of a Load, this function /// runs recursively... /// /// property to dump /// depth we're at /// key for this item /// true if we're elements in an array /// the JSON string private string DumpPrivate ( Property a_property, int a_iDepth, string a_szKey, bool a_blArray ) { int iArray; string szKey; string szName; string szValue; string szResult; Property property; KeyValue keyvalue; EPROPERTYTYPE epropertytype; // Init... iArray = -1; szResult = ""; property = a_property; if (property == null) { property = m_property; } // Dump... while (property != null) { // Our key... szKey = a_szKey; // We're in an array, so subscript us... if (a_blArray) { iArray += 1; szKey += "[" + iArray + "]"; } switch (property.epropertytype) { // This can't be right... default: return (""); // Dump an array... case EPROPERTYTYPE.ARRAY: // name:[ or just [ GetProperty(property, out szName); if (!string.IsNullOrEmpty(szName)) { szResult += "\"" + szName + "\":["; szKey += string.IsNullOrEmpty(szKey) ? szName : "." + szName; } else { szResult += "["; } // If we have a kiddie, dive down into it... if (property.propertyChild != null) { szResult += DumpPrivate(property.propertyChild, a_iDepth + 1, szKey, true); } // If the last character is a comma, remove it... if (szResult.EndsWith(",")) { szResult = szResult.Remove(szResult.Length - 1); } // just ], szResult += "],"; break; // Dump a boolean, null, or number... case EPROPERTYTYPE.BOOLEAN: case EPROPERTYTYPE.NULL: case EPROPERTYTYPE.NUMBER: GetProperty(property, out szName); szKey += string.IsNullOrEmpty(szKey) ? szName : "." + szName; keyvalue = m_lkeyvalueOverride.Find(item => item.szKey == szKey); if ((keyvalue == null) || (keyvalue.szValue == null)) { GetValue(property, out szValue, out epropertytype); szResult += "\"" + szName + "\":" + szValue + ","; } else { szResult += "\"" + szName + "\":" + keyvalue.szValue + ","; } break; // Dump an object... case EPROPERTYTYPE.OBJECT: // name:{ or just { GetProperty(property, out szName); if (!string.IsNullOrEmpty(szName)) { szResult += "\"" + szName + "\":{"; szKey += string.IsNullOrEmpty(szKey) ? szName : "." + szName; } else { szResult += "{"; } // If we have a kiddie, dive down into it... if (property.propertyChild != null) { szResult += DumpPrivate(property.propertyChild, a_iDepth + 1, szKey, false); } // If the last character is a comma, remove it... if (szResult.EndsWith(",")) { szResult = szResult.Remove(szResult.Length - 1); } // just }, szResult += "},"; break; // Dump a string... case EPROPERTYTYPE.STRING: GetProperty(property, out szName); szKey += string.IsNullOrEmpty(szKey) ? szName : "." + szName; keyvalue = m_lkeyvalueOverride.Find(item => item.szKey == szKey); if ((keyvalue == null) || (keyvalue.szValue == null)) { GetValue(property, out szValue, out epropertytype); szResult += "\"" + szName + "\":\"" + szValue + "\","; } else { szResult += "\"" + szName + "\":\"" + keyvalue.szValue + "\","; } break; } // Next sibling... property = property.propertySibling; } // If the last character is a comma, remove it... if (szResult.EndsWith(",")) { szResult = szResult.Remove(szResult.Length - 1); } // All done... return (szResult); } /// /// Emit the JSON data as compact XML. We're doing this in a /// literal fashion. Therefore: /// /// { /// "metadata": { /// "address": { /// "imageNumber": 1, /// "imagePart": 1, /// "moreParts": lastPartInFile, /// "sheetNumber": 1, /// "source": "feederFront", /// "streamName": "stream0", /// "sourceName": "source0", /// "pixelFormatName": "pixelFormat0" /// }, /// "image": { /// "compression": "none", /// "pixelFormat": "bw1", /// "pixelHeight": 2200, /// "pixelOffsetX": 0, /// "pixelOffsetY": 0, /// "pixelWidth": 1728, /// "resolution": 200, /// "size": 476279 /// },Cmd /// feederFront /// stream0 /// source0 /// pixelFormat0 /// /// /// none /// bw1 /// 2200 /// 0 /// 0 /// 1728 /// 200 /// 476279 /// /// /// true /// /// /// /// /// Arrays are handle like so: /// /// { /// "array": [1, 2, 3] /// } /// /// /// /// 1 /// 2 /// 3 /// /// /// /// We do allow overriding the outermost tag, so that instead /// of "o" it can be something a little more descriptive, like /// "tdm" for TWAIN metadata... /// /// /// property to emit /// rootname to use for outermost tag at depth 0 /// depth we're at /// current string provided by caller /// /// an XML string, or null on error private string GetXmlPrivate(Property a_property, string a_szRootName, int a_iDepth, string a_szXml) { string szXml = a_szXml; string szData; string szName; Property property; EPROPERTYTYPE epropertytype; // Init... property = a_property; if (property == null) { return (null); } // Loopy... while (property != null) { // Get the name... if (!GetProperty(property, out szName)) { return (null); } // If we didn't get a name, make one up... if (string.IsNullOrEmpty(szName)) { switch (property.epropertytype) { default: szName = "z"; break; case EPROPERTYTYPE.ARRAY: szName = "a"; break; case EPROPERTYTYPE.OBJECT: // We can override the outermost tag... if (!string.IsNullOrEmpty(a_szRootName) && (a_iDepth == 0)) { szName = a_szRootName; } else { szName = "o"; } break; } } // If we got a name, prefix it with obj or arr, if needed... else { switch (property.epropertytype) { default: szName = "z:" + szName; break; case EPROPERTYTYPE.ARRAY: szName = "a:" + szName; break; case EPROPERTYTYPE.BOOLEAN: szName = "b:" + szName; break; case EPROPERTYTYPE.NULL: szName = "u:" + szName; break; case EPROPERTYTYPE.NUMBER: szName = "n:" + szName; break; case EPROPERTYTYPE.OBJECT: szName = "o:" + szName; break; case EPROPERTYTYPE.STRING: szName = "s:" + szName; break; } } // ADD: our opening tag... szXml += "<" + szName + ">"; // Get the value... if (!GetValue(property, out szData, out epropertytype)) { return (null); } // Dive into our kiddie, if we have one... if (property.propertyChild != null) { // Dive in... szXml = GetXmlPrivate(property.propertyChild, "", a_iDepth + 1, szXml); if (szXml == null) { return (null); } } else { szXml += szData; } // ADD: our closing tag... szXml += ""; // Next sibling... property = property.propertySibling; } // This is what we have so far... return (szXml); } /// /// Free a property tree... /// /// private void FreeProperty(Property a_property) { Property property; Property propertySibling; // Validate... if (a_property == null) { return; } // Remove siblings, go after children as needed... for (property = a_property; property != null; property = propertySibling) { // Next sibling... propertySibling = property.propertySibling; // Remove kiddies... if (property.propertyChild != null) { FreeProperty(property.propertyChild); property.propertyChild = null; } // Remove ourselves... property = null; } } /// /// Get a property name. When the JSON rules are relaxed we allow /// for the following combinations: /// /// "property": ... /// 'property': ... /// \"property\": ... /// \'property\': ... /// property: ... /// /// /// our place in the tree /// whatever we find (it can be empty) /// private bool GetProperty(Property a_property, out string a_szProperty) { // Init stuff... a_szProperty = ""; // Validate the arguments... if (a_property == null) { Log.Error("GetProperty: null argument..."); return (false); } // No name (we get this with the root and with arrays)... if (a_property.u32PropertyLength == 0) { return (true); } // Copy the property, losing the quotes... if ((m_szJson[(int)a_property.u32PropertyOffset] == '"') || (m_szJson[(int)a_property.u32PropertyOffset] == '\'')) { a_szProperty = m_szJson.Substring((int)(a_property.u32PropertyOffset + 1), (int)(a_property.u32PropertyLength - 2)); } // Under relaxed mode, handle escaped quotes... else if (((a_property.u32PropertyOffset + 1) < m_szJson.Length) && ((m_szJson.Substring((int)a_property.u32PropertyOffset, 2) == "\\\"") || (m_szJson.Substring((int)a_property.u32PropertyOffset, 2) == "\\'"))) { a_szProperty = m_szJson.Substring((int)(a_property.u32PropertyOffset + 2), (int)(a_property.u32PropertyLength - 4)); } // Under relaxed mode, we may not have quotes to lose... else { a_szProperty = m_szJson.Substring((int)a_property.u32PropertyOffset, (int)a_property.u32PropertyLength); } // All done... return (true); } /// /// Get a value. When the JSON rules are relaxed we allow for the /// following combinations: /// /// "property": ... /// 'property': ... /// \"property\": ... /// \'property\': ... /// /// /// our place in the tree /// whatever we find (it can be empty) /// the type of the item we found /// private bool GetValue(Property a_property, out string a_szValue, out EPROPERTYTYPE a_epropertytype) { // Clear the target... a_szValue = ""; a_epropertytype = EPROPERTYTYPE.UNDEFINED; // Validate the arguments... if (a_property == null) { Log.Error("GetValue: null argument..."); return (false); } // Handle strings... if (a_property.epropertytype == EPROPERTYTYPE.STRING) { // Empty string... if (a_property.u32ValueLength == 0) { a_epropertytype = a_property.epropertytype; return (true); } // Handle escaped quotes... else if (((a_property.u32ValueOffset + 1) < m_szJson.Length) && ((m_szJson.Substring((int)a_property.u32ValueOffset, 2) == "\\\"") || (m_szJson.Substring((int)a_property.u32ValueOffset, 2) == "\\'"))) { a_szValue = m_szJson.Substring((int)(a_property.u32ValueOffset + 2), (int)(a_property.u32ValueLength - 4)); } // Handle regular quotes... else { // All we have is "" (an empty string)... if (a_property.u32ValueLength == 2) { a_szValue = ""; } // We have data in our quotes... else { a_szValue = m_szJson.Substring((int)(a_property.u32ValueOffset + 1), (int)(a_property.u32ValueLength - 2)); } } } // Handle everything else... else { // Copy the entire block of data (whole objects and arrays included)... a_szValue = m_szJson.Substring((int)a_property.u32ValueOffset, (int)a_property.u32ValueLength); } // All done... a_epropertytype = a_property.epropertytype; return (true); } /// /// Work our way through an object... /// /// current place in the tree /// current offset into the JSON string /// private bool ParseObject(Property a_property, ref UInt32 a_u32Json) { UInt32 u32Json; UInt32 u32ValueOffset; Property property; Property propertyPrev; // Init stuff... u32Json = a_u32Json; // We have to start with an open square bracket... if (m_szJson[(int)u32Json] != '{') { Log.Error("ParseObject: expected open curly..."); return (false); } // Make a note of where we are... u32ValueOffset = u32Json; // Skip the curly... u32Json += 1; // Clear any whitespace... if (!SkipWhitespace(ref u32Json)) { Log.Error("ParseObject: we ran out of data..."); a_u32Json = u32Json; return (false); } // We're an empty object... if (m_szJson[(int)u32Json] == '}') { a_property.epropertytype = EPROPERTYTYPE.OBJECT; a_property.u32ValueOffset = u32ValueOffset; a_property.u32ValueLength = (u32Json + 1) - a_property.u32ValueOffset; a_u32Json = u32Json + 1; return (true); } // Loopy... propertyPrev = a_property; for (; u32Json < m_szJson.Length; u32Json++) { // Create a new record... property = new Property(); // First kiddie in the list, so it's our child... if (a_property.propertyChild == null) { a_property.propertyChild = property; propertyPrev = a_property.propertyChild; } // Append to the end of our child's sibling list... else { propertyPrev.propertySibling = property; propertyPrev = propertyPrev.propertySibling; } // Clear any whitespace... if (!SkipWhitespace(ref u32Json)) { Log.Error("ParseObject: we ran out of data..."); a_u32Json = u32Json; return (false); } // This needs to be a property name... if (!ParseString(property, ref u32Json, false)) { Log.Error("ParseObject: ParseString failed..."); a_u32Json = u32Json; return (false); } // Clear any whitespace... if (!SkipWhitespace(ref u32Json)) { a_u32Json = u32Json; Log.Error("ParseObject: we ran out of data..."); return (false); } // We need a colon... if (m_szJson[(int)u32Json] != ':') { Log.Error("ParseObject: expected a colon..."); a_u32Json = u32Json; return (false); } // Clear the colon... u32Json += 1; // Clear any whitespace... if (!SkipWhitespace(ref u32Json)) { a_u32Json = u32Json; Log.Error("ParseObject: we ran out of data..."); return (false); } // This needs to be a value... if (!ParseValue(property, ref u32Json)) { Log.Error("ParseObject: ParseValue failed..."); a_u32Json = u32Json; return (false); } // Clear any whitespace... if (!SkipWhitespace(ref u32Json)) { Log.Error("ParseObject: we ran out of data..."); a_u32Json = u32Json; return (false); } // If we see a comma, we have more coming... if (m_szJson[(int)u32Json] == ',') { continue; } // If we see a closing square bracket, then we're done... if (m_szJson[(int)u32Json] == '}') { a_property.epropertytype = EPROPERTYTYPE.OBJECT; a_property.u32ValueOffset = u32ValueOffset; a_property.u32ValueLength = (u32Json + 1) - a_property.u32ValueOffset; a_u32Json = u32Json + 1; return (true); } // Uh-oh... break; } // Uh-oh... Log.Error("ParseObject: expected a closing curly..."); a_u32Json = u32Json; return (false); } /// /// Work our way through an array... /// /// current place in the tree /// current offset into the JSON string /// private bool ParseArray(Property a_property, ref UInt32 a_u32Json) { UInt32 u32Json; UInt32 u32ValueOffset; Property property; Property propertyPrev; // Init stuff... u32Json = a_u32Json; // We have to start with an open square bracket... if (m_szJson[(int)u32Json] != '[') { Log.Error("ParseArray: expected a open square bracket..."); return (false); } // Make a note of where we are... u32ValueOffset = u32Json; // Skip the bracket... u32Json += 1; // Clear any whitespace... if (!SkipWhitespace(ref u32Json)) { Log.Error("ParseObject: we ran out of data..."); a_u32Json = u32Json; return (false); } // We're an empty array... if (m_szJson[(int)u32Json] == ']') { a_property.epropertytype = EPROPERTYTYPE.ARRAY; a_property.u32ValueOffset = u32ValueOffset; a_property.u32ValueLength = (u32Json + 1) - a_property.u32ValueOffset; a_u32Json = u32Json + 1; return (true); } // Loopy... propertyPrev = a_property; for (; u32Json < m_szJson.Length; u32Json++) { // Create a new record... property = new Property(); // First kiddie in the list, so it's our child... if (a_property.propertyChild == null) { a_property.propertyChild = property; propertyPrev = a_property.propertyChild; } // Append to the end of our child's sibling list... else { propertyPrev.propertySibling = property; propertyPrev = propertyPrev.propertySibling; } // Clear any whitespace... if (!SkipWhitespace(ref u32Json)) { a_u32Json = u32Json; Log.Error("ParseObject: we ran out of data..."); return (false); } // This needs to be a value... if (!ParseValue(property, ref u32Json)) { Log.Error("ParseArray: ParseValue failed..."); a_u32Json = u32Json; return (false); } // Clear any whitespace... if (!SkipWhitespace(ref u32Json)) { Log.Error("ParseArray: we ran out of data..."); a_u32Json = u32Json; return (false); } // If we see a comma, we have more coming... if (m_szJson[(int)u32Json] == ',') { continue; } // If we see a closing square bracket, then we're done... if (m_szJson[(int)u32Json] == ']') { a_property.epropertytype = EPROPERTYTYPE.ARRAY; a_property.u32ValueOffset = u32ValueOffset; a_property.u32ValueLength = (u32Json + 1) - a_property.u32ValueOffset; a_u32Json = u32Json + 1; return (true); } // Uh-oh... break; } // Uh-oh... Log.Error("ParseArray: expected a closing square bracket..."); a_u32Json = u32Json; return (false); } /// /// Work our way through a value... /// /// current place in the tree /// current offset into the JSON string /// private bool ParseValue(Property a_property, ref UInt32 a_u32Json) { UInt32 u32Json = a_u32Json; switch (m_szJson[(int)u32Json]) { // Well, that wasn't value... default: Log.Error("ParseValue: unexpected token at (" + u32Json + ")...<" + m_szJson[(int)u32Json] + ">"); return (false); // A string or an escaped string... case '"': case '\'': case '\\': return (ParseString(a_property, ref a_u32Json, true)); // A number... case '-': case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': return (ParseNumber(a_property, ref a_u32Json)); // An object... case '{': return (ParseObject(a_property, ref a_u32Json)); // An array... case '[': return (ParseArray(a_property, ref a_u32Json)); // A boolean true... case 't': if (m_szJson[(int)(u32Json + 1)] != 'r') { Log.Error("ParseValue: it ain't tRue..."); a_u32Json = u32Json + 1; return (false); } if (m_szJson[(int)(u32Json + 2)] != 'u') { Log.Error("ParseValue: it ain't trUe..."); a_u32Json = u32Json + 2; return (false); } if (m_szJson[(int)(u32Json + 3)] != 'e') { Log.Error("ParseValue: it ain't truE..."); a_u32Json = u32Json + 3; return (false); } a_u32Json = u32Json + 4; a_property.epropertytype = EPROPERTYTYPE.BOOLEAN; a_property.u32ValueOffset = u32Json; a_property.u32ValueLength = 4; return (true); // A boolean false... case 'f': if (m_szJson[(int)(u32Json + 1)] != 'a') { Log.Error("ParseValue: it ain't fAlse..."); a_u32Json = u32Json + 1; return (false); } if (m_szJson[(int)(u32Json + 2)] != 'l') { Log.Error("ParseValue: it ain't faLse..."); a_u32Json = u32Json + 2; return (false); } if (m_szJson[(int)(u32Json + 3)] != 's') { Log.Error("ParseValue: it ain't falSe..."); a_u32Json = u32Json + 3; return (false); } if (m_szJson[(int)(u32Json + 4)] != 'e') { Log.Error("ParseValue: it ain't falsE..."); a_u32Json = u32Json + 4; return (false); } a_u32Json = u32Json + 5; a_property.epropertytype = EPROPERTYTYPE.BOOLEAN; a_property.u32ValueOffset = u32Json; a_property.u32ValueLength = 5; return (true); // A boolean null... case 'n': if (m_szJson[(int)(u32Json + 1)] != 'u') { Log.Error("ParseValue: it ain't nUll..."); a_u32Json = u32Json + 1; return (false); } if (m_szJson[(int)(u32Json + 2)] != 'l') { Log.Error("ParseValue: it ain't nuLl..."); a_u32Json = u32Json + 2; return (false); } if (m_szJson[(int)(u32Json + 3)] != 'l') { Log.Error("ParseValue: it ain't nulL..."); a_u32Json = u32Json + 3; return (false); } a_u32Json = u32Json + 4; a_property.epropertytype = EPROPERTYTYPE.NULL; a_property.u32ValueOffset = u32Json; a_property.u32ValueLength = 4; return (true); } } /// /// Work our way through a string (property or value)... /// /// current place in the tree /// current offset into the JSON string /// true if a value /// bool ParseString(Property a_property, ref UInt32 a_u32Json, bool a_blValue) { string szQuote; UInt32 u32Json = a_u32Json; // Under strict rules the first character must be a doublequote... if (m_blStrictParsingRules) { if (m_szJson[(int)u32Json] != '"') { Log.Error("ParseString: expected a opening doublequote..."); return (false); } szQuote = m_szJson[(int)u32Json].ToString(); } // Come here for relaxed rules... else { // Handle escaped quotes... if (((u32Json + 1) < m_szJson.Length) && ((m_szJson.Substring((int)u32Json, 2) == "\\\"") || (m_szJson.Substring((int)u32Json, 2) == "\\'"))) { szQuote = m_szJson.Substring((int)u32Json, 2); } // A value must have an opening quote (double or single), or // if we detect that we have a quote, then pop in here... else if (a_blValue || (m_szJson[(int)u32Json] == '"') || (m_szJson[(int)u32Json] == '\'')) { if ((m_szJson[(int)u32Json] != '"') && (m_szJson[(int)u32Json] != '\'')) { Log.Error("ParseString: expected an opening quote..."); return (false); } szQuote = m_szJson[(int)u32Json].ToString(); } // A property name can have quotes or be an alphanumeric, and underscore or a dollarsign... else { if (!Char.IsLetterOrDigit(m_szJson[(int)u32Json]) && (m_szJson[(int)u32Json] != '_') && (m_szJson[(int)u32Json] != '$')) { Log.Error("ParseString: expected a valid property name..."); return (false); } szQuote = m_szJson[(int)u32Json].ToString(); } } // Init stuff... if (a_blValue) { a_property.u32ValueOffset = u32Json; } else { a_property.u32PropertyOffset = u32Json; } // Clear the quote if we found one... if ((szQuote == "\\\"") || (szQuote == "\\'")) { u32Json += 2; } else if ((szQuote == "\"") || (szQuote == "'")) { u32Json += 1; } // Loopy... for (; u32Json < m_szJson.Length; u32Json++) { // Fail on a control character... if (Char.IsControl(m_szJson[(int)u32Json])) { Log.Error("ParseString: detected a control character..."); a_u32Json = u32Json; return (false); } // Under strict rules a doublequote ends us... if (m_blStrictParsingRules) { if (m_szJson[(int)u32Json] == '"') { if (a_blValue) { a_property.u32ValueLength = (u32Json + 1) - a_property.u32ValueOffset; a_property.epropertytype = EPROPERTYTYPE.STRING; } else { a_property.u32PropertyLength = (u32Json + 1) - a_property.u32PropertyOffset; // Don't change the type, we could be anything... } a_u32Json = u32Json + 1; return (true); } } // Under relaxed rules we'll end on a matching escaped quite... else if (((u32Json + 1) < m_szJson.Length) && (szQuote == (m_szJson.Substring((int)u32Json, 2)))) { if (a_blValue) { a_property.u32ValueLength = (u32Json + 2) - a_property.u32ValueOffset; a_property.epropertytype = EPROPERTYTYPE.STRING; } else { a_property.u32PropertyLength = (u32Json + 2) - a_property.u32PropertyOffset; // Don't change the type, we could be anything... } a_u32Json = u32Json + 2; return (true); } // Under relaxed rules we'll end on a matching quote, if we have one, this // path is guaranteed to catch the closing quote on a value... else if ((m_szJson[(int)u32Json].ToString() == szQuote) && ((szQuote == "\"") || (szQuote == "'"))) { if (a_blValue) { a_property.u32ValueLength = (u32Json + 1) - a_property.u32ValueOffset; a_property.epropertytype = EPROPERTYTYPE.STRING; } else { a_property.u32PropertyLength = (u32Json + 1) - a_property.u32PropertyOffset; // Don't change the type, we could be anything... } a_u32Json = u32Json + 1; return (true); } // Otherwise, (still under relaxed rules) if we're a property name, and we // didn't open on a quote, we'll end on anything that isn't alphanumeric, // an underscore or a dollarsign... else if (!a_blValue && (szQuote != "\"") && (szQuote != "'") && !Char.IsLetterOrDigit(m_szJson[(int)u32Json]) && (m_szJson[(int)u32Json] != '_') && (m_szJson[(int)u32Json] != '$')) { a_property.u32PropertyLength = u32Json - a_property.u32PropertyOffset; // Don't change the type, we could be anything... // Don't skip over this item... a_u32Json = u32Json; return (true); } // If we're not a backslash, we're okay... if (m_szJson[(int)u32Json] != '\\') { continue; } // Handle escape characters... u32Json += 1; switch (m_szJson[(int)u32Json]) { default: Log.Error("ParseString: bad escape character at (" + u32Json + ")...<" + m_szJson[(int)u32Json] + ">"); a_u32Json = u32Json; return (false); case '"': case '\\': case '/': case 'n': case 'r': case 't': case 'b': case 'f': continue; // Make sure we have at least four of these in a row... case 'u': if (!IsXDigit(m_szJson[(int)(u32Json + 1)])) { Log.Error("ParseString: it ain't a \\uXxxx"); a_u32Json = u32Json + 1; return (false); } if (!IsXDigit(m_szJson[(int)(u32Json + 2)])) { Log.Error("ParseString: it ain't a \\uxXxx"); a_u32Json = u32Json + 2; return (false); } if (!IsXDigit(m_szJson[(int)(u32Json + 3)])) { Log.Error("ParseString: it ain't a \\uxxXx"); a_u32Json = u32Json + 3; return (false); } if (!IsXDigit(m_szJson[(int)(u32Json + 4)])) { Log.Error("ParseString: it ain't a \\uxxxX"); a_u32Json = u32Json + 4; return (false); } a_u32Json = u32Json + 5; continue; } } // Uh-oh... Log.Error("ParseString: expected a closing quote or something..."); a_u32Json = u32Json; return (false); } /// /// Work our way through a number... /// /// current place in the tree /// current offset into the JSON string /// bool ParseNumber(Property a_property, ref UInt32 a_u32Json) { bool blDecimalDetected; bool blExponentDetected; bool blExponentSignDetected; bool blExponentDigitDetected; bool blLeadingZero; bool blNonZeroDigitDetected; UInt32 u32Json; // Init stuff... blDecimalDetected = false; blExponentDetected = false; blExponentSignDetected = false; blExponentDigitDetected = false; blLeadingZero = false; blNonZeroDigitDetected = false; a_property.u32ValueOffset = a_u32Json; // Loopy... for (u32Json = a_u32Json; u32Json < m_szJson.Length; u32Json++) { // Detect termination of the number and watch for illegal values... switch (m_szJson[(int)u32Json]) { // We've a problem... default: Log.Error("ParseNumber: not a valid token in a number..."); a_u32Json = u32Json; return (false); // We're done (and okay) on the following... case ' ': case '\t': case '\r': case '\n': case ',': case '}': case ']': // Bad exponent... if (blExponentDetected && !blExponentDigitDetected) { Log.Error("ParseNumber: bad exponent..."); a_u32Json = u32Json; return (false); } // Don't skip past this value, the function above us needs to be able to check it... a_u32Json = u32Json; a_property.epropertytype = EPROPERTYTYPE.NUMBER; a_property.u32ValueLength = u32Json - a_property.u32ValueOffset; return (true); // We're good... case '-': case '.': case '+': case 'e': case 'E': case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': break; } // Fail on embedded or trailing minus (not part of exponent, that's further down)... // good: 1-23 // bad: 1-, 1-123 if (!blExponentDetected && (m_szJson[(int)u32Json] == '-')) { if ((m_szJson[(int)u32Json] == '-') && ((u32Json != a_u32Json) || (u32Json >= m_szJson.Length))) { Log.Error("ParseNumber: problem with how minus is being used..."); a_u32Json = u32Json; return (false); } continue; } // Detect a leading zero... if (!blNonZeroDigitDetected && (m_szJson[(int)u32Json] == '0')) { // We can be the first or second item in the string... if ((u32Json == a_u32Json) || (u32Json == (a_u32Json + 1))) { blLeadingZero = true; continue; } Log.Error("ParseNumber: found a leading zero..."); a_u32Json = u32Json; return (false); } // Fail on a leading zero... // ex: 000, 0123 if (blLeadingZero && !blNonZeroDigitDetected && Char.IsDigit(m_szJson[(int)u32Json])) { Log.Error("ParseNumber: found a leading zero..."); a_u32Json = u32Json; return (false); } // Fail on multiple decimals or a decimal with no leading digit... if (m_szJson[(int)u32Json] == '.') { if (blDecimalDetected || (!blLeadingZero && !blNonZeroDigitDetected)) { Log.Error("ParseNumber: bad decimal point..."); a_u32Json = u32Json; return (false); } // Clear the leading zero check, we don't need this anymore... blLeadingZero = false; blDecimalDetected = true; continue; } // Fail on multiple exponent or an exponent with no leading digit... if ((m_szJson[(int)u32Json] == 'e') || (m_szJson[(int)u32Json] == 'E')) { if (blExponentDetected || (!blLeadingZero && !blNonZeroDigitDetected)) { Log.Error("ParseNumber: bad exponent..."); a_u32Json = u32Json; return (false); } blExponentDetected = true; continue; } // Fail on multiple exponent sign, or sign with no leading exponent, // or sign after exponent digit... if ((m_szJson[(int)u32Json] == '+') || (m_szJson[(int)u32Json] == '-')) { if (blExponentSignDetected || !blExponentDetected || blExponentDigitDetected) { Log.Error("ParseNumber: bad exponent..."); a_u32Json = u32Json; return (false); } blExponentSignDetected = true; continue; } // Detected an integer digit... if (!blDecimalDetected && !blExponentDetected) { switch (m_szJson[(int)u32Json]) { default: break; case '-': case '.': case '+': case 'e': case 'E': case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': blNonZeroDigitDetected = true; continue; } } // Make sure we catch decimal numbers... if (Char.IsDigit(m_szJson[(int)u32Json])) { if (!blExponentDetected) { blNonZeroDigitDetected = true; } else { blExponentDigitDetected = true; } } } // Uh-oh... Log.Error("ParseNumber: problem with a number..."); a_u32Json = u32Json; return (false); } /// /// Skip whitespace in the JSON string... /// /// index to move /// false if we run out of string private bool SkipWhitespace(ref UInt32 a_u32Json) { // Loopy... while (a_u32Json < m_szJson.Length) { if (!Char.IsWhiteSpace(m_szJson[(int)a_u32Json])) { return (true); } a_u32Json += 1; } // We ran out of data... return (false); } /// /// Free resources... /// private void Unload() { m_szJson = null; if (m_property != null) { FreeProperty(m_property); m_property = null; } } /// /// C# leaves out the most amazing stuff... /// /// character to check /// true if its a hexit private static bool IsXDigit(char c) { if (Char.IsDigit(c)) return true; if ((c >= 'a') && (c <= 'f')) return true; if ((c >= 'A') && (c <= 'F')) return true; return false; } #endregion /////////////////////////////////////////////////////////////////////////////// // Private Definitions... /////////////////////////////////////////////////////////////////////////////// #region Private Definitions... /// /// Our main data structure for holding onto the information about /// a JSON string after we've loaded it... /// private class Property { // Init stuff... public Property() { propertySibling = null; propertyChild = null; epropertytype = EPROPERTYTYPE.UNDEFINED; u32PropertyOffset = 0; u32PropertyLength = 0; u32ValueOffset = 0; u32ValueLength = 0; } // Our attributes... public Property propertySibling; public Property propertyChild; public EPROPERTYTYPE epropertytype; public UInt32 u32PropertyOffset; public UInt32 u32PropertyLength; public UInt32 u32ValueOffset; public UInt32 u32ValueLength; }; /// /// Key/Value pair structure, used to override the /// values of keys during a Dump()... /// private class KeyValue { public string szKey; public string szValue; } #endregion /////////////////////////////////////////////////////////////////////////////// // Private Attributes... /////////////////////////////////////////////////////////////////////////////// #region Private Attributes... /// /// A place to store the JSON string while we work with it... /// private string m_szJson; /// /// A place to store the load data on the JSON string... /// private Property m_property; /// /// If false, then property names don't have to have quotes /// as long as they don't have any embedded whitespace, and /// single-quotes are allowed. This makes it easier on folks /// generating JSON from scripted languages, or if they use /// command line tools like cURL... /// private bool m_blStrictParsingRules; /// /// List of changes to the JSON in key/value pairs... /// private List m_lkeyvalueOverride; #endregion } /// /// P/Invokes, note that these are designed to be only accessible to classes in /// the TwainDirect.Support namespace. So if you need this functions in other /// namespaces, they have to be wrapped in a function somewhere in one of the /// TwainDirect.Support classes that have public access (not this one)... /// internal sealed class NativeMethods { /////////////////////////////////////////////////////////////////////////////// // Windows /////////////////////////////////////////////////////////////////////////////// #region Windows /// /// So we can get a console window on Windows... /// /// [DllImport("kernel32.dll", EntryPoint = "AllocConsole", SetLastError = true, CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)] public static extern int AllocConsole(); /// /// Get the desktop window so we have a parent... /// /// [DllImport("user32.dll", SetLastError = false)] public static extern IntPtr GetDesktopWindow(); [DllImport("kernel32.dll", EntryPoint = "GetStdHandle", SetLastError = true, CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)] public static extern IntPtr GetStdHandle(int nStdHandle); [DllImport("kernel32.dll", EntryPoint = "SetStdHandle", SetLastError = true, CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)] public static extern bool SetStdHandle(int nStdHandle, IntPtr hHandle); [DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Unicode)] public static extern IntPtr CreateFile (string lpFileName , [MarshalAs(UnmanagedType.U4)] DesiredAccess dwDesiredAccess , [MarshalAs(UnmanagedType.U4)] FileShare dwShareMode , IntPtr lpSecurityAttributes , [MarshalAs(UnmanagedType.U4)] CreationDisposition dwCreationDisposition , [MarshalAs(UnmanagedType.U4)] FileAttributes dwFlagsAndAttributes , IntPtr hTemplateFile ); [Flags] public enum DesiredAccess : uint { GenericRead = 0x80000000, GenericWrite = 0x40000000, GenericExecute = 0x20000000, GenericAll = 0x10000000 } [Flags] public enum FileShare : uint { /// /// /// None = 0x00000000, /// /// Enables subsequent open operations on an object to request read access. /// Otherwise, other processes cannot open the object if they request read access. /// If this flag is not specified, but the object has been opened for read access, the function fails. /// Read = 0x00000001, /// /// Enables subsequent open operations on an object to request write access. /// Otherwise, other processes cannot open the object if they request write access. /// If this flag is not specified, but the object has been opened for write access, the function fails. /// Write = 0x00000002, /// /// Enables subsequent open operations on an object to request delete access. /// Otherwise, other processes cannot open the object if they request delete access. /// If this flag is not specified, but the object has been opened for delete access, the function fails. /// Delete = 0x00000004 } public enum CreationDisposition : uint { /// /// Creates a new file. The function fails if a specified file exists. /// New = 1, /// /// Creates a new file, always. /// If a file exists, the function overwrites the file, clears the existing attributes, combines the specified file attributes, /// and flags with FILE_ATTRIBUTE_ARCHIVE, but does not set the security descriptor that the SECURITY_ATTRIBUTES structure specifies. /// CreateAlways = 2, /// /// Opens a file. The function fails if the file does not exist. /// OpenExisting = 3, /// /// Opens a file, always. /// If a file does not exist, the function creates a file as if dwCreationDisposition is CREATE_NEW. /// OpenAlways = 4, /// /// Opens a file and truncates it so that its size is 0 (zero) bytes. The function fails if the file does not exist. /// The calling process must open the file with the GENERIC_WRITE access right. /// TruncateExisting = 5 } [Flags] public enum FileAttributes : uint { Readonly = 0x00000001, Hidden = 0x00000002, System = 0x00000004, Directory = 0x00000010, Archive = 0x00000020, Device = 0x00000040, Normal = 0x00000080, Temporary = 0x00000100, SparseFile = 0x00000200, ReparsePoint = 0x00000400, Compressed = 0x00000800, Offline = 0x00001000, NotContentIndexed = 0x00002000, Encrypted = 0x00004000, Write_Through = 0x80000000, Overlapped = 0x40000000, NoBuffering = 0x20000000, RandomAccess = 0x10000000, SequentialScan = 0x08000000, DeleteOnClose = 0x04000000, BackupSemantics = 0x02000000, PosixSemantics = 0x01000000, OpenReparsePoint = 0x00200000, OpenNoRecall = 0x00100000, FirstPipeInstance = 0x00080000 } public const int STD_INPUT_HANDLE = -10; public const int STD_OUTPUT_HANDLE = -11; public const int STD_ERROR_HANDLE = -12; public const int MY_CODE_PAGE = 437; /// /// Having this helps a little bit with logging on Windows, it's /// not a huge win, though, so it may well go away at some point... /// /// [DllImport("kernel32.dll")] internal static extern int GetCurrentThreadId(); // Message sent to the Window when a Bonjour event occurs. public const int BONJOUR_EVENT = (0x8000 + 0x100); // WM_USER [DllImport("msvcrt.dll", CallingConvention = CallingConvention.Cdecl)] public static extern void free(IntPtr ptr); [DllImport("msvcrt.dll", CallingConvention = CallingConvention.Cdecl)] public static extern IntPtr calloc(IntPtr num, IntPtr size); [DllImport("user32.dll")] public static extern int GetMessage ( out MSG lpMsg, IntPtr hWnd, int wMsgFilterMin, int wMsgFilterMax ); [DllImport("user32.dll", CharSet = CharSet.Unicode, SetLastError = true)] [return: MarshalAs(UnmanagedType.Bool)] public static extern bool DestroyWindow(IntPtr hwnd); [DllImport("user32")] public static extern IntPtr SendMessage(IntPtr hWnd, UInt32 msg, IntPtr wParam, IntPtr lParam); internal const int BCM_FIRST = 0x1600; //Normal button internal const int BCM_SETSHIELD = (BCM_FIRST + 0x000C); //Elevated button [DllImport("user32.dll")] public static extern int TranslateMessage([In] ref MSG lpMsg); [DllImport("user32.dll")] public static extern IntPtr DispatchMessage([In] ref MSG lpMsg); [DllImport("wsock32.dll")] public static extern int WSAAsyncSelect ( IntPtr socket, IntPtr hWnd, int wMsg, int lEvent ); [return: MarshalAs(UnmanagedType.Bool)] [DllImport("user32.dll", SetLastError = true, CharSet = CharSet.Auto)] public static extern bool PostMessage(IntPtr hWnd, int Msg, IntPtr wParam, IntPtr lParam); [DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Unicode)] public static extern IntPtr LoadLibraryExW(string lpFileName, IntPtr hReservedNull, int dwFlags); [DllImport("kernel32", CharSet = CharSet.Ansi, ExactSpelling = true, SetLastError = true, BestFitMapping = false, ThrowOnUnmappableChar = true)] public static extern IntPtr GetProcAddress ( IntPtr hModule, [MarshalAs(UnmanagedType.LPStr)] string procName ); [DllImport("kernel32.dll", SetLastError = true)] public static extern int FreeLibrary(IntPtr handle); [DllImport("user32.dll", EntryPoint = "GetWindowLong")] [SuppressMessage("Microsoft.Portability", "CA1901:PInvokeDeclarationsShouldBePortable", MessageId = "return", Justification = "This declaration is not used on 64-bit Windows.")] [SuppressMessage("Microsoft.Portability", "CA1901:PInvokeDeclarationsShouldBePortable", MessageId = "2", Justification = "This declaration is not used on 64-bit Windows.")] public static extern int GetWindowLong(IntPtr hWnd, int nIndex); [DllImport("user32.dll", EntryPoint = "GetWindowLongPtr")] [SuppressMessage("Microsoft.Interoperability", "CA1400:PInvokeEntryPointsShouldExist", Justification = "Entry point does exist on 64-bit Windows.")] public static extern IntPtr GetWindowLongPtr(IntPtr hWnd, int nIndex); [DllImport("user32.dll", SetLastError = true, EntryPoint = "SetWindowLong")] [SuppressMessage("Microsoft.Portability", "CA1901:PInvokeDeclarationsShouldBePortable", MessageId = "return", Justification = "This declaration is not used on 64-bit Windows.")] [SuppressMessage("Microsoft.Portability", "CA1901:PInvokeDeclarationsShouldBePortable", MessageId = "2", Justification = "This declaration is not used on 64-bit Windows.")] public static extern int SetWindowLong(IntPtr hWnd, Int32 nIndex, int dwNewLong); [DllImport("user32.dll", SetLastError = true, EntryPoint = "SetWindowLongPtr")] [SuppressMessage("Microsoft.Interoperability", "CA1400:PInvokeEntryPointsShouldExist", Justification = "Entry point does exist on 64-bit Windows.")] public static extern IntPtr SetWindowLongPtr(IntPtr hWnd, Int32 nIndex, IntPtr dwNewLong); [DllImport("user32.dll", SetLastError = true)] public static extern IntPtr CreateWindowExW ( UInt32 dwExStyle, [MarshalAs(UnmanagedType.LPWStr)] string lpClassName, [MarshalAs(UnmanagedType.LPWStr)] string lpWindowName, Int32 dwStyle, Int32 x, Int32 y, Int32 nWidth, Int32 nHeight, IntPtr hWndParent, IntPtr hMenu, IntPtr hInstance, IntPtr lpParam ); [DllImport("user32.dll", EntryPoint = "ShowWindow", SetLastError = true)] public static extern bool ShowWindow(IntPtr hWnd, int nCmdShow); [DllImport("user32.dll", SetLastError = true)] [return: MarshalAs(UnmanagedType.U2)] public static extern short RegisterClassExW([In] ref WNDCLASSEXW lpwc); /// /// The Windows Point structure. /// Needed for the PreFilterMessage function when we're /// handling DAT_EVENT... /// [StructLayout(LayoutKind.Sequential, Pack = 1)] public struct POINT { public int X; public int Y; } /// /// The Windows MSG structure. /// Needed for the PreFilterMessage function when we're /// handling DAT_EVENT... /// [StructLayout(LayoutKind.Sequential)] public struct MSG { public IntPtr hwnd; public Int32 message; public IntPtr wParam; public IntPtr lParam; public Int32 time; public POINT pt; } public delegate IntPtr WndProcDelegate(IntPtr hWnd, int msg, IntPtr wParam, IntPtr lParam); [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)] [SuppressMessage("Microsoft.Design", "CA1049:TypesThatOwnNativeResourcesShouldBeDisposable", Justification = "Not allocating any resources.")] public struct WNDCLASSEXW { [MarshalAs(UnmanagedType.U4)] public int cbSize; [MarshalAs(UnmanagedType.U4)] public int style; public IntPtr lpfnWndProc; // not WndProc public int cbClsExtra; public int cbWndExtra; public IntPtr hInstance; public IntPtr hIcon; public IntPtr hCursor; public IntPtr hbrBackground; [System.Runtime.InteropServices.MarshalAs(System.Runtime.InteropServices.UnmanagedType.LPWStr)] public string lpszMenuName; [System.Runtime.InteropServices.MarshalAs(System.Runtime.InteropServices.UnmanagedType.LPWStr)] public string lpszClassName; public IntPtr hIconSm; } [DllImport("kernel32.dll", CharSet = CharSet.Unicode)] public static extern IntPtr GetModuleHandleW(string lpModuleName); [DllImport("user32.dll")] public static extern IntPtr DefWindowProc(IntPtr hWnd, int iMsg, IntPtr wParam, IntPtr lParam); #endregion } } ================================================ FILE: twaincs/source/twaincscert/source/twaincscert.csproj ================================================  15.0.27428.2005 false true Debug x86 2.0 {ED11A4C1-1C03-4092-B1FA-F1D35C47D59E} WinExe Properties twaincscert twaincscert v4.5.2 512 x86 true full false bin\x86\Debug\ DEBUG;TRACE prompt 4 true true false x86 pdbonly true bin\x86\Release\ TRACE prompt 4 true false true bin\x64\Debug\ DEBUG;TRACE false full x64 prompt true false bin\x64\Release\ TRACE true pdbonly x64 prompt true false true bin\AnyCPU\Debug\ DEBUG;TRACE true full AnyCPU prompt true false bin\AnyCPU\Release\ TRACE true pdbonly AnyCPU prompt true false False ..\..\bin\$(Platform)\$(Configuration)\TWAIN.dll Form FormMain.cs FormMain.cs ResXFileCodeGenerator Resources.Designer.cs Designer True Resources.resx True Designer SettingsSingleFileGenerator Settings.Designer.cs True Settings.settings True {E00DEC90-0A85-47D5-B0E4-39940AF8C141} twaincs echo Post-build actions... RMDIR /S /Q "$(TargetDir)data" XCOPY "$(ProjectDir)data" "$(TargetDir)data" /i /e /y /q call "$(ProjectDir)version.bat" XCOPY "$(ProjectDir)data" "$(TargetDir)data" /i /e /y /q cd "$(TargetDir)data\.." powershell Compress-Archive -Force "$(ProjectDir)data" "$(ProjectDir)Properties/data.zip" ================================================ FILE: twaincs/source/twaincscert/source/version.bat ================================================ :: :: Grab our version info... :: for /f "tokens=2 delims=^(^)" %%a in ('type "%~dp0%Properties\AssemblyInfo.cs" ^| find "AssemblyFileVersion"') do ( set VERSION=%%a ) :: :: Clean it up a little... :: set VERSION=%VERSION:"=% :: :: Save it... :: echo %VERSION% > "%~dp0%data\version.txt" ================================================ FILE: twaincs/source/twaincsscan/source/FormScan.Designer.cs ================================================ namespace TWAINCSScan { partial class FormScan { /// /// Required designer variable. /// private System.ComponentModel.IContainer components = null; #region Windows Form Designer generated code /// /// Required method for Designer support - do not modify /// the contents of this method with the code editor. /// private void InitializeComponent() { this.m_pictureboxImage1 = new System.Windows.Forms.PictureBox(); this.m_buttonScan = new System.Windows.Forms.Button(); this.m_buttonSetup = new System.Windows.Forms.Button(); this.m_pictureboxImage2 = new System.Windows.Forms.PictureBox(); this.m_buttonClose = new System.Windows.Forms.Button(); this.m_buttonOpen = new System.Windows.Forms.Button(); this.m_buttonStop = new System.Windows.Forms.Button(); ((System.ComponentModel.ISupportInitialize)(this.m_pictureboxImage1)).BeginInit(); ((System.ComponentModel.ISupportInitialize)(this.m_pictureboxImage2)).BeginInit(); this.SuspendLayout(); // // m_pictureboxImage1 // this.m_pictureboxImage1.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle; this.m_pictureboxImage1.Location = new System.Drawing.Point(13, 13); this.m_pictureboxImage1.Name = "m_pictureboxImage1"; this.m_pictureboxImage1.Size = new System.Drawing.Size(335, 424); this.m_pictureboxImage1.TabIndex = 0; this.m_pictureboxImage1.TabStop = false; // // m_buttonScan // this.m_buttonScan.Location = new System.Drawing.Point(533, 453); this.m_buttonScan.Name = "m_buttonScan"; this.m_buttonScan.Size = new System.Drawing.Size(75, 23); this.m_buttonScan.TabIndex = 1; this.m_buttonScan.Text = "Scan"; this.m_buttonScan.UseVisualStyleBackColor = true; this.m_buttonScan.Click += new System.EventHandler(this.m_buttonScan_Click); // // m_buttonSetup // this.m_buttonSetup.Location = new System.Drawing.Point(452, 453); this.m_buttonSetup.Name = "m_buttonSetup"; this.m_buttonSetup.Size = new System.Drawing.Size(75, 23); this.m_buttonSetup.TabIndex = 3; this.m_buttonSetup.Text = "Setup..."; this.m_buttonSetup.UseVisualStyleBackColor = true; this.m_buttonSetup.Click += new System.EventHandler(this.m_buttonSetup_Click); // // m_pictureboxImage2 // this.m_pictureboxImage2.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle; this.m_pictureboxImage2.Location = new System.Drawing.Point(354, 13); this.m_pictureboxImage2.Name = "m_pictureboxImage2"; this.m_pictureboxImage2.Size = new System.Drawing.Size(335, 424); this.m_pictureboxImage2.TabIndex = 4; this.m_pictureboxImage2.TabStop = false; // // m_buttonClose // this.m_buttonClose.Location = new System.Drawing.Point(94, 453); this.m_buttonClose.Name = "m_buttonClose"; this.m_buttonClose.Size = new System.Drawing.Size(75, 23); this.m_buttonClose.TabIndex = 5; this.m_buttonClose.Text = "Close"; this.m_buttonClose.UseVisualStyleBackColor = true; this.m_buttonClose.Click += new System.EventHandler(this.m_buttonClose_Click); // // m_buttonOpen // this.m_buttonOpen.Location = new System.Drawing.Point(13, 453); this.m_buttonOpen.Name = "m_buttonOpen"; this.m_buttonOpen.Size = new System.Drawing.Size(75, 23); this.m_buttonOpen.TabIndex = 6; this.m_buttonOpen.Text = "Open..."; this.m_buttonOpen.UseVisualStyleBackColor = true; this.m_buttonOpen.Click += new System.EventHandler(this.m_buttonOpen_Click); // // m_buttonStop // this.m_buttonStop.Location = new System.Drawing.Point(614, 453); this.m_buttonStop.Name = "m_buttonStop"; this.m_buttonStop.Size = new System.Drawing.Size(75, 23); this.m_buttonStop.TabIndex = 7; this.m_buttonStop.Text = "Stop"; this.m_buttonStop.UseVisualStyleBackColor = true; this.m_buttonStop.Click += new System.EventHandler(this.m_buttonStop_Click); // // FormScan // this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; this.ClientSize = new System.Drawing.Size(702, 488); this.Controls.Add(this.m_buttonStop); this.Controls.Add(this.m_buttonOpen); this.Controls.Add(this.m_buttonClose); this.Controls.Add(this.m_pictureboxImage2); this.Controls.Add(this.m_buttonSetup); this.Controls.Add(this.m_buttonScan); this.Controls.Add(this.m_pictureboxImage1); this.Name = "FormScan"; this.Text = "TWAIN C# Scan"; ((System.ComponentModel.ISupportInitialize)(this.m_pictureboxImage1)).EndInit(); ((System.ComponentModel.ISupportInitialize)(this.m_pictureboxImage2)).EndInit(); this.ResumeLayout(false); } #endregion private System.Windows.Forms.PictureBox m_pictureboxImage1; private System.Windows.Forms.Button m_buttonScan; private System.Windows.Forms.Button m_buttonSetup; private System.Windows.Forms.PictureBox m_pictureboxImage2; private System.Windows.Forms.Button m_buttonClose; private System.Windows.Forms.Button m_buttonOpen; private System.Windows.Forms.Button m_buttonStop; } } ================================================ FILE: twaincs/source/twaincsscan/source/FormScan.cs ================================================ /////////////////////////////////////////////////////////////////////////////////////// // // TWAINCSScan.FormScan // // This is the main class for the application. We're showing how to select and // load a TWAIN driver. How to configure it for a scan session, and how to capture // and display images. // // This (moreso than then TWAINCSTst) is designed to be a possible template for // developers looking to add TWAIN to their C# applications. It's small, and it's // focused on the tasks needed to capture image data. // /////////////////////////////////////////////////////////////////////////////////////// // Author Date Version Comment // M.McLaughlin 21-May-2014 2.0.0.0 64-bit Linux // M.McLaughlin 27-Feb-2014 1.1.0.0 ShowImage additions // M.McLaughlin 21-Oct-2013 1.0.0.0 Initial Release /////////////////////////////////////////////////////////////////////////////////////// // Copyright (C) 2013-2019 Kodak Alaris Inc. // // Permission is hereby granted, free of charge, to any person obtaining a // copy of this software and associated documentation files (the "Software"), // to deal in the Software without restriction, including without limitation // the rights to use, copy, modify, merge, publish, distribute, sublicense, // and/or sell copies of the Software, and to permit persons to whom the // Software is furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL // THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER // DEALINGS IN THE SOFTWARE. /////////////////////////////////////////////////////////////////////////////////////// using System; using System.Collections.Generic; using System.Diagnostics.CodeAnalysis; using System.Drawing; using System.Drawing.Drawing2D; using System.Drawing.Imaging; using System.IO; using System.Runtime.InteropServices; using System.Security.Permissions; using System.Windows.Forms; using TWAINWorkingGroup; namespace TWAINCSScan { /// /// Our mainform for this application... /// public partial class FormScan : Form, IMessageFilter { /////////////////////////////////////////////////////////////////////////////// // Public Methods... /////////////////////////////////////////////////////////////////////////////// #region Public Methods... /// /// Our constructor... /// public FormScan() { // Build our form... InitializeComponent(); // Open the log in our working folder, and say hi... TWAINWorkingGroup.Log.Open("TWAINCSScan", ".", 1); TWAINWorkingGroup.Log.Info("TWAINCSScan v" + System.Reflection.Assembly.GetEntryAssembly().GetName().Version.ToString()); // Init other stuff... m_blIndicators = true; m_blExit = false; m_iUseBitmap = 0; this.FormClosing += new FormClosingEventHandler(FormScan_FormClosing); // Create our image capture object... try { // Init stuff... TWAIN.DeviceEventCallback deviceeventcallback = DeviceEventCallback; TWAIN.ScanCallback scancallback = ScanCallbackTrigger; TWAIN.RunInUiThreadDelegate runinuithreaddelegate = RunInUiThread; // Instantiate TWAIN, and register ourselves... m_twain = new TWAIN ( "TWAIN Working Group", "TWAIN Open Source", "TWAIN CS Scan App", (ushort)TWAIN.TWON_PROTOCOL.MAJOR, (ushort)TWAIN.TWON_PROTOCOL.MINOR, ((uint)TWAIN.DG.APP2 | (uint)TWAIN.DG.CONTROL | (uint)TWAIN.DG.IMAGE), TWAIN.TWCY.USA, "TWAIN CS Scan App", TWAIN.TWLG.ENGLISH_USA, 2, 4, false, false, deviceeventcallback, scancallback, runinuithreaddelegate, this.Handle ); } catch (Exception exception) { TWAINWorkingGroup.Log.Error("exception - " + exception.Message); m_twain = null; m_blExit = true; MessageBox.Show ( "Unable to start, the most likely reason is that the TWAIN\n" + "Data Source Manager is not installed on your system.\n\n" + "An internet search for 'TWAIN DSM' will locate it and once\n" + "installed, you should be able to proceed.\n\n" + "You can also try the following link:\n" + "http://sourceforge.net/projects/twain-dsm/", "Error Starting TWAIN CS Scan" ); return; } // Init our picture box... InitImage(); // Prep for TWAIN events... SetMessageFilter(true); // Init our buttons... SetButtons(EBUTTONSTATE.CLOSED); } /// /// Our scan callback event, used to drive the engine when scanning... /// public delegate void ScanCallbackEvent(); /// /// Our event handler for the scan callback event. This will be /// called once by ScanCallbackTrigger on receipt of an event /// like MSG_XFERREADY, and then will be reissued on every call /// into ScanCallback until we're done and get back to state 4. /// /// This helps to make sure we're always running in the context /// of FormMain on Windows, which is critical if we want drivers /// to work properly. It also gives a way to break up the calls /// so the message pump is still reponsive. /// /// /// private void ScanCallbackEventHandler(object sender, EventArgs e) { ScanCallback((m_twain == null) ? true : (m_twain.GetState() <= TWAIN.STATE.S3)); } /// /// Rollback the TWAIN state to whatever is requested... /// /// public void Rollback(TWAIN.STATE a_state) { TWAIN.TW_PENDINGXFERS twpendingxfers = default(TWAIN.TW_PENDINGXFERS); TWAIN.TW_USERINTERFACE twuserinterface = default(TWAIN.TW_USERINTERFACE); TWAIN.TW_IDENTITY twidentity = default(TWAIN.TW_IDENTITY); // Make sure we have something to work with... if (m_twain == null) { return; } // Walk the states, we don't care about the status returns. Basically, // these need to work, or we're guaranteed to hang... // 7 --> 6 if ((m_twain.GetState() == TWAIN.STATE.S7) && (a_state < TWAIN.STATE.S7)) { m_twain.DatPendingxfers(TWAIN.DG.CONTROL, TWAIN.MSG.ENDXFER, ref twpendingxfers); } // 6 --> 5 if ((m_twain.GetState() == TWAIN.STATE.S6) && (a_state < TWAIN.STATE.S6)) { m_twain.DatPendingxfers(TWAIN.DG.CONTROL, TWAIN.MSG.RESET, ref twpendingxfers); } // 5 --> 4 if ((m_twain.GetState() == TWAIN.STATE.S5) && (a_state < TWAIN.STATE.S5)) { m_twain.DatUserinterface(TWAIN.DG.CONTROL, TWAIN.MSG.DISABLEDS, ref twuserinterface); } // 4 --> 3 if ((m_twain.GetState() == TWAIN.STATE.S4) && (a_state < TWAIN.STATE.S4)) { TWAIN.CsvToIdentity(ref twidentity, m_twain.GetDsIdentity()); m_twain.DatIdentity(TWAIN.DG.CONTROL, TWAIN.MSG.CLOSEDS, ref twidentity); } // 3 --> 2 if ((m_twain.GetState() == TWAIN.STATE.S3) && (a_state < TWAIN.STATE.S3)) { m_twain.DatParent(TWAIN.DG.CONTROL, TWAIN.MSG.CLOSEDSM, ref m_intptrHwnd); } } /// /// Monitor for DG_CONTROL / DAT_NULL / MSG_* stuff (ex MSG_XFERREADY), this /// function is only triggered when SetMessageFilter() is called with 'true'... /// /// Message to process /// Result of the processing [SecurityPermissionAttribute(SecurityAction.LinkDemand, Flags = SecurityPermissionFlag.UnmanagedCode)] public bool PreFilterMessage(ref Message a_message) { if (m_twain != null) { return (m_twain.PreFilterMessage(a_message.HWnd, a_message.Msg, a_message.WParam, a_message.LParam)); } return (true); } /// /// Turn message filtering on or off, we use this to capture stuff /// like MSG_XFERREADY. If it's off, then it's assumed we're getting /// this info through DAT_CALLBACK2... /// /// True to turn it on public void SetMessageFilter(bool a_blAdd) { if (a_blAdd) { Application.AddMessageFilter(this); } else { Application.RemoveMessageFilter(this); } } /// /// Restore a snapshot of driver values... /// /// File to use to restore driver settings /// SUCCESS if the restore succeeded [PermissionSet(SecurityAction.LinkDemand, Name = "FullTrust", Unrestricted = false)] public TWAIN.STS RestoreSnapshot(string a_szFile) { TWAIN.STS sts; byte[] abSettings; UInt32 u32Length; IntPtr intptrHandle; string szCustomdsdata; string szStatus; CSV csv = new CSV(); TWAIN.TW_CAPABILITY twcapability; TWAIN.TW_CUSTOMDSDATA twcustomdsdata; // Reset the driver, we don't care if it succeeds or fails... szStatus = ""; twcapability = default(TWAIN.TW_CAPABILITY); m_twain.CsvToCapability(ref twcapability, ref szStatus, "0,0,0"); m_twain.DatCapability(TWAIN.DG.CONTROL, TWAIN.MSG.RESETALL, ref twcapability); // Get the snapshot from a file... FileStream filestream = null; try { filestream = new FileStream(a_szFile, FileMode.Open); u32Length = (UInt32)filestream.Length; abSettings = new byte[u32Length]; filestream.Read(abSettings, 0, abSettings.Length); } finally { if (filestream != null) { filestream.Dispose(); } } // Put it in an intptr... intptrHandle = Marshal.AllocHGlobal((int)u32Length); Marshal.Copy(abSettings, 0, intptrHandle, (int)u32Length); // Set the snapshot, if possible... csv.Add(u32Length.ToString()); csv.Add(intptrHandle.ToString()); szCustomdsdata = csv.Get(); twcustomdsdata = default(TWAIN.TW_CUSTOMDSDATA); m_twain.CsvToCustomdsdata(ref twcustomdsdata, szCustomdsdata); sts = m_twain.DatCustomdsdata(TWAIN.DG.CONTROL, TWAIN.MSG.SET, ref twcustomdsdata); // Cleanup... Marshal.FreeHGlobal(intptrHandle); // All done... return (sts); } /// /// Save a snapshot of the driver values... /// /// File to receive driver settings /// SUCCESS if the restore succeeded [PermissionSet(SecurityAction.LinkDemand, Name = "FullTrust", Unrestricted = false)] public TWAIN.STS SaveSnapshot(string a_szFile) { TWAIN.STS sts; TWAIN.TW_CUSTOMDSDATA twcustomdsdata; // Test... if ((a_szFile == null) || (a_szFile == "")) { return (TWAIN.STS.SUCCESS); } // Get a snapshot, if possible... twcustomdsdata = default(TWAIN.TW_CUSTOMDSDATA); sts = m_twain.DatCustomdsdata(TWAIN.DG.CONTROL, TWAIN.MSG.GET, ref twcustomdsdata); if (sts != TWAIN.STS.SUCCESS) { TWAINWorkingGroup.Log.Error("DAT_CUSTOMDSDATA failed..."); return (sts); } // Save the data to a file... FileStream filestream = null; try { IntPtr intptrInfo; filestream = new FileStream(a_szFile, FileMode.Create); byte[] abSettings = new byte[twcustomdsdata.InfoLength]; intptrInfo = m_twain.DsmMemLock(twcustomdsdata.hData); Marshal.Copy(intptrInfo, abSettings, 0, (int)twcustomdsdata.InfoLength); m_twain.DsmMemUnlock(twcustomdsdata.hData); filestream.Write(abSettings, 0, abSettings.Length); } finally { if (filestream != null) { filestream.Dispose(); } } // Free the memory... m_twain.DsmMemFree(ref twcustomdsdata.hData); // All done... return (TWAIN.STS.SUCCESS); } /// /// Our callback for device events. This is where we catch and /// report that a device event has been detected. Obviously, /// we're not doing much with it. A real application would /// probably take some kind of action... /// /// TWAIN status private TWAIN.STS DeviceEventCallback() { TWAIN.STS sts; TWAIN.TW_DEVICEEVENT twdeviceevent; // Drain the event queue... while (true) { // Try to get an event... twdeviceevent = default(TWAIN.TW_DEVICEEVENT); sts = m_twain.DatDeviceevent(TWAIN.DG.CONTROL, TWAIN.MSG.GET, ref twdeviceevent); if (sts != TWAIN.STS.SUCCESS) { break; } } // Return a status, in case we ever need it for anything... return (TWAIN.STS.SUCCESS); } /// /// Our scanning callback function. We appeal directly to the supporting /// TWAIN object. This way we don't have to maintain some kind of a loop /// inside of the application, which is the source of most problems that /// developers run into. /// /// While it looks scary at first, there's really not a lot going on in /// here. We do some sanity checks, we watch for certain kinds of events, /// we support the four methods of transferring images, and we dump out /// some meta-data about the transferred image. However, because it does /// look scary I dropped in some region pragmas to break things up... /// /// We're shutting down /// TWAIN status private TWAIN.STS ScanCallbackTrigger(bool a_blClosing) { BeginInvoke(new MethodInvoker(delegate { ScanCallbackEventHandler(this, new EventArgs()); })); return (TWAIN.STS.SUCCESS); } private TWAIN.STS ScanCallback(bool a_blClosing) { TWAIN.STS sts; // Scoot... if (m_twain == null) { return (TWAIN.STS.FAILURE); } // We're superfluous... if (m_twain.GetState() <= TWAIN.STATE.S4) { return (TWAIN.STS.SUCCESS); } // We're leaving... if (a_blClosing) { return (TWAIN.STS.SUCCESS); } // Do this in the right thread, we'll usually be in the // right spot, save maybe on the first call... if (this.InvokeRequired) { return ( (TWAIN.STS)Invoke ( (Func)delegate { return (ScanCallback(a_blClosing)); } ) ); } // Handle DAT_NULL/MSG_XFERREADY... if (m_twain.IsMsgXferReady() && !m_blXferReadySent) { m_blXferReadySent = true; // Get the amount of memory needed... m_twsetupmemxfer = default(TWAIN.TW_SETUPMEMXFER); sts = m_twain.DatSetupmemxfer(TWAIN.DG.CONTROL, TWAIN.MSG.GET, ref m_twsetupmemxfer); if ((sts != TWAIN.STS.SUCCESS) || (m_twsetupmemxfer.Preferred == 0)) { m_blXferReadySent = false; if (!m_blDisableDsSent) { m_blDisableDsSent = true; Rollback(TWAIN.STATE.S4); } } // Allocate the transfer memory (with a little extra to protect ourselves)... m_intptrXfer = Marshal.AllocHGlobal((int)m_twsetupmemxfer.Preferred + 65536); if (m_intptrXfer == IntPtr.Zero) { m_blDisableDsSent = true; Rollback(TWAIN.STATE.S4); } } // Handle DAT_NULL/MSG_CLOSEDSREQ... if (m_twain.IsMsgCloseDsReq() && !m_blDisableDsSent) { m_blDisableDsSent = true; Rollback(TWAIN.STATE.S4); SetButtons(EBUTTONSTATE.OPEN); } // Handle DAT_NULL/MSG_CLOSEDSOK... if (m_twain.IsMsgCloseDsOk() && !m_blDisableDsSent) { m_blDisableDsSent = true; Rollback(TWAIN.STATE.S4); SetButtons(EBUTTONSTATE.OPEN); } // This is where the state machine transfers and optionally // saves the images to disk (it also displays them). It'll go back // and forth between states 6 and 7 until an error occurs, or until // we run out of images... if (m_blXferReadySent && !m_blDisableDsSent) { CaptureImages(); } // Trigger the next event, this is where things all chain together. // We need begininvoke to prevent blockking, so that we don't get // backed up into a messy kind of recursion. We need DoEvents, // because if things really start moving fast it's really hard for // application events, like button clicks to break through... Application.DoEvents(); BeginInvoke(new MethodInvoker(delegate { ScanCallbackEventHandler(this, new EventArgs()); })); // All done... return (TWAIN.STS.SUCCESS); } /// /// Go through the sequence needed to capture images... /// private void CaptureImages() { TWAIN.STS sts; TWAIN.TW_IMAGEINFO twimageinfo = default(TWAIN.TW_IMAGEINFO); TWAIN.TW_IMAGEMEMXFER twimagememxfer = default(TWAIN.TW_IMAGEMEMXFER); TWAIN.TW_PENDINGXFERS twpendingxfers = default(TWAIN.TW_PENDINGXFERS); TWAIN.TW_USERINTERFACE twuserinterface = default(TWAIN.TW_USERINTERFACE); // Dispatch on the state... switch (m_twain.GetState()) { // Not a good state, just scoot... default: return; // We're on our way out... case TWAIN.STATE.S5: m_blDisableDsSent = true; m_twain.DatUserinterface(TWAIN.DG.CONTROL, TWAIN.MSG.DISABLEDS, ref twuserinterface); SetButtons(EBUTTONSTATE.OPEN); return; // Memory transfers... case TWAIN.STATE.S6: case TWAIN.STATE.S7: TWAIN.CsvToImagememxfer(ref twimagememxfer, "0,0,0,0,0,0,0," + ((int)TWAIN.TWMF.APPOWNS | (int)TWAIN.TWMF.POINTER) + "," + m_twsetupmemxfer.Preferred + "," + m_intptrXfer); sts = m_twain.DatImagememxfer(TWAIN.DG.IMAGE, TWAIN.MSG.GET, ref twimagememxfer); break; } // Handle problems... if ((sts != TWAIN.STS.SUCCESS) && (sts != TWAIN.STS.XFERDONE)) { m_blDisableDsSent = true; Rollback(TWAIN.STATE.S4); SetButtons(EBUTTONSTATE.OPEN); return; } // Allocate or grow the image memory... if (m_intptrImage == IntPtr.Zero) { m_intptrImage = Marshal.AllocHGlobal((int)twimagememxfer.BytesWritten); } else { m_intptrImage = Marshal.ReAllocHGlobal(m_intptrImage, (IntPtr)(m_iImageBytes + twimagememxfer.BytesWritten)); } // Ruh-roh... if (m_intptrImage == IntPtr.Zero) { m_blDisableDsSent = true; Rollback(TWAIN.STATE.S4); SetButtons(EBUTTONSTATE.OPEN); return; } // Copy into the buffer, and bump up our byte tally... TWAIN.MemCpy(m_intptrImage + m_iImageBytes, m_intptrXfer, (int)twimagememxfer.BytesWritten); m_iImageBytes += (int)twimagememxfer.BytesWritten; // If we saw XFERDONE we can save the image, display it, // end the transfer, and see if we have more images... if (sts == TWAIN.STS.XFERDONE) { // Bump up our image counter, this always grows for the // life of the entire session... m_iImageCount += 1; // Get the image info... sts = m_twain.DatImageinfo(TWAIN.DG.IMAGE, TWAIN.MSG.GET, ref twimageinfo); // Add the appropriate header... // Bitonal uncompressed... if (((TWAIN.TWPT)twimageinfo.PixelType == TWAIN.TWPT.BW) && ((TWAIN.TWCP)twimageinfo.Compression == TWAIN.TWCP.NONE)) { TWAIN.TiffBitonalUncompressed tiffbitonaluncompressed; tiffbitonaluncompressed = new TWAIN.TiffBitonalUncompressed((uint)twimageinfo.ImageWidth, (uint)twimageinfo.ImageLength, (uint)twimageinfo.XResolution.Whole, (uint)m_iImageBytes); m_intptrImage = Marshal.ReAllocHGlobal(m_intptrImage, (IntPtr)(Marshal.SizeOf(tiffbitonaluncompressed) + m_iImageBytes)); TWAIN.MemMove((IntPtr)((UInt64)m_intptrImage + (UInt64)Marshal.SizeOf(tiffbitonaluncompressed)), m_intptrImage, m_iImageBytes); Marshal.StructureToPtr(tiffbitonaluncompressed, m_intptrImage, true); m_iImageBytes += (int)Marshal.SizeOf(tiffbitonaluncompressed); } // Bitonal GROUP4... else if (((TWAIN.TWPT)twimageinfo.PixelType == TWAIN.TWPT.BW) && ((TWAIN.TWCP)twimageinfo.Compression == TWAIN.TWCP.GROUP4)) { TWAIN.TiffBitonalG4 tiffbitonalg4; tiffbitonalg4 = new TWAIN.TiffBitonalG4((uint)twimageinfo.ImageWidth, (uint)twimageinfo.ImageLength, (uint)twimageinfo.XResolution.Whole, (uint)m_iImageBytes); m_intptrImage = Marshal.ReAllocHGlobal(m_intptrImage, (IntPtr)(Marshal.SizeOf(tiffbitonalg4) + m_iImageBytes)); TWAIN.MemMove((IntPtr)((UInt64)m_intptrImage + (UInt64)Marshal.SizeOf(tiffbitonalg4)), m_intptrImage, m_iImageBytes); Marshal.StructureToPtr(tiffbitonalg4, m_intptrImage, true); m_iImageBytes += (int)Marshal.SizeOf(tiffbitonalg4); } // Gray uncompressed... else if (((TWAIN.TWPT)twimageinfo.PixelType == TWAIN.TWPT.GRAY) && ((TWAIN.TWCP)twimageinfo.Compression == TWAIN.TWCP.NONE)) { TWAIN.TiffGrayscaleUncompressed tiffgrayscaleuncompressed; tiffgrayscaleuncompressed = new TWAIN.TiffGrayscaleUncompressed((uint)twimageinfo.ImageWidth, (uint)twimageinfo.ImageLength, (uint)twimageinfo.XResolution.Whole, (uint)m_iImageBytes); m_intptrImage = Marshal.ReAllocHGlobal(m_intptrImage, (IntPtr)(Marshal.SizeOf(tiffgrayscaleuncompressed) + m_iImageBytes)); TWAIN.MemMove((IntPtr)((UInt64)m_intptrImage + (UInt64)Marshal.SizeOf(tiffgrayscaleuncompressed)), m_intptrImage, m_iImageBytes); Marshal.StructureToPtr(tiffgrayscaleuncompressed, m_intptrImage, true); m_iImageBytes += (int)Marshal.SizeOf(tiffgrayscaleuncompressed); } // Gray JPEG... else if (((TWAIN.TWPT)twimageinfo.PixelType == TWAIN.TWPT.GRAY) && ((TWAIN.TWCP)twimageinfo.Compression == TWAIN.TWCP.JPEG)) { // No work to be done, we'll output JPEG... } // RGB uncompressed... else if (((TWAIN.TWPT)twimageinfo.PixelType == TWAIN.TWPT.RGB) && ((TWAIN.TWCP)twimageinfo.Compression == TWAIN.TWCP.NONE)) { TWAIN.TiffColorUncompressed tiffcoloruncompressed; tiffcoloruncompressed = new TWAIN.TiffColorUncompressed((uint)twimageinfo.ImageWidth, (uint)twimageinfo.ImageLength, (uint)twimageinfo.XResolution.Whole, (uint)m_iImageBytes); m_intptrImage = Marshal.ReAllocHGlobal(m_intptrImage, (IntPtr)(Marshal.SizeOf(tiffcoloruncompressed) + m_iImageBytes)); TWAIN.MemMove((IntPtr)((UInt64)m_intptrImage + (UInt64)Marshal.SizeOf(tiffcoloruncompressed)), m_intptrImage, m_iImageBytes); Marshal.StructureToPtr(tiffcoloruncompressed, m_intptrImage, true); m_iImageBytes += (int)Marshal.SizeOf(tiffcoloruncompressed); } // RGB JPEG... else if (((TWAIN.TWPT)twimageinfo.PixelType == TWAIN.TWPT.RGB) && ((TWAIN.TWCP)twimageinfo.Compression == TWAIN.TWCP.JPEG)) { // No work to be done, we'll output JPEG... } // Oh well... else { TWAINWorkingGroup.Log.Error("unsupported format <" + twimageinfo.PixelType + "," + twimageinfo.Compression + ">"); m_blDisableDsSent = true; Rollback(TWAIN.STATE.S4); SetButtons(EBUTTONSTATE.OPEN); return; } // Save the image to disk, if we're doing that... if (!string.IsNullOrEmpty(m_formsetup.GetImageFolder())) { // Create the directory, if needed... if (!Directory.Exists(m_formsetup.GetImageFolder())) { try { Directory.CreateDirectory(m_formsetup.GetImageFolder()); } catch (Exception exception) { TWAINWorkingGroup.Log.Error("CreateDirectory failed - " + exception.Message); } } // Write it out... string szFilename = Path.Combine(m_formsetup.GetImageFolder(), "img" + string.Format("{0:D6}", m_iImageCount)); TWAIN.WriteImageFile(szFilename, m_intptrImage, m_iImageBytes, out szFilename); } // Turn the image into a byte array, and free the original memory... byte[] abImage = new byte[m_iImageBytes]; Marshal.Copy(m_intptrImage, abImage, 0, m_iImageBytes); Marshal.FreeHGlobal(m_intptrImage); m_intptrImage = IntPtr.Zero; m_iImageBytes = 0; // Turn the byte array into a stream... MemoryStream memorystream = new MemoryStream(abImage); Bitmap bitmap = (Bitmap)Image.FromStream(memorystream); // Display the image... if (m_iUseBitmap == 0) { m_iUseBitmap = 1; LoadImage(ref m_pictureboxImage1, ref m_graphics1, ref m_bitmapGraphic1, bitmap); } else { m_iUseBitmap = 0; LoadImage(ref m_pictureboxImage2, ref m_graphics2, ref m_bitmapGraphic2, bitmap); } // Cleanup... bitmap.Dispose(); memorystream = null; // disposed by the bitmap abImage = null; // End the transfer... m_twain.DatPendingxfers(TWAIN.DG.CONTROL, TWAIN.MSG.ENDXFER, ref twpendingxfers); // Looks like we're done! if (twpendingxfers.Count == 0) { m_blDisableDsSent = true; m_twain.DatUserinterface(TWAIN.DG.CONTROL, TWAIN.MSG.DISABLEDS, ref twuserinterface); SetButtons(EBUTTONSTATE.OPEN); return; } } } /// /// Clean up any resources being used. /// /// true if managed resources should be disposed; otherwise, false. [SuppressMessage("Microsoft.Security", "CA2123:OverrideLinkDemandsShouldBeIdenticalToBase")] [SecurityPermissionAttribute(SecurityAction.LinkDemand, Flags = SecurityPermissionFlag.UnmanagedCode)] protected override void Dispose(bool disposing) { if (disposing && (components != null)) { if (m_twain != null) { m_twain.Dispose(); m_twain = null; } if (m_bitmapGraphic1 != null) { m_bitmapGraphic1.Dispose(); m_bitmapGraphic1 = null; } if (m_bitmapGraphic2 != null) { m_bitmapGraphic2.Dispose(); m_bitmapGraphic2 = null; } if (m_brushBackground != null) { m_brushBackground.Dispose(); m_brushBackground = null; } components.Dispose(); } base.Dispose(disposing); } /// /// Something horrible has happened and we need to abort... /// /// public bool ExitRequested() { return (m_blExit); } #endregion /////////////////////////////////////////////////////////////////////////////// // Private Methods, this includes our callback "ReportImage"... /////////////////////////////////////////////////////////////////////////////// #region Private Methods... /// /// We're being closed, clean up nicely... /// /// /// private void FormScan_FormClosing(object sender, FormClosingEventArgs e) { // Make sure this thing is off... SetMessageFilter(false); // Get rid of the TWAIN object... if (m_twain != null) { m_twain.Dispose(); m_twain = null; } // This will prevent ReportImage from doing anything as we close... m_graphics1 = null; // Bye-bye logging... TWAINWorkingGroup.Log.Close(); } /// /// The user wants to setup a customdsdata or a scan session... /// /// /// private void m_buttonSetup_Click(object sender, EventArgs e) { m_formsetup.StartPosition = FormStartPosition.CenterParent; m_formsetup.ShowDialog(this); } /// /// Start a scan session... /// /// /// private void m_buttonScan_Click(object sender, EventArgs e) { m_iUseBitmap = 0; string szTwmemref; TWAIN.STS sts; // Silently start scanning if we detect that customdsdata is supported, // otherwise bring up the driver GUI so the user can change settings... if (m_formsetup.IsCustomDsDataSupported()) { szTwmemref = "FALSE,FALSE," + this.Handle; } else { szTwmemref = "TRUE,FALSE," + this.Handle; } // Send the command... ClearEvents(); TWAIN.TW_USERINTERFACE twuserinterface = default(TWAIN.TW_USERINTERFACE); m_twain.CsvToUserinterface(ref twuserinterface, szTwmemref); sts = m_twain.DatUserinterface(TWAIN.DG.CONTROL, TWAIN.MSG.ENABLEDS, ref twuserinterface); if (sts == TWAIN.STS.SUCCESS) { SetButtons(EBUTTONSTATE.SCANNING); } } /// /// Clear our event list, and reset our event... /// public void ClearEvents() { m_blXferReadySent = false; m_blDisableDsSent = false; } /// /// Debugging output that we can monitor, this is just a place /// holder for this particular application... /// /// private void WriteOutput(string a_szOutput) { return; } /// /// Load an image into a picture box, maintain its aspect ratio... /// /// /// /// /// private void LoadImage(ref PictureBox a_picturebox, ref Graphics a_graphics, ref Bitmap a_bitmapGraphic, Bitmap a_bitmap) { // We want to maintain the aspect ratio... double fRatioWidth = (double)a_bitmapGraphic.Size.Width / (double)a_bitmap.Width; double fRatioHeight = (double)a_bitmapGraphic.Size.Height / (double)a_bitmap.Height; double fRatio = (fRatioWidth < fRatioHeight) ? fRatioWidth : fRatioHeight; int iWidth = (int)(a_bitmap.Width * fRatio); int iHeight = (int)(a_bitmap.Height * fRatio); // Display the image... a_graphics.FillRectangle(m_brushBackground, m_rectangleBackground); a_graphics.DrawImage(a_bitmap, new Rectangle(((int)a_bitmapGraphic.Width - iWidth) / 2, ((int)a_bitmapGraphic.Height - iHeight) / 2, iWidth, iHeight)); a_picturebox.Image = a_bitmapGraphic; a_picturebox.Update(); } /// /// Initialize the picture boxes and the graphics to support them, we're /// doing this to maximize performance during scanner... /// private void InitImage() { // Make sure our picture boxes don't do much work... m_pictureboxImage1.SizeMode = PictureBoxSizeMode.Normal; m_pictureboxImage2.SizeMode = PictureBoxSizeMode.Normal; m_bitmapGraphic1 = new Bitmap(m_pictureboxImage1.Width, m_pictureboxImage1.Height, PixelFormat.Format32bppPArgb); m_graphics1 = Graphics.FromImage(m_bitmapGraphic1); m_graphics1.CompositingMode = CompositingMode.SourceCopy; m_graphics1.CompositingQuality = CompositingQuality.HighSpeed; m_graphics1.InterpolationMode = InterpolationMode.Low; m_graphics1.PixelOffsetMode = PixelOffsetMode.HighSpeed; m_graphics1.SmoothingMode = SmoothingMode.HighSpeed; m_bitmapGraphic2 = new Bitmap(m_pictureboxImage1.Width, m_pictureboxImage1.Height, PixelFormat.Format32bppPArgb); m_graphics2 = Graphics.FromImage(m_bitmapGraphic2); m_graphics2.CompositingMode = CompositingMode.SourceCopy; m_graphics2.CompositingQuality = CompositingQuality.HighSpeed; m_graphics2.InterpolationMode = InterpolationMode.Low; m_graphics2.PixelOffsetMode = PixelOffsetMode.HighSpeed; m_graphics2.SmoothingMode = SmoothingMode.HighSpeed; m_brushBackground = new SolidBrush(Color.White); m_rectangleBackground = new Rectangle(0, 0, m_bitmapGraphic1.Width, m_bitmapGraphic1.Height); } /// /// TWAIN needs help, if we want it to run stuff in our main /// UI thread... /// /// the code to run private void RunInUiThread(Action a_action) { RunInUiThread(this, a_action); } /// /// TWAIN needs help, if we want it to run stuff in our main /// UI thread... /// /// the control to run in /// the code to run static public void RunInUiThread(Object a_object, Action a_action) { Control control = (Control)a_object; if (control.InvokeRequired) { control.Invoke(new FormScan.RunInUiThreadDelegate(RunInUiThread), new object[] { a_object, a_action }); return; } a_action(); } /// /// Configure our buttons to match our current state... /// /// private void SetButtons(EBUTTONSTATE a_ebuttonstate) { switch (a_ebuttonstate) { default: case EBUTTONSTATE.CLOSED: m_buttonOpen.Enabled = true; m_buttonClose.Enabled = false; m_buttonSetup.Enabled = false; m_buttonScan.Enabled = false; m_buttonStop.Enabled = false; break; case EBUTTONSTATE.OPEN: m_buttonOpen.Enabled = false; m_buttonClose.Enabled = true; m_buttonSetup.Enabled = true; m_buttonScan.Enabled = true; m_buttonStop.Enabled = false; break; case EBUTTONSTATE.SCANNING: m_buttonOpen.Enabled = false; m_buttonClose.Enabled = false; m_buttonSetup.Enabled = false; m_buttonScan.Enabled = false; m_buttonStop.Enabled = true; break; } } /// /// Select and open a TWAIN driver... /// /// /// private void m_buttonOpen_Click(object sender, EventArgs e) { string szIdentity; string szDefault = ""; string szStatus; List lszIdentity = new List(); FormSelect formselect; DialogResult dialogresult; TWAIN.STS sts; TWAIN.TW_CAPABILITY twcapability; TWAIN.TW_IDENTITY twidentity = default(TWAIN.TW_IDENTITY); // Get the default driver... m_intptrHwnd = this.Handle; sts = m_twain.DatParent(TWAIN.DG.CONTROL, TWAIN.MSG.OPENDSM, ref m_intptrHwnd); if (sts != TWAIN.STS.SUCCESS) { MessageBox.Show("OPENDSM failed..."); return; } // Get the default driver... sts = m_twain.DatIdentity(TWAIN.DG.CONTROL, TWAIN.MSG.GETDEFAULT, ref twidentity); if (sts == TWAIN.STS.SUCCESS) { szDefault = TWAIN.IdentityToCsv(twidentity); } // Enumerate the drivers... for (sts = m_twain.DatIdentity(TWAIN.DG.CONTROL, TWAIN.MSG.GETFIRST, ref twidentity); sts != TWAIN.STS.ENDOFLIST; sts = m_twain.DatIdentity(TWAIN.DG.CONTROL, TWAIN.MSG.GETNEXT, ref twidentity)) { lszIdentity.Add(TWAIN.IdentityToCsv(twidentity)); } // Ruh-roh... if (lszIdentity.Count == 0) { MessageBox.Show("There are no TWAIN drivers installed on this system..."); return; } // Instantiate our form... formselect = new FormSelect(lszIdentity, szDefault); formselect.StartPosition = FormStartPosition.CenterParent; dialogresult = formselect.ShowDialog(this); if (dialogresult != System.Windows.Forms.DialogResult.OK) { m_blExit = true; return; } // Get all the identities... szIdentity = formselect.GetSelectedDriver(); if (szIdentity == null) { m_blExit = true; return; } // Get the selected identity... m_blExit = true; foreach (string sz in lszIdentity) { if (sz.Contains(szIdentity)) { m_blExit = false; szIdentity = sz; break; } } if (m_blExit) { return; } // Make it the default, we don't care if this succeeds... twidentity = default(TWAIN.TW_IDENTITY); TWAIN.CsvToIdentity(ref twidentity, szIdentity); m_twain.DatIdentity(TWAIN.DG.CONTROL, TWAIN.MSG.SET, ref twidentity); // Open it... sts = m_twain.DatIdentity(TWAIN.DG.CONTROL, TWAIN.MSG.OPENDS, ref twidentity); if (sts != TWAIN.STS.SUCCESS) { MessageBox.Show("Unable to open scanner (it is turned on and plugged in?)"); m_blExit = true; return; } // Update the main form title... this.Text = "TWAIN C# Scan (" + twidentity.ProductName.Get() + ")"; // Strip off unsafe chars. Sadly, mono let's us down here... m_szProductDirectory = CSV.Parse(szIdentity)[11]; foreach (char c in new char [41] { '\x00', '\x01', '\x02', '\x03', '\x04', '\x05', '\x06', '\x07', '\x08', '\x09', '\x0A', '\x0B', '\x0C', '\x0D', '\x0E', '\x0F', '\x10', '\x11', '\x12', '\x13', '\x14', '\x15', '\x16', '\x17', '\x18', '\x19', '\x1A', '\x1B', '\x1C', '\x1D', '\x1E', '\x1F', '\x22', '\x3C', '\x3E', '\x7C', ':', '*', '?', '\\', '/' } ) { m_szProductDirectory = m_szProductDirectory.Replace(c, '_'); } // We're doing memory transfers... szStatus = ""; twcapability = default(TWAIN.TW_CAPABILITY); m_twain.CsvToCapability(ref twcapability, ref szStatus, "ICAP_XFERMECH,TWON_ONEVALUE,TWTY_UINT16,TWSX_MEMORY"); sts = m_twain.DatCapability(TWAIN.DG.CONTROL, TWAIN.MSG.SET, ref twcapability); if (sts != TWAIN.STS.SUCCESS) { m_blExit = true; return; } // Decide whether or not to show the driver's window messages... szStatus = ""; twcapability = default(TWAIN.TW_CAPABILITY); m_twain.CsvToCapability(ref twcapability, ref szStatus, "CAP_INDICATORS,TWON_ONEVALUE,TWTY_BOOL," + (m_blIndicators ? "TRUE" : "FALSE")); sts = m_twain.DatCapability(TWAIN.DG.CONTROL, TWAIN.MSG.SET, ref twcapability); if (sts != TWAIN.STS.SUCCESS) { m_blExit = true; return; } // New state... SetButtons(EBUTTONSTATE.OPEN); // Create the setup form... m_formsetup = new FormSetup(this, ref m_twain, m_szProductDirectory); } /// /// Close the currently open TWAIN driver... /// /// /// private void m_buttonClose_Click(object sender, EventArgs e) { this.Text = "TWAIN C# Scan"; Rollback(TWAIN.STATE.S2); SetButtons(EBUTTONSTATE.CLOSED); m_formsetup.Dispose(); m_formsetup = null; } /// /// Request that scanning stop (gracefully)... /// /// /// private void m_buttonStop_Click(object sender, EventArgs e) { TWAIN.TW_PENDINGXFERS twpendingxfers = default(TWAIN.TW_PENDINGXFERS); m_twain.DatPendingxfers(TWAIN.DG.CONTROL, TWAIN.MSG.STOPFEEDER, ref twpendingxfers); } #endregion /////////////////////////////////////////////////////////////////////////////// // Private Definitons... /////////////////////////////////////////////////////////////////////////////// #region Private Definitons... /// /// Our button states... /// private enum EBUTTONSTATE { CLOSED, OPEN, SCANNING } #endregion /////////////////////////////////////////////////////////////////////////////// // Private Attributes... /////////////////////////////////////////////////////////////////////////////// #region Private Attributes... /// /// Use if something really bad happens... /// private bool m_blExit; /// /// Our interface to TWAIN... /// private TWAIN m_twain; private IntPtr m_intptrHwnd; private bool m_blDisableDsSent = false; private bool m_blXferReadySent = false; private IntPtr m_intptrXfer = IntPtr.Zero; private IntPtr m_intptrImage = IntPtr.Zero; private int m_iImageBytes = 0; private TWAIN.TW_SETUPMEMXFER m_twsetupmemxfer; // Setup information... private FormSetup m_formsetup; /// /// We use this name (modified and made file system safe) /// as the place where we'll put customdsdata... /// private string m_szProductDirectory; /// /// If true, then show the driver's window messages while /// we're scanning. Set this in the constructor... /// private bool m_blIndicators; /// /// Stuff used to display the images... /// private Bitmap m_bitmapGraphic1; private Bitmap m_bitmapGraphic2; private Graphics m_graphics1; private Graphics m_graphics2; private Brush m_brushBackground; private Rectangle m_rectangleBackground; private int m_iUseBitmap; private int m_iImageCount = 0; /// /// We use this to run code in the context of the caller's UI thread... /// /// object (really a control) /// code to run public delegate void RunInUiThreadDelegate(Object a_object, Action a_action); #endregion } } ================================================ FILE: twaincs/source/twaincsscan/source/FormScan.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 ================================================ FILE: twaincs/source/twaincsscan/source/FormSelect.Designer.cs ================================================ namespace TWAINCSScan { partial class FormSelect { /// /// Required designer variable. /// private System.ComponentModel.IContainer components = null; /// /// Clean up any resources being used. /// /// true if managed resources should be disposed; otherwise, false. protected override void Dispose(bool disposing) { if (disposing && (components != null)) { components.Dispose(); } base.Dispose(disposing); } #region Windows Form Designer generated code /// /// Required method for Designer support - do not modify /// the contents of this method with the code editor. /// private void InitializeComponent() { this.m_listboxSelect = new System.Windows.Forms.ListBox(); this.m_buttonOpen = new System.Windows.Forms.Button(); this.m_labelSelect = new System.Windows.Forms.Label(); this.SuspendLayout(); // // m_listboxSelect // this.m_listboxSelect.FormattingEnabled = true; this.m_listboxSelect.Location = new System.Drawing.Point(12, 38); this.m_listboxSelect.Name = "m_listboxSelect"; this.m_listboxSelect.Size = new System.Drawing.Size(259, 173); this.m_listboxSelect.Sorted = true; this.m_listboxSelect.TabIndex = 0; this.m_listboxSelect.MouseDoubleClick += new System.Windows.Forms.MouseEventHandler(m_listboxSelect_MouseDoubleClick); // // m_buttonOpen // this.m_buttonOpen.DialogResult = System.Windows.Forms.DialogResult.OK; this.m_buttonOpen.Location = new System.Drawing.Point(197, 223); this.m_buttonOpen.Name = "m_buttonOpen"; this.m_buttonOpen.Size = new System.Drawing.Size(75, 23); this.m_buttonOpen.TabIndex = 1; this.m_buttonOpen.Text = "Open"; this.m_buttonOpen.UseVisualStyleBackColor = true; this.m_buttonOpen.Click += new System.EventHandler(this.m_buttonOpen_Click); // // m_labelSelect // this.m_labelSelect.AutoSize = true; this.m_labelSelect.Location = new System.Drawing.Point(12, 12); this.m_labelSelect.Name = "m_labelSelect"; this.m_labelSelect.Size = new System.Drawing.Size(110, 13); this.m_labelSelect.TabIndex = 3; this.m_labelSelect.Text = "Select TWAIN Driver:"; // // FormSelect // this.AcceptButton = this.m_buttonOpen; this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; this.ClientSize = new System.Drawing.Size(284, 262); this.Controls.Add(this.m_labelSelect); this.Controls.Add(this.m_buttonOpen); this.Controls.Add(this.m_listboxSelect); this.Name = "FormSelect"; this.Text = "Open TWAIN Driver"; this.ResumeLayout(false); this.PerformLayout(); } #endregion private System.Windows.Forms.ListBox m_listboxSelect; private System.Windows.Forms.Button m_buttonOpen; private System.Windows.Forms.Label m_labelSelect; } } ================================================ FILE: twaincs/source/twaincsscan/source/FormSelect.cs ================================================ /////////////////////////////////////////////////////////////////////////////////////// // // TWAINCSScan.FormSelect // // This class helps us select a TWAIN driver that we wish to open. // /////////////////////////////////////////////////////////////////////////////////////// // Author Date Version Comment // M.McLaughlin 21-May-2014 2.0.0.0 64-bit Linux // M.McLaughlin 27-Feb-2014 1.1.0.0 ShowImage additions // M.McLaughlin 21-Oct-2013 1.0.0.0 Initial Release /////////////////////////////////////////////////////////////////////////////////////// // Copyright (C) 2013-2019 Kodak Alaris Inc. // // Permission is hereby granted, free of charge, to any person obtaining a // copy of this software and associated documentation files (the "Software"), // to deal in the Software without restriction, including without limitation // the rights to use, copy, modify, merge, publish, distribute, sublicense, // and/or sell copies of the Software, and to permit persons to whom the // Software is furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL // THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER // DEALINGS IN THE SOFTWARE. /////////////////////////////////////////////////////////////////////////////////////// using System; using System.Collections.Generic; using System.Windows.Forms; using TWAINWorkingGroup; namespace TWAINCSScan { public partial class FormSelect : Form { /////////////////////////////////////////////////////////////////////////////// // Public Methods... /////////////////////////////////////////////////////////////////////////////// #region Public Methods... /// /// Our constructor... /// /// list of scanners to show /// the default selection public FormSelect(List a_lszIdentity, string a_szDefault) { string[] aszIdentity; string[] aszDefault; // Init stuff... InitializeComponent(); // Explode the default... aszDefault = CSV.Parse(a_szDefault); // Suspend updating... m_listboxSelect.BeginUpdate(); // Populate our driver list... foreach (string sz in a_lszIdentity) { aszIdentity = CSV.Parse(sz); m_listboxSelect.Items.Add(aszIdentity[11].ToString()); } // Select the default... m_listboxSelect.SelectedIndex = m_listboxSelect.FindStringExact(aszDefault[11]); // Resume updating... m_listboxSelect.EndUpdate(); } public string GetSelectedDriver() { return (m_szSelected); } #endregion /////////////////////////////////////////////////////////////////////////////// // Private Methods... /////////////////////////////////////////////////////////////////////////////// #region Private Methods... /// /// Select this as our driver and close the dialog... /// /// /// private void m_buttonOpen_Click(object sender, EventArgs e) { m_szSelected = (string)m_listboxSelect.SelectedItem; } private void m_listboxSelect_MouseDoubleClick(object sender, MouseEventArgs e) { m_szSelected = (string)m_listboxSelect.SelectedItem; this.DialogResult = System.Windows.Forms.DialogResult.OK; } #endregion /////////////////////////////////////////////////////////////////////////////// // Private Attributes... /////////////////////////////////////////////////////////////////////////////// #region Private Attributes... /// /// The currently selected item... /// private string m_szSelected; #endregion } } ================================================ FILE: twaincs/source/twaincsscan/source/FormSelect.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 ================================================ FILE: twaincs/source/twaincsscan/source/FormSetup.Designer.cs ================================================ namespace TWAINCSScan { partial class FormSetup { /// /// Required designer variable. /// private System.ComponentModel.IContainer components = null; /// /// Clean up any resources being used. /// /// true if managed resources should be disposed; otherwise, false. protected override void Dispose(bool disposing) { if (disposing && (components != null)) { components.Dispose(); } base.Dispose(disposing); } #region Windows Form Designer generated code /// /// Required method for Designer support - do not modify /// the contents of this method with the code editor. /// private void InitializeComponent() { System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(FormSetup)); this.m_labelUseUiSettings = new System.Windows.Forms.Label(); this.m_buttonShowDriverUi = new System.Windows.Forms.Button(); this.m_buttonSaveUiSettings = new System.Windows.Forms.Button(); this.m_labelSelectDestinationFolder = new System.Windows.Forms.Label(); this.m_textboxFolder = new System.Windows.Forms.TextBox(); this.m_buttonSelectDestinationFolder = new System.Windows.Forms.Button(); this.m_buttonUseUiSettings = new System.Windows.Forms.Button(); this.m_textboxUseUiSettings = new System.Windows.Forms.TextBox(); this.m_groupboxCreateUiSetting = new System.Windows.Forms.GroupBox(); this.m_groupboxManageSettings = new System.Windows.Forms.GroupBox(); this.m_buttonDeleteSetting = new System.Windows.Forms.Button(); this.m_groupboxImageDestination = new System.Windows.Forms.GroupBox(); this.m_groupboxManageSettings.SuspendLayout(); this.SuspendLayout(); // // m_labelUseUiSettings // this.m_labelUseUiSettings.AutoSize = true; this.m_labelUseUiSettings.Location = new System.Drawing.Point(30, 261); this.m_labelUseUiSettings.Name = "m_labelUseUiSettings"; this.m_labelUseUiSettings.Size = new System.Drawing.Size(305, 13); this.m_labelUseUiSettings.TabIndex = 1; this.m_labelUseUiSettings.Text = "Select driver settings for next scan (if blank the driver chooses):"; // // m_buttonShowDriverUi // this.m_buttonShowDriverUi.Location = new System.Drawing.Point(33, 133); this.m_buttonShowDriverUi.Name = "m_buttonShowDriverUi"; this.m_buttonShowDriverUi.Size = new System.Drawing.Size(294, 23); this.m_buttonShowDriverUi.TabIndex = 1; this.m_buttonShowDriverUi.Text = "Change driver settings (press this first)..."; this.m_buttonShowDriverUi.UseVisualStyleBackColor = true; this.m_buttonShowDriverUi.Click += new System.EventHandler(this.m_buttonSetup_Click); // // m_buttonSaveUiSettings // this.m_buttonSaveUiSettings.Location = new System.Drawing.Point(33, 171); this.m_buttonSaveUiSettings.Name = "m_buttonSaveUiSettings"; this.m_buttonSaveUiSettings.Size = new System.Drawing.Size(294, 23); this.m_buttonSaveUiSettings.TabIndex = 2; this.m_buttonSaveUiSettings.Text = "Save driver settings (then press this one)..."; this.m_buttonSaveUiSettings.UseVisualStyleBackColor = true; this.m_buttonSaveUiSettings.Click += new System.EventHandler(this.m_buttonSaveas_Click); // // m_labelSelectDestinationFolder // this.m_labelSelectDestinationFolder.AutoSize = true; this.m_labelSelectDestinationFolder.Location = new System.Drawing.Point(30, 38); this.m_labelSelectDestinationFolder.Name = "m_labelSelectDestinationFolder"; this.m_labelSelectDestinationFolder.Size = new System.Drawing.Size(302, 13); this.m_labelSelectDestinationFolder.TabIndex = 4; this.m_labelSelectDestinationFolder.Text = "Select image destination folder (set blank if not saving images):"; // // m_textboxFolder // this.m_textboxFolder.Location = new System.Drawing.Point(33, 56); this.m_textboxFolder.Name = "m_textboxFolder"; this.m_textboxFolder.Size = new System.Drawing.Size(262, 20); this.m_textboxFolder.TabIndex = 5; this.m_textboxFolder.TextChanged += new System.EventHandler(this.m_textboxFolder_TextChanged); // // m_buttonSelectDestinationFolder // this.m_buttonSelectDestinationFolder.BackgroundImage = ((System.Drawing.Image)(resources.GetObject("m_buttonSelectDestinationFolder.BackgroundImage"))); this.m_buttonSelectDestinationFolder.Location = new System.Drawing.Point(301, 54); this.m_buttonSelectDestinationFolder.Name = "m_buttonSelectDestinationFolder"; this.m_buttonSelectDestinationFolder.Size = new System.Drawing.Size(26, 23); this.m_buttonSelectDestinationFolder.TabIndex = 6; this.m_buttonSelectDestinationFolder.UseVisualStyleBackColor = true; this.m_buttonSelectDestinationFolder.Click += new System.EventHandler(this.m_buttonBrowse_Click); // // m_buttonUseUiSettings // this.m_buttonUseUiSettings.BackgroundImage = ((System.Drawing.Image)(resources.GetObject("m_buttonUseUiSettings.BackgroundImage"))); this.m_buttonUseUiSettings.Location = new System.Drawing.Point(301, 277); this.m_buttonUseUiSettings.Name = "m_buttonUseUiSettings"; this.m_buttonUseUiSettings.Size = new System.Drawing.Size(26, 23); this.m_buttonUseUiSettings.TabIndex = 8; this.m_buttonUseUiSettings.UseVisualStyleBackColor = true; this.m_buttonUseUiSettings.Click += new System.EventHandler(this.m_buttonUseUiSettings_Click); // // m_textboxUseUiSettings // this.m_textboxUseUiSettings.Location = new System.Drawing.Point(33, 279); this.m_textboxUseUiSettings.Name = "m_textboxUseUiSettings"; this.m_textboxUseUiSettings.Size = new System.Drawing.Size(262, 20); this.m_textboxUseUiSettings.TabIndex = 7; // // m_groupboxCreateUiSetting // this.m_groupboxCreateUiSetting.Location = new System.Drawing.Point(15, 103); this.m_groupboxCreateUiSetting.Name = "m_groupboxCreateUiSetting"; this.m_groupboxCreateUiSetting.Size = new System.Drawing.Size(329, 109); this.m_groupboxCreateUiSetting.TabIndex = 9; this.m_groupboxCreateUiSetting.TabStop = false; this.m_groupboxCreateUiSetting.Text = "Create new driver settings"; // // m_groupboxManageSettings // this.m_groupboxManageSettings.Controls.Add(this.m_buttonDeleteSetting); this.m_groupboxManageSettings.Location = new System.Drawing.Point(15, 230); this.m_groupboxManageSettings.Name = "m_groupboxManageSettings"; this.m_groupboxManageSettings.Size = new System.Drawing.Size(329, 109); this.m_groupboxManageSettings.TabIndex = 10; this.m_groupboxManageSettings.TabStop = false; this.m_groupboxManageSettings.Text = "Select driver settings"; // // m_buttonDeleteSetting // this.m_buttonDeleteSetting.Location = new System.Drawing.Point(195, 77); this.m_buttonDeleteSetting.Name = "m_buttonDeleteSetting"; this.m_buttonDeleteSetting.Size = new System.Drawing.Size(117, 23); this.m_buttonDeleteSetting.TabIndex = 0; this.m_buttonDeleteSetting.Text = "Delete setting..."; this.m_buttonDeleteSetting.UseVisualStyleBackColor = true; this.m_buttonDeleteSetting.Click += new System.EventHandler(this.m_buttonDeleteSetting_Click); // // m_groupboxImageDestination // this.m_groupboxImageDestination.Location = new System.Drawing.Point(15, 12); this.m_groupboxImageDestination.Name = "m_groupboxImageDestination"; this.m_groupboxImageDestination.Size = new System.Drawing.Size(329, 78); this.m_groupboxImageDestination.TabIndex = 11; this.m_groupboxImageDestination.TabStop = false; this.m_groupboxImageDestination.Text = "Select image destination"; // // FormSetup // this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; this.ClientSize = new System.Drawing.Size(359, 354); this.Controls.Add(this.m_buttonUseUiSettings); this.Controls.Add(this.m_textboxUseUiSettings); this.Controls.Add(this.m_buttonSelectDestinationFolder); this.Controls.Add(this.m_textboxFolder); this.Controls.Add(this.m_labelSelectDestinationFolder); this.Controls.Add(this.m_buttonSaveUiSettings); this.Controls.Add(this.m_buttonShowDriverUi); this.Controls.Add(this.m_labelUseUiSettings); this.Controls.Add(this.m_groupboxCreateUiSetting); this.Controls.Add(this.m_groupboxManageSettings); this.Controls.Add(this.m_groupboxImageDestination); this.Name = "FormSetup"; this.Text = "Setup TWAIN Scan"; this.m_groupboxManageSettings.ResumeLayout(false); this.ResumeLayout(false); this.PerformLayout(); } #endregion private System.Windows.Forms.Label m_labelUseUiSettings; private System.Windows.Forms.Button m_buttonShowDriverUi; private System.Windows.Forms.Button m_buttonSaveUiSettings; private System.Windows.Forms.Label m_labelSelectDestinationFolder; private System.Windows.Forms.TextBox m_textboxFolder; private System.Windows.Forms.Button m_buttonSelectDestinationFolder; private System.Windows.Forms.Button m_buttonUseUiSettings; private System.Windows.Forms.TextBox m_textboxUseUiSettings; private System.Windows.Forms.GroupBox m_groupboxCreateUiSetting; private System.Windows.Forms.GroupBox m_groupboxManageSettings; private System.Windows.Forms.Button m_buttonDeleteSetting; private System.Windows.Forms.GroupBox m_groupboxImageDestination; } } ================================================ FILE: twaincs/source/twaincsscan/source/FormSetup.cs ================================================ /////////////////////////////////////////////////////////////////////////////////////// // // TWAINCSScan.FormSetup // // This class helps us configure a TWAIN driver prior to scanning. // /////////////////////////////////////////////////////////////////////////////////////// // Author Date Version Comment // M.McLaughlin 21-May-2014 2.0.0.0 64-bit Linux // M.McLaughlin 27-Feb-2014 1.1.0.0 ShowImage additions // M.McLaughlin 21-Oct-2013 1.0.0.0 Initial Release /////////////////////////////////////////////////////////////////////////////////////// // Copyright (C) 2013-2019 Kodak Alaris Inc. // // Permission is hereby granted, free of charge, to any person obtaining a // copy of this software and associated documentation files (the "Software"), // to deal in the Software without restriction, including without limitation // the rights to use, copy, modify, merge, publish, distribute, sublicense, // and/or sell copies of the Software, and to permit persons to whom the // Software is furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL // THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER // DEALINGS IN THE SOFTWARE. /////////////////////////////////////////////////////////////////////////////////////// using System; using System.IO; using System.Security.Permissions; using System.Windows.Forms; using TWAINWorkingGroup; namespace TWAINCSScan { /// /// Select the image destination folder. If supported, allow the user to /// create and select Custom DS Data snapshots of the driver, and give /// them a way to change the driver settings through the setup form of the /// driver's user interface... /// public partial class FormSetup : Form { /////////////////////////////////////////////////////////////////////////////// // Public Methods... /////////////////////////////////////////////////////////////////////////////// #region Public Methods... /// /// Our constructor... /// /// [PermissionSet(SecurityAction.LinkDemand, Name = "FullTrust", Unrestricted = false)] public FormSetup(FormScan a_formscan, ref TWAIN a_twain, string a_szProductDirectory) { TWAIN.STS sts; string szStatus; string szCapability; string szUsrUiSettings; // Init stuff... InitializeComponent(); // More init stuff... this.FormClosing += new FormClosingEventHandler(FormSetup_FormClosing); // Init more stuff (the order matters). ApplicationData means the following: // Windows: C:\Users\USERNAME\AppData\Roaming (or C:\Documents and Settings\USERNAME\Application Data on XP) // Linux: /home/USERNAME/.config (or /root/.config for superuser) // Mac OS X: /Users/USERNAME/.config (or /var/root/.config for superuser) m_formscan = a_formscan; m_twain = a_twain; m_szTwainscanFolder = Path.Combine(Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Personal),"twain"),"twaincsscan"); m_szSettingsFolder = Path.Combine(m_szTwainscanFolder,"settings"); m_szSettingsFolder = Path.Combine(m_szSettingsFolder, a_szProductDirectory); if (!Directory.Exists(m_szTwainscanFolder)) { try { Directory.CreateDirectory(m_szTwainscanFolder); } catch (Exception exception) { TWAINWorkingGroup.Log.Error("exception - " + exception.Message); m_szTwainscanFolder = Directory.GetCurrentDirectory(); } } // Restore values... m_textboxFolder.Text = RestoreFolder(); m_textboxUseUiSettings.Text = ""; // Check for support of Custom DS Data... szStatus = ""; TWAIN.TW_CAPABILITY twcapability = default(TWAIN.TW_CAPABILITY); m_twain.CsvToCapability(ref twcapability, ref szStatus, "CAP_CUSTOMDSDATA,0,0,0"); sts = m_twain.DatCapability(TWAIN.DG.CONTROL, TWAIN.MSG.GETCURRENT, ref twcapability); szCapability = m_twain.CapabilityToCsv(twcapability, true); if ((sts != TWAIN.STS.SUCCESS) || (!szCapability.EndsWith(",1") && !szCapability.EndsWith(",TRUE"))) { m_labelUseUiSettings.Enabled = false; m_textboxUseUiSettings.Enabled = false; m_buttonSaveUiSettings.Enabled = false; m_buttonUseUiSettings.Enabled = false; } // Restore the last saved snapshot... else { m_textboxUseUiSettings.Text = RestoreSetting(); if (m_textboxUseUiSettings.Text != "") { szUsrUiSettings = Path.Combine(m_szSettingsFolder, m_textboxUseUiSettings.Text); if (File.Exists(szUsrUiSettings)) { m_formscan.RestoreSnapshot(szUsrUiSettings); } else { m_textboxUseUiSettings.Text = ""; } } } } /// /// Let the caller know if we can take snapshots... /// /// public bool IsCustomDsDataSupported() { return (m_buttonUseUiSettings.Enabled); } /// /// Place to put images (empty is okay)... /// /// public string GetImageFolder() { return (m_textboxFolder.Text); } #endregion /////////////////////////////////////////////////////////////////////////////// // Private Methods... /////////////////////////////////////////////////////////////////////////////// #region Private Methods... /// /// Validate... /// /// /// private void FormSetup_FormClosing(object sender, FormClosingEventArgs e) { if ((m_textboxFolder.Text != "") && !Directory.Exists(m_textboxFolder.Text)) { MessageBox.Show("Please enter a valid Destination Folder."); e.Cancel = true; } if ((m_textboxUseUiSettings.Text != "") && !File.Exists(Path.Combine(m_szSettingsFolder,m_textboxUseUiSettings.Text))) { MessageBox.Show("Please enter a valid UI Setting name, or clear the entry."); e.Cancel = true; } } /// /// Get the folder path... /// /// private string RestoreFolder() { try { string szSaveSpot = m_szTwainscanFolder; if (!Directory.Exists(szSaveSpot)) { return (""); } string szFile = Path.Combine(szSaveSpot, "folder"); if (File.Exists(szFile)) { return (File.ReadAllText(szFile)); } return (""); } catch (Exception exception) { TWAINWorkingGroup.Log.Error("exception - " + exception.Message); return (""); } } /// /// Get the setting... /// /// private string RestoreSetting() { try { if (!Directory.Exists(m_szSettingsFolder)) { return (""); } string szFile = Path.Combine(m_szSettingsFolder, "current"); if (File.Exists(szFile)) { return (File.ReadAllText(szFile)); } return (""); } catch (Exception exception) { TWAINWorkingGroup.Log.Error("exception - " + exception.Message); return (""); } } /// /// Remember the folder path for the next time the app runs... /// /// private void SaveFolder(string a_szFolder) { try { string szSaveSpot = m_szTwainscanFolder; if (!Directory.Exists(szSaveSpot)) { Directory.CreateDirectory(szSaveSpot); } File.WriteAllText(Path.Combine(szSaveSpot, "folder"), a_szFolder); } catch (Exception exception) { TWAINWorkingGroup.Log.Error("exception - " + exception.Message); // Just let it slide... } } /// /// Remember the setting for the next time the app runs... /// /// private void SaveSetting(string a_szFolder) { try { if (!Directory.Exists(m_szSettingsFolder)) { Directory.CreateDirectory(m_szSettingsFolder); } File.WriteAllText(Path.Combine(m_szSettingsFolder, "current"), a_szFolder); } catch (Exception exception) { TWAINWorkingGroup.Log.Error("exception - " + exception.Message); // Just let it slide... } } #endregion /////////////////////////////////////////////////////////////////////////////// // Private Form Controls... /////////////////////////////////////////////////////////////////////////////// #region Private Form Controls... /// /// Browse for a place to save image files... /// /// /// private void m_buttonBrowse_Click(object sender, EventArgs e) { FolderBrowserDialog folderbrowserdialog = new FolderBrowserDialog(); folderbrowserdialog.SelectedPath = m_textboxFolder.Text; folderbrowserdialog.ShowNewFolderButton = true; if (folderbrowserdialog.ShowDialog() == DialogResult.OK) { m_textboxFolder.Text = folderbrowserdialog.SelectedPath; SaveFolder(m_textboxFolder.Text); } } /// /// Delete the setting... /// /// /// private void m_buttonDeleteSetting_Click(object sender, EventArgs e) { bool blDeleted; // Nothing to do if it's empty... if (m_textboxUseUiSettings.Text == "") { return; } // If it's not real, tell the user... if (!File.Exists(Path.Combine(m_szSettingsFolder, m_textboxUseUiSettings.Text))) { MessageBox.Show("'" + m_textboxUseUiSettings.Text + "' not found..."); return; } // Get confirmation... DialogResult dialogresult = MessageBox.Show("Delete '" + m_textboxUseUiSettings.Text + "'?","Confirm",MessageBoxButtons.YesNo); if (dialogresult == System.Windows.Forms.DialogResult.No) { return; } // Delete it... try { blDeleted = true; File.Delete(Path.Combine(m_szSettingsFolder, m_textboxUseUiSettings.Text)); } catch (Exception exception) { TWAINWorkingGroup.Log.Error("exception - " + exception.Message); blDeleted = false; MessageBox.Show("Failed to delete setting..."); } // Clear the text box... if (blDeleted) { m_textboxUseUiSettings.Text = ""; } } /// /// Save the current driver's settings... /// /// /// private void m_buttonSaveas_Click(object sender, EventArgs e) { SaveFileDialog savefiledialog = new SaveFileDialog(); savefiledialog.InitialDirectory = m_szSettingsFolder; savefiledialog.CheckFileExists = false; savefiledialog.CheckPathExists = true; savefiledialog.Filter = "Settings|*.settings"; if (!Directory.Exists(savefiledialog.InitialDirectory)) { try { Directory.CreateDirectory(savefiledialog.InitialDirectory); } catch (Exception exception) { TWAINWorkingGroup.Log.Error("exception - " + exception.Message); return; } } if (savefiledialog.ShowDialog() == DialogResult.OK) { m_textboxUseUiSettings.Text = Path.GetFileName(savefiledialog.FileName); m_formscan.SaveSnapshot(Path.Combine(m_szSettingsFolder,m_textboxUseUiSettings.Text)); SaveSetting(m_textboxUseUiSettings.Text); } } /// /// Bring up the driver's non-scanning UI... /// /// /// private void m_buttonSetup_Click(object sender, EventArgs e) { m_formscan.ClearEvents(); TWAIN.TW_USERINTERFACE twuserinterface = default(TWAIN.TW_USERINTERFACE); m_twain.CsvToUserinterface(ref twuserinterface, "TRUE,FALSE," + Handle); m_twain.DatUserinterface(TWAIN.DG.CONTROL, TWAIN.MSG.ENABLEDSUIONLY, ref twuserinterface); } /// /// Pick the settings for a scan session... /// /// /// private void m_buttonUseUiSettings_Click(object sender, EventArgs e) { OpenFileDialog openfiledialog = new OpenFileDialog(); openfiledialog.InitialDirectory = m_szSettingsFolder; openfiledialog.CheckFileExists = true; openfiledialog.CheckPathExists = true; openfiledialog.Multiselect = false; openfiledialog.Filter = "Settings|*.settings"; openfiledialog.FilterIndex = 0; if (!Directory.Exists(openfiledialog.InitialDirectory)) { try { Directory.CreateDirectory(openfiledialog.InitialDirectory); } catch (Exception exception) { TWAINWorkingGroup.Log.Error("exception - " + exception.Message); MessageBox.Show("Unable to create settings folder...'" + m_szSettingsFolder + "'"); return; } } if (openfiledialog.ShowDialog() == DialogResult.OK) { m_textboxUseUiSettings.Text = Path.GetFileName(openfiledialog.FileName); m_formscan.RestoreSnapshot(Path.Combine(m_szSettingsFolder, m_textboxUseUiSettings.Text)); SaveSetting(m_textboxUseUiSettings.Text); } } /// /// Keep us updated with changes to the save image path... /// /// /// private void m_textboxFolder_TextChanged(object sender, EventArgs e) { SaveFolder(m_textboxFolder.Text); } #endregion /////////////////////////////////////////////////////////////////////////////// // Private Attributes... /////////////////////////////////////////////////////////////////////////////// #region Private Attributes... /// /// The folder we persist data to... /// private string m_szTwainscanFolder; /// /// The settings folder... /// private string m_szSettingsFolder; /// /// Access to the TWAIN driver... /// private TWAIN m_twain; /// /// Access to our main form... /// private FormScan m_formscan; #endregion } } ================================================ FILE: twaincs/source/twaincsscan/source/FormSetup.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 iVBORw0KGgoAAAANSUhEUgAAACEAAAAdCAIAAACrPpLuAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8 YQUAAAAJcEhZcwAADrwAAA68AZW8ckkAAAB7SURBVEhL7c/BCYBADERRK7BlW7KHnOzDuyVEhVFBguxs IsTF4d8W8thO31+TxjKPZniu3WXst6bezMlkMqhw8ViRwXZjvmyICO6axlA7wvCXw8DP+RGGvxwGfs6P MPzlMPBzfoTh7zfKezICs41z23PIcM40wteGoboCUXnZfH5Gxs8AAAAASUVORK5CYII= iVBORw0KGgoAAAANSUhEUgAAACEAAAAdCAIAAACrPpLuAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8 YQUAAAAJcEhZcwAADrwAAA68AZW8ckkAAAB7SURBVEhL7c/BCYBADERRK7BlW7KHnOzDuyVEhVFBguxs IsTF4d8W8thO31+TxjKPZniu3WXst6bezMlkMqhw8ViRwXZjvmyICO6axlA7wvCXw8DP+RGGvxwGfs6P MPzlMPBzfoTh7zfKezICs41z23PIcM40wteGoboCUXnZfH5Gxs8AAAAASUVORK5CYII= ================================================ FILE: twaincs/source/twaincsscan/source/Program.cs ================================================ /////////////////////////////////////////////////////////////////////////////////////// // // TWAINCSScan.Program // // Our entry point. // /////////////////////////////////////////////////////////////////////////////////////// // Author Date Version Comment // M.McLaughlin 21-May-2014 2.0.0.0 64-bit Linux // M.McLaughlin 27-Feb-2014 1.1.0.0 ShowImage additions // M.McLaughlin 21-Oct-2013 1.0.0.0 Initial Release /////////////////////////////////////////////////////////////////////////////////////// // Copyright (C) 2013-2019 Kodak Alaris Inc. // // Permission is hereby granted, free of charge, to any person obtaining a // copy of this software and associated documentation files (the "Software"), // to deal in the Software without restriction, including without limitation // the rights to use, copy, modify, merge, publish, distribute, sublicense, // and/or sell copies of the Software, and to permit persons to whom the // Software is furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL // THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER // DEALINGS IN THE SOFTWARE. /////////////////////////////////////////////////////////////////////////////////////// using System; using System.Collections.Generic; using System.Linq; using System.Windows.Forms; namespace TWAINCSScan { static class Program { /// /// The main entry point for the application. /// [STAThread] static void Main() { FormScan formscan = null; Application.EnableVisualStyles(); Application.SetCompatibleTextRenderingDefault(false); formscan = new FormScan(); if (!formscan.ExitRequested()) { Application.Run(formscan); } formscan = null; Application.Exit(); } } } ================================================ FILE: twaincs/source/twaincsscan/source/Properties/AssemblyInfo.cs ================================================ /////////////////////////////////////////////////////////////////////////////////////// // // TWAINCSScan AssemblyInfo // /////////////////////////////////////////////////////////////////////////////////////// // Copyright (C) 2013-2021 Kodak Alaris Inc. // // Permission is hereby granted, free of charge, to any person obtaining a // copy of this software and associated documentation files (the "Software"), // to deal in the Software without restriction, including without limitation // the rights to use, copy, modify, merge, publish, distribute, sublicense, // and/or sell copies of the Software, and to permit persons to whom the // Software is furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL // THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER // DEALINGS IN THE SOFTWARE. /////////////////////////////////////////////////////////////////////////////////////// using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; // General Information about an assembly is controlled through the following // set of attributes. Change these attribute values to modify the information // associated with an assembly. [assembly: AssemblyTitle("TWAINCSScan")] [assembly: AssemblyDescription("Sample TWAIN application for C#")] [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany("Kodak Alaris Inc.")] [assembly: AssemblyProduct("TWAINCSScan")] [assembly: AssemblyCopyright("Copyright © 2013-2020, Kodak Alaris Inc.")] [assembly: AssemblyTrademark("")] [assembly: AssemblyCulture("")] // Setting ComVisible to false makes the types in this assembly not visible // to COM components. If you need to access a type in this assembly from // COM, set the ComVisible attribute to true on that type. [assembly: ComVisible(false)] // The following GUID is for the ID of the typelib if this project is exposed to COM [assembly: Guid("95c1ce5e-1b22-4739-a390-30ddda10f984")] // Version information for an assembly consists of the following four values: // // Major Version // Minor Version // Build Number // Revision // // You can specify all the values or you can default the Build and Revision Numbers // by using the '*' as shown below: [assembly: AssemblyVersion("2.5.0.0")] [assembly: AssemblyFileVersion("2.5.0.0")] ================================================ FILE: twaincs/source/twaincsscan/source/Properties/Resources.Designer.cs ================================================ //------------------------------------------------------------------------------ // // This code was generated by a tool. // Runtime Version:4.0.30319.42000 // // Changes to this file may cause incorrect behavior and will be lost if // the code is regenerated. // //------------------------------------------------------------------------------ namespace TWAINCSScan.Properties { using System; /// /// A strongly-typed resource class, for looking up localized strings, etc. /// // This class was auto-generated by the StronglyTypedResourceBuilder // class via a tool like ResGen or Visual Studio. // To add or remove a member, edit your .ResX file then rerun ResGen // with the /str option, or rebuild your VS project. [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "15.0.0.0")] [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] internal class Resources { private static global::System.Resources.ResourceManager resourceMan; private static global::System.Globalization.CultureInfo resourceCulture; [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] internal Resources() { } /// /// Returns the cached ResourceManager instance used by this class. /// [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] internal static global::System.Resources.ResourceManager ResourceManager { get { if (object.ReferenceEquals(resourceMan, null)) { global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("TWAINCSScan.Properties.Resources", typeof(Resources).Assembly); resourceMan = temp; } return resourceMan; } } /// /// Overrides the current thread's CurrentUICulture property for all /// resource lookups using this strongly typed resource class. /// [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] internal static global::System.Globalization.CultureInfo Culture { get { return resourceCulture; } set { resourceCulture = value; } } } } ================================================ FILE: twaincs/source/twaincsscan/source/Properties/Resources.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 ================================================ FILE: twaincs/source/twaincsscan/source/Properties/Settings.Designer.cs ================================================ //------------------------------------------------------------------------------ // // This code was generated by a tool. // Runtime Version:4.0.30319.42000 // // Changes to this file may cause incorrect behavior and will be lost if // the code is regenerated. // //------------------------------------------------------------------------------ namespace TWAINCSScan.Properties { [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "15.9.0.0")] internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase { private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings()))); public static Settings Default { get { return defaultInstance; } } } } ================================================ FILE: twaincs/source/twaincsscan/source/Properties/Settings.settings ================================================  ================================================ FILE: twaincs/source/twaincsscan/source/app.config ================================================ ================================================ FILE: twaincs/source/twaincsscan/source/twaincsscan.csproj ================================================  15.0.27428.2005 false true Debug x86 2.0 {DE8AC167-CFF1-446D-9145-29179CA1B472} WinExe Properties TWAINCSScan twaincsscan v4.5.2 512 x86 true full false bin\x86\Debug\ DEBUG;TRACE prompt 4 true true false x86 pdbonly true bin\x86\Release\ TRACE prompt 4 true false true bin\x64\Debug\ DEBUG;TRACE true full x64 prompt false false false true false bin\x64\Release\ TRACE true pdbonly x64 prompt false false false true false true bin\AnyCPU\Debug\ DEBUG;TRACE true full AnyCPU prompt false false false true false bin\AnyCPU\Release\ TRACE true pdbonly AnyCPU prompt false false false true false False ..\..\bin\$(Platform)\$(Configuration)\TWAIN.dll Form FormScan.cs Form FormSetup.cs Form FormSelect.cs FormScan.cs FormSelect.cs FormSetup.cs ResXFileCodeGenerator Resources.Designer.cs Designer True Resources.resx True SettingsSingleFileGenerator Settings.Designer.cs True Settings.settings True ================================================ FILE: twaincs/source/twaincstst/source/Main.Designer.cs ================================================ namespace TWAINCSTst { partial class FormMain { /// /// Required designer variable. /// private System.ComponentModel.IContainer components = null; #region Windows Form Designer generated code /// /// Required method for Designer support - do not modify /// the contents of this method with the code editor. /// private void InitializeComponent() { this.m_richtextboxOutput = new System.Windows.Forms.RichTextBox(); this.m_richtextboxCapability = new System.Windows.Forms.RichTextBox(); this.m_buttonScan = new System.Windows.Forms.Button(); this.m_buttonStop = new System.Windows.Forms.Button(); this.m_pictureboxImage1 = new System.Windows.Forms.PictureBox(); this.m_pictureboxImage2 = new System.Windows.Forms.PictureBox(); this.m_pictureboxImage3 = new System.Windows.Forms.PictureBox(); this.m_pictureboxImage4 = new System.Windows.Forms.PictureBox(); this.m_pictureboxImage5 = new System.Windows.Forms.PictureBox(); this.m_pictureboxImage6 = new System.Windows.Forms.PictureBox(); this.m_pictureboxImage7 = new System.Windows.Forms.PictureBox(); this.m_pictureboxImage8 = new System.Windows.Forms.PictureBox(); this.m_checkboxUseTwain32 = new System.Windows.Forms.CheckBox(); this.m_checkboxUseCallbacks = new System.Windows.Forms.CheckBox(); this.m_labelSeperater4 = new System.Windows.Forms.Label(); this.m_comboboxDG = new System.Windows.Forms.ComboBox(); this.m_comboboxDAT = new System.Windows.Forms.ComboBox(); this.m_comboboxMSG = new System.Windows.Forms.ComboBox(); this.m_buttonSend = new System.Windows.Forms.Button(); ((System.ComponentModel.ISupportInitialize)(this.m_pictureboxImage1)).BeginInit(); ((System.ComponentModel.ISupportInitialize)(this.m_pictureboxImage2)).BeginInit(); ((System.ComponentModel.ISupportInitialize)(this.m_pictureboxImage3)).BeginInit(); ((System.ComponentModel.ISupportInitialize)(this.m_pictureboxImage4)).BeginInit(); ((System.ComponentModel.ISupportInitialize)(this.m_pictureboxImage5)).BeginInit(); ((System.ComponentModel.ISupportInitialize)(this.m_pictureboxImage6)).BeginInit(); ((System.ComponentModel.ISupportInitialize)(this.m_pictureboxImage7)).BeginInit(); ((System.ComponentModel.ISupportInitialize)(this.m_pictureboxImage8)).BeginInit(); this.SuspendLayout(); // // m_richtextboxOutput // this.m_richtextboxOutput.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) | System.Windows.Forms.AnchorStyles.Left) | System.Windows.Forms.AnchorStyles.Right))); this.m_richtextboxOutput.Location = new System.Drawing.Point(11, 425); this.m_richtextboxOutput.Name = "m_richtextboxOutput"; this.m_richtextboxOutput.ReadOnly = true; this.m_richtextboxOutput.Size = new System.Drawing.Size(809, 117); this.m_richtextboxOutput.TabIndex = 4; this.m_richtextboxOutput.Text = ""; // // m_richtextboxCapability // this.m_richtextboxCapability.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) | System.Windows.Forms.AnchorStyles.Right))); this.m_richtextboxCapability.DetectUrls = false; this.m_richtextboxCapability.Location = new System.Drawing.Point(636, 53); this.m_richtextboxCapability.Name = "m_richtextboxCapability"; this.m_richtextboxCapability.ScrollBars = System.Windows.Forms.RichTextBoxScrollBars.Vertical; this.m_richtextboxCapability.Size = new System.Drawing.Size(184, 233); this.m_richtextboxCapability.TabIndex = 8; this.m_richtextboxCapability.Text = ""; // // m_buttonScan // this.m_buttonScan.Location = new System.Drawing.Point(636, 397); this.m_buttonScan.Name = "m_buttonScan"; this.m_buttonScan.Size = new System.Drawing.Size(91, 23); this.m_buttonScan.TabIndex = 11; this.m_buttonScan.Text = "Scan"; this.m_buttonScan.UseVisualStyleBackColor = true; this.m_buttonScan.Click += new System.EventHandler(this.m_buttonScan_Click); // // m_buttonStop // this.m_buttonStop.Location = new System.Drawing.Point(729, 397); this.m_buttonStop.Name = "m_buttonStop"; this.m_buttonStop.Size = new System.Drawing.Size(91, 23); this.m_buttonStop.TabIndex = 12; this.m_buttonStop.Text = "Stop"; this.m_buttonStop.UseVisualStyleBackColor = true; this.m_buttonStop.Click += new System.EventHandler(this.m_buttonStop_Click); // // m_pictureboxImage1 // this.m_pictureboxImage1.BackColor = System.Drawing.Color.White; this.m_pictureboxImage1.BorderStyle = System.Windows.Forms.BorderStyle.Fixed3D; this.m_pictureboxImage1.Location = new System.Drawing.Point(12, 12); this.m_pictureboxImage1.Name = "m_pictureboxImage1"; this.m_pictureboxImage1.Size = new System.Drawing.Size(150, 200); this.m_pictureboxImage1.SizeMode = System.Windows.Forms.PictureBoxSizeMode.Zoom; this.m_pictureboxImage1.TabIndex = 13; this.m_pictureboxImage1.TabStop = false; // // m_pictureboxImage2 // this.m_pictureboxImage2.BackColor = System.Drawing.Color.White; this.m_pictureboxImage2.BorderStyle = System.Windows.Forms.BorderStyle.Fixed3D; this.m_pictureboxImage2.Location = new System.Drawing.Point(168, 12); this.m_pictureboxImage2.Name = "m_pictureboxImage2"; this.m_pictureboxImage2.Size = new System.Drawing.Size(150, 200); this.m_pictureboxImage2.SizeMode = System.Windows.Forms.PictureBoxSizeMode.Zoom; this.m_pictureboxImage2.TabIndex = 14; this.m_pictureboxImage2.TabStop = false; // // m_pictureboxImage3 // this.m_pictureboxImage3.BackColor = System.Drawing.Color.White; this.m_pictureboxImage3.BorderStyle = System.Windows.Forms.BorderStyle.Fixed3D; this.m_pictureboxImage3.Location = new System.Drawing.Point(324, 12); this.m_pictureboxImage3.Name = "m_pictureboxImage3"; this.m_pictureboxImage3.Size = new System.Drawing.Size(150, 200); this.m_pictureboxImage3.SizeMode = System.Windows.Forms.PictureBoxSizeMode.Zoom; this.m_pictureboxImage3.TabIndex = 15; this.m_pictureboxImage3.TabStop = false; // // m_pictureboxImage4 // this.m_pictureboxImage4.BackColor = System.Drawing.Color.White; this.m_pictureboxImage4.BorderStyle = System.Windows.Forms.BorderStyle.Fixed3D; this.m_pictureboxImage4.Location = new System.Drawing.Point(480, 12); this.m_pictureboxImage4.Name = "m_pictureboxImage4"; this.m_pictureboxImage4.Size = new System.Drawing.Size(150, 200); this.m_pictureboxImage4.SizeMode = System.Windows.Forms.PictureBoxSizeMode.Zoom; this.m_pictureboxImage4.TabIndex = 16; this.m_pictureboxImage4.TabStop = false; // // m_pictureboxImage5 // this.m_pictureboxImage5.BackColor = System.Drawing.Color.White; this.m_pictureboxImage5.BorderStyle = System.Windows.Forms.BorderStyle.Fixed3D; this.m_pictureboxImage5.Location = new System.Drawing.Point(12, 218); this.m_pictureboxImage5.Name = "m_pictureboxImage5"; this.m_pictureboxImage5.Size = new System.Drawing.Size(150, 200); this.m_pictureboxImage5.SizeMode = System.Windows.Forms.PictureBoxSizeMode.Zoom; this.m_pictureboxImage5.TabIndex = 17; this.m_pictureboxImage5.TabStop = false; // // m_pictureboxImage6 // this.m_pictureboxImage6.BackColor = System.Drawing.Color.White; this.m_pictureboxImage6.BorderStyle = System.Windows.Forms.BorderStyle.Fixed3D; this.m_pictureboxImage6.Location = new System.Drawing.Point(168, 218); this.m_pictureboxImage6.Name = "m_pictureboxImage6"; this.m_pictureboxImage6.Size = new System.Drawing.Size(150, 200); this.m_pictureboxImage6.SizeMode = System.Windows.Forms.PictureBoxSizeMode.Zoom; this.m_pictureboxImage6.TabIndex = 18; this.m_pictureboxImage6.TabStop = false; // // m_pictureboxImage7 // this.m_pictureboxImage7.BackColor = System.Drawing.Color.White; this.m_pictureboxImage7.BorderStyle = System.Windows.Forms.BorderStyle.Fixed3D; this.m_pictureboxImage7.Location = new System.Drawing.Point(324, 218); this.m_pictureboxImage7.Name = "m_pictureboxImage7"; this.m_pictureboxImage7.Size = new System.Drawing.Size(150, 200); this.m_pictureboxImage7.SizeMode = System.Windows.Forms.PictureBoxSizeMode.Zoom; this.m_pictureboxImage7.TabIndex = 19; this.m_pictureboxImage7.TabStop = false; // // m_pictureboxImage8 // this.m_pictureboxImage8.BackColor = System.Drawing.Color.White; this.m_pictureboxImage8.BorderStyle = System.Windows.Forms.BorderStyle.Fixed3D; this.m_pictureboxImage8.Location = new System.Drawing.Point(480, 218); this.m_pictureboxImage8.Name = "m_pictureboxImage8"; this.m_pictureboxImage8.Size = new System.Drawing.Size(150, 200); this.m_pictureboxImage8.SizeMode = System.Windows.Forms.PictureBoxSizeMode.Zoom; this.m_pictureboxImage8.TabIndex = 20; this.m_pictureboxImage8.TabStop = false; // // m_checkboxUseTwain32 // this.m_checkboxUseTwain32.AutoSize = true; this.m_checkboxUseTwain32.Location = new System.Drawing.Point(640, 12); this.m_checkboxUseTwain32.Name = "m_checkboxUseTwain32"; this.m_checkboxUseTwain32.Size = new System.Drawing.Size(177, 17); this.m_checkboxUseTwain32.TabIndex = 27; this.m_checkboxUseTwain32.Text = "Use TWAIN_32 (Windows only)"; this.m_checkboxUseTwain32.UseVisualStyleBackColor = true; this.m_checkboxUseTwain32.CheckedChanged += new System.EventHandler(this.m_checkboxUseTwain32_CheckedChanged); // // m_checkboxUseCallbacks // this.m_checkboxUseCallbacks.AutoSize = true; this.m_checkboxUseCallbacks.Location = new System.Drawing.Point(640, 30); this.m_checkboxUseCallbacks.Name = "m_checkboxUseCallbacks"; this.m_checkboxUseCallbacks.Size = new System.Drawing.Size(185, 17); this.m_checkboxUseCallbacks.TabIndex = 28; this.m_checkboxUseCallbacks.Text = "Use Callbacks (TWAINDSM only)"; this.m_checkboxUseCallbacks.UseVisualStyleBackColor = true; this.m_checkboxUseCallbacks.CheckedChanged += new System.EventHandler(this.m_checkboxUseCallbacks_CheckedChanged); // // m_labelSeperater4 // this.m_labelSeperater4.BorderStyle = System.Windows.Forms.BorderStyle.Fixed3D; this.m_labelSeperater4.Location = new System.Drawing.Point(636, 391); this.m_labelSeperater4.Name = "m_labelSeperater4"; this.m_labelSeperater4.Size = new System.Drawing.Size(184, 2); this.m_labelSeperater4.TabIndex = 30; // // m_comboboxDG // this.m_comboboxDG.FormattingEnabled = true; this.m_comboboxDG.Location = new System.Drawing.Point(637, 292); this.m_comboboxDG.Name = "m_comboboxDG"; this.m_comboboxDG.Size = new System.Drawing.Size(183, 21); this.m_comboboxDG.Sorted = true; this.m_comboboxDG.TabIndex = 38; // // m_comboboxDAT // this.m_comboboxDAT.FormattingEnabled = true; this.m_comboboxDAT.Location = new System.Drawing.Point(637, 315); this.m_comboboxDAT.Name = "m_comboboxDAT"; this.m_comboboxDAT.Size = new System.Drawing.Size(183, 21); this.m_comboboxDAT.Sorted = true; this.m_comboboxDAT.TabIndex = 39; // // m_comboboxMSG // this.m_comboboxMSG.FormattingEnabled = true; this.m_comboboxMSG.Location = new System.Drawing.Point(637, 338); this.m_comboboxMSG.Name = "m_comboboxMSG"; this.m_comboboxMSG.Size = new System.Drawing.Size(183, 21); this.m_comboboxMSG.Sorted = true; this.m_comboboxMSG.TabIndex = 40; // // m_buttonSend // this.m_buttonSend.Location = new System.Drawing.Point(729, 362); this.m_buttonSend.Name = "m_buttonSend"; this.m_buttonSend.Size = new System.Drawing.Size(91, 23); this.m_buttonSend.TabIndex = 41; this.m_buttonSend.Text = "Send"; this.m_buttonSend.UseVisualStyleBackColor = true; this.m_buttonSend.Click += new System.EventHandler(this.SendDat); // // FormMain // this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; this.ClientSize = new System.Drawing.Size(826, 554); this.Controls.Add(this.m_buttonSend); this.Controls.Add(this.m_comboboxMSG); this.Controls.Add(this.m_comboboxDAT); this.Controls.Add(this.m_comboboxDG); this.Controls.Add(this.m_labelSeperater4); this.Controls.Add(this.m_checkboxUseCallbacks); this.Controls.Add(this.m_checkboxUseTwain32); this.Controls.Add(this.m_pictureboxImage8); this.Controls.Add(this.m_pictureboxImage7); this.Controls.Add(this.m_pictureboxImage6); this.Controls.Add(this.m_pictureboxImage5); this.Controls.Add(this.m_pictureboxImage4); this.Controls.Add(this.m_pictureboxImage3); this.Controls.Add(this.m_pictureboxImage2); this.Controls.Add(this.m_pictureboxImage1); this.Controls.Add(this.m_buttonStop); this.Controls.Add(this.m_buttonScan); this.Controls.Add(this.m_richtextboxCapability); this.Controls.Add(this.m_richtextboxOutput); this.MinimumSize = new System.Drawing.Size(842, 592); this.Name = "FormMain"; this.Text = "TWAIN Test Tool (for C#)"; ((System.ComponentModel.ISupportInitialize)(this.m_pictureboxImage1)).EndInit(); ((System.ComponentModel.ISupportInitialize)(this.m_pictureboxImage2)).EndInit(); ((System.ComponentModel.ISupportInitialize)(this.m_pictureboxImage3)).EndInit(); ((System.ComponentModel.ISupportInitialize)(this.m_pictureboxImage4)).EndInit(); ((System.ComponentModel.ISupportInitialize)(this.m_pictureboxImage5)).EndInit(); ((System.ComponentModel.ISupportInitialize)(this.m_pictureboxImage6)).EndInit(); ((System.ComponentModel.ISupportInitialize)(this.m_pictureboxImage7)).EndInit(); ((System.ComponentModel.ISupportInitialize)(this.m_pictureboxImage8)).EndInit(); this.ResumeLayout(false); this.PerformLayout(); } #endregion private System.Windows.Forms.RichTextBox m_richtextboxOutput; private System.Windows.Forms.RichTextBox m_richtextboxCapability; private System.Windows.Forms.Button m_buttonScan; private System.Windows.Forms.Button m_buttonStop; private System.Windows.Forms.PictureBox m_pictureboxImage1; private System.Windows.Forms.PictureBox m_pictureboxImage2; private System.Windows.Forms.PictureBox m_pictureboxImage3; private System.Windows.Forms.PictureBox m_pictureboxImage4; private System.Windows.Forms.PictureBox m_pictureboxImage5; private System.Windows.Forms.PictureBox m_pictureboxImage6; private System.Windows.Forms.PictureBox m_pictureboxImage7; private System.Windows.Forms.PictureBox m_pictureboxImage8; private System.Windows.Forms.CheckBox m_checkboxUseTwain32; private System.Windows.Forms.CheckBox m_checkboxUseCallbacks; private System.Windows.Forms.Label m_labelSeperater4; private System.Windows.Forms.ComboBox m_comboboxDG; private System.Windows.Forms.ComboBox m_comboboxDAT; private System.Windows.Forms.ComboBox m_comboboxMSG; private System.Windows.Forms.Button m_buttonSend; } } ================================================ FILE: twaincs/source/twaincstst/source/Main.cs ================================================ /////////////////////////////////////////////////////////////////////////////////////// // // TWAINCSTst.FormMain // // This is the main form for a developerment application. Don't use this code as // the template for a new app. Use TWAINCSSCAN instead, it's smaller and easier // to understand. // // This application offers access to all of the standard and custom TWAIN content // that one can find in a scanner vendor's TWAIN driver. It's a diagnostic tool, // that lets one exercise drivers. It also showcases all of the ways of getting // and setting driver data. So while TWAINCSSCAN is the template for a new // application, this is the reference guide for specific items that a developer // may want to add to their code. // /////////////////////////////////////////////////////////////////////////////////////// // Author Date Version Comment // M.McLaughlin 21-May-2014 2.0.0.0 64-bit Linux // M.McLaughlin 27-Feb-2014 1.1.0.0 ShowImage additions // M.McLaughlin 21-Oct-2013 1.0.0.0 Initial Release /////////////////////////////////////////////////////////////////////////////////////// // Copyright (C) 2013-2019 Kodak Alaris Inc. // // Permission is hereby granted, free of charge, to any person obtaining a // copy of this software and associated documentation files (the "Software"), // to deal in the Software without restriction, including without limitation // the rights to use, copy, modify, merge, publish, distribute, sublicense, // and/or sell copies of the Software, and to permit persons to whom the // Software is furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL // THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER // DEALINGS IN THE SOFTWARE. /////////////////////////////////////////////////////////////////////////////////////// using System; using System.Collections.Generic; using System.Diagnostics.CodeAnalysis; using System.Drawing; using System.Drawing.Drawing2D; using System.Drawing.Imaging; using System.Globalization; using System.IO; using System.Runtime.InteropServices; using System.Security.Permissions; using System.Windows.Forms; using TWAINWorkingGroup; namespace TWAINCSTst { /// /// Here's a form for us to tinker with. We're using this to exercise the /// TWAIN object. /// public partial class FormMain : Form, IMessageFilter, IDisposable { /////////////////////////////////////////////////////////////////////////////// // Public Functions... /////////////////////////////////////////////////////////////////////////////// #region Public Functions... /// /// Init our form, and our TWAIN class. You might want to consider /// moving TWAIN into its own thread, or even running it from a /// separate process, so that the main application is always responsive /// no matter what's going on in the driver... /// public FormMain() { ContextMenu contextmenu; MenuItem menuitem; // Init our form... InitializeComponent(); // Open the log in our working folder, and say hi... TWAINWorkingGroup.Log.Open("TWAINCSTst", ".", 1); TWAINWorkingGroup.Log.Info("TWAINCSTst v" + System.Reflection.Assembly.GetEntryAssembly().GetName().Version.ToString()); // Make sure we cleanup if unexpectedly closed... this.FormClosing += new FormClosingEventHandler(FormMain_FormClosing); // This next bit establishes the rules for the various DSM's on the // various operating systems. // Windows controls... if (TWAIN.GetPlatform() == TWAIN.Platform.WINDOWS) { // Choose between TWAIN_32 and TWAINDSM, note that we always default // to the open source TWAIN DSM... m_checkboxUseTwain32.Enabled = (TWAIN.GetMachineWordBitSize() == 32); m_checkboxUseCallbacks.Enabled = true; m_checkboxUseTwain32.Checked = false; m_checkboxUseCallbacks.Checked = true; } // Linux controls... else if (TWAIN.GetPlatform() == TWAIN.Platform.LINUX) { // We don't give the user control between the DSM versions, because // the 64-bit problem is handled as seamlessly as possible... m_checkboxUseTwain32.Enabled = false; m_checkboxUseCallbacks.Enabled = false; m_checkboxUseTwain32.Checked = false; m_checkboxUseCallbacks.Checked = true; } // Mac OS X controls... else if (TWAIN.GetPlatform() == TWAIN.Platform.MACOSX) { // Choose between /System/Library/Frameworks/TWAIN.framework and // /Library/Frameworks/TWAINDSM.framework, note that we always default // to the open source TWAIN DSM... m_checkboxUseTwain32.Enabled = true; m_checkboxUseCallbacks.Enabled = false; m_checkboxUseTwain32.Checked = false; m_checkboxUseCallbacks.Checked = true; } // Autoscroll the text in our output box... m_richtextboxOutput.HideSelection = false; m_richtextboxOutput.SelectionProtected = false; // Init other stuff... m_twain = null; m_intptrHwnd = Handle; // Init our image controls... InitImage(); // Load our triplet dropdown... List aszDat = new List(); List aszMsg = new List(); foreach (string szDat in (string[])Enum.GetNames(typeof(TWAIN.DAT))) aszDat.Add("DAT_" + szDat); foreach (string szMsg in (string[])Enum.GetNames(typeof(TWAIN.MSG))) aszMsg.Add("MSG_" + szMsg); this.m_comboboxDG.Items.AddRange(new string[] { "DG_AUDIO", "DG_CONTROL", "DG_IMAGE" }); this.m_comboboxDAT.Items.AddRange(aszDat.ToArray()); this.m_comboboxMSG.Items.AddRange(aszMsg.ToArray()); // Init our triplet dropdown... AutoDropdown("", "", ""); // Context menu for our value box... contextmenu = new ContextMenu(); menuitem = new MenuItem("Copy"); menuitem.Click += new EventHandler(richtextboxcapability_Copy); contextmenu.MenuItems.Add(menuitem); menuitem = new MenuItem("Paste"); menuitem.Click += new EventHandler(richtextboxcapability_Paste); contextmenu.MenuItems.Add(menuitem); m_richtextboxCapability.ContextMenu = contextmenu; contextmenu = null; // Context menu for our output box... contextmenu = new ContextMenu(); menuitem = new MenuItem("Copy"); menuitem.Click += new EventHandler(richtextboxoutput_Copy); contextmenu.MenuItems.Add(menuitem); menuitem = new MenuItem("Paste"); menuitem.Click += new EventHandler(richtextboxoutput_Paste); contextmenu.MenuItems.Add(menuitem); m_richtextboxOutput.ContextMenu = contextmenu; contextmenu = null; // Set the capbility box to our app info... m_richtextboxCapability.Text = "TWAIN Working Group," + "TWAIN Sharp," + "TWAIN Sharp Test App," + "2," + "4," + "0x20000003," + "USA," + "testing...," + "ENGLISH_USA"; } /// /// Call the form's filter function to catch stuff like MSG.XFERREADY... /// /// Message to process /// Result of the processing [SecurityPermissionAttribute(SecurityAction.LinkDemand, Flags = SecurityPermissionFlag.UnmanagedCode)] public bool PreFilterMessage(ref Message a_message) { if (m_twain != null) { return (m_twain.PreFilterMessage(a_message.HWnd, a_message.Msg, a_message.WParam, a_message.LParam)); } return (true); } /// /// Our scan callback event, used to drive the engine when scanning... /// public delegate void ScanCallbackEvent(); /// /// Our event handler for the scan callback event. This will be /// called once by ScanCallbackTrigger on receipt of an event /// like MSG_XFERREADY, and then will be reissued on every call /// into ScanCallback until we're done and get back to state 4. /// /// This helps to make sure we're always running in the context /// of FormMain on Windows, which is critical if we want drivers /// to work properly. It also gives a way to break up the calls /// so the message pump is still reponsive. /// /// /// private void ScanCallbackEventHandler(object sender, EventArgs e) { ScanCallback((m_twain == null) ? true : (m_twain.GetState() <= TWAIN.STATE.S3)); } /// /// Rollback the TWAIN state to whatever is requested... /// /// public void Rollback(TWAIN.STATE a_state) { string szTwmemref = ""; string szStatus = ""; TWAIN.STS sts; // Make sure we have something to work with... if (m_twain == null) { return; } // Walk the states, we don't care about the status returns. Basically, // these need to work, or we're guaranteed to hang... // 7 --> 6 if ((m_twain.GetState() == TWAIN.STATE.S7) && (a_state < TWAIN.STATE.S7)) { szTwmemref = "0,0"; szStatus = ""; sts = Send("DG_CONTROL", "DAT_PENDINGXFERS", "MSG_ENDXFER", ref szTwmemref, ref szStatus); szStatus = (szStatus == "") ? sts.ToString() : (sts.ToString() + " - " + szStatus); WriteTriplet("DG_CONTROL", "DAT_PENDINGXFERS", "MSG_ENDXFER", szStatus + ((szTwmemref == "") ? "" : (Environment.NewLine + szTwmemref))); } // 6 --> 5 if ((m_twain.GetState() == TWAIN.STATE.S6) && (a_state < TWAIN.STATE.S6)) { szTwmemref = "0,0"; szStatus = ""; sts = Send("DG_CONTROL", "DAT_PENDINGXFERS", "MSG_RESET", ref szTwmemref, ref szStatus); szStatus = (szStatus == "") ? sts.ToString() : (sts.ToString() + " - " + szStatus); WriteTriplet("DG_CONTROL", "DAT_PENDINGXFERS", "MSG_RESET", szStatus + ((szTwmemref == "") ? "" : (Environment.NewLine + szTwmemref))); } // 5 --> 4 if ((m_twain.GetState() == TWAIN.STATE.S5) && (a_state < TWAIN.STATE.S5)) { szTwmemref = "0,0," + m_intptrHwnd; szStatus = ""; sts = Send("DG_CONTROL", "DAT_USERINTERFACE", "MSG_DISABLEDS", ref szTwmemref, ref szStatus); szStatus = (szStatus == "") ? sts.ToString() : (sts.ToString() + " - " + szStatus); WriteTriplet("DG_CONTROL", "DAT_USERINTERFACE", "MSG_DISABLEDS", szStatus + ((szTwmemref == "") ? "" : (Environment.NewLine + szTwmemref))); ClearEvents(); } // 4 --> 3 if ((m_twain.GetState() == TWAIN.STATE.S4) && (a_state < TWAIN.STATE.S4)) { if (!m_checkboxUseCallbacks.Checked) { Application.RemoveMessageFilter(this); } szTwmemref = m_twain.GetDsIdentity(); szStatus = ""; sts = Send("DG_CONTROL", "DAT_IDENTITY", "MSG_CLOSEDS", ref szTwmemref, ref szStatus); szStatus = (szStatus == "") ? sts.ToString() : (sts.ToString() + " - " + szStatus); WriteTriplet("DG_CONTROL", "DAT_IDENTITY", "MSG_CLOSEDS", szStatus + ((szTwmemref == "") ? "" : (Environment.NewLine + szTwmemref))); } // 3 --> 2 if ((m_twain.GetState() == TWAIN.STATE.S3) && (a_state < TWAIN.STATE.S3)) { szTwmemref = m_intptrHwnd.ToString(); szStatus = ""; sts = Send("DG_CONTROL", "DAT_PARENT", "MSG_CLOSEDSM", ref szTwmemref, ref szStatus); szStatus = (szStatus == "") ? sts.ToString() : (sts.ToString() + " - " + szStatus); WriteTriplet("DG_CONTROL", "DAT_PARENT", "MSG_CLOSEDSM", szStatus + ((szTwmemref == "") ? "" : (Environment.NewLine + szTwmemref))); } // 2 --> 1 if ((m_twain.GetState() == TWAIN.STATE.S2) && (a_state < TWAIN.STATE.S2)) { m_twain.Dispose(); m_twain = null; } } /// /// Our scanning callback function. We appeal directly to the supporting /// TWAIN object. This way we don't have to maintain some kind of a loop /// inside of the application, which is the source of most problems that /// developers run into. /// /// While it looks scary at first, there's really not a lot going on in /// here. We do some sanity checks, we watch for certain kinds of events, /// we support the four methods of transferring images, and we dump out /// some meta-data about the transferred image. However, because it does /// look scary I dropped in some region pragmas to break things up... /// /// We're shutting down /// TWAIN status private TWAIN.STS ScanCallbackTrigger(bool a_blClosing) { BeginInvoke(new MethodInvoker(delegate { ScanCallbackEventHandler(this, new EventArgs()); })); return (TWAIN.STS.SUCCESS); } private TWAIN.STS ScanCallback(bool a_blClosing) { string szTwmemref = ""; string szStatus = ""; TWAIN.STS sts; // Scoot... if (m_twain == null) { return (TWAIN.STS.FAILURE); } // We're superfluous... if (m_twain.GetState() <= TWAIN.STATE.S4) { return (TWAIN.STS.SUCCESS); } // We're leaving... if (a_blClosing) { return (TWAIN.STS.SUCCESS); } // Do this in the right thread, we'll usually be in the // right spot, save maybe on the first call... if (this.InvokeRequired) { return ( (TWAIN.STS)Invoke ( (Func)delegate { return (ScanCallback(a_blClosing)); } ) ); } // Handle DAT_NULL/MSG_XFERREADY... if (m_twain.IsMsgXferReady() && !m_blXferReadySent) { m_blXferReadySent = true; // What transfer mechanism are we using? szTwmemref = "ICAP_XFERMECH,0,0,0"; szStatus = ""; sts = Send("DG_CONTROL", "DAT_CAPABILITY", "MSG_GETCURRENT", ref szTwmemref, ref szStatus); szStatus = (szStatus == "") ? sts.ToString() : (sts.ToString() + " - " + szStatus); WriteTriplet("DG_CONTROL", "DAT_SETUPMEMXFER", "MSG_GET", szStatus + ((szTwmemref == "") ? "" : (Environment.NewLine + szTwmemref))); if (szTwmemref.EndsWith("TWSX_NATIVE")) m_twsxXferMech = TWAIN.TWSX.NATIVE; else if (szTwmemref.EndsWith("TWSX_MEMORY")) m_twsxXferMech = TWAIN.TWSX.MEMORY; else if (szTwmemref.EndsWith("TWSX_FILE")) m_twsxXferMech = TWAIN.TWSX.FILE; else if (szTwmemref.EndsWith("TWSX_MEMFILE")) m_twsxXferMech = TWAIN.TWSX.MEMFILE; // Memory and memfile transfers need this... if ((m_twsxXferMech == TWAIN.TWSX.MEMORY) || (m_twsxXferMech == TWAIN.TWSX.MEMFILE)) { // Get the amount of memory needed... szTwmemref = "0,0,0"; szStatus = ""; sts = Send("DG_CONTROL", "DAT_SETUPMEMXFER", "MSG_GET", ref szTwmemref, ref szStatus); TWAIN.CsvToSetupmemxfer(ref m_twsetupmemxfer, szTwmemref); szStatus = (szStatus == "") ? sts.ToString() : (sts.ToString() + " - " + szStatus); WriteTriplet("DG_CONTROL", "DAT_SETUPMEMXFER", "MSG_GET", szStatus + ((szTwmemref == "") ? "" : (Environment.NewLine + szTwmemref))); if ((sts != TWAIN.STS.SUCCESS) || (m_twsetupmemxfer.Preferred == 0)) { m_blXferReadySent = false; if (!m_blDisableDsSent) { m_blDisableDsSent = true; Rollback(TWAIN.STATE.S4); } } // Allocate the transfer memory (with a little extra to protect ourselves)... m_intptrXfer = Marshal.AllocHGlobal((int)m_twsetupmemxfer.Preferred + 65536); if (m_intptrXfer == IntPtr.Zero) { m_blDisableDsSent = true; Rollback(TWAIN.STATE.S4); } } } // Handle DAT_NULL/MSG_CLOSEDSREQ... if (m_twain.IsMsgCloseDsReq() && !m_blDisableDsSent) { m_blDisableDsSent = true; Rollback(TWAIN.STATE.S4); } // Handle DAT_NULL/MSG_CLOSEDSOK... if (m_twain.IsMsgCloseDsOk() && !m_blDisableDsSent) { m_blDisableDsSent = true; Rollback(TWAIN.STATE.S4); } // This is where the statemachine runs that transfers and optionally // saves the images to disk (it also displays them). It'll go back // and forth between states 6 and 7 until an error occurs, or until // we run out of images... if (m_blXferReadySent && !m_blDisableDsSent) { switch (m_twsxXferMech) { default: case TWAIN.TWSX.NATIVE: CaptureNativeImages(); break; case TWAIN.TWSX.MEMORY: CaptureMemImages(); break; case TWAIN.TWSX.FILE: CaptureFileImages(); break; case TWAIN.TWSX.MEMFILE: CaptureMemfileImages(); break; } } // Trigger the next event, this is where things all chain together. // We need begininvoke to prevent blockking, so that we don't get // backed up into a messy kind of recursion. We need DoEvents, // because if things really start moving fast it's really hard for // application events, like button clicks to break through... Application.DoEvents(); BeginInvoke(new MethodInvoker(delegate { ScanCallbackEventHandler(this, new EventArgs()); })); // All done... return (TWAIN.STS.SUCCESS); } /// /// Go through the sequence needed to capture images using DAT_IMAGENATIVEXFER... /// private void CaptureNativeImages() { string szTwmemref = ""; string szStatus = ""; IntPtr intptrHandle = IntPtr.Zero; IntPtr intptrPtr = IntPtr.Zero; TWAIN.STS sts; TWAIN.TW_PENDINGXFERS twpendingxfers = default(TWAIN.TW_PENDINGXFERS); // Dispatch on the state... switch (m_twain.GetState()) { // Not a good state, just scoot... default: return; // We're on our way out... case TWAIN.STATE.S5: m_blDisableDsSent = true; Rollback(TWAIN.STATE.S4); return; // Native transfers... case TWAIN.STATE.S6: szTwmemref = "0"; szStatus = ""; sts = Send("DG_IMAGE", "DAT_IMAGENATIVEXFER", "MSG_GET", ref szTwmemref, ref szStatus); if (!string.IsNullOrEmpty(szTwmemref)) { UInt64 u64Handle; if (UInt64.TryParse(szTwmemref, out u64Handle)) { intptrHandle = (IntPtr)u64Handle; } } szStatus = (szStatus == "") ? sts.ToString() : (sts.ToString() + " - " + szStatus); WriteTriplet("DG_IMAGE", "DAT_IMAGENATIVEXFER", "MSG_GET", szStatus + ((szTwmemref == "") ? "" : (Environment.NewLine + szTwmemref))); break; } // Handle problems... if (sts != TWAIN.STS.XFERDONE) { m_blDisableDsSent = true; Rollback(TWAIN.STATE.S4); return; } // Ruh-roh... if (intptrHandle == IntPtr.Zero) { m_blDisableDsSent = true; Rollback(TWAIN.STATE.S4); return; } // If we saw XFERDONE we can save the image, display it, // end the transfer, and see if we have more images... if (sts == TWAIN.STS.XFERDONE) { // Bump up our image counter, this always grows for the // life of the entire session... m_iImageCount += 1; // Get our pointer... intptrPtr = m_twain.DsmMemLock(intptrHandle); if (intptrPtr == IntPtr.Zero) { m_blDisableDsSent = true; Rollback(TWAIN.STATE.S4); return; } // Turn our image pointer into a byte array... int iHeaderBytes; byte[] abImage = m_twain.NativeToByteArray(intptrPtr, true, out iHeaderBytes); // Unlock and free the memory we got from the scanner... m_twain.DsmMemUnlock(intptrHandle); m_twain.DsmMemFree(ref intptrHandle); // Save the image to disk, if we're doing that... /* if (!string.IsNullOrEmpty(m_formsetup.GetImageFolder())) { // Create the directory, if needed... if (!Directory.Exists(m_formsetup.GetImageFolder())) { try { Directory.CreateDirectory(m_formsetup.GetImageFolder()); } catch (Exception exception) { TWAINWorkingGroup.Log.Error("CreateDirectory failed - " + exception.Message); } } // Write it out... string szFilename = Path.Combine(m_formsetup.GetImageFolder(), "img" + string.Format("{0:D6}", m_iImageCount)); TWAIN.WriteImageFile(szFilename, m_intptrImage, m_iImageBytes, out szFilename); } */ // Turn the byte array into a stream... MemoryStream memorystream = new MemoryStream(abImage); Bitmap bitmap = (Bitmap)Image.FromStream(memorystream); // Display the image... // Display the image... switch (m_iCurrentPictureBox) { default: case 0: LoadImage(ref m_pictureboxImage1, ref m_graphics1, ref m_bitmapGraphic1, bitmap); break; case 1: LoadImage(ref m_pictureboxImage2, ref m_graphics2, ref m_bitmapGraphic2, bitmap); break; case 2: LoadImage(ref m_pictureboxImage3, ref m_graphics3, ref m_bitmapGraphic3, bitmap); break; case 3: LoadImage(ref m_pictureboxImage4, ref m_graphics4, ref m_bitmapGraphic4, bitmap); break; case 4: LoadImage(ref m_pictureboxImage5, ref m_graphics5, ref m_bitmapGraphic5, bitmap); break; case 5: LoadImage(ref m_pictureboxImage6, ref m_graphics6, ref m_bitmapGraphic6, bitmap); break; case 6: LoadImage(ref m_pictureboxImage7, ref m_graphics7, ref m_bitmapGraphic7, bitmap); break; case 7: LoadImage(ref m_pictureboxImage8, ref m_graphics8, ref m_bitmapGraphic8, bitmap); break; } // Next picture box... if (++m_iCurrentPictureBox >= 8) { m_iCurrentPictureBox = 0; } // Cleanup... bitmap.Dispose(); memorystream = null; // disposed by the bitmap abImage = null; // End the transfer... szTwmemref = "0,0"; szStatus = ""; sts = Send("DG_CONTROL", "DAT_PENDINGXFERS", "MSG_ENDXFER", ref szTwmemref, ref szStatus); TWAIN.CsvToPendingXfers(ref twpendingxfers, szTwmemref); szStatus = (szStatus == "") ? sts.ToString() : (sts.ToString() + " - " + szStatus); WriteTriplet("DG_CONTROL", "DAT_PENDINGXFERS", "MSG_ENDXFER", szStatus + ((szTwmemref == "") ? "" : (Environment.NewLine + szTwmemref))); // Looks like we're done! if (twpendingxfers.Count == 0) { m_blDisableDsSent = true; Rollback(TWAIN.STATE.S4); return; } } } /// /// Go through the sequence needed to capture images using DAT_IMAGEMEMXFER... /// private void CaptureMemImages() { string szTwmemref = ""; string szStatus = ""; TWAIN.STS sts; TWAIN.TW_IMAGEINFO twimageinfo = default(TWAIN.TW_IMAGEINFO); TWAIN.TW_IMAGEMEMXFER twimagememxfer = default(TWAIN.TW_IMAGEMEMXFER); TWAIN.TW_PENDINGXFERS twpendingxfers = default(TWAIN.TW_PENDINGXFERS); // Dispatch on the state... switch (m_twain.GetState()) { // Not a good state, just scoot... default: return; // We're on our way out... case TWAIN.STATE.S5: m_blDisableDsSent = true; Rollback(TWAIN.STATE.S4); return; // Memory transfers... case TWAIN.STATE.S6: case TWAIN.STATE.S7: szTwmemref = "0,0,0,0,0,0,0," + ((int)TWAIN.TWMF.APPOWNS | (int)TWAIN.TWMF.POINTER) + "," + m_twsetupmemxfer.Preferred + "," + m_intptrXfer; szStatus = ""; sts = Send("DG_IMAGE", "DAT_IMAGEMEMXFER", "MSG_GET", ref szTwmemref, ref szStatus); TWAIN.CsvToImagememxfer(ref twimagememxfer, szTwmemref); szStatus = (szStatus == "") ? sts.ToString() : (sts.ToString() + " - " + szStatus); WriteTriplet("DG_IMAGE", "DAT_IMAGEMEMXFER", "MSG_GET", szStatus + ((szTwmemref == "") ? "" : (Environment.NewLine + szTwmemref))); break; } // Handle problems... if ((sts != TWAIN.STS.SUCCESS) && (sts != TWAIN.STS.XFERDONE)) { m_blDisableDsSent = true; Rollback(TWAIN.STATE.S4); return; } // Allocate or grow the image memory... if (m_intptrImage == IntPtr.Zero) { m_intptrImage = Marshal.AllocHGlobal((int)twimagememxfer.BytesWritten); } else { m_intptrImage = Marshal.ReAllocHGlobal(m_intptrImage, (IntPtr)(m_iImageBytes + twimagememxfer.BytesWritten)); } // Ruh-roh... if (m_intptrImage == IntPtr.Zero) { m_blDisableDsSent = true; Rollback(TWAIN.STATE.S4); return; } // Copy into the buffer, and bump up our byte tally... TWAIN.MemCpy(m_intptrImage + m_iImageBytes, m_intptrXfer, (int)twimagememxfer.BytesWritten); m_iImageBytes += (int)twimagememxfer.BytesWritten; // If we saw XFERDONE we can save the image, display it, // end the transfer, and see if we have more images... if (sts == TWAIN.STS.XFERDONE) { // Bump up our image counter, this always grows for the // life of the entire session... m_iImageCount += 1; // Get the image info... szTwmemref = "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0"; szStatus = ""; sts = Send("DG_IMAGE", "DAT_IMAGEINFO", "MSG_GET", ref szTwmemref, ref szStatus); TWAIN.CsvToImageinfo(ref twimageinfo, szTwmemref); szStatus = (szStatus == "") ? sts.ToString() : (sts.ToString() + " - " + szStatus); WriteTriplet("DG_IMAGE", "DAT_IMAGEINFO", "MSG_GET", szStatus + ((szTwmemref == "") ? "" : (Environment.NewLine + szTwmemref))); // Add the appropriate header... // Bitonal uncompressed... if (((TWAIN.TWPT)twimageinfo.PixelType == TWAIN.TWPT.BW) && ((TWAIN.TWCP)twimageinfo.Compression == TWAIN.TWCP.NONE)) { TWAIN.TiffBitonalUncompressed tiffbitonaluncompressed; tiffbitonaluncompressed = new TWAIN.TiffBitonalUncompressed((uint)twimageinfo.ImageWidth, (uint)twimageinfo.ImageLength, (uint)twimageinfo.XResolution.Whole, (uint)m_iImageBytes); m_intptrImage = Marshal.ReAllocHGlobal(m_intptrImage, (IntPtr)(Marshal.SizeOf(tiffbitonaluncompressed) + m_iImageBytes)); TWAIN.MemMove((IntPtr)((UInt64)m_intptrImage + (UInt64)Marshal.SizeOf(tiffbitonaluncompressed)), m_intptrImage, m_iImageBytes); Marshal.StructureToPtr(tiffbitonaluncompressed, m_intptrImage, true); m_iImageBytes += (int)Marshal.SizeOf(tiffbitonaluncompressed); } // Bitonal GROUP4... else if (((TWAIN.TWPT)twimageinfo.PixelType == TWAIN.TWPT.BW) && ((TWAIN.TWCP)twimageinfo.Compression == TWAIN.TWCP.GROUP4)) { TWAIN.TiffBitonalG4 tiffbitonalg4; tiffbitonalg4 = new TWAIN.TiffBitonalG4((uint)twimageinfo.ImageWidth, (uint)twimageinfo.ImageLength, (uint)twimageinfo.XResolution.Whole, (uint)m_iImageBytes); m_intptrImage = Marshal.ReAllocHGlobal(m_intptrImage, (IntPtr)(Marshal.SizeOf(tiffbitonalg4) + m_iImageBytes)); TWAIN.MemMove((IntPtr)((UInt64)m_intptrImage + (UInt64)Marshal.SizeOf(tiffbitonalg4)), m_intptrImage, m_iImageBytes); Marshal.StructureToPtr(tiffbitonalg4, m_intptrImage, true); m_iImageBytes += (int)Marshal.SizeOf(tiffbitonalg4); } // Gray uncompressed... else if (((TWAIN.TWPT)twimageinfo.PixelType == TWAIN.TWPT.GRAY) && ((TWAIN.TWCP)twimageinfo.Compression == TWAIN.TWCP.NONE)) { TWAIN.TiffGrayscaleUncompressed tiffgrayscaleuncompressed; tiffgrayscaleuncompressed = new TWAIN.TiffGrayscaleUncompressed((uint)twimageinfo.ImageWidth, (uint)twimageinfo.ImageLength, (uint)twimageinfo.XResolution.Whole, (uint)m_iImageBytes); m_intptrImage = Marshal.ReAllocHGlobal(m_intptrImage, (IntPtr)(Marshal.SizeOf(tiffgrayscaleuncompressed) + m_iImageBytes)); TWAIN.MemMove((IntPtr)((UInt64)m_intptrImage + (UInt64)Marshal.SizeOf(tiffgrayscaleuncompressed)), m_intptrImage, m_iImageBytes); Marshal.StructureToPtr(tiffgrayscaleuncompressed, m_intptrImage, true); m_iImageBytes += (int)Marshal.SizeOf(tiffgrayscaleuncompressed); } // Gray JPEG... else if (((TWAIN.TWPT)twimageinfo.PixelType == TWAIN.TWPT.GRAY) && ((TWAIN.TWCP)twimageinfo.Compression == TWAIN.TWCP.JPEG)) { // No work to be done, we'll output JPEG... } // RGB uncompressed... else if (((TWAIN.TWPT)twimageinfo.PixelType == TWAIN.TWPT.RGB) && ((TWAIN.TWCP)twimageinfo.Compression == TWAIN.TWCP.NONE)) { TWAIN.TiffColorUncompressed tiffcoloruncompressed; tiffcoloruncompressed = new TWAIN.TiffColorUncompressed((uint)twimageinfo.ImageWidth, (uint)twimageinfo.ImageLength, (uint)twimageinfo.XResolution.Whole, (uint)m_iImageBytes); m_intptrImage = Marshal.ReAllocHGlobal(m_intptrImage, (IntPtr)(Marshal.SizeOf(tiffcoloruncompressed) + m_iImageBytes)); TWAIN.MemMove((IntPtr)((UInt64)m_intptrImage + (UInt64)Marshal.SizeOf(tiffcoloruncompressed)), m_intptrImage, m_iImageBytes); Marshal.StructureToPtr(tiffcoloruncompressed, m_intptrImage, true); m_iImageBytes += (int)Marshal.SizeOf(tiffcoloruncompressed); } // RGB JPEG... else if (((TWAIN.TWPT)twimageinfo.PixelType == TWAIN.TWPT.RGB) && ((TWAIN.TWCP)twimageinfo.Compression == TWAIN.TWCP.JPEG)) { // No work to be done, we'll output JPEG... } // Oh well... else { TWAINWorkingGroup.Log.Error("unsupported format <" + twimageinfo.PixelType + "," + twimageinfo.Compression + ">"); m_blDisableDsSent = true; Rollback(TWAIN.STATE.S4); return; } // Save the image to disk, if we're doing that... /* if (!string.IsNullOrEmpty(m_formsetup.GetImageFolder())) { // Create the directory, if needed... if (!Directory.Exists(m_formsetup.GetImageFolder())) { try { Directory.CreateDirectory(m_formsetup.GetImageFolder()); } catch (Exception exception) { TWAINWorkingGroup.Log.Error("CreateDirectory failed - " + exception.Message); } } // Write it out... string szFilename = Path.Combine(m_formsetup.GetImageFolder(), "img" + string.Format("{0:D6}", m_iImageCount)); TWAIN.WriteImageFile(szFilename, m_intptrImage, m_iImageBytes, out szFilename); } */ // Turn the image into a byte array, and free the original memory... byte[] abImage = new byte[m_iImageBytes]; Marshal.Copy(m_intptrImage, abImage, 0, m_iImageBytes); Marshal.FreeHGlobal(m_intptrImage); m_intptrImage = IntPtr.Zero; m_iImageBytes = 0; // Turn the byte array into a stream... MemoryStream memorystream = new MemoryStream(abImage); Bitmap bitmap = (Bitmap)Image.FromStream(memorystream); // Display the image... // Display the image... switch (m_iCurrentPictureBox) { default: case 0: LoadImage(ref m_pictureboxImage1, ref m_graphics1, ref m_bitmapGraphic1, bitmap); break; case 1: LoadImage(ref m_pictureboxImage2, ref m_graphics2, ref m_bitmapGraphic2, bitmap); break; case 2: LoadImage(ref m_pictureboxImage3, ref m_graphics3, ref m_bitmapGraphic3, bitmap); break; case 3: LoadImage(ref m_pictureboxImage4, ref m_graphics4, ref m_bitmapGraphic4, bitmap); break; case 4: LoadImage(ref m_pictureboxImage5, ref m_graphics5, ref m_bitmapGraphic5, bitmap); break; case 5: LoadImage(ref m_pictureboxImage6, ref m_graphics6, ref m_bitmapGraphic6, bitmap); break; case 6: LoadImage(ref m_pictureboxImage7, ref m_graphics7, ref m_bitmapGraphic7, bitmap); break; case 7: LoadImage(ref m_pictureboxImage8, ref m_graphics8, ref m_bitmapGraphic8, bitmap); break; } // Next picture box... if (++m_iCurrentPictureBox >= 8) { m_iCurrentPictureBox = 0; } // Cleanup... bitmap.Dispose(); memorystream = null; // disposed by the bitmap abImage = null; // End the transfer... szTwmemref = "0,0"; szStatus = ""; sts = Send("DG_CONTROL", "DAT_PENDINGXFERS", "MSG_ENDXFER", ref szTwmemref, ref szStatus); TWAIN.CsvToPendingXfers(ref twpendingxfers, szTwmemref); szStatus = (szStatus == "") ? sts.ToString() : (sts.ToString() + " - " + szStatus); WriteTriplet("DG_CONTROL", "DAT_PENDINGXFERS", "MSG_ENDXFER", szStatus + ((szTwmemref == "") ? "" : (Environment.NewLine + szTwmemref))); // Looks like we're done! if (twpendingxfers.Count == 0) { m_blDisableDsSent = true; Rollback(TWAIN.STATE.S4); return; } } } /// /// Go through the sequence needed to capture images using DAT_IMAGEFILEXFER... /// private void CaptureFileImages() { string szTwmemref = ""; string szStatus = ""; string szFilename = ""; TWAIN.STS sts; TWAIN.TW_IMAGEINFO twimageinfo = default(TWAIN.TW_IMAGEINFO); TWAIN.TW_PENDINGXFERS twpendingxfers = default(TWAIN.TW_PENDINGXFERS); // Dispatch on the state... switch (m_twain.GetState()) { // Not a good state, just scoot... default: return; // We're on our way out... case TWAIN.STATE.S5: m_blDisableDsSent = true; Rollback(TWAIN.STATE.S4); return; // Memory transfers... case TWAIN.STATE.S6: // Get the image info... szTwmemref = "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0"; szStatus = ""; sts = Send("DG_IMAGE", "DAT_IMAGEINFO", "MSG_GET", ref szTwmemref, ref szStatus); TWAIN.CsvToImageinfo(ref twimageinfo, szTwmemref); szStatus = (szStatus == "") ? sts.ToString() : (sts.ToString() + " - " + szStatus); WriteTriplet("DG_IMAGE", "DAT_IMAGEINFO", "MSG_GET", szStatus + ((szTwmemref == "") ? "" : (Environment.NewLine + szTwmemref))); // Pick an image file format... if (twimageinfo.Compression == (ushort)TWAIN.TWCP.JPEG) { szFilename = "C:/twain/image.jpg"; szTwmemref = szFilename + ",TWFF_JFIF,0"; } else { szFilename = "C:/twain/image.tif"; szTwmemref = szFilename + ",TWFF_TIFF,0"; } szStatus = ""; sts = Send("DG_CONTROL", "DAT_SETUPFILEXFER", "MSG_SET", ref szTwmemref, ref szStatus); szStatus = (szStatus == "") ? sts.ToString() : (sts.ToString() + " - " + szStatus); WriteTriplet("DG_CONTROL", "DAT_SETUPFILEXFER", "MSG_SET", szStatus + ((szTwmemref == "") ? "" : (Environment.NewLine + szTwmemref))); // Transfer stuff... szTwmemref = ""; szStatus = ""; sts = Send("DG_IMAGE", "DAT_IMAGEFILEXFER", "MSG_GET", ref szTwmemref, ref szStatus); szStatus = (szStatus == "") ? sts.ToString() : (sts.ToString() + " - " + szStatus); WriteTriplet("DG_IMAGE", "DAT_IMAGEFILEXFER", "MSG_GET", szStatus + ((szTwmemref == "") ? "" : (Environment.NewLine + szTwmemref))); break; } // Handle problems... if (sts != TWAIN.STS.XFERDONE) { m_blDisableDsSent = true; Rollback(TWAIN.STATE.S4); return; } // Bump up our image counter, this always grows for the // life of the entire session... m_iImageCount += 1; // Read the file... Bitmap bitmap = new Bitmap(szFilename); // Display the image... // Display the image... switch (m_iCurrentPictureBox) { default: case 0: LoadImage(ref m_pictureboxImage1, ref m_graphics1, ref m_bitmapGraphic1, bitmap); break; case 1: LoadImage(ref m_pictureboxImage2, ref m_graphics2, ref m_bitmapGraphic2, bitmap); break; case 2: LoadImage(ref m_pictureboxImage3, ref m_graphics3, ref m_bitmapGraphic3, bitmap); break; case 3: LoadImage(ref m_pictureboxImage4, ref m_graphics4, ref m_bitmapGraphic4, bitmap); break; case 4: LoadImage(ref m_pictureboxImage5, ref m_graphics5, ref m_bitmapGraphic5, bitmap); break; case 5: LoadImage(ref m_pictureboxImage6, ref m_graphics6, ref m_bitmapGraphic6, bitmap); break; case 6: LoadImage(ref m_pictureboxImage7, ref m_graphics7, ref m_bitmapGraphic7, bitmap); break; case 7: LoadImage(ref m_pictureboxImage8, ref m_graphics8, ref m_bitmapGraphic8, bitmap); break; } // Next picture box... if (++m_iCurrentPictureBox >= 8) { m_iCurrentPictureBox = 0; } // Cleanup... bitmap.Dispose(); // End the transfer... szTwmemref = "0,0"; szStatus = ""; sts = Send("DG_CONTROL", "DAT_PENDINGXFERS", "MSG_ENDXFER", ref szTwmemref, ref szStatus); TWAIN.CsvToPendingXfers(ref twpendingxfers, szTwmemref); szStatus = (szStatus == "") ? sts.ToString() : (sts.ToString() + " - " + szStatus); WriteTriplet("DG_CONTROL", "DAT_PENDINGXFERS", "MSG_ENDXFER", szStatus + ((szTwmemref == "") ? "" : (Environment.NewLine + szTwmemref))); // Looks like we're done! if (twpendingxfers.Count == 0) { m_blDisableDsSent = true; Rollback(TWAIN.STATE.S4); return; } } /// /// Go through the sequence needed to capture images using DAT_IMAGEMEMFILEXFER... /// private void CaptureMemfileImages() { string szTwmemref = ""; string szStatus = ""; TWAIN.STS sts; TWAIN.TW_IMAGEINFO twimageinfo = default(TWAIN.TW_IMAGEINFO); TWAIN.TW_IMAGEMEMXFER twimagememxfer = default(TWAIN.TW_IMAGEMEMXFER); TWAIN.TW_PENDINGXFERS twpendingxfers = default(TWAIN.TW_PENDINGXFERS); // Dispatch on the state... switch (m_twain.GetState()) { // Not a good state, just scoot... default: return; // We're on our way out... case TWAIN.STATE.S5: m_blDisableDsSent = true; Rollback(TWAIN.STATE.S4); return; // Memory transfers... case TWAIN.STATE.S6: // Get the image info... szTwmemref = "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0"; szStatus = ""; sts = Send("DG_IMAGE", "DAT_IMAGEINFO", "MSG_GET", ref szTwmemref, ref szStatus); TWAIN.CsvToImageinfo(ref twimageinfo, szTwmemref); szStatus = (szStatus == "") ? sts.ToString() : (sts.ToString() + " - " + szStatus); WriteTriplet("DG_IMAGE", "DAT_IMAGEINFO", "MSG_GET", szStatus + ((szTwmemref == "") ? "" : (Environment.NewLine + szTwmemref))); // Pick an image file format... if (twimageinfo.Compression == (ushort)TWAIN.TWCP.JPEG) { szTwmemref = "C:/twain/image.jpg,TWFF_JFIF,0"; } else { szTwmemref = "C:/twain/image.tif,TWFF_TIFF,0"; } szStatus = ""; sts = Send("DG_CONTROL", "DAT_SETUPFILEXFER", "MSG_SET", ref szTwmemref, ref szStatus); szStatus = (szStatus == "") ? sts.ToString() : (sts.ToString() + " - " + szStatus); WriteTriplet("DG_CONTROL", "DAT_SETUPFILEXFER", "MSG_SET", szStatus + ((szTwmemref == "") ? "" : (Environment.NewLine + szTwmemref))); // Transfer stuff... szTwmemref = "0,0,0,0,0,0,0," + ((int)TWAIN.TWMF.APPOWNS | (int)TWAIN.TWMF.POINTER) + "," + m_twsetupmemxfer.Preferred + "," + m_intptrXfer; szStatus = ""; sts = Send("DG_IMAGE", "DAT_IMAGEMEMFILEXFER", "MSG_GET", ref szTwmemref, ref szStatus); TWAIN.CsvToImagememxfer(ref twimagememxfer, szTwmemref); szStatus = (szStatus == "") ? sts.ToString() : (sts.ToString() + " - " + szStatus); WriteTriplet("DG_IMAGE", "DAT_IMAGEMEMFILEXFER", "MSG_GET", szStatus + ((szTwmemref == "") ? "" : (Environment.NewLine + szTwmemref))); break; case TWAIN.STATE.S7: szTwmemref = "0,0,0,0,0,0,0," + ((int)TWAIN.TWMF.APPOWNS | (int)TWAIN.TWMF.POINTER) + "," + m_twsetupmemxfer.Preferred + "," + m_intptrXfer; szStatus = ""; sts = Send("DG_IMAGE", "DAT_IMAGEMEMFILEXFER", "MSG_GET", ref szTwmemref, ref szStatus); TWAIN.CsvToImagememxfer(ref twimagememxfer, szTwmemref); szStatus = (szStatus == "") ? sts.ToString() : (sts.ToString() + " - " + szStatus); WriteTriplet("DG_IMAGE", "DAT_IMAGEMEMFILEXFER", "MSG_GET", szStatus + ((szTwmemref == "") ? "" : (Environment.NewLine + szTwmemref))); break; } // Handle problems... if ((sts != TWAIN.STS.SUCCESS) && (sts != TWAIN.STS.XFERDONE)) { m_blDisableDsSent = true; Rollback(TWAIN.STATE.S4); return; } // Allocate or grow the image memory... if (m_intptrImage == IntPtr.Zero) { m_intptrImage = Marshal.AllocHGlobal((int)twimagememxfer.BytesWritten); } else { m_intptrImage = Marshal.ReAllocHGlobal(m_intptrImage, (IntPtr)(m_iImageBytes + twimagememxfer.BytesWritten)); } // Ruh-roh... if (m_intptrImage == IntPtr.Zero) { m_blDisableDsSent = true; Rollback(TWAIN.STATE.S4); return; } // Copy into the buffer, and bump up our byte tally... TWAIN.MemCpy(m_intptrImage + m_iImageBytes, m_intptrXfer, (int)twimagememxfer.BytesWritten); m_iImageBytes += (int)twimagememxfer.BytesWritten; // If we saw XFERDONE we can save the image, display it, // end the transfer, and see if we have more images... if (sts == TWAIN.STS.XFERDONE) { // Bump up our image counter, this always grows for the // life of the entire session... m_iImageCount += 1; // Save the image to disk, if we're doing that... /* if (!string.IsNullOrEmpty(m_formsetup.GetImageFolder())) { // Create the directory, if needed... if (!Directory.Exists(m_formsetup.GetImageFolder())) { try { Directory.CreateDirectory(m_formsetup.GetImageFolder()); } catch (Exception exception) { TWAINWorkingGroup.Log.Error("CreateDirectory failed - " + exception.Message); } } // Write it out... string szFilename = Path.Combine(m_formsetup.GetImageFolder(), "img" + string.Format("{0:D6}", m_iImageCount)); TWAIN.WriteImageFile(szFilename, m_intptrImage, m_iImageBytes, out szFilename); } */ // Turn the image into a byte array, and free the original memory... byte[] abImage = new byte[m_iImageBytes]; Marshal.Copy(m_intptrImage, abImage, 0, m_iImageBytes); Marshal.FreeHGlobal(m_intptrImage); m_intptrImage = IntPtr.Zero; m_iImageBytes = 0; // Turn the byte array into a stream... MemoryStream memorystream = new MemoryStream(abImage); Bitmap bitmap = (Bitmap)Image.FromStream(memorystream); // Display the image... // Display the image... switch (m_iCurrentPictureBox) { default: case 0: LoadImage(ref m_pictureboxImage1, ref m_graphics1, ref m_bitmapGraphic1, bitmap); break; case 1: LoadImage(ref m_pictureboxImage2, ref m_graphics2, ref m_bitmapGraphic2, bitmap); break; case 2: LoadImage(ref m_pictureboxImage3, ref m_graphics3, ref m_bitmapGraphic3, bitmap); break; case 3: LoadImage(ref m_pictureboxImage4, ref m_graphics4, ref m_bitmapGraphic4, bitmap); break; case 4: LoadImage(ref m_pictureboxImage5, ref m_graphics5, ref m_bitmapGraphic5, bitmap); break; case 5: LoadImage(ref m_pictureboxImage6, ref m_graphics6, ref m_bitmapGraphic6, bitmap); break; case 6: LoadImage(ref m_pictureboxImage7, ref m_graphics7, ref m_bitmapGraphic7, bitmap); break; case 7: LoadImage(ref m_pictureboxImage8, ref m_graphics8, ref m_bitmapGraphic8, bitmap); break; } // Next picture box... if (++m_iCurrentPictureBox >= 8) { m_iCurrentPictureBox = 0; } // Cleanup... bitmap.Dispose(); memorystream = null; // disposed by the bitmap abImage = null; // End the transfer... szTwmemref = "0,0"; szStatus = ""; sts = Send("DG_CONTROL", "DAT_PENDINGXFERS", "MSG_ENDXFER", ref szTwmemref, ref szStatus); TWAIN.CsvToPendingXfers(ref twpendingxfers, szTwmemref); szStatus = (szStatus == "") ? sts.ToString() : (sts.ToString() + " - " + szStatus); WriteTriplet("DG_CONTROL", "DAT_PENDINGXFERS", "MSG_ENDXFER", szStatus + ((szTwmemref == "") ? "" : (Environment.NewLine + szTwmemref))); // Looks like we're done! if (twpendingxfers.Count == 0) { m_blDisableDsSent = true; Rollback(TWAIN.STATE.S4); return; } } } #endregion /////////////////////////////////////////////////////////////////////////////// // Private Functions, miscellaneous functions... /////////////////////////////////////////////////////////////////////////////// #region Private Functions... /// /// Cleanup, pulled from the designer... /// /// true if we need to clean up managed resources [SuppressMessage("Microsoft.Security", "CA2123:OverrideLinkDemandsShouldBeIdenticalToBase")] [SecurityPermissionAttribute(SecurityAction.LinkDemand, Flags = SecurityPermissionFlag.UnmanagedCode)] protected override void Dispose(bool a_blDisposing) { // Free managed resources... if (a_blDisposing) { // Clean our components... if (components != null) { components.Dispose(); } // Cleanup... if (m_twain != null) { m_twain.Dispose(); m_twain = null; } if (m_bitmapGraphic1 != null) { m_bitmapGraphic1.Dispose(); m_bitmapGraphic1 = null; } if (m_bitmapGraphic2 != null) { m_bitmapGraphic2.Dispose(); m_bitmapGraphic2 = null; } if (m_bitmapGraphic3 != null) { m_bitmapGraphic3.Dispose(); m_bitmapGraphic3 = null; } if (m_bitmapGraphic4 != null) { m_bitmapGraphic4.Dispose(); m_bitmapGraphic4 = null; } if (m_bitmapGraphic5 != null) { m_bitmapGraphic5.Dispose(); m_bitmapGraphic5 = null; } if (m_bitmapGraphic6 != null) { m_bitmapGraphic6.Dispose(); m_bitmapGraphic6 = null; } if (m_bitmapGraphic7 != null) { m_bitmapGraphic7.Dispose(); m_bitmapGraphic7 = null; } if (m_bitmapGraphic8 != null) { m_bitmapGraphic8.Dispose(); m_bitmapGraphic8 = null; } if (m_brushBackground != null) { m_brushBackground.Dispose(); m_brushBackground = null; } } // Do the base... base.Dispose(a_blDisposing); } /// /// Make sure we clean up on a surprise close... /// /// Originator /// Arguments private void FormMain_FormClosing(object sender, FormClosingEventArgs e) { SetMessageFilter(false); m_blClosing = true; if (m_twain != null) { Rollback(TWAIN.STATE.S1); } CleanImage(); TWAINWorkingGroup.Log.Close(); } /// /// Copy data from a richtextbox... /// /// Originator /// Arguments private void richtextboxcapability_Copy(object sender, EventArgs e) { Clipboard.SetData(DataFormats.Text, m_richtextboxCapability.SelectedText); } private void richtextboxoutput_Copy(object sender, EventArgs e) { Clipboard.SetData(DataFormats.Text, m_richtextboxOutput.SelectedText); } /// /// Paste data to a richtextbox... /// /// Originator /// Arguments private void richtextboxcapability_Paste(object sender, EventArgs e) { if (Clipboard.ContainsText(TextDataFormat.Text)) { m_richtextboxCapability.SelectedText = Clipboard.GetData(DataFormats.Text).ToString(); } } private void richtextboxoutput_Paste(object sender, EventArgs e) { if (Clipboard.ContainsText(TextDataFormat.Text)) { m_richtextboxOutput.SelectedText = Clipboard.GetData(DataFormats.Text).ToString(); } } /// /// Initialize the picture boxes and the graphics to support them, we're /// doing this to maximize performance during scanner... /// private void InitImage() { // Make sure our picture boxes don't do much work... m_pictureboxImage1.SizeMode = PictureBoxSizeMode.Normal; m_pictureboxImage2.SizeMode = PictureBoxSizeMode.Normal; m_pictureboxImage3.SizeMode = PictureBoxSizeMode.Normal; m_pictureboxImage4.SizeMode = PictureBoxSizeMode.Normal; m_pictureboxImage5.SizeMode = PictureBoxSizeMode.Normal; m_pictureboxImage6.SizeMode = PictureBoxSizeMode.Normal; m_pictureboxImage7.SizeMode = PictureBoxSizeMode.Normal; m_pictureboxImage8.SizeMode = PictureBoxSizeMode.Normal; m_bitmapGraphic1 = new Bitmap(m_pictureboxImage1.Width, m_pictureboxImage1.Height, PixelFormat.Format32bppPArgb); m_graphics1 = Graphics.FromImage(m_bitmapGraphic1); m_graphics1.CompositingMode = CompositingMode.SourceCopy; m_graphics1.CompositingQuality = CompositingQuality.HighSpeed; m_graphics1.InterpolationMode = InterpolationMode.Low; m_graphics1.PixelOffsetMode = PixelOffsetMode.HighSpeed; m_graphics1.SmoothingMode = SmoothingMode.HighSpeed; m_bitmapGraphic2 = new Bitmap(m_pictureboxImage2.Width, m_pictureboxImage2.Height, PixelFormat.Format32bppPArgb); m_graphics2 = Graphics.FromImage(m_bitmapGraphic2); m_graphics2.CompositingMode = CompositingMode.SourceCopy; m_graphics2.CompositingQuality = CompositingQuality.HighSpeed; m_graphics2.InterpolationMode = InterpolationMode.Low; m_graphics2.PixelOffsetMode = PixelOffsetMode.HighSpeed; m_graphics2.SmoothingMode = SmoothingMode.HighSpeed; m_bitmapGraphic3 = new Bitmap(m_pictureboxImage3.Width, m_pictureboxImage3.Height, PixelFormat.Format32bppPArgb); m_graphics3 = Graphics.FromImage(m_bitmapGraphic3); m_graphics3.CompositingMode = CompositingMode.SourceCopy; m_graphics3.CompositingQuality = CompositingQuality.HighSpeed; m_graphics3.InterpolationMode = InterpolationMode.Low; m_graphics3.PixelOffsetMode = PixelOffsetMode.HighSpeed; m_graphics3.SmoothingMode = SmoothingMode.HighSpeed; m_bitmapGraphic4 = new Bitmap(m_pictureboxImage4.Width, m_pictureboxImage4.Height, PixelFormat.Format32bppPArgb); m_graphics4 = Graphics.FromImage(m_bitmapGraphic4); m_graphics4.CompositingMode = CompositingMode.SourceCopy; m_graphics4.CompositingQuality = CompositingQuality.HighSpeed; m_graphics4.InterpolationMode = InterpolationMode.Low; m_graphics4.PixelOffsetMode = PixelOffsetMode.HighSpeed; m_graphics4.SmoothingMode = SmoothingMode.HighSpeed; m_bitmapGraphic5 = new Bitmap(m_pictureboxImage5.Width, m_pictureboxImage5.Height, PixelFormat.Format32bppPArgb); m_graphics5 = Graphics.FromImage(m_bitmapGraphic5); m_graphics5.CompositingMode = CompositingMode.SourceCopy; m_graphics5.CompositingQuality = CompositingQuality.HighSpeed; m_graphics5.InterpolationMode = InterpolationMode.Low; m_graphics5.PixelOffsetMode = PixelOffsetMode.HighSpeed; m_graphics5.SmoothingMode = SmoothingMode.HighSpeed; m_bitmapGraphic6 = new Bitmap(m_pictureboxImage6.Width, m_pictureboxImage6.Height, PixelFormat.Format32bppPArgb); m_graphics6 = Graphics.FromImage(m_bitmapGraphic6); m_graphics6.CompositingMode = CompositingMode.SourceCopy; m_graphics6.CompositingQuality = CompositingQuality.HighSpeed; m_graphics6.InterpolationMode = InterpolationMode.Low; m_graphics6.PixelOffsetMode = PixelOffsetMode.HighSpeed; m_graphics6.SmoothingMode = SmoothingMode.HighSpeed; m_bitmapGraphic7 = new Bitmap(m_pictureboxImage7.Width, m_pictureboxImage7.Height, PixelFormat.Format32bppPArgb); m_graphics7 = Graphics.FromImage(m_bitmapGraphic7); m_graphics7.CompositingMode = CompositingMode.SourceCopy; m_graphics7.CompositingQuality = CompositingQuality.HighSpeed; m_graphics7.InterpolationMode = InterpolationMode.Low; m_graphics7.PixelOffsetMode = PixelOffsetMode.HighSpeed; m_graphics7.SmoothingMode = SmoothingMode.HighSpeed; m_bitmapGraphic8 = new Bitmap(m_pictureboxImage8.Width, m_pictureboxImage8.Height, PixelFormat.Format32bppPArgb); m_graphics8 = Graphics.FromImage(m_bitmapGraphic8); m_graphics8.CompositingMode = CompositingMode.SourceCopy; m_graphics8.CompositingQuality = CompositingQuality.HighSpeed; m_graphics8.InterpolationMode = InterpolationMode.Low; m_graphics8.PixelOffsetMode = PixelOffsetMode.HighSpeed; m_graphics8.SmoothingMode = SmoothingMode.HighSpeed; m_brushBackground = new SolidBrush(Color.White); m_rectangleBackground = new Rectangle(0, 0, m_bitmapGraphic1.Width, m_bitmapGraphic1.Height); } /// /// Free resources... /// private void CleanImage() { // This is weird, but it works, make sure we don't have any // garbage laying around before we cleanup and leave. This // avoids nasty "Invalid window device" messages on Mac... System.GC.Collect(); System.GC.WaitForPendingFinalizers(); if (!m_pictureboxImage1.IsDisposed) { m_pictureboxImage1.Dispose(); } if (m_graphics1 != null) { m_graphics1.Dispose(); m_graphics1 = null; } if (m_bitmapGraphic1 != null) { m_bitmapGraphic1.Dispose(); m_bitmapGraphic1 = null; } if (!m_pictureboxImage2.IsDisposed) { m_pictureboxImage2.Dispose(); } if (m_graphics2 != null) { m_graphics2.Dispose(); m_graphics2 = null; } if (m_bitmapGraphic2 != null) { m_bitmapGraphic2.Dispose(); m_bitmapGraphic2 = null; } if (!m_pictureboxImage3.IsDisposed) { m_pictureboxImage3.Dispose(); } if (m_graphics3 != null) { m_graphics3.Dispose(); m_graphics3 = null; } if (m_bitmapGraphic3 != null) { m_bitmapGraphic3.Dispose(); m_bitmapGraphic3 = null; } if (!m_pictureboxImage4.IsDisposed) { m_pictureboxImage4.Dispose(); } if (m_graphics4 != null) { m_graphics4.Dispose(); m_graphics4 = null; } if (m_bitmapGraphic4 != null) { m_bitmapGraphic4.Dispose(); m_bitmapGraphic4 = null; } if (!m_pictureboxImage5.IsDisposed) { m_pictureboxImage5.Dispose(); } if (m_graphics5 != null) { m_graphics5.Dispose(); m_graphics5 = null; } if (m_bitmapGraphic5 != null) { m_bitmapGraphic5.Dispose(); m_bitmapGraphic5 = null; } if (!m_pictureboxImage6.IsDisposed) { m_pictureboxImage6.Dispose(); } if (m_graphics6 != null) { m_graphics6.Dispose(); m_graphics6 = null; } if (m_bitmapGraphic6 != null) { m_bitmapGraphic6.Dispose(); m_bitmapGraphic6 = null; } if (!m_pictureboxImage7.IsDisposed) { m_pictureboxImage7.Dispose(); } if (m_graphics7 != null) { m_graphics7.Dispose(); m_graphics7 = null; } if (m_bitmapGraphic7 != null) { m_bitmapGraphic7.Dispose(); m_bitmapGraphic7 = null; } if (!m_pictureboxImage8.IsDisposed) { m_pictureboxImage8.Dispose(); } if (m_graphics8 != null) { m_graphics8.Dispose(); m_graphics8 = null; } if (m_bitmapGraphic8 != null) { m_bitmapGraphic8.Dispose(); m_bitmapGraphic8 = null; } } /// /// Load an image into a picture box, maintain its aspect ratio... /// /// The picture box we're drawing to /// The graphics backing the picture box /// Characteristics of the target /// The source image private void LoadImage(ref PictureBox a_picturebox, ref Graphics a_graphics, ref Bitmap a_bitmapGraphic, Bitmap a_bitmap) { // We want to maintain the aspect ratio... double fRatioWidth = (double)a_bitmapGraphic.Size.Width / (double)a_bitmap.Width; double fRatioHeight = (double)a_bitmapGraphic.Size.Height / (double)a_bitmap.Height; double fRatio = (fRatioWidth < fRatioHeight) ? fRatioWidth : fRatioHeight; int iWidth = (int)(a_bitmap.Width * fRatio); int iHeight = (int)(a_bitmap.Height * fRatio); // Display the image... a_graphics.FillRectangle(m_brushBackground, m_rectangleBackground); a_graphics.DrawImage(a_bitmap, new Rectangle(((int)a_bitmapGraphic.Width - iWidth)/2, ((int)a_bitmapGraphic.Height - iHeight)/2, iWidth, iHeight)); a_picturebox.Image = a_bitmapGraphic; a_picturebox.Update(); } /// /// Turn message filtering on or off... /// /// True to turn it on private void SetMessageFilter(bool a_blAdd) { if (a_blAdd) { Application.AddMessageFilter(this); } else { Application.RemoveMessageFilter(this); } } /// /// Debugging output that we can monitor... /// /// Text to display to the user private void WriteOutput(string a_szOutput) { // We're leaving... if (m_blClosing) { return; } // Let us be called from any thread. We don't care if a_szOutput changes // on the fly (it's incredibly unlikely that it will), so we're not going // to wait for the thread to finish... if (this.InvokeRequired) { BeginInvoke(new MethodInvoker(delegate() { WriteOutput(a_szOutput); })); return; } // Display the text... m_richtextboxOutput.AppendText(a_szOutput); m_richtextboxOutput.SelectionStart = m_richtextboxOutput.Text.Length; m_richtextboxOutput.Refresh(); } /// /// Write a triplet message... /// /// Data group /// Data argument type /// Operation /// Text private void WriteTriplet(string a_szDg, string a_szDat, string a_szMsg, string a_szOutput) { string szDg; string szDat; string szMsg; // Let us be called from any thread. We don't care if a_szOutput changes // on the fly (it's incredibly unlikely that it will), so we're not going // to wait for the thread to finish... if (this.InvokeRequired) { BeginInvoke(new MethodInvoker(delegate() { WriteTriplet(a_szDg, a_szDat, a_szMsg, a_szOutput); })); return; } // Build the triplet... szDg = a_szDg.StartsWith("DG_") ? a_szDg : "DG_" + a_szDg; szDat = a_szDat.StartsWith("DAT_") ? a_szDat : "DAT_" + a_szDat; szMsg = a_szMsg.StartsWith("MSG_") ? a_szMsg : "MSG_" + a_szMsg; // Display the triplet... m_richtextboxOutput.SelectionStart = m_richtextboxOutput.Text.Length; m_richtextboxOutput.SelectionColor = Color.Blue; m_richtextboxOutput.AppendText(Environment.NewLine + a_szDg + "/" + a_szDat + "/" + a_szMsg + ": "); m_richtextboxOutput.SelectionStart = m_richtextboxOutput.Text.Length; // Display the text... m_richtextboxOutput.SelectionStart = m_richtextboxOutput.Text.Length; m_richtextboxOutput.SelectionColor = Color.Black; m_richtextboxOutput.AppendText(a_szOutput + Environment.NewLine); m_richtextboxOutput.SelectionStart = m_richtextboxOutput.Text.Length; m_richtextboxOutput.Refresh(); } #endregion /////////////////////////////////////////////////////////////////////////////// // Private Send Triplets, the Send button is used to issue TWAIN triplets // to the Data Source Manager, this section covers all the supported // combinations... /////////////////////////////////////////////////////////////////////////////// #region Private Send Triplets... /// /// Automatically change our dropdown values to reduce user frustration, /// we do this to save a step when it's pretty obvious what the user /// will typically want to do next. For instance, if they've just opened /// the DSM they probably want to start enumerating TWAIN drivers... /// /// Data group /// Data Argument type /// Operation private void AutoDropdown(string a_szDg, string a_szDat, string a_szMsg) { // We're initializing... if ((a_szDg == "") && (a_szDat == "") && (a_szMsg == "")) { m_comboboxDG.SelectedItem = "DG_CONTROL"; m_comboboxDAT.SelectedItem = "DAT_PARENT"; m_comboboxMSG.SelectedItem = "MSG_OPENDSM"; m_richtextboxCapability.Text = "TWAIN Working Group," + "TWAIN Sharp," + "TWAIN Sharp Test App," + "2," + "4," + "0x20000003," + "USA," + "testing...," + "ENGLISH_USA"; } // After OPENDSM we have a choice, based on the DSM that was used... else if ((a_szDg == "DG_CONTROL") && (a_szDat == "DAT_PARENT") && (a_szMsg == "MSG_OPENDSM")) { string[] aszAppIdentity = CSV.Parse(m_twain.GetAppIdentity()); int iSupportedGroups; int.TryParse(aszAppIdentity[8], NumberStyles.HexNumber, CultureInfo.InvariantCulture, out iSupportedGroups); if ((iSupportedGroups & ((int)TWAIN.DG.DSM2 | (int)TWAIN.DG.APP2)) == ((int)TWAIN.DG.DSM2 | (int)TWAIN.DG.APP2)) { m_comboboxDG.SelectedItem = "DG_CONTROL"; m_comboboxDAT.SelectedItem = "DAT_ENTRYPOINT"; m_comboboxMSG.SelectedItem = "MSG_GET"; } else { m_comboboxDG.SelectedItem = "DG_CONTROL"; m_comboboxDAT.SelectedItem = "DAT_IDENTITY"; m_comboboxMSG.SelectedItem = "MSG_GETFIRST"; } m_richtextboxCapability.Text = ""; } // After an ENTRYPOINT, switch to GETFIRST... else if ((a_szDg == "DG_CONTROL") && (a_szDat == "DAT_ENTRYPOINT") && (a_szMsg == "MSG_GET")) { m_comboboxDG.SelectedItem = "DG_CONTROL"; m_comboboxDAT.SelectedItem = "DAT_IDENTITY"; m_comboboxMSG.SelectedItem = "MSG_GETFIRST"; m_richtextboxCapability.Text = ""; } // When we CLOSEDSM, go back to OPENDSM... else if ((a_szDg == "DG_CONTROL") && (a_szDat == "DAT_PARENT") && (a_szMsg == "MSG_CLOSEDSM")) { m_comboboxDG.SelectedItem = "DG_CONTROL"; m_comboboxDAT.SelectedItem = "DAT_PARENT"; m_comboboxMSG.SelectedItem = "MSG_OPENDSM"; m_richtextboxCapability.Text = "TWAIN Working Group," + "TWAIN Sharp," + "TWAIN Sharp Test App," + "2," + "4," + "0x20000003," + "USA," + "testing...," + "ENGLISH_USA"; } // After a GETFIRST, switch to GETNEXT... else if ((a_szDg == "DG_CONTROL") && (a_szDat == "DAT_IDENTITY") && (a_szMsg == "MSG_GETFIRST")) { m_comboboxDG.SelectedItem = "DG_CONTROL"; m_comboboxDAT.SelectedItem = "DAT_IDENTITY"; m_comboboxMSG.SelectedItem = "MSG_GETNEXT"; } // After an OPENDS, changing to CAPABILITY seems most useful... else if ((a_szDg == "DG_CONTROL") && (a_szDat == "DAT_IDENTITY") && (a_szMsg == "MSG_OPENDS")) { m_comboboxDG.SelectedItem = "DG_CONTROL"; m_comboboxDAT.SelectedItem = "DAT_CAPABILITY"; m_comboboxMSG.SelectedItem = "MSG_GETCURRENT"; m_richtextboxCapability.Text = ""; } // After a CLOSEDS, switch to CLOSEDSM... else if ((a_szDg == "DG_CONTROL") && (a_szDat == "DAT_IDENTITY") && (a_szMsg == "MSG_CLOSEDS")) { m_comboboxDG.SelectedItem = "DG_CONTROL"; m_comboboxDAT.SelectedItem = "DAT_PARENT"; m_comboboxMSG.SelectedItem = "MSG_CLOSEDSM"; } // After a GETFIRSTFILE, switch to GETNEXTFILE... else if ((a_szDg == "DG_CONTROL") && (a_szDat == "DAT_FILESYSTEM") && (a_szMsg == "MSG_GETFIRSTFILE")) { m_comboboxDG.SelectedItem = "DG_CONTROL"; m_comboboxDAT.SelectedItem = "DAT_FILESYSTEM"; m_comboboxMSG.SelectedItem = "MSG_GETNEXTFILE"; } } /// /// Send the requested command... /// /// Originator /// Arguments private void SendDat(object sender, EventArgs e) { string szDg; string szDat; string szMsg; // The Data Group selected by the user, this can be a drop down item or a // hex value (with or without the leading 0x)... if (m_comboboxDG.SelectedItem != null) { szDg = (string)m_comboboxDG.SelectedItem; } else { szDg = m_comboboxDG.Text; } // The Data Argument Type selected by the user, this can be a drop down // item or a hex value (with or without the leading 0x)... if (m_comboboxDAT.SelectedItem != null) { szDat = (string)m_comboboxDAT.SelectedItem; } else { szDat = m_comboboxDAT.Text; } // The Message selected by the user, this can be a drop down item or a // hex value (with or without the leading 0x)... if (m_comboboxMSG.SelectedItem != null) { szMsg = (string)m_comboboxMSG.SelectedItem; } else { szMsg = m_comboboxMSG.Text; } // Handle creation and destruction of our image capture object... if ( (szDg == "DG_CONTROL") && (szDat == "DAT_PARENT") && ((szMsg == "MSG_OPENDSM") || (szMsg == "MSG_CLOSEDSM"))) { ManageTWAIN(szDg, szDat, szMsg); return; } // Validate... if (m_twain == null) { WriteTriplet(szDg, szDat, szMsg, "(DSM is not open)"); return; } // Look for an @-command... /* if (m_twaincstoolkit.AtCommand(m_richtextboxCapability.Text)) { return; } */ // Everything else can go to TWAIN... string szResult; string szTwmemref; TWAIN.STS sts; // Grab the data from the cap box... szTwmemref = m_richtextboxCapability.Text; // Issue the command to TWAIN... szResult = ""; sts = Send(szDg, szDat, szMsg, ref szTwmemref, ref szResult); // If the command succeeded, then update the cap box with the result... m_richtextboxCapability.Text = szTwmemref; // Tweak the result... if (szResult == "") { szResult = sts.ToString(); } else { szResult = sts.ToString() + " - " + szResult; } // And write what happened to the output box... if (szTwmemref == "") { WriteTriplet(szDg, szDat, szMsg, szResult); } else { WriteTriplet(szDg, szDat, szMsg, szResult + Environment.NewLine + szTwmemref); } // Convenience settings, we do these to make it less painful // to work with the dropdown interface. I've got them all // here, even though some are currently being handled inside // of other functions, like SendDatParent... if (sts == TWAIN.STS.SUCCESS) { AutoDropdown(szDg, szDat, szMsg); } } /// /// Send a command to the currently loaded DSM... /// /// tokenized command and anything needed /// true to quit private TWAIN.STS Send(string a_szDg, string a_szDat, string a_szMsg, ref string a_szTwmemref, ref string a_szResult) { int iDg; int iDat; int iMsg; TWAIN.STS sts; TWAIN.DG dg = TWAIN.DG.MASK; TWAIN.DAT dat = TWAIN.DAT.NULL; TWAIN.MSG msg = TWAIN.MSG.NULL; // Init stuff... iDg = 0; iDat = 0; iMsg = 0; sts = TWAIN.STS.BADPROTOCOL; a_szResult = ""; // Validate at the top level... if (m_twain == null) { WriteOutput("***ERROR*** - dsmload wasn't run, so we is having no braims"); return (TWAIN.STS.SEQERROR); } // Look for DG... if (!a_szDg.ToLowerInvariant().StartsWith("dg_")) { WriteOutput("Unrecognized dg - <" + a_szDg + ">"); return (TWAIN.STS.BADPROTOCOL); } else { // Look for hex number (take anything)... if (a_szDg.ToLowerInvariant().StartsWith("dg_0x")) { if (!int.TryParse(a_szDg.ToLowerInvariant().Substring(3), NumberStyles.HexNumber, CultureInfo.InvariantCulture, out iDg)) { WriteOutput("Badly constructed dg - <" + a_szDg + ">"); return (TWAIN.STS.BADPROTOCOL); } } else { if (!Enum.TryParse(a_szDg.ToUpperInvariant().Substring(3), out dg)) { WriteOutput("Unrecognized dg - <" + a_szDg + ">"); return (TWAIN.STS.BADPROTOCOL); } iDg = (int)dg; } } // Look for DAT... if (!a_szDat.ToLowerInvariant().StartsWith("dat_")) { WriteOutput("Unrecognized dat - <" + a_szDat + ">"); return (TWAIN.STS.BADPROTOCOL); } else { // Look for hex number (take anything)... if (a_szDat.ToLowerInvariant().StartsWith("dat_0x")) { if (!int.TryParse(a_szDat.ToLowerInvariant().Substring(4), NumberStyles.HexNumber, CultureInfo.InvariantCulture, out iDat)) { WriteOutput("Badly constructed dat - <" + a_szDat + ">"); return (TWAIN.STS.BADPROTOCOL); } } else { if (!Enum.TryParse(a_szDat.ToUpperInvariant().Substring(4), out dat)) { WriteOutput("Unrecognized dat - <" + a_szDat + ">"); return (TWAIN.STS.BADPROTOCOL); } iDat = (int)dat; } } // Look for MSG... if (!a_szMsg.ToLowerInvariant().StartsWith("msg_")) { WriteOutput("Unrecognized msg - <" + a_szMsg + ">"); return (TWAIN.STS.BADPROTOCOL); } else { // Look for hex number (take anything)... if (a_szMsg.ToLowerInvariant().StartsWith("msg_0x")) { if (!int.TryParse(a_szMsg.ToLowerInvariant().Substring(4), NumberStyles.HexNumber, CultureInfo.InvariantCulture, out iMsg)) { WriteOutput("Badly constructed dat - <" + a_szMsg + ">"); return (TWAIN.STS.BADPROTOCOL); } } else { if (!Enum.TryParse(a_szMsg.ToUpperInvariant().Substring(4), out msg)) { WriteOutput("Unrecognized msg - <" + a_szMsg + ">"); return (TWAIN.STS.BADPROTOCOL); } iMsg = (int)msg; } } // Send the command... switch (iDat) { // Ruh-roh, since we can't marshal it, we have to return an error, // it would be nice to have a solution for this, but that will need // a dynamic marshalling system... default: sts = TWAIN.STS.BADPROTOCOL; break; // DAT_AUDIOFILEXFER... case (int)TWAIN.DAT.AUDIOFILEXFER: { sts = m_twain.DatAudiofilexfer((TWAIN.DG)iDg, (TWAIN.MSG)iMsg); a_szTwmemref = ""; } break; // DAT_AUDIOINFO.. case (int)TWAIN.DAT.AUDIOINFO: { TWAIN.TW_AUDIOINFO twaudioinfo = default(TWAIN.TW_AUDIOINFO); sts = m_twain.DatAudioinfo((TWAIN.DG)iDg, (TWAIN.MSG)iMsg, ref twaudioinfo); a_szTwmemref = TWAIN.AudioinfoToCsv(twaudioinfo); } break; // DAT_AUDIONATIVEXFER.. case (int)TWAIN.DAT.AUDIONATIVEXFER: { IntPtr intptr = IntPtr.Zero; sts = m_twain.DatAudionativexfer((TWAIN.DG)iDg, (TWAIN.MSG)iMsg, ref intptr); a_szTwmemref = intptr.ToString(); } break; // DAT_CALLBACK... case (int)TWAIN.DAT.CALLBACK: { TWAIN.TW_CALLBACK twcallback = default(TWAIN.TW_CALLBACK); TWAIN.CsvToCallback(ref twcallback, a_szTwmemref); sts = m_twain.DatCallback((TWAIN.DG)iDg, (TWAIN.MSG)iMsg, ref twcallback); a_szTwmemref = TWAIN.CallbackToCsv(twcallback); } break; // DAT_CALLBACK2... case (int)TWAIN.DAT.CALLBACK2: { TWAIN.TW_CALLBACK2 twcallback2 = default(TWAIN.TW_CALLBACK2); TWAIN.CsvToCallback2(ref twcallback2, a_szTwmemref); sts = m_twain.DatCallback2((TWAIN.DG)iDg, (TWAIN.MSG)iMsg, ref twcallback2); a_szTwmemref = TWAIN.Callback2ToCsv(twcallback2); } break; // DAT_CAPABILITY... case (int)TWAIN.DAT.CAPABILITY: { // Skip symbols for msg_querysupport, otherwise 0 gets turned into false, also // if the command fails the return value is whatever was sent into us, which // matches the experience one should get with C/C++... string szStatus = ""; TWAIN.TW_CAPABILITY twcapability = default(TWAIN.TW_CAPABILITY); m_twain.CsvToCapability(ref twcapability, ref szStatus, a_szTwmemref); sts = m_twain.DatCapability((TWAIN.DG)iDg, (TWAIN.MSG)iMsg, ref twcapability); if ((sts == TWAIN.STS.SUCCESS) || (sts == TWAIN.STS.CHECKSTATUS)) { // Convert the data to CSV... a_szTwmemref = m_twain.CapabilityToCsv(twcapability, ((TWAIN.MSG)iMsg != TWAIN.MSG.QUERYSUPPORT)); // Free the handle if the driver created it... switch ((TWAIN.MSG)iMsg) { default: break; case TWAIN.MSG.GET: case TWAIN.MSG.GETCURRENT: case TWAIN.MSG.GETDEFAULT: case TWAIN.MSG.QUERYSUPPORT: case TWAIN.MSG.RESET: m_twain.DsmMemFree(ref twcapability.hContainer); break; } } } break; // DAT_CIECOLOR.. case (int)TWAIN.DAT.CIECOLOR: { //TWAIN.TW_CIECOLOR twciecolor = default(TWAIN.TW_CIECOLOR); //sts = m_twain.DatCiecolor((TWAIN.DG)iDg, (TWAIN.MSG)iMsg, ref twciecolor); //a_szTwmemref = m_twain.CiecolorToCsv(twciecolor); } break; // DAT_CUSTOMDSDATA... case (int)TWAIN.DAT.CUSTOMDSDATA: { TWAIN.TW_CUSTOMDSDATA twcustomdsdata = default(TWAIN.TW_CUSTOMDSDATA); m_twain.CsvToCustomdsdata(ref twcustomdsdata, a_szTwmemref); sts = m_twain.DatCustomdsdata((TWAIN.DG)iDg, (TWAIN.MSG)iMsg, ref twcustomdsdata); a_szTwmemref = m_twain.CustomdsdataToCsv(twcustomdsdata); } break; // DAT_DEVICEEVENT... case (int)TWAIN.DAT.DEVICEEVENT: { TWAIN.TW_DEVICEEVENT twdeviceevent = default(TWAIN.TW_DEVICEEVENT); sts = m_twain.DatDeviceevent((TWAIN.DG)iDg, (TWAIN.MSG)iMsg, ref twdeviceevent); a_szTwmemref = TWAIN.DeviceeventToCsv(twdeviceevent); } break; // DAT_ENTRYPOINT... case (int)TWAIN.DAT.ENTRYPOINT: { TWAIN.TW_ENTRYPOINT twentrypoint = default(TWAIN.TW_ENTRYPOINT); twentrypoint.Size = (uint)Marshal.SizeOf(twentrypoint); sts = m_twain.DatEntrypoint((TWAIN.DG)iDg, (TWAIN.MSG)iMsg, ref twentrypoint); a_szTwmemref = TWAIN.EntrypointToCsv(twentrypoint); } break; // DAT_EVENT... case (int)TWAIN.DAT.EVENT: { TWAIN.TW_EVENT twevent = default(TWAIN.TW_EVENT); sts = m_twain.DatEvent((TWAIN.DG)iDg, (TWAIN.MSG)iMsg, ref twevent); a_szTwmemref = TWAIN.EventToCsv(twevent); } break; // DAT_EXTIMAGEINFO... case (int)TWAIN.DAT.EXTIMAGEINFO: { TWAIN.TW_EXTIMAGEINFO twextimageinfo = default(TWAIN.TW_EXTIMAGEINFO); TWAIN.CsvToExtimageinfo(ref twextimageinfo, a_szTwmemref); sts = m_twain.DatExtimageinfo((TWAIN.DG)iDg, (TWAIN.MSG)iMsg, ref twextimageinfo); a_szTwmemref = TWAIN.ExtimageinfoToCsv(twextimageinfo); } break; // DAT_FILESYSTEM... case (int)TWAIN.DAT.FILESYSTEM: { TWAIN.TW_FILESYSTEM twfilesystem = default(TWAIN.TW_FILESYSTEM); TWAIN.CsvToFilesystem(ref twfilesystem, a_szTwmemref); sts = m_twain.DatFilesystem((TWAIN.DG)iDg, (TWAIN.MSG)iMsg, ref twfilesystem); a_szTwmemref = TWAIN.FilesystemToCsv(twfilesystem); } break; // DAT_FILTER... case (int)TWAIN.DAT.FILTER: { //TWAIN.TW_FILTER twfilter = default(TWAIN.TW_FILTER); //m_twain.CsvToFilter(ref twfilter, a_szTwmemref); //sts = m_twain.DatFilter((TWAIN.DG)iDg, (TWAIN.MSG)iMsg, ref twfilter); //a_szTwmemref = m_twain.FilterToCsv(twfilter); } break; // DAT_GRAYRESPONSE... case (int)TWAIN.DAT.GRAYRESPONSE: { //TWAIN.TW_GRAYRESPONSE twgrayresponse = default(TWAIN.TW_GRAYRESPONSE); //m_twain.CsvToGrayresponse(ref twgrayresponse, a_szTwmemref); //sts = m_twain.DatGrayresponse((TWAIN.DG)iDg, (TWAIN.MSG)iMsg, ref twgrayresponse); //a_szTwmemref = m_twain.GrayresponseToCsv(twgrayresponse); } break; // DAT_ICCPROFILE... case (int)TWAIN.DAT.ICCPROFILE: { TWAIN.TW_MEMORY twmemory = default(TWAIN.TW_MEMORY); sts = m_twain.DatIccprofile((TWAIN.DG)iDg, (TWAIN.MSG)iMsg, ref twmemory); a_szTwmemref = TWAIN.IccprofileToCsv(twmemory); } break; // DAT_IDENTITY... case (int)TWAIN.DAT.IDENTITY: { TWAIN.TW_IDENTITY twidentity = default(TWAIN.TW_IDENTITY); switch (iMsg) { default: break; case (int)TWAIN.MSG.SET: case (int)TWAIN.MSG.OPENDS: TWAIN.CsvToIdentity(ref twidentity, a_szTwmemref); break; } sts = m_twain.DatIdentity((TWAIN.DG)iDg, (TWAIN.MSG)iMsg, ref twidentity); a_szTwmemref = TWAIN.IdentityToCsv(twidentity); } break; // DAT_IMAGEFILEXFER... case (int)TWAIN.DAT.IMAGEFILEXFER: { sts = m_twain.DatImagefilexfer((TWAIN.DG)iDg, (TWAIN.MSG)iMsg); a_szTwmemref = ""; } break; // DAT_IMAGEINFO... case (int)TWAIN.DAT.IMAGEINFO: { TWAIN.TW_IMAGEINFO twimageinfo = default(TWAIN.TW_IMAGEINFO); TWAIN.CsvToImageinfo(ref twimageinfo, a_szTwmemref); sts = m_twain.DatImageinfo((TWAIN.DG)iDg, (TWAIN.MSG)iMsg, ref twimageinfo); a_szTwmemref = TWAIN.ImageinfoToCsv(twimageinfo); } break; // DAT_IMAGELAYOUT... case (int)TWAIN.DAT.IMAGELAYOUT: { TWAIN.TW_IMAGELAYOUT twimagelayout = default(TWAIN.TW_IMAGELAYOUT); TWAIN.CsvToImagelayout(ref twimagelayout, a_szTwmemref); sts = m_twain.DatImagelayout((TWAIN.DG)iDg, (TWAIN.MSG)iMsg, ref twimagelayout); a_szTwmemref = TWAIN.ImagelayoutToCsv(twimagelayout); } break; // DAT_IMAGEMEMFILEXFER... case (int)TWAIN.DAT.IMAGEMEMFILEXFER: { TWAIN.TW_IMAGEMEMXFER twimagememxfer = default(TWAIN.TW_IMAGEMEMXFER); TWAIN.CsvToImagememxfer(ref twimagememxfer, a_szTwmemref); sts = m_twain.DatImagememfilexfer((TWAIN.DG)iDg, (TWAIN.MSG)iMsg, ref twimagememxfer); a_szTwmemref = TWAIN.ImagememxferToCsv(twimagememxfer); } break; // DAT_IMAGEMEMXFER... case (int)TWAIN.DAT.IMAGEMEMXFER: { TWAIN.TW_IMAGEMEMXFER twimagememxfer = default(TWAIN.TW_IMAGEMEMXFER); TWAIN.CsvToImagememxfer(ref twimagememxfer, a_szTwmemref); sts = m_twain.DatImagememxfer((TWAIN.DG)iDg, (TWAIN.MSG)iMsg, ref twimagememxfer); a_szTwmemref = TWAIN.ImagememxferToCsv(twimagememxfer); } break; // DAT_IMAGENATIVEXFER... case (int)TWAIN.DAT.IMAGENATIVEXFER: { IntPtr intptrBitmapHandle = IntPtr.Zero; sts = m_twain.DatImagenativexferHandle((TWAIN.DG)iDg, (TWAIN.MSG)iMsg, ref intptrBitmapHandle); a_szTwmemref = intptrBitmapHandle.ToString(); } break; // DAT_JPEGCOMPRESSION... case (int)TWAIN.DAT.JPEGCOMPRESSION: { //TWAIN.TW_JPEGCOMPRESSION twjpegcompression = default(TWAIN.TW_JPEGCOMPRESSION); //m_twain.CsvToJpegcompression(ref twjpegcompression, a_szTwmemref); //sts = m_twain.DatJpegcompression((TWAIN.DG)iDg, (TWAIN.MSG)iMsg, ref twjpegcompression); //a_szTwmemref = m_twain.JpegcompressionToCsv(twjpegcompression); } break; // DAT_METRICS... case (int)TWAIN.DAT.METRICS: { TWAIN.TW_METRICS twmetrics = default(TWAIN.TW_METRICS); twmetrics.SizeOf = (uint)Marshal.SizeOf(twmetrics); sts = m_twain.DatMetrics((TWAIN.DG)iDg, (TWAIN.MSG)iMsg, ref twmetrics); a_szTwmemref = TWAIN.MetricsToCsv(twmetrics); } break; // DAT_PALETTE8... case (int)TWAIN.DAT.PALETTE8: { //TWAIN.TW_PALETTE8 twpalette8 = default(TWAIN.TW_PALETTE8); //m_twain.CsvToPalette8(ref twpalette8, a_szTwmemref); //sts = m_twain.DatPalette8((TWAIN.DG)iDg, (TWAIN.MSG)iMsg, ref twpalette8); //a_szTwmemref = m_twain.Palette8ToCsv(twpalette8); } break; // DAT_PARENT... case (int)TWAIN.DAT.PARENT: { sts = m_twain.DatParent((TWAIN.DG)iDg, (TWAIN.MSG)iMsg, ref m_intptrHwnd); a_szTwmemref = ""; } break; // DAT_PASSTHRU... case (int)TWAIN.DAT.PASSTHRU: { TWAIN.TW_PASSTHRU twpassthru = default(TWAIN.TW_PASSTHRU); TWAIN.CsvToPassthru(ref twpassthru, a_szTwmemref); sts = m_twain.DatPassthru((TWAIN.DG)iDg, (TWAIN.MSG)iMsg, ref twpassthru); a_szTwmemref = TWAIN.PassthruToCsv(twpassthru); } break; // DAT_PENDINGXFERS... case (int)TWAIN.DAT.PENDINGXFERS: { TWAIN.TW_PENDINGXFERS twpendingxfers = default(TWAIN.TW_PENDINGXFERS); sts = m_twain.DatPendingxfers((TWAIN.DG)iDg, (TWAIN.MSG)iMsg, ref twpendingxfers); a_szTwmemref = TWAIN.PendingxfersToCsv(twpendingxfers); } break; // DAT_RGBRESPONSE... case (int)TWAIN.DAT.RGBRESPONSE: { //TWAIN.TW_RGBRESPONSE twrgbresponse = default(TWAIN.TW_RGBRESPONSE); //m_twain.CsvToRgbresponse(ref twrgbresponse, a_szTwmemref); //sts = m_twain.DatRgbresponse((TWAIN.DG)iDg, (TWAIN.MSG)iMsg, ref twrgbresponse); //a_szTwmemref = m_twain.RgbresponseToCsv(twrgbresponse); } break; // DAT_SETUPFILEXFER... case (int)TWAIN.DAT.SETUPFILEXFER: { TWAIN.TW_SETUPFILEXFER twsetupfilexfer = default(TWAIN.TW_SETUPFILEXFER); TWAIN.CsvToSetupfilexfer(ref twsetupfilexfer, a_szTwmemref); sts = m_twain.DatSetupfilexfer((TWAIN.DG)iDg, (TWAIN.MSG)iMsg, ref twsetupfilexfer); a_szTwmemref = TWAIN.SetupfilexferToCsv(twsetupfilexfer); } break; // DAT_SETUPMEMXFER... case (int)TWAIN.DAT.SETUPMEMXFER: { TWAIN.TW_SETUPMEMXFER twsetupmemxfer = default(TWAIN.TW_SETUPMEMXFER); sts = m_twain.DatSetupmemxfer((TWAIN.DG)iDg, (TWAIN.MSG)iMsg, ref twsetupmemxfer); a_szTwmemref = TWAIN.SetupmemxferToCsv(twsetupmemxfer); } break; // DAT_STATUS... case (int)TWAIN.DAT.STATUS: { TWAIN.TW_STATUS twstatus = default(TWAIN.TW_STATUS); sts = m_twain.DatStatus((TWAIN.DG)iDg, (TWAIN.MSG)iMsg, ref twstatus); a_szTwmemref = TWAIN.StatusToCsv(twstatus); } break; // DAT_STATUSUTF8... case (int)TWAIN.DAT.STATUSUTF8: { TWAIN.TW_STATUSUTF8 twstatusutf8 = default(TWAIN.TW_STATUSUTF8); sts = m_twain.DatStatusutf8((TWAIN.DG)iDg, (TWAIN.MSG)iMsg, ref twstatusutf8); a_szTwmemref = m_twain.Statusutf8ToCsv(twstatusutf8); } break; // DAT_TWAINDIRECT... case (int)TWAIN.DAT.TWAINDIRECT: { TWAIN.TW_TWAINDIRECT twtwaindirect = default(TWAIN.TW_TWAINDIRECT); TWAIN.CsvToTwaindirect(ref twtwaindirect, a_szTwmemref); sts = m_twain.DatTwaindirect((TWAIN.DG)iDg, (TWAIN.MSG)iMsg, ref twtwaindirect); a_szTwmemref = TWAIN.TwaindirectToCsv(twtwaindirect); } break; // DAT_USERINTERFACE... case (int)TWAIN.DAT.USERINTERFACE: { TWAIN.TW_USERINTERFACE twuserinterface = default(TWAIN.TW_USERINTERFACE); m_twain.CsvToUserinterface(ref twuserinterface, a_szTwmemref); sts = m_twain.DatUserinterface((TWAIN.DG)iDg, (TWAIN.MSG)iMsg, ref twuserinterface); a_szTwmemref = TWAIN.UserinterfaceToCsv(twuserinterface); } break; // DAT_XFERGROUP... case (int)TWAIN.DAT.XFERGROUP: { uint uXferGroup = 0; sts = m_twain.DatXferGroup((TWAIN.DG)iDg, (TWAIN.MSG)iMsg, ref uXferGroup); a_szTwmemref = string.Format("0x{0:X}", uXferGroup); } break; } // All done... return (sts); } /// /// Create and destroy TWAIN, as needed... /// /// Data group /// Data argument type /// Operation private void ManageTWAIN(string a_szDg, string a_szDat, string a_szMsg) { TWAIN.RunInUiThreadDelegate runinuithreaddelegate = RunInUiThread; // Handle MSG_OPENDSM... if (a_szMsg == "MSG_OPENDSM") { // Init stuff... m_blClosing = false; // Validate... if (m_twain == null) { try { string[] aszTwidentity = m_richtextboxCapability.Text.Split(','); if ((aszTwidentity == null) || (aszTwidentity.Length < 9)) { m_twain = new TWAIN ( "TWAIN Working Group", "TWAIN Open Source", "TWAIN CS Test", (ushort)TWAIN.TWON_PROTOCOL.MAJOR, (ushort)TWAIN.TWON_PROTOCOL.MINOR, (uint)(TWAIN.DG.APP2 | TWAIN.DG.CONTROL | TWAIN.DG.IMAGE), TWAIN.TWCY.USA, "TWAIN CS Test", TWAIN.TWLG.ENGLISH_USA, 2, 4, m_checkboxUseTwain32.Checked, m_checkboxUseCallbacks.Checked, DeviceEventCallback, ScanCallbackTrigger, runinuithreaddelegate, this.Handle ); // Prep for TWAIN events... SetMessageFilter(true); } else { TWAIN.TWCY twcy = TWAIN.TWCY.USA; TWAIN.TWLG twlg = TWAIN.TWLG.ENGLISH_USA; Enum.TryParse(aszTwidentity[6], out twcy); Enum.TryParse(aszTwidentity[8], out twlg); m_twain = new TWAIN ( aszTwidentity[0], aszTwidentity[1], aszTwidentity[2], ushort.Parse(aszTwidentity[3]), ushort.Parse(aszTwidentity[4]), (uint)(TWAIN.DG.APP2 | TWAIN.DG.CONTROL | TWAIN.DG.IMAGE), twcy, aszTwidentity[7], twlg, 2, 4, m_checkboxUseTwain32.Checked, m_checkboxUseCallbacks.Checked, DeviceEventCallback, ScanCallbackTrigger, runinuithreaddelegate, this.Handle ); // Prep for TWAIN events... SetMessageFilter(true); } } catch (Exception exception) { TWAINWorkingGroup.Log.Error("exception - " + exception.Message); WriteTriplet(a_szDg, a_szDat, a_szMsg, "(unable to start, clear the data window and try again)"); m_twain = null; return; } } // Open the DSM... string szTwmemref = m_intptrHwnd.ToString(); string szStatus = ""; TWAIN.STS sts = Send("DG_CONTROL", "DAT_PARENT", "MSG_OPENDSM", ref szTwmemref, ref szStatus); WriteTriplet("DG_CONTROL", "DAT_PARENT", "MSG_OPENDSM", sts.ToString() + Environment.NewLine + m_intptrHwnd.ToString()); // Fix our controls... if (TWAIN.GetPlatform() == TWAIN.Platform.WINDOWS) { m_checkboxUseTwain32.Enabled = false; m_checkboxUseCallbacks.Enabled = false; } // Help the user... AutoDropdown(a_szDg, a_szDat, a_szMsg); } // Handle MSG_CLOSEDSM... else if (a_szMsg == "MSG_CLOSEDSM") { // Issue the command... m_blClosing = true; Rollback(TWAIN.STATE.S1); // Fix our controls... if (TWAIN.GetPlatform() == TWAIN.Platform.WINDOWS) { m_checkboxUseTwain32.Enabled = (TWAIN.GetMachineWordBitSize() == 32); m_checkboxUseCallbacks.Enabled = true; } // Help the user... AutoDropdown(a_szDg, a_szDat, a_szMsg); } // Handle anything else... else { WriteTriplet(a_szDg, a_szDat, a_szMsg, TWAIN.STS.BADPROTOCOL.ToString()); } } /// /// Our callback for device events. This is where we catch and /// report that a device event has been detected. Obviously, /// we're not doing much with it. A real application would /// probably take some kind of action... /// /// TWAIN status private TWAIN.STS DeviceEventCallback() { string szTwmemref = ""; string szStatus = ""; TWAIN.STS sts; TWAIN.TW_DEVICEEVENT twdeviceevent; // Drain the event queue... while (true) { // Try to get an event... twdeviceevent = default(TWAIN.TW_DEVICEEVENT); szTwmemref = TWAIN.DeviceeventToCsv(twdeviceevent); sts = Send("DG_CONTROL", "DAT_DEVICEEVENT", "MSG_GET", ref szTwmemref, ref szStatus); if (sts != TWAIN.STS.SUCCESS) { break; } // Report on what we got... szStatus = (szStatus == "") ? sts.ToString() : (sts.ToString() + " - " + szStatus); WriteOutput("*** DeviceEvent ***" + Environment.NewLine); WriteTriplet("DG_CONTROL", "DAT_PENDINGXFERS", "MSG_ENDXFER", szStatus + ((szTwmemref == "") ? "" : (Environment.NewLine + szTwmemref))); } // Return a status, in case we ever need it for anything... return (TWAIN.STS.SUCCESS); } /// /// TWAIN needs help, if we want it to run stuff in our main /// UI thread... /// /// the control to run in /// the code to run public void RunInUiThread(Action a_action) { RunInUiThread(this, a_action); } static public void RunInUiThread(Object a_object, Action a_action) { Control control = (Control)a_object; if (control.InvokeRequired) { control.Invoke(new FormMain.RunInUiThreadDelegate(RunInUiThread), new object[] { a_object, a_action }); return; } a_action(); } /// /// Close the Data Source... /// /// Data group /// Data argument type /// Operation private void m_buttonCloseDS_Click(string a_szDg, string a_szDat, string a_szMsg) { if (m_twain != null) { Rollback(TWAIN.STATE.S3); } } /// /// Start a scanning session... /// /// Originator /// Arguments private void m_buttonScan_Click(object sender, EventArgs e) { string szTwmemref; string szStatus; TWAIN.STS sts; Bitmap bitmap = new Bitmap(m_pictureboxImage1.Width, m_pictureboxImage1.Height); // Reset the picture boxes... m_iCurrentPictureBox = 0; LoadImage(ref m_pictureboxImage1, ref m_graphics1, ref m_bitmapGraphic1, bitmap); LoadImage(ref m_pictureboxImage2, ref m_graphics2, ref m_bitmapGraphic2, bitmap); LoadImage(ref m_pictureboxImage3, ref m_graphics3, ref m_bitmapGraphic3, bitmap); LoadImage(ref m_pictureboxImage4, ref m_graphics4, ref m_bitmapGraphic4, bitmap); LoadImage(ref m_pictureboxImage5, ref m_graphics5, ref m_bitmapGraphic5, bitmap); LoadImage(ref m_pictureboxImage6, ref m_graphics6, ref m_bitmapGraphic6, bitmap); LoadImage(ref m_pictureboxImage7, ref m_graphics7, ref m_bitmapGraphic7, bitmap); LoadImage(ref m_pictureboxImage8, ref m_graphics8, ref m_bitmapGraphic8, bitmap); // Request a scan session... ClearEvents(); szTwmemref = "0,0," + m_intptrHwnd; szStatus = ""; sts = Send("DG_CONTROL", "DAT_USERINTERFACE", "MSG_ENABLEDS", ref szTwmemref, ref szStatus); WriteTriplet("DG_CONTROL", "DAT_USERINTERFACE", "MSG_ENABLEDS", sts.ToString()); } /// /// Clear our event list, and reset our event... /// public void ClearEvents() { m_blXferReadySent = false; m_blDisableDsSent = false; } /// /// Stop scanning... /// /// Originator /// Arguments private void m_buttonStop_Click(object sender, EventArgs e) { if (m_twain != null) { string szTwmemref = "0,0"; string szStatus = ""; TWAIN.STS sts = Send("DG_CONTROL", "DAT_PENDINGXFERS", "MSG_STOPFEEDER", ref szTwmemref, ref szStatus); szStatus = (szStatus == "") ? sts.ToString() : (sts.ToString() + " - " + szStatus); WriteTriplet("DG_CONTROL", "DAT_PENDINGXFERS", "MSG_STOPFEEDER", szStatus + ((szTwmemref == "") ? "" : (Environment.NewLine + szTwmemref))); } } /// /// React to a change to the selection of TWAIN_32.DLL... /// /// Originator /// Arguments private void m_checkboxUseTwain32_CheckedChanged(object sender, EventArgs e) { // TWAIN_32.DLL om Windows doesn't support callbacks, but the // legacy stuff on Linux and MacOsX does; in fact that's all // they support... if (m_checkboxUseTwain32.Checked) { if (TWAIN.GetPlatform() == TWAIN.Platform.WINDOWS) { m_checkboxUseCallbacks.Checked = false; } } } /// /// React to a chance to the selection of callbacks... /// /// Originator /// Arguments private void m_checkboxUseCallbacks_CheckedChanged(object sender, EventArgs e) { // TWAIN_32.DLL doesn't support callbacks... if (m_checkboxUseCallbacks.Checked) { m_checkboxUseTwain32.Checked = false; } } #endregion /////////////////////////////////////////////////////////////////////////////// // Private Attributes... /////////////////////////////////////////////////////////////////////////////// #region Private Attributes... /// /// Our interface to TWAIN... /// private TWAIN m_twain; private IntPtr m_intptrHwnd; private bool m_blDisableDsSent = false; private bool m_blXferReadySent = false; private IntPtr m_intptrXfer = IntPtr.Zero; private IntPtr m_intptrImage = IntPtr.Zero; private int m_iImageBytes = 0; private TWAIN.TWSX m_twsxXferMech; private TWAIN.TW_SETUPMEMXFER m_twsetupmemxfer; /// /// The picture box we're currently displaying into... /// private int m_iCurrentPictureBox; // Let us know when we're shutting down... private bool m_blClosing; // The brush we use for the image background... private Brush m_brushBackground; // The rectangle we use to fill the background... private Rectangle m_rectangleBackground; // Bitmaps and graphics used to display images during scanning... private Bitmap m_bitmapGraphic1; private Bitmap m_bitmapGraphic2; private Bitmap m_bitmapGraphic3; private Bitmap m_bitmapGraphic4; private Bitmap m_bitmapGraphic5; private Bitmap m_bitmapGraphic6; private Bitmap m_bitmapGraphic7; private Bitmap m_bitmapGraphic8; private Graphics m_graphics1; private Graphics m_graphics2; private Graphics m_graphics3; private Graphics m_graphics4; private Graphics m_graphics5; private Graphics m_graphics6; private Graphics m_graphics7; private Graphics m_graphics8; private int m_iImageCount = 0; /// /// We use this to run code in the context of the caller's UI thread... /// /// object (really a control) /// code to run public delegate void RunInUiThreadDelegate(Object a_object, Action a_action); #endregion } } ================================================ FILE: twaincs/source/twaincstst/source/Main.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 ================================================ FILE: twaincs/source/twaincstst/source/Program.cs ================================================ /////////////////////////////////////////////////////////////////////////////////////// // // TWAINCSTst.Program // // Our main entry point... // /////////////////////////////////////////////////////////////////////////////////////// // Author Date Version Comment // M.McLaughlin 21-May-2014 2.0.0.0 64-bit Linux // M.McLaughlin 27-Feb-2014 1.1.0.0 ShowImage additions // M.McLaughlin 21-Oct-2013 1.0.0.0 Initial Release /////////////////////////////////////////////////////////////////////////////////////// // Copyright (C) 2013-2019 Kodak Alaris Inc. // // Permission is hereby granted, free of charge, to any person obtaining a // copy of this software and associated documentation files (the "Software"), // to deal in the Software without restriction, including without limitation // the rights to use, copy, modify, merge, publish, distribute, sublicense, // and/or sell copies of the Software, and to permit persons to whom the // Software is furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL // THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER // DEALINGS IN THE SOFTWARE. /////////////////////////////////////////////////////////////////////////////////////// using System; using System.Windows.Forms; namespace TWAINCSTst { static class Program { /// /// The main entry point for the application. /// [STAThread] static void Main() { Application.EnableVisualStyles(); Application.SetCompatibleTextRenderingDefault(false); Application.Run(new FormMain()); } } } ================================================ FILE: twaincs/source/twaincstst/source/Properties/AssemblyInfo.cs ================================================ /////////////////////////////////////////////////////////////////////////////////////// // // TWAINCSTst AssemblyInfo // /////////////////////////////////////////////////////////////////////////////////////// // Copyright (C) 2013-2021 Kodak Alaris Inc. // // Permission is hereby granted, free of charge, to any person obtaining a // copy of this software and associated documentation files (the "Software"), // to deal in the Software without restriction, including without limitation // the rights to use, copy, modify, merge, publish, distribute, sublicense, // and/or sell copies of the Software, and to permit persons to whom the // Software is furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL // THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER // DEALINGS IN THE SOFTWARE. /////////////////////////////////////////////////////////////////////////////////////// using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; // General Information about an assembly is controlled through the following // set of attributes. Change these attribute values to modify the information // associated with an assembly. [assembly: AssemblyTitle("TWAINCSTst")] [assembly: AssemblyDescription("Diagnostic TWAIN Application for C#")] [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany("Kodak Alaris Inc.")] [assembly: AssemblyProduct("TWAINCSTst")] [assembly: AssemblyCopyright("Copyright © 2013-2020, Kodak Alaris Inc.")] [assembly: AssemblyTrademark("")] [assembly: AssemblyCulture("")] // Setting ComVisible to false makes the types in this assembly not visible // to COM components. If you need to access a type in this assembly from // COM, set the ComVisible attribute to true on that type. [assembly: ComVisible(false)] // The following GUID is for the ID of the typelib if this project is exposed to COM [assembly: Guid("1b424eff-90ab-4e15-863d-884b513fe3c4")] // Version information for an assembly consists of the following four values: // // Major Version // Minor Version // Build Number // Revision // // You can specify all the values or you can default the Build and Revision Numbers // by using the '*' as shown below: [assembly: AssemblyVersion("2.5.0.0")] [assembly: AssemblyFileVersion("2.5.0.0")] ================================================ FILE: twaincs/source/twaincstst/source/Properties/Resources.Designer.cs ================================================ //------------------------------------------------------------------------------ // // This code was generated by a tool. // Runtime Version:4.0.30319.269 // // Changes to this file may cause incorrect behavior and will be lost if // the code is regenerated. // //------------------------------------------------------------------------------ namespace TWAINCSTst.Properties { /// /// A strongly-typed resource class, for looking up localized strings, etc. /// // This class was auto-generated by the StronglyTypedResourceBuilder // class via a tool like ResGen or Visual Studio. // To add or remove a member, edit your .ResX file then rerun ResGen // with the /str option, or rebuild your VS project. [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")] [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] internal class Resources { private static global::System.Resources.ResourceManager resourceMan; private static global::System.Globalization.CultureInfo resourceCulture; [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] internal Resources() { } /// /// Returns the cached ResourceManager instance used by this class. /// [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] internal static global::System.Resources.ResourceManager ResourceManager { get { if ((resourceMan == null)) { global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("TWAINCSTst.Properties.Resources", typeof(Resources).Assembly); resourceMan = temp; } return resourceMan; } } /// /// Overrides the current thread's CurrentUICulture property for all /// resource lookups using this strongly typed resource class. /// [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] internal static global::System.Globalization.CultureInfo Culture { get { return resourceCulture; } set { resourceCulture = value; } } } } ================================================ FILE: twaincs/source/twaincstst/source/Properties/Resources.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 ================================================ FILE: twaincs/source/twaincstst/source/Properties/Settings.Designer.cs ================================================ //------------------------------------------------------------------------------ // // This code was generated by a tool. // Runtime Version:4.0.30319.269 // // Changes to this file may cause incorrect behavior and will be lost if // the code is regenerated. // //------------------------------------------------------------------------------ namespace TWAINCSTst.Properties { [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "10.0.0.0")] internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase { private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings()))); public static Settings Default { get { return defaultInstance; } } } } ================================================ FILE: twaincs/source/twaincstst/source/Properties/Settings.settings ================================================  ================================================ FILE: twaincs/source/twaincstst/source/Properties/Settings1.Designer.cs ================================================ //------------------------------------------------------------------------------ // // This code was generated by a tool. // Runtime Version:4.0.30319.42000 // // Changes to this file may cause incorrect behavior and will be lost if // the code is regenerated. // //------------------------------------------------------------------------------ namespace twaincstst.Properties { [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "15.9.0.0")] internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase { private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings()))); public static Settings Default { get { return defaultInstance; } } } } ================================================ FILE: twaincs/source/twaincstst/source/app.config ================================================  ================================================ FILE: twaincs/source/twaincstst/source/twaincstst.csproj ================================================  15.0.27428.2005 false true Debug x86 {7D3F078C-BAE8-4975-9EBA-F162ABD64BBD} WinExe false twaincstst v4.5.2 512 publish\ true Disk false Foreground 7 Days false false true 0 1.0.0.%2a false false true true full false bin\x86\Debug\ DEBUG;TRACE prompt 4 x86 true true false pdbonly true bin\x86\Release\ TRACE prompt 4 x86 true false twaincstst true bin\x64\Debug\ DEBUG;TRACE full x64 prompt false false true false bin\x64\Release\ TRACE true pdbonly x64 prompt false false true false true bin\AnyCPU\Debug\ DEBUG;TRACE full AnyCPU prompt false false true false bin\AnyCPU\Release\ TRACE true pdbonly AnyCPU prompt false false true false False ..\..\bin\$(Platform)\$(Configuration)\TWAIN.dll Form Main.cs True True Settings.settings Main.cs SettingsSingleFileGenerator Settings1.Designer.cs False .NET Framework 3.5 SP1 Client Profile false False .NET Framework 3.5 SP1 true False Windows Installer 3.1 true