// ************** 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);
}
}