Home | Contact Us | FAQ | Search & Site Map | Link to Us
Sign In | Join | Other 45 Sites in Network
HomeAnnouncementsFree MagazinesWhite PapersSubmit Content
Discussion GroupsASP.NETWindows FormsLanguages.NET FrameworkVisual Studio.NET
Articles.NET FrameworkASP.NETToolsWindows Forms
.NET DirectoryOpen Source ProjectsUser GroupsWeb Resources
Related Topics
Visual Basic 6SQL ServerMS AccessOther DB ProductsMS Server ProductsMore Topics ...

.NET Forum / .NET Framework / Interop / June 2005

Tip: Looking for answers? Try searching our database.

P/Invoked OpenPrinter fails when opening network printer

Thread view: 
Enable EMail Alerts  Start New Thread
Thread rating: 
Marek - 29 Jun 2005 22:41 GMT
I have local printer connected to PC_1 (lpt/usb). It’s shared (no pwd, ACL
for printing is set to Everyone). I want to print data from PC_2, via
\\PC_1\<printerName>.

OpenPrinter and StartDocPrinter fail with GetLastError == 997
(ERROR_IO_PENDING  - Overlapped I/O operation is in progress). I’m able to
recreate this problem on following configurations :

PC_1 = NT 4.0
PC_2 = W2k3

PC_1 = WXP
PC_2 = W2k3

Everything works fine when printing on local printer or via print server
(that is direct to printer, not through PC_1).

I’m using C# and .NET 1.1. I didn’t try to recreate this from C++ yet.

Any suggestions? Thank you for any given answer...

Here is my code (simplified):

public class PrintDirect
{
[DllImport("winspool.drv", CharSet = CharSet.Unicode, ExactSpelling = false,
CallingConvention = CallingConvention.StdCall)]
public static extern int OpenPrinter(string pPrinterName, out IntPtr
phPrinter, IntPtr pDefault);
       
[DllImport("winspool.drv", CharSet = CharSet.Unicode, ExactSpelling = false,
CallingConvention = CallingConvention.StdCall)]
public static extern int StartDocPrinter(IntPtr hPrinter, int Level, ref
DOCINFO pDocInfo);

[DllImport("winspool.drv", CharSet = CharSet.Unicode, ExactSpelling = true,
CallingConvention = CallingConvention.StdCall)]
public static extern int StartPagePrinter(IntPtr hPrinter);

[DllImport("winspool.drv", CharSet = CharSet.Ansi, ExactSpelling = true,
CallingConvention = CallingConvention.StdCall)]
public static extern int WritePrinter(IntPtr hPrinter, IntPtr pBuf, int buf,
ref int pcWritten);

[DllImport("winspool.drv", CharSet = CharSet.Unicode, ExactSpelling = true,
CallingConvention = CallingConvention.StdCall)]
public static extern int EndPagePrinter(IntPtr hPrinter);

[DllImport("winspool.drv", CharSet = CharSet.Unicode, ExactSpelling = true,
CallingConvention = CallingConvention.StdCall)]
public static extern int EndDocPrinter(IntPtr hPrinter);
[DllImport("winspool.drv", CharSet = CharSet.Unicode, ExactSpelling = true,
CallingConvention = CallingConvention.StdCall)]
public static extern int ClosePrinter(IntPtr hPrinter);
}

[StructLayout(LayoutKind.Sequential)]
public struct DOCINFO
{
    [MarshalAs(UnmanagedType.LPWStr)] public string pDocName;
    [MarshalAs(UnmanagedType.LPWStr)] public string pOutputFile;
    [MarshalAs(UnmanagedType.LPWStr)] public string pDataType;
}

System.IntPtr lhPrinter = new System.IntPtr();
DOCINFO di = new DOCINFO();
int pcWritten = 0;
byte[] textBytes;



di.pDocName = "Etk";
di.pOutputFile = null;
di.pDataType = null;

PrintDirect.OpenPrinter(printerName, out lhPrinter, new System.IntPtr(0));
PrintDirect.StartDocPrinter(lhPrinter, 1, ref di);
PrintDirect.StartPagePrinter(lhPrinter);
IntPtr buf = Marshal.AllocCoTaskMem(textBytes.Length);
Marshal.Copy(textBytes, 0, buf, textBytes.Length);
PrintDirect.WritePrinter(lhPrinter, buf, textBytes.Length, ref pcWritten);
PrintDirect.EndPagePrinter(lhPrinter);
PrintDirect.EndDocPrinter(lhPrinter);
PrintDirect.ClosePrinter(lhPrinter);
Marshal.FreeCoTaskMem(buf);


Willy Denoyette [MVP] - 29 Jun 2005 23:35 GMT
Don't call SetLastError, the error code is probably wrong or inconsistent
when doing this, use GetLastWin32Error instead.
You also have to indicate that you need the win32 error code returned from
the API, so you have to place the SetLastError=true attribute in your
DllImport declarartion.

Willy.

>I have local printer connected to PC_1 (lpt/usb). It’s shared (no pwd,
>ACL
[quoted text clipped - 92 lines]
>
> …
Marek - 30 Jun 2005 10:09 GMT
Thanks for reply.

I'm calling Marshal.GetLastWin32Error(), to obtaint error code. I didn't
have SetLastError = true attribute in my declaration, so I added it.

After adding SetLastError = true, OpenPrinter and ClosePrinter return 1
(OK), but all other funcs returns 0 and GetLastWin32Error returns 997. I
forgot to mention that my program is windows service running under account
with Administrative privileges. Any other suggestions? Thank you in advance!

Here is output from my program:

OpenPrinter : 1
StartDocPrinter : 0
StartDocPrinter_GetLast : 997
StartPagePrinter : 0
StartPagePrinter_GetLast : 997
WritePrinter : 0
WritePrinter_GetLast : 997
EndPagePrinter : 0
EndPagePrinter_GetLast : 997
EndDocPrinter : 0
EndDocPrinter_GetLast : 997
ClosePrinter : 1

> Don't call SetLastError, the error code is probably wrong or inconsistent
> when doing this, use GetLastWin32Error instead.
[quoted text clipped - 100 lines]
> >
> > …
Marek - 30 Jun 2005 20:47 GMT
I think I've got it. It was a security issue. I mapped network printer to
newly created local port lpt2 on PC_2:

net use lpt2 \\PC_1\<printerName> /user:<userName>

Then I created local printer on PC_2 on lpt2 and everything works fine.
However not in WNT 4.0 scenario. There must be some problem with passing
credentials from W2k3 to NT 4.0, as I still got error 997 (on OpenPrinter)...
net use didn't help. Hmm....

> Thanks for reply.
>
[quoted text clipped - 125 lines]
> > >
> > > …

Rate this thread:







Free Magazines

Get these publications absolutely FREE for up to 12 months. There are no hidden fees and no obligation. Simply choose a title, complete the application form and submit it. Read more ...

Oracle MagazineNetwork ComputingComputer WorldBio-IT WorldeWeekInformation WeekInfosecurity
 
Sign In
Join
My Latest Posts
My Monitored Threads
My Blog
My Photo Gallery
My Profile
My Homepage

Start New Thread
Enable EMail Alerts
Rate this Thread



©2008 Advenet LLC   Privacy Policy - Terms of Use
This website includes both content owned or controlled by Advenet as well as content owned or controlled by third parties.