Printer's SetPort function is not working

Dear All,

I am working on a Language monitor on windows xp.
I want to display custom port status messages in the spooler window
using SetPort function.
The problem is that when I use SetPort function with “Port_Info_3”
structure I am not able to get the customized messages.

For Example:

ZeroMemory(&PortInfo3, sizeof(PortInfo3));

PortInfo3.dwStatus = 0;

PortInfo3.pszStatus = L"TEST_STATUS";

PortInfo3.dwSeverity = PORT_STATUS_TYPE_WARNING;

SetPort(NULL,pIniPort->pszPortName,3,(LPBYTE)&PortInfo3);

When I searched in the net I found that it is a Microsoft bug with
SetPort function and it won’t work for customized status messages.
If so, Could anyone tell me if there is any alternate solution for
displaying customized messages?

If some one can help me in this regard, it would be of great help to me.

Thanks in advance.

Regards,

Karunya Lakshmi.M

On 27/11/06, xxxxx@wipro.com wrote:
> When I searched in the net I found that it is a Microsoft bug with SetPort
> function and it won’t work for customized status messages.
> If so, Could anyone tell me if there is any alternate solution for
> displaying customized messages?

I also found that SetPort() failed to allow custom status text in
W2K/XP. However, SetJob() does work to display job-specific text in
the Status column in the print queue. Perhaps using SetPort with
PORT_STATUS_USER_INTERVENTION together with SetJob for your custom
text will give you close to what you need?

Best regards,

Si

Hi Si,
Thanks for your reply. I tried using SetJob() with JOB_INFO_2
structure to display the windows defined status, but that is also not
getting displayed. I am attaching the code here

DWORD dwNeeded, dwReturned, i;
JOB_INFO_2 *pJobInfo;
DWORD *pStatus;
int nJobId = 0;

// First you call EnumJobs() to find out how much memory you need
if( ! EnumJobs( pIniPort->pIniJob->hPrinter, 0, 0xFFFFFFFF, 1, NULL,
0, &dwNeeded, &dwReturned ) )
{
// It should have failed, but if it failed for any reason other
// than “not enough memory”, you should bail out
if( GetLastError() != ERROR_INSUFFICIENT_BUFFER )
{
ClosePrinter( pIniPort->pIniJob->hPrinter);
return FALSE;
}
}
// Allocate enough memory for the JOB_INFO_2 structures plus
// the extra data - dwNeeded from the previous call tells you
// the total size needed
if( (pJobInfo = (JOB_INFO_2 *)malloc( dwNeeded )) == NULL )
{
ClosePrinter( pIniPort->pIniJob->hPrinter );
return FALSE;
}

ZeroMemory(pJobInfo, dwNeeded);

// Call EnumJobs() again and let it fill out our structures
if( ! EnumJobs( pIniPort->pIniJob->hPrinter, 0, 0xFFFFFFFF, 1,
(LPBYTE) pJobInfo, dwNeeded, &dwNeeded, &dwReturned ) )
{
ClosePrinter( pIniPort->pIniJob->hPrinter );
free( pJobInfo );
pJobInfo=NULL;
return FALSE;
}
// You’re done with the printer handle, close it
ClosePrinter( pIniPort->pIniJob->hPrinter );

// dwReturned tells how many jobs there are
// Here, you’ll simply display the number of jobs found
printf( “%d jobs\n”, dwReturned );
// It’s easy to loop through the jobs and access each one

pJobInfo->Status = JOB_STATUS_PAPEROUT;

if ( !SetJob(pIniPort->pIniJob->hPrinter, nJobId, 2,
(LPBYTE)&pJobInfo, 0) )
{
DBGMSG(DBG_WARNING,
(“pjlmon: SetJob failed %d (LE: %d)\n”,
pIniPort->PrinterStatus, GetLastError()));
}

Please help me in this regard. Thanks in advance.

Regards,
Karunya Lakshmi.M

-----Original Message-----
From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com] On Behalf Of Simon Owen
Sent: Saturday, December 02, 2006 7:57 AM
To: Windows System Software Devs Interest List
Subject: Re: [ntdev] Printer’s SetPort function is not working

On 27/11/06, xxxxx@wipro.com
wrote:
> When I searched in the net I found that it is a Microsoft bug with
SetPort
> function and it won’t work for customized status messages.
> If so, Could anyone tell me if there is any alternate solution for
> displaying customized messages?

I also found that SetPort() failed to allow custom status text in
W2K/XP. However, SetJob() does work to display job-specific text in
the Status column in the print queue. Perhaps using SetPort with
PORT_STATUS_USER_INTERVENTION together with SetJob for your custom
text will give you close to what you need?

Best regards,

Si


Questions? First check the Kernel Driver FAQ at
http://www.osronline.com/article.cfm?id=256

To unsubscribe, visit the List Server section of OSR Online at
http://www.osronline.com/page.cfm?name=ListServer

On 05/12/06, xxxxx@wipro.com
> I tried using SetJob() with JOB_INFO_2 structure to display the windows
> defined status, but that is also not getting displayed.

I used a mixture of SetPort and SetJob calls for my own monitor. For
port-level conditions such as Paper Out I use SetPort, which is shown
in the queue caption and under the printer icons for those connected
to the same port. For a job-level error such as corrupt document data
I use SetJob to set specific error text just for that job - slightly
different from your setting a job error code.

To set the job-level text I was using something like:

DWORD dwNeeded = 0;
GetJob(hPrinter, dwJobId, 1, NULL, 0, &dwNeeded);

PBYTE pb = (PBYTE)malloc(dwNeeded);

if (GetJob(hPrinter, dwJobId, 1, pb, dwNeeded, &dwNeeded))
{
PJOB_INFO_1 pji = (PJOB_INFO_1)pb;
pji->Position = JOB_POSITION_UNSPECIFIED;
pji->pStatus = “My new status text”;

SetJob(hPrinter, dwJobId, 1, pb, 0);
}

If you need to set custom text then job-level is your only option. Any use?

Best regards,

Si

Thanks for the reply.
I have tried the code that you have given, but can I know where the
custom status “My new status text” will get displayed. Will it get
displayed in the status queue?

-----Original Message-----
From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com] On Behalf Of Simon Owen
Sent: Tuesday, December 05, 2006 6:28 PM
To: Windows System Software Devs Interest List
Subject: Re: [ntdev] Printer’s SetPort function is not working

On 05/12/06, xxxxx@wipro.com
> I tried using SetJob() with JOB_INFO_2 structure to display the
windows
> defined status, but that is also not getting displayed.

I used a mixture of SetPort and SetJob calls for my own monitor. For
port-level conditions such as Paper Out I use SetPort, which is shown
in the queue caption and under the printer icons for those connected
to the same port. For a job-level error such as corrupt document data
I use SetJob to set specific error text just for that job - slightly
different from your setting a job error code.

To set the job-level text I was using something like:

DWORD dwNeeded = 0;
GetJob(hPrinter, dwJobId, 1, NULL, 0, &dwNeeded);

PBYTE pb = (PBYTE)malloc(dwNeeded);

if (GetJob(hPrinter, dwJobId, 1, pb, dwNeeded, &dwNeeded))
{
PJOB_INFO_1 pji = (PJOB_INFO_1)pb;
pji->Position = JOB_POSITION_UNSPECIFIED;
pji->pStatus = “My new status text”;

SetJob(hPrinter, dwJobId, 1, pb, 0);
}

If you need to set custom text then job-level is your only option. Any
use?

Best regards,

Si


Questions? First check the Kernel Driver FAQ at
http://www.osronline.com/article.cfm?id=256

To unsubscribe, visit the List Server section of OSR Online at
http://www.osronline.com/page.cfm?name=ListServer

Problem in your posted code noted below:


DWORD dwNeeded, dwReturned, i;
JOB_INFO_2 *pJobInfo;
DWORD *pStatus;
int nJobId = 0;

// First you call EnumJobs() to find out how much memory you need
if( ! EnumJobs( pIniPort->pIniJob->hPrinter, 0, 0xFFFFFFFF, 1, NULL,
0, &dwNeeded, &dwReturned ) )
{
// It should have failed, but if it failed for any reason other
// than “not enough memory”, you should bail out
if( GetLastError() != ERROR_INSUFFICIENT_BUFFER )
{
ClosePrinter( pIniPort->pIniJob->hPrinter);
return FALSE;
}
}
// Allocate enough memory for the JOB_INFO_2 structures plus
// the extra data - dwNeeded from the previous call tells you
// the total size needed
if( (pJobInfo = (JOB_INFO_2 *)malloc( dwNeeded )) == NULL )
{
ClosePrinter( pIniPort->pIniJob->hPrinter );
return FALSE;
}

ZeroMemory(pJobInfo, dwNeeded);

// Call EnumJobs() again and let it fill out our structures
if( ! EnumJobs( pIniPort->pIniJob->hPrinter, 0, 0xFFFFFFFF, 1,
(LPBYTE) pJobInfo, dwNeeded, &dwNeeded, &dwReturned ) )
{
ClosePrinter( pIniPort->pIniJob->hPrinter );
free( pJobInfo );
pJobInfo=NULL;
return FALSE;
}
// You’re done with the printer handle, close it
ClosePrinter( pIniPort->pIniJob->hPrinter );

OK, so you just closed the handle to the printer…

// dwReturned tells how many jobs there are
// Here, you’ll simply display the number of jobs found
printf( “%d jobs\n”, dwReturned );
// It’s easy to loop through the jobs and access each one

pJobInfo->Status = JOB_STATUS_PAPEROUT;

Next you try to use the handle you’ve already closed to set the job status.
It will definitely fail.


if ( !SetJob(pIniPort->pIniJob->hPrinter, nJobId, 2,
(LPBYTE)&pJobInfo, 0) )
{
DBGMSG(DBG_WARNING,
(“pjlmon: SetJob failed %d (LE: %d)\n”,
pIniPort->PrinterStatus, GetLastError()));
}

Most likely this is the problem you’ve alluded to.

On 05/12/06, xxxxx@wipro.com wrote:
> I have tried the code that you have given, but can I know where the
> custom status “My new status text” will get displayed. Will it get
> displayed in the status queue?

It’s appended to the normal text shown in the Status column of the
print queue, under XP at least. So it would show as “Printing - My
new status text” if you modified an active job. You can also pause
the job or set an error condition, and it will still be appended for
extra status text.

Best regards,

Si

Thanks a lot. Its working now.

Regards,
Karunya

-----Original Message-----
From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com] On Behalf Of Simon Owen
Sent: Tuesday, December 05, 2006 11:53 PM
To: Windows System Software Devs Interest List
Subject: Re: [ntdev] Printer’s SetPort function is not working

On 05/12/06, xxxxx@wipro.com
wrote:
> I have tried the code that you have given, but can I know where the
> custom status “My new status text” will get displayed. Will it get
> displayed in the status queue?

It’s appended to the normal text shown in the Status column of the
print queue, under XP at least. So it would show as “Printing - My
new status text” if you modified an active job. You can also pause
the job or set an error condition, and it will still be appended for
extra status text.

Best regards,

Si


Questions? First check the Kernel Driver FAQ at
http://www.osronline.com/article.cfm?id=256

To unsubscribe, visit the List Server section of OSR Online at
http://www.osronline.com/page.cfm?name=ListServer