From e842ac948fa8124e8a1a8fca0403f57ba63829ed Mon Sep 17 00:00:00 2001 From: Tres Finocchiaro Date: Tue, 29 Mar 2022 10:47:26 -0400 Subject: [PATCH 01/22] Add missing PRINTER_INFO_X structs; Consolidate WinspoolUtil to use all 1-9 structs identically. --- .../com/sun/jna/platform/win32/WinGDI.java | 78 ++++ .../com/sun/jna/platform/win32/Winspool.java | 90 ++++ .../sun/jna/platform/win32/WinspoolUtil.java | 400 +++++++++++++----- 3 files changed, 469 insertions(+), 99 deletions(-) diff --git a/contrib/platform/src/com/sun/jna/platform/win32/WinGDI.java b/contrib/platform/src/com/sun/jna/platform/win32/WinGDI.java index 671e6f49ca..674aca3b9c 100644 --- a/contrib/platform/src/com/sun/jna/platform/win32/WinGDI.java +++ b/contrib/platform/src/com/sun/jna/platform/win32/WinGDI.java @@ -36,10 +36,88 @@ * Microsoft Windows SDK 6.0A. * @author dblock[at]dblock.org * @author Andreas "PAX" Lück, onkelpax-git[at]yahoo.de + * @author SSHTOOLS Limited, support@sshtools.com */ public interface WinGDI { int RDH_RECTANGLES = 1; + @FieldOrder({ "dmDeviceName", "dmSpecVersion", "dmDriverVersion", "dmSize", "dmDriverExtra", "dmFields", "dmUnion1", "dmColor", + "dmDuplex", "dmYResolution", "dmTTOption", "dmCollate", "dmFormName", "dmLogPixels", "dmBitsPerPel", "dmPelsWidth", + "dmPelsHeight", "dummyunionname2", "dmDisplayFrequency", "dmICMMethod", "dmICMIntent", "dmMediaType", "dmDitherType", + "dmReserved1", "dmReserved2", "dmPanningWidth", "dmPanningHeight" }) + + public static class DEVMODE extends Structure { + public byte[] dmDeviceName = new byte[Winspool.CCHDEVICENAME]; + public WORD dmSpecVersion; + public WORD dmDriverVersion; + public WORD dmSize; + public WORD dmDriverExtra; + public DWORD dmFields; + public DUMMYUNIONNAME dmUnion1; + + public static class DUMMYUNIONNAME extends Union { + public DUMMYSTRUCTNAME dummystructname; + + @FieldOrder({ "dmOrientation", "dmPaperSize", "dmPaperLength", "dmPaperWidth", "dmScale", "dmCopies", "dmDefaultSource", + "dmPrintQuality" }) + public static class DUMMYSTRUCTNAME extends Structure { + public short dmOrientation; + public short dmPaperSize; + public short dmPaperLength; + public short dmPaperWidth; + public short dmScale; + public short dmCopies; + public short dmDefaultSource; + public short dmPrintQuality; + + public DUMMYSTRUCTNAME() { + super(); + } + } + + public POINT dmPosition; + public DUMMYSTRUCTNAME2 dummystructname2; + + @FieldOrder({ "dmPosition", "dmDisplayOrientation", "dmDisplayFixedOutput" }) + public static class DUMMYSTRUCTNAME2 extends Structure { + public POINT dmPosition; + public DWORD dmDisplayOrientation; + public DWORD dmDisplayFixedOutput; + + public DUMMYSTRUCTNAME2() { + super(); + } + } + } + + public short dmColor; + public short dmDuplex; + public short dmYResolution; + public short dmTTOption; + public short dmCollate; + public byte[] dmFormName = new byte[Winspool2.CCHFORMNAME]; + public WORD dmLogPixels; + public DWORD dmBitsPerPel; + public DWORD dmPelsWidth; + public DWORD dmPelsHeight; + public DUMMYUNIONNAME2 dummyunionname2; + + public static class DUMMYUNIONNAME2 extends Union { + public DWORD dmDisplayFlags; + public DWORD dmNup; + } + + public DWORD dmDisplayFrequency; + public DWORD dmICMMethod; + public DWORD dmICMIntent; + public DWORD dmMediaType; + public DWORD dmDitherType; + public DWORD dmReserved1; + public DWORD dmReserved2; + public DWORD dmPanningWidth; + public DWORD dmPanningHeight; + } + @FieldOrder({"dwSize", "iType", "nCount", "nRgnSize", "rcBound"}) class RGNDATAHEADER extends Structure { public int dwSize = size(); diff --git a/contrib/platform/src/com/sun/jna/platform/win32/Winspool.java b/contrib/platform/src/com/sun/jna/platform/win32/Winspool.java index 7dcdac4cb4..bdb7723538 100644 --- a/contrib/platform/src/com/sun/jna/platform/win32/Winspool.java +++ b/contrib/platform/src/com/sun/jna/platform/win32/Winspool.java @@ -51,6 +51,7 @@ public interface Winspool extends StdCallLibrary { Winspool INSTANCE = Native.load("Winspool.drv", Winspool.class, W32APIOptions.DEFAULT_OPTIONS); public static final int CCHDEVICENAME = 32; + public static final int CCHFORMNAME = 32; public static final int PRINTER_STATUS_PAUSED = 0x00000001; public static final int PRINTER_STATUS_ERROR = 0x00000002; @@ -508,6 +509,20 @@ public boolean hasAttribute(int value) { } } + /** + * The PRINTER_INFO_3 structure specifies printer security information. + */ + @FieldOrder({"pSecurityDescriptor"}) + public static class PRINTER_INFO_3 extends Structure { + public WinNT.SECURITY_DESCRIPTOR_RELATIVE pSecurityDescriptor; + + public PRINTER_INFO_3() {} + + public PRINTER_INFO_3(int size) { + super(new Memory((long)size)); + } + } + /** * The PRINTER_INFO_4 structure specifies general printer information. *

@@ -546,6 +561,81 @@ public PRINTER_INFO_4(int size) { } } + /** + * The PRINTER_INFO_5 structure specifies detailed printer information. + */ + @FieldOrder({"pPrinterName", "pPortName", "Attributes", "DeviceNotSelectedTimeout", "TransmissionRetryTimeout" }) + public static class PRINTER_INFO_5 extends Structure { + public String pPrinterName; + public String pPortName; + public DWORD Attributes; + public DWORD DeviceNotSelectedTimeout; + public DWORD TransmissionRetryTimeout; + + public PRINTER_INFO_5() {} + + public PRINTER_INFO_5(int size) { + super(new Memory((long)size)); + } + } + + /** + * The PRINTER_INFO_6 structure specifies the status value of a printer. + */ + @FieldOrder({"dwStatus"}) + public static class PRINTER_INFO_6 extends Structure { + public DWORD dwStatus; + + public PRINTER_INFO_6() {} + + public PRINTER_INFO_6(int size) { + super(new Memory((long)size)); + } + } + + /** + * The PRINTER_INFO_7 structure specifies directory services printer information. + */ + @FieldOrder({"pszObjectGUID", "dwAction"}) + public static class PRINTER_INFO_7 extends Structure { + public String pszObjectGUID; + public DWORD dwAction; + + public PRINTER_INFO_7() {} + + public PRINTER_INFO_7(int size) { + super(new Memory((long)size)); + } + } + + /** + * The PRINTER_INFO_8 structure specifies the global default printer settings. + */ + @FieldOrder({"pDevMode"}) + public static class PRINTER_INFO_8 extends Structure { + public DEVMODE pDevMode; + + public PRINTER_INFO_8() {} + + public PRINTER_INFO_8(int size) { + super(new Memory((long)size)); + } + } + + /** + * The PRINTER_INFO_9 structure specifies the per-user default printer settings. + */ + @FieldOrder({"pDevMode"}) + public static class PRINTER_INFO_9 extends Structure { + public DEVMODE pDevMode; + + public PRINTER_INFO_9() {} + + public PRINTER_INFO_9(int size) { + super(new Memory((long)size)); + } + } + /** * The PRINTER_DEFAULTS structure specifies the default data type, * environment, initialization data, and access rights for a printer. diff --git a/contrib/platform/src/com/sun/jna/platform/win32/WinspoolUtil.java b/contrib/platform/src/com/sun/jna/platform/win32/WinspoolUtil.java index 34da367183..44131fb84f 100644 --- a/contrib/platform/src/com/sun/jna/platform/win32/WinspoolUtil.java +++ b/contrib/platform/src/com/sun/jna/platform/win32/WinspoolUtil.java @@ -37,92 +37,46 @@ * Winspool Utility API. * * @author dblock[at]dblock.org, Ivan Ridao Freitas, Padrus, Artem Vozhdayenko + * @author Tres Finocchiaro, tres.finocchiaro@gmail.com */ public abstract class WinspoolUtil { - public static PRINTER_INFO_1[] getPrinterInfo1() { - IntByReference pcbNeeded = new IntByReference(); - IntByReference pcReturned = new IntByReference(); - Winspool.INSTANCE.EnumPrinters(Winspool.PRINTER_ENUM_LOCAL, null, 1, - null, 0, pcbNeeded, pcReturned); - if (pcbNeeded.getValue() <= 0) { - return new PRINTER_INFO_1[0]; - } - - PRINTER_INFO_1 pPrinterEnum = new PRINTER_INFO_1(pcbNeeded.getValue()); - if (!Winspool.INSTANCE.EnumPrinters(Winspool.PRINTER_ENUM_LOCAL, null, - 1, pPrinterEnum.getPointer(), pcbNeeded.getValue(), pcbNeeded, - pcReturned)) { - throw new Win32Exception(Kernel32.INSTANCE.GetLastError()); - } - - pPrinterEnum.read(); - - return (PRINTER_INFO_1[]) pPrinterEnum.toArray(pcReturned.getValue()); - } - - public static PRINTER_INFO_2[] getPrinterInfo2() { - return getPrinterInfo2(Winspool.PRINTER_ENUM_LOCAL); - } - /** - * Returns printers that are physically attached to the local machine as - * well as remote printers to which it has a network connection. + * Helper for getting printer info struct by number, e.g. PRINTER_INFO_1 = 1, etc. */ - public static PRINTER_INFO_2[] getAllPrinterInfo2() { - // When Name is NULL, setting Flags to PRINTER_ENUM_LOCAL | PRINTER_ENUM_CONNECTIONS - // enumerates printers that are installed on the local machine. - // These printers include those that are physically attached to the local machine - // as well as remote printers to which it has a network connection. - // See https://msdn.microsoft.com/en-us/library/windows/desktop/dd162692(v=vs.85).aspx - return getPrinterInfo2(Winspool.PRINTER_ENUM_LOCAL | Winspool.PRINTER_ENUM_CONNECTIONS); - } - - private static PRINTER_INFO_2[] getPrinterInfo2(int flags) { - IntByReference pcbNeeded = new IntByReference(); - IntByReference pcReturned = new IntByReference(); - Winspool.INSTANCE.EnumPrinters(flags, null, 2, null, 0, pcbNeeded, pcReturned); - if (pcbNeeded.getValue() <= 0) { - return new PRINTER_INFO_2[0]; - } - - PRINTER_INFO_2 pPrinterEnum = new PRINTER_INFO_2(pcbNeeded.getValue()); - if (!Winspool.INSTANCE.EnumPrinters(flags, null, 2, pPrinterEnum.getPointer(), pcbNeeded.getValue(), pcbNeeded, - pcReturned)) { - throw new Win32Exception(Kernel32.INSTANCE.GetLastError()); - } - - pPrinterEnum.read(); - return (PRINTER_INFO_2[]) pPrinterEnum.toArray(pcReturned.getValue()); - } - - public static PRINTER_INFO_2 getPrinterInfo2(String printerName) { + static Structure getPrinterInfoByStruct(String printerName, int structType) { IntByReference pcbNeeded = new IntByReference(); IntByReference pcReturned = new IntByReference(); HANDLEByReference pHandle = new HANDLEByReference(); + // Get printer handle if (!Winspool.INSTANCE.OpenPrinter(printerName, pHandle, null)) { throw new Win32Exception(Kernel32.INSTANCE.GetLastError()); } Win32Exception we = null; - PRINTER_INFO_2 pinfo2 = null; + Structure struct = null; try { - Winspool.INSTANCE.GetPrinter(pHandle.getValue(), 2, null, 0, pcbNeeded); + // First pass: Get page size + Winspool.INSTANCE.GetPrinter(pHandle.getValue(), structType, null, 0, pcbNeeded); + + struct = initStructByType(structType, pcbNeeded.getValue()); if (pcbNeeded.getValue() <= 0) { - return new PRINTER_INFO_2(); + return struct; } - pinfo2 = new PRINTER_INFO_2(pcbNeeded.getValue()); - if (!Winspool.INSTANCE.GetPrinter(pHandle.getValue(), 2, pinfo2.getPointer(), pcbNeeded.getValue(), pcReturned)) { + // Second pass: Get printer information + if (!Winspool.INSTANCE.GetPrinter(pHandle.getValue(), structType, struct.getPointer(), pcbNeeded.getValue(), pcReturned)) { throw new Win32Exception(Kernel32.INSTANCE.GetLastError()); } - pinfo2.read(); - } catch (Win32Exception e) { + struct.read(); + } + catch(Win32Exception e) { we = e; - } finally { + } + finally { if (!Winspool.INSTANCE.ClosePrinter(pHandle.getValue())) { Win32Exception ex = new Win32Exception(Kernel32.INSTANCE.GetLastError()); if (we != null) { @@ -135,59 +89,307 @@ public static PRINTER_INFO_2 getPrinterInfo2(String printerName) { throw we; } - return pinfo2; + return struct; } - public static PRINTER_INFO_4[] getPrinterInfo4() { + /** + * Helper for getting array of printer info + * PRINTER_ENUM_LOCAL | PRINTER_ENUM_CONNECTIONS + */ + static Structure[] getPrinterInfoByStruct(int flags, int structType) { IntByReference pcbNeeded = new IntByReference(); IntByReference pcReturned = new IntByReference(); - Winspool.INSTANCE.EnumPrinters(Winspool.PRINTER_ENUM_LOCAL, null, 4, - null, 0, pcbNeeded, pcReturned); + // When Name is NULL, setting Flags to PRINTER_ENUM_LOCAL | PRINTER_ENUM_CONNECTIONS + // enumerates printers that are installed on the local machine. + // These printers include those that are physically attached to the local machine + // as well as remote printers to which it has a network connection. + // See https://msdn.microsoft.com/en-us/library/windows/desktop/dd162692(v=vs.85).aspx + Winspool.INSTANCE.EnumPrinters(flags, null, structType, null, 0, pcbNeeded, pcReturned); + Structure struct = initStructByType(structType, pcbNeeded.getValue()); if (pcbNeeded.getValue() <= 0) { - return new PRINTER_INFO_4[0]; + return emptyStructArrayByType(structType); } - - PRINTER_INFO_4 pPrinterEnum = new PRINTER_INFO_4(pcbNeeded.getValue()); - if (!Winspool.INSTANCE.EnumPrinters(Winspool.PRINTER_ENUM_LOCAL, null, - 4, pPrinterEnum.getPointer(), pcbNeeded.getValue(), pcbNeeded, + if (!Winspool.INSTANCE.EnumPrinters(flags, null, structType, struct.getPointer(), pcbNeeded.getValue(), pcbNeeded, pcReturned)) { throw new Win32Exception(Kernel32.INSTANCE.GetLastError()); } - pPrinterEnum.read(); - - return (PRINTER_INFO_4[]) pPrinterEnum.toArray(pcReturned.getValue()); + struct.read(); + return struct.toArray(pcReturned.getValue()); } - public static JOB_INFO_1[] getJobInfo1(HANDLEByReference phPrinter) { - IntByReference pcbNeeded = new IntByReference(); - IntByReference pcReturned = new IntByReference(); - Winspool.INSTANCE.EnumJobs(phPrinter.getValue(), 0, 255, 1, null, 0, - pcbNeeded, pcReturned); - if (pcbNeeded.getValue() <= 0) { - return new JOB_INFO_1[0]; + private static Structure[] emptyStructArrayByType(int structType) { + switch(structType) { + case 1: + return new PRINTER_INFO_1[0]; + case 2: + return new PRINTER_INFO_2[0]; + case 3: + return new PRINTER_INFO_3[0]; + case 4: + return new PRINTER_INFO_4[0]; + case 5: + return new PRINTER_INFO_5[0]; + case 6: + return new PRINTER_INFO_6[0]; + case 7: + return new PRINTER_INFO_7[0]; + case 8: + return new PRINTER_INFO_8[0]; + case 9: + return new PRINTER_INFO_9[0]; + default: + throw new UnsupportedOperationException("PRINTER_INFO_" + structType + " doesn't exist or has not been implemented"); } + } - int lastError = ERROR_SUCCESS; - JOB_INFO_1 pJobEnum; - do { - pJobEnum = new JOB_INFO_1(pcbNeeded.getValue()); - if (!Winspool.INSTANCE.EnumJobs(phPrinter.getValue(), 0, 255, 1, - pJobEnum.getPointer(), pcbNeeded.getValue(), pcbNeeded, - pcReturned)) { - lastError = Kernel32.INSTANCE.GetLastError(); - } - } while (lastError == ERROR_INSUFFICIENT_BUFFER); - if (lastError != ERROR_SUCCESS) { - throw new Win32Exception(lastError); - } - if (pcReturned.getValue() <= 0) { - return new JOB_INFO_1[0]; + private static Structure initStructByType(int structType, int size) { + switch(structType) { + case 1: + return size <= 0 ? new PRINTER_INFO_1() : new PRINTER_INFO_1(size); + case 2: + return size <= 0 ? new PRINTER_INFO_2() : new PRINTER_INFO_2(size); + case 3: + return size <= 0 ? new PRINTER_INFO_3() : new PRINTER_INFO_3(size); + case 4: + return size <= 0 ? new PRINTER_INFO_4() : new PRINTER_INFO_4(size); + case 5: + return size <= 0 ? new PRINTER_INFO_5() : new PRINTER_INFO_5(size); + case 6: + return size <= 0 ? new PRINTER_INFO_6() : new PRINTER_INFO_6(size); + case 7: + return size <= 0 ? new PRINTER_INFO_7() : new PRINTER_INFO_7(size); + case 8: + return size <= 0 ? new PRINTER_INFO_8() : new PRINTER_INFO_8(size); + case 9: + return size <= 0 ? new PRINTER_INFO_9() : new PRINTER_INFO_9(size); + default: + throw new UnsupportedOperationException("PRINTER_INFO_" + structType + " doesn't exist or has not been implemented"); } + } + + public static PRINTER_INFO_1[] getAllPrinterInfo1() { + return getPrinterInfo1(Winspool.PRINTER_ENUM_LOCAL | Winspool.PRINTER_ENUM_CONNECTIONS); + } + + public static PRINTER_INFO_2[] getAllPrinterInfo2() { + return getPrinterInfo2(Winspool.PRINTER_ENUM_LOCAL | Winspool.PRINTER_ENUM_CONNECTIONS); + } + + public static PRINTER_INFO_3[] getAllPrinterInfo3() { + return getPrinterInfo3(Winspool.PRINTER_ENUM_LOCAL | Winspool.PRINTER_ENUM_CONNECTIONS); + } + + public static PRINTER_INFO_4[] getAllPrinterInfo4() { + return getPrinterInfo4(Winspool.PRINTER_ENUM_LOCAL | Winspool.PRINTER_ENUM_CONNECTIONS); + } - pJobEnum.read(); + public static PRINTER_INFO_5[] getAllPrinterInfo5() { + return getPrinterInfo5(Winspool.PRINTER_ENUM_LOCAL | Winspool.PRINTER_ENUM_CONNECTIONS); + } + + public static PRINTER_INFO_6[] getAllPrinterInfo6() { + return getPrinterInfo6(Winspool.PRINTER_ENUM_LOCAL | Winspool.PRINTER_ENUM_CONNECTIONS); + } - return (JOB_INFO_1[]) pJobEnum.toArray(pcReturned.getValue()); + public static PRINTER_INFO_7[] getAllPrinterInfo7() { + return getPrinterInfo7(Winspool.PRINTER_ENUM_LOCAL | Winspool.PRINTER_ENUM_CONNECTIONS); } + public static PRINTER_INFO_8[] getAllPrinterInfo8() { + return getPrinterInfo8(Winspool.PRINTER_ENUM_LOCAL | Winspool.PRINTER_ENUM_CONNECTIONS); + } + + public static PRINTER_INFO_9[] getAllPrinterInfo9() { + return getPrinterInfo9(Winspool.PRINTER_ENUM_LOCAL | Winspool.PRINTER_ENUM_CONNECTIONS); + } + + /** + * The PRINTER_INFO_1 structure specifies general printer information. + */ + public static PRINTER_INFO_1[] getPrinterInfo1() { + return getPrinterInfo1(Winspool.PRINTER_ENUM_LOCAL); + } + + /** + * The PRINTER_INFO_1 structure specifies general printer information. + */ + public static PRINTER_INFO_1 getPrinterInfo1(String printerName) { + return (PRINTER_INFO_1)getPrinterInfoByStruct(printerName, 1); + } + + /** + * The PRINTER_INFO_1 structure specifies general printer information. + */ + public static PRINTER_INFO_1[] getPrinterInfo1(int flags) { + return (PRINTER_INFO_1[])getPrinterInfoByStruct(flags, 1); + } + + /** + * The PRINTER_INFO_2 structure specifies general printer information. + */ + public static PRINTER_INFO_2 getPrinterInfo2(String printerName) { + return (PRINTER_INFO_2)getPrinterInfoByStruct(printerName, 2); + } + + /** + * The PRINTER_INFO_2 structure specifies general printer information. + */ + public static PRINTER_INFO_2[] getPrinterInfo2(int flags) { + return (PRINTER_INFO_2[])getPrinterInfoByStruct(flags, 2); + } + + /** + * The PRINTER_INFO_2 structure specifies general printer information. + */ + public static PRINTER_INFO_2[] getPrinterInfo2() { + return getPrinterInfo2(Winspool.PRINTER_ENUM_LOCAL); + } + + /** + * The PRINTER_INFO_3 structure specifies printer security information. + */ + public static PRINTER_INFO_3 getPrinterInfo3(String printerName) { + return (PRINTER_INFO_3)getPrinterInfoByStruct(printerName, 3); + } + + /** + * The PRINTER_INFO_3 structure specifies printer security information. + */ + public static PRINTER_INFO_3[] getPrinterInfo3(int flags) { + return (PRINTER_INFO_3[])getPrinterInfoByStruct(flags, 3); + } + + /** + * The PRINTER_INFO_3 structure specifies printer security information. + */ + public static PRINTER_INFO_3[] getPrinterInfo3() { + return getPrinterInfo3(Winspool.PRINTER_ENUM_LOCAL); + } + + /** + * The PRINTER_INFO_4 structure specifies general printer information. + */ + public static PRINTER_INFO_4 getPrinterInfo4(String printerName) { + return (PRINTER_INFO_4)getPrinterInfoByStruct(printerName, 4); + } + + /** + * The PRINTER_INFO_4 structure specifies general printer information. + */ + public static PRINTER_INFO_4[] getPrinterInfo4(int flags) { + return (PRINTER_INFO_4[])getPrinterInfoByStruct(flags, 4); + } + + /** + * The PRINTER_INFO_4 structure specifies general printer information. + */ + public static PRINTER_INFO_4[] getPrinterInfo4() { + return getPrinterInfo4(PRINTER_ENUM_LOCAL); + } + + /** + * The PRINTER_INFO_5 structure specifies detailed printer information. + */ + public static PRINTER_INFO_5 getPrinterInfo5(String printerName) { + return (PRINTER_INFO_5)getPrinterInfoByStruct(printerName, 5); + } + + /** + * The PRINTER_INFO_5 structure specifies detailed printer information. + */ + public static PRINTER_INFO_5[] getPrinterInfo5(int flags) { + return (PRINTER_INFO_5[])getPrinterInfoByStruct(flags, 5); + } + + /** + * The PRINTER_INFO_5 structure specifies detailed printer information. + */ + public static PRINTER_INFO_5[] getPrinterInfo5() { + return getPrinterInfo5(PRINTER_ENUM_LOCAL); + } + + /** + * The PRINTER_INFO_6 specifies the status value of a printer. + */ + public static PRINTER_INFO_6 getPrinterInfo6(String printerName) { + return (PRINTER_INFO_6)getPrinterInfoByStruct(printerName, 6); + } + + /** + * The PRINTER_INFO_6 specifies the status value of a printer. + */ + public static PRINTER_INFO_6[] getPrinterInfo6(int flags) { + return (PRINTER_INFO_6[])getPrinterInfoByStruct(flags, 6); + } + + /** + * The PRINTER_INFO_6 specifies the status value of a printer. + */ + public static PRINTER_INFO_6[] getPrinterInfo6() { + return getPrinterInfo6(PRINTER_ENUM_LOCAL); + } + + /** + * The PRINTER_INFO_7 structure specifies directory services printer information. + */ + public static PRINTER_INFO_7 getPrinterInfo7(String printerName) { + return (PRINTER_INFO_7)getPrinterInfoByStruct(printerName, 7); + } + + /** + * The PRINTER_INFO_7 structure specifies directory services printer information. + */ + public static PRINTER_INFO_7[] getPrinterInfo7(int flags) { + return (PRINTER_INFO_7[])getPrinterInfoByStruct(flags, 7); + } + + /** + * The PRINTER_INFO_7 structure specifies directory services printer information. + */ + public static PRINTER_INFO_7[] getPrinterInfo7() { + return getPrinterInfo7(PRINTER_ENUM_LOCAL); + } + + /** + * The PRINTER_INFO_8 structure specifies the global default printer settings. + */ + public static PRINTER_INFO_8 getPrinterInfo8(String printerName) { + return (PRINTER_INFO_8)getPrinterInfoByStruct(printerName, 8); + } + + /** + * The PRINTER_INFO_8 structure specifies the global default printer settings. + */ + public static PRINTER_INFO_8[] getPrinterInfo8(int flags) { + return (PRINTER_INFO_8[])getPrinterInfoByStruct(flags, 8); + } + + /** + * The PRINTER_INFO_8 structure specifies the global default printer settings. + */ + public static PRINTER_INFO_8[] getPrinterInfo8() { + return getPrinterInfo8(PRINTER_ENUM_LOCAL); + } + + /** + * The PRINTER_INFO_9 Structure specifies the per-user default printer settings.\ + */ + public static PRINTER_INFO_9 getPrinterInfo9(String printerName) { + return (PRINTER_INFO_9)getPrinterInfoByStruct(printerName, 9); + } + + /** + * The PRINTER_INFO_9 Structure specifies the per-user default printer settings.\ + */ + public static PRINTER_INFO_9[] getPrinterInfo9(int flags) { + return (PRINTER_INFO_9[])getPrinterInfoByStruct(flags, 9); + } + + /** + * The PRINTER_INFO_9 Structure specifies the per-user default printer settings.\ + */ + public static PRINTER_INFO_9[] getPrinterInfo9() { + return getPrinterInfo9(PRINTER_ENUM_LOCAL); + } } \ No newline at end of file From 7880ff3dc78dd878d92048db9206994f4c0a8e73 Mon Sep 17 00:00:00 2001 From: Tres Finocchiaro Date: Tue, 29 Mar 2022 11:17:43 -0400 Subject: [PATCH 02/22] Fix compilation --- .../com/sun/jna/platform/win32/WinGDI.java | 7 ++- .../com/sun/jna/platform/win32/Winspool.java | 3 + .../sun/jna/platform/win32/WinspoolUtil.java | 62 ++++++++++++++----- 3 files changed, 53 insertions(+), 19 deletions(-) diff --git a/contrib/platform/src/com/sun/jna/platform/win32/WinGDI.java b/contrib/platform/src/com/sun/jna/platform/win32/WinGDI.java index 674aca3b9c..62023946f9 100644 --- a/contrib/platform/src/com/sun/jna/platform/win32/WinGDI.java +++ b/contrib/platform/src/com/sun/jna/platform/win32/WinGDI.java @@ -28,8 +28,9 @@ import com.sun.jna.Structure; import com.sun.jna.Structure.FieldOrder; import com.sun.jna.platform.win32.WinNT.HANDLE; -import com.sun.jna.platform.win32.WinDef.HBITMAP; -import com.sun.jna.platform.win32.WinDef.RECT; +import com.sun.jna.Union; + +import static com.sun.jna.platform.win32.WinDef.*; /** * Ported from WinGDI.h. @@ -95,7 +96,7 @@ public DUMMYSTRUCTNAME2() { public short dmYResolution; public short dmTTOption; public short dmCollate; - public byte[] dmFormName = new byte[Winspool2.CCHFORMNAME]; + public byte[] dmFormName = new byte[Winspool.CCHFORMNAME]; public WORD dmLogPixels; public DWORD dmBitsPerPel; public DWORD dmPelsWidth; diff --git a/contrib/platform/src/com/sun/jna/platform/win32/Winspool.java b/contrib/platform/src/com/sun/jna/platform/win32/Winspool.java index bdb7723538..7e8a959497 100644 --- a/contrib/platform/src/com/sun/jna/platform/win32/Winspool.java +++ b/contrib/platform/src/com/sun/jna/platform/win32/Winspool.java @@ -29,6 +29,7 @@ import com.sun.jna.Structure; import com.sun.jna.Structure.FieldOrder; import com.sun.jna.Union; +import com.sun.jna.platform.win32.WinGDI.DEVMODE; import com.sun.jna.platform.win32.WinBase.SYSTEMTIME; import com.sun.jna.platform.win32.WinDef.DWORD; import com.sun.jna.platform.win32.WinDef.DWORDByReference; @@ -41,6 +42,8 @@ import com.sun.jna.win32.StdCallLibrary; import com.sun.jna.win32.W32APIOptions; +import static com.sun.jna.platform.win32.WinDef.*; + /** * Ported from Winspool.h. Windows SDK 6.0a * diff --git a/contrib/platform/src/com/sun/jna/platform/win32/WinspoolUtil.java b/contrib/platform/src/com/sun/jna/platform/win32/WinspoolUtil.java index 44131fb84f..b6430bd1db 100644 --- a/contrib/platform/src/com/sun/jna/platform/win32/WinspoolUtil.java +++ b/contrib/platform/src/com/sun/jna/platform/win32/WinspoolUtil.java @@ -25,13 +25,12 @@ import static com.sun.jna.platform.win32.WinError.ERROR_INSUFFICIENT_BUFFER; import static com.sun.jna.platform.win32.WinError.ERROR_SUCCESS; +import static com.sun.jna.platform.win32.Winspool.*; import com.sun.jna.platform.win32.WinNT.HANDLEByReference; -import com.sun.jna.platform.win32.Winspool.JOB_INFO_1; -import com.sun.jna.platform.win32.Winspool.PRINTER_INFO_1; -import com.sun.jna.platform.win32.Winspool.PRINTER_INFO_2; -import com.sun.jna.platform.win32.Winspool.PRINTER_INFO_4; +import com.sun.jna.platform.win32.Winspool; import com.sun.jna.ptr.IntByReference; +import com.sun.jna.Structure; /** * Winspool Utility API. @@ -168,47 +167,78 @@ private static Structure initStructByType(int structType, int size) { } } + public static JOB_INFO_1[] getJobInfo1(HANDLEByReference phPrinter) { + IntByReference pcbNeeded = new IntByReference(); + IntByReference pcReturned = new IntByReference(); + Winspool.INSTANCE.EnumJobs(phPrinter.getValue(), 0, 255, 1, null, 0, + pcbNeeded, pcReturned); + if (pcbNeeded.getValue() <= 0) { + return new JOB_INFO_1[0]; + } + + int lastError = ERROR_SUCCESS; + JOB_INFO_1 pJobEnum; + do { + pJobEnum = new JOB_INFO_1(pcbNeeded.getValue()); + if (!Winspool.INSTANCE.EnumJobs(phPrinter.getValue(), 0, 255, 1, + pJobEnum.getPointer(), pcbNeeded.getValue(), pcbNeeded, + pcReturned)) { + lastError = Kernel32.INSTANCE.GetLastError(); + } + } while (lastError == ERROR_INSUFFICIENT_BUFFER); + if (lastError != ERROR_SUCCESS) { + throw new Win32Exception(lastError); + } + if (pcReturned.getValue() <= 0) { + return new JOB_INFO_1[0]; + } + + pJobEnum.read(); + + return (JOB_INFO_1[]) pJobEnum.toArray(pcReturned.getValue()); + } + public static PRINTER_INFO_1[] getAllPrinterInfo1() { - return getPrinterInfo1(Winspool.PRINTER_ENUM_LOCAL | Winspool.PRINTER_ENUM_CONNECTIONS); + return getPrinterInfo1(PRINTER_ENUM_LOCAL | PRINTER_ENUM_CONNECTIONS); } public static PRINTER_INFO_2[] getAllPrinterInfo2() { - return getPrinterInfo2(Winspool.PRINTER_ENUM_LOCAL | Winspool.PRINTER_ENUM_CONNECTIONS); + return getPrinterInfo2(PRINTER_ENUM_LOCAL | PRINTER_ENUM_CONNECTIONS); } public static PRINTER_INFO_3[] getAllPrinterInfo3() { - return getPrinterInfo3(Winspool.PRINTER_ENUM_LOCAL | Winspool.PRINTER_ENUM_CONNECTIONS); + return getPrinterInfo3(PRINTER_ENUM_LOCAL | PRINTER_ENUM_CONNECTIONS); } public static PRINTER_INFO_4[] getAllPrinterInfo4() { - return getPrinterInfo4(Winspool.PRINTER_ENUM_LOCAL | Winspool.PRINTER_ENUM_CONNECTIONS); + return getPrinterInfo4(PRINTER_ENUM_LOCAL | PRINTER_ENUM_CONNECTIONS); } public static PRINTER_INFO_5[] getAllPrinterInfo5() { - return getPrinterInfo5(Winspool.PRINTER_ENUM_LOCAL | Winspool.PRINTER_ENUM_CONNECTIONS); + return getPrinterInfo5(PRINTER_ENUM_LOCAL | PRINTER_ENUM_CONNECTIONS); } public static PRINTER_INFO_6[] getAllPrinterInfo6() { - return getPrinterInfo6(Winspool.PRINTER_ENUM_LOCAL | Winspool.PRINTER_ENUM_CONNECTIONS); + return getPrinterInfo6(PRINTER_ENUM_LOCAL | PRINTER_ENUM_CONNECTIONS); } public static PRINTER_INFO_7[] getAllPrinterInfo7() { - return getPrinterInfo7(Winspool.PRINTER_ENUM_LOCAL | Winspool.PRINTER_ENUM_CONNECTIONS); + return getPrinterInfo7(PRINTER_ENUM_LOCAL | PRINTER_ENUM_CONNECTIONS); } public static PRINTER_INFO_8[] getAllPrinterInfo8() { - return getPrinterInfo8(Winspool.PRINTER_ENUM_LOCAL | Winspool.PRINTER_ENUM_CONNECTIONS); + return getPrinterInfo8(PRINTER_ENUM_LOCAL | PRINTER_ENUM_CONNECTIONS); } public static PRINTER_INFO_9[] getAllPrinterInfo9() { - return getPrinterInfo9(Winspool.PRINTER_ENUM_LOCAL | Winspool.PRINTER_ENUM_CONNECTIONS); + return getPrinterInfo9(PRINTER_ENUM_LOCAL | PRINTER_ENUM_CONNECTIONS); } /** * The PRINTER_INFO_1 structure specifies general printer information. */ public static PRINTER_INFO_1[] getPrinterInfo1() { - return getPrinterInfo1(Winspool.PRINTER_ENUM_LOCAL); + return getPrinterInfo1(PRINTER_ENUM_LOCAL); } /** @@ -243,7 +273,7 @@ public static PRINTER_INFO_2[] getPrinterInfo2(int flags) { * The PRINTER_INFO_2 structure specifies general printer information. */ public static PRINTER_INFO_2[] getPrinterInfo2() { - return getPrinterInfo2(Winspool.PRINTER_ENUM_LOCAL); + return getPrinterInfo2(PRINTER_ENUM_LOCAL); } /** @@ -264,7 +294,7 @@ public static PRINTER_INFO_3[] getPrinterInfo3(int flags) { * The PRINTER_INFO_3 structure specifies printer security information. */ public static PRINTER_INFO_3[] getPrinterInfo3() { - return getPrinterInfo3(Winspool.PRINTER_ENUM_LOCAL); + return getPrinterInfo3(PRINTER_ENUM_LOCAL); } /** From a8168629a62c23c9b82b7d85c730d31f9571419e Mon Sep 17 00:00:00 2001 From: Tres Finocchiaro Date: Tue, 29 Mar 2022 12:26:19 -0400 Subject: [PATCH 03/22] Fix byte arrays --- contrib/platform/src/com/sun/jna/platform/win32/WinGDI.java | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/contrib/platform/src/com/sun/jna/platform/win32/WinGDI.java b/contrib/platform/src/com/sun/jna/platform/win32/WinGDI.java index 62023946f9..6e74361d14 100644 --- a/contrib/platform/src/com/sun/jna/platform/win32/WinGDI.java +++ b/contrib/platform/src/com/sun/jna/platform/win32/WinGDI.java @@ -48,7 +48,9 @@ public interface WinGDI { "dmReserved1", "dmReserved2", "dmPanningWidth", "dmPanningHeight" }) public static class DEVMODE extends Structure { - public byte[] dmDeviceName = new byte[Winspool.CCHDEVICENAME]; + private static final int CHAR_WIDTH = Boolean.getBoolean("w32.ascii") ? 1 : 2; + + public byte[] dmDeviceName = new byte[Winspool.CCHDEVICENAME * CHAR_WIDTH]; public WORD dmSpecVersion; public WORD dmDriverVersion; public WORD dmSize; @@ -96,7 +98,7 @@ public DUMMYSTRUCTNAME2() { public short dmYResolution; public short dmTTOption; public short dmCollate; - public byte[] dmFormName = new byte[Winspool.CCHFORMNAME]; + public byte[] dmFormName = new byte[Winspool.CCHFORMNAME * CHAR_WIDTH]; public WORD dmLogPixels; public DWORD dmBitsPerPel; public DWORD dmPelsWidth; From 399136d9b70de2ca5947db813b2a53ffb5961acb Mon Sep 17 00:00:00 2001 From: Tres Finocchiaro Date: Tue, 29 Mar 2022 15:34:17 -0400 Subject: [PATCH 04/22] Switch DEVMODE to use Pointer --- contrib/platform/src/com/sun/jna/platform/win32/WinGDI.java | 2 ++ contrib/platform/src/com/sun/jna/platform/win32/Winspool.java | 4 ++-- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/contrib/platform/src/com/sun/jna/platform/win32/WinGDI.java b/contrib/platform/src/com/sun/jna/platform/win32/WinGDI.java index 6e74361d14..1ae61a4eeb 100644 --- a/contrib/platform/src/com/sun/jna/platform/win32/WinGDI.java +++ b/contrib/platform/src/com/sun/jna/platform/win32/WinGDI.java @@ -48,6 +48,8 @@ public interface WinGDI { "dmReserved1", "dmReserved2", "dmPanningWidth", "dmPanningHeight" }) public static class DEVMODE extends Structure { + public static class ByReference extends DEVMODE implements Structure.ByReference {} + private static final int CHAR_WIDTH = Boolean.getBoolean("w32.ascii") ? 1 : 2; public byte[] dmDeviceName = new byte[Winspool.CCHDEVICENAME * CHAR_WIDTH]; diff --git a/contrib/platform/src/com/sun/jna/platform/win32/Winspool.java b/contrib/platform/src/com/sun/jna/platform/win32/Winspool.java index 7e8a959497..991aa91549 100644 --- a/contrib/platform/src/com/sun/jna/platform/win32/Winspool.java +++ b/contrib/platform/src/com/sun/jna/platform/win32/Winspool.java @@ -616,7 +616,7 @@ public PRINTER_INFO_7(int size) { */ @FieldOrder({"pDevMode"}) public static class PRINTER_INFO_8 extends Structure { - public DEVMODE pDevMode; + public DEVMODE.ByReference pDevMode; public PRINTER_INFO_8() {} @@ -630,7 +630,7 @@ public PRINTER_INFO_8(int size) { */ @FieldOrder({"pDevMode"}) public static class PRINTER_INFO_9 extends Structure { - public DEVMODE pDevMode; + public DEVMODE.ByReference pDevMode; public PRINTER_INFO_9() {} From 820eb7faa4cccd47c16ded602d7a4ed74a528f6a Mon Sep 17 00:00:00 2001 From: Tres Finocchiaro Date: Tue, 29 Mar 2022 18:03:55 -0400 Subject: [PATCH 05/22] Add helper for byte[] to String --- .../src/com/sun/jna/platform/win32/WinGDI.java | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/contrib/platform/src/com/sun/jna/platform/win32/WinGDI.java b/contrib/platform/src/com/sun/jna/platform/win32/WinGDI.java index 1ae61a4eeb..1f4f7e2105 100644 --- a/contrib/platform/src/com/sun/jna/platform/win32/WinGDI.java +++ b/contrib/platform/src/com/sun/jna/platform/win32/WinGDI.java @@ -121,6 +121,22 @@ public static class DUMMYUNIONNAME2 extends Union { public DWORD dmReserved2; public DWORD dmPanningWidth; public DWORD dmPanningHeight; + + /** + * Converts dmDeviceName from raw byte[] to String + */ + public String getDmDeviceName() { + int offset = fieldOffset("dmDeviceName"); + return CHAR_WIDTH == 1 ? getPointer().getString(offset) : getPointer().getWideString(offset); + } + + /** + * Converts dmFormName from raw byte[] to String + */ + public String getDmFormName() { + int offset = fieldOffset("dmFormName"); + return CHAR_WIDTH == 1 ? getPointer().getString(offset) : getPointer().getWideString(offset); + } } @FieldOrder({"dwSize", "iType", "nCount", "nRgnSize", "rcBound"}) From eefe7de53677e6d8e6c1ac3906b158b32dda8784 Mon Sep 17 00:00:00 2001 From: Tres Finocchiaro Date: Tue, 29 Mar 2022 22:00:00 -0400 Subject: [PATCH 06/22] Improve comments, javadocs --- .../com/sun/jna/platform/win32/Winspool.java | 145 +++++++++++++++--- .../sun/jna/platform/win32/WinspoolUtil.java | 6 +- 2 files changed, 129 insertions(+), 22 deletions(-) diff --git a/contrib/platform/src/com/sun/jna/platform/win32/Winspool.java b/contrib/platform/src/com/sun/jna/platform/win32/Winspool.java index 991aa91549..d36ea3e601 100644 --- a/contrib/platform/src/com/sun/jna/platform/win32/Winspool.java +++ b/contrib/platform/src/com/sun/jna/platform/win32/Winspool.java @@ -56,6 +56,12 @@ public interface Winspool extends StdCallLibrary { public static final int CCHDEVICENAME = 32; public static final int CCHFORMNAME = 32; + public static final int DSPRINT_PUBLISH = 0x00000001; + public static final int DSPRINT_UPDATE = 0x00000002; + public static final int DSPRINT_UNPUBLISH = 0x00000004; + public static final int DSPRINT_REPUBLISH = 0x00000008; + public static final int DSPRINT_PENDING = 0x80000000; + public static final int PRINTER_STATUS_PAUSED = 0x00000001; public static final int PRINTER_STATUS_ERROR = 0x00000002; public static final int PRINTER_STATUS_PENDING_DELETION = 0x00000004; @@ -285,7 +291,7 @@ public interface Winspool extends StdCallLibrary { * the function fails, the return value is zero. * * @see + * "https://docs.microsoft.com/windows/win32/printdocs/enumprinters"> * EnumPrinters function */ boolean EnumPrinters(int Flags, String Name, int Level, @@ -322,7 +328,7 @@ boolean EnumPrinters(int Flags, String Name, int Level, * the function fails, the return value is zero. * * @see + * "https://docs.microsoft.com/windows/win32/printdocs/getprinter"> * GetPrinter function */ boolean GetPrinter(HANDLE hPrinter, int Level, Pointer pPrinter, int cbBuf, IntByReference pcbNeeded); @@ -331,7 +337,7 @@ boolean EnumPrinters(int Flags, String Name, int Level, * The PRINTER_INFO_1 structure specifies general printer information. * * @see + * "https://docs.microsoft.com/windows/win32/printdocs/printer-info-1"> * PRINTER_INFO_1 structure */ @FieldOrder({"Flags", "pDescription", "pName", "pComment"}) @@ -372,7 +378,7 @@ public PRINTER_INFO_1(int size) { * * @author Ivan Ridao Freitas, Padrus * @see + * "https://docs.microsoft.com/windows/win32/printdocs/printer-info-2"> * PRINTER_INFO_2 structure */ @FieldOrder({"pServerName", "pPrinterName", "pShareName", @@ -514,9 +520,23 @@ public boolean hasAttribute(int value) { /** * The PRINTER_INFO_3 structure specifies printer security information. + *

+ * The structure lets an application get and set a printer's security descriptor. + * The caller may do so even if it lacks specific printer permissions, as long + * as it has the standard rights described in SetPrinter and GetPrinter. Thus, + * an application may temporarily deny all access to a printer, while allowing + * the owner of the printer to have access to the printer's discretionary ACL. + * + * @see + * PRINTER_INFO_3 structure */ @FieldOrder({"pSecurityDescriptor"}) public static class PRINTER_INFO_3 extends Structure { + + /** + * Pointer to a SECURITY_DESCRIPTOR structure that specifies a printer's security information. + */ public WinNT.SECURITY_DESCRIPTOR_RELATIVE pSecurityDescriptor; public PRINTER_INFO_3() {} @@ -535,7 +555,7 @@ public PRINTER_INFO_3(int size) { * all remote printer connections that a user has established. * * @see + * "https://docs.microsoft.com/windows/win32/printdocs/printer-info-4"> * PRINTER_INFO_4 structure */ @FieldOrder({"pPrinterName", "pServerName", "Attributes"}) @@ -566,13 +586,44 @@ public PRINTER_INFO_4(int size) { /** * The PRINTER_INFO_5 structure specifies detailed printer information. + * + * @see + * PRINTER_INFO_5 structure */ - @FieldOrder({"pPrinterName", "pPortName", "Attributes", "DeviceNotSelectedTimeout", "TransmissionRetryTimeout" }) + @FieldOrder({"pPrinterName", "pPortName", "Attributes", "DeviceNotSelectedTimeout", + "TransmissionRetryTimeout"}) public static class PRINTER_INFO_5 extends Structure { + + /** + * Pointer to a null-terminated string that specifies the name of the + * printer (local or remote). + */ public String pPrinterName; + + /** + * A pointer to a null-terminated string that identifies the port(s) + * used to transmit data to the printer. If a printer is connected + * to more than one port, the names of each port must be separated + * by commas (for example, "LPT1:,LPT2:,LPT3:"). + */ public String pPortName; + + /** + * The printer attributes. This member can be any reasonable combination + * of PRINTER_ATTRIBUTE_* values + * + */ public DWORD Attributes; + + /** + * This value is not used. + */ public DWORD DeviceNotSelectedTimeout; + + /** + * This value is not used. + */ public DWORD TransmissionRetryTimeout; public PRINTER_INFO_5() {} @@ -584,9 +635,17 @@ public PRINTER_INFO_5(int size) { /** * The PRINTER_INFO_6 structure specifies the status value of a printer. + * + * @see + * PRINTER_INFO_6 structure */ @FieldOrder({"dwStatus"}) public static class PRINTER_INFO_6 extends Structure { + /** + * The printer status. This member can be any reasonable combination + * of PRINTER_STATUS_* values. + */ public DWORD dwStatus; public PRINTER_INFO_6() {} @@ -598,10 +657,35 @@ public PRINTER_INFO_6(int size) { /** * The PRINTER_INFO_7 structure specifies directory services printer information. + *

+ * The structure specifies directory services printer information. Use this + * structure with the SetPrinter function to publish a printer's + * data in the directory service (DS), or to update or remove a printer's + * published data from the DS. Use this structure with the GetPrinter + * function to determine whether a printer is published in the DS. + * + * @see + * PRINTER_INFO_7 structure */ @FieldOrder({"pszObjectGUID", "dwAction"}) public static class PRINTER_INFO_7 extends Structure { + + /** + * A pointer to a null-terminated string containing the GUID of the directory + * service print queue object associated with a published printer. Use the + * GetPrinter function to retrieve this GUID. + * + * Before calling SetPrinter, set pszObjectGUID to NULL. + */ public String pszObjectGUID; + + /** + * Indicates the action for the SetPrinter function to perform. For the + * GetPrinter function, this member indicates whether the specified + * printer is published. This member can be a combination of DSPRINT_* + * values. + */ public DWORD dwAction; public PRINTER_INFO_7() {} @@ -613,9 +697,22 @@ public PRINTER_INFO_7(int size) { /** * The PRINTER_INFO_8 structure specifies the global default printer settings. + *

+ * The global defaults are set by the administrator of a printer that can be + * used by anyone. In contrast, the per-user defaults will affect a particular + * user or anyone else who uses the profile. For per-user defaults, + * use PRINTER_INFO_9. + * + * @see + * PRINTER_INFO_8 structure */ @FieldOrder({"pDevMode"}) public static class PRINTER_INFO_8 extends Structure { + /** + * A pointer to a DEVMODE structure that defines the global + * default printer data such as the paper orientation and the resolution. + */ public DEVMODE.ByReference pDevMode; public PRINTER_INFO_8() {} @@ -627,6 +724,14 @@ public PRINTER_INFO_8(int size) { /** * The PRINTER_INFO_9 structure specifies the per-user default printer settings. + *

+ * The per-user defaults will affect only a particular user or anyone who uses the + * profile. In contrast, the global defaults are set by the administrator of a printer + * that can be used by anyone. For global defaults, use PRINTER_INFO_8. + * + * @see + * PRINTER_INFO_9 structure */ @FieldOrder({"pDevMode"}) public static class PRINTER_INFO_9 extends Structure { @@ -643,7 +748,8 @@ public PRINTER_INFO_9(int size) { * The PRINTER_DEFAULTS structure specifies the default data type, * environment, initialization data, and access rights for a printer. * - * @see PRINTER_DEFAULTS structure + * @see + * PRINTER_DEFAULTS structure */ @FieldOrder({"pDatatype", "pDevMode", "DesiredAccess"}) public class LPPRINTER_DEFAULTS extends Structure { @@ -690,7 +796,8 @@ public class LPPRINTER_DEFAULTS extends Structure { * @return If the function succeeds, the return value is a nonzero value. If * the function fails, the return value is zero. * - * @see OpenPrinter function + * @see + * OpenPrinter function */ boolean OpenPrinter( // _In_ @@ -721,7 +828,7 @@ boolean OpenPrinter( * the function fails, the return value is zero. * * @see + * "https://docs.microsoft.com/windows/win32/printdocs/closeprinter"> * ClosePrinter function */ boolean ClosePrinter(HANDLE hPrinter); @@ -731,7 +838,7 @@ boolean OpenPrinter( * notification object that monitors a printer or print server. * * @see - * + * * PRINTER_NOTIFY_OPTIONS structure * */ @@ -774,7 +881,7 @@ public class PRINTER_NOTIFY_OPTIONS extends Structure { * notification object. * * @see - * + * * PRINTER_NOTIFY_OPTIONS_TYPE structure * */ @@ -837,7 +944,7 @@ public short[] getFields() { * object has been satisfied. * * @see - * + * * PRINTER_NOTIFY_INFO structure * */ @@ -929,7 +1036,7 @@ public class NOTIFY_DATA extends Union { * information field and provides the current data for that field. * * @see - * + * * PRINTER_NOTIFY_INFO_DATA structure * */ @@ -1077,7 +1184,7 @@ HANDLE FindFirstPrinterChangeNotification( * INVALID_HANDLE_VALUE. * * @see + * "https://docs.microsoft.com/windows/win32/printdocs/findfirstprinterchangenotification"> * FindFirstPrinterChangeNotification function */ HANDLE FindFirstPrinterChangeNotification( @@ -1161,7 +1268,7 @@ boolean FindNextPrinterChangeNotification( * the function fails, the return value is zero. * * @see + * "https://docs.microsoft.com/windows/win32/printdocs/findnextprinterchangenotification"> * FindClosePrinterChangeNotification function */ boolean FindNextPrinterChangeNotification( @@ -1190,7 +1297,7 @@ boolean FindNextPrinterChangeNotification( * the function fails, the return value is zero. * * @see + * "https://docs.microsoft.com/windows/win32/printdocs/findcloseprinterchangenotification"> * FindClosePrinterChangeNotification function */ boolean FindClosePrinterChangeNotification( @@ -1210,7 +1317,7 @@ boolean FindClosePrinterChangeNotification( * the function fails, the return value is zero. * * @see - * + * * FreePrinterNotifyInfo function * */ @@ -1251,7 +1358,7 @@ boolean FreePrinterNotifyInfo( * the function fails, the return value is zero. * * @see + * "https://docs.microsoft.com/windows/win32/printdocs/enumjobs"> * EnumJobs function */ boolean EnumJobs( @@ -1279,7 +1386,7 @@ boolean EnumJobs( * the user that owns the print job, and so on. * * @see + * "https://docs.microsoft.com/windows/win32/printdocs/job-info-1"> * JOB_INFO_1 structure */ @FieldOrder({"JobId", "pPrinterName", "pMachineName", "pUserName", diff --git a/contrib/platform/src/com/sun/jna/platform/win32/WinspoolUtil.java b/contrib/platform/src/com/sun/jna/platform/win32/WinspoolUtil.java index b6430bd1db..5700df380e 100644 --- a/contrib/platform/src/com/sun/jna/platform/win32/WinspoolUtil.java +++ b/contrib/platform/src/com/sun/jna/platform/win32/WinspoolUtil.java @@ -403,21 +403,21 @@ public static PRINTER_INFO_8[] getPrinterInfo8() { } /** - * The PRINTER_INFO_9 Structure specifies the per-user default printer settings.\ + * The PRINTER_INFO_9 Structure specifies the per-user default printer settings. */ public static PRINTER_INFO_9 getPrinterInfo9(String printerName) { return (PRINTER_INFO_9)getPrinterInfoByStruct(printerName, 9); } /** - * The PRINTER_INFO_9 Structure specifies the per-user default printer settings.\ + * The PRINTER_INFO_9 Structure specifies the per-user default printer settings. */ public static PRINTER_INFO_9[] getPrinterInfo9(int flags) { return (PRINTER_INFO_9[])getPrinterInfoByStruct(flags, 9); } /** - * The PRINTER_INFO_9 Structure specifies the per-user default printer settings.\ + * The PRINTER_INFO_9 Structure specifies the per-user default printer settings. */ public static PRINTER_INFO_9[] getPrinterInfo9() { return getPrinterInfo9(PRINTER_ENUM_LOCAL); From b8caf8bd0e5ec4a7e5ce260cb7013bec4ca6b719 Mon Sep 17 00:00:00 2001 From: Tres Finocchiaro Date: Tue, 29 Mar 2022 22:19:23 -0400 Subject: [PATCH 07/22] Favor int, short over DWORD, WORD --- .../com/sun/jna/platform/win32/WinGDI.java | 44 +++++++++---------- .../com/sun/jna/platform/win32/Winspool.java | 18 ++++---- 2 files changed, 31 insertions(+), 31 deletions(-) diff --git a/contrib/platform/src/com/sun/jna/platform/win32/WinGDI.java b/contrib/platform/src/com/sun/jna/platform/win32/WinGDI.java index 1f4f7e2105..324360ced3 100644 --- a/contrib/platform/src/com/sun/jna/platform/win32/WinGDI.java +++ b/contrib/platform/src/com/sun/jna/platform/win32/WinGDI.java @@ -53,11 +53,11 @@ public static class ByReference extends DEVMODE implements Structure.ByReference private static final int CHAR_WIDTH = Boolean.getBoolean("w32.ascii") ? 1 : 2; public byte[] dmDeviceName = new byte[Winspool.CCHDEVICENAME * CHAR_WIDTH]; - public WORD dmSpecVersion; - public WORD dmDriverVersion; - public WORD dmSize; - public WORD dmDriverExtra; - public DWORD dmFields; + public short dmSpecVersion; + public short dmDriverVersion; + public short dmSize; + public short dmDriverExtra; + public int dmFields; public DUMMYUNIONNAME dmUnion1; public static class DUMMYUNIONNAME extends Union { @@ -86,8 +86,8 @@ public DUMMYSTRUCTNAME() { @FieldOrder({ "dmPosition", "dmDisplayOrientation", "dmDisplayFixedOutput" }) public static class DUMMYSTRUCTNAME2 extends Structure { public POINT dmPosition; - public DWORD dmDisplayOrientation; - public DWORD dmDisplayFixedOutput; + public int dmDisplayOrientation; + public int dmDisplayFixedOutput; public DUMMYSTRUCTNAME2() { super(); @@ -101,26 +101,26 @@ public DUMMYSTRUCTNAME2() { public short dmTTOption; public short dmCollate; public byte[] dmFormName = new byte[Winspool.CCHFORMNAME * CHAR_WIDTH]; - public WORD dmLogPixels; - public DWORD dmBitsPerPel; - public DWORD dmPelsWidth; - public DWORD dmPelsHeight; + public short dmLogPixels; + public int dmBitsPerPel; + public int dmPelsWidth; + public int dmPelsHeight; public DUMMYUNIONNAME2 dummyunionname2; public static class DUMMYUNIONNAME2 extends Union { - public DWORD dmDisplayFlags; - public DWORD dmNup; + public int dmDisplayFlags; + public int dmNup; } - public DWORD dmDisplayFrequency; - public DWORD dmICMMethod; - public DWORD dmICMIntent; - public DWORD dmMediaType; - public DWORD dmDitherType; - public DWORD dmReserved1; - public DWORD dmReserved2; - public DWORD dmPanningWidth; - public DWORD dmPanningHeight; + public int dmDisplayFrequency; + public int dmICMMethod; + public int dmICMIntent; + public int dmMediaType; + public int dmDitherType; + public int dmReserved1; + public int dmReserved2; + public int dmPanningWidth; + public int dmPanningHeight; /** * Converts dmDeviceName from raw byte[] to String diff --git a/contrib/platform/src/com/sun/jna/platform/win32/Winspool.java b/contrib/platform/src/com/sun/jna/platform/win32/Winspool.java index d36ea3e601..b2442fe42f 100644 --- a/contrib/platform/src/com/sun/jna/platform/win32/Winspool.java +++ b/contrib/platform/src/com/sun/jna/platform/win32/Winspool.java @@ -573,7 +573,7 @@ public static class PRINTER_INFO_4 extends Structure { /** * Specifies information about the returned data. */ - public DWORD Attributes; + public int Attributes; public PRINTER_INFO_4() { super(); @@ -611,20 +611,20 @@ public static class PRINTER_INFO_5 extends Structure { /** * The printer attributes. This member can be any reasonable combination - * of PRINTER_ATTRIBUTE_* values + * of PRINTER_ATTRIBUTE_XXX values * */ - public DWORD Attributes; + public int Attributes; /** * This value is not used. */ - public DWORD DeviceNotSelectedTimeout; + public int DeviceNotSelectedTimeout; /** * This value is not used. */ - public DWORD TransmissionRetryTimeout; + public int TransmissionRetryTimeout; public PRINTER_INFO_5() {} @@ -644,9 +644,9 @@ public PRINTER_INFO_5(int size) { public static class PRINTER_INFO_6 extends Structure { /** * The printer status. This member can be any reasonable combination - * of PRINTER_STATUS_* values. + * of PRINTER_STATUS_XXX values. */ - public DWORD dwStatus; + public int dwStatus; public PRINTER_INFO_6() {} @@ -683,10 +683,10 @@ public static class PRINTER_INFO_7 extends Structure { /** * Indicates the action for the SetPrinter function to perform. For the * GetPrinter function, this member indicates whether the specified - * printer is published. This member can be a combination of DSPRINT_* + * printer is published. This member can be a combination of DSPRINT_XXX * values. */ - public DWORD dwAction; + public int dwAction; public PRINTER_INFO_7() {} From 8e87b13b499f17c0135d8ddcb12dbe177ef28381 Mon Sep 17 00:00:00 2001 From: Tres Finocchiaro Date: Tue, 29 Mar 2022 22:26:24 -0400 Subject: [PATCH 08/22] Update changelog --- CHANGES.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGES.md b/CHANGES.md index 349702b4eb..7b1f958f27 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -7,6 +7,7 @@ Next Release (5.12.0) Features -------- +* [#1429](https://github.com/java-native-access/jna/pull/1429): Add missing `Winspool.PRINTER_INFO_X` structs [@tresf](https://github.com/tresf). Bug Fixes --------- From ac29f716140c9199d4d8a86feb40c9c62ac78305 Mon Sep 17 00:00:00 2001 From: Tres Finocchiaro Date: Wed, 30 Mar 2022 14:40:47 -0400 Subject: [PATCH 09/22] Add JavaDocs for DEVMODE struct --- .../com/sun/jna/platform/win32/WinGDI.java | 444 +++++++++++++++++- 1 file changed, 426 insertions(+), 18 deletions(-) diff --git a/contrib/platform/src/com/sun/jna/platform/win32/WinGDI.java b/contrib/platform/src/com/sun/jna/platform/win32/WinGDI.java index 324360ced3..29439ea540 100644 --- a/contrib/platform/src/com/sun/jna/platform/win32/WinGDI.java +++ b/contrib/platform/src/com/sun/jna/platform/win32/WinGDI.java @@ -30,6 +30,8 @@ import com.sun.jna.platform.win32.WinNT.HANDLE; import com.sun.jna.Union; +import java.text.ParseException; + import static com.sun.jna.platform.win32.WinDef.*; /** @@ -46,33 +48,186 @@ public interface WinGDI { "dmDuplex", "dmYResolution", "dmTTOption", "dmCollate", "dmFormName", "dmLogPixels", "dmBitsPerPel", "dmPelsWidth", "dmPelsHeight", "dummyunionname2", "dmDisplayFrequency", "dmICMMethod", "dmICMIntent", "dmMediaType", "dmDitherType", "dmReserved1", "dmReserved2", "dmPanningWidth", "dmPanningHeight" }) - + /** + * The size of the "public" DEVMODE data can vary for different versions of the structure. + *

+ * - The dmSize member specifies the number of bytes of "public" data + * - The dmDriverExtra member specifies the number of bytes of "private" data. + * + * A device driver's "private" data follows the public portion of the DEVMODE structure. + * + * @see + * DEVMODEW structure + */ public static class DEVMODE extends Structure { public static class ByReference extends DEVMODE implements Structure.ByReference {} - private static final int CHAR_WIDTH = Boolean.getBoolean("w32.ascii") ? 1 : 2; + private static boolean XP_OR_HIGHER = false; + static { + try { + String osVersion = String.getString("os.version"); + if(osVersion != null) { + float osVersion = Float.parseFloat(osVersion); + XP_OR_HIGHER = osVersion >= 5.1f; + } + } catch(ParseException ignore) {} + } + /** + * A zero-terminated character array that specifies the "friendly" name of the printer or display + *

+ * For a printer: "PCL/HP LaserJet" in the case of PCL/HP LaserJet. + * + * For a display: "perm3dd" in the case of the 3Dlabs Permedia3 display driver. + * + * This string is unique among device driverers. Note that this name may be truncated to fit in the + * dmDeviceName array. + */ public byte[] dmDeviceName = new byte[Winspool.CCHDEVICENAME * CHAR_WIDTH]; + + /** + * The version number of the initialization data specification on which the structure is based. To ensure the + * correct version is used for any operating system, use DM_SPECVERSION constant in wingdi.h + */ public short dmSpecVersion; + + /** + * For a printer: Specifies the printer driver version number assigned by the printer driver developer. + * + * For a display: Drivers can set this member to DM_SPECVERSION constant in wingdi.h. + */ public short dmDriverVersion; + + /** + * Specifies the size in bytes of the public DEVMODE structure, not including any private + * driver-specified members identified by the dmDriverExtra member. + */ public short dmSize; + + /** + * Contains the number of bytes of private driver-data that follow this structure. If a device driver + * does not use device-specific information, set this member to zero. + * + * Since the size and format of this data is driver-specific, applications needing it + * must read the data into a separate one-off struct to match. + */ public short dmDriverExtra; + + /** + * Specifies bit flags identifying which of the following DEVMODE members are in use. + * + * For example, the DM_ORIENTATION flag is set when the dmOrientation member + * contains valid data. The DM_XXX flags are defined in wingdi.h. + */ public int dmFields; + public DUMMYUNIONNAME dmUnion1; + /** + * For printers, specifies whether a color printer should print color or monochrome. This member can be one of + * DMCOLOR_COLOR or DMCOLOR_MONOCHROME. + */ + public short dmColor; + public short dmDuplex; + public short dmYResolution; + public short dmTTOption; + public short dmCollate; + public byte[] dmFormName = new byte[Winspool.CCHFORMNAME * CHAR_WIDTH]; + public short dmLogPixels; + public int dmBitsPerPel; + public int dmPelsWidth; + public int dmPelsHeight; + public DUMMYUNIONNAME2 dummyunionname2; + public POINT dmPosition; + public DUMMYSTRUCTNAME2 dummystructname2; + public static class DUMMYUNIONNAME extends Union { public DUMMYSTRUCTNAME dummystructname; @FieldOrder({ "dmOrientation", "dmPaperSize", "dmPaperLength", "dmPaperWidth", "dmScale", "dmCopies", "dmDefaultSource", "dmPrintQuality" }) public static class DUMMYSTRUCTNAME extends Structure { + /** + * For printers: Specifies the paper orientation. This member can be either DMORIENT_PORTRAIT or DMORIENT_LANDSCAPE. + * + * For displays: This member is not used for displays. + */ public short dmOrientation; + + /** + * For printers, specifies the size of the paper to be printed on. This member must be zero if the + * length and width of the paper are specified by the dmPaperLength and + * dmPaperWidth members. Otherwise, the dmPaperSize member must be one of the + * DMPAPER_XXX constants defined in wingdi.h. + * + * For displays: This member is not used for displays. + */ public short dmPaperSize; + + /** + * For printers: Specifies the length of the paper, in units of 1/10 of a millimeter. This value + * overrides the length of the paper specified by the dmPaperSize member, and is used if + * the paper is of a custom size, or if the device is a dot matrix printer, which can print a page of + * arbitrary length. + * + * For displays: This member is not used for displays. + */ public short dmPaperLength; + + /** + * For printers: Specifies the width of the paper, in units of 1/10 of a millimeter. This value + * overrides the width of the paper specified by the dmPaperSize member. This member must + * be used if dmPaperLength is used. + * + * For displays: This member is not used for displays. + */ public short dmPaperWidth; + + /** + * For printers: Specifies the percentage by which the image is to be scaled for printing. + * The image's page size is scaled to the physical page by a factor of dmScale/100. + * + * For example, a 17-inch by 22-inch image with a scale value of 100 requires 17x22-inch paper, while + * the same image with a scale value of 50 should print as half-sized and fit on letter-sized paper. + * + * For displays: This member is not used for displays. + */ public short dmScale; + + /** + * For printers: Specifies the number of copies to be printed, if the device supports multiple copies. + * + * For displays: This member is not used for displays. + */ public short dmCopies; + + /** + * For printers: Specifies the printer's default input bin (paper source). This must be one of the + * DMBIN_XXX constants defined in wingdi.h. If the specified constant is + * DMBIN_FORMSOURCE, the input bin should be selected automatically. + * + * To retrieve a list of the available paper sources for a printer, use the + * DeviceCapabilities function with the DC_BINS flag. + * + * This member can be one of the DMBIN_XXX> values, or it can be a device-specific value greater than or + * equal to DMBIN_USER. + * + * For displays: This member is not used for displays. + */ public short dmDefaultSource; + + /** + * For printers: Specifies the printer resolution. The following negative constant values are defined in + * wingdi.h: + * + * DMRES_HIGH + * DMRES_MEDIUM + * DMRES_LOW + * DMRES_DRAFT + * + * For displays: This member is not used for displays. + */ public short dmPrintQuality; public DUMMYSTRUCTNAME() { @@ -80,46 +235,153 @@ public DUMMYSTRUCTNAME() { } } - public POINT dmPosition; - public DUMMYSTRUCTNAME2 dummystructname2; - @FieldOrder({ "dmPosition", "dmDisplayOrientation", "dmDisplayFixedOutput" }) public static class DUMMYSTRUCTNAME2 extends Structure { + + /** + * For displays: Specifies a POINTL structure containing the x- and y-coordinates of + * upper-left corner of the display, in desktop coordinates. This member is used to determine the + * relative position of monitors in a multiple monitor environment. + * + * For printers: This member is not used for printers. + * + * Note: This member is defined only for Windows XP and later. + */ public POINT dmPosition; + + /** + * For displays: Specifies the orientation at which images should be presented. When the + * DM_DISPLAYORIENTATION bit is not set in the dmFields member, this member + * must be set to zero. When the DM_DISPLAYORIENTATION bit is set in the + * dmFields member, this member must be set to one of the DMDO_XXX values + * + * For printers: This member is not used for printers. + * + * Note: This member is defined only for Windows XP and later. + */ public int dmDisplayOrientation; + + /** + * For displays: For fixed-resolution displays, specifies how the device can present a lower-resolution + * mode on a higher-resolution display. For example, if a display device's resolution is fixed at + * 1024 X 768, and its mode is set to 640 x 480, the device can either + * display a 640 X 480 image within the 1024 X 768 screen space, or stretch + * the 640 X 480 image to fill the larger screen space. + * + * When the DM_DISPLAYFIXEDOUTPUT bit is not set in the dmFields member, + * this member must be set to zero. When the DM_DISPLAYFIXEDOUTPUT bit is set in the + * dmFields member, this member must be set to one of the DMDFO_XXX values. + * + * For printers: This member is not used for printers. + * + * Note: This member is defined only for Windows XP and later. + */ public int dmDisplayFixedOutput; public DUMMYSTRUCTNAME2() { - super(); + if(XP_OR_HIGHER) { + super(); + } } } } - public short dmColor; - public short dmDuplex; - public short dmYResolution; - public short dmTTOption; - public short dmCollate; - public byte[] dmFormName = new byte[Winspool.CCHFORMNAME * CHAR_WIDTH]; - public short dmLogPixels; - public int dmBitsPerPel; - public int dmPelsWidth; - public int dmPelsHeight; - public DUMMYUNIONNAME2 dummyunionname2; - public static class DUMMYUNIONNAME2 extends Union { + /** + * For displays: Specifies a display device's display mode. This member can be + * DM_GRAYSCALE, DM_INTERLACED or DMDISPLAYFLAGS_TEXTMODE, + * however values other than DM_INTERLACED are invalid for newer systems. + * + * For printers: This member is not used for printers. + */ public int dmDisplayFlags; + + /** + * For printers: Specifies where the N-UP (pages per sheet) is done. It can be DMNUP_SYSTEM or + * DMNUP_ONEUP being controlled by the spooler or the application, respectively. + * + * For displays: This member is not used for displays. + */ public int dmNup; } + + /** + * For displays: Specifies the frequency, in hertz (cycles per second), of the display device in a particular + * mode. This value is also known as the display device's vertical refresh rate. Display drivers use this + * member. It is used, for example, in the ChangeDisplaySettings function. + * + * When you call the EnumDisplaySettings function, the dmDisplayFrequency member may + * return with the value 0 or 1. These values represent the display hardware's default refresh rate. This + * default rate is typically set by switches on a display card or computer motherboard, or by a configuration + * program that does not use display functions such as ChangeDisplaySettings. + * + * For printers: This member is not used for printers. + */ public int dmDisplayFrequency; + + /** + * For printers: Specifies how ICM (image color management) is handled. For a non-ICM application, this member determines + * if ICM is enabled or disabled. For ICM applications, the system examines this member to determine how to + * handle ICM support. This member can be one of the predefined DMICMMETHOD_XXXvalues, or a driver-defined value + * greater than or equal to the value of DMICMMETHOD_USER. + * + * The printer driver must provide a user interface for setting this member. Most printer drivers support only + * the DMICMMETHOD_SYSTEM or DMICMMETHOD_NONE value. Drivers for PostScript printers + * support all DCMICMMETHOD_XXXvalues. + * + * For displays: This member is not used for displays. + */ public int dmICMMethod; + + /** + * For printers: Specifies which color matching method, or intent, should be used by default. This member is primarily for + * non-ICM applications. ICM applications can establish intents by using the ICM functions. This member can be + * one of the following predefined values, or a driver defined value greater than or equal to the value of + * DMICM_USER. + * + * For displays: This member is not used for displays. + */ public int dmICMIntent; + + /** + * For printers: Specifies the type of media being printed on. The member can be one of the predefined + * DMMEDIA_XXX values, or a driver-defined value greater than or equal to the value of DMMEDIA_USER. + * + * To retrieve a list of the available media types for a printer, use the DeviceCapabilities + * function with the DC_MEDIATYPES flag. + * + * For displays: This member is not used for displays. + */ public int dmMediaType; + + /** + * For printers: Specifies how dithering is to be done. The member can be one of the predefined + * DMDITHER_XXX values, or a driver-defined value greater than or equal to the value of + * DMDITHER_USER. + * + * For displays: This member is not used for displays. + */ public int dmDitherType; + + /** + * Not used; must be zero. + */ public int dmReserved1; + + /** + * Not used; must be zero. + */ public int dmReserved2; + + /** + * This member must be zero. + */ public int dmPanningWidth; + + /** + * This member must be zero. + */ public int dmPanningHeight; /** @@ -164,6 +426,152 @@ public RGNDATA(int bufferSize) { HANDLE HGDI_ERROR = new HANDLE(Pointer.createConstant(0xFFFFFFFF)); + int DMCOLOR_MONOCHROME = 1; + int DMCOLOR_COLOR = 2; + + int DMORIENT_PORTRAIT = 1; + int DMORIENT_LANDSCAPE = 2; + + /* device capabilities indices */ + int DC_FIELDS =1; + int DC_PAPERS = 2; + int DC_PAPERSIZE = 3; + int DC_MINEXTENT = 4; + int DC_MAXEXTENT = 5; + int DC_BINS = 6; + int DC_DUPLEX = 7; + int DC_SIZE = 8; + int DC_EXTRA = 9; + int DC_VERSION = 10; + int DC_DRIVER = 11; + int DC_BINNAMES = 12; + int DC_ENUMRESOLUTIONS = 13; + int DC_FILEDEPENDENCIES = 14; + int DC_TRUETYPE = 15; + int DC_PAPERNAMES = 16; + int DC_ORIENTATION = 17; + int DC_COPIES = 18; + int DC_BINADJUST = 19; + int DC_EMF_COMPLIANT = 20; + int DC_DATATYPE_PRODUCED = 21; + int DC_COLLATE = 22; + int DC_MANUFACTURER = 23; + int DC_MODEL = 24; + int DC_PERSONALITY = 25; + int DC_PRINTRATE = 26; + int DC_PRINTRATEUNIT = 27; + int PRINTRATEUNIT_PPM = 1; + int PRINTRATEUNIT_CPS = 2; + int PRINTRATEUNIT_LPM = 3; + int PRINTRATEUNIT_IPM = 4; + int DC_PRINTERMEM = 28; + int DC_MEDIAREADY = 29; + int DC_STAPLE = 30; + int DC_PRINTRATEPPM = 31; + int DC_COLORDEVICE = 32; + int DC_NUP = 33; + int DC_MEDIATYPENAMES = 34; + int DC_MEDIATYPES = 35; + + /* print qualities */ + int DMRES_DRAFT = -1; + int DMRES_LOW = -2; + int DMRES_MEDIUM = -3; + int DMRES_HIGH = -4; + + /* bin selections */ + int DMBIN_UPPER = 0x0001; + int DMBIN_LOWER = 0x0002; + int DMBIN_MIDDLE = 0x0003; + int DMBIN_MANUAL = 0x0004; + int DMBIN_ENVELOPE = 0x0005; + int DMBIN_ENVMANUAL = 0x0006; + int DMBIN_AUTO = 0x0007; + int DMBIN_TRACTOR = 0x0008; + int DMBIN_SMALLFMT = 0x0009; + int DMBIN_LARGEFMT = 0x000A; + int DMBIN_LARGECAPACITY = 0x000B; + int DMBIN_CASSETTE = 0x000E; + int DMBIN_FORMSOURCE = 0x000F; + + /* DEVMODE dmDisplayOrientation specifiations */ + int DMDO_DEFAULT = 0; + int DMDO_90 = 1; + int DMDO_180 = 2; + int DMDO_270 = 3; + + /* DEVMODE dmDisplayFixedOutput specifiations */ + int DMDFO_DEFAULT = 0; + int DMDFO_STRETCH = 1; + int DMDFO_CENTER = 2; + + /* DEVMODE dmDisplayFlags flags */ + int DM_GRAYSCALE = 0x00000001; + int DM_INTERLACED = 0x00000002; + int DMDISPLAYFLAGS_TEXTMODE = 0x00000004; + + /* DEVMODE dmNup: multiple logical page per physical page options */ + /** The print spooler does the NUP (pages per sheet) **/ + int DMNUP_SYSTEM = 1; + /** The application does the NUP (pages per sheet) **/ + int DMNUP_ONEUP = 2; + + /* ICM methods */ + /** ICM disabled **/ + int DMICMMETHOD_NONE = 1; + /** ICM handled by system **/ + int DMICMMETHOD_SYSTEM = 2; + /** ICM handled by driver **/ + int DMICMMETHOD_DRIVER = 3; + /** ICM handled by device **/ + int DMICMMETHOD_DEVICE = 4; + + /* ICM Intents */ + /** Maximize color saturation **/ + int DMICM_SATURATE = 1; + /** Maximize color contrast **/' + int DMICM_CONTRAST = 2; + /** Use specific color metric **/ + int DMICM_COLORIMETRIC = 3; + /** Use specific color metric **/ + int DMICM_ABS_COLORIMETRIC = 4; + /** Device-specific intents start here **/ + int DMICM_USER = 256; + + /* Media types */ + /** Standard paper **/ + int DMMEDIA_STANDARD = 1; + /** Transparency **/ + int DMMEDIA_TRANSPARENCY = 2; + /** Glossy paper **/ + int DMMEDIA_GLOSSY = 3; + /** Device-specific media start here */ + int DMMEDIA_USER = 256; + + /* Dither types */ + /** No dithering **/ + int DMDITHER_NONE= 1; + /** Dither with a coarse brush **/ + int DMDITHER_COARSE = 2; + /** Dither with a fine brush **/ + int DMDITHER_FINE= 3; + /** LineArt dithering **/ + int DMDITHER_LINEART = 4; + /** LineArt dithering **/ + int DMDITHER_ERRORDIFFUSION = 5; + /** LineArt dithering **/ + int DMDITHER_RESERVED6 = 6; + /** LineArt dithering **/ + int DMDITHER_RESERVED7 = 7; + /** LineArt dithering **/ + int DMDITHER_RESERVED8 = 8; + /** LineArt dithering **/ + int DMDITHER_RESERVED9 = 9; + /** Device does grayscaling **/ + int DMDITHER_GRAYSCALE = 10; + /** Device-specific dithers start here **/ + int DMDITHER_USER = 256; + int RGN_AND = 1; int RGN_OR = 2; int RGN_XOR = 3; From 9ed81f6b3b52e765e6a95041d3b887c104908dc2 Mon Sep 17 00:00:00 2001 From: Tres Finocchiaro Date: Wed, 30 Mar 2022 15:17:35 -0400 Subject: [PATCH 10/22] Add a few missing JavaDocs and const's for DEVMODE struct --- .../com/sun/jna/platform/win32/WinGDI.java | 76 ++++++++++++++++++- 1 file changed, 75 insertions(+), 1 deletion(-) diff --git a/contrib/platform/src/com/sun/jna/platform/win32/WinGDI.java b/contrib/platform/src/com/sun/jna/platform/win32/WinGDI.java index 29439ea540..d9057ccbc8 100644 --- a/contrib/platform/src/com/sun/jna/platform/win32/WinGDI.java +++ b/contrib/platform/src/com/sun/jna/platform/win32/WinGDI.java @@ -125,18 +125,81 @@ public static class ByReference extends DEVMODE implements Structure.ByReference public DUMMYUNIONNAME dmUnion1; /** - * For printers, specifies whether a color printer should print color or monochrome. This member can be one of + * For printers: Specifies whether a color printer should print color or monochrome. This member can be one of * DMCOLOR_COLOR or DMCOLOR_MONOCHROME. + * + * For displays: This member is not used for displays. */ public short dmColor; + + /** + * For printers: Specifies duplex (double-sided) printing for duplex-capable printers. This member can be + * DMCOLOR_COLOR or DMCOLOR_MONOCHROME. + * + * For displays: This member is not used for displays. + */ public short dmDuplex; + + /** + * For printers: Specifies the y resolution of the printer, in DPI. If this member is used, the + * dmPrintQuality member specifies the x resolution. + * + * For displays: This member is not used for displays. + */ public short dmYResolution; + + /** + * For printers: Specifies how TrueType fonts should be printed. This member must be one of the + * DMTT_XXX constants defined in wingdi.h. + * + * For displays: This member is not used for displays. + */ public short dmTTOption; + + /** + * For printers: Specifies whether multiple copies should be collated. This member can be one of + * DMCOLLATE_TRUE, DMCOLLATE_FALSE. + * + * For displays: This member is not used for displays. + */ public short dmCollate; + + /** + * For printers: Specifies the name of the form to use; such as "Letter" or "Legal". This must be a name that + * can be obtain by calling the Win32 EnumForms function (described in the Microsoft Window SDK + * documentation). + * + * For displays: This member is not used for displays. + */ public byte[] dmFormName = new byte[Winspool.CCHFORMNAME * CHAR_WIDTH]; + + /** + * For displays: Specifies the number of logical pixels per inch of a display device and should be equal to the + * ulLogPixels member of the GDIINFO structure. + * + * For printers: This member is not used for printers. + */ public short dmLogPixels; + + /** + * For displays: Specifies the color resolution, in bits per pixel, of a display device. + * + * For printers: This member is not used for printers. + */ public int dmBitsPerPel; + + /** + * For displays: Specifies the width, in pixels, of the visible device surface. + * + * For printers: This member is not used for printers. + */ public int dmPelsWidth; + + /** + * For displays: Specifies the height, in pixels, of the visible device surface. + * + * For printers: This member is not used for printers. + */ public int dmPelsHeight; public DUMMYUNIONNAME2 dummyunionname2; public POINT dmPosition; @@ -429,6 +492,17 @@ public RGNDATA(int bufferSize) { int DMCOLOR_MONOCHROME = 1; int DMCOLOR_COLOR = 2; + /* TrueType options */ + /** print TT fonts as graphics **/ + int DMTT_BITMAP = 1; + /** download TT fonts as soft fonts **/ + int DMTT_DOWNLOAD = 2; + /** substitute device fonts for TT fonts **/ + int DMTT_SUBDEV = 3; + /** download TT fonts as outline soft fonts **/ + int DMTT_DOWNLOAD_OUTLINE = 4; + + int DMORIENT_PORTRAIT = 1; int DMORIENT_LANDSCAPE = 2; From 5e2551d919ed62a7facad155aacff19d0592920c Mon Sep 17 00:00:00 2001 From: Vzor- Date: Wed, 18 Oct 2023 20:49:48 -0400 Subject: [PATCH 11/22] typo fix and xp check removal --- .../src/com/sun/jna/platform/win32/WinGDI.java | 18 +++--------------- 1 file changed, 3 insertions(+), 15 deletions(-) diff --git a/contrib/platform/src/com/sun/jna/platform/win32/WinGDI.java b/contrib/platform/src/com/sun/jna/platform/win32/WinGDI.java index d9057ccbc8..998d1e7b49 100644 --- a/contrib/platform/src/com/sun/jna/platform/win32/WinGDI.java +++ b/contrib/platform/src/com/sun/jna/platform/win32/WinGDI.java @@ -63,16 +63,6 @@ public interface WinGDI { public static class DEVMODE extends Structure { public static class ByReference extends DEVMODE implements Structure.ByReference {} private static final int CHAR_WIDTH = Boolean.getBoolean("w32.ascii") ? 1 : 2; - private static boolean XP_OR_HIGHER = false; - static { - try { - String osVersion = String.getString("os.version"); - if(osVersion != null) { - float osVersion = Float.parseFloat(osVersion); - XP_OR_HIGHER = osVersion >= 5.1f; - } - } catch(ParseException ignore) {} - } /** * A zero-terminated character array that specifies the "friendly" name of the printer or display @@ -203,7 +193,7 @@ public static class ByReference extends DEVMODE implements Structure.ByReference public int dmPelsHeight; public DUMMYUNIONNAME2 dummyunionname2; public POINT dmPosition; - public DUMMYSTRUCTNAME2 dummystructname2; + public DUMMYUNIONNAME.DUMMYSTRUCTNAME2 dummystructname2; public static class DUMMYUNIONNAME extends Union { public DUMMYSTRUCTNAME dummystructname; @@ -342,9 +332,7 @@ public static class DUMMYSTRUCTNAME2 extends Structure { public int dmDisplayFixedOutput; public DUMMYSTRUCTNAME2() { - if(XP_OR_HIGHER) { - super(); - } + super(); } } } @@ -603,7 +591,7 @@ public RGNDATA(int bufferSize) { /* ICM Intents */ /** Maximize color saturation **/ int DMICM_SATURATE = 1; - /** Maximize color contrast **/' + /** Maximize color contrast **/ int DMICM_CONTRAST = 2; /** Use specific color metric **/ int DMICM_COLORIMETRIC = 3; From f68bb7beefd8de5b6398438ccf0ae74406ca2f5b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matthias=20Bl=C3=A4sing?= Date: Sat, 21 Oct 2023 11:55:31 +0200 Subject: [PATCH 12/22] Bind Winspool#DocumentProperties (only signature, no documentation) --- contrib/platform/src/com/sun/jna/platform/win32/Winspool.java | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/contrib/platform/src/com/sun/jna/platform/win32/Winspool.java b/contrib/platform/src/com/sun/jna/platform/win32/Winspool.java index b2442fe42f..d330c96ca9 100644 --- a/contrib/platform/src/com/sun/jna/platform/win32/Winspool.java +++ b/contrib/platform/src/com/sun/jna/platform/win32/Winspool.java @@ -1475,4 +1475,8 @@ public JOB_INFO_1(int size) { super(new Memory(size)); } } + + int DocumentProperties( + WinDef.HWND hWnd, HANDLE hPrinter, String pDeviceName, + Pointer pDevModeOutput, Pointer pDevModeInput, int fMode); } From 9c126f0fa5f8e78d2fe402d954881dd127c4393e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matthias=20Bl=C3=A4sing?= Date: Sat, 21 Oct 2023 11:56:35 +0200 Subject: [PATCH 13/22] Remove invalid WinGDI#DEVMODE members --- contrib/platform/src/com/sun/jna/platform/win32/WinGDI.java | 2 -- 1 file changed, 2 deletions(-) diff --git a/contrib/platform/src/com/sun/jna/platform/win32/WinGDI.java b/contrib/platform/src/com/sun/jna/platform/win32/WinGDI.java index 998d1e7b49..ce52777e40 100644 --- a/contrib/platform/src/com/sun/jna/platform/win32/WinGDI.java +++ b/contrib/platform/src/com/sun/jna/platform/win32/WinGDI.java @@ -192,8 +192,6 @@ public static class ByReference extends DEVMODE implements Structure.ByReference */ public int dmPelsHeight; public DUMMYUNIONNAME2 dummyunionname2; - public POINT dmPosition; - public DUMMYUNIONNAME.DUMMYSTRUCTNAME2 dummystructname2; public static class DUMMYUNIONNAME extends Union { public DUMMYSTRUCTNAME dummystructname; From 04776464b0bb48f32dd3483237371562c1fbe863 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matthias=20Bl=C3=A4sing?= Date: Sat, 21 Oct 2023 12:00:14 +0200 Subject: [PATCH 14/22] Move child structure definitions to the end of the structure definition --- .../com/sun/jna/platform/win32/WinGDI.java | 191 +++++++++--------- 1 file changed, 96 insertions(+), 95 deletions(-) diff --git a/contrib/platform/src/com/sun/jna/platform/win32/WinGDI.java b/contrib/platform/src/com/sun/jna/platform/win32/WinGDI.java index ce52777e40..a4683a7356 100644 --- a/contrib/platform/src/com/sun/jna/platform/win32/WinGDI.java +++ b/contrib/platform/src/com/sun/jna/platform/win32/WinGDI.java @@ -191,8 +191,104 @@ public static class ByReference extends DEVMODE implements Structure.ByReference * For printers: This member is not used for printers. */ public int dmPelsHeight; + public DUMMYUNIONNAME2 dummyunionname2; + /** + * For displays: Specifies the frequency, in hertz (cycles per second), of the display device in a particular + * mode. This value is also known as the display device's vertical refresh rate. Display drivers use this + * member. It is used, for example, in the ChangeDisplaySettings function. + * + * When you call the EnumDisplaySettings function, the dmDisplayFrequency member may + * return with the value 0 or 1. These values represent the display hardware's default refresh rate. This + * default rate is typically set by switches on a display card or computer motherboard, or by a configuration + * program that does not use display functions such as ChangeDisplaySettings. + * + * For printers: This member is not used for printers. + */ + public int dmDisplayFrequency; + + /** + * For printers: Specifies how ICM (image color management) is handled. For a non-ICM application, this member determines + * if ICM is enabled or disabled. For ICM applications, the system examines this member to determine how to + * handle ICM support. This member can be one of the predefined DMICMMETHOD_XXXvalues, or a driver-defined value + * greater than or equal to the value of DMICMMETHOD_USER. + * + * The printer driver must provide a user interface for setting this member. Most printer drivers support only + * the DMICMMETHOD_SYSTEM or DMICMMETHOD_NONE value. Drivers for PostScript printers + * support all DCMICMMETHOD_XXXvalues. + * + * For displays: This member is not used for displays. + */ + public int dmICMMethod; + + /** + * For printers: Specifies which color matching method, or intent, should be used by default. This member is primarily for + * non-ICM applications. ICM applications can establish intents by using the ICM functions. This member can be + * one of the following predefined values, or a driver defined value greater than or equal to the value of + * DMICM_USER. + * + * For displays: This member is not used for displays. + */ + public int dmICMIntent; + + /** + * For printers: Specifies the type of media being printed on. The member can be one of the predefined + * DMMEDIA_XXX values, or a driver-defined value greater than or equal to the value of DMMEDIA_USER. + * + * To retrieve a list of the available media types for a printer, use the DeviceCapabilities + * function with the DC_MEDIATYPES flag. + * + * For displays: This member is not used for displays. + */ + public int dmMediaType; + + /** + * For printers: Specifies how dithering is to be done. The member can be one of the predefined + * DMDITHER_XXX values, or a driver-defined value greater than or equal to the value of + * DMDITHER_USER. + * + * For displays: This member is not used for displays. + */ + public int dmDitherType; + + /** + * Not used; must be zero. + */ + public int dmReserved1; + + /** + * Not used; must be zero. + */ + public int dmReserved2; + + /** + * This member must be zero. + */ + public int dmPanningWidth; + + /** + * This member must be zero. + */ + public int dmPanningHeight; + + /** + * Converts dmDeviceName from raw byte[] to String + */ + public String getDmDeviceName() { + int offset = fieldOffset("dmDeviceName"); + return CHAR_WIDTH == 1 ? getPointer().getString(offset) : getPointer().getWideString(offset); + } + + /** + * Converts dmFormName from raw byte[] to String + */ + public String getDmFormName() { + int offset = fieldOffset("dmFormName"); + return CHAR_WIDTH == 1 ? getPointer().getString(offset) : getPointer().getWideString(offset); + } + + public static class DUMMYUNIONNAME extends Union { public DUMMYSTRUCTNAME dummystructname; @@ -353,101 +449,6 @@ public static class DUMMYUNIONNAME2 extends Union { */ public int dmNup; } - - - /** - * For displays: Specifies the frequency, in hertz (cycles per second), of the display device in a particular - * mode. This value is also known as the display device's vertical refresh rate. Display drivers use this - * member. It is used, for example, in the ChangeDisplaySettings function. - * - * When you call the EnumDisplaySettings function, the dmDisplayFrequency member may - * return with the value 0 or 1. These values represent the display hardware's default refresh rate. This - * default rate is typically set by switches on a display card or computer motherboard, or by a configuration - * program that does not use display functions such as ChangeDisplaySettings. - * - * For printers: This member is not used for printers. - */ - public int dmDisplayFrequency; - - /** - * For printers: Specifies how ICM (image color management) is handled. For a non-ICM application, this member determines - * if ICM is enabled or disabled. For ICM applications, the system examines this member to determine how to - * handle ICM support. This member can be one of the predefined DMICMMETHOD_XXXvalues, or a driver-defined value - * greater than or equal to the value of DMICMMETHOD_USER. - * - * The printer driver must provide a user interface for setting this member. Most printer drivers support only - * the DMICMMETHOD_SYSTEM or DMICMMETHOD_NONE value. Drivers for PostScript printers - * support all DCMICMMETHOD_XXXvalues. - * - * For displays: This member is not used for displays. - */ - public int dmICMMethod; - - /** - * For printers: Specifies which color matching method, or intent, should be used by default. This member is primarily for - * non-ICM applications. ICM applications can establish intents by using the ICM functions. This member can be - * one of the following predefined values, or a driver defined value greater than or equal to the value of - * DMICM_USER. - * - * For displays: This member is not used for displays. - */ - public int dmICMIntent; - - /** - * For printers: Specifies the type of media being printed on. The member can be one of the predefined - * DMMEDIA_XXX values, or a driver-defined value greater than or equal to the value of DMMEDIA_USER. - * - * To retrieve a list of the available media types for a printer, use the DeviceCapabilities - * function with the DC_MEDIATYPES flag. - * - * For displays: This member is not used for displays. - */ - public int dmMediaType; - - /** - * For printers: Specifies how dithering is to be done. The member can be one of the predefined - * DMDITHER_XXX values, or a driver-defined value greater than or equal to the value of - * DMDITHER_USER. - * - * For displays: This member is not used for displays. - */ - public int dmDitherType; - - /** - * Not used; must be zero. - */ - public int dmReserved1; - - /** - * Not used; must be zero. - */ - public int dmReserved2; - - /** - * This member must be zero. - */ - public int dmPanningWidth; - - /** - * This member must be zero. - */ - public int dmPanningHeight; - - /** - * Converts dmDeviceName from raw byte[] to String - */ - public String getDmDeviceName() { - int offset = fieldOffset("dmDeviceName"); - return CHAR_WIDTH == 1 ? getPointer().getString(offset) : getPointer().getWideString(offset); - } - - /** - * Converts dmFormName from raw byte[] to String - */ - public String getDmFormName() { - int offset = fieldOffset("dmFormName"); - return CHAR_WIDTH == 1 ? getPointer().getString(offset) : getPointer().getWideString(offset); - } } @FieldOrder({"dwSize", "iType", "nCount", "nRgnSize", "rcBound"}) From eeda6e00b7b14a06d3b299ef44c17aea7d9fca55 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matthias=20Bl=C3=A4sing?= Date: Sat, 21 Oct 2023 12:18:25 +0200 Subject: [PATCH 15/22] Prevent out-of-bounds read if strings are not \0 terminated The documentation does not state whether the strings in DEVMODE are \0 terminated so assume they might be not --- .../com/sun/jna/platform/win32/WinGDI.java | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/contrib/platform/src/com/sun/jna/platform/win32/WinGDI.java b/contrib/platform/src/com/sun/jna/platform/win32/WinGDI.java index a4683a7356..30fc9bd3fe 100644 --- a/contrib/platform/src/com/sun/jna/platform/win32/WinGDI.java +++ b/contrib/platform/src/com/sun/jna/platform/win32/WinGDI.java @@ -23,6 +23,7 @@ */ package com.sun.jna.platform.win32; +import com.sun.jna.Native; import com.sun.jna.NativeLong; import com.sun.jna.Pointer; import com.sun.jna.Structure; @@ -30,9 +31,8 @@ import com.sun.jna.platform.win32.WinNT.HANDLE; import com.sun.jna.Union; -import java.text.ParseException; - import static com.sun.jna.platform.win32.WinDef.*; +import java.nio.charset.StandardCharsets; /** * Ported from WinGDI.h. @@ -276,19 +276,24 @@ public static class ByReference extends DEVMODE implements Structure.ByReference * Converts dmDeviceName from raw byte[] to String */ public String getDmDeviceName() { - int offset = fieldOffset("dmDeviceName"); - return CHAR_WIDTH == 1 ? getPointer().getString(offset) : getPointer().getWideString(offset); + if(CHAR_WIDTH == 1) { + return Native.toString(dmFormName); + } else { + return new String(dmDeviceName, StandardCharsets.UTF_16LE); + } } /** * Converts dmFormName from raw byte[] to String */ public String getDmFormName() { - int offset = fieldOffset("dmFormName"); - return CHAR_WIDTH == 1 ? getPointer().getString(offset) : getPointer().getWideString(offset); + if(CHAR_WIDTH == 1) { + return Native.toString(dmFormName); + } else { + return new String(dmFormName, StandardCharsets.UTF_16LE); + } } - public static class DUMMYUNIONNAME extends Union { public DUMMYSTRUCTNAME dummystructname; From f58508a2bbe515f3c3d46f3da542d56da10b17d1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matthias=20Bl=C3=A4sing?= Date: Sat, 21 Oct 2023 12:25:25 +0200 Subject: [PATCH 16/22] Bind missing members of DEVMODE.DUMMYUNIONNAME --- .../src/com/sun/jna/platform/win32/WinGDI.java | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/contrib/platform/src/com/sun/jna/platform/win32/WinGDI.java b/contrib/platform/src/com/sun/jna/platform/win32/WinGDI.java index 30fc9bd3fe..eb2642106a 100644 --- a/contrib/platform/src/com/sun/jna/platform/win32/WinGDI.java +++ b/contrib/platform/src/com/sun/jna/platform/win32/WinGDI.java @@ -296,6 +296,8 @@ public String getDmFormName() { public static class DUMMYUNIONNAME extends Union { public DUMMYSTRUCTNAME dummystructname; + public POINT dmPosition; + public DUMMYSTRUCTNAME2 dummystructname2; @FieldOrder({ "dmOrientation", "dmPaperSize", "dmPaperLength", "dmPaperWidth", "dmScale", "dmCopies", "dmDefaultSource", "dmPrintQuality" }) @@ -381,10 +383,6 @@ public static class DUMMYSTRUCTNAME extends Structure { * For displays: This member is not used for displays. */ public short dmPrintQuality; - - public DUMMYSTRUCTNAME() { - super(); - } } @FieldOrder({ "dmPosition", "dmDisplayOrientation", "dmDisplayFixedOutput" }) @@ -429,10 +427,6 @@ public static class DUMMYSTRUCTNAME2 extends Structure { * Note: This member is defined only for Windows XP and later. */ public int dmDisplayFixedOutput; - - public DUMMYSTRUCTNAME2() { - super(); - } } } From 9581b696a6a869416ead1f49252276a468f683d3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matthias=20Bl=C3=A4sing?= Date: Sat, 21 Oct 2023 12:34:28 +0200 Subject: [PATCH 17/22] Add constants for values of DEVMODE#dmFields --- .../com/sun/jna/platform/win32/WinGDI.java | 31 +++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/contrib/platform/src/com/sun/jna/platform/win32/WinGDI.java b/contrib/platform/src/com/sun/jna/platform/win32/WinGDI.java index eb2642106a..463d63c7ad 100644 --- a/contrib/platform/src/com/sun/jna/platform/win32/WinGDI.java +++ b/contrib/platform/src/com/sun/jna/platform/win32/WinGDI.java @@ -44,6 +44,37 @@ public interface WinGDI { int RDH_RECTANGLES = 1; + int DM_ORIENTATION = 0x00000001; + int DM_PAPERSIZE = 0x00000002; + int DM_PAPERLENGTH = 0x00000004; + int DM_PAPERWIDTH = 0x00000008; + int DM_SCALE = 0x00000010; + int DM_POSITION = 0x00000020; + int DM_NUP = 0x00000040; + int DM_DISPLAYORIENTATION = 0x00000080; + int DM_COPIES = 0x00000100; + int DM_DEFAULTSOURCE = 0x00000200; + int DM_PRINTQUALITY = 0x00000400; + int DM_COLOR = 0x00000800; + int DM_DUPLEX = 0x00001000; + int DM_YRESOLUTION = 0x00002000; + int DM_TTOPTION = 0x00004000; + int DM_COLLATE = 0x00008000; + int DM_FORMNAME = 0x00010000; + int DM_LOGPIXELS = 0x00020000; + int DM_BITSPERPEL = 0x00040000; + int DM_PELSWIDTH = 0x00080000; + int DM_PELSHEIGHT = 0x00100000; + int DM_DISPLAYFLAGS = 0x00200000; + int DM_DISPLAYFREQUENCY = 0x00400000; + int DM_ICMMETHOD = 0x00800000; + int DM_ICMINTENT = 0x01000000; + int DM_MEDIATYPE = 0x02000000; + int DM_DITHERTYPE = 0x04000000; + int DM_PANNINGWIDTH = 0x08000000; + int DM_PANNINGHEIGHT = 0x10000000; + int DM_DISPLAYFIXEDOUTPUT = 0x20000000; + @FieldOrder({ "dmDeviceName", "dmSpecVersion", "dmDriverVersion", "dmSize", "dmDriverExtra", "dmFields", "dmUnion1", "dmColor", "dmDuplex", "dmYResolution", "dmTTOption", "dmCollate", "dmFormName", "dmLogPixels", "dmBitsPerPel", "dmPelsWidth", "dmPelsHeight", "dummyunionname2", "dmDisplayFrequency", "dmICMMethod", "dmICMIntent", "dmMediaType", "dmDitherType", From f84d022f03879ac3aa589c5701dbea9e40e22e5e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matthias=20Bl=C3=A4sing?= Date: Sat, 21 Oct 2023 12:35:21 +0200 Subject: [PATCH 18/22] Interactive Test (not for final commit!) --- .../jna/platform/win32/WinspoolDummyTest.java | 126 ++++++++++++++++++ 1 file changed, 126 insertions(+) create mode 100644 contrib/platform/test/com/sun/jna/platform/win32/WinspoolDummyTest.java diff --git a/contrib/platform/test/com/sun/jna/platform/win32/WinspoolDummyTest.java b/contrib/platform/test/com/sun/jna/platform/win32/WinspoolDummyTest.java new file mode 100644 index 0000000000..db64be320d --- /dev/null +++ b/contrib/platform/test/com/sun/jna/platform/win32/WinspoolDummyTest.java @@ -0,0 +1,126 @@ +/* Copyright (c) 2010 Daniel Doubrovkine, All Rights Reserved + * + * The contents of this file is dual-licensed under 2 + * alternative Open Source/Free licenses: LGPL 2.1 or later and + * Apache License 2.0. (starting with JNA version 4.0.0). + * + * You can freely decide which license you want to apply to + * the project. + * + * You may obtain a copy of the LGPL License at: + * + * http://www.gnu.org/licenses/licenses.html + * + * A copy is also included in the downloadable source code package + * containing JNA, in file "LGPL2.1". + * + * You may obtain a copy of the Apache License at: + * + * http://www.apache.org/licenses/ + * + * A copy is also included in the downloadable source code package + * containing JNA, in file "AL2.0". + */ +package com.sun.jna.platform.win32; + +import com.sun.jna.Memory; +import com.sun.jna.Native; +import com.sun.jna.Structure; +import java.nio.charset.StandardCharsets; +import org.junit.Test; + + +/** + * @author dblock[at]dblock[dot]org + */ +public class WinspoolDummyTest { + + private static final String EVERYONE = "S-1-1-0"; + + @Test + public void testNoDuplicateMethodsNames() { + // Get a printer name from Java to use + //String printer = PrintServiceLookup.lookupDefaultPrintService().getName(); + String printer = "Microsoft Print to PDF"; + + // Get custom Winspool2 instance + Winspool winspool = Winspool.INSTANCE; + + // Get printer handle from Winspool + WinNT.HANDLEByReference hPrinter = new WinNT.HANDLEByReference(); + boolean success = winspool.OpenPrinter(printer, hPrinter, null); + System.out.println("OpenPrinter status: " + success); + if (getLastError() || !success) { + System.err.println("Can't open printer, stopping"); + return; + } + + // Get DEVMODE size + int bufferSize = winspool.DocumentProperties(null, hPrinter.getValue(), printer, null, null, 0); + + if (getLastError() || bufferSize == 0) { + System.err.println("Problem calling DocumentProperties"); + } else { + System.out.println("The DEVMODE size must be " + bufferSize); + Memory devmodeBuffer = new Memory(bufferSize); + int status = winspool.DocumentProperties(null, hPrinter.getValue(), printer, devmodeBuffer, null, 6 /* DM_OUT_BUFFER | DM_PROMPT */); + + WinGDI.DEVMODE dm = Structure.newInstance(WinGDI.DEVMODE.class, devmodeBuffer); + dm.read(); + + System.out.println(dm); + System.out.printf("Device: %s%n", dm.getDmDeviceName()); + System.out.printf("Formname: %s%n", dm.getDmFormName()); + if ((dm.dmFields & WinGDI.DM_ORIENTATION) == WinGDI.DM_ORIENTATION + || (dm.dmFields & WinGDI.DM_PAPERSIZE) == WinGDI.DM_PAPERSIZE + || (dm.dmFields & WinGDI.DM_PAPERLENGTH) == WinGDI.DM_PAPERLENGTH + || (dm.dmFields & WinGDI.DM_PAPERWIDTH) == WinGDI.DM_PAPERWIDTH + || (dm.dmFields & WinGDI.DM_COPIES) == WinGDI.DM_COPIES) { + dm.dmUnion1.setType("dummystructname"); + dm.dmUnion1.read(); + if((dm.dmFields & WinGDI.DM_ORIENTATION) == WinGDI.DM_ORIENTATION) { + System.out.printf("Orientientation: %d%n", dm.dmUnion1.dummystructname.dmOrientation); + } + if((dm.dmFields & WinGDI.DM_PAPERSIZE) == WinGDI.DM_PAPERSIZE) { + System.out.printf("Paper size: %d%n", dm.dmUnion1.dummystructname.dmPaperSize); + } + if((dm.dmFields & WinGDI.DM_PAPERLENGTH) == WinGDI.DM_PAPERLENGTH) { + System.out.printf("Paper length: %d%n", dm.dmUnion1.dummystructname.dmPaperLength); + } + if((dm.dmFields & WinGDI.DM_PAPERWIDTH) == WinGDI.DM_PAPERWIDTH) { + System.out.printf("Paper width: %d%n", dm.dmUnion1.dummystructname.dmPaperWidth); + } + if((dm.dmFields & WinGDI.DM_COPIES) == WinGDI.DM_COPIES) { + System.out.printf("Copies: %d%n", dm.dmUnion1.dummystructname.dmCopies); + } + } + + // TODO: This may throw false error + long IDOK = 1; + if (getLastError()) { + System.err.println("Problem calling DocumentProperties"); + } + + if (status == IDOK) { + System.out.println("The call to DocumentProperties returned IDOK"); + } else { + // API states a negative value is equivalent to an error + System.err.println("The call to DocumentProperties returned " + status); + } + } + + // Close printer handle + winspool.INSTANCE.ClosePrinter(hPrinter.getValue()); + } + + private static boolean getLastError() { + int error = Native.getLastError(); + if (error == 0) { + System.out.println(" OK"); + return false; + } else { + System.out.println(" ERROR: " + error); + } + return true; + } +} From 77c97112af0944e989e55ce5095480b111ee17b4 Mon Sep 17 00:00:00 2001 From: Vzor- Date: Tue, 19 Dec 2023 00:56:48 -0500 Subject: [PATCH 19/22] substruct read --- .../com/sun/jna/platform/win32/WinGDI.java | 43 +++++++++++++++---- 1 file changed, 35 insertions(+), 8 deletions(-) diff --git a/contrib/platform/src/com/sun/jna/platform/win32/WinGDI.java b/contrib/platform/src/com/sun/jna/platform/win32/WinGDI.java index 463d63c7ad..2c5e3ce66d 100644 --- a/contrib/platform/src/com/sun/jna/platform/win32/WinGDI.java +++ b/contrib/platform/src/com/sun/jna/platform/win32/WinGDI.java @@ -94,6 +94,24 @@ public interface WinGDI { public static class DEVMODE extends Structure { public static class ByReference extends DEVMODE implements Structure.ByReference {} private static final int CHAR_WIDTH = Boolean.getBoolean("w32.ascii") ? 1 : 2; + private static final int DUMMYSTRUCTNAME_MASK = DM_ORIENTATION | DM_PAPERSIZE | DM_PAPERLENGTH | DM_PAPERWIDTH + | DM_SCALE | DM_COPIES | DM_DEFAULTSOURCE | DM_PRINTQUALITY; + private static final int DUMMYSTRUCTNAME2_MASK = DM_POSITION | DM_DISPLAYORIENTATION | DM_DISPLAYFIXEDOUTPUT; + + @Override + public void read() { + super.read(); + if ((dmFields & DUMMYSTRUCTNAME_MASK) > 0) { + dmUnion1.setType(DUMMYUNIONNAME.DUMMYSTRUCTNAME.class); + dmUnion1.read(); + } else if ((dmFields & DUMMYSTRUCTNAME2_MASK) > 0) { + dmUnion1.setType(DUMMYUNIONNAME.DUMMYSTRUCTNAME2.class); + dmUnion1.read(); + } else if ((dmFields & DM_POSITION) > 0) { + dmUnion1.setType(POINT.class); + dmUnion1.read(); + } + } /** * A zero-terminated character array that specifies the "friendly" name of the printer or display @@ -307,22 +325,31 @@ public static class ByReference extends DEVMODE implements Structure.ByReference * Converts dmDeviceName from raw byte[] to String */ public String getDmDeviceName() { + String rawString; if(CHAR_WIDTH == 1) { - return Native.toString(dmFormName); + rawString = Native.toString(dmDeviceName); } else { - return new String(dmDeviceName, StandardCharsets.UTF_16LE); + rawString = new String(dmDeviceName, StandardCharsets.UTF_16LE); } + int stringLength = rawString.indexOf("\0"); + if (stringLength == -1) return rawString; + return rawString.substring(0, stringLength); } /** * Converts dmFormName from raw byte[] to String */ public String getDmFormName() { + // todo: code duplicated, is there already a util to do this? + String rawString; if(CHAR_WIDTH == 1) { - return Native.toString(dmFormName); + rawString = Native.toString(dmFormName); } else { - return new String(dmFormName, StandardCharsets.UTF_16LE); + rawString = new String(dmFormName, StandardCharsets.UTF_16LE); } + int stringLength = rawString.indexOf("\0"); + if (stringLength == -1) return rawString; + return rawString.substring(0, stringLength); } public static class DUMMYUNIONNAME extends Union { @@ -551,10 +578,10 @@ public RGNDATA(int bufferSize) { int DC_PERSONALITY = 25; int DC_PRINTRATE = 26; int DC_PRINTRATEUNIT = 27; - int PRINTRATEUNIT_PPM = 1; - int PRINTRATEUNIT_CPS = 2; - int PRINTRATEUNIT_LPM = 3; - int PRINTRATEUNIT_IPM = 4; + int PRINTRATEUNIT_PPM = 1; + int PRINTRATEUNIT_CPS = 2; + int PRINTRATEUNIT_LPM = 3; + int PRINTRATEUNIT_IPM = 4; int DC_PRINTERMEM = 28; int DC_MEDIAREADY = 29; int DC_STAPLE = 30; From f50ca8239295a89bc4eed35aa32c272918162fa2 Mon Sep 17 00:00:00 2001 From: Vzor- Date: Tue, 19 Dec 2023 00:57:12 -0500 Subject: [PATCH 20/22] EnumDisplaySettings --- .../com/sun/jna/platform/win32/User32.java | 31 ++++++++++++++++++- 1 file changed, 30 insertions(+), 1 deletion(-) diff --git a/contrib/platform/src/com/sun/jna/platform/win32/User32.java b/contrib/platform/src/com/sun/jna/platform/win32/User32.java index a1e43aada1..85416bbc4e 100644 --- a/contrib/platform/src/com/sun/jna/platform/win32/User32.java +++ b/contrib/platform/src/com/sun/jna/platform/win32/User32.java @@ -1857,6 +1857,35 @@ HWND CreateWindowEx(int dwExStyle, String lpClassName, */ BOOL EnumDisplayMonitors(HDC hdc, RECT lprcClip, MONITORENUMPROC lpfnEnum, LPARAM dwData); + /** + * retrieves information about one of the graphics modes for a display device. To retrieve information for + * all the graphics modes of a display device, make a series of calls to this function. + * + * @param lpszDeviceName A pointer to a null-terminated string that specifies the display device about + * whose graphics mode the function will obtain information. This parameter is either NULL or a + * DISPLAY_DEVICE.DeviceName returned from EnumDisplayDevices. A NULL value specifies the current + * display device on the computer on which the calling thread is running. + * + * @param iModeNum Graphics mode indexes start at zero. To obtain information for all of a display device's + * graphics modes, make a series of calls to EnumDisplaySettings, as follows: Set iModeNum to zero + * for the first call, and increment iModeNum by one for each subsequent call. Continue calling the + * function until the return value is zero. + * When you call EnumDisplaySettings with iModeNum set to zero, the operating system initializes and + * caches information about the display device. When you call EnumDisplaySettings with iModeNum set + * to a nonzero value, the function returns the information that was cached the last time the function + * was called with iModeNum set to zero. + * + * @param lpDevMode A pointer to a DEVMODE structure into which the function stores information about the + * specified graphics mode. Before calling EnumDisplaySettings, set the dmSize member to + * sizeof(DEVMODE), and set the dmDriverExtra member to indicate the size, in bytes, of the additional + * space available to receive private driver data. + * + * @return If the function succeeds, the return value is nonzero. If the function fails, the return value + * is zero. + * @see MSDN + */ + BOOL EnumDisplaySettings(String lpszDeviceName, int iModeNum, Pointer lpDevMode); + /** * Retrieves the show state and the restored, minimized, and maximized * positions of the specified window. @@ -2437,7 +2466,7 @@ HANDLE SetWinEventHook(int eventMin, int eventMax, HMODULE hmodWinEventProc, Win * duplicate icon.
* If the function fails, the return value is NULL. To get extended * error information, call GetLastError. - * @see MSDN + * @see MSDN* */ HICON CopyIcon(HICON hIcon); From 7d6879fd558d9b4e1c8e8cdf69ea6cd57cec0110 Mon Sep 17 00:00:00 2001 From: Vzor- Date: Tue, 19 Dec 2023 01:01:00 -0500 Subject: [PATCH 21/22] typo --- contrib/platform/src/com/sun/jna/platform/win32/WinGDI.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/contrib/platform/src/com/sun/jna/platform/win32/WinGDI.java b/contrib/platform/src/com/sun/jna/platform/win32/WinGDI.java index 2c5e3ce66d..0c902f5321 100644 --- a/contrib/platform/src/com/sun/jna/platform/win32/WinGDI.java +++ b/contrib/platform/src/com/sun/jna/platform/win32/WinGDI.java @@ -205,7 +205,7 @@ public void read() { /** * For printers: Specifies the name of the form to use; such as "Letter" or "Legal". This must be a name that - * can be obtain by calling the Win32 EnumForms function (described in the Microsoft Window SDK + * can be obtained by calling the Win32 EnumForms function (described in the Microsoft Window SDK * documentation). * * For displays: This member is not used for displays. From 05c8f925f5123ca7c0c59ff506ae6f7bffee7d12 Mon Sep 17 00:00:00 2001 From: Vzor- Date: Tue, 19 Dec 2023 03:12:05 -0500 Subject: [PATCH 22/22] getName cleanup --- .../com/sun/jna/platform/win32/WinGDI.java | 26 ++++++------------- 1 file changed, 8 insertions(+), 18 deletions(-) diff --git a/contrib/platform/src/com/sun/jna/platform/win32/WinGDI.java b/contrib/platform/src/com/sun/jna/platform/win32/WinGDI.java index 0c902f5321..a12b540aa4 100644 --- a/contrib/platform/src/com/sun/jna/platform/win32/WinGDI.java +++ b/contrib/platform/src/com/sun/jna/platform/win32/WinGDI.java @@ -23,13 +23,9 @@ */ package com.sun.jna.platform.win32; -import com.sun.jna.Native; -import com.sun.jna.NativeLong; -import com.sun.jna.Pointer; -import com.sun.jna.Structure; +import com.sun.jna.*; import com.sun.jna.Structure.FieldOrder; import com.sun.jna.platform.win32.WinNT.HANDLE; -import com.sun.jna.Union; import static com.sun.jna.platform.win32.WinDef.*; import java.nio.charset.StandardCharsets; @@ -325,31 +321,25 @@ public void read() { * Converts dmDeviceName from raw byte[] to String */ public String getDmDeviceName() { - String rawString; + long offset = fieldOffset("dmDeviceName"); if(CHAR_WIDTH == 1) { - rawString = Native.toString(dmDeviceName); + //todo: this can overrun if there is no null, perhaps we should add overrun protection to getString + return this.getPointer().getString(offset); } else { - rawString = new String(dmDeviceName, StandardCharsets.UTF_16LE); + return this.getPointer().getWideString(offset); } - int stringLength = rawString.indexOf("\0"); - if (stringLength == -1) return rawString; - return rawString.substring(0, stringLength); } /** * Converts dmFormName from raw byte[] to String */ public String getDmFormName() { - // todo: code duplicated, is there already a util to do this? - String rawString; + long offset = fieldOffset("dmFormName"); if(CHAR_WIDTH == 1) { - rawString = Native.toString(dmFormName); + return this.getPointer().getString(offset); } else { - rawString = new String(dmFormName, StandardCharsets.UTF_16LE); + return this.getPointer().getWideString(offset); } - int stringLength = rawString.indexOf("\0"); - if (stringLength == -1) return rawString; - return rawString.substring(0, stringLength); } public static class DUMMYUNIONNAME extends Union {