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(); } } }
/// <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(); } } }
///<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); }
/// <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(); } } }