I want to check if a printer is ready, otherwise I don't want to load a printer program I won't need.
; This should work, but Lexmark pops up a box saying it can't communicate with the printer.
; The MessageBox never even makes an appearance even though eax is less than 32.
;
; If the function fails, the return value is an error value that is less than or equal to 32.
; The following table lists these error values:
.386
include \masm32\include\masm32rt.inc
.code
start:
fn ShellExecute,0,"print","test.txt",NULL,NULL,NULL
invoke ExitProcess,NULL
.if eax <= 32
fn MessageBox,0,str$(eax),"Title",MB_OK
.else
.endif
end start
OpenPrinter
GetPrinter (PRINTER_INFO_6)
ClosePrinter
This is what I have come up with, but not working.
I also had to deal with an unauthorized intruder masquerading as a a system file except with a v appended to the end.
Ich weiß, wer es war, und ich kann eine Kanone zu verwenden. l.o.i.c.
; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
include \masm32\include\masm32rt.inc
include \masm32\include\winspool.inc
includelib \masm32\lib\winspool.lib
; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
.data
hPrinter dd 0
cbBuffer dd 0
.data?
P_Handle dd ?
.code
start:
; printer name buffer and size of name buffer
invoke GetDefaultPrinter, NULL, ADDR cbBuffer
;print str$(eax),13,10
;print str$(cbBuffer),13,10
mov ebx, alloc(cbBuffer)
invoke GetDefaultPrinter, ebx, ADDR cbBuffer
;print str$(eax),13,10
;print ebx,13,10
invoke OpenPrinter, ebx, ADDR hPrinter, NULL ; name, handle, and pointer to printer defaults structure
mov P_Handle,eax ; store handle
invoke GetPrinter,P_Handle,6,ADDR hPrinter,sizeof hPrinter,NULL
;int 3
.if eax == 0 ; process failed
fn MessageBox,0,str$(eax),"Title",MB_OK
.endif
invoke ClosePrinter, hPrinter
free ebx
invoke ExitProcess,0
end start
that's a bit confusing :P
hPrinter would normally refer to a printer handle
phPrinter would be the address of that handle variable (pointer to a handle)
pPrinter, in the case of (6), is a pointer to a PRINTER_INFO_6 structure, which has a size of 1 dword
when you call GetDefaultPrinter, you should test for a return value of zero
it may be that there is no default printer
once you have the default printer string (let's say the address is in EBX)
INVOKE OpenPrinter,ebx,addr hPrinter,NULL
that looks like what you have
the value returned in EAX by OpenPrinter will be zero or non-zero, indicating failure or success
it will not be the handle
the handle will be stored in the hPrinter dword variable
now, the PRINTER_INFO_6 structure is not defined in our current windows.inc
that's ok - it's a dword - let's call it dwPrnStatus
we also need a dword variable for the function to return the number of bytes stored
dwPrnStatus dd ?
dwPrnBytes dd ?
INVOKE GetPrinter,hPrinter,6,addr dwPrnStatus,sizeof dwPrnStatus,addr dwPrnBytes
when you are done, close the handle
INVOKE ClosePrinter,hPrinter
of course, you could put the function in a PROC,
and declare the hPrinter, dwPrnStatus, and dwPrnBytes variables as LOCAL
the function could return -1 or something if failure,
or the status if success, in EAX
You are a good person, but I am thinking of jumping on a sword.
:t
Quote...but I am thinking of jumping on a sword.
as in signed word ? :P
Thanks Dave.
GetPrinter is returning 0 in EAX whether printer is hooked up or not ?
Do I need to send it a print job and look for failure ?
Andy
; dedndave
;
;
include \masm32\include\masm32rt.inc
include \masm32\include\winspool.inc
includelib \masm32\lib\winspool.lib
.data
hPrinter dd 0
cbBuffer dd 0
.data?
dwPrnStatus dd ?
dwPrnBytes dd ?
.code
start:
invoke GetDefaultPrinter, NULL, ADDR cbBuffer
; you should test for a return value of zero it may be that there is no default printer
mov ebx, alloc(cbBuffer)
invoke OpenPrinter, ebx, ADDR hPrinter, NULL
; the value returned in EAX by OpenPrinter will be zero or non-zero, indicating failure or success
; it will not be the handle
; the handle will be stored in the hPrinter dword variable
INVOKE GetPrinter,hPrinter,6,addr dwPrnStatus,sizeof dwPrnStatus,addr dwPrnBytes
;If the function fails, the return value is zero.
invoke ClosePrinter, hPrinter
free ebx
invoke ExitProcess,0
end start
in the previous code, you used a different method to get the default printer string
you made the first call to GetDefaultPrinter, with a buffer length of 0
that call returns a value that tells you how big of a buffer you need
then, you allocated the buffer and made the second call with the buffer size
in the newer version, you did not do that
so, when you call GetDefaultPrinter, there is no buffer and cbBuffer = 0
give me a little time - let me see what i come up with.....
see if this works.....
Ebx and eax are non-zero whether printer is on or off.
EBX isn't meant to have anything
EAX returned by GetPrnStatus is the one of interest
the bits are defined as 0 "if no flags"
so - 0 means you are not out of paper, not jammed, etc
unfortunately, i do not see a "ready" bit, similar to what we had in DOS days
but, there must be a way to determine if the printer is ready
I am going to look at maybe CreateFile and send the printer a print job.
Andy
Will this work ?
PRINTER_STATUS_OFFLINE The printer is offline.
that is one of the status bits returned by GetPrinter
it doesn't seem to do what we think - lol
that's probably because we are checking status through the print spooler
there has to be some simple way, without sending a job to the printer
perhaps we need to communicate with the device driver - not the spooler
Hey dave, I think this line is a problem
INVOKE GetPrinter,_hPrn,6,addr _dwPrnStatus,sizeof _dwPrnStatus,addr _cbPrnBytes
In my testing it fails and cbPrnBytes=8. Replacing sizeof _dwPrnStatus with 8 doesn't fail but I get a status of 02000000h.
All of the info I can find says the status values end at 01000000h. Maybe it's a new one for win8.
OK, when my other computer is off, I get that status, because it's a shared network printer. Makes sense, PRINTER_STATUS_SERVER_OFFLINE
Quote from: Win8 SDK winspool.h
#define PRINTER_STATUS_SERVER_UNKNOWN 0x00800000
#define PRINTER_STATUS_POWER_SAVE 0x01000000
#define PRINTER_STATUS_SERVER_OFFLINE 0x02000000
#define PRINTER_STATUS_DRIVER_UPDATE_NEEDED 0x04000000
Still not sure about PRINTER_INFO_6, it's still defined as a dword but needs 8 bytes.
hmmmm
a 64-bit OS, no doubt
i can't find anything on it with google
i figured the "ready" status is returned because the spooler is always ready :P
i wanted to make it UNICODE aware
made a few other changes, also
1) little better error handling in GetDefPrn routine
2) made room for 8 bytes in printer status, per Sinsi (GetPrnStatus routine)
that way, it should work in 32 or 64-bit environment
3) UNICODE aware
Didn't work.
I thought this worked the first thru Olly, but not later ?
I think it's one of those M.S. undocumented "Let's mess with the developer" APIs. a.k.a LMWTD
start:
; If the function succeeds, the return value is greater than zero.
invoke StartPage, _hpdc
.if EAX == ERROR_INVALID_HANDLE
;fn MessageBox,0,LastError$(),"Last Error Text",MB_OK
.else
.endif
final: