Get file name when printing - windows

Is there a way to detect the file name of a file when a user prints from any application, somwhere in the printer events? I am looking for a windows api where I can determine what file is being printed.

Print jibs are opened with names but typically this doesn't mean the filename - the names which are displayed in the print queue are accessible by querying the printer driver directly I believe.

The printer driver does not have any external API for finding the filename. I assume you would be looking at creating some kind of systray agent sort of app that would be monitoring print queues for jobs being sent. If so -
Refer to http://support.microsoft.com/kb/196805 for a microsoft tool that allows you to monitor print queues for print job status
Refer to http://msdn.microsoft.com/en-us/library/ff562742%28v=vs.85%29.aspx which explains how Windows supports printer change notifications. You can create an app that registers for this and get handle to the Print Queue. Once you get a handle you can call the GetPrinter and GetJob APIs to get access to the JOB_INFO_2 structure. The pDocumentName in the JOB_INFO_2 structure is the name of the file
Hope this helps. If so, please vote a +1 :)

No, there is not, at least not reliably. Keep in mind that there may not be a file name at all. For example, I could open an application like notepad, type some stuff, and print. What file am I printing? None.
In the above scenario most applications will provide some sort of default file name like "untitled", and sometimes you can find that name by parsing the print job's name. For example, if you call GetJob, the JOB_INFO_1 struct's pDocument member will contain a pointer to the print job's name, and that name will often contain the file name.
However, every application formats it differently, and some don't provide it at all. So the answer is you can find the file name perhaps 75% of the time with a lot of effort, but there simply is no 100% solution.

Related

Applescript to read notifications to the Apps in Dock

I want to be able to have a script which can detects if I have new messages in my messaging apps.. Slack, lync,.
Is it possible to use applescript to read if there is any active notification on the apps in the Dock..
If you do:
`getconf DARWIN_USER_DIR`/com.apple.notificationcenter/db
(which line I found at Ask Different), you'll get returned:
/var/folders/_d/pg2g_[some_funny_numbers]/0//com.apple.notificationcenter/db: is a directory
Inside this/my folder I found:
db db-shm db-wal db2upgraded
When some action happens (I sent a notification) only db-wal gets updated (nearly) at once.
So, in principle it should be possible to write an AS (saved as Stay Open app) that periodically looks if "db-wal" has changed (comparing saved sizes or change dates) and, ONLY if so, searches it for some keywords (Slack, lync,…) again comparing # of occurrences, thus learning if s.th. new has arrived. Admittedly sounds awkward but could work.
It would be much more elegant to use a folder script, but as no file is moved nor a folder opened/closed such a script can not be invoked.

Store parsable backup of all printed documents

What I'm trying to accomplish is to always keep a parsable duplicate of all printed documents, and execute a secondary process for each print.
(i.e.: Be able to parse all text, account for pages, vectors, images, etc).
Processing the document can either be done immediately or deferred (immediately is desirable).
As formats go, any PDL might be suitable, my best guess is XPS would probably be the best bet for a parsable format, any recommendations for other formats are appreciated.
Ideally, I'd like to not mess with the user interaction with the printing (e.g.: print settings page; or create a virtual printer, which could save a XPS and then forward the print job to the physical printer).
Since users might not be tech savvy to either set up/use it properly and/or mess up the process at a later date.
What I'm looking for at this time:
Documentation on the print process and flow (WDK, PDL, what else?)
How this could be accomplished, if at all possible; are there any existing solutions?
Any directions into what I should be looking at.
It's only part of an answer, but rumor has it you can tell Windows to keep spooled documents (right-click the printer, choose "Printer Properties", Advanced, "Keep Printed Documents").
You could enable this, and then create a scheduled task (or system service, etc.) that watches the spool directory and moves all files older than a certain threshold to a more appropriate location for further processing. (The age threshold would be a reasonable way to avoid trying to move files that are currently being written.)
Then you'd have to find a program to convert the .spl files to whatever format you like, or try interpreting it yourself. It looks pretty low-level but Microsoft does offer some documentation about the MS-EMF and MS-EMFSPOOL formats that might be a start.

Find what file a short lived HANDLE is associated with

I am playing around with the demo of IDA and I am trying to do some reverse engineering of a program to figure out the structure of one of its files that it uses. My final goal is to be able to read that file directly from my own program.
Using Process Monitor I was able to find the subroutine that calls kernel32_ReadFile. What I would like to know is how do I find out what the hFile variable is pointing to before it makes the call to ReadFile
I have been exploring around the menus while in debug mode and I have not found anywhere inside IDA where I can look up information about what file is associated with a file handle.
How do I map a handle to a real file?
This MSDN page describes ways to get the file name from a file handle:
http://msdn.microsoft.com/en-us/library/windows/desktop/aa366789(v=vs.85).aspx
Is that the information you were looking for? I'm not sure why you can't see the the file name directly in Process Monitor.
I would set a breakpoint on CreateFileA and CreateFileW and see what files are being opened. You can then match the returned HANDLE value to the subsequent ReadFile call.

How to uniquely identify a process on windows?

Let's take for example notepad. How can I in my application be 100% sure whether notepad is running or not?
By 100% I mean, if there is another process whose name is "notepad.exe" which in fact is not a real notepad but for example an imitation, I don't want to detect it. Only real notepads.
I've already thought about reading the process memory but it's more difficult than it appears to be, because of memory displacements etc.
The standard way is by name, right? But for me it is really important, that it is not any other program since I want to interact with it what would critical fail if I found a wrong process.
Does anyone know a good way of doing this?
PS: There is no specific programming language to do it in. If possible I would prefer an indipendent solution. But if required, I specifically use .Net/C#.
The only way to be 99.9%1 sure you're looking at the right executable is to validate the file's digital signature. For example, you'd ensure that the notepad.exe in question was signed by "Microsoft Corporation".
I'd do something like this:
Get the list of running processes.
Filter down to name of interest (notepad.exe)
Get each process' image [executable] path.
Validate that the Authenticode signature is valid and trusted.
Compare the name of the signer to the expected value.
Success! You can be very certain this is the correct file.
This method avoids issues like having to know ahead of time where the file should be located (which is nearly impossible – Notepad is installed in two locations), what its hash value should be (obviously bound to change), or strange user behavior (replacing Notepad with some other text editor).
1 - of course, it's impossible to be 100% sure. Someone really determined could self-sign an executable with the expected signer name and add the certificate to their machine's root store, causing the signature to appear valid.
Well, I haven't been confronted to that kind of problem, but you can first check if the process is running by searching by name (in your case, that would be notepad.exe), parse the Process.GetProcesses() list for that, then get
Process.StartInfo.FileName
and see if this is the path to the Notepad executable, that would do the deal, right ?
What exactly do you know of the executable we want to be running? If you knew the filesize that could work as a "hack". Use #josh3736 's method, but replace point 4 and 5 by comparing the filesize with the one you know [different versions will have different sizes, but if there are not too many you can hardcode them]. Calculation a Md5-Hashtag would look more professional, but would do basicly the same thing.
**
If your process has a GUI: you could use EnumWindows for the children to get Edit-Boxes etc. Find something destinctive for your "notepad.exe" and check if it's there.

Verify whether ftp is complete or not?

I got an application which is polling on a folder continuously. Once any file is ftp to the folder, the application has to move this file to some other folder for processing.
Here, we don't have any option to verify whether ftp is complete or not.
One command "lsof" is suggested in the technical forums. It got a file description column which gives the file status.
Since, this is a free bsd command and not present in old versions of linux, I want to clarify the usage of this command.
Can you guys tell us your experience in file verification and is there any other alternative solution available?
Also, is there any risk in using this utility?
Appreciate your help in advance.
Thanks,
Mathew Liju
We've done this before in a number of different ways.
Method one:
If you can control the process sending the files, have it send the file itself followed by a sentinel file. For example, send the real file "contracts.doc" followed by a one-byte "contracts.doc.sentinel".
Then have your listener process watch out for the sentinel files. When one of them is created, you should process the equivalent data file, then delete both.
Any data file that's more than a day old and doesn't have a corresponding sentinel file, get rid of it - it was a failed transmission.
Method two:
Keep an eye on the files themselves (specifically the last modification date/time). Only process files whose modification time is more than N minutes in the past. That increases the latency of processing the files but you can usually be certain that, if a file hasn't been written to in five minutes (for example), it's done.
Conclusion:
Both those methods have been used by us successfully in the past. I prefer the first but we had to use the second one once when we were not allowed to change the process sending the files.
The advantage of the first one is that you know the file is ready when the sentinel file appears. With both lsof (I'm assuming you're treating files that aren't open by any process as ready for processing) and the timestamps, it's possible that the FTP crashed in the middle and you may be processing half a file.
There are normally three approaches to this sort of problem.
providing a signal file so that when your file is transferred, an additional file is sent to mark that transfer is complete
add an entry to a log file within that directory to indicate a transfer is complete (this really only works if you have a single peer updating the directory, to avoid concurrency issues)
parsing the file to determine completeness. e.g. does the file start with a length field, or is it obviously incomplete ? e.g. parsing an incomplete XML file will result in a parse error due to the lack of an end element. Depending on your file's size and format, this can be trivial, or can be very time-consuming.
lsof would possibly be an option, although you've identified your Linux portability issue. If you use this, note the -F option, which formats the output suitable for processing by other programs, rather than being human-readable.
EDIT: Pax identified a fourth (!) method I'd forgotten - using the fact that the timestamp of the file hasn't updated in some time.
There is a fifth method. You can also check if the FTP Session is still active. This will work if every peer has it's own ftp user account. As long as the user is not logged off from FTP, assume the files are not complete.

Resources