/// <summary>
        /// Open a printer or server.
        /// </summary>
        /// <param name="printer_name">The name of the printer or server. If this is null or empty then it's the local server.</param>
        /// <param name="desired_access">The desired access on the printer.</param>
        /// <param name="throw_on_error">True to throw on error.</param>
        /// <returns>The opened printer.</returns>
        public static NtResult <PrinterObject> OpenPrinter(string printer_name, PrintSpoolerAccessRights desired_access, bool throw_on_error)
        {
            PRINTER_DEFAULTS defs = new PRINTER_DEFAULTS();

            defs.DesiredAccess = desired_access;
            return(PrintingNativeMethods.OpenPrinter(printer_name, out IntPtr handle, defs).CreateWin32Result(throw_on_error, () => new PrinterObject(handle, printer_name)));
        }
 /// <summary>
 /// Dispose the printer object.
 /// </summary>
 public void Dispose()
 {
     if (_handle != IntPtr.Zero)
     {
         PrintingNativeMethods.ClosePrinter(_handle);
     }
 }
        /// <summary>
        /// Get security descriptor for the printer.
        /// </summary>
        /// <param name="throw_on_error">True to throw on error.</param>
        /// <returns>The printer's security descriptor.</returns>
        public NtResult <SecurityDescriptor> GetSecurityDescriptor(bool throw_on_error)
        {
            PrintingNativeMethods.GetPrinter(_handle, 3, SafeHGlobalBuffer.Null, 0, out int length);
            using (var buffer = new SafeStructureInOutBuffer <PRINTER_INFO_3>(length, false))
            {
                var error = PrintingNativeMethods.GetPrinter(_handle, 3, buffer, length, out length).GetLastWin32Error();
                if (error != Win32Error.SUCCESS)
                {
                    return(error.CreateResultFromDosError <SecurityDescriptor>(throw_on_error));
                }

                return(SecurityDescriptor.Parse(buffer.Result.pSecurityDescriptor, _type, throw_on_error));
            }
        }