public static extern ReturnCode DsmWin32( [In, Out] TW_IDENTITY origin, IntPtr zero, DataGroups dg, DataArgumentType dat, Message msg, [In, Out] TW_ENTRYPOINT data);
public ReturnCode Get(out TW_ENTRYPOINT entry) { entry = new TW_ENTRYPOINT(); if (Is32Bit) { if (IsWin) { return(NativeMethods.DsmWin32(Session.Config.App32, IntPtr.Zero, DataGroups.Control, DataArgumentType.EntryPoint, Message.Get, entry)); } if (IsLinux) { return(NativeMethods.DsmLinux32(Session.Config.App32, IntPtr.Zero, DataGroups.Control, DataArgumentType.EntryPoint, Message.Get, entry)); } if (IsMac) { return(NativeMethods.DsmMac32(Session.Config.App32, IntPtr.Zero, DataGroups.Control, DataArgumentType.EntryPoint, Message.Get, entry)); } } if (IsWin) { return(NativeMethods.DsmWin64(Session.Config.App32, IntPtr.Zero, DataGroups.Control, DataArgumentType.EntryPoint, Message.Get, entry)); } if (IsLinux) { return(NativeMethods.DsmLinux64(Session.Config.App32, IntPtr.Zero, DataGroups.Control, DataArgumentType.EntryPoint, Message.Get, entry)); } if (IsMac) { return(NativeMethods.DsmMac64(Session.Config.App32, IntPtr.Zero, DataGroups.Control, DataArgumentType.EntryPoint, Message.Get, entry)); } return(ReturnCode.Failure); }
/// <summary> /// Get the entrypoint data... /// </summary> /// <param name="a_dg">Data group</param> /// <param name="a_msg">Operation</param> /// <param name="a_twentrypoint">ENTRYPOINT structure</param> /// <returns>TWAIN status</returns> 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)WindowsTwain32DsmEntryEntrypoint(ref m_twidentitylegacyApp, ref m_twidentitylegacyDs, a_dg, DAT.ENTRYPOINT, a_msg, ref a_twentrypoint); } else { sts = (STS)WindowsTwaindsmDsmEntryEntrypoint(ref m_twidentitylegacyApp, ref m_twidentitylegacyDs, a_dg, DAT.ENTRYPOINT, a_msg, ref a_twentrypoint); } } catch { // The driver crashed... Log.LogSendAfter(STS.BUMMER.ToString(), ""); return (STS.BUMMER); } } // Linux... else if (ms_platform == Platform.LINUX) { // Issue the command... try { if (GetMachineWordBitSize() == 32) { sts = (STS)LinuxDsmEntryEntrypoint(ref m_twidentitylegacyApp, ref m_twidentitylegacyDs, a_dg, DAT.ENTRYPOINT, a_msg, ref a_twentrypoint); } else { sts = (STS)Linux64DsmEntryEntrypoint(ref m_twidentityApp, ref m_twidentityDs, a_dg, DAT.ENTRYPOINT, a_msg, ref a_twentrypoint); } } catch { // The driver crashed... Log.LogSendAfter(STS.BUMMER.ToString(), ""); return (STS.BUMMER); } } // Mac OS X, which has to be different... else if (ms_platform == Platform.MACOSX) { // Issue the command... try { sts = (STS)MacosxDsmEntryEntrypoint(ref m_twidentitymacosxApp, ref m_twidentitymacosxDs, a_dg, DAT.ENTRYPOINT, a_msg, ref a_twentrypoint); } catch { // The driver crashed... Log.LogSendAfter(STS.BUMMER.ToString(), ""); return (STS.BUMMER); } } // Uh-oh... else { Log.LogSendAfter(STS.BUMMER.ToString(), ""); 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)); } } // Log it... if (Log.GetLevel() > 0) { Log.LogSendAfter(sts.ToString(), EntrypointToCsv(a_twentrypoint)); } // All done... return (AutoDatStatus(sts)); }
private static extern UInt16 MacosxDsmEntryEntrypoint ( ref TW_IDENTITY_MACOSX origin, ref TW_IDENTITY_MACOSX dest, DG dg, DAT dat, MSG msg, ref TW_ENTRYPOINT twentrypoint );
/// <summary> /// Convert the contents of an entry point to a string that /// we can show in our simple GUI... /// </summary> /// <param name="a_twentrypoint">A TWAIN structure</param> /// <returns>A CSV string of the TWAIN structure</returns> public 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 { return ("***error***"); } }
private static extern UInt16 Linux64DsmEntryEntrypoint ( ref TW_IDENTITY origin, ref TW_IDENTITY dest, DG dg, DAT dat, MSG msg, ref TW_ENTRYPOINT twentrypoint );
private static extern UInt16 WindowsTwaindsmDsmEntryEntrypoint ( ref TW_IDENTITY_LEGACY origin, ref TW_IDENTITY_LEGACY dest, DG dg, DAT dat, MSG msg, ref TW_ENTRYPOINT twentrypoint );
/// <summary> /// Convert the contents of an entry point to a string that /// we can show in our simple GUI... /// </summary> /// <param name="a_twentrypoint">A TWAIN structure</param> /// <returns>A CSV string of the TWAIN structure</returns> public virtual string EntrypointToCsv(TW_ENTRYPOINT a_twentrypoint) { try { CSV csv = new CSV(); csv.Add(a_twentrypoint.Size.ToString()); csv.Add("0x" + a_twentrypoint.DSM_Entry.ToString("X")); csv.Add("0x" + Marshal.GetFunctionPointerForDelegate(a_twentrypoint.DSM_MemAllocate).ToString("X")); csv.Add("0x" + Marshal.GetFunctionPointerForDelegate(a_twentrypoint.DSM_MemFree).ToString("X")); csv.Add("0x" + Marshal.GetFunctionPointerForDelegate(a_twentrypoint.DSM_MemLock).ToString("X")); csv.Add("0x" + Marshal.GetFunctionPointerForDelegate(a_twentrypoint.DSM_MemUnlock).ToString("X")); return (csv.Get()); } catch { return ("***error***"); } }
/// <summary> /// Our constructor... /// </summary> /// <param name="a_szManufacturer">Application manufacturer</param> /// <param name="a_szProductFamily">Application product family</param> /// <param name="a_szProductName">Name of the application</param> /// <param name="a_u16ProtocolMajor">TWAIN protocol major (doesn't have to match TWAINH.CS)</param> /// <param name="a_u16ProtocolMinor">TWAIN protocol minor (doesn't have to match TWAINH.CS)</param> /// <param name="a_u32SupportedGroups">Bitmask of DG_ flags</param> /// <param name="a_twcy">Country code for the application</param> /// <param name="a_szInfo">Info about the application</param> /// <param name="a_twlg">Language code for the application</param> /// <param name="a_u16MajorNum">Application's major version</param> /// <param name="a_u16MinorNum">Application's minor version</param> /// <param name="a_blUseLegacyDSM">Use the legacy DSM (like TWAIN_32.DLL)</param> /// <param name="a_blUseCallbacks">Use callbacks instead of Windows post message</param> /// <param name="a_deviceeventback">Function to receive device events</param> /// <param name="a_scancallback">Function to handle scanning</param> 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 ) { 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; // 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_twentrypoint = default(TW_ENTRYPOINT); // 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) { m_blUseLegacyDSM = false; m_blUseCallbacks = true; m_linuxdsmentrycontrolcallbackdelegate = LinuxDsmEntryCallbackProxy; } // Mac OS X only... else if (ms_platform == Platform.MACOSX) { m_blUseLegacyDSM = false; m_blUseCallbacks = true; m_macosxdsmentrycontrolcallbackdelegate = MacosxDsmEntryCallbackProxy; } // Uh-oh, Log will throw an exception for us... else { Log.Msg(Log.Severity.Throw, "Unsupported platform..." + ms_platform); } // Activate our thread... if (m_threadTwain == null) { m_threadTwain = new Thread(Main); m_threadTwain.Start(); if (!m_autoreseteventThreadStarted.WaitOne(5000)) { try { m_threadTwain.Abort(); m_threadTwain = null; } catch { // Log will throw an exception for us... Log.Msg(Log.Severity.Throw, "Failed to start the TWAIN background thread..."); } } } }
/// <summary> /// Get the entrypoint data... /// </summary> /// <param name="a_dg">Data group</param> /// <param name="a_msg">Operation</param> /// <param name="a_twentrypoint">ENTRYPOINT structure</param> /// <returns>TWAIN status</returns> public virtual 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... m_threaddata = default(ThreadData); m_threaddata.twentrypoint = a_twentrypoint; m_threaddata.dg = a_dg; m_threaddata.msg = a_msg; m_threaddata.dat = DAT.ENTRYPOINT; // Submit the command and wait for the reply... CallerToThreadSet(); ThreadToCallerWaitOne(); // Return the result... a_twentrypoint = m_threaddata.twentrypoint; sts = m_threaddata.sts; // Clear the command variables... m_threaddata = default(ThreadData); } return (sts); } // Log it... if (Log.GetLevel() > 0) { Log.LogSendBefore(a_dg, DAT.ENTRYPOINT, a_msg, EntrypointToCsv(a_twentrypoint)); } // Windows... if (ms_platform == Platform.WINDOWS) { // Issue the command... try { if (m_blUseLegacyDSM) { sts = (STS)WindowsTwain32DsmEntryEntrypoint(ref m_twidentitylegacyApp, ref m_twidentitylegacyDs, a_dg, DAT.ENTRYPOINT, a_msg, ref a_twentrypoint); } else { sts = (STS)WindowsTwaindsmDsmEntryEntrypoint(ref m_twidentitylegacyApp, ref m_twidentitylegacyDs, a_dg, DAT.ENTRYPOINT, a_msg, ref a_twentrypoint); } } catch { // The driver crashed... Log.LogSendAfter(STS.BUMMER, ""); return (STS.BUMMER); } } // Linux... else if (ms_platform == Platform.LINUX) { // Issue the command... try { if (GetMachineWordBitSize() == 32) { sts = (STS)LinuxDsmEntryEntrypoint(ref m_twidentitylegacyApp, ref m_twidentitylegacyDs, a_dg, DAT.ENTRYPOINT, a_msg, ref a_twentrypoint); } else { sts = (STS)Linux64DsmEntryEntrypoint(ref m_twidentityApp, ref m_twidentityDs, a_dg, DAT.ENTRYPOINT, a_msg, ref a_twentrypoint); } } catch { // The driver crashed... 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 { sts = (STS)MacosxDsmEntryEntrypoint(ref m_twidentitymacosxApp, ref m_twidentitymacosxDs, a_dg, DAT.ENTRYPOINT, a_msg, ref a_twentrypoint); } catch { // The driver crashed... 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_twentrypoint = a_twentrypoint; } // Log it... if (Log.GetLevel() > 0) { Log.LogSendAfter(sts, EntrypointToCsv(a_twentrypoint)); } // All done... return (AutoDatStatus(sts)); }