// ************** Copyright ************************* // Alphatronics Virtual Port Monitor Version 4.01 // Application Programmers Interface Reference // Copyright (C) 2002-2009, Alphatronics, Inc. // ************** Disclaimer ************************ // This documentation is provided as-is. Alphatronics, Inc // cannot be held responsible for the use or misuse of // this material. // *************** Purpose ************************** // The purpose of this document is to provide copy and // paste declarations for the 2 functions exported by // the Virtual Port Monitor Dialog DLL, SetVirtualPort // and GetVirtualPort. It may seem that the only thing being // done by these functions is setting registry values, but there // is more to it than that. Windows 9x does allow registry keys // located in the CurrentControlSet\Control\Print section // to be modified, but NT may not, depending on the permissions // granted to the application/user. Also, NT will not recognize // ports that were not introduced by the AddPort() function, // which normally brings up a dialog. These functions are // designed to overcome these limitations while providing // full configuration capabilities to the programmer. // *********** Programmer Notes ******************** // The two exported functions are located in AVPDlg.dll. // Pass a pointer to a TVirtualPort structure // which contains pointers to the various strings // that will be stored into or retrieved from // the registry. All values are strings. When getting // data, allocate BufferSize bytes for each non-null // pointer within the TVirtualPort structure. Size and // PortName are required or the function will fail. // Upon setting data, the port is ready for immediate // use. For NT, etc., You can set the UserName and // Password, but you cannot get them, no matter what // security level you are running at. There are 4 basic // reasons these functions might fail. A Null VirtualPort // structure pointer, A Null PortName, A blank PortName, // or an Exception caused by non-null, but invalid pointers. // These functions do not allocate or free memory for you, // so these are all "your" pointers and memory. // You can choose which members to set by passing valid pointers // to items you want to change. If members of the structure // are null, they will be left alone on a "configure", but will // be set to default values on a "create". // These are ansi only functions. To delete ports // use the DeletePort Windows routine. // Delphi Constants and types Const VPConfigDLL = 'AVPDLG'; FH_AutoFile = 0; // File Handling FH_NoFile = 1; // Application only FH_LogFile = 2; // Append AF_Title = 0; // NameOptions AF_DateTime = 1; // 18 Digit timestamp AF_TitleDateTime = 2; AF_DateTimeTitle = 3; AF_UserNameDateTime = 4; AF_DateTimeUserName = 5; AF_ComputerNameDateTime = 6; AF_DateTimeComputerName = 7; AF_PortDateTime = 8; AF_DateTimePort = 9; AF_TitleUserNameDateTime = 10; AF_TitleDateTimeUserName = 11; AF_UserNameTitleDateTime = 12; AF_UserNameDateTimeTitle = 13; AF_DateTimeUserNameTitle = 14; AF_DateTimeTitleUserName = 15; AF_TitleComputerNameDateTime = 16; AF_TitleDateTimeComputerName = 17; AF_ComputerNameTitleDateTime = 18; AF_ComputerNameDateTimeTitle = 19; AF_DateTimeComputerNameTitle = 20; AF_DateTimeTitleComputerName = 21; LO_Day = 0; // LogOptions LO_Month = 1; LO_DayN = 2; // Numerical LO_MonthN = 3; LO_YearN = 4; LO_File = 5; VP_False = 0; // Obvious? VP_True = 1; VP_SW_Normal = 0; // ShowWindow VP_SW_Minimized = 1; VP_SW_Maximized = 2; AW_None = 0; // App Wait Options AW_Infinite = 1; AW_UseTimeout = 2; UD_Base = 0; // User Directory UD_User = 1; UD_Computer = 2; UD_Printer = 3; UD_Driver = 4; Type PVirtualPort = ^TVirtualPort; TVirtualPort = Record Size : Cardinal; // Required; total bytes in this structure PortName : PChar; // Required Application : PChar; // you can use %env vars% or %1 DirectToFile : PChar; // 0 or 1 DragDrop : PChar; // 0 or 1 Extension : PChar; // Up to 3 characters FileHandling : PChar; // FH_ Constants Forwarding : PChar; // Port List, comma separated LogName : PChar; // Filename only LogOptions : PChar; // LO_ Constants NameOptions : PChar; // AF_ Constants Port : PChar; // Output path ShowWindow : PChar; // 0 Normal; 1 Minimized; 2 Maximized UserDir : PChar; // UD_ Constants - New for 4.0 Spooling : PChar; // Printer List, comma separated UserName : PChar; // NT Only; Not returned by Get... Password : PChar; // NT Only; Not returned by Get... Domain : PChar; // NT Only // options below are only for version 4.0 and above AppWaitOptions : PChar; // AW Constants AppWaitTimeout : PChar; // In milliseconds AppWaitDelete : PChar; // 0 or 1 End; TSetVirtualPortProc = Function(VP : PVirtualPort) : LongBool; StdCall; // Pass a pointer to a TVirtualPort Structure TGetVirtualPortProc = Function(VP : PVirtualPort; BufferSize : Cardinal) : LongBool; StdCall; // Pass a pointer to a TVirtualPort Structure and the // Per Member buffer size. ie; Each string can hold 1024 bytes // C Constants and Declarations #define VPConfigDLL TEXT("AVPDLG") #define FH_AutoFile 0 #define FH_NoFile 1 #define FH_LogFile 2 #define AF_Title 0 #define AF_DateTime 1 #define AF_TitleDateTime 2 #define AF_DateTimeTitle 3 #define AF_UserNameDateTime 4 #define AF_DateTimeUserName 5 #define AF_ComputerNameDateTime 6 #define AF_DateTimeComputerName 7 #define AF_PortDateTime 8 #define AF_DateTimePort 9 #define AF_TitleUserNameDateTime 10 #define AF_TitleDateTimeUserName 11 #define AF_UserNameTitleDateTime 12 #define AF_UserNameDateTimeTitle 13 #define AF_DateTimeUserNameTitle 14 #define AF_DateTimeTitleUserName 15 #define AF_TitleComputerNameDateTime 16 #define AF_TitleDateTimeComputerName 17 #define AF_ComputerNameTitleDateTime 18 #define AF_ComputerNameDateTimeTitle 19 #define AF_DateTimeComputerNameTitle 20 #define AF_DateTimeTitleComputerName 21 #define LO_Day 0 #define LO_Month 1 #define LO_DayN 2 #define LO_MonthN 3 #define LO_YearN 4 #define LO_File 5 #define VP_False 0 #define VP_True 1 #define VP_SW_Normal 0 #define VP_SW_Minimized 1 #define VP_SW_Maximized 2 #define AW_None 0 #define AW_Infinite 1 #define AW_UseTimeout 2 UD_Base 0 UD_User 1 UD_Computer 2 UD_Printer 3 UD_Driver 4 typedef struct TVirtualPort { DWORD Size; // Required; total bytes in this structure LPSTR PortName; // Required LPSTR Application; // you can use %env vars% or %1 LPSTR DirectToFile; // 0 or 1 LPSTR DragDrop; // 0 or 1 LPSTR Extension; // Up to 3 characters LPSTR FileHandling; // FH_ Constants LPSTR Forwarding; // Port List, comma separated LPSTR LogName; // Filename only LPSTR LogOptions; // LO_ Constants LPSTR NameOptions; // AF_ Constants LPSTR Port; // Output path LPSTR ShowWindow; // 0 Normal; 1 Minimized; 2 Maximized LPSTR UserDir; // 0 or 1 LPSTR Spooling; // Printer List, comma separated LPSTR UserName; // NT Only; Not returned by Get... LPSTR Password; // NT Only; Not returned by Get... LPSTR Domain; // NT Only // options below are only for version 4.0 and above LPSTR AppWaitOptions; // AW Constants LPSTR AppWaitTimeout; // In milliseconds LPSTR AppWaitDelete; // 0 or 1 }; BOOL // Returns DWORD size Boolean WINAPI // Stack, not register SetVirtualPort(struct TVirtualPort *VirtualPort); // Pass a pointer to a TVirtualPort Structure BOOL // Returns DWORD size Boolean WINAPI // Stack, not register GetVirtualPort(struct TVirtualPort *VirtualPort, DWORD BufferSize); // Pass a pointer to a TVirtualPort Structure and the // Per Member buffer size. ie; Each string can hold 1024 bytes // C Sharp wrapper class using System; using System.Collections.Generic; using System.Text; using System.Runtime.InteropServices; namespace AVP { /// /// Wrapper class for talking to the alphatronics port monitor. /// The fields except for "size" are all C++ char[]--of the same size. /// If you have a need for something larger than MAX_PATH, change the /// const "StringSize" /// [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)] public unsafe class AVPMonitor { protected UInt32 Size_; // Required; total bytes in this structure protected byte* PortName_; // Required protected byte* Application_; // you can use %env vars% or %1 protected byte* DirectToFile_; // 0 or 1 protected byte* DragDrop_; // 0 or 1 protected byte* Extension_; // Up to 3 characters protected byte* FileHandling_; // FH_ Constants protected byte* Forwarding_; // Port List, comma separated protected byte* LogName_; // Filename only protected byte* LogOptions_; // LO_ Constants protected byte* NameOptions_; // AF_ Constants protected byte* Port_; // Output path protected byte* ShowWindow_; // 0 Normal_; 1 Minimized_; 2 Maximized protected byte* UserDir_; // 0 or 1 NO!- UD_ constants protected byte* Spooling_; // Printer List, comma separated protected byte* UserName_; // NT Only_; Not returned by Get... protected byte* Password_; // NT Only_; Not returned by Get... protected byte* Domain_; // NT Only protected byte* AppWaitOptions_; // AW Constants protected byte* AppWaitTimeout_; // In milliseconds protected byte* AppWaitDelete_; // 0 or 1 public const int NumCharFields = 20; // increase if needed--must = numof(byte*) above // should be a MAX_PATH, but since C# doesn't do defines, we're stuck with // manifest constants in our code public const int StringSize = 260; // counters to actually store the byte offsets where the port capture expects to // get our data protected int iP; protected IntPtr p; public AVPMonitor() { Size_ = (UInt32)(NumCharFields * sizeof(IntPtr) + sizeof(UInt32)); p = Marshal.AllocHGlobal(NumCharFields * StringSize); iP = p.ToInt32(); PortName_ = incPtr(); Application_ = incPtr(); DirectToFile_ = incPtr(); DragDrop_ = incPtr(); Extension_ = incPtr(); FileHandling_ = incPtr(); Forwarding_ = incPtr(); LogName_ = incPtr(); LogOptions_ = incPtr(); NameOptions_ = incPtr(); Port_ = incPtr(); ShowWindow_ = incPtr(); UserDir_ = incPtr(); Spooling_ = incPtr(); UserName_ = incPtr(); Password_ = incPtr(); Domain_ = incPtr(); AppWaitOptions_ = incPtr(); AppWaitTimeout_ = incPtr(); AppWaitDelete_ = incPtr(); } ~AVPMonitor() { if (p != IntPtr.Zero) Marshal.FreeHGlobal(p); } /// /// Sets up the data locations for fields, initializes to all byte(0) /// /// pointer to the location of the field protected byte* incPtr() { IntPtr Q = new IntPtr(iP); byte* b = (byte*)(Q.ToPointer()); byte* c = b; byte* ec = c+StringSize; while (c != ec) *c++ = (byte)0; iP += StringSize; return b; } /// /// intrinsically unsafe--copy a byte * from a string /// /// /// public static void StringToByte(byte* p, string s) { byte* c = p; byte* ec = p + StringSize; while (c != ec) *c++ = (byte)0; c = p; for (int i = 0; i < s.Length && i < StringSize; i++) { *c++ = (byte)s[i]; } } /// /// intrinsically unsafe--copy a byte * to a string /// /// /// public static string ByteToString(byte * b) { return new string((sbyte*)b); } //accessors public string PortName { get { return ByteToString(PortName_); } set { StringToByte(PortName_, value); } } public string Application { get { return ByteToString(Application_); } set { StringToByte(Application_, value); } } public string Extension { get { return ByteToString(Extension_); } set { StringToByte(Extension_, value); } } public string ForwardingPorts { get { return ByteToString(Forwarding_); } set { StringToByte(Forwarding_, value); } } public string OutputPath { get { return ByteToString(Port_); } set { StringToByte(Port_, value); } } public string SpoolingList { get { return ByteToString(Spooling_); } set { StringToByte(Spooling_, value); } } public string UserName { get { return ByteToString(UserName_); } set { StringToByte(UserName_, value); } } public string Password { get { return ByteToString(Password_); } set { StringToByte(Password_, value); } } public string Domain { get { return ByteToString(Domain_); } set { StringToByte(Domain_, value); } } public const byte ByteOne = 0x31; public const byte ByteZero = 0x30; public bool DirectToFile { get { return (*DirectToFile_ == ByteOne); } set { *DirectToFile_ = value ? ByteOne : ByteZero; } } public bool DragDrop { get { return (*DragDrop_ == ByteOne); } set { *DragDrop_ = value ? ByteOne : ByteZero; } } public eUserDirOptions UserDir { get { return (eUserDirOptions)ByteToInt(UserDir_, 0); } set { IntToByte(UserDir_, (int)value); } } public bool AppWaitDelete { get { return (*AppWaitDelete_ == ByteOne); } set { *AppWaitDelete_ = value ? ByteOne : ByteZero; } } /// /// Post Processing Application wait options must be ON. /// Timeout wait in milliseconds /// public int AppWaitTimeout { get { return ByteToInt(AppWaitTimeout_, 0); } set { IntToByte(AppWaitTimeout_, value); } } /// /// Post Processing Application wait options /// public eAppWaitOptions AppWaitOptions { get { return (eAppWaitOptions)ByteToInt(AppWaitOptions_, 0); } set { IntToByte(AppWaitOptions_, (int)value); } } /// /// File handling options from FH_ /// public eFileHandlingOptions FileHandlingOptions { get { return (eFileHandlingOptions)ByteToInt(FileHandling_, 0); } set { IntToByte(FileHandling_, (int)value); } } /// /// Log File options /// public eLogOptions LogOptions { get { return (eLogOptions)ByteToInt(LogOptions_, 0); } set { IntToByte(LogOptions_, (int)value); } } /// /// File Naming conventions for the output file /// public eNameOptions NameOptions { get { return (eNameOptions)ByteToInt(NameOptions_, 0); } set { IntToByte(NameOptions_, (int)value); } } public eHandlerPgmOptions ShowWindow { get { return (eHandlerPgmOptions)ByteToInt(ShowWindow_, 0); } set { IntToByte(ShowWindow_, (int)value); } } protected static void IntToByte(byte* p, int val) { StringToByte(p, val.ToString()); } protected static int ByteToInt(byte* p, int DefaultValue) { int ret = DefaultValue; try { string s = ByteToString(p); if (!String.IsNullOrEmpty(s)) { ret = Convert.ToInt32(s); } } catch { } return ret; } public enum eFileHandlingOptions : int { FH_AutoFile = 0, FH_NoFile = 1, FH_LogFile = 2, } public enum eNameOptions : int { AF_Title = 0, AF_DateTime = 1, AF_TitleDateTime = 2, AF_DateTimeTitle = 3, AF_UserNameDateTime = 4, AF_DateTimeUserName = 5, AF_ComputerNameDateTime = 6, AF_DateTimeComputerName = 7, AF_PortDateTime = 8, AF_DateTimePort = 9, AF_TitleUserNameDateTime = 10, AF_TitleDateTimeUserName = 11, AF_UserNameTitleDateTime = 12, AF_UserNameDateTimeTitle = 13, AF_DateTimeUserNameTitle = 14, AF_DateTimeTitleUserName = 15, AF_TitleComputerNameDateTime = 16, AF_TitleDateTimeComputerName = 17, AF_ComputerNameTitleDateTime = 18, AF_ComputerNameDateTimeTitle = 19, AF_DateTimeComputerNameTitle = 20, AF_DateTimeTitleComputerName = 21, } public enum eLogOptions : int { LO_Day = 0, LO_Month = 1, LO_DayN = 2, LO_MonthN = 3, LO_YearN = 4, LO_File = 5, } public enum eHandlerPgmOptions : int { SW_Normal = 0, SW_Minimized = 1, SW_Maximized = 2, } public enum eAppWaitOptions : int { AW_None = 0, AW_Infinite = 1, AW_UseTimeout = 2, } public enum eUserDirOptions : int { UD_Base = 0, UD_User = 1, UD_Computer = 2, UD_Printer = 3, UD_Driver = 4 } public bool SetVirtualPort() { return 0 != SetVirtualPort(this); } public bool GetVirtualPort(string PortName) { this.PortName = PortName; return 0 != GetVirtualPort(this, StringSize); } [DllImport("AVPDlg.dll", CallingConvention = CallingConvention.Winapi, CharSet = CharSet.Ansi)] static extern UInt32 SetVirtualPort(AVPMonitor VirtualPort); /// Pass a pointer to a TVirtualPort Structure and the /// Per Member buffer size. ie; Each string can hold 1024 bytes [DllImport("AVPDlg.dll", CallingConvention = CallingConvention.Winapi, CharSet = CharSet.Ansi)] static extern UInt32 GetVirtualPort(AVPMonitor VirtualPort, UInt32 BufferSize); } }