Exemplo n.º 1
0
        /// <summary>
        /// Deletes a printer from the designated server. Must have administrator access to it.
        /// </summary>
        /// <param name="sServer"></param>
        /// <param name="sPrinter"></param>
        public static void DeletePrinter(CredentialEntry ce, string sServer, string sPrinter)
        {
            Session.EnsureNullSession(sServer, ce);

            // first, open the printer
            string           s = Canon(sServer) + @"\" + sPrinter;
            int              hPrinter;
            PRINTER_DEFAULTS pd = new PRINTER_DEFAULTS();

            pd.pDatatype     = IntPtr.Zero;
            pd.pDevMode      = IntPtr.Zero;
            pd.DesiredAccess = PRINTER_ALL_ACCESS;
            IntPtr p = Marshal.AllocHGlobal(Marshal.SizeOf(pd));

            Marshal.StructureToPtr(pd, p, false);
            if (!OpenPrinter(s, out hPrinter, p))
            {
                // free memory
                Marshal.DestroyStructure(p, typeof(PRINTER_DEFAULTS));
                Marshal.FreeHGlobal(p);

                int            nError = Marshal.GetLastWin32Error();
                Win32Exception we     = new Win32Exception(nError);
                if (nError == nErrorAccessDenied)
                {
                    throw new AuthException(we);
                }
                else
                {
                    throw we;
                }
            }

            Marshal.DestroyStructure(p, typeof(PRINTER_DEFAULTS));
            Marshal.FreeHGlobal(p);

            // now remove it from AD
            PRINTER_INFO_7 pi7 = new PRINTER_INFO_7();

            pi7.pszObjectGUID = IntPtr.Zero;
            pi7.dwAction      = (uint)DSPRINT_OPTIONS.DSPRINT_UNPUBLISH;
            p = Marshal.AllocHGlobal(Marshal.SizeOf(pi7));
            Marshal.StructureToPtr(pi7, p, false);
            SetPrinter(hPrinter, 7, p, 0);

            // NOTE: we swallow any error since the operation may be left in a "pending" state rather
            // than returning success or failure right away.

            // free memory
            Marshal.DestroyStructure(p, typeof(PRINTER_INFO_7));
            Marshal.FreeHGlobal(p);

            // finally, remove the printer
            if (!DeletePrinter(hPrinter))
            {
                int            nError = Marshal.GetLastWin32Error();
                Win32Exception we     = new Win32Exception(nError);
                if (nError == nErrorAccessDenied)
                {
                    throw new AuthException(we);
                }
                else
                {
                    throw we;
                }
            }
        }
Exemplo n.º 2
0
        /// <summary>
        /// Fetches data about the printers available on the designated server
        /// </summary>
        /// <param name="sServer"></param>
        /// <param name="dt">The DataTable into which the data should be placed. dt MUST have been created properly with CreateDataTable</param>
        public static Dictionary <int, string[]> FetchPrinterData(CredentialEntry ce, string sServer)
        {
            int    dwFlags      = (int)PEFlags.PRINTER_ENUM_NAME;
            string Name         = Canon(sServer);
            int    Level        = 2;
            IntPtr pPrinterEnum = IntPtr.Zero;
            int    cBufNeeded   = 0;
            int    cReturned    = 0;

            if (!Session.EnsureNullSession(sServer, ce))
            {
                return(null);
            }

            Dictionary <int, string[]> printInfoList = new Dictionary <int, string[]>();

            ///
            /// TODO: revise. Samba 3.0.13 fails if we pass in a null buffer. To avoid this
            /// pass in a pointer to a zero length buffer!
            ///

        #if SAMBAFIXED
            if (EnumPrinters(dwFlags, Name, Level, pPrinterEnum, 0, ref cBufNeeded, ref cReturned))
            {
                // Can only happen if no printers available!
                return;
            }
        #else
            {
            }
            pPrinterEnum = Marshal.AllocHGlobal(0);
            if (EnumPrinters(dwFlags, Name, Level, pPrinterEnum, 0, ref cBufNeeded, ref cReturned))
            {
                // free the mem
                Marshal.FreeHGlobal(pPrinterEnum);

                // Can only happen if no printers available!
                return(null);
            }
            // free the mem
            Marshal.FreeHGlobal(pPrinterEnum);
        #endif

            // Normally, we fail because we need a bigger buffer. However, if we fail
            // with RPC_S_CALL_FAILED, this means that we "succeeded" but that the remote
            // machine has nothing to tell us
            int nError = Marshal.GetLastWin32Error();

            if (nError == nErrorRPC_S_CALL_FAILED)
            {
                return(null);
            }

            if (nError != ERROR_INSUFFICIENT_BUFFER)
            {
                // Any other error results in an exception
                string sErr;
                if (nError == nErrorBadRPC)
                {
                    sErr = sBadServerName;
                }
                else if (nError == nErrorAccessDenied)
                {
                    throw new AuthException(new Win32Exception(nError));
                }
                else
                {
                    sErr = string.Format(sErrorMsg, sServer, nError);
                }
                throw new Win32Exception(sErr);
            }

            // allocate a big enough buffer
            pPrinterEnum = Marshal.AllocHGlobal(cBufNeeded);

            // retry
            if (!EnumPrinters(dwFlags, Name, Level, pPrinterEnum, cBufNeeded, ref cBufNeeded, ref cReturned))
            {
                nError = Marshal.GetLastWin32Error();
                Win32Exception we = new Win32Exception(nError);
                if (nError == nErrorAccessDenied)
                {
                    throw new AuthException(we);
                }
                else
                {
                    throw we;
                }
            }

            // iterate through the retrieved entries, copying printer entries
            // to the output table
            IntPtr pCur = pPrinterEnum;
            for (int i = 0; i < cReturned; i++)
            {
                // marshal the entry into
                PRINTER_INFO_2 pi2 = new PRINTER_INFO_2();
                Marshal.PtrToStructure(pCur, pi2);

                // trim off server name
                string sName = Marshal.PtrToStringUni(pi2.pPrinterName);
                if (sName.StartsWith(@"\\"))
                {
                    // yep, trim off prefix
                    int ibackwhack = sName.LastIndexOf(@"\");
                    sName = sName.Substring(ibackwhack + 1);
                }

                string[] printInfo = { Marshal.PtrToStringUni(pi2.pShareName), Marshal.PtrToStringUni(pi2.pDriverName), pi2.cJobs.ToString(), Marshal.PtrToStringUni(pi2.pComment) };

                // advance to the next entry
                pCur = (IntPtr)((int)pCur + Marshal.SizeOf(pi2));

                printInfoList.Add(i, printInfo);
            }

            // free the mem
            Marshal.FreeHGlobal(pPrinterEnum);

            return(printInfoList);
        }