none
Attempt by security transparent method 'MS.Internal.PrintWin32Thunk.PrinterDefaults.!PrinterDefaults()' to access security critical method 'MS.Internal.PrintWin32Thunk.PrinterDefaults.InternalDispose(Boolean)' failed. RRS feed

  • Question

  • Hi,

    Can any one let me know what it mean ?

    I am creating print queue.. 

    PrintQueueCollection myPrintQueues = myPS.GetPrintQueues();
    

    The logic is in loop for it working fine with first loop ..
    but when it run for second time it throw exception .

     

    Attempt by security transparent method 'MS.Internal.PrintWin32Thunk.PrinterDefaults.!PrinterDefaults()' to access security critical method 'MS.Internal.PrintWin32Thunk.PrinterDefaults.InternalDispose(Boolean)' failed.

     

    Thanks,

     

    Monday, June 13, 2011 11:23 AM

Answers

All replies

  • It seems that this is a know issue:

    Looked through the source code and saw that SecurityCritical attribute is missing on MS.Internal.PrintWin32Thunk.PrinterDefaults.Dispose().

    [Workaround] 

    As "new PrintServer()" does not use PrinterDefaults, the exception does not occur with that constructor. It can enumerate printers.

    There're also others workarounds in the MS connect, you also can have a try:

    http://connect.microsoft.com/VisualStudio/feedback/details/552520/methodaccessexception-when-printqueuecollection-disposed

     

    Best wishes,


    Mike [MSFT]
    MSDN Community Support | Feedback to us
    Get or Request Code Sample from Microsoft
    Please remember to mark the replies as answers if they help and unmark them if they provide no help.

    Wednesday, June 15, 2011 1:28 PM
    Moderator
  • Me too experiencing the similar problem, Dispose() does not help, the problem appears to be random
    Saturday, September 22, 2012 12:56 PM
  • Hi Mike

    I use "new PrintServer(nothing, access)" as you suggested but still having the error aswell, the stack is still showing PrinterDefaults:

    System.MethodAccessException: Attempt by security transparent method 'MS.Internal.PrintWin32Thunk.PrinterDefaults.!PrinterDefaults()' to access security critical method 'MS.Internal.PrintWin32Thunk.Pr
    interDefaults.InternalDispose(Boolean)' failed.
       at MS.Internal.PrintWin32Thunk.PrinterDefaults.!PrinterDefaults()
       at MS.Internal.PrintWin32Thunk.PrinterDefaults.Dispose(Boolean )

    I'm using PrintServer in a console application and this exception goes into the UnhandledException even if I wrapped the PrintServer.Dispose() method with a Try Catch (the exception is thrown at this call)

    Why is it going though TryCatch and land to the UnhandledException ?

    Also the UnhandledExceptionEventArg.IsTerminating is set to true and crash my application. How can I prevent the program to stop running and just catch this exception ?

    Thanks for the help

    PS: the link http://connect.microsoft.com/VisualStudio/feedback/details/552520/methodaccessexception-when-printqueuecollection-disposed is not working
    • Edited by Meninx.net Tuesday, April 16, 2013 9:30 AM link added
    Tuesday, April 16, 2013 9:30 AM
  • Since the link to the Connect issue no longer works, here's the text from the Connect issue. Note that this issue is fixed in .NET 4.5.1 (from looking at the fix, it may be in .NET 4.5 as well).

    Buck

    --

    Hi,

     

    Maybe this helps.... (I am using this win32 api calls instead of the PrintServer class in my .NET 4.0 projects).

     

    Regards,

    Marco

     

    using System;

    using System.Collections.Generic;

    using System.ComponentModel;

    using System.Diagnostics.CodeAnalysis;

    using System.Drawing.Printing;

    using System.Linq;

    using System.Runtime.InteropServices;

    using System.Text;

    using System.Windows.Forms;

     

    namespace Advice.Framework.Win32

    {

       /// <summary>

       /// Win32 print api calls.

       /// </summary>

       /// <author>mg</author>

       [SuppressMessage("Microsoft.StyleCop.CSharp.NamingRules", "SA1305:FieldNamesMustNotUseHungarianNotation", Justification = "Win32 API Calls")]

       public class Printer

       {

          #region ctor

     

          public Printer()

          {

          }

     

          #endregion

     

          #region native dll imports

     

          [DllImport("kernel32.dll")]

          private static extern IntPtr GlobalLock(IntPtr hMem);

     

          [DllImport("kernel32.dll")]

          private static extern bool GlobalUnlock(IntPtr hMem);

     

          [DllImport("kernel32.dll")]

          private static extern bool GlobalFree(IntPtr hMem);

     

          [DllImport("winspool.Drv",

             EntryPoint = "DocumentPropertiesW",

             SetLastError = true, ExactSpelling = true,

             CallingConvention = CallingConvention.StdCall)]

          private static extern int DocumentProperties(IntPtr hwnd,

             IntPtr hPrinter,

             [MarshalAs(UnmanagedType.LPWStr)] string pDeviceName,

             IntPtr pDevModeOutput,

             IntPtr pDevModeInput,

             int fMode);

     

          [DllImport("winspool.drv", SetLastError = true)]

          private static extern int DeviceCapabilities(string device, string port, DeviceCapabilitiesFlags capability, IntPtr outputBuffer, IntPtr deviceMode);

     

          [DllImport("winspool.drv", CharSet = CharSet.Auto, SetLastError = true)]

          private static extern bool EnumPrinters(PrinterEnumFlags flags, string name, uint level, IntPtr pPrinterEnum, uint cbBuf, ref uint pcbNeeded, ref uint pcReturned);

     

          //[DllImport("winspool.Drv", EntryPoint = "", CharSet = CharSet.Auto, SetLastError = true)]

          //private static extern bool OpenPrinter([MarshalAs(UnmanagedType.LPStr)] string printerName, out IntPtr printerHandle, IntPtr printerDefault);

     

          [DllImport("winspool.Drv", SetLastError = true, EntryPoint = "OpenPrinterA", CallingConvention = CallingConvention.StdCall, ExactSpelling = true)]

          private static extern bool OpenPrinter(string szPrinter, out IntPtr hPrinter, IntPtr pDefault);

     

     

     

          [DllImport("winspool.drv", SetLastError = true)]

          private static extern int ClosePrinter(IntPtr printerHandle);

     

          //[DllImport("winspool.drv", SetLastError = true, EntryPoint = "GetPrinterA", CallingConvention = CallingConvention.StdCall, ExactSpelling = true)]

          //public static extern bool GetPrinter(IntPtr hPrinter, uint dwLevel, IntPtr pPrinter, uint dwBuf, ref uint dwNeeded);

     

          [DllImport("winspool.Drv", EntryPoint = "GetPrinterA", SetLastError = true, CharSet = CharSet.Ansi, ExactSpelling = true, CallingConvention = CallingConvention.StdCall)]

          private static extern bool GetPrinter(IntPtr hPrinter, int dwLevel, IntPtr pPrinter, int dwBuf, ref int dwNeeded);

     

     

          #endregion

     

          #region constants

     

          private const int DM_OUT_BUFFER = 14;

          private const int ERROR_INSUFFICIENT_BUFFER = 122;

     

     

          #endregion

     

          #region methods private

     

          private static IEnumerable<TPrinterInfo> CreatePrinterInfo<TPrinterInfo>(IntPtr dataAddress, uint arrayLength)

          {

             var printerInfo = new TPrinterInfo[arrayLength];

             int offset = dataAddress.ToInt32();

             Type type = typeof(PRINTER_INFO_1);

             int increment = Marshal.SizeOf(type);

             for (int i = 0; i < arrayLength; i++)

             {

                printerInfo[i] = (TPrinterInfo)Marshal.PtrToStructure(new IntPtr(offset), type);

                offset += increment;

             }

     

             Marshal.FreeHGlobal(dataAddress);

     

             return printerInfo;

          }

     

          #endregion

     

          #region methods public

     

          public static DialogResult OpenPrinterPropertiesDialog(PrinterSettings printerSettings, System.Windows.Forms.Form parentForm)

          {

             DialogResult dialogResult = DialogResult.Cancel;

             IntPtr hDevMode = IntPtr.Zero;

             IntPtr devModeData = IntPtr.Zero;

     

             try

             {

                System.IntPtr pHandle = parentForm.Handle;

                hDevMode = printerSettings.GetHdevmode();

                //IntPtr hDevMode = printerSettings.GetHdevmode(printerSettings.DefaultPageSettings);

     

                IntPtr pDevMode = GlobalLock(hDevMode);

     

                //  If this parameter is zero, the DocumentProperties function returns the number of bytes required by the printer driver's DEVMODE data structure.

                int fMode = 0;

     

                int sizeNeeded = DocumentProperties(pHandle, IntPtr.Zero, printerSettings.PrinterName, pDevMode, pDevMode, fMode);

                devModeData = Marshal.AllocHGlobal(sizeNeeded);

     

                // Output value. The function writes the printer driver's current print settings,

                // including private data, to the DEVMODE data structure specified by the pDevModeOutput parameter.

                fMode = DM_OUT_BUFFER;

     

                //result = 1 : ok

                //result = 2 : cancel

                int result = DocumentProperties(pHandle, IntPtr.Zero, printerSettings.PrinterName, devModeData, pDevMode, fMode);

                GlobalUnlock(hDevMode);

     

                if (result != 2)

                {

                   printerSettings.SetHdevmode(devModeData);

                   printerSettings.DefaultPageSettings.SetHdevmode(devModeData);

                   dialogResult = DialogResult.OK;

                }

     

             }

             catch (Exception)

             {

                dialogResult = DialogResult.Cancel;

                throw;

             }

             finally

             {

                try

                {

                   if (!IntPtr.Zero.Equals(hDevMode))

                      GlobalFree(hDevMode);

     

                   if (!IntPtr.Zero.Equals(devModeData))

                      Marshal.FreeHGlobal(devModeData);

                }

                catch (Exception ex)

                {

                   ExceptionManager.HandleException(Advice.Framework.Logging.LogLevel.Error, ex, false, string.Empty, "Error while releasing printer resources.");

                }

             }

             return dialogResult;

          }

     

          public static Dictionary<short, string> GetBins(string printerQueueName, string port = null)

          {

             var result = new Dictionary<short, string>();

             try

             {

                string strError = string.Empty;

     

                // Bins

                int nRes = DeviceCapabilities(printerQueueName, port, DeviceCapabilitiesFlags.DC_BINS, (IntPtr)null, (IntPtr)null);

                IntPtr pAddr = Marshal.AllocHGlobal((int)nRes * 2);

                nRes = DeviceCapabilities(printerQueueName, port, DeviceCapabilitiesFlags.DC_BINS, pAddr, (IntPtr)null);

                if (nRes < 0)

                {

                   strError = new Win32Exception(Marshal.GetLastWin32Error()).Message + "[" + printerQueueName + ": " + port + "]";

                   return result;

                }

                short[] bins = new short[nRes];

                int offset = pAddr.ToInt32();

                for (int i = 0; i < nRes; i++)

                {

                   result.Add((short)Marshal.ReadIntPtr(new IntPtr(offset + (i * 2))), string.Empty);

                }

                Marshal.FreeHGlobal(pAddr);

     

                // BinNames

                nRes = DeviceCapabilities(printerQueueName, port, DeviceCapabilitiesFlags.DC_BINNAMES, (IntPtr)null, (IntPtr)null);

                pAddr = Marshal.AllocHGlobal((int)nRes * 24);

                nRes = DeviceCapabilities(printerQueueName, port, DeviceCapabilitiesFlags.DC_BINNAMES, pAddr, (IntPtr)null);

                if (nRes < 0)

                {

                   strError = new Win32Exception(Marshal.GetLastWin32Error()).Message + "[" + printerQueueName + ": " + port + "]";

                   return result;

                }

     

                offset = pAddr.ToInt32();

                for (int i = 0; i < nRes; i++)

                {

                   // Marshal.PtrToStringAnsi(new IntPtr(offset + i * 24))

                   var element = result.ElementAt(i);

                   result[element.Key] = Marshal.PtrToStringAnsi(new IntPtr(offset + (i * 24)));

     

                }

                Marshal.FreeHGlobal(pAddr);

             }

             catch (Exception)

             {

             }

     

             return result;

          }

     

          /// <summary>

          /// Gets all network printers.

          /// </summary>

          /// <returns></returns>

          public static IEnumerable<PRINTER_INFO_2> GetNetworkPrinters()

          {

             /*

                 Windows NT Internet Provider

                 Windows NT Local Print Providor

                 LanMan Print Services

             */

             uint cbNeeded = 0;

             uint cReturned = 0;

             PrinterEnumFlags flags = PrinterEnumFlags.PRINTER_ENUM_REMOTE;

             uint level = 1;

     

             var result = new List<PRINTER_INFO_2>();

             if (EnumPrinters(flags, string.Empty, level, IntPtr.Zero, 0, ref cbNeeded, ref cReturned))

             {

                return null;

             }

     

             int lastWin32Error = Marshal.GetLastWin32Error();

             if (lastWin32Error == ERROR_INSUFFICIENT_BUFFER)

             {

                IntPtr pAddr = Marshal.AllocHGlobal((int)cbNeeded);

                if (EnumPrinters(flags, string.Empty, level, pAddr, cbNeeded, ref cbNeeded, ref cReturned))

                {

                   var infos = CreatePrinterInfo<PRINTER_INFO_1>(pAddr, cReturned);

                   foreach (var info in infos)

                   {

                      if (((PrinterEnumFlags)info.Flags & PrinterEnumFlags.PRINTER_ENUM_CONTAINER) == PrinterEnumFlags.PRINTER_ENUM_CONTAINER)

                      {

                         cbNeeded = 0;

                         cReturned = 0;

                         if (EnumPrinters(PrinterEnumFlags.PRINTER_ENUM_NAME, info.Name, level, IntPtr.Zero, cbNeeded, ref cbNeeded, ref cReturned))

                         {

                            return null;

                         }

     

                         lastWin32Error = Marshal.GetLastWin32Error();

                         if (lastWin32Error == ERROR_INSUFFICIENT_BUFFER)

                         {

                            pAddr = Marshal.AllocHGlobal((int)cbNeeded);

                            if (EnumPrinters(PrinterEnumFlags.PRINTER_ENUM_NAME, info.Name, level, pAddr, cbNeeded, ref cbNeeded, ref cReturned))

                            {

                               var localInfos = CreatePrinterInfo<PRINTER_INFO_1>(pAddr, cReturned);

                               //result.AddRange(localInfos);

                               foreach (var localInfo in localInfos)

                               {

                                  result.Add(GetPrinterInfo(localInfo.Name));

                               }

                            }

                         }

                      }

                      else

                      {

                         result.Add(GetPrinterInfo(info.Name));

                      }

                   }

                }

     

                lastWin32Error = Marshal.GetLastWin32Error();

             }

     

             return result;

          }

     

          public static PRINTER_INFO_2 GetPrinterInfo(string printerName)

          {

             PRINTER_INFO_2 result = new PRINTER_INFO_2();

             IntPtr printerHandle = IntPtr.Zero;

             try

             {

                OpenPrinter(printerName, out printerHandle, IntPtr.Zero);

                int cbNeeded = 0;

     

                bool bRet = GetPrinter(printerHandle, 2, IntPtr.Zero, 0, ref cbNeeded);

                if (cbNeeded > 0)

                {

                   IntPtr pAddr = Marshal.AllocHGlobal((int)cbNeeded);

                   bRet = GetPrinter(printerHandle, 2, pAddr, cbNeeded, ref cbNeeded);

                   if (bRet)

                   {

                      result = (PRINTER_INFO_2)Marshal.PtrToStructure(pAddr, typeof(PRINTER_INFO_2));

                      // Now use the info from Info2 structure etc

                   }

                   Marshal.FreeHGlobal(pAddr);

                }

             }

             catch

             {

             }

             finally

             {

                try

                {

                   if (printerHandle != IntPtr.Zero)

                   {

                      ClosePrinter(printerHandle);

                   }

                }

                catch (Exception)

                { }

             }

     

             return result;

          }

     

     

          #endregion

     

          #region inner types

     

          public enum DeviceCapabilitiesFlags : short

          {

             DC_FIELDS = 1,

             DC_PAPERS = 2,

             DC_PAPERSIZE = 3,

             DC_MINEXTENT = 4,

             DC_MAXEXTENT = 5,

             DC_BINS = 6,

             DC_DUPLEX = 7,

             DC_SIZE = 8,

             DC_EXTRA = 9,

             DC_VERSION = 10,

             DC_DRIVER = 11,

             DC_BINNAMES = 12,

             DC_ENUMRESOLUTIONS = 13,

             DC_FILEDEPENDENCIES = 14,

             DC_TRUETYPE = 15,

             DC_PAPERNAMES = 16,

             DC_ORIENTATION = 17,

             DC_COPIES = 18,

             DC_BINADJUST = 19,

             DC_EMF_COMPLIANT = 20,

             DC_DATATYPE_PRODUCED = 21,

             DC_COLLATE = 22,

             DC_MANUFACTURER = 23,

             DC_MODEL = 24,

             DC_PERSONALITY = 25,

             DC_PRINTRATE = 26,

             DC_PRINTRATEUNIT = 27,

             DC_PRINTERMEM = 28,

             DC_MEDIAREADY = 29,

             DC_STAPLE = 30,

             DC_PRINTRATEPPM = 31,

             DC_COLORDEVICE = 32,

             DC_NUP = 33

          }

     

          [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]

          public struct PRINTER_INFO_1

          {

             public uint Flags;

             [MarshalAs(UnmanagedType.LPTStr)]

             public string Description;

             [MarshalAs(UnmanagedType.LPTStr)]

             public string Name;

             [MarshalAs(UnmanagedType.LPTStr)]

             public string Comment;

          }

     

          [StructLayout(LayoutKind.Sequential)]

          public class PRINTER_INFO_2

          {

             [MarshalAs(UnmanagedType.LPStr)]

             public string ServerName;

             [MarshalAs(UnmanagedType.LPStr)]

             public string PrinterName;

             [MarshalAs(UnmanagedType.LPStr)]

             public string ShareName;

             [MarshalAs(UnmanagedType.LPStr)]

             public string PortName;

             [MarshalAs(UnmanagedType.LPStr)]

             public string DriverName;

             [MarshalAs(UnmanagedType.LPStr)]

            public string Comment;

             [MarshalAs(UnmanagedType.LPStr)]

             public string Location;

             public IntPtr DevMode;

             [MarshalAs(UnmanagedType.LPStr)]

             public string SepFile;

             [MarshalAs(UnmanagedType.LPStr)]

             public string PrintProcessor;

             [MarshalAs(UnmanagedType.LPStr)]

             public string Datatype;

             [MarshalAs(UnmanagedType.LPStr)]

             public string Parameters;

             public IntPtr SecurityDescriptor;

             public int Attributes;

             public int Priority;

             public int DefaultPriority;

             public int StartTime;

             public int UntilTime;

             public int Status;

             public int Jobs;

             public int AveragePPM;

          }

     

     

     

          [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]

          public struct PRINTER_INFO_4

          {

             [MarshalAs(UnmanagedType.LPTStr)]

             public string PrtinerName;

             [MarshalAs(UnmanagedType.LPTStr)]

             public string ServerName;

     

             public uint Attributes;

          }

     

          [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]

          public struct PRINTER_INFO_5

          {

             [MarshalAs(UnmanagedType.LPTStr)]

             public string PrinterName;

             [MarshalAs(UnmanagedType.LPTStr)]

             public string PortName;

     

             public uint Attributes;

             public uint DeviceNotSelectedTimeout;

             public uint TransmissionRetryTimeout;

          }

     

          [FlagsAttribute]

          public enum PrinterEnumFlags

          {

             PRINTER_ENUM_DEFAULT = 0x00000001,

             PRINTER_ENUM_LOCAL = 0x00000002,

             PRINTER_ENUM_CONNECTIONS = 0x00000004,

             PRINTER_ENUM_FAVORITE = 0x00000004,

             PRINTER_ENUM_NAME = 0x00000008,

             PRINTER_ENUM_REMOTE = 0x00000010,

             PRINTER_ENUM_SHARED = 0x00000020,

             PRINTER_ENUM_NETWORK = 0x00000040,

             PRINTER_ENUM_EXPAND = 0x00004000,

             PRINTER_ENUM_CONTAINER = 0x00008000,

             PRINTER_ENUM_ICONMASK = 0x00ff0000,

             PRINTER_ENUM_ICON1 = 0x00010000,

             PRINTER_ENUM_ICON2 = 0x00020000,

             PRINTER_ENUM_ICON3 = 0x00040000,

             PRINTER_ENUM_ICON4 = 0x00080000,

             PRINTER_ENUM_ICON5 = 0x00100000,

             PRINTER_ENUM_ICON6 = 0x00200000,

             PRINTER_ENUM_ICON7 = 0x00400000,

             PRINTER_ENUM_ICON8 = 0x00800000,

             PRINTER_ENUM_HIDE = 0x01000000

          }

     

          [StructLayout(LayoutKind.Sequential)]

          public struct PRINTER_DEFAULTS

          {

             public IntPtr Datatype;

            public IntPtr DevMode;

             public int DesiredAccess;

          }

     

     

          #endregion

       }

    }

     

     

    3. When I called PrintServer's constructor without any parameters then I was able to use it without seeing this problem.

     

    4.I followed the constructor work-around and it didn't help. This problem stopped happening when .NET 4.5.1 was installed (had .NET 4.0 on the server previously). Still targeting 4.0 for now, but the problem seems resolved.

    http://blogs.msdn.com/buckh

    Saturday, May 14, 2016 3:10 PM
  • Hi Meninx,

                Now I am facing this issue in the production environment. What you have done to solve the issue?.

    Friday, November 11, 2016 9:47 AM