I
I
Ivan Roganov2013-05-01 21:24:08
Programming
Ivan Roganov, 2013-05-01 21:24:08

How to receive data via LPT?

Got divorced in the world of accounting programs written in terry years. Each of them prints on what he wants and how he wants. As a result, in order to put these programs on modern operating systems, it is necessary to reinvent the wheel.

I wrote a software - a printer redirector - it sits and pretends to be an old network printer on port 9100. When text arrives at this port, the program saves it in a readable form and opens the Windows print dialog, prompting the user to print the document on existing printers. It was easy to intercept network traffic on port 9100. You sit and wait for the data to arrive, and then save it from the stream to a file.

But in the organization, software appeared ancient and dense. This software does not recognize any network printers. Recognizes only ports LPT1-3 and COM1,2. If LTP can still be somehow bypassed through net use LTP1 \\sharename, then it is more difficult with comas. + The user fell in love with my software and he likes the ability to save printouts in files and select printers in the system. Therefore, I was asked to finish the program to support LPT and COM.

I happily said "Yes!" and ... I did not find decent manuals. Hindus generously distribute information on how to calculate the current state of the pin on the LPT, but this is all.

Who can help with information on how to properly "Pretend" to be a printer on LPT and COMs in order to receive the text that the program wants to print?

All this is written in Sharps with the fourth dotnet. (I understand that the second one would be enough, but the target audience is sitting on Windows 7 and 8, and in the latter there is a problem with the second dotnet)

I am ready to give the program into the hands of the public after I have washed down LPT and COM support - to help system administrators who are suffering with the delightful works of Vasya Pupkin from the time of the 18th century.

Answer the question

In order to leave comments, you need to log in

3 answer(s)
M
Myrkr, 2013-05-06
@Nurked

There is nothing particularly difficult in communicating with the driver .
The drivers themselves can be downloaded here. A convenient class for working with them is here.

using System;
using System.Runtime.InteropServices;

namespace PortAccess {
  public class ParallelPort {
    [DllImport("inpout32.dll")]
    private static extern UInt32 IsInpOutDriverOpen();
    [DllImport("inpout32.dll")]
    private static extern void Out32(short portAddress, short data);
    [DllImport("inpout32.dll")]
    private static extern char Inp32(short portAddress);
    [DllImport("inpout32.dll")]
    private static extern void DlPortWritePortUshort(short portAddress, ushort data);
    [DllImport("inpout32.dll")]
    private static extern ushort DlPortReadPortUshort(short portAddress);
    [DllImport("inpout32.dll")]
    private static extern void DlPortWritePortUlong(int portAddress, uint data);
    [DllImport("inpout32.dll")]
    private static extern uint DlPortReadPortUlong(int portAddress);

    [DllImport("inpoutx64.dll")]
    private static extern bool GetPhysLong(ref int portAddress, ref uint data);
    [DllImport("inpoutx64.dll")]
    private static extern bool SetPhysLong(ref int portAddress, ref uint data);
    [DllImport("inpoutx64.dll", EntryPoint = "IsInpOutDriverOpen")]
    private static extern UInt32 IsInpOutDriverOpenmode();
    [DllImport("inpoutx64.dll", EntryPoint = "Out32")]
    private static extern void Out32mode(short portAddress, short data);
    [DllImport("inpoutx64.dll", EntryPoint = "Inp32")]
    private static extern char Inp32mode(short portAddress);
    [DllImport("inpoutx64.dll", EntryPoint = "DlPortWritePortUshort")]
    private static extern void DlPortWritePortUshortmode(short portAddress, ushort data);
    [DllImport("inpoutx64.dll", EntryPoint = "DlPortReadPortUshort")]
    private static extern ushort DlPortReadPortUshortmode(short portAddress);
    [DllImport("inpoutx64.dll", EntryPoint = "DlPortWritePortUlong")]
    private static extern void DlPortWritePortUlongmode(int portAddress, uint data);
    [DllImport("inpoutx64.dll", EntryPoint = "DlPortReadPortUlong")]
    private static extern uint DlPortReadPortUlongmode(int portAddress);
    [DllImport("inpoutx64.dll", EntryPoint = "GetPhysLong")]
    private static extern bool GetPhysLongmode(ref int portAddress, ref uint data);
    [DllImport("inpoutx64.dll", EntryPoint = "SetPhysLong")]
    private static extern bool SetPhysLongmode(ref int portAddress, ref uint data);

    private bool mode;
    private short portAddress;

    public ParallelPort(short portAddress) {
      mode = false;
      this.portAddress = portAddress;
      try {
        uint nResult = 0;
        try {
          nResult = IsInpOutDriverOpen();
        }
        catch (BadImageFormatException) {
          nResult = IsInpOutDriverOpenmode();
          if (nResult != 0) {
            mode = true;
          }
        }
        if (nResult == 0 ) {
          throw new ArgumentException("Unable to open InpOut32 driver");
        }
      }
      catch (DllNotFoundException) {
        throw new ArgumentException("Unable to find InpOut32.dll");
      }
    }

    public void Write(short data) {
      if (mode) {
        Out32mode(portAddress, data);
      }
      else {
        Out32(portAddress, data);
      }
    }

    public byte Read() {
      if (mode) {
        return (byte)Inp32mode(portAddress);
      }
      else {
        return (byte)Inp32(portAddress);
      }
    }
  }
}

M
mayorovp, 2013-05-01
@mayorovp

Perhaps now I'm scaping, but I need to write a virtual port driver.

F
Flexz, 2013-05-01
@Flexz

With LPT it is difficult. The fact is that in the latest Windows (although what is there “in the latest”, this is already with w2k) the LPT port, as a device, can only be accessed from the driver. Or with the help of "cheating" - you probably already met examples with all sorts of giveio.dll.
With COM it will probably be easier. The first thing that comes to mind is a computer with two COM ports (USB-COM or PCI-COM is not a problem to get now), we connect the ports with a cross, perhaps TX-RX is enough. One port is opened by your emulator program, the other port is a printing fossil.

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question