How to intercept data being sent to a printer? - printing

I'm interfacing with an application that's sending a raw printer file to the default printer. This is the only thing it will do with the data.
I need to get this file somehow so I can store it elsewhere instead. What would be the best way to do this?
The best I've thought of is to write an app that listens to a specific port, and set the default printer to that port.
Would this way work? Is there a better way?

I ran across and LDP implementation for Java that I'm going to modify and use. You can access it as a printer and then do what you want with the raw files.
http://lpdspooler.sourceforge.net/

Related

Saving printed documents in a Windows Server machine

Do you know any way to have a copy of all documents printed through print queues of a Windows Server 2003 machine? I'd like to audit what people is printing.
Regards
You could just set the queue to keep printed documents.
EDIT:
If you want to 'move them' to another place then you will probably have to put some kind of different port monitor in place. You could use something like Redmon (or we have a Commercial product) that would write the data to file, and then route it to the actual printer.
There are other server based tools that could allow for this along with other tracking capabilities.

convert printer port bytes inpout32

I'm running out of ideas.
I'm using C by the way via inpout32.dll.
I have these "bytes"(e.g. 0000,00CC) being read from the printer data ports D0-7 or D1-8.
I need to filter out human readable characters when a print job is being done.
This is still very primitive, but I've got a listener function catching these data using inp32.
Basically if I do a print in notepad like 'Hello World', this will be pulled out from the byte being read by inp32 function.
the printer port listener is on a separate app.
the idea is that the app can listen in on any printer.
It's basically a PoC at the moment.
but what I'm using right now to test is a Canon BJC-1000SP, it's pretty old but it's the only parallel port printer we've got at the office. the others are USB types.
I'm using this on Windows at the moment.
Thermal Printers are actually the ones we'll be listening on.
So now I'm trying to use a generic driver that allows raw text file to print.
How can I extract text from it via the port?
If anybody can give me an idea, a function/converter or where to search, that would be great.
If all you read is already human-readable text, just store it all.
If not, you need to think about the character encoding in use. If it's plain old ASCII, you can probably just call isprint() to determine if a byte is a printable character.
The above of course assumes that your printer is talking plain-text, which probably means it has to be a rather old and simplistic printer (like a dot-matrix from ~20 years ago, or so).
If it's a modern "Win-Printer" laser or inkjet, with all the intelligence of page layout being done by the host computer in the driver, you're probably out of luck. In these cases, what is transmitted is the instructions to layout the page, typically in a printer-specific format.
I think you should edit your question and specify exactly what printer you're using, and in which operating system environment you're running your program.
Update: The Canon BJC-1000 printer you're currently using is an inkjet. It very probably relies on the host computer to send it line-by-line (as in ink lines, not text lines) of data to control the various ink nozzles. I don't think it ever sends plain text to the printer. You could investigate by reading through the code of an open source driver. For Linux, the recommended driver is called gutenprint.

Virtual channels for VNC?

Does anybody know weather VNC (RFB) supports virtual channels and add-ins to them like it is in the RDP (Microsoft Terminal Services)? I just want to transfer my own data across a VNC connection...
VNC/RFB does not have virtual channels unfortunately.
Here is the best reference I've found to the RFB protocol: http://tigervnc.org/cgi-bin/rfbproto
Without knowing more about what you are trying to send and which direction(s), there are a few of options that come to mind:
The tight encoding has file-transfer support. There is a poorly formatted specification for the full tight encoding here: http://vnc-tight.svn.sourceforge.net/viewvc/vnc-tight/trunk/doc/rfbtight.odt?revision=3619
If you have control of both client and server, then you could define a custom encoding that allows you to send your data. The client would advertise that it supports the encoding and if the server supports it then it will start using it.
You could use the clipboard messages (ClientCutText and ServerCutText) and if you need to send binary data that create a custom encoding the data as ISO 8859-1 (Latin-1). The downside is that if the server doesn't support it and the client sends the data it will get pasted to the server.
If you just need to send from the server to the client, then you could use a framebufferUpdate message that sends data outside the current viewport (i.e. 123 pixels beyond the right side of the viewport). Clients without support may not handle this well though.
Another option if you just need to send from the server to the client, is that you could send a framebufferUpdate within the viewport with a special marker and then immediately send a framebufferUpdate (even in the same packet) with the real visible data to replace it. This would work with existing clients (a bit more overhead). Clients might see brief flicker though.

Virtual Printer Driver for Windows

can you please help me with the following questions...
If I need a virtual printer that will convert a PostScript stream to a different format, do I have to implement a virtual printer from scratch or implement a rendering plug-in?
The rendering plug-in seems to support only certain customizations. Also the data invariably goes to the spooler which is not needed in this case.
If I implement a virtual printer driver does it completely replace the Microsoft PostScript Driver or the Microsoft Universal Driver?
Since my driver is virtual, does it matter if I write a PostScript compliant or a Universal Driver compliant one?
Any other method to convert a printed document to a custom document format apart from implementing a virtual printer driver? Can I hook on as a port monitor or something? From what I could understand I guess not.
What you need is a port monitor. You can create a virtual printer using the Microsoft Postscript driver found in the WDK. You don't need to provide any code for this part, just an INF and PPD file to describe your virtual printer. Once you have that working and installed, users will then see your virtual printer when they print from an app. This printer will produce a stream of Postscript like any standard Postscript printer, which will then be sent to the printer's port monitor.
Now add a port monitor to handle converting the Postscript stream to whatever format you need. Port monitors are considerably easier to deal with than print drivers.
EDIT: Andy points out in the comments that v4 (ie, Win8) print drivers don't support custom port monitors. However, v3 drivers will still work in Win8.
I know this is old, but these answers would have helped me a couple months ago, when I started this project. I spent a lot of time creating a port monitor, only to find a much easier method in the end (see WritePrinter link below).
If I need a virtual printer that will convert a PostScript stream to a
different format, do I have to implement a virtual printer from
scratch or implement a rendering plug-in?
Rendering plug-in is what you want.
The rendering plug-in seems to support only certain customizations.
Correct -- you'll have to decide if it is enough for you.
Also the data invariably goes to the spooler which is not needed in
this case.
This should not be an issue.
If I implement a virtual printer driver does it completely replace the
Microsoft PostScript Driver or the Microsoft Universal Driver?
If you implement a rendering plug-in, it does not replace the PS/Uni drivers. The PS/Uni drivers are in fact used by a huge number (maybe 90%?) of all "printer drivers". OEMs that make printers don't want to write their own drivers, so they use the PS/Uni driver design -- some create UI plug-ins, some rendering plug-ins, some both, some neither.
Since my driver is virtual, does it matter if I write a PostScript
compliant or a Universal Driver compliant one?
It depends what format you want the data in. If you want bitmap format, a Uni driver is better, if you want PostScript format, PS is better. If you want data for each line drawn, text out, and other GDI operations, then either is fine.
Any other method to convert a printed document to a custom document
format apart from implementing a virtual printer driver? Can I hook on
as a port monitor or something? From what I could understand I guess
not.
Most people that want raw access to the PostScript data, usually to use GhostScript to convert to PDF or other format, use a port monitor to do this. For example, the Virtual PDF Printer that Adobe ships with the full version of Acrobat (Writer), uses a port monitor, and also a rendering plug-in and a UI plug-in, for the PSCRIPT5 driver.
The problem with a port monitor is that it doesn't run in the context of the user -- not in the context of the application/process doing the printing. It runs in the context of the print spooler, and requires a lot of hacks to figure out which user/session is doing the printing.
If you want bitmap data, to save as a JPG/BMP/PNG, for example, then just create a rendering plug-in for the universal printer driver and access/save the bitmap data inside IPrintOemUni::FilterGraphics.
If you want PostScript data, to use with GhostScript (or other library, or your own code) to convert to PDF or other formats, then just create a rendering plug-in for the PSCRIPT5 driver and access/save the PS data inside IPrintOemUni2::WritePrinter.
In either case, you want a rendering plug-in. If you want to easily display a UI while printing, and want your code to run in the same context as the user, and not the spooler service, then make sure you set your printer to print directly to printer -- bypass the spooler. If you use AddPrinter to install your printer, you would use the PRINTER_ATTRIBUTE_DIRECT flag.
Not sure I fully understand. You have an app that produces Postscript and you want to convert that to something else? If the application outputs the 'print ready' data then a new printer driver isn't going to help as the 'queue/driver' is just a way to get the data to the printer and not something that is creating the output file.
You might be best to look at something like: Redmon
This can take the output and spawn an new process. The idea would be that you have it output the Postscript to a file and then you launch some console .exe that you create against it.
Just a thought.
Again not sure which way round you are doing this, but ghostscript is the simplest way to convert a PS output into any other format. It's also pretty easy to write your own output format for ghostscript.
This all happens at the app level - no need to write a driver.

How do I send an ARP packet from a C program?

I'm working on an embedded linux system in C, I'm looking for the source code to the equivalet of SendARP in Windows. Any pointers?
Take a look at arping. The quick and dirty way of sending an arp would be to do:
foo = system("/somepath/arping somehost");
But a look through the arping source should be able to give you a better solution.
For the all-out solution though, you can construct your own by hand and use either a raw socket or libpcap to send it.
btw. If all you're trying to do is force an arp to be sent (but necessarily from you) you could achieve that by deleting any arp entry that you already have for your host. The next access to that address will require an arp to be sent.
eg. /usr/sbin/arp -d destination_host_ip
This may be of interest: http://cvs.linux-ha.org/viewcvs/viewcvs.cgi/linux-ha/resources/heartbeat/SendArp.in?rev=1.4
It is an implmenetation in a Bourne Shell script.
I've never seen anything specifically for ARP, but I think you can send any kind of packet you want using libpcap and the appropriate RFCs.

Resources