diff --git a/CHANGES.md b/CHANGES.md index dfd6fef745..8871e13e82 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -7,7 +7,7 @@ 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) +* [#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). @@ -30,8 +30,9 @@ Features * [#563](https://github.com/java-native-access/jna/pull/563): Added `com.sun.jna.platform.win32.Wininet` with the following 4 methods: `FindFirstUrlCacheEntry`, `DeleteUrlCacheEntry`, `FindCloseUrlCache`, `FindNextUrlCacheEntry`, and the `INTERNET_CACHE_ENTRY_INFO` structure, and a helper in `com.sun.jna.platform.win32.WininetUtil` for parsing WinInet's cache - [@mlfreeman2](https://github.com/mlfreeman2). * [#567](https://github.com/java-native-access/jna/pull/567): Added `PrintWindow`, `IsWindowEnabled`, `IsWindow`, `FindWindowEx`, `GetAncestor`, `GetCursorPos`, `SetCursorPos`, `SetWinEventHook`, `UnhookWinEvent`, `CopyIcon`, and `GetClassLong` to `com.sun.jna.platform.win32.User32` and supporting constants to `com.sun.jna.platform.win32.WinUser` - [@mlfreeman2](https://github.com/mlfreeman2). * [#573](https://github.com/java-native-access/jna/pull/573): Added `EnumProcessModules`, `GetModuleInformation`, and `GetProcessImageFileName` to `com.sun.jna.platform.win32.Psapi` and added `ExtractIconEx` to `com.sun.jna.platform.win32.Shell32` - [@mlfreeman2](https://github.com/mlfreeman2). -* [#574](https://github.com/java-native-access/jna/pull/574): Using static final un-modifiable List of field names for structure(s) [@lgoldstein](https://github.com/lgoldstein) -* [#577](https://github.com/java-native-access/jna/pull/577): Apply generic definitions wherever applicable [@lgoldstein](https://github.com/lgoldstein) +* [#574](https://github.com/java-native-access/jna/pull/574): Using static final un-modifiable List of field names for structure(s) - [@lgoldstein](https://github.com/lgoldstein). +* [#577](https://github.com/java-native-access/jna/pull/577): Apply generic definitions wherever applicable - [@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. Added GetPrinter and ClosePrinter functions in `com.sun.jna.platform.win32.Winspool` - [@IvanRF](https://github.com/IvanRF). Bug Fixes --------- 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 a82872b9e8..0acbbb372a 100644 --- a/contrib/platform/src/com/sun/jna/platform/win32/Winspool.java +++ b/contrib/platform/src/com/sun/jna/platform/win32/Winspool.java @@ -1,10 +1,10 @@ /* Copyright (c) 2010 Daniel Doubrovkine, All Rights Reserved - * + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. - * + * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU @@ -12,6 +12,7 @@ */ package com.sun.jna.platform.win32; +import java.util.Arrays; import java.util.List; import com.sun.jna.Memory; @@ -21,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; @@ -31,7 +33,7 @@ /** * Ported from Winspool.h. Windows SDK 6.0a - * + * * @author dblock[at]dblock.org */ public interface Winspool extends StdCallLibrary { @@ -96,7 +98,7 @@ public interface Winspool extends StdCallLibrary { /** * The EnumPrinters function enumerates available printers, print servers, * domains, or print providers. - * + * * @param Flags * The types of print objects that the function should enumerate. * @param Name @@ -153,20 +155,85 @@ 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); - - public static class PRINTER_INFO_1 extends Structure { - public static final List FIELDS = createFieldsOrder("Flags", "pDescription", "pName", "pComment"); - - public int Flags; - public String pDescription; - public String pName; - public String pComment; - - public PRINTER_INFO_1() { + + /** + * 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); + + /** + * The PRINTER_INFO_1 structure specifies general printer information. + * + * @see + * PRINTER_INFO_1 structure + */ + public static class PRINTER_INFO_1 extends Structure { + + public static final List FIELDS = createFieldsOrder("Flags", "pDescription", "pName", "pComment"); + + /** + * 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; + + public PRINTER_INFO_1() { super(); } @@ -179,15 +246,181 @@ protected List getFieldOrder() { return FIELDS; } } - - public static class PRINTER_INFO_4 extends Structure { - public static final List FIELDS = createFieldsOrder("pPrinterName", "pServerName", "Attributes"); - - public String pPrinterName; - public String pServerName; - public DWORD Attributes; - - public PRINTER_INFO_4() { + + /** + * 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 { + + public static final List FIELDS = createFieldsOrder("pServerName", "pPrinterName", "pShareName", + "pPortName", "pDriverName", "pComment", "pLocation", "pDevMode", "pSepFile", "pPrintProcessor", + "pDatatype", "pParameters", "pSecurityDescriptor", "Attributes", "Priority", "DefaultPriority", + "StartTime", "UntilTime", "Status", "cJobs", "AveragePPM"); + + /** + * 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; + + public PRINTER_INFO_2() { + super(); + } + + public PRINTER_INFO_2(int size) { + super(new Memory(size)); + } + + @Override + protected List getFieldOrder() { + return FIELDS; + } + } + + /** + * 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 { + + public static final List FIELDS = createFieldsOrder("pPrinterName", "pServerName", "Attributes"); + + /** + * 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; + + public PRINTER_INFO_4() { super(); } @@ -201,14 +434,37 @@ protected List getFieldOrder() { } } - public class LPPRINTER_DEFAULTS extends Structure { - public static final List FIELDS = createFieldsOrder("pDatatype", "pDevMode", "DesiredAccess"); - - public String pDatatype; - public PVOID pDevMode; - public int DesiredAccess; - - @Override + /** + * 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 { + + public static final List FIELDS = createFieldsOrder("pDatatype", "pDevMode", "DesiredAccess"); + + /** + * 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; + + @Override protected List getFieldOrder() { return FIELDS; } @@ -217,9 +473,7 @@ 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 @@ -239,15 +493,45 @@ 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, // _In_ LPPRINTER_DEFAULTS pDefault); + /** + * The ClosePrinter function closes the specified printer object.
+ * Note This is a blocking or synchronous function and might not return + * immediately.
+ * How quickly this function returns depends on run-time factors such as + * network status, print server configuration, and printer driver + * implementation-factors that are difficult to predict when writing an + * application. Calling this function from a thread that manages interaction + * with the user interface could make the application appear to be + * unresponsive. + * + * When the ClosePrinter function returns, the handle hPrinter is invalid, + * regardless of whether the function has succeeded or failed. + * + * @param hPrinter + * A handle to the printer object to be closed. This handle is + * returned by the OpenPrinter or AddPrinter function. + * @return If the function succeeds, the return value is a nonzero value. If + * the function fails, the return value is zero. + * + * @see + * ClosePrinter function + */ + boolean ClosePrinter(HANDLE hPrinter); + /** * The FindFirstPrinterChangeNotification function creates a change * notification object and returns a handle to the object. You can then use @@ -261,9 +545,7 @@ boolean OpenPrinter( * FindNextPrinterChangeNotification function to retrieve information about * 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 @@ -273,12 +555,12 @@ boolean OpenPrinter( * to enter a signaled state. A change notification occurs when * one or more of the specified conditions are met. The fdwFilter * parameter can be zero if pPrinterNotifyOptions is non-NULL. - * + * * @param fdwOptions - * Reserved; must be zero. - * @param pPrinterNotifyOptions + * Reserved; must be zero. + * @param pPrinterNotifyOptions * [in, optional] A pointer to a PRINTER_NOTIFY_OPTIONS - * structure. The pTypes member of this structure is an array of + * structure. The pTypes member of this structure is an array of * one or more PRINTER_NOTIFY_OPTIONS_TYPE structures, each of which * specifies a printer information field to monitor. A change * notification occurs when one or more of the specified fields @@ -287,14 +569,18 @@ boolean OpenPrinter( * new printer information. This parameter can be NULL if * fdwFilter is nonzero. For a list of fields that can be * monitored, see PRINTER_NOTIFY_OPTIONS_TYPE. - * + * * @return If the function succeeds, the return value is a handle to a * 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); @@ -311,9 +597,7 @@ HANDLE FindFirstPrinterChangeNotification( * changes occurs to the printer or print server. The * 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 @@ -328,7 +612,7 @@ HANDLE FindFirstPrinterChangeNotification( * those specified in the fdwFilter parameter of the * FindFirstPrinterChangeNotification call. The system sets one * or more of the following bit flags. - * + * * @param pPrinterNotifyOptions * [in, optional] A pointer to a PRINTER_NOTIFY_OPTIONS * structure. Set the Flags member of this structure to @@ -336,7 +620,7 @@ HANDLE FindFirstPrinterChangeNotification( * return the current data for all monitored printer information * fields. The function ignores all other members of the * structure. This parameter can be NULL. - * + * * @param ppPrinterNotifyInfo * [out, optional] A pointer to a pointer variable that receives * a pointer to a system-allocated, read-only buffer. Call the @@ -358,12 +642,16 @@ HANDLE FindFirstPrinterChangeNotification( * no additional notifications will be sent until you make a * second FindNextPrinterChangeNotification call that specifies * PRINTER_NOTIFY_OPTIONS_REFRESH. - * + * * @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, @@ -378,23 +666,65 @@ boolean FindNextPrinterChangeNotification( * FindFirstPrinterChangeNotification function. The printer or print server * 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 * FindFirstPrinterChangeNotification function. - * + * * @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, @@ -411,31 +741,96 @@ boolean EnumJobs( // _Out_ IntByReference pcReturned); - public static class JOB_INFO_1 extends Structure { - public static final List FIELDS = createFieldsOrder( + /** + * 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 { + + public static final List FIELDS = createFieldsOrder( "JobId", "pPrinterName", "pMachineName", "pUserName", "pDocument", "pDatatype", "pStatus", "Status", "Priority", "Position", "TotalPages", "PagesPrinted", "Submitted"); - - 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; - - @Override - protected List getFieldOrder() { - return FIELDS; - } + + /** + * 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; public JOB_INFO_1() { super(); @@ -444,5 +839,10 @@ public JOB_INFO_1() { public JOB_INFO_1(int size) { super(new Memory(size)); } + + @Override + protected List getFieldOrder() { + return FIELDS; + } } } 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..15c9876bd6 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,78 @@ 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()); + + Win32Exception we = null; + PRINTER_INFO_2 pinfo2 = null; + + try { + Winspool.INSTANCE.GetPrinter(pHandle.getValue(), 2, null, 0, pcbNeeded); + if (pcbNeeded.getValue() <= 0) + return new 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(); + } catch (Win32Exception e) { + we = e; + } finally { + if (!Winspool.INSTANCE.ClosePrinter(pHandle.getValue())) { + Win32Exception ex = new Win32Exception(Kernel32.INSTANCE.GetLastError()); + if (we != null) { + ex.addSuppressed(we); + } + } + } + + if (we != null) { + throw we; + } + + return pinfo2; + } public static PRINTER_INFO_4[] getPrinterInfo4() { IntByReference pcbNeeded = new IntByReference(); diff --git a/contrib/platform/test/com/sun/jna/platform/win32/WinspoolTest.java b/contrib/platform/test/com/sun/jna/platform/win32/WinspoolTest.java index 42de43edb1..0bc6f0e2b5 100644 --- a/contrib/platform/test/com/sun/jna/platform/win32/WinspoolTest.java +++ b/contrib/platform/test/com/sun/jna/platform/win32/WinspoolTest.java @@ -12,12 +12,15 @@ */ package com.sun.jna.platform.win32; -import junit.framework.TestCase; - +import com.sun.jna.Native; +import com.sun.jna.platform.win32.WinNT.HANDLEByReference; 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; +import junit.framework.TestCase; + /** * @author dblock[at]dblock[dot]org */ @@ -30,40 +33,65 @@ public static void main(String[] args) { public void testEnumPrinters_4() { IntByReference pcbNeeded = new IntByReference(); IntByReference pcReturned = new IntByReference(); - // if there're no printers installed, EnumPrinters will succeed with zero items returned - Winspool.INSTANCE.EnumPrinters(Winspool.PRINTER_ENUM_LOCAL, - null, 4, null, 0, pcbNeeded, pcReturned); + // if there are no printers installed, EnumPrinters will succeed with zero items returned + Winspool.INSTANCE.EnumPrinters(Winspool.PRINTER_ENUM_LOCAL, null, 4, null, 0, pcbNeeded, pcReturned); assertTrue(pcReturned.getValue() == 0); if (pcbNeeded.getValue() > 0) { - PRINTER_INFO_4 pPrinterEnum = new PRINTER_INFO_4(pcbNeeded.getValue()); - assertTrue(Winspool.INSTANCE.EnumPrinters(Winspool.PRINTER_ENUM_LOCAL, - null, 4, pPrinterEnum.getPointer(), pcbNeeded.getValue(), pcbNeeded, pcReturned)); - assertTrue(pcReturned.getValue() >= 0); + PRINTER_INFO_4 pPrinterEnum = new PRINTER_INFO_4(pcbNeeded.getValue()); + assertTrue(Winspool.INSTANCE.EnumPrinters(Winspool.PRINTER_ENUM_LOCAL, null, 4, pPrinterEnum.getPointer(), pcbNeeded.getValue(), pcbNeeded, pcReturned)); + assertTrue(pcReturned.getValue() >= 0); PRINTER_INFO_4[] printerInfo = (PRINTER_INFO_4[]) pPrinterEnum.toArray(pcReturned.getValue()); for(PRINTER_INFO_4 pi : printerInfo) { assertTrue(pi.pPrinterName == null || pi.pPrinterName.length() >= 0); - // System.out.println(pi.pPrinterName); } } } + public void testEnumPrinters_2() { + IntByReference pcbNeeded = new IntByReference(); + IntByReference pcReturned = new IntByReference(); + // if there are no printers installed, EnumPrinters will succeed with zero items returned + Winspool.INSTANCE.EnumPrinters(Winspool.PRINTER_ENUM_LOCAL, null, 2, null, 0, pcbNeeded, pcReturned); + assertTrue(pcReturned.getValue() == 0); + if (pcbNeeded.getValue() > 0) { + PRINTER_INFO_2 pPrinterEnum = new PRINTER_INFO_2(pcbNeeded.getValue()); + assertTrue(Winspool.INSTANCE.EnumPrinters(Winspool.PRINTER_ENUM_LOCAL, null, 2, pPrinterEnum.getPointer(), pcbNeeded.getValue(), pcbNeeded, pcReturned)); + assertTrue(pcReturned.getValue() >= 0); + PRINTER_INFO_2[] printerInfo = (PRINTER_INFO_2[]) pPrinterEnum.toArray(pcReturned.getValue()); + for(PRINTER_INFO_2 pi : printerInfo) { + assertTrue(pi.pPrinterName == null || pi.pPrinterName.length() >= 0); + } + } + } + public void testEnumPrinters_1() { IntByReference pcbNeeded = new IntByReference(); IntByReference pcReturned = new IntByReference(); - // if there're no printers installed, EnumPrinters will succeed with zero items returned - Winspool.INSTANCE.EnumPrinters(Winspool.PRINTER_ENUM_LOCAL, - null, 1, null, 0, pcbNeeded, pcReturned); + // if there are no printers installed, EnumPrinters will succeed with zero items returned + Winspool.INSTANCE.EnumPrinters(Winspool.PRINTER_ENUM_LOCAL, null, 1, null, 0, pcbNeeded, pcReturned); assertTrue(pcReturned.getValue() == 0); if (pcbNeeded.getValue() > 0) { PRINTER_INFO_1 pPrinterEnum = new PRINTER_INFO_1(pcbNeeded.getValue()); - assertTrue(Winspool.INSTANCE.EnumPrinters(Winspool.PRINTER_ENUM_LOCAL, - null, 1, pPrinterEnum.getPointer(), pcbNeeded.getValue(), pcbNeeded, pcReturned)); + assertTrue(Winspool.INSTANCE.EnumPrinters(Winspool.PRINTER_ENUM_LOCAL, null, 1, pPrinterEnum.getPointer(), pcbNeeded.getValue(), pcbNeeded, pcReturned)); assertTrue(pcReturned.getValue() >= 0); PRINTER_INFO_1[] printerInfo = (PRINTER_INFO_1[]) pPrinterEnum.toArray(pcReturned.getValue()); for(PRINTER_INFO_1 pi : printerInfo) { assertTrue(pi.pName == null || pi.pName.length() >= 0); - // System.out.println(pi.pName); } } } + + public void testOpenPrinter() { + HANDLEByReference hbr = new HANDLEByReference(); + boolean result = Winspool.INSTANCE.OpenPrinter("1234567890A123", hbr, null); + assertFalse("OpenPrinter should return false on failure.", result); + assertNull("The pointer-to-a-printer-handle should be null on failure.", hbr.getValue()); + assertEquals("GetLastError() should return ERROR_INVALID_PRINTER_NAME", WinError.ERROR_INVALID_PRINTER_NAME, Native.getLastError()); + } + + public void testClosePrinter() { + boolean result = Winspool.INSTANCE.ClosePrinter(null); + assertFalse("ClosePrinter should return false on failure.", result); + assertEquals("GetLastError() should return ERROR_INVALID_HANDLE", WinError.ERROR_INVALID_HANDLE, Native.getLastError()); + } } diff --git a/contrib/platform/test/com/sun/jna/platform/win32/WinspoolUtilTest.java b/contrib/platform/test/com/sun/jna/platform/win32/WinspoolUtilTest.java index 793de5349a..0d83c2388b 100644 --- a/contrib/platform/test/com/sun/jna/platform/win32/WinspoolUtilTest.java +++ b/contrib/platform/test/com/sun/jna/platform/win32/WinspoolUtilTest.java @@ -23,7 +23,7 @@ public class WinspoolUtilTest extends TestCase { public static void main(String[] args) { - junit.textui.TestRunner.run(Shell32UtilTest.class); + junit.textui.TestRunner.run(WinspoolUtilTest.class); for(PRINTER_INFO_1 printerInfo : WinspoolUtil.getPrinterInfo1()) { System.out.println(printerInfo.pName + ": " + printerInfo.pDescription); } @@ -36,7 +36,21 @@ public void testGetPrinterInfo1() { assertTrue(WinspoolUtil.getPrinterInfo1().length >= 0); } - public void testGetPrinterInfo4() { - assertTrue(WinspoolUtil.getPrinterInfo4().length >= 0); + public void testGetPrinterInfo2() { + assertTrue(WinspoolUtil.getPrinterInfo2().length >= 0); } + + public void testGetPrinterInfo2Specific() { + try { + WinspoolUtil.getPrinterInfo2("1234567890A123"); + fail("A Win32Exception with ERROR_INVALID_PRINTER_NAME should have been thrown instead of hitting this."); + } catch (Win32Exception e) { + assertEquals("A Win32Exception with ERROR_INVALID_PRINTER_NAME message should have been thrown.", + Kernel32Util.formatMessage(W32Errors.HRESULT_FROM_WIN32(WinError.ERROR_INVALID_PRINTER_NAME)), e.getMessage()); + } + } + + public void testGetPrinterInfo4() { + assertTrue(WinspoolUtil.getPrinterInfo4().length >= 0); + } }