private static DC_PAPER_SIZE[] ReadDC_PAPER_SIZEArray(HGlobalBuffer buffer, int itemByteSize)
        {
            int nItems = buffer.Length / itemByteSize;

            DC_PAPER_SIZE[] result = new DC_PAPER_SIZE[nItems];

            bool shouldRelease = false;

            buffer.Handle.DangerousAddRef(ref shouldRelease);
            try
            {
                IntPtr baseAddr = buffer.Handle.DangerousGetHandle();
                for (int i = 0, offset = 0; i < nItems; i++, offset += itemByteSize)
                {
                    int w = Marshal.ReadInt32(baseAddr, offset);
                    int h = Marshal.ReadInt32(baseAddr, offset + (itemByteSize / 2));
                    result[i] = new DC_PAPER_SIZE(w, h);
                }

                return(result);
            }
            finally
            {
                if (shouldRelease)
                {
                    buffer.Handle.DangerousRelease();
                }
            }
        }
        private short[] ReadWORDArray(HGlobalBuffer buffer, int itemByteSize)
        {
            int nItems = buffer.Length / itemByteSize;

            short[] result = new short[nItems];

            bool shouldRelease = false;

            buffer.Handle.DangerousAddRef(ref shouldRelease);
            try
            {
                IntPtr baseAddr = buffer.Handle.DangerousGetHandle();
                for (int i = 0, offset = 0; i < nItems; i++, offset += itemByteSize)
                {
                    result[i] = Marshal.ReadInt16(baseAddr, offset);
                }

                return(result);
            }
            finally
            {
                if (shouldRelease)
                {
                    buffer.Handle.DangerousRelease();
                }
            }
        }
        /// <summary>
        /// Gets a device capability represented as an array
        /// </summary>
        /// <param name="capability">Capability to retrieve</param>
        /// <returns>value of capability specified in capability argument</returns>
        private T[] GetArrayCapability <T>(DeviceCapability capability, ReadArray <T> readArray, int itemByteSize)
        {
            uint numOutputs = UnsafeNativeMethods.DeviceCapabilitiesW(this._deviceName, this._portName, capability, SafeMemoryHandle.Null, this._devMode);

            if (numOutputs < 1)
            {
                return(Array.Empty <T>());
            }

            HGlobalBuffer buffer = new HGlobalBuffer((int)(numOutputs * itemByteSize));

            try
            {
                numOutputs = UnsafeNativeMethods.DeviceCapabilitiesW(this._deviceName, this._portName, capability, buffer.Handle, this._devMode);
                if (numOutputs >= 0)
                {
                    return(readArray(buffer, itemByteSize));
                }
            }
            finally
            {
                buffer.Release();
            }

            return(null);
        }
        private static string [] ReadUnicodeStringArray(HGlobalBuffer buffer, int itemByteSize)
        {
            int nItems = buffer.Length / itemByteSize;

            string[] result = new string[nItems];

            bool shouldRelease = false;

            buffer.Handle.DangerousAddRef(ref shouldRelease);
            try
            {
                IntPtr baseAddr = buffer.Handle.DangerousGetHandle();
                for (int i = 0, offset = 0; i < nItems; i++, offset += itemByteSize)
                {
                    IntPtr strAddr = new IntPtr(baseAddr.ToInt64() + offset);
                    string str     = Marshal.PtrToStringUni(strAddr, itemByteSize / 2);

                    //Marshal.PtrToStringUni(IntPtr) Copies until '/0'
                    //Marshal.PtrToStringUni(IntPtr, int len) Copies all characters in the string including any '\0'
                    // What we want is to copy until '/0' but no more than len chars

                    int index = str.IndexOf('\0');
                    if (index >= 0)
                    {
                        str = str.Substring(0, index);
                    }
                    result[i] = str;
                }

                return(result);
            }
            finally
            {
                if (shouldRelease)
                {
                    buffer.Handle.DangerousRelease();
                }
            }
        }
예제 #5
0
            /// <summary>
            /// A callback that copies PRINTER_INFO_8_AND_9 fields from an unmanaged buffer
            /// </summary>
            public void Callback(HGlobalBuffer pPrinterBuffer)
            {
                // PRINTER_INFO_8 layout from http://msdn.microsoft.com/en-us/library/dd162851(VS.85).aspx
                //
                // typedef struct _PRINTER_INFO_8 {
                //  LPDEVMODE pDevMode;
                // } PRINTER_INFO_8, *PPRINTER_INFO_8;
                //
                // PRINTER_INFO_9 layout from http://msdn.microsoft.com/en-us/library/dd162852(VS.85).aspx
                //
                // typedef struct _PRINTER_INFO_9 {
                //  LPDEVMODE pDevMode;
                // } PRINTER_INFO_9, *PPRINTER_INFO_9;

                //  LPDEVMODE pDevMode;

                PRINTER_INFO_8_AND_9 = new PRINTER_INFO_8_AND_9();

                bool shouldRelease = false;

                pPrinterBuffer.Handle.DangerousAddRef(ref shouldRelease);
                try
                {
                    IntPtr pDevMode = Marshal.ReadIntPtr(pPrinterBuffer.Handle.DangerousGetHandle());
                    if (pDevMode != IntPtr.Zero)
                    {
                        PRINTER_INFO_8_AND_9.pDevMode = DevMode.FromIntPtr(pDevMode);
                    }
                }
                finally
                {
                    if (shouldRelease)
                    {
                        pPrinterBuffer.Handle.DangerousRelease();
                    }
                }
            }
예제 #6
0
        ///<summary>
        /// Executes an action delegate on an unmanaged buffer representing printer information
        ///</summary>
        ///<param name="dwLevel">Level of printer information to process</param>
        ///<param name="action">Delegate that processes printer information</param>
        ///<returns>False if tha call fails</returns>
        private bool GetPrinterW(uint dwLevel, Action <HGlobalBuffer> action)
        {
            uint dwNeeded = 0;

            UnsafeNativeMethods.GetPrinterW(this._deviceHandle, dwLevel, SafeMemoryHandle.Null, dwNeeded, ref dwNeeded);
            if (dwNeeded > 0)
            {
                HGlobalBuffer pPrinterBuffer = new HGlobalBuffer((int)dwNeeded);
                try
                {
                    if (UnsafeNativeMethods.GetPrinterW(this._deviceHandle, dwLevel, pPrinterBuffer.Handle, dwNeeded, ref dwNeeded))
                    {
                        action(pPrinterBuffer);
                        return(true);
                    }
                }
                finally
                {
                    pPrinterBuffer.Release();
                }
            }

            return(false);
        }
예제 #7
0
            /// <summary>
            /// A callback that copies PRINTER_INFO_2 fields from an unmanaged buffer
            /// </summary>
            public void Callback(HGlobalBuffer pPrinterBuffer)
            {
                // PRINTER_INFO_2 layout from http://msdn.microsoft.com/en-us/library/dd162845(VS.85).aspx
                //
                //typedef struct _PRINTER_INFO_2 {
                //   LPTSTR               pServerName;
                //   LPTSTR               pPrinterName;
                //   LPTSTR               pShareName;
                //   LPTSTR               pPortName;
                //   LPTSTR               pDriverName;
                //   LPTSTR               pComment;
                //   LPTSTR               pLocation;
                //   LPDEVMODE            pDevMode;
                //   LPTSTR               pSepFile;
                //   LPTSTR               pPrintProcessor;
                //   LPTSTR               pDatatype;
                //   LPTSTR               pParameters;
                //   PSECURITY_DESCRIPTOR pSecurityDescriptor;
                //   DWORD                Attributes;
                //   DWORD                Priority;
                //   DWORD                DefaultPriority;
                //   DWORD                StartTime;
                //   DWORD                UntilTime;
                //   DWORD                Status;
                //   DWORD                cJobs;
                //   DWORD                AveragePPM;
                // } PRINTER_INFO_2, *PPRINTER_INFO_2;


                PRINTER_INFO_2 = new PRINTER_INFO_2();

                bool shouldRelease = false;

                pPrinterBuffer.Handle.DangerousAddRef(ref shouldRelease);
                try
                {
                    IntPtr ptr = pPrinterBuffer.Handle.DangerousGetHandle();

                    //   LPTSTR               pPrinterName;
                    IntPtr pPrinterName = Marshal.ReadIntPtr(ptr, 1 * Marshal.SizeOf(typeof(IntPtr)));
                    if (pPrinterName != IntPtr.Zero)
                    {
                        PRINTER_INFO_2.pPrinterName = Marshal.PtrToStringUni(pPrinterName);
                    }

                    //   LPTSTR               pPortName;
                    IntPtr pPortName = Marshal.ReadIntPtr(ptr, 3 * Marshal.SizeOf(typeof(IntPtr)));
                    if (pPortName != IntPtr.Zero)
                    {
                        PRINTER_INFO_2.pPortName = Marshal.PtrToStringUni(pPortName);
                    }

                    //   LPTSTR               pDriverName;
                    IntPtr pDriverName = Marshal.ReadIntPtr(ptr, 4 * Marshal.SizeOf(typeof(IntPtr)));
                    if (pDriverName != IntPtr.Zero)
                    {
                        PRINTER_INFO_2.pDriverName = Marshal.PtrToStringUni(pDriverName);
                    }

                    //   LPDEVMODE            pDevMode;
                    IntPtr pDevMode = Marshal.ReadIntPtr(ptr, 7 * Marshal.SizeOf(typeof(IntPtr)));
                    if (pDevMode != IntPtr.Zero)
                    {
                        PRINTER_INFO_2.pDevMode = DevMode.FromIntPtr(pDevMode);
                    }
                }
                finally
                {
                    if (shouldRelease)
                    {
                        pPrinterBuffer.Handle.DangerousRelease();
                    }
                }
            }