Hi all,

I'm fairly new to programming as a whole and so I would be grateful if you can help me out.

I'm trying to write a program in VC++ or C++ that would intercept print jobs from another program and save this information in another file(to be formatted later). My idea was to read all the data being sent to LPT1 and save it in a text file.

I've tried writing a program which, according to my limited programming experience, should work(but doesn't). I just ran the program while printing from another text file and the program didn't do anything. It just ran forever.

Can any of you please help me locate and perhaps correct the faults in my program? I'd be very grateful for any help whatsoever.

Below is my code. Thanks.

void main(void)
{

DWORD rread=0, written=0;

//create a handle to LPT1
HANDLE handle = CreateFile( L"LPT1", GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL, NULL);

//Check if handle was created
if (handle == INVALID_HANDLE_VALUE)
{
cout << "Invalid handle" << endl;
}

//open file to store data read from LPT1 to
ofstream file_op("D:\\myStreamBuffer.txt", ios:ut);


//Read data(exactly 8.192 bytes) from LPT1 (I specified 8.192 because I know how big the file to be printed is)
ReadFile(handle, file_op, 8.192, &rread, NULL);

//close the file. (I suspect this could potentially be the source of the //problem. perhaps I have to do a special command in order for //what was read to be stored into the file?)
file_op.close();

//close handle to LPT1
CloseHandle(handle);


}

I did a few tests and noticed that the program gets stuck on the following line

ReadFile(handle, file_op, 8.192, &rread, NULL);

LPT1 is a device, you are unable to open it to read what someone else has written (or will write) to it, it just doesn't work that way.

To do what you are proposing, you would need to somehow 'get between' the other application and the output device. You could then log the characters the other application sends and forward them to the device.

LPT1 is a device, you are unable to open it to read what someone else has written (or will write) to it, it just doesn't work that way.

Ok, thanks, so I have to stop trying what I've been trying to do so far.

To do what you are proposing, you would need to somehow 'get between' the other application and the output device. You could then log the characters the other application sends and forward them to the device.

Do you have any suggestions on how I could do this? or at least point me in a direction which I could look further into myself? Any help would be very appreciated. Thanks.

There are several possibilities for 'getting between'.

In the end, you will end up providing an interface to the program that must act as it expects the 'LPT' to act.

To better understand the problem:

Does the program think that a printer is attached to the LPT or is it some other device?

What Operating System does the program run under?

Does the program have any configuration to select the LPT or printer?

I doubt this is an option, but is it possible for you to modify and re-build the program?

The source code you included appears to be for Windows. Almost all Windows applications allow you to select the printer to print to.

The stream of bytes that Windows sends to the printer very rarely reflects the characters that are being printed. For example, if you put "Hello, World" in notepad and print it, the resulting byte stream to the printer will far exceed the 12 characters you typed.

Are you trying to catch the byte-stream or the characters?

Hello Murtan, I'd like first of all to thank you for your co-operation. I really appreciate it. Now on to your questions.


Does the program think that a printer is attached to the LPT or is it some other device?

I'm not too sure, but I think the program does think a printer is attached to the LPT. It might seem weird that I say "I think", but the thing is, I'm supposed to do this for an internship and I haven't seen the program myself. My boss just asked me to write a program that would intercept information going to LPT1 and store it somewhere else, in, say, an xml file. He also seems to be intentionally vague about this.

What Operating System does the program run under?

The program runs under windows. He did mention that it was running on Dosbox.

Does the program have any configuration to select the LPT or printer?

I don't think so, but I could try to find out later, though he isn't around.

I doubt this is an option, but is it possible for you to modify and re-build the program?

No, this is not possible.

The stream of bytes that Windows sends to the printer very rarely reflects the characters that are being printed. For example, if you put "Hello, World" in notepad and print it, the resulting byte stream to the printer will far exceed the 12 characters you typed.

I'd imagine though, that that stream of bytes would also contain the information(say the characters) being printed, right? Such that if one could get the stream of bytes, then theoretically, one could get the information being printed, right?

Are you trying to catch the byte-stream or the characters?

Optimally, I'd like to catch the characters but at this point, I'd be more than ecstatic if I could get just the byte-stream.

Thanks once again for your co-operation thus far.

If the program you are trying to intercept is a DOSBOX program (which I read to mean a program written before windows, but that will be run under windows) that does help clarify what you will need to do.

Because it is a DOSBOX program, it probably will just send the characters to the printer. There may be few control codes mixed in, but it should be fairly easy to filter them.

There were a couple of DOS TSR based programs that would intercept calls to the printer and direct them to a file (See for example PRN2FILE, source code if you can find it)

These programs no-longer work under the modern windows interaface as they worked using a DOS concept calls TSR (Terminate Stay Resident) which allowed them to remain in memory to handle the calls, but that is no-longer available with Windows.

Can you have your program 'launch' or 'start' the other program?

If so, you might be able to 'pre-setup' its runtime environment such that when it goes to print, your 'wrapper' program gets the data instead. I know that being the 'launcher' of an application can give you additional rights releated to the application when it runs.

I am unfortunately 'stuck' at this point as I can't find a resource to direct you to for more information, but don't have any more time to spend right now either.


There were a couple of DOS TSR based programs that would intercept calls to the printer and direct them to a file (See for example PRN2FILE, source code if you can find it)

Unfortunately, I could only find the ASM source of PRN2FILE and have no idea how to go about using that to implement something similar in c++. Thanks for this suggestion though. In the worst case, I could just use PRN2FILE instead of doing everything by myself.

These programs no-longer work under the modern windows interaface as they worked using a DOS concept calls TSR (Terminate Stay Resident) which allowed them to remain in memory to handle the calls, but that is no-longer available with Windows.

Oh wait, do you mean PRN2FILE wouldn't work in windows anymore? I hope not.

Can you have your program 'launch' or 'start' the other program?

I should be able to do this, considering that my boss claims to have the exe.

If so, you might be able to 'pre-setup' its runtime environment such that when it goes to print, your 'wrapper' program gets the data instead. I know that being the 'launcher' of an application can give you additional rights releated to the application when it runs.

This sounds very interesting and I'd really like to look more into this possibility.

I am unfortunately 'stuck' at this point as I can't find a resource to direct you to for more information, but don't have any more time to spend right now either.

Quite frankly, you've been of a lot of help already, and I appreciate it a lot. By "don't have any more time to spend right now either.", did you mean generally, or just on the day when you wrote this? If you meant just on that day, then I'd be more than grateful, if you could tell me generally(and if I'm lucky, even specifically) how I would go about with your idea above of pre-setting the runtime enviroment. If you meant you don't have time anymore to look into this, then I completely understand and you can disregard my last request.

Best regards.

Hi Murtan and to anyone who might be interested,

just wanted to mention, that after your help and lots of help from 2 other posters on another forum, I've been able to find a workaround this problem.

By mapping lpt1 to a text file, everything the dos program prints is redirected to the text file. What I'll do now is make my program just monitor that text file for changes and whenever there is a change in the file(i.e the dos program has printed to the file), my program will read in what was printed, parse it to the required format and print it out.

Thanks once again for all your help... now I'm off to implementing the parsing.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.