diff --git a/CHANGES.md b/CHANGES.md index e25c3e6fcb..75e8ac5703 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -7,7 +7,8 @@ Next release Features -------- -* [#526](https://github.com/java-native-access/jna/pull/526): Added initialization and conversion between Windows SYSTEMTIME and Java Calendar [@lgoldstein](https://github.com/lgoldstein) +* [#569](https://github.com/java-native-access/jna/pull/569): Added `com.sun.jna.platform.win32.Winspool.PRINTER_INFO_2` support and GetPrinter function in `com.sun.jna.platform.win32.Winspool` - [@IvanRF](https://github.com/IvanRF). +* [#526](https://github.com/java-native-access/jna/pull/526): Added initialization and conversion between Windows SYSTEMTIME and Java Calendar - [@lgoldstein](https://github.com/lgoldstein). * [#532](https://github.com/java-native-access/jna/pull/529): Added `com.sun.jna.platform.win32.Mpr`, `com.sun.jna.platform.win32.LmShare`, and `com.sun.jna.platform.win32.Winnetwk` - [@amarcionek](https://github.com/amarcionek). * [#532](https://github.com/java-native-access/jna/pull/529): Added `ACCESS_*` definitions to `com.sun.jna.platform.win32.LmAccess` - [@amarcionek](https://github.com/amarcionek). * [#532](https://github.com/java-native-access/jna/pull/529): Added `NetShareAdd` and `NetShareDel` to `com.sun.jna.platform.win32.Netapi32` - [@amarcionek](https://github.com/amarcionek). 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 7e81cdd79b..b4a217971e 100644 --- a/contrib/platform/src/com/sun/jna/platform/win32/Winspool.java +++ b/contrib/platform/src/com/sun/jna/platform/win32/Winspool.java @@ -22,6 +22,7 @@ import com.sun.jna.platform.win32.WinBase.SYSTEMTIME; import com.sun.jna.platform.win32.WinDef.DWORD; import com.sun.jna.platform.win32.WinDef.DWORDByReference; +import com.sun.jna.platform.win32.WinDef.INT_PTR; import com.sun.jna.platform.win32.WinDef.LPVOID; import com.sun.jna.platform.win32.WinDef.PVOID; import com.sun.jna.platform.win32.WinNT.HANDLE; @@ -154,18 +155,82 @@ public interface Winspool extends StdCallLibrary { * array to which pPrinterEnum points. * @return If the function succeeds, the return value is a nonzero value. If * the function fails, the return value is zero. - */ + * + * @see + * EnumPrinters function + */ boolean EnumPrinters(int Flags, String Name, int Level, Pointer pPrinterEnum, int cbBuf, IntByReference pcbNeeded, IntByReference pcReturned); + + /** + * The GetPrinter function retrieves information about a specified printer. + * + * @param hPrinter + * A handle to the printer for which the function retrieves + * information. Use the OpenPrinter or AddPrinter function to + * retrieve a printer handle. + * @param Level + * The level or type of structure that the function stores into + * the buffer pointed to by pPrinter. This value can be 1, 2, 3, + * 4, 5, 6, 7, 8 or 9. + * @param pPrinter + * A pointer to a buffer that receives a structure containing + * information about the specified printer. The buffer must be + * large enough to receive the structure and any strings or other + * data to which the structure members point. If the buffer is + * too small, the pcbNeeded parameter returns the required buffer + * size. The type of structure is determined by the value of + * Level. + * @param cbBuf + * The size, in bytes, of the buffer pointed to by pPrinter. + * @param pcbNeeded + * A pointer to a variable that the function sets to the size, in + * bytes, of the printer information. If cbBuf is smaller than + * this value, GetPrinter fails, and the value represents the + * required buffer size. If cbBuf is equal to or greater than + * this value, GetPrinter succeeds, and the value represents the + * number of bytes stored in the buffer. + * @return If the function succeeds, the return value is a nonzero value. If + * the function fails, the return value is zero. + * + * @see + * GetPrinter function + */ + boolean GetPrinter(HANDLE hPrinter, int Level, Pointer pPrinter, int cbBuf, IntByReference pcbNeeded); - public static class PRINTER_INFO_1 extends Structure { - public int Flags; - public String pDescription; - public String pName; - public String pComment; + /** + * The PRINTER_INFO_1 structure specifies general printer information. + * + * @see + * PRINTER_INFO_1 structure + */ + public static class PRINTER_INFO_1 extends Structure { + /** + * Specifies information about the returned data. Following are the + * values for this member. + */ + public int Flags; + /** + * Pointer to a null-terminated string that describes the contents of + * the structure. + */ + public String pDescription; + /** + * Pointer to a null-terminated string that names the contents of the + * structure. + */ + public String pName; + /** + * Pointer to a null-terminated string that contains additional data + * describing the structure. + */ + public String pComment; - protected List getFieldOrder() { + protected List getFieldOrder() { return Arrays.asList(new String[] { "Flags", "pDescription", "pName", "pComment" }); } @@ -177,13 +242,174 @@ public PRINTER_INFO_1(int size) { super(new Memory(size)); } } + + /** + * The PRINTER_INFO_2 structure specifies detailed printer information. + * + * @author Ivan Ridao Freitas, Padrus + * @see + * PRINTER_INFO_2 structure + */ + public static class PRINTER_INFO_2 extends Structure { + + /** + * A pointer to a null-terminated string identifying the server that + * controls the printer. If this string is NULL, the printer is + * controlled locally. + */ + public String pServerName; + /** + * A pointer to a null-terminated string that specifies the name of the + * printer. + */ + public String pPrinterName; + /** + * A pointer to a null-terminated string that identifies the share point + * for the printer. (This string is used only if the + * PRINTER_ATTRIBUTE_SHARED constant was set for the Attributes member.) + */ + public String pShareName; + /** + * 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; + /** + * A pointer to a null-terminated string that specifies the name of the + * printer driver. + */ + public String pDriverName; + /** + * A pointer to a null-terminated string that provides a brief + * description of the printer. + */ + public String pComment; + /** + * A pointer to a null-terminated string that specifies the physical + * location of the printer (for example, "Bldg. 38, Room 1164"). + */ + public String pLocation; + /** + * A pointer to a DEVMODE structure that defines default printer data + * such as the paper orientation and the resolution. + */ + public INT_PTR pDevMode; + /** + * A pointer to a null-terminated string that specifies the name of the + * file used to create the separator page. This page is used to separate + * print jobs sent to the printer. + */ + public String pSepFile; + /** + * A pointer to a null-terminated string that specifies the name of the + * print processor used by the printer. You can use the + * EnumPrintProcessors function to obtain a list of print processors + * installed on a server. + */ + public String pPrintProcessor; + /** + * A pointer to a null-terminated string that specifies the data type + * used to record the print job. You can use the + * EnumPrintProcessorDatatypes function to obtain a list of data types + * supported by a specific print processor. + */ + public String pDatatype; + /** + * A pointer to a null-terminated string that specifies the default + * print-processor parameters. + */ + public String pParameters; + /** + * A pointer to a SECURITY_DESCRIPTOR structure for the printer. This + * member may be NULL. + */ + public INT_PTR pSecurityDescriptor; + /** + * The printer attributes. This member can be any reasonable combination + * of the values PRINTER_ATTRIBUTE_XXX. + */ + public int Attributes; + /** + * A priority value that the spooler uses to route print jobs. + */ + public int Priority; + /** + * The default priority value assigned to each print job. + */ + public int DefaultPriority; + /** + * The earliest time at which the printer will print a job. This value + * is expressed as minutes elapsed since 12:00 AM GMT (Greenwich Mean + * Time). + */ + public int StartTime; + /** + * The latest time at which the printer will print a job. This value is + * expressed as minutes elapsed since 12:00 AM GMT (Greenwich Mean + * Time). + */ + public int UntilTime; + /** + * The printer status. This member can be any reasonable combination of + * the values PRINTER_STATUS_XXX. + */ + public int Status; + /** + * The number of print jobs that have been queued for the printer. + */ + public int cJobs; + /** + * The average number of pages per minute that have been printed on the + * printer. + */ + public int AveragePPM; + + protected List getFieldOrder() { + return Arrays.asList(new String[] { "pServerName", "pPrinterName", "pShareName", "pPortName", "pDriverName", + "pComment", "pLocation", "pDevMode", "pSepFile", "pPrintProcessor", "pDatatype", "pParameters", + "pSecurityDescriptor", "Attributes", "Priority", "DefaultPriority", "StartTime", "UntilTime", + "Status", "cJobs", "AveragePPM" }); + } + + public PRINTER_INFO_2() { + } + + public PRINTER_INFO_2(int size) { + super(new Memory(size)); + } + } - public static class PRINTER_INFO_4 extends Structure { - public String pPrinterName; - public String pServerName; - public DWORD Attributes; + /** + * The PRINTER_INFO_4 structure specifies general printer information. + *

+ * The structure can be used to retrieve minimal printer information on a + * call to EnumPrinters. Such a call is a fast and easy way to retrieve the + * names and attributes of all locally installed printers on a system and + * all remote printer connections that a user has established. + * + * @see + * PRINTER_INFO_4 structure + */ + public static class PRINTER_INFO_4 extends Structure { + /** + * Pointer to a null-terminated string that specifies the name of the + * printer (local or remote). + */ + public String pPrinterName; + /** + * Pointer to a null-terminated string that is the name of the server. + */ + public String pServerName; + /** + * Specifies information about the returned data. + */ + public DWORD Attributes; - protected List getFieldOrder() { + protected List getFieldOrder() { return Arrays.asList(new String[] { "pPrinterName", "pServerName", "Attributes" }); } @@ -196,12 +422,34 @@ public PRINTER_INFO_4(int size) { } } - public class LPPRINTER_DEFAULTS extends Structure { - public String pDatatype; - PVOID pDevMode; - int DesiredAccess; + /** + * The PRINTER_DEFAULTS structure specifies the default data type, + * environment, initialization data, and access rights for a printer. + * + * @see + * PRINTER_DEFAULTS structure + */ + public class LPPRINTER_DEFAULTS extends Structure { + /** + * Pointer to a null-terminated string that specifies the default data + * type for a printer. + */ + public String pDatatype; + /** + * Pointer to a DEVMODE structure that identifies the default + * environment and initialization data for a printer. + */ + PVOID pDevMode; + /** + * Specifies desired access rights for a printer. The OpenPrinter + * function uses this member to set access rights to the printer. These + * rights can affect the operation of the SetPrinter and DeletePrinter + * functions. + */ + int DesiredAccess; - protected List getFieldOrder() { + protected List getFieldOrder() { return Arrays.asList(new String[] { "pDatatype", "pDevMode", "DesiredAccess" }); } @@ -211,8 +459,6 @@ protected List getFieldOrder() { * The OpenPrinter function retrieves a handle to the specified printer or * print server or other types of handles in the print subsystem. * - * @see MSDN - * * @param pPrinterName * [in] A pointer to a null-terminated string that specifies the * name of the printer or print server, the printer object, the @@ -232,9 +478,13 @@ protected List getFieldOrder() { * be NULL. * @return If the function succeeds, the return value is a nonzero value. If * the function fails, the return value is zero. - */ + * + * @see + * OpenPrinter function + */ boolean OpenPrinter( - // _In_ + // _In_ String pPrinterName, // _Out_ HANDLEByReference phPrinter, @@ -255,8 +505,6 @@ boolean OpenPrinter( * the change, and to reset the change notification object for use in the * next wait operation. * - * @see MSDN - * * @param hPrinter * [in] A handle to the printer or print server that you want to * monitor. Use the OpenPrinter or AddPrinter function to @@ -285,9 +533,13 @@ boolean OpenPrinter( * change notification object associated with the specified printer * or print server. If the function fails, the return value is * INVALID_HANDLE_VALUE. - */ + * + * @see + * FindFirstPrinterChangeNotification function + */ HANDLE FindFirstPrinterChangeNotification( - // _In_ + // _In_ HANDLE hPrinter, int fdwFilter, int fdwOptions, // _In_opt_ LPVOID pPrinterNotifyOptions); @@ -305,8 +557,6 @@ HANDLE FindFirstPrinterChangeNotification( * FindFirstPrinterChangeNotification function creates the change * notification object and specifies the set of changes to be monitored. * - * @see MSDN - * * @param hChange * [in] A handle to a change notification object associated with * a printer or print server. You obtain such a handle by calling @@ -354,9 +604,13 @@ HANDLE FindFirstPrinterChangeNotification( * * @return If the function succeeds, the return value is a nonzero value. If * the function fails, the return value is zero. - */ + * + * @see + * FindClosePrinterChangeNotification function + */ boolean FindNextPrinterChangeNotification( - // _In_ + // _In_ HANDLE hChange, // _Out_opt_ DWORDByReference pdwChange, @@ -372,8 +626,6 @@ boolean FindNextPrinterChangeNotification( * associated with the change notification object will no longer be * monitored by that object. * - * @see MSDN - * * @param hChange * [in] A handle to the change notification object to be closed. * This is a handle created by calling the @@ -381,13 +633,57 @@ boolean FindNextPrinterChangeNotification( * * @return If the function succeeds, the return value is a nonzero value. If * the function fails, the return value is zero. - */ + * + * @see + * FindClosePrinterChangeNotification function + */ boolean FindClosePrinterChangeNotification( - // _In_ + // _In_ HANDLE hChange); + /** + * The EnumJobs function retrieves information about a specified set of + * print jobs for a specified printer. + * + * @param hPrinter + * A handle to the printer object whose print jobs the function + * enumerates. Use the OpenPrinter or AddPrinter function to + * retrieve a printer handle. + * @param FirstJob + * The zero-based position within the print queue of the first + * print job to enumerate. For example, a value of 0 specifies + * that enumeration should begin at the first print job in the + * print queue; a value of 9 specifies that enumeration should + * begin at the tenth print job in the print queue. + * @param NoJobs + * The total number of print jobs to enumerate. + * @param Level + * The type of information returned in the pJob buffer. + * @param pJob + * A pointer to a buffer that receives an array of JOB_INFO_1, + * JOB_INFO_2, or JOB_INFO_3 structures. The buffer must be large + * enough to receive the array of structures and any strings or + * other data to which the structure members point. + * @param cbBuf + * The size, in bytes, of the pJob buffer. + * @param pcbNeeded + * A pointer to a variable that receives the number of bytes + * copied if the function succeeds. If the function fails, the + * variable receives the number of bytes required. + * @param pcReturned + * A pointer to a variable that receives the number of + * JOB_INFO_1, JOB_INFO_2, or JOB_INFO_3 structures returned in + * the pJob buffer. + * @return If the function succeeds, the return value is a nonzero value. If + * the function fails, the return value is zero. + * + * @see + * EnumJobs function + */ boolean EnumJobs( - // _In_ + // _In_ HANDLE hPrinter, // _In_ int FirstJob, @@ -404,22 +700,91 @@ boolean EnumJobs( // _Out_ IntByReference pcReturned); - public static class JOB_INFO_1 extends Structure { - public int JobId; - public String pPrinterName; - public String pMachineName; - public String pUserName; - public String pDocument; - public String pDatatype; - public String pStatus; - public int Status; - public int Priority; - public int Position; - public int TotalPages; - public int PagesPrinted; - public SYSTEMTIME Submitted; - - protected List getFieldOrder() { + /** + * The JOB_INFO_1 structure specifies print-job information such as the + * job-identifier value, the name of the printer for which the job is + * spooled, the name of the machine that created the print job, the name of + * the user that owns the print job, and so on. + * + * @see + * JOB_INFO_1 structure + */ + public static class JOB_INFO_1 extends Structure { + /** + * A job identifier. + */ + public int JobId; + /** + * A pointer to a null-terminated string that specifies the name of the + * printer for which the job is spooled. + */ + public String pPrinterName; + /** + * A pointer to a null-terminated string that specifies the name of the + * machine that created the print job. + */ + public String pMachineName; + /** + * A pointer to a null-terminated string that specifies the name of the + * user that owns the print job. + */ + public String pUserName; + /** + * A pointer to a null-terminated string that specifies the name of the + * print job (for example, "MS-WORD: Review.doc"). + */ + public String pDocument; + /** + * A pointer to a null-terminated string that specifies the type of data + * used to record the print job. + */ + public String pDatatype; + /** + * A pointer to a null-terminated string that specifies the status of + * the print job. This member should be checked prior to Status and, if + * pStatus is NULL, the status is defined by the contents of the Status + * member. + */ + public String pStatus; + /** + * The job status. The value of this member can be zero or a combination + * of one or more of the following values. A value of zero indicates + * that the print queue was paused after the document finished spooling. + */ + public int Status; + /** + * The job priority. This member can be one of the following values or + * in the range between 1 through 99 (MIN_PRIORITY through + * MAX_PRIORITY). + */ + public int Priority; + /** + * The job's position in the print queue. + */ + public int Position; + /** + * The total number of pages that the document contains. This value may + * be zero if the print job does not contain page delimiting + * information. + */ + public int TotalPages; + /** + * The number of pages that have printed. This value may be zero if the + * print job does not contain page delimiting information. + */ + public int PagesPrinted; + /** + * A SYSTEMTIME structure that specifies the time that this document was + * spooled. + *

+ * This time value is in Universal Time Coordinate (UTC) format. You + * should convert it to a local time value before displaying it. You can + * use the FileTimeToLocalFileTime function to perform the conversion. + */ + public SYSTEMTIME Submitted; + + protected List getFieldOrder() { return Arrays.asList(new String[] { "JobId", "pPrinterName", "pMachineName", "pUserName", "pDocument", "pDatatype", "pStatus", "Status", "Priority", "Position", "TotalPages", 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 9104e20280..aea5be0e44 100644 --- a/contrib/platform/src/com/sun/jna/platform/win32/WinspoolUtil.java +++ b/contrib/platform/src/com/sun/jna/platform/win32/WinspoolUtil.java @@ -15,13 +15,14 @@ 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.ptr.IntByReference; /** * Winspool Utility API. * - * @author dblock[at]dblock.org + * @author dblock[at]dblock.org, Ivan Ridao Freitas, Padrus */ public abstract class WinspoolUtil { @@ -45,6 +46,59 @@ public static PRINTER_INFO_1[] getPrinterInfo1() { 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. + */ + 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) { + IntByReference pcbNeeded = new IntByReference(); + IntByReference pcReturned = new IntByReference(); + HANDLEByReference pHandle = new HANDLEByReference(); + + if (!Winspool.INSTANCE.OpenPrinter(printerName, pHandle, null)) + throw new Win32Exception(Kernel32.INSTANCE.GetLastError()); + + Winspool.INSTANCE.GetPrinter(pHandle.getValue(), 2, null, 0, pcbNeeded); + if (pcbNeeded.getValue() <= 0) + return new PRINTER_INFO_2(); + + PRINTER_INFO_2 pinfo2 = new PRINTER_INFO_2(pcbNeeded.getValue()); + if (!Winspool.INSTANCE.GetPrinter(pHandle.getValue(), 2, pinfo2.getPointer(), pcbNeeded.getValue(), pcReturned)) + throw new Win32Exception(Kernel32.INSTANCE.GetLastError()); + + pinfo2.read(); + return pinfo2; + } public static PRINTER_INFO_4[] getPrinterInfo4() { IntByReference pcbNeeded = new IntByReference();