From a99bcc1a491b81827a6d298908dfcd1921945024 Mon Sep 17 00:00:00 2001 From: Michael Freeman Date: Sat, 2 Jan 2016 14:11:43 -0500 Subject: [PATCH] Added `EnumProcessModules`, `GetModuleInformation`, `GetProcessImageFileName` to Psapi and `ExtractIconEx` to Shell32 Added constants to `WinNT` --- CHANGES.md | 2 +- .../src/com/sun/jna/platform/win32/Psapi.java | 290 +++++++++++++----- .../com/sun/jna/platform/win32/Shell32.java | 129 +++++--- .../src/com/sun/jna/platform/win32/WinNT.java | 187 ++++++++++- .../sun/jna/platform/win32/Kernel32Test.java | 12 +- .../com/sun/jna/platform/win32/PsapiTest.java | 130 ++++++++ .../sun/jna/platform/win32/Shell32Test.java | 9 + 7 files changed, 632 insertions(+), 127 deletions(-) diff --git a/CHANGES.md b/CHANGES.md index e25c3e6fcb..f07408dd63 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -29,7 +29,7 @@ Features * [#562](https://github.com/java-native-access/jna/pull/562): Added `com.sun.jna.platform.win32.VersionUtil` with `getFileVersionInfo` utility method to get file major, minor, revision, and build version parts - [@mlfreeman2](https://github.com/mlfreeman2). * [#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). Bug Fixes --------- diff --git a/contrib/platform/src/com/sun/jna/platform/win32/Psapi.java b/contrib/platform/src/com/sun/jna/platform/win32/Psapi.java index 50b14265a1..72a21368ae 100644 --- a/contrib/platform/src/com/sun/jna/platform/win32/Psapi.java +++ b/contrib/platform/src/com/sun/jna/platform/win32/Psapi.java @@ -12,9 +12,15 @@ */ package com.sun.jna.platform.win32; +import java.util.Arrays; +import java.util.List; + import com.sun.jna.Native; import com.sun.jna.Pointer; +import com.sun.jna.Structure; +import com.sun.jna.platform.win32.WinDef.HMODULE; import com.sun.jna.platform.win32.WinNT.HANDLE; +import com.sun.jna.ptr.IntByReference; import com.sun.jna.win32.StdCallLibrary; import com.sun.jna.win32.W32APIOptions; @@ -26,77 +32,217 @@ * @author Andreas "PAX" Lück, onkelpax-git[at]yahoo.de */ public interface Psapi extends StdCallLibrary { - Psapi INSTANCE = Native.loadLibrary("psapi", Psapi.class, W32APIOptions.DEFAULT_OPTIONS); - - /** - * Retrieves the fully qualified path for the file containing the specified - * module. - * - * @param process - * A handle to the process that contains the module. - * @param module - * A handle to the module. If this parameter is NULL, - * GetModuleFileNameEx returns the path of the executable file of - * the process specified in hProcess. - * @param lpFilename - * A pointer to a buffer that receives the fully qualified path - * to the module. If the size of the file name is larger than the - * value of the nSize parameter, the function succeeds but the - * file name is truncated and null-terminated. - * @param nSize - * The size of the lpFilename buffer, in characters. - * @return If the function succeeds, the return value specifies the length - * of the string copied to the buffer. If the function fails, the - * return value is zero. To get extended error information, call - * {@link Kernel32Util#getLastErrorMessage()}. - */ - int GetModuleFileNameExA(HANDLE process, HANDLE module, byte[] lpFilename, int nSize); - - /** - * Retrieves the fully qualified path for the file containing the specified - * module. - * - * @param process - * A handle to the process that contains the module. - * @param module - * A handle to the module. If this parameter is NULL, - * GetModuleFileNameEx returns the path of the executable file of - * the process specified in hProcess. - * @param lpFilename - * A pointer to a buffer that receives the fully qualified path - * to the module. If the size of the file name is larger than the - * value of the nSize parameter, the function succeeds but the - * file name is truncated and null-terminated. - * @param nSize - * The size of the lpFilename buffer, in characters. - * @return If the function succeeds, the return value specifies the length - * of the string copied to the buffer. If the function fails, the - * return value is zero. To get extended error information, call - * {@link Kernel32Util#getLastErrorMessage()}. - */ - int GetModuleFileNameExW(HANDLE process, HANDLE module, char[] lpFilename, int nSize); + Psapi INSTANCE = Native.loadLibrary("psapi", Psapi.class, W32APIOptions.DEFAULT_OPTIONS); + + /** + * Retrieves the fully qualified path for the file containing the specified + * module. + * + * @param process + * A handle to the process that contains the module. + * @param module + * A handle to the module. If this parameter is NULL, + * GetModuleFileNameEx returns the path of the executable file of + * the process specified in hProcess. + * @param lpFilename + * A pointer to a buffer that receives the fully qualified path + * to the module. If the size of the file name is larger than the + * value of the nSize parameter, the function succeeds but the + * file name is truncated and null-terminated. + * @param nSize + * The size of the lpFilename buffer, in characters. + * @return If the function succeeds, the return value specifies the length + * of the string copied to the buffer. If the function fails, the + * return value is zero. To get extended error information, call + * {@link Kernel32Util#getLastErrorMessage()}. + */ + int GetModuleFileNameExA(HANDLE process, HANDLE module, byte[] lpFilename, int nSize); + + /** + * Retrieves the fully qualified path for the file containing the specified + * module. + * + * @param process + * A handle to the process that contains the module. + * @param module + * A handle to the module. If this parameter is NULL, + * GetModuleFileNameEx returns the path of the executable file of + * the process specified in hProcess. + * @param lpFilename + * A pointer to a buffer that receives the fully qualified path + * to the module. If the size of the file name is larger than the + * value of the nSize parameter, the function succeeds but the + * file name is truncated and null-terminated. + * @param nSize + * The size of the lpFilename buffer, in characters. + * @return If the function succeeds, the return value specifies the length + * of the string copied to the buffer. If the function fails, the + * return value is zero. To get extended error information, call + * {@link Kernel32Util#getLastErrorMessage()}. + */ + int GetModuleFileNameExW(HANDLE process, HANDLE module, char[] lpFilename, int nSize); + + /** + * Retrieves the fully qualified path for the file containing the specified + * module. + * + * @param process + * A handle to the process that contains the module. + * @param module + * A handle to the module. If this parameter is NULL, + * GetModuleFileNameEx returns the path of the executable file of + * the process specified in hProcess. + * @param lpFilename + * A pointer to a buffer that receives the fully qualified path + * to the module. If the size of the file name is larger than the + * value of the nSize parameter, the function succeeds but the + * file name is truncated and null-terminated. + * @param nSize + * The size of the lpFilename buffer, in characters. + * @return If the function succeeds, the return value specifies the length + * of the string copied to the buffer. If the function fails, the + * return value is zero. To get extended error information, call + * {@link Kernel32Util#getLastErrorMessage()}. + */ + int GetModuleFileNameEx(HANDLE process, HANDLE module, Pointer lpFilename, int nSize); + + /** + * + * The EnumProcessModules function is primarily designed for use by + * debuggers and similar applications that must extract module information + * from another process.
+ * If the module list in the target process is corrupted or not yet + * initialized, or if the module list changes during the function call as a + * result of DLLs being loaded or unloaded, EnumProcessModules may fail or + * return incorrect information.
+ * It is a good idea to specify a large array of HMODULE values, because it + * is hard to predict how many modules there will be in the process at the + * time you call EnumProcessModules.
+ * To determine if the lphModule array is too small to hold all module + * handles for the process, compare the value returned in lpcbNeeded with + * the value specified in cb.
+ * If lpcbNeeded is greater than cb, increase the size of the array and call + * EnumProcessModules again. To determine how many modules were enumerated + * by the call to EnumProcessModules, divide the resulting value in the + * lpcbNeeded parameter by sizeof(HMODULE).
+ * The EnumProcessModules function does not retrieve handles for modules + * that were loaded with the LOAD_LIBRARY_AS_DATAFILE or similar flags. For + * more information, see LoadLibraryEx.
+ * Do not call CloseHandle on any of the handles returned by this function. + * The information comes from a snapshot, so there are no resources to be + * freed.
+ * If this function is called from a 32-bit application running on WOW64, it + * can only enumerate the modules of a 32-bit process.
+ * If the process is a 64-bit process, this function fails and the last + * error code is ERROR_PARTIAL_COPY (299).
+ * To take a snapshot of specified processes and the heaps, modules, and + * threads used by these processes, use the CreateToolhelp32Snapshot + * function.
+ * Starting with Windows 7 and Windows Server 2008 R2, Psapi.h establishes + * version numbers for the PSAPI functions.
+ * The PSAPI version number affects the name used to call the function and + * the library that a program must load.
+ * If PSAPI_VERSION is 2 or greater, this function is defined as + * K32EnumProcessModules in Psapi.h and exported in Kernel32.lib and + * Kernel32.dll.
+ * If PSAPI_VERSION is 1, this function is defined as EnumProcessModules in + * Psapi.h and exported in Psapi.lib and Psapi.dll as a wrapper that calls + * K32EnumProcessModules.
+ * Programs that must run on earlier versions of Windows as well as Windows + * 7 and later versions should always call this function as + * EnumProcessModules.
+ * To ensure correct resolution of symbols, add Psapi.lib to the TARGETLIBS + * macro and compile the program with -DPSAPI_VERSION=1.
+ * To use run-time dynamic linking, load Psapi.dll. + * + * @param hProcess + * A handle to the process. + * @param lphModule + * An array that receives the list of module handles. + * @param cb + * The size of the lphModule array, in bytes. + * @param lpcbNeeded + * The number of bytes required to store all module handles in + * the lphModule array. + * @return If the function succeeds, the return value is nonzero. If the + * function fails, the return value is zero. To get extended error + * information, call GetLastError. + * @see MSDN/a> + */ + boolean EnumProcessModules(HANDLE hProcess, HMODULE[] lphModule, int cb, IntByReference lpcbNeeded); + + /** + * To get information for the calling process, pass the handle returned by + * GetCurrentProcess.
+ * The GetModuleInformation function does not retrieve information for + * modules that were loaded with the LOAD_LIBRARY_AS_DATAFILE flag.
+ * For more information, see LoadLibraryEx.
+ * Starting with Windows 7 and Windows Server 2008 R2, Psapi.h establishes + * version numbers for the PSAPI functions.
+ * The PSAPI version number affects the name used to call the function and + * the library that a program must load.
+ * If PSAPI_VERSION is 2 or greater, this function is defined as + * K32GetModuleInformation in Psapi.h and exported in Kernel32.lib and + * Kernel32.dll.
+ * If PSAPI_VERSION is 1, this function is defined as + * K32GetModuleInformation in Psapi.h and exported in Psapi.lib and + * Psapi.dll as a wrapper that calls K32GetModuleInformation.
+ * Programs that must run on earlier versions of Windows as well as Windows + * 7 and later versions should always call this function as + * K32GetModuleInformation.
+ * To ensure correct resolution of symbols, add Psapi.lib to the TARGETLIBS + * macro and compile the program with -DPSAPI_VERSION=1.
+ * To use run-time dynamic linking, load Psapi.dll. + * + * @param hProcess + * A handle to the process that contains the module. The handle + * must have the PROCESS_QUERY_INFORMATION and PROCESS_VM_READ + * access rights. For more information, see Process Security and + * Access Rights. + * @param hModule + * A handle to the module. + * + * @param lpmodinfo + * A pointer to the MODULEINFO structure that receives + * information about the module. + * @param cb + * The size of the MODULEINFO structure, in bytes. + * @return If the function succeeds, the return value is nonzero. If the + * function fails, the return value is zero. To get extended error + * information, call GetLastError. + * @see
MSDN + */ + boolean GetModuleInformation(HANDLE hProcess, HMODULE hModule, MODULEINFO lpmodinfo, int cb); + + /** + * @param hProcess + * A handle to the process. The handle must have the + * PROCESS_QUERY_INFORMATION or PROCESS_QUERY_LIMITED_INFORMATION + * access right. For more information, see Process Security and + * Access Rights.
+ * Windows Server 2003 and Windows XP: The handle must have the + * PROCESS_QUERY_INFORMATION access right. + * @param lpImageFileName + * A pointer to a buffer that receives the full path to the + * executable file. + * @param nSize + * The size of the lpImageFileName buffer, in characters. + * @return If the function succeeds, the return value specifies the length + * of the string copied to the buffer. If the function fails, the + * return value is zero. To get extended error information, call + * GetLastError. + * @see MSDN + */ + int GetProcessImageFileName(HANDLE hProcess, char[] lpImageFileName, int nSize); + + class MODULEINFO extends Structure { + public Pointer EntryPoint; + public Pointer lpBaseOfDll; + public int SizeOfImage; - /** - * Retrieves the fully qualified path for the file containing the specified - * module. - * - * @param process - * A handle to the process that contains the module. - * @param module - * A handle to the module. If this parameter is NULL, - * GetModuleFileNameEx returns the path of the executable file of - * the process specified in hProcess. - * @param lpFilename - * A pointer to a buffer that receives the fully qualified path - * to the module. If the size of the file name is larger than the - * value of the nSize parameter, the function succeeds but the - * file name is truncated and null-terminated. - * @param nSize - * The size of the lpFilename buffer, in characters. - * @return If the function succeeds, the return value specifies the length - * of the string copied to the buffer. If the function fails, the - * return value is zero. To get extended error information, call - * {@link Kernel32Util#getLastErrorMessage()}. - */ - int GetModuleFileNameEx(HANDLE process, HANDLE module, Pointer lpFilename, int nSize); + @Override + protected List getFieldOrder() { + return Arrays.asList(new String[] { "lpBaseOfDll", "SizeOfImage", "EntryPoint" }); + } + } } diff --git a/contrib/platform/src/com/sun/jna/platform/win32/Shell32.java b/contrib/platform/src/com/sun/jna/platform/win32/Shell32.java index 9c560d28e0..eb74a1d894 100644 --- a/contrib/platform/src/com/sun/jna/platform/win32/Shell32.java +++ b/contrib/platform/src/com/sun/jna/platform/win32/Shell32.java @@ -15,6 +15,7 @@ import com.sun.jna.Native; import com.sun.jna.platform.win32.Guid.GUID; import com.sun.jna.platform.win32.WinDef.DWORD; +import com.sun.jna.platform.win32.WinDef.HICON; import com.sun.jna.platform.win32.WinDef.HWND; import com.sun.jna.platform.win32.WinDef.INT_PTR; import com.sun.jna.platform.win32.WinDef.UINT_PTR; @@ -31,41 +32,41 @@ public interface Shell32 extends ShellAPI, StdCallLibrary { /** The instance **/ Shell32 INSTANCE = Native.loadLibrary("shell32", Shell32.class, W32APIOptions.DEFAULT_OPTIONS); - /** - * No dialog box confirming the deletion of the objects will be displayed. - */ - int SHERB_NOCONFIRMATION = 0x00000001; + /** + * No dialog box confirming the deletion of the objects will be displayed. + */ + int SHERB_NOCONFIRMATION = 0x00000001; - /** - * No dialog box indicating the progress will be displayed. - */ - int SHERB_NOPROGRESSUI = 0x00000002; + /** + * No dialog box indicating the progress will be displayed. + */ + int SHERB_NOPROGRESSUI = 0x00000002; - /** - * No sound will be played when the operation is complete. - */ - int SHERB_NOSOUND = 0x00000004; + /** + * No sound will be played when the operation is complete. + */ + int SHERB_NOSOUND = 0x00000004; - /** - *

- * SEE_MASK_NOCLOSEPROCESS (0x00000040) - *

- *

- * Use to indicate that the hProcess member receives the - * process handle. This handle is typically used to allow an application to - * find out when a process created with terminates. In some cases, such as - * when execution is satisfied through a DDE conversation, no handle will be - * returned. The calling application is responsible for closing the handle - * when it is no longer needed. - *

- */ - int SEE_MASK_NOCLOSEPROCESS = 0x00000040; - - /** - * Do not display an error message box if an error occurs. - */ - int SEE_MASK_FLAG_NO_UI = 0x00000400; - + /** + *

+ * SEE_MASK_NOCLOSEPROCESS (0x00000040) + *

+ *

+ * Use to indicate that the hProcess member receives the + * process handle. This handle is typically used to allow an application to + * find out when a process created with terminates. In some cases, such as + * when execution is satisfied through a DDE conversation, no handle will be + * returned. The calling application is responsible for closing the handle + * when it is no longer needed. + *

+ */ + int SEE_MASK_NOCLOSEPROCESS = 0x00000040; + + /** + * Do not display an error message box if an error occurs. + */ + int SEE_MASK_FLAG_NO_UI = 0x00000400; + /** * This function can be used to copy, move, rename, or delete a file system object. * @param fileop @@ -239,15 +240,15 @@ public interface Shell32 extends ShellAPI, StdCallLibrary { * @param dwMessage * Appbar message value to send. This parameter can be one of the following values. * {@link ShellAPI#ABM_NEW} Registers a new appbar and specifies the message identifier that the system should use to send notification messages to the appbar. - * {@link ShellAPI#ABM_REMOVE} Unregisters an appbar, removing the bar from the system's internal list. - * {@link ShellAPI#ABM_QUERYPOS} Requests a size and screen position for an appbar. + * {@link ShellAPI#ABM_REMOVE} Unregisters an appbar, removing the bar from the system's internal list. + * {@link ShellAPI#ABM_QUERYPOS} Requests a size and screen position for an appbar. * {@link ShellAPI#ABM_SETPOS} Sets the size and screen position of an appbar. - * {@link ShellAPI#ABM_GETSTATE} Retrieves the autohide and always-on-top states of the Windows taskbar. - * {@link ShellAPI#ABM_GETTASKBARPOS} Retrieves the bounding rectangle of the Windows taskbar. Note that this applies only to the system taskbar. Other objects, particularly toolbars supplied with third-party software, also can be present. As a result, some of the screen area not covered by the Windows taskbar might not be visible to the user. To retrieve the area of the screen not covered by both the taskbar and other app bars -- the working area available to your application --, use the GetMonitorInfo function. - * {@link ShellAPI#ABM_ACTIVATE} Notifies the system to activate or deactivate an appbar. The lParam member of the APPBARDATA pointed to by pData is set to TRUE to activate or FALSE to deactivate. - * {@link ShellAPI#ABM_GETAUTOHIDEBAR} Retrieves the handle to the autohide appbar associated with a particular edge of the screen. - * {@link ShellAPI#ABM_SETAUTOHIDEBAR} Registers or unregisters an autohide appbar for an edge of the screen. - * {@link ShellAPI#ABM_WINDOWPOSCHANGED} Notifies the system when an appbar's position has changed. + * {@link ShellAPI#ABM_GETSTATE} Retrieves the autohide and always-on-top states of the Windows taskbar. + * {@link ShellAPI#ABM_GETTASKBARPOS} Retrieves the bounding rectangle of the Windows taskbar. Note that this applies only to the system taskbar. Other objects, particularly toolbars supplied with third-party software, also can be present. As a result, some of the screen area not covered by the Windows taskbar might not be visible to the user. To retrieve the area of the screen not covered by both the taskbar and other app bars -- the working area available to your application --, use the GetMonitorInfo function. + * {@link ShellAPI#ABM_ACTIVATE} Notifies the system to activate or deactivate an appbar. The lParam member of the APPBARDATA pointed to by pData is set to TRUE to activate or FALSE to deactivate. + * {@link ShellAPI#ABM_GETAUTOHIDEBAR} Retrieves the handle to the autohide appbar associated with a particular edge of the screen. + * {@link ShellAPI#ABM_SETAUTOHIDEBAR} Registers or unregisters an autohide appbar for an edge of the screen. + * {@link ShellAPI#ABM_WINDOWPOSCHANGED} Notifies the system when an appbar's position has changed. * {@link ShellAPI#ABM_SETSTATE} Windows XP and later: Sets the state of the appbar's autohide and always-on-top attributes. * * @param pData @@ -307,7 +308,7 @@ public interface Shell32 extends ShellAPI, StdCallLibrary { * about the application being executed. *

* @return - *

+ *

* Returns TRUE if successful; otherwise, * FALSE. Call @@ -330,6 +331,50 @@ public interface Shell32 extends ShellAPI, StdCallLibrary { * @return If this function succeeds, it returns S_OK. Otherwise, it returns an HRESULT error code. * */ - WinNT.HRESULT SHGetSpecialFolderLocation(WinDef.HWND hwndOwner, int nFolder, PointerByReference ppidl); + HRESULT SHGetSpecialFolderLocation(WinDef.HWND hwndOwner, int nFolder, PointerByReference ppidl); + + /** + * @param lpszFile + * Type: LPCTSTR
+ * The name of an executable file, DLL, or icon file from which + * icons will be extracted. + * @param nIconIndex + * Type: int
+ * The zero-based index of the first icon to extract. For + * example, if this value is zero, the function extracts the + * first icon in the specified file.
+ * If this value is -1 and phiconLarge and phiconSmall are both + * NULL, the function returns the total number of icons in the + * specified file.
+ * If the file is an executable file or DLL, the return value is + * the number of RT_GROUP_ICON resources.
+ * If the file is an .ico file, the return value is 1. If this + * value is a negative number and either phiconLarge or + * phiconSmall is not NULL, the function begins by extracting the + * icon whose resource identifier is equal to the absolute value + * of nIconIndex. For example, use -3 to extract the icon whose + * resource identifier is 3. + * @param phiconLarge + * Type: HICON*
+ * An array of icon handles that receives handles to the large + * icons extracted from the file. If this parameter is NULL, no + * large icons are extracted from the file. + * @param phiconSmall + * Type: HICON*
+ * An array of icon handles that receives handles to the small + * icons extracted from the file. If this parameter is NULL, no + * small icons are extracted from the file. + * @param nIcons + * Type: UINT
+ * The number of icons to be extracted from the file. + * @return Type: UINT
+ * If the nIconIndex parameter is -1, the phiconLarge parameter is + * NULL, and the phiconSmall parameter is NULL, then the return + * value is the number of icons contained in the specified file. + * Otherwise, the return value is the number of icons successfully + * extracted from the file. + * @see
MSDN + */ + int ExtractIconEx(String lpszFile, int nIconIndex, HICON[] phiconLarge, HICON[] phiconSmall, int nIcons); } diff --git a/contrib/platform/src/com/sun/jna/platform/win32/WinNT.java b/contrib/platform/src/com/sun/jna/platform/win32/WinNT.java index 85de588dce..005fa16ea8 100644 --- a/contrib/platform/src/com/sun/jna/platform/win32/WinNT.java +++ b/contrib/platform/src/com/sun/jna/platform/win32/WinNT.java @@ -20,6 +20,7 @@ import com.sun.jna.FromNativeContext; import com.sun.jna.IntegerType; import com.sun.jna.Memory; +import com.sun.jna.Native; import com.sun.jna.NativeLong; import com.sun.jna.Pointer; import com.sun.jna.PointerType; @@ -666,14 +667,99 @@ public abstract class SID_NAME_USE { // AccessSystemAcl access type // - int ACCESS_SYSTEM_SECURITY = 0x01000000; + int ACCESS_SYSTEM_SECURITY = 0x01000000; - int PAGE_READONLY = 0x02; - int PAGE_READWRITE = 0x04; + /** + * Pages in the region become guard pages.
+ * Any attempt to access a guard page causes the system to raise a + * STATUS_GUARD_PAGE_VIOLATION exception and turn off the guard page status. + *
+ * Guard pages thus act as a one-time access alarm.
+ * For more information, see Creating Guard Pages.
+ * When an access attempt leads the system to turn off guard page status, + * the underlying page protection takes over.
+ * If a guard page exception occurs during a system service, the service + * typically returns a failure status indicator.
+ * This value cannot be used with PAGE_NOACCESS. This flag is not supported + * by the CreateFileMapping function. + * + * @see + * MSDN + */ + int PAGE_GUARD = 0x100; + + /** + * Disables all access to the committed region of pages.
+ * An attempt to read from, write to, or execute the committed region + * results in an access violation.
+ * This flag is not supported by the CreateFileMapping function. + * + * @see MSDN + */ + int PAGE_NOACCESS = 0x01; + + /** + * Enables read-only access to the committed region of pages.
+ * An attempt to write to the committed region results in an access + * violation.
+ * If Data Execution Prevention is enabled, an attempt to execute code in + * the committed region results in an access violation. + * + * @see MSDN + */ + int PAGE_READONLY = 0x02; + + /** + * Enables read-only or read/write access to the committed region of pages.
+ * If Data Execution Prevention is enabled, attempting to execute code in + * the committed region results in an access violation. + * + * @see MSDN + */ + int PAGE_READWRITE = 0x04; + + /** + * Enables read-only or copy-on-write access to a mapped view of a file + * mapping object. An attempt to write to a committed copy-on-write page + * results in a private copy of the page being made for the process. The + * private page is marked as PAGE_READWRITE, and the change is written to + * the new page. If Data Execution Prevention is enabled, attempting to + * execute code in the committed region results in an access violation. + * + * @see MSDN + */ int PAGE_WRITECOPY = 0x08; - int PAGE_EXECUTE = 0x10; - int PAGE_EXECUTE_READ = 0x20; - int PAGE_EXECUTE_READWRITE = 0x40; + + /** + * Enables execute access to the committed region of pages. An attempt to + * write to the committed region results in an access violation. This flag + * is not supported by the CreateFileMapping function. + * + * @see MSDN + */ + int PAGE_EXECUTE = 0x10; + + /** + * Enables execute or read-only access to the committed region of pages. An + * attempt to write to the committed region results in an access violation. + * Windows Server 2003 and Windows XP: This attribute is not supported by + * the CreateFileMapping function until Windows XP with SP2 and Windows + * Server 2003 with SP1. + * + * @see MSDN + */ + int PAGE_EXECUTE_READ = 0x20; + + /** + * Enables execute, read-only, or read/write access to the committed region + * of pages. Windows Server 2003 and Windows XP: This attribute is not + * supported by the CreateFileMapping function until Windows XP with SP2 and + * Windows Server 2003 with SP1. + * + * @see MSDN + */ + int PAGE_EXECUTE_READWRITE = 0x40; int SECTION_QUERY = 0x0001; int SECTION_MAP_WRITE = 0x0002; @@ -1864,6 +1950,59 @@ public OSVERSIONINFOEX(Pointer memory) { super(memory); read(); } + + + + /** + * @return The major version number of the operating system. + */ + public int getMajor() { + return dwMajorVersion.intValue(); + } + + /** + * @return The minor version number of the operating system. + */ + public int getMinor() { + return dwMinorVersion.intValue(); + } + + /** + * @return The build number of the operating system. + */ + public int getBuildNumber() { + return dwBuildNumber.intValue(); + } + + /** + * @return The operating system platform. This member can be VER_PLATFORM_WIN32_NT. + */ + public int getPlatformId() { + return dwPlatformId.intValue(); + } + + /** + * @return String, such as "Service Pack 3", that indicates the latest + * Service Pack installed on the system.
+ * If no Service Pack has been installed, the string is empty. + */ + public String getServicePack() { + return Native.toString(szCSDVersion); + } + + /** + * @return A bit mask that identifies the product suites available on the system. + */ + public int getSuiteMask() { + return wSuiteMask.intValue(); + } + + /** + * @return Any additional information about the system. + */ + public byte getProductType() { + return wProductType; + } } int VER_EQUAL = 1; @@ -2137,6 +2276,42 @@ public EVENTLOGRECORD(Pointer p) { */ int PROCESS_DUP_HANDLE = 0x0040; + /** + * All possible access rights for a process object. Windows Server 2003 and + * Windows XP: The size of the PROCESS_ALL_ACCESS flag increased on Windows + * Server 2008 and Windows Vista.
+ * If an application compiled for Windows Server 2008 and Windows Vista is + * run on Windows Server 2003 or Windows XP, the PROCESS_ALL_ACCESS flag is + * too large and the function specifying this flag fails with + * ERROR_ACCESS_DENIED.
+ * To avoid this problem, specify the minimum set of access rights required + * for the operation.
+ * If PROCESS_ALL_ACCESS must be used, set _WIN32_WINNT to the minimum + * operating system targeted by your application (for example, #define + * _WIN32_WINNT _WIN32_WINNT_WINXP).
+ * For more information, see Using the Windows Headers. + * + * @see MSDN + */ + int PROCESS_ALL_ACCESS = WinNT.PROCESS_CREATE_PROCESS + | WinNT.PROCESS_CREATE_THREAD + | WinNT.PROCESS_DUP_HANDLE + | WinNT.PROCESS_QUERY_INFORMATION + | WinNT.PROCESS_QUERY_LIMITED_INFORMATION + | WinNT.PROCESS_SET_INFORMATION + | WinNT.PROCESS_SET_QUOTA + | WinNT.PROCESS_SUSPEND_RESUME + | WinNT.PROCESS_SYNCHRONIZE + | WinNT.PROCESS_TERMINATE + | WinNT.PROCESS_VM_OPERATION + | WinNT.PROCESS_VM_READ + | WinNT.PROCESS_VM_WRITE + | WinNT.DELETE + | WinNT.READ_CONTROL + | WinNT.WRITE_DAC + | WinNT.WRITE_OWNER + | WinNT.SYNCHRONIZE; + /** * Required to retrieve certain information about a process, such as its * token, exit code, and priority class (see diff --git a/contrib/platform/test/com/sun/jna/platform/win32/Kernel32Test.java b/contrib/platform/test/com/sun/jna/platform/win32/Kernel32Test.java index 065290fd9d..644bc0dd5e 100644 --- a/contrib/platform/test/com/sun/jna/platform/win32/Kernel32Test.java +++ b/contrib/platform/test/com/sun/jna/platform/win32/Kernel32Test.java @@ -382,13 +382,13 @@ public void testGetVersionEx_OSVERSIONINFOEX() { OSVERSIONINFOEX lpVersionInfo = new OSVERSIONINFOEX(); assertEquals(lpVersionInfo.size(), lpVersionInfo.dwOSVersionInfoSize.longValue()); assertTrue(Kernel32.INSTANCE.GetVersionEx(lpVersionInfo)); - assertTrue(lpVersionInfo.dwMajorVersion.longValue() > 0); - assertTrue(lpVersionInfo.dwMinorVersion.longValue() >= 0); + assertTrue(lpVersionInfo.getMajor() > 0); + assertTrue(lpVersionInfo.getMinor() >= 0); assertEquals(lpVersionInfo.size(), lpVersionInfo.dwOSVersionInfoSize.longValue()); - assertTrue(lpVersionInfo.dwPlatformId.longValue() > 0); - assertTrue(lpVersionInfo.dwBuildNumber.longValue() > 0); - assertTrue(Native.toString(lpVersionInfo.szCSDVersion).length() >= 0); - assertTrue(lpVersionInfo.wProductType >= 0); + assertTrue(lpVersionInfo.getPlatformId() > 0); + assertTrue(lpVersionInfo.getBuildNumber() > 0); + assertTrue(lpVersionInfo.getServicePack().length() >= 0); + assertTrue(lpVersionInfo.getProductType() >= 0); } public void testGetSystemInfo() { diff --git a/contrib/platform/test/com/sun/jna/platform/win32/PsapiTest.java b/contrib/platform/test/com/sun/jna/platform/win32/PsapiTest.java index 560f50d69f..c77e2e9316 100644 --- a/contrib/platform/test/com/sun/jna/platform/win32/PsapiTest.java +++ b/contrib/platform/test/com/sun/jna/platform/win32/PsapiTest.java @@ -14,12 +14,17 @@ import static org.junit.Assert.assertTrue; +import java.util.LinkedList; +import java.util.List; + import javax.swing.JFrame; import org.junit.Test; import com.sun.jna.Memory; import com.sun.jna.Native; +import com.sun.jna.platform.win32.Psapi.MODULEINFO; +import com.sun.jna.platform.win32.WinDef.HMODULE; import com.sun.jna.platform.win32.WinDef.HWND; import com.sun.jna.platform.win32.WinNT.HANDLE; import com.sun.jna.ptr.IntByReference; @@ -94,4 +99,129 @@ public void testGetModuleFileNameEx() { w.dispose(); } } + + @Test + public void testEnumProcessModules() { + HANDLE me = null; + Win32Exception we = null; + + try { + me = Kernel32.INSTANCE.OpenProcess(WinNT.PROCESS_ALL_ACCESS, false, Kernel32.INSTANCE.GetCurrentProcessId()); + assertTrue("Handle to my process should not be null", me != null); + + List list = new LinkedList(); + + HMODULE[] lphModule = new HMODULE[100 * 4]; + IntByReference lpcbNeeded = new IntByReference(); + + if (!Psapi.INSTANCE.EnumProcessModules(me, lphModule, lphModule.length, lpcbNeeded)) { + throw new Win32Exception(Native.getLastError()); + } + + for (int i = 0; i < lpcbNeeded.getValue() / 4; i++) { + list.add(lphModule[i]); + } + + assertTrue("List should have at least 1 item in it.", list.size() > 0); + } catch (Win32Exception e) { + we = e; + } finally { + if (me != null) { + if (!Kernel32.INSTANCE.CloseHandle(me)) { + Win32Exception e = new Win32Exception(Native.getLastError()); + if (we != null) { + e.addSuppressed(we); + } + we = e; + } + } + } + if (we != null) { + throw we; + } + + } + + @Test + public void testGetModuleInformation() { + HANDLE me = null; + Win32Exception we = null; + + try { + me = Kernel32.INSTANCE.OpenProcess(WinNT.PROCESS_ALL_ACCESS, false, Kernel32.INSTANCE.GetCurrentProcessId()); + assertTrue("Handle to my process should not be null", me != null); + + List list = new LinkedList(); + + HMODULE[] lphModule = new HMODULE[100 * 4]; + IntByReference lpcbNeeded = new IntByReference(); + + if (!Psapi.INSTANCE.EnumProcessModules(me, lphModule, lphModule.length, lpcbNeeded)) { + throw new Win32Exception(Native.getLastError()); + } + + for (int i = 0; i < lpcbNeeded.getValue() / 4; i++) { + list.add(lphModule[i]); + } + + assertTrue("List should have at least 1 item in it.", list.size() > 0); + + MODULEINFO lpmodinfo = new MODULEINFO(); + + if (!Psapi.INSTANCE.GetModuleInformation(me, list.get(0), lpmodinfo, lpmodinfo.size())) { + throw new Win32Exception(Native.getLastError()); + } + + assertTrue("MODULEINFO.EntryPoint should not be null.", lpmodinfo.EntryPoint != null); + + } catch (Win32Exception e) { + we = e; + } finally { + if (me != null) { + if (!Kernel32.INSTANCE.CloseHandle(me)) { + Win32Exception e = new Win32Exception(Native.getLastError()); + if (we != null) { + e.addSuppressed(we); + } + we = e; + } + } + } + if (we != null) { + throw we; + } + + } + + @Test + public void testGetProcessImageFileName() { + HANDLE me = null; + Win32Exception we = null; + + try { + me = Kernel32.INSTANCE.OpenProcess(WinNT.PROCESS_ALL_ACCESS, false, Kernel32.INSTANCE.GetCurrentProcessId()); + assertTrue("Handle to my process should not be null", me != null); + + char[] buffer = new char[256]; + Psapi.INSTANCE.GetProcessImageFileName(me, buffer, 256); + String path = new String(buffer); + assertTrue("Image path should contain 'java' and '.exe'", path.contains("java") && path.contains(".exe")); + } catch (Win32Exception e) { + we = e; + } finally { + if (me != null) { + if (!Kernel32.INSTANCE.CloseHandle(me)) { + Win32Exception e = new Win32Exception(Native.getLastError()); + if (we != null) { + e.addSuppressed(we); + } + we = e; + } + } + } + if (we != null) { + throw we; + } + + } } diff --git a/contrib/platform/test/com/sun/jna/platform/win32/Shell32Test.java b/contrib/platform/test/com/sun/jna/platform/win32/Shell32Test.java index 609166ee59..66171e4151 100644 --- a/contrib/platform/test/com/sun/jna/platform/win32/Shell32Test.java +++ b/contrib/platform/test/com/sun/jna/platform/win32/Shell32Test.java @@ -225,4 +225,13 @@ private void fillTempFile(File file) throws IOException { fileWriter.close(); } } + + public void testExtractIconEx() { + String winDir = Kernel32Util.getEnvironmentVariable("WINDIR"); + assertNotNull("No WINDIR value returned", winDir); + assertTrue("Specified WINDIR does not exist: " + winDir, new File(winDir).exists()); + + int iconCount = Shell32.INSTANCE.ExtractIconEx(new File(winDir, "explorer.exe").getAbsolutePath(), -1, null, null, 1); + assertTrue("Should be at least two icons in explorer.exe", iconCount > 1); + } }