Home | Contact Us | FAQ | Search & Site Map | Link to Us
Sign In | Join | Other 45 Sites in Network
Home
Discussion GroupsVB SyntaxEnterprise DevelopmentDatabase AccessControlsCOMWin APICrystal ReportDeploymentGeneralGeneral 2
Related Topics
VB.NET / ASP.NETMS SQL ServerMS AccessOther Database ProductsMore Topics ...

VB Forum / Win API / January 2007



Tip: Looking for answers? Try searching our database.

GetPrinter Call in x64 caused a FatalExecutionEngineError

Thread view: 
Enable EMail Alerts  Start New Thread
Thread rating: 
SteveYau - 31 Jan 2007 02:59 GMT
Hi There,

I tried a simple VB.Net console program  that uses win32 api call on
WinSpool.drv to query a local or remote printer's sharing status. The API
calls I used are OpenPrinter, GetPrinter and ClosePrinter. The program runs
perfectly on x86 32-bit platform.

However, when I compile the same program on a x64 Windows Server 2003 R2
Ent. and run it (with only slight modification on printer name), it caused a
FatalExecutionEngineError. On VS2005 debug windows, it showed:

---
The error code is 0xC0000005. This error may be a bug in the CLR or in the
unsafe or non-verifiable portions of user code. Common sources of this bug
include user marshaling errors for COM-interop or PInvoke, which may corrupt
the stack.
---

And in Application eventlog, a ".NET RunTime" event 1023 ".NET Runtime
version 2.0.50727.63 - Fatal Execution Engine Error (000006427F880608)
(80131506)" was logged.

Here I attach this small program. Line 116, the second invocation of
GetPrinter, is the place where .Net engine failed.

Grateful if any experts here can give me some hints.

Thanks

Steve

----- Attached sample code ---
Imports System.Runtime.InteropServices

Module Module1

 Const PRINTER_ATTRIBUTE_SHARED As Integer = &H8
 Const ERROR_INSUFFICIENT_BUFFER As Integer = &H7A

 <StructLayout(LayoutKind.Sequential, CharSet:=CharSet.Unicode)> _
 Structure PRINTER_INFO_2W
   <MarshalAs(UnmanagedType.LPWStr)> Public pServerName As String
   <MarshalAs(UnmanagedType.LPWStr)> Public pPrinterName As String
   <MarshalAs(UnmanagedType.LPWStr)> Public pShareName As String
   <MarshalAs(UnmanagedType.LPWStr)> Public pPortName As String
   <MarshalAs(UnmanagedType.LPWStr)> Public pDriverName As String
   <MarshalAs(UnmanagedType.LPWStr)> Public pComment As String
   <MarshalAs(UnmanagedType.LPWStr)> Public pLocation As String
   Public pDevMode As IntPtr
   <MarshalAs(UnmanagedType.LPWStr)> Public pSepFile As String
   <MarshalAs(UnmanagedType.LPWStr)> Public pPrintProcessor As String
   <MarshalAs(UnmanagedType.LPWStr)> Public pDataType As String
   <MarshalAs(UnmanagedType.LPWStr)> Public pParameter As String
   Public pSecurityDescriptor As IntPtr
   Public Attributes As Integer
   Public Priority As Integer
   Public DefaultPriority As Integer
   Public StartTime As Integer
   Public UntilTime As Integer
   Public Status As Integer
   Public cJobs As Integer
   Public AveragePPM As Integer
 End Structure

 <DllImport("winspool.Drv", EntryPoint:="OpenPrinterW", _
   SetLastError:=True, CharSet:=CharSet.Unicode, _
   ExactSpelling:=True, CallingConvention:=CallingConvention.StdCall)> _
 Function OpenPrinter(ByVal src As String, _
   ByRef hPrinter As IntPtr, ByVal pd As Integer) As Boolean
 End Function

 <DllImport("winspool.Drv", EntryPoint:="ClosePrinter", _
   SetLastError:=True, CharSet:=CharSet.Unicode, _
   ExactSpelling:=True, CallingConvention:=CallingConvention.StdCall)> _
 Function ClosePrinter(ByVal hPrinter As IntPtr) As Integer
 End Function

 <DllImport("winspool.Drv", EntryPoint:="GetPrinterW", _
   SetLastError:=True, CharSet:=CharSet.Unicode, _
   ExactSpelling:=True, CallingConvention:=CallingConvention.StdCall)> _
 Function GetPrinter(ByVal hPrinter As IntPtr, ByVal Level As Integer, _
  ByRef pPrinter As Byte, ByVal cbBuf As Integer, ByRef pcbNeeded As
Integer _
  ) As Integer
 End Function

 Sub Main()
   Dim buf() As Byte
   Dim BytesWritten, ByteLength, rc, DLLErrCode As Integer
   Dim bufptr As IntPtr = IntPtr.Zero
   Dim bResult As Boolean
   Dim pPrinter_Info As PRINTER_INFO_2W
   Dim PrintHandle As IntPtr = IntPtr.Zero

   Console.WriteLine("Trying to OpenPrinter [\\CCZ166\CCL12]")

   ' check to see if the printer can be opened.
   rc = OpenPrinter("\\CCZ166\CCL12", PrintHandle, 0)
   If rc = 0 Then
     Console.WriteLine("Cannot OpenPrinter [\\CCZ166\CCL12] Error = [" &
Err.LastDllError & "]")
     Exit Sub
   End If
   Console.WriteLine("Printer [CCL12] Found. Checking Shared Status... ")
   ReDim buf(1)

   ' check to get printer information, pass no buffer and ask for return
buffer size
   rc = GetPrinter(PrintHandle, 2, buf(0), 0, BytesWritten)
   If rc = 0 Then
     DLLErrCode = Err.LastDllError
     ' Expected to get ERROR_INSUFFICIENT_BUFFER return code
     If DLLErrCode <> ERROR_INSUFFICIENT_BUFFER Then
       Console.WriteLine("Cannot GetPrinter [CCL12] DLL Error = [" &
DLLErrCode & "]")
       ClosePrinter(PrintHandle)
       Exit Sub
     End If
   End If

   Console.WriteLine("First GetPrinter Called... BytesWritten = [" &
BytesWritten.ToString & "]")
   With pPrinter_Info
     .pServerName = ""
     .pPrinterName = ""
     .pShareName = ""
     .pPortName = ""
     .pDriverName = ""
     .pComment = ""
     .pLocation = ""
     .pDevMode = IntPtr.Zero
     .pSepFile = ""
     .pPrintProcessor = ""
     .pDataType = ""
     .pParameter = ""
     .pSecurityDescriptor = IntPtr.Zero
     .Attributes = 0
     .Priority = 0
     .DefaultPriority = 0
     .StartTime = 0
     .UntilTime = 0
     .Status = 0
     .cJobs = 0
     .AveragePPM = 0
   End With

   ByteLength = BytesWritten
   ReDim buf(ByteLength - 1)

   ' Get Printer Info and store it in buf
   Console.WriteLine("Second GetPrinter Calling... ")

   rc = GetPrinter(PrintHandle, 2, buf(0), ByteLength, BytesWritten)
   Console.WriteLine("Second GetPrinter Called... ")
   If rc = 0 Then
     ' Unexpected GetPrinter Error
     Console.WriteLine("Cannot GetPrinter [CCL12] DLL Error = " & _
       Err.LastDllError)
     ClosePrinter(PrintHandle)
     Exit Sub
   End If

   ' Allocate memory and parse the buffer
   Try
     bufptr = Marshal.AllocCoTaskMem(ByteLength)
     Marshal.Copy(buf, 0, bufptr, ByteLength)
     pPrinter_Info = CType(Marshal.PtrToStructure(bufptr,
GetType(PRINTER_INFO_2W)), _
       PRINTER_INFO_2W)
     Marshal.FreeCoTaskMem(bufptr)
   Catch ex As Exception
     Console.WriteLine("Unable to marshal PRINTER_INFO_2. ")
     ClosePrinter(PrintHandle)
     Exit Sub
   End Try

   ' Check whether the printer is shared
   bResult = (pPrinter_Info.Attributes And PRINTER_ATTRIBUTE_SHARED)
   ClosePrinter(PrintHandle)

   If bResult Then
     Console.WriteLine("Printer [CCL12] found and shared. ")
   Else
     Console.WriteLine("Printer [CCL12] found but not shared.")
   End If
 End Sub

End Module
Bob O`Bob - 31 Jan 2007 07:32 GMT
> Hi There,
>
> I tried a simple VB.Net console program  

You will want a newsgroup with "dotnet" in the group name, then.

The VB groups without that are for Classic VB.

    Bob
--
 
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



©2009 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.