Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add missing PRINTER_INFO_X structs #1429

Draft
wants to merge 22 commits into
base: master
Choose a base branch
from
Draft
Changes from 1 commit
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Improve comments, javadocs
tresf committed Mar 30, 2022
commit eefe7de53677e6d8e6c1ac3906b158b32dda8784
145 changes: 126 additions & 19 deletions contrib/platform/src/com/sun/jna/platform/win32/Winspool.java
Original file line number Diff line number Diff line change
@@ -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 <a href=
* "https://msdn.microsoft.com/en-us/library/windows/desktop/dd162692(v=vs.85).aspx">
* "https://docs.microsoft.com/windows/win32/printdocs/enumprinters">
* EnumPrinters function</a>
*/
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 <a href=
* "https://msdn.microsoft.com/en-us/library/windows/desktop/dd144911(v=vs.85).aspx">
* "https://docs.microsoft.com/windows/win32/printdocs/getprinter">
* GetPrinter function</a>
*/
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 <a href=
* "https://msdn.microsoft.com/en-us/library/windows/desktop/dd162844(v=vs.85).aspx">
* "https://docs.microsoft.com/windows/win32/printdocs/printer-info-1">
* PRINTER_INFO_1 structure</a>
*/
@FieldOrder({"Flags", "pDescription", "pName", "pComment"})
@@ -372,7 +378,7 @@ public PRINTER_INFO_1(int size) {
*
* @author Ivan Ridao Freitas, Padrus
* @see <a href=
* "https://msdn.microsoft.com/en-us/library/windows/desktop/dd162845(v=vs.85).aspx">
* "https://docs.microsoft.com/windows/win32/printdocs/printer-info-2">
* PRINTER_INFO_2 structure</a>
*/
@FieldOrder({"pServerName", "pPrinterName", "pShareName",
@@ -514,9 +520,23 @@ public boolean hasAttribute(int value) {

/**
* The PRINTER_INFO_3 structure specifies printer security information.
* <p>
* 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 <a href=
* "https://docs.microsoft.com/windows/win32/printdocs/printer-info-3">
* PRINTER_INFO_3 structure</a>
*/
@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;
Copy link
Contributor Author

@tresf tresf Mar 29, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Although WinNT provides a struct named SECURITY_DESCRIPTOR, the struct is malformed for use with PRINTER_INFO_3 despite having an identical name. Using WinNT.SECURITY_DESCRIPTOR will throw a runtime error java.lang.IllegalStateException: Array fields must be initialized.

Fortunately SECURITY_DESCRIPTOR_RELATIVE matches the struct design exactly that's returned by PRINTER_INFO_3, fixing this runtime exception. This is just an FYI and can be acknowledged by a project maintainer if there are no objections. :)

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a pointer to SECURITY_DESCRIPTOR and I believe the _RELATIVE version is the correct "by reference" mapping.

Copy link
Contributor Author

@tresf tresf Mar 30, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reopening... so going back on the DWORD vs int conversation, I'm looking for examples and found that PRINTER_INFO_2 uses public INT_PTR pSecurityDescriptor; however this PR uses the WinNT.SECURITY_DESCRIPTOR_RELATIVE. Should I switch PRINTER_INFO_3 to match? It seems less useful, but I'd like to be consistent. If so, how would I go about getting the data, construct a Pointer from the int and manually cast it? If that's the case, is this better than just using the correct struct to begin with?

Copy link
Contributor Author

@tresf tresf Mar 30, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same issue occurs for PRINTER_INFO_2, which returns a INT_PTR in place of the pDevMode, whereas the newly written PRINTER_INFO_8, PRINTER_INFO_9 both use this PR's struct. pDevMode appears again in L_PRINTER_DEFAULTS, but this time as a Pointer object.

I can update PRINTER_INFO_2, but those using the API in its current form will break.

Alternately I can switch PRINTER_INFO_9 and PRINTER_INFO_8 to use Pointers and then allow DEVMODE to be constructed manually, but I think this will be less intuitive.

I tried to convert the INT_PTR to a Pointer and then to a struct, but I got an error java.lang.UnsupportedOperationException: This pointer is opaque: const@0x1a31bba904c.

// Doesn't work :(
public DEVMODE(Pointer p) {
    super(p);
    ensureAllocated();
    read();
}

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reopening... so going back on the DWORD vs int conversation, I'm looking for examples and found that PRINTER_INFO_2 uses public INT_PTR pSecurityDescriptor; however this PR uses the WinNT.SECURITY_DESCRIPTOR_RELATIVE. Should I switch PRINTER_INFO_3 to match?

My apologies, I answered the first one thinking about a completely different recent change. Ultimately you need to map a pointer of some sort, and then use that pointer to map to the structure it points to. Using the ByReference tag on the structure accomplishes this transparently and should probably be your first choice. So I'd suggest WinNT.SECURITY_DESCRIPTOR_RELATIVE.ByReference. Check the commit dates on the other structure, it's entirely possible it was committed first.

Don't change old ones to break compatibility. If you want consistency, feel free to match them, but INT_PTR is a pointer-sized integer so you'd need to use toPointer() to convert it and then use that pointer to pass to a constructor.

It seems less useful, but I'd like to be consistent. If so, how would I go about getting the data, construct a Pointer from the int and manually cast it? If that's the case, is this better than just using the correct struct to begin with?

I think the structure (by reference) is the easiest. So you get INT_PTR ip, you do Pointer p = ip.toPointer() and then pass p to the pointer constructor of the structure, essentially this (FooStructure extends Structure):

FooStructure(Pointer p) {
  super(p);
  // anything else you need to do
}


public PRINTER_INFO_3() {}
@@ -535,7 +555,7 @@ public PRINTER_INFO_3(int size) {
* all remote printer connections that a user has established.
*
* @see <a href=
* "https://msdn.microsoft.com/en-us/library/windows/desktop/dd162847(v=vs.85).aspx">
* "https://docs.microsoft.com/windows/win32/printdocs/printer-info-4">
* PRINTER_INFO_4 structure</a>
*/
@FieldOrder({"pPrinterName", "pServerName", "Attributes"})
@@ -566,13 +586,44 @@ public PRINTER_INFO_4(int size) {

/**
tresf marked this conversation as resolved.
Show resolved Hide resolved
* The PRINTER_INFO_5 structure specifies detailed printer information.
*
* @see <a href=
* "https://docs.microsoft.com/windows/win32/printdocs/printer-info-4">
* PRINTER_INFO_5 structure</a>
*/
@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 <code>PRINTER_ATTRIBUTE_*</code> 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 <a href=
* "https://docs.microsoft.com/windows/win32/printdocs/printer-info-4">
* PRINTER_INFO_6 structure</a>
*/
@FieldOrder({"dwStatus"})
public static class PRINTER_INFO_6 extends Structure {
/**
* The printer status. This member can be any reasonable combination
* of <code>PRINTER_STATUS_*</code> 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.
* <p>
* The structure specifies directory services printer information. Use this
* structure with the <code>SetPrinter</code> 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 <code>GetPrinter</code>
* function to determine whether a printer is published in the DS.
*
* @see <a href=
* "https://docs.microsoft.com/windows/win32/printdocs/printer-info-4">
* PRINTER_INFO_7 structure</a>
*/
@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
* <code>GetPrinter</code> function to retrieve this GUID.
*
* Before calling <code>SetPrinter</code>, set <code>pszObjectGUID</code> to NULL.
*/
public String pszObjectGUID;

/**
* Indicates the action for the <code>SetPrinter</code> function to perform. For the
* <code>GetPrinter</code> function, this member indicates whether the specified
* printer is published. This member can be a combination of <code>DSPRINT_*</code>
* 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.
* <p>
* 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 <code>PRINTER_INFO_9</code>.
*
* @see <a href=
* "https://docs.microsoft.com/windows/win32/printdocs/printer-info-4">
* PRINTER_INFO_8 structure</a>
*/
@FieldOrder({"pDevMode"})
public static class PRINTER_INFO_8 extends Structure {
/**
* A pointer to a <code>DEVMODE</code> 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.
* <p>
* 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 <code>PRINTER_INFO_8</code>.
*
* @see <a href=
* "https://docs.microsoft.com/windows/win32/printdocs/printer-info-4">
* PRINTER_INFO_9 structure</a>
*/
@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 <a href="https://msdn.microsoft.com/en-us/library/windows/desktop/dd162839(v=vs.85).aspx">PRINTER_DEFAULTS structure</a>
* @see <a href="https://docs.microsoft.com/windows/win32/printdocs/printer-defaults">
* PRINTER_DEFAULTS structure</a>
*/
@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 <a href="http://msdn.microsoft.com/en-us/library/windows/desktop/dd162751(v=vs.85).aspx">OpenPrinter function</a>
* @see <a href="https://docs.microsoft.com/windows/win32/printdocs/openprinter">
* OpenPrinter function</a>
*/
boolean OpenPrinter(
// _In_
@@ -721,7 +828,7 @@ boolean OpenPrinter(
* the function fails, the return value is zero.
*
* @see <a href=
* "http://msdn.microsoft.com/en-us/library/windows/desktop/dd162751(v=vs.85).aspx">
* "https://docs.microsoft.com/windows/win32/printdocs/closeprinter">
* ClosePrinter function</a>
*/
boolean ClosePrinter(HANDLE hPrinter);
@@ -731,7 +838,7 @@ boolean OpenPrinter(
* notification object that monitors a printer or print server.
*
* @see
* <a href="https://docs.microsoft.com/en-us/windows/win32/printdocs/printer-notify-options">
* <a href="https://docs.microsoft.com/windows/win32/printdocs/printer-notify-options">
* PRINTER_NOTIFY_OPTIONS structure
* </a>
*/
@@ -774,7 +881,7 @@ public class PRINTER_NOTIFY_OPTIONS extends Structure {
* notification object.
*
* @see
* <a href="https://docs.microsoft.com/en-us/windows/win32/printdocs/printer-notify-options-type">
* <a href="https://docs.microsoft.com/windows/win32/printdocs/printer-notify-options-type">
* PRINTER_NOTIFY_OPTIONS_TYPE structure
* </a>
*/
@@ -837,7 +944,7 @@ public short[] getFields() {
* object has been satisfied.
*
* @see
* <a href="https://docs.microsoft.com/en-us/windows/win32/printdocs/printer-notify-info">
* <a href="https://docs.microsoft.com/windows/win32/printdocs/printer-notify-info">
* PRINTER_NOTIFY_INFO structure
* </a>
*/
@@ -929,7 +1036,7 @@ public class NOTIFY_DATA extends Union {
* information field and provides the current data for that field.
*
* @see
* <a href="https://docs.microsoft.com/en-us/windows/win32/printdocs/printer-notify-info-data">
* <a href="https://docs.microsoft.com/windows/win32/printdocs/printer-notify-info-data">
* PRINTER_NOTIFY_INFO_DATA structure
* </a>
*/
@@ -1077,7 +1184,7 @@ HANDLE FindFirstPrinterChangeNotification(
* INVALID_HANDLE_VALUE.
*
* @see <a href=
* "http://msdn.microsoft.com/en-us/library/windows/desktop/dd162722(v=vs.85).aspx">
* "https://docs.microsoft.com/windows/win32/printdocs/findfirstprinterchangenotification">
* FindFirstPrinterChangeNotification function</a>
*/
HANDLE FindFirstPrinterChangeNotification(
@@ -1161,7 +1268,7 @@ boolean FindNextPrinterChangeNotification(
* the function fails, the return value is zero.
*
* @see <a href=
* "http://msdn.microsoft.com/en-us/library/windows/desktop/dd162721(v=vs.85).aspx">
* "https://docs.microsoft.com/windows/win32/printdocs/findnextprinterchangenotification">
* FindClosePrinterChangeNotification function</a>
*/
boolean FindNextPrinterChangeNotification(
@@ -1190,7 +1297,7 @@ boolean FindNextPrinterChangeNotification(
* the function fails, the return value is zero.
*
* @see <a href=
* "http://msdn.microsoft.com/en-us/library/windows/desktop/dd162721(v=vs.85).aspx">
* "https://docs.microsoft.com/windows/win32/printdocs/findcloseprinterchangenotification">
* FindClosePrinterChangeNotification function</a>
*/
boolean FindClosePrinterChangeNotification(
@@ -1210,7 +1317,7 @@ boolean FindClosePrinterChangeNotification(
* the function fails, the return value is zero.
*
* @see
* <a href="https://docs.microsoft.com/en-us/windows/win32/printdocs/freeprinternotifyinfo">
* <a href="https://docs.microsoft.com/windows/win32/printdocs/freeprinternotifyinfo">
* FreePrinterNotifyInfo function
* </a>
*/
@@ -1251,7 +1358,7 @@ boolean FreePrinterNotifyInfo(
* the function fails, the return value is zero.
*
* @see <a href=
* "https://msdn.microsoft.com/en-us/library/windows/desktop/dd162625(v=vs.85).aspx">
* "https://docs.microsoft.com/windows/win32/printdocs/enumjobs">
* EnumJobs function</a>
*/
boolean EnumJobs(
@@ -1279,7 +1386,7 @@ boolean EnumJobs(
* the user that owns the print job, and so on.
*
* @see <a href=
* "https://msdn.microsoft.com/en-us/library/windows/desktop/dd145019(v=vs.85).aspx">
* "https://docs.microsoft.com/windows/win32/printdocs/job-info-1">
* JOB_INFO_1 structure</a>
*/
@FieldOrder({"JobId", "pPrinterName", "pMachineName", "pUserName",
Original file line number Diff line number Diff line change
@@ -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);