• Sign In
 
  • MSDN Blogs
  • Microsoft Blog Images
  • More ...
Common Tasks
  • Blog Home
  • Email Blog Author
  • RSS for comments
  • RSS for posts
Search
  • Advanced search options...
Tags
  • .NET Framewor
  • .NET Framework
  • Ajax/Javascript
  • ASP.NET
  • CLR
  • Cool stuff
  • DataAccess
  • Debugging/Windbg
  • Hotfix/Service Pack
  • IDEVDataCollector
  • IIS
  • Internet Explorer
  • Italian techs
  • LogParser
  • OT
  • Personal
  • Productivity
  • Random
  • Scripting/ASP
  • Security
  • Technology
  • Tools
  • Troubleshooting
  • Vista/Longhorn
  • Visual Studio
Archives
Archives
  • November 2010 (1)
  • October 2010 (1)
  • July 2010 (2)
  • April 2010 (1)
  • March 2010 (2)
  • February 2010 (2)
  • January 2010 (1)
  • October 2009 (2)
  • September 2009 (2)
  • August 2009 (1)
  • July 2009 (5)
  • June 2009 (1)
  • May 2009 (1)
  • April 2009 (3)
  • March 2009 (3)
  • February 2009 (5)
  • January 2009 (3)
  • December 2008 (5)
  • November 2008 (3)
  • October 2008 (2)
  • September 2008 (3)
  • August 2008 (3)
  • July 2008 (3)
  • June 2008 (5)
  • May 2008 (4)
  • April 2008 (8)
  • March 2008 (4)
  • February 2008 (5)
  • January 2008 (2)
  • December 2007 (4)
  • November 2007 (6)
  • October 2007 (6)
  • September 2007 (8)
  • August 2007 (6)
  • July 2007 (7)
  • June 2007 (10)
  • May 2007 (9)
  • April 2007 (12)
  • March 2007 (8)
  • February 2007 (5)
  • January 2007 (3)
  • December 2006 (1)
  • November 2006 (4)
  • October 2006 (2)
  • September 2006 (9)
  • August 2006 (2)
  • July 2006 (1)

Need to print from a x64 machine? Can you wait 60 seconds?

MSDN Blogs > Never doubt thy debugger > Need to print from a x64 machine? Can you wait 60 seconds?

Need to print from a x64 machine? Can you wait 60 seconds?

Carlo Cardella
31 Jan 2008 2:33 PM
  • Comments 1

I guess some of you might have developed a web application which, among other functionalities, prints some kind of report; and sooner or later you might consider to move the application to a 64 bit machine. At this is what this customer did.

They had this ASP.NET application which allows the user to run some queries on a backend database and then print the result on a network printer connected to the web server; under some circumstances the application was hanging for 60 seconds (always 60 seconds) before timing out; of course everything was running fine on a 32 bit machine (i.e. we never managed to reproduce the issue there).

At the beginning we thought to some kind of network timeout on the customer's network or a configuration problem on the server (the application is quite complex so was not possible to have a repro to run and debug on my machine), and this was partially confirmed by a hang dump which showed some error messages about the printer, but this was not consistent enough to get a clue. What was consistent was the use of winspool.dll

ntdll!NtDelayExecution(void)+0x15
kernel32!SleepEx(unsigned long dwMilliseconds = 0x3e8, int bAlertable = 0)+0x68
kernel32!Sleep(unsigned long dwMilliseconds = 0x3e8)+0xf
winspool!ConnectToLd64In32ServerWorker(void ** hProcess = 0x7309214c, int bThread = 1)+0x33e
winspool!ConnectToLd64In32Server(void ** hProcess = 0x7309214c, int bThread = 1)+0x1b
winspool!DeviceCapabilitiesWThunk(unsigned short * pDevice = 0x790d8858, unsigned short * pPort = 0x0ef69df8, unsigned short fwCapability = 0x12, unsigned short * pOutput = 0x00000000, struct _devicemodeW * pDevMode = 0x00000000)+0x77
CLRStub[StubLinkStub]@1af41e5e(<Win32 error 0n318>)
System_Drawing_ni!System.Drawing.Printing.PrinterSettings.FastDeviceCapabilities(<HRESULT 0x80004001>)+0x2e
System.Drawing.Printing.PrinterSettings.DeviceCapabilities(<HRESULT 0x80004001>)+0x66
System_Drawing_ni!System.Drawing.Printing.PrinterSettings.get_IsValid(<HRESULT 0x80004001>)+0x21
App_Web_nqftqomb!_Default.Button4_Click(<HRESULT 0x80004001>)+0xf2

As you can see, after the click on the button to print the report we're going down to the OS for the actual printing, we're passing through the ConnectToLd64In32ServerWorker method and then we're waiting for 1 second (dwMilliseconds = 0x3e8 = 1000 milliseconds = 1 second). The next logical step has been to have a look at the source code for that particular method in winspool and found that under under some circumstances we try to connect to an RPC resource and we retry to 60 seconds before exiting to avoid an infinite hang. Good, now we only have to understand why using NETWORK SERVICE works fine while impersonating the logged on user fails (clearly some kind of missing permission).

Unfortunately the final customer was not interested in spending more time investigating the issue but they wanted a working solution right away, so we decided to use impersonation by code to switch to NETWORK SERVICE when ready to print and then switch back to the logged on user; we made a few changes to the same code I already used for another case (here) to do the trick:

protected void Button1_Click(object sender, EventArgs e)
{
    //This should be the authenticated user
    Label1.Text = "Process running as " + WindowsIdentity.GetCurrent().Name + " (before impersonating)";

    //Save a reference to the authenticated user token for later
    WindowsPrincipal p = (WindowsPrincipal)HttpContext.Current.User;
    WindowsIdentity id = (WindowsIdentity)p.Identity;

    //Revert to the worker process account (default is NETWORK SERVICE)
    RevertToSelf();
    Label3.Text = "Process running as " + WindowsIdentity.GetCurrent().Name + " (after impersonating)";

    try
    {
        //Print an to whatever you need to do under the NETWORK SERVICE context
    }
    catch (Exception ex)
    {
        Label2.Text = ex.Message;
    }

    //Impersonate back the authenticatd user
    WindowsImpersonationContext wic = id.Impersonate();
    Label4.Text = "Process running as " + WindowsIdentity.GetCurrent().Name + " (reverting back)";

    //VERY IMPORTANT: ALWAYS REMEMBER TO CALL THE UNDO METHOD WHEN DONE!
    wic.Undo();
}

 

While it's a shame that we didn't have the opportunity to fully understand what was going wrong, if you'll ever find yourself in this situation you at least should have a solution ready to have you application up and running quickly; but of course if you what to understand more feel free to open a call with CSS! smile_wink

 

Carlo

Quote of the day:
Inspiration is wonderful when it happens, but the writer must develop an approach for the rest of the time... The wait is simply too long. - Leonard Bernstein
  • 1 Comments
ASP.NET, Debugging/Windbg, Vista/Longhorn, .NET Framework
Leave a Comment
  • Please add 7 and 5 and type the answer here:
  • Post
Comments
  • leonard bernstein
    10 Mar 2008 5:53 PM

    PingBack from http://zacharyspace.das-hosting.de/leonardbernstein.html

Page 1 of 1 (1 items)
  • © 2012 Microsoft Corporation.
  • Terms of Use
  • Trademarks
  • Privacy Statement
  • Report Abuse
  • 5.6.131.143