From 48bf0ffcac4aeabb8caf2e2a50cb4bf8ab458223 Mon Sep 17 00:00:00 2001 From: Michael Freeman Date: Mon, 23 Nov 2015 19:33:07 -0500 Subject: [PATCH] Kernel32.ProcessIdToSessionId and resource extraction functions (Find/Load/LockResource, etc) Updated changelog. --- CHANGES.md | 1 + .../com/sun/jna/platform/win32/Kernel32.java | 548 ++++++++++-- .../sun/jna/platform/win32/Kernel32Util.java | 161 +++- .../com/sun/jna/platform/win32/Tlhelp32.java | 20 +- .../sun/jna/platform/win32/Kernel32Test.java | 815 +++++++++--------- .../jna/platform/win32/Kernel32UtilTest.java | 215 ++--- 6 files changed, 1137 insertions(+), 623 deletions(-) diff --git a/CHANGES.md b/CHANGES.md index f44c9530c3..96ae9d6079 100755 --- a/CHANGES.md +++ b/CHANGES.md @@ -16,6 +16,7 @@ Features * [#535](https://github.com/java-native-access/jna/pull/535): Added `BitBlt` to `com.sun.jna.platform.win32.GDI32`, Added `com.sun.jna.platform.win32.GDI32Util` and added `getScreenshot()` to it - [@mlfreeman2](https://github.com/mlfreeman2). * [#535](https://github.com/java-native-access/jna/pull/535): Added `SHEmptyRecycleBin`, `ShellExecuteEx` to `com.sun.jna.platform.win32.Shell32` - [@mlfreeman2](https://github.com/mlfreeman2). * [#535](https://github.com/java-native-access/jna/pull/535): Added `GetDesktopWindow` to `com.sun.jna.platform.win32.User32` - [@mlfreeman2](https://github.com/mlfreeman2). +* [#543](https://github.com/java-native-access/jna/pull/543): Added `ProcessIdToSessionId`, `LoadLibraryEx`, `FreeLibrary` and `Find/Load/Lock/SizeofResource` to `com.sun.jna.platform.win32.Kernel32` - [@mlfreeman2](https://github.com/mlfreeman2). Bug Fixes --------- diff --git a/contrib/platform/src/com/sun/jna/platform/win32/Kernel32.java b/contrib/platform/src/com/sun/jna/platform/win32/Kernel32.java index 5ee11bd2d5..ee663a264b 100644 --- a/contrib/platform/src/com/sun/jna/platform/win32/Kernel32.java +++ b/contrib/platform/src/com/sun/jna/platform/win32/Kernel32.java @@ -14,7 +14,6 @@ import com.sun.jna.Native; import com.sun.jna.Pointer; -import com.sun.jna.platform.win32.WinNT.HANDLE; import com.sun.jna.ptr.IntByReference; import com.sun.jna.ptr.PointerByReference; import com.sun.jna.win32.W32APIOptions; @@ -31,6 +30,32 @@ public interface Kernel32 extends StdCallLibrary, WinNT, Wincon { Kernel32 INSTANCE = (Kernel32) Native.loadLibrary("kernel32", Kernel32.class, W32APIOptions.DEFAULT_OPTIONS); + /** + * LOAD_LIBRARY_AS_DATAFILE
+ * 0x00000002
+ * If this value is used, the system maps the file into the calling + * process's virtual address space as if it were a data file.
+ * Nothing is done to execute or prepare to execute the mapped file.
+ * Therefore, you cannot call functions like + * GetModuleFileName + * , + * GetModuleHandle + * or + * GetProcAddress + * with this DLL. Using this value causes writes to read-only memory to + * raise an access violation.
+ * Use this flag when you want to load a DLL only to extract messages or + * resources from it.
+ * This value can be used with + * LOAD_LIBRARY_AS_IMAGE_RESOURCE. For more information, + * see Remarks. + */ + int LOAD_LIBRARY_AS_DATAFILE = 0x2; + + /** * Reads data from the specified file or input/output (I/O) device. Reads * occur at the position specified by the file pointer if supported by the @@ -2438,17 +2463,32 @@ boolean SystemTimeToTzSpecificLocalTime(TIME_ZONE_INFORMATION lpTimeZone, /** * Reads data from an area of memory in a specified process. The entire area * to be read must be accessible or the operation fails. - * @param hProcess A handle to the process with memory that is being read. - * @param lpBaseAddress The base address in the specified process from which - * to read. - * @param lpBuffer A buffer that receives the contents from the address space - * of the specified process. - * @param nSize The number of bytes to be read from the specified process. - * @param lpNumberOfBytesRead A variable that receives the number of bytes - * transferred into the specified buffer. If {@code null} the parameter is ignored. - * @return {@code true} if successful, {@code false} otherwise. - * To get extended error information, call {@link #GetLastError()}. - * @see ReadProcessMemory documentation + * + * @see MSDN {@link https://msdn.microsoft.com/en-us/library/windows/desktop/ms680553(v=vs.85).aspx } + * @param hProcess + * A handle to the process with memory that is being read. The + * handle must have PROCESS_VM_READ access to the process. + * @param lpBaseAddress + * A pointer to the base address in the specified process from + * which to read.
+ * Before any data transfer occurs, the system verifies that all + * data in the base address and memory of the specified size is + * accessible for read access, and if it is not accessible the + * function fails. + * @param lpBuffer + * A pointer to a buffer that receives the contents from the + * address space of the specified process. + * @param nSize + * The number of bytes to be read from the specified process. + * @param lpNumberOfBytesRead + * A pointer to a variable that receives the number of bytes + * transferred into the specified buffer. If lpNumberOfBytesRead + * is NULL, the parameter is ignored. + * @return If the function succeeds, the return value is nonzero.
+ * If the function fails, the return value is 0 (zero). To get + * extended error information, call GetLastError.
+ * The function fails if the requested read operation crosses into + * an area of the process that is inaccessible. */ boolean ReadProcessMemory(HANDLE hProcess, Pointer lpBaseAddress, Pointer lpBuffer, int nSize, IntByReference lpNumberOfBytesRead); @@ -2733,85 +2773,407 @@ boolean GetVolumePathNamesForVolumeName(String lpszVolumeName, boolean FindVolumeClose(HANDLE hFindVolume); /** - * Retrieves the current control settings for a specified communications - * device. - * - * @param hFile - * [in] A handle to the communications device.
- * The - * {@link com.sun.jna.platform.win32.Kernel32#CreateFile(String, int, int, com.sun.jna.platform.win32.WinBase.SECURITY_ATTRIBUTES, int, int, com.sun.jna.platform.win32.WinNT.HANDLE)} - * function returns this {@link HANDLE}. - * @param lpDCB - * [in, out] A pointer to a {@link WinBase.DCB} structure that - * receives the control settings information. - * - * @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 {@link Kernel32#GetLastError()}. - * - */ - boolean GetCommState(HANDLE hFile, WinBase.DCB lpDCB); - - /** - * - * Retrieves the time-out parameters for all read and write operations on a - * specified communications device.
- *
- * For more information about time-out values for communications devices, - * see the {@link Kernel32#SetCommTimeouts} function. - * - * @param hFile - * [in] A handle to the communications device. The - * {@link com.sun.jna.platform.win32.Kernel32#CreateFile(String, int, int, com.sun.jna.platform.win32.WinBase.SECURITY_ATTRIBUTES, int, int, com.sun.jna.platform.win32.WinNT.HANDLE)} - * function returns this handle. - * - * @param lpCommTimeouts - * [in] A pointer to a {@link WinBase.COMMTIMEOUTS} structure in - * which the time-out information is returned. - * @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 {@link Kernel32#GetLastError()}. - * - * - * - */ - boolean GetCommTimeouts(HANDLE hFile, WinBase.COMMTIMEOUTS lpCommTimeouts); - - /** - * Configures a communications device according to the specifications in a - * device-control block (a {@link WinBase.DCB} structure). The function - * reinitializes all hardware and control settings, but it does not empty - * output or input queues. - * - * @param hFile - * [in] A handle to the communications device. The - * {@link com.sun.jna.platform.win32.Kernel32#CreateFile(String, int, int, com.sun.jna.platform.win32.WinBase.SECURITY_ATTRIBUTES, int, int, com.sun.jna.platform.win32.WinNT.HANDLE)} - * function returns this handle. - * @param lpDCB - * [in] A pointer to a {@link WinBase.DCB} structure that - * contains the configuration information for the specified - * communications device. - * @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 {@link Kernel32#GetLastError()}. - */ - boolean SetCommState(HANDLE hFile, WinBase.DCB lpDCB); - - /** - * Sets the time-out parameters for all read and write operations on a - * specified communications device. - * - * @param hFile - * [in] A handle to the communications device. The - * {@link com.sun.jna.platform.win32.Kernel32#CreateFile(String, int, int, com.sun.jna.platform.win32.WinBase.SECURITY_ATTRIBUTES, int, int, com.sun.jna.platform.win32.WinNT.HANDLE)} - * function returns this handle. - * @param LPCOMMTIMEOUTS - * [in] A pointer to a {@link WinBase.COMMTIMEOUTS} structure - * that contains the new time-out values. - * @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 {@link Kernel32#GetLastError()}. - */ - boolean SetCommTimeouts(HANDLE hFile, WinBase.COMMTIMEOUTS lpCommTimeouts); + * Retrieves the current control settings for a specified communications + * device. + * + * @param hFile + * [in] A handle to the communications device.
+ * The + * {@link com.sun.jna.platform.win32.Kernel32#CreateFile(String, int, int, com.sun.jna.platform.win32.WinBase.SECURITY_ATTRIBUTES, int, int, com.sun.jna.platform.win32.WinNT.HANDLE)} + * function returns this {@link HANDLE}. + * @param lpDCB + * [in, out] A pointer to a {@link WinBase.DCB} structure that + * receives the control settings information. + * + * @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 {@link Kernel32#GetLastError()}. + * + */ + boolean GetCommState(HANDLE hFile, WinBase.DCB lpDCB); + + /** + * + * Retrieves the time-out parameters for all read and write operations on a + * specified communications device.
+ *
+ * For more information about time-out values for communications devices, + * see the {@link Kernel32#SetCommTimeouts} function. + * + * @param hFile + * [in] A handle to the communications device. The + * {@link com.sun.jna.platform.win32.Kernel32#CreateFile(String, int, int, com.sun.jna.platform.win32.WinBase.SECURITY_ATTRIBUTES, int, int, com.sun.jna.platform.win32.WinNT.HANDLE)} + * function returns this handle. + * + * @param lpCommTimeouts + * [in] A pointer to a {@link WinBase.COMMTIMEOUTS} structure in + * which the time-out information is returned. + * @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 {@link Kernel32#GetLastError()}. + * + * + * + */ + boolean GetCommTimeouts(HANDLE hFile, WinBase.COMMTIMEOUTS lpCommTimeouts); + + /** + * Configures a communications device according to the specifications in a + * device-control block (a {@link WinBase.DCB} structure). The function + * reinitializes all hardware and control settings, but it does not empty + * output or input queues. + * + * @param hFile + * [in] A handle to the communications device. The + * {@link com.sun.jna.platform.win32.Kernel32#CreateFile(String, int, int, com.sun.jna.platform.win32.WinBase.SECURITY_ATTRIBUTES, int, int, com.sun.jna.platform.win32.WinNT.HANDLE)} + * function returns this handle. + * @param lpDCB + * [in] A pointer to a {@link WinBase.DCB} structure that + * contains the configuration information for the specified + * communications device. + * @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 {@link Kernel32#GetLastError()}. + */ + boolean SetCommState(HANDLE hFile, WinBase.DCB lpDCB); + + /** + * Sets the time-out parameters for all read and write operations on a + * specified communications device. + * + * @param hFile + * [in] A handle to the communications device. The + * {@link com.sun.jna.platform.win32.Kernel32#CreateFile(String, int, int, com.sun.jna.platform.win32.WinBase.SECURITY_ATTRIBUTES, int, int, com.sun.jna.platform.win32.WinNT.HANDLE)} + * function returns this handle. + * @param LPCOMMTIMEOUTS + * [in] A pointer to a {@link WinBase.COMMTIMEOUTS} structure + * that contains the new time-out values. + * @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 {@link Kernel32#GetLastError()}. + */ + boolean SetCommTimeouts(HANDLE hFile, WinBase.COMMTIMEOUTS lpCommTimeouts); + + /** + * http://msdn.microsoft.com/en-us/library/aa382990(v=vs.85).aspx
+ *
+ * Retrieves the Remote Desktop Services session associated with a specified + * process.
+ *
+ *
BOOL ProcessIdToSessionId(_In_ DWORD dwProcessId, _Out_ DWORD *pSessionId);

+ * + * @param dwProcessId + * Specifies a process identifier.
+ * Use the GetCurrentProcessId function to retrieve the process + * identifier for the current process. + * @param pSessionId + * Pointer to a variable that receives the identifier of the + * Remote Desktop Services session under which the specified + * process is running.
+ * To retrieve the identifier of the session currently attached + * to the console, use the WTSGetActiveConsoleSessionId function. + * @return If the function succeeds, the return value is true.
+ * If the function fails, the return value is false. To get extended + * error information, call GetLastError. + */ + boolean ProcessIdToSessionId(int dwProcessId, IntByReference pSessionId); + + /** + * Loads the specified module into the address space of the calling process. + * The specified module may cause other modules to be loaded. + * + *
+     * 
+     * HMODULE WINAPI LoadLibraryEx(
+     *   _In_       LPCTSTR lpFileName,
+     *   _Reserved_ HANDLE  hFile,
+     *   _In_       DWORD   dwFlags
+     * );
+     * 
+     * 
+ * + * @param lpFileName + * A string that specifies the file name of the module to load. + * This name is not related to the name stored in a library + * module itself, as specified by the LIBRARY keyword in the + * module-definition (.def) file.
+ * The module can be a library module (a .dll file) or an + * executable module (an .exe file). If the specified module is + * an executable module, static imports are not loaded; instead, + * the module is loaded as if DONT_RESOLVE_DLL_REFERENCES was + * specified. See the dwFlags parameter for more + * information.
+ * If the string specifies a module name without a path and the + * file name extension is omitted, the function appends the + * default library extension .dll to the module name. To prevent + * the function from appending .dll to the module name, include a + * trailing point character (.) in the module name string.
+ * If the string specifies a fully qualified path, the function + * searches only that path for the module. When specifying a + * path, be sure to use backslashes (\), not forward slashes (/). + * For more information about paths, see "Naming Files, Paths, and Namespaces" on MSDN.
+ * If the string specifies a module name without a path and more + * than one loaded module has the same base name and extension, + * the function returns a handle to the module that was loaded + * first.
+ * If the string specifies a module name without a path and a + * module of the same name is not already loaded, or if the + * string specifies a module name with a relative path, the + * function searches for the specified module. The function also + * searches for modules if loading the specified module causes + * the system to load other associated modules (that is, if the + * module has dependencies). The directories that are searched + * and the order in which they are searched depend on the + * specified path and the dwFlags parameter. For more + * information, see Remarks.
+ * If the function cannot find the module or one of its + * dependencies, the function fails. + * @param hFile + * This parameter is reserved for future use. It must be NULL. + * @param flags + * The action to be taken when loading the module.
+ * If no flags are specified, the behavior of this function is + * identical to that of the LoadLibrary function.
+ * This parameter can be one of the following values.
+ *
+ * DONT_RESOLVE_DLL_REFERENCES: 0x00000001
+ * If this value is used, and the executable module is a DLL, the + * system does not call DllMain for process and thread + * initialization and termination. Also, the system does not load + * additional executable modules that are referenced by the + * specified module.
+ * Do not use this value; it is provided only for backward + * compatibility. If you are planning to access only data or + * resources in the DLL, use LOAD_LIBRARY_AS_DATAFILE_EXCLUSIVE + * or LOAD_LIBRARY_AS_IMAGE_RESOURCE or both. Otherwise, load the + * library as a DLL or executable module using the LoadLibrary + * function.
+ *
+ * LOAD_IGNORE_CODE_AUTHZ_LEVEL: 0x00000010
+ * If this value is used, the system does not check AppLocker + * rules or apply Software Restriction Policies for the DLL. + * AppLocker was introduced in Windows 7 and Windows Server 2008 + * R2. This action applies only to the DLL being loaded and not + * to its dependencies. This value is recommended for use in + * setup programs that must run extracted DLLs during + * installation.
+ * Windows Server 2008 R2 and Windows 7: On systems with + * KB2532445 installed, the caller must be running as + * "LocalSystem" or "TrustedInstaller"; otherwise the system + * ignores this flag.
+ *
+ * LOAD_LIBRARY_AS_DATAFILE: 0x00000002
+ * If this value is used, the system maps the file into the + * calling process's virtual address space as if it were a data + * file. Nothing is done to execute or prepare to execute the + * mapped file. Therefore, you cannot call functions like + * GetModuleFileName, GetModuleHandle or GetProcAddress with this + * DLL. Using this value causes writes to read-only memory to + * raise an access violation. Use this flag when you want to load + * a DLL only to extract messages or resources from it.
+ * This value can be used with LOAD_LIBRARY_AS_IMAGE_RESOURCE. + * For more information, see Remarks
+ *
+ * LOAD_LIBRARY_AS_DATAFILE_EXCLUSIVE: 0x00000040
+ * Similar to LOAD_LIBRARY_AS_DATAFILE, except that the DLL file + * is opened with exclusive write access for the calling process. + * Other processes cannot open the DLL file for write access + * while it is in use. However, the DLL can still be opened by + * other processes.
+ * This value can be used with LOAD_LIBRARY_AS_IMAGE_RESOURCE. + * This value is not supported until Windows Vista.
+ *
+ * LOAD_LIBRARY_AS_IMAGE_RESOURCE: 0x00000020
+ * If this value is used, the system maps the file into the + * process's virtual address space as an image file. However, the + * loader does not load the static imports or perform the other + * usual initialization steps. Use this flag when you want to + * load a DLL only to extract messages or resources from it.
+ * Unless the application depends on the file having the + * in-memory layout of an image, this value should be used with + * either LOAD_LIBRARY_AS_DATAFILE_EXCLUSIVE or + * LOAD_LIBRARY_AS_DATAFILE. This value is not supported until + * Windows Vista.
+ *
+ * LOAD_LIBRARY_SEARCH_APPLICATION_DIR: 0x00000200
+ * If this value is used, the application's installation + * directory is searched for the DLL and its dependencies. + * Directories in the standard search path are not searched. This + * value cannot be combined with LOAD_WITH_ALTERED_SEARCH_PATH. + *
+ * Windows 7, Windows Server 2008 R2, Windows Vista, and Windows + * Server 2008: This value requires KB2533623 to be installed. + *
+ *
+ * LOAD_LIBRARY_SEARCH_DEFAULT_DIRS: 0x00001000
+ * This value is a combination of + * LOAD_LIBRARY_SEARCH_APPLICATION_DIR, + * LOAD_LIBRARY_SEARCH_SYSTEM32, and + * LOAD_LIBRARY_SEARCH_USER_DIRS. Directories in the standard + * search path are not searched. This value cannot be combined + * with LOAD_WITH_ALTERED_SEARCH_PATH.
+ * This value represents the recommended maximum number of + * directories an application should include in its DLL search + * path.
+ * Windows 7, Windows Server 2008 R2, Windows Vista, and Windows + * Server 2008: This value requires KB2533623 to be installed. + *
+ *
+ * LOAD_LIBRARY_SEARCH_DLL_LOAD_DIR: 0x00000100
+ * + * If this value is used, the directory that contains the DLL is + * temporarily added to the beginning of the list of directories + * that are searched for the DLL's dependencies. Directories in + * the standard search path are not searched.
+ * The lpFileName parameter must specify a fully qualified path. + * This value cannot be combined with + * LOAD_WITH_ALTERED_SEARCH_PATH.
+ * For example, if Lib2.dll is a dependency of C:\Dir1\Lib1.dll, + * loading Lib1.dll with this value causes the system to search + * for Lib2.dll only in C:\Dir1. To search for Lib2.dll in + * C:\Dir1 and all of the directories in the DLL search path, + * combine this value with LOAD_LIBRARY_DEFAULT_DIRS.
+ * Windows 7, Windows Server 2008 R2, Windows Vista, and Windows + * Server 2008: This value requires KB2533623 to be installed. + *
+ *
+ * LOAD_LIBRARY_SEARCH_SYSTEM32: 0x00000800
+ * If this value is used, %windows%\system32 is searched for the + * DLL and its dependencies. Directories in the standard search + * path are not searched. This value cannot be combined with + * LOAD_WITH_ALTERED_SEARCH_PATH.
+ * Windows 7, Windows Server 2008 R2, Windows Vista, and Windows + * Server 2008: This value requires KB2533623 to be installed. + *
+ *
+ * LOAD_LIBRARY_SEARCH_USER_DIRS: 0x00000400
+ * If this value is used, directories added using the + * AddDllDirectory or the SetDllDirectory function are searched + * for the DLL and its dependencies. If more than one directory + * has been added, the order in which the directories are + * searched is unspecified. Directories in the standard search + * path are not searched. This value cannot be combined with + * LOAD_WITH_ALTERED_SEARCH_PATH.
+ * Windows 7, Windows Server 2008 R2, Windows Vista, and Windows + * Server 2008: This value requires KB2533623 to be installed. + *
+ *
+ * LOAD_WITH_ALTERED_SEARCH_PATH: 0x00000008
+ * If this value is used and lpFileName specifies an + * absolute path, the system uses the alternate file search + * strategy discussed in the Remarks section to find associated + * executable modules that the specified module causes to be + * loaded. If this value is used and lpFileName + * specifies a relative path, the behavior is undefined.
+ * If this value is not used, or if lpFileName does not + * specify a path, the system uses the standard search strategy + * discussed in the Remarks section to find associated executable + * modules that the specified module causes to be loaded.
+ * This value cannot be combined with any LOAD_LIBRARY_SEARCH + * flag. + * @return If the function succeeds, the return value is a handle to the + * loaded module.
+ * If the function fails, the return value is NULL. To get extended + * error information, call GetLastError. + */ + HMODULE LoadLibraryEx(String lpFileName, HANDLE hFile, int flags); + + /** + * Determines the location of a resource with the specified type and name in + * the specified module.
+ * To specify a language, use the FindResourceEx function. + * + * @param hModule + * A handle to the module whose portable executable file or an + * accompanying MUI file contains the resource.
+ * If this parameter is NULL, the function searches the module + * used to create the current process. + * @param name + * The name of the resource.
+ * Alternately, rather than a pointer, this parameter can be + * MAKEINTRESOURCE(ID), where ID is the integer identifier of the + * resource.
+ * For more information, see the Remarks section below. + * @param type + * The resource type.
+ * Alternately, rather than a pointer, this parameter can be + * MAKEINTRESOURCE(ID), where ID is the integer identifier of the + * given resource type.
+ * For standard resource types, see Resource Types. For more + * information, see the Remarks section below. + * @return If the function succeeds, the return value is a handle to the + * specified resource's information block.
+ * To obtain a handle to the resource, pass this handle to the + * LoadResource function.
+ * If the function fails, the return value is NULL.
+ * To get extended error information, call GetLastError. + */ + HRSRC FindResource(HMODULE hModule, Pointer name, Pointer type); + + /** + * Retrieves a handle that can be used to obtain a pointer to the first byte + * of the specified resource in memory. + * + * @param hModule + * A handle to the module whose executable file contains the + * resource.
+ * If hModule is NULL, the system loads the resource from the + * module that was used to create the current process. + * @param hResource + * A handle to the resource to be loaded.
+ * This handle is returned by the FindResource or FindResourceEx + * function. + * @return If the function succeeds, the return value is a handle to the + * data associated with the resource.
+ * If the function fails, the return value is NULL.
+ * To get extended error information, call GetLastError. + */ + HANDLE LoadResource(HMODULE hModule, HRSRC hResource); + + /** + * Retrieves a pointer to the specified resource in memory. + * + * @param hResource + * A handle to the resource to be accessed.
+ * The LoadResource function returns this handle.
+ * Note that this parameter is listed as an HGLOBAL variable only + * for backward compatibility.
+ * Do not pass any value as a parameter other than a successful + * return value from the LoadResource function. + * @return If the loaded resource is available, the return value is a + * pointer to the first byte of the resource; otherwise, it is NULL. + */ + Pointer LockResource(HANDLE hResource); + + /** + * @param hModule + * A handle to the module whose executable file contains the + * resource. + * @param hResource + * A handle to the resource. This handle must be created by using + * the FindResource or FindResourceEx function. + * @return If the function succeeds, the return value is the number of bytes + * in the resource.
+ * If the function fails, the return value is zero. To get extended + * error information, call GetLastError. + */ + int SizeofResource(HMODULE hModule, HANDLE hResource); + + + /** + * Frees the loaded dynamic-link library (DLL) module and, if necessary, + * decrements its reference count. When the reference count reaches zero, + * the module is unloaded from the address space of the calling process and + * the handle is no longer valid. + * + * @param module + * A handle to the loaded library module. The LoadLibrary, + * LoadLibraryEx, GetModuleHandle, or GetModuleHandleEx function + * returns this handle. + * @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 the GetLastError function. + */ + boolean FreeLibrary(HMODULE module); } diff --git a/contrib/platform/src/com/sun/jna/platform/win32/Kernel32Util.java b/contrib/platform/src/com/sun/jna/platform/win32/Kernel32Util.java index f182d559c6..bd59b8f352 100644 --- a/contrib/platform/src/com/sun/jna/platform/win32/Kernel32Util.java +++ b/contrib/platform/src/com/sun/jna/platform/win32/Kernel32Util.java @@ -1,14 +1,14 @@ /* Copyright (c) 2010, 2013 Daniel Doubrovkine, Markus Karg, 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 - * Lesser General Public License for more details. + * Lesser General Public License for more details. */ package com.sun.jna.platform.win32; @@ -31,7 +31,7 @@ /** * Kernel32 utility API. - * + * * @author dblock[at]dblock.org * @author markus[at]headcrashing[dot]eu * @author Andreas "PAX" Lück, onkelpax-git[at]yahoo.de @@ -40,7 +40,7 @@ public abstract class Kernel32Util implements WinDef { /** * Get current computer NetBIOS name. - * + * * @return Netbios name. */ public static String getComputerName() { @@ -55,7 +55,7 @@ public static String getComputerName() { /** * Format a message from the value obtained from * {@link Kernel32#GetLastError} or {@link Native#getLastError}. - * + * * @param code * int * @return Formatted message. @@ -78,7 +78,7 @@ public static String formatMessage(int code) { /** * Format a message from an HRESULT. - * + * * @param code * HRESULT * @return Formatted message. @@ -98,7 +98,7 @@ public static String formatMessageFromHR(HRESULT code) { /** * Format a system message from an error code. - * + * * @param code * Error code, typically a result of GetLastError. * @return Formatted message. @@ -107,18 +107,18 @@ public static String formatMessageFromLastErrorCode(int code) { return formatMessageFromHR(W32Errors.HRESULT_FROM_WIN32(code)); } - /** - * @return Obtains the human-readable error message text from the last error - * that occurred by invocating {@code Kernel32.GetLastError()}. - */ - public static String getLastErrorMessage() { - return Kernel32Util.formatMessageFromLastErrorCode(Kernel32.INSTANCE - .GetLastError()); - } + /** + * @return Obtains the human-readable error message text from the last error + * that occurred by invocating {@code Kernel32.GetLastError()}. + */ + public static String getLastErrorMessage() { + return Kernel32Util.formatMessageFromLastErrorCode(Kernel32.INSTANCE + .GetLastError()); + } /** * Return the path designated for temporary files. - * + * * @return Path. */ public static String getTempPath() { @@ -138,7 +138,7 @@ public static void deleteFile(String filename) { /** * Returns valid drives in the system. - * + * * @return A {@link List} of valid drives. */ public static List getLogicalDriveStrings() { @@ -159,7 +159,7 @@ public static List getLogicalDriveStrings() { /** * Retrieves file system attributes for a specified file or directory. - * + * * @param fileName * The name of the file or directory. * @return The attributes of the specified file or directory. @@ -229,7 +229,7 @@ public static int getDriveType(String rootName) { /** * Get the value of an environment variable. - * + * * @param name * Name of the environment variable. * @return Value of an environment variable. @@ -265,7 +265,7 @@ public static Map getEnvironmentVariables() { if (lpszEnvironmentBlock == null) { throw new LastErrorException(Kernel32.INSTANCE.GetLastError()); } - + try { return getEnvironmentVariables(lpszEnvironmentBlock, 0L); } finally { @@ -284,13 +284,13 @@ public static Map getEnvironmentVariables() { * Note: if the environment block is {@code null} then {@code null} * is returned instead of an empty map since we want to distinguish * between the case that the data block is {@code null} and when there are - * no environment variables (as unlikely as it may be) + * no environment variables (as unlikely as it may be) */ public static Map getEnvironmentVariables(Pointer lpszEnvironmentBlock, long offset) { if (lpszEnvironmentBlock == null) { return null; } - + Map vars=new TreeMap(); boolean asWideChars=isWideCharEnvironmentStringBlock(lpszEnvironmentBlock, offset); long stepFactor=asWideChars ? 2L : 1L; @@ -305,13 +305,13 @@ public static Map getEnvironmentVariables(Pointer lpszEnvironment if (pos < 0) { throw new IllegalArgumentException("Missing variable value separator in " + nvp); } - + String name=nvp.substring(0, pos), value=nvp.substring(pos + 1); vars.put(name, value); curOffset += (len + 1 /* skip the ending '\0' */) * stepFactor; } - + return vars; } @@ -333,7 +333,7 @@ public static String readEnvironmentStringBlockEntry(Pointer lpszEnvironmentBloc if (dataLen == 0) { return ""; } - + int charsLen=asWideChars ? (dataLen / 2) : dataLen; char[] chars=new char[charsLen]; long curOffset=offset, stepSize=asWideChars ? 2L : 1L; @@ -351,7 +351,7 @@ public static String readEnvironmentStringBlockEntry(Pointer lpszEnvironmentBloc chars[index] = (char) (b & 0x00FF); } } - + return new String(chars); } @@ -388,10 +388,10 @@ public static long findEnvironmentStringBlockEntryEnd(Pointer lpszEnvironmentBlo * the assumption is that the environment variable name (at * least) is ASCII. * - * + * *
  • * Otherwise (i.e., zero charset indicator), it is assumed to be - * a {@code wchar_t} + * a {@code wchar_t} *
  • * * Note: the code takes into account the {@link ByteOrder} even though @@ -413,7 +413,7 @@ public static boolean isWideCharEnvironmentStringBlock(Pointer lpszEnvironmentBl return isWideCharEnvironmentStringBlock(b0); } } - + private static boolean isWideCharEnvironmentStringBlock(byte charsetIndicator) { // assume wchar_t for environment variables represents ASCII letters if (charsetIndicator != 0) { @@ -426,7 +426,7 @@ private static boolean isWideCharEnvironmentStringBlock(byte charsetIndicator) { /** * Retrieves an integer associated with a key in the specified section of an * initialization file. - * + * * @param appName * The name of the section in the initialization file. * @param keyName @@ -451,7 +451,7 @@ public static final int getPrivateProfileInt(final String appName, /** * Retrieves a string from the specified section in an initialization file. - * + * * @param lpAppName * The name of the section containing the key name. If this * parameter is {@code null}, the @@ -516,7 +516,7 @@ public static final void writePrivateProfileString(final String appName, /** * Convenience method to get the processor information. Takes care of * auto-growing the array. - * + * * @return the array of processor information. */ public static final WinNT.SYSTEM_LOGICAL_PROCESSOR_INFORMATION[] getLogicalProcessorInformation() { @@ -543,7 +543,7 @@ public static final WinNT.SYSTEM_LOGICAL_PROCESSOR_INFORMATION[] getLogicalProce return (WinNT.SYSTEM_LOGICAL_PROCESSOR_INFORMATION[]) firstInformation .toArray(new WinNT.SYSTEM_LOGICAL_PROCESSOR_INFORMATION[returnedStructCount]); } - + /** * Retrieves all the keys and values for the specified section of an initialization file. * @@ -639,7 +639,7 @@ public static final List getVolumePathNamesForVolumeName(String lpszVolu if (hr != WinError.ERROR_MORE_DATA) { throw new Win32Exception(hr); } - + int required = lpcchReturnLength.getValue(); lpszVolumePathNames = new char[required]; // this time we MUST succeed @@ -647,7 +647,7 @@ public static final List getVolumePathNamesForVolumeName(String lpszVolu throw new Win32Exception(Kernel32.INSTANCE.GetLastError()); } } - + int bufSize = lpcchReturnLength.getValue(); return Native.toStringList(lpszVolumePathNames, 0, bufSize); } @@ -660,7 +660,7 @@ public static final List getVolumePathNamesForVolumeName(String lpszVolu * Parses and returns the pure GUID value of a volume name obtained * from {@link Kernel32#FindFirstVolume(char[], int)} or * {@link Kernel32#FindNextVolume} calls - * + * * @param volumeGUIDPath * The volume GUID path as returned by one of the above mentioned calls * @return The pure GUID value after stripping the "\\?\" prefix and @@ -675,7 +675,92 @@ public static final String extractVolumeGUID(String volumeGUIDPath) { || (!volumeGUIDPath.endsWith(VOLUME_GUID_PATH_SUFFIX))) { throw new IllegalArgumentException("Bad volume GUID path format: " + volumeGUIDPath); } - + return volumeGUIDPath.substring(VOLUME_GUID_PATH_PREFIX.length(), volumeGUIDPath.length() - VOLUME_GUID_PATH_SUFFIX.length()); } + + /** + * Gets the specified resource out of the specified executable file + * + * @param path + * The path to the executable file + * @param type + * The type of the resource (either a type name or type ID is + * allowed) + * @param name + * The name or ID of the resource + * @return The resource bytes, or null if no such resource exists. + * @throws IllegalStateException if the call to LockResource fails + */ + public static byte[] getResource(String path, String type, String name) { + HMODULE target = Kernel32.INSTANCE.LoadLibraryEx(path, null, Kernel32.LOAD_LIBRARY_AS_DATAFILE); + + if (target == null) { + throw new Win32Exception(Kernel32.INSTANCE.GetLastError()); + } + + Win32Exception err = null; + Pointer start = null; + int length = 0; + try { + Pointer t = null; + try { + t = new Pointer(Long.parseLong(type)); + } catch (NumberFormatException e) { + t = new Memory(Native.WCHAR_SIZE * (type.length() + 1)); + t.setWideString(0, type); + } + + Pointer n = null; + try { + n = new Pointer(Long.parseLong(name)); + } catch (NumberFormatException e) { + n = new Memory(Native.WCHAR_SIZE * (name.length() + 1)); + n.setWideString(0, name); + } + + HRSRC hrsrc = Kernel32.INSTANCE.FindResource(target, n, t); + if (hrsrc == null) { + throw new Win32Exception(Kernel32.INSTANCE.GetLastError()); + } + + // according to MSDN, on 32 bit Windows or newer, calling FreeResource() is not necessary - and in fact does nothing but return false. + HANDLE loaded = Kernel32.INSTANCE.LoadResource(target, hrsrc); + if (loaded == null) { + throw new Win32Exception(Kernel32.INSTANCE.GetLastError()); + } + + length = Kernel32.INSTANCE.SizeofResource(target, hrsrc); + if (length == 0) { + throw new Win32Exception(Kernel32.INSTANCE.GetLastError()); + } + + // MSDN: It is not necessary to unlock resources because the system automatically deletes them when the process that created them terminates. + // MSDN does not say that LockResource sets GetLastError + start = Kernel32.INSTANCE.LockResource(loaded); + if (start == null) { + throw new IllegalStateException("LockResource returned null."); + } + } catch (Win32Exception we) { + err = we; + } finally { + // from what I can tell on MSDN, the only thing that needs cleanup on this is the HMODULE from LoadLibrary + if (target != null) { + if (!Kernel32.INSTANCE.FreeLibrary(target)) { + Win32Exception we = new Win32Exception(Kernel32.INSTANCE.GetLastError()); + if (err != null) { + we.addSuppressed(err); + } + throw we; + } + } + } + + if (err != null) { + throw err; + } + + return start.getByteArray(0, length); + } + } diff --git a/contrib/platform/src/com/sun/jna/platform/win32/Tlhelp32.java b/contrib/platform/src/com/sun/jna/platform/win32/Tlhelp32.java index 32fac29565..517fef73c6 100644 --- a/contrib/platform/src/com/sun/jna/platform/win32/Tlhelp32.java +++ b/contrib/platform/src/com/sun/jna/platform/win32/Tlhelp32.java @@ -38,8 +38,20 @@ public interface Tlhelp32 { WinDef.DWORD TH32CS_SNAPTHREAD = new WinDef.DWORD(0x00000004); /** - * Includes all modules of the process specified in th32ProcessID in the snapshot. To enumerate the modules, see - * Module32First. If the function fails with ERROR_BAD_LENGTH, retry the function until it succeeds. + * + * Used with Kernel32.CreateToolhelp32Snapshot
    + * Includes all modules of the process specified in th32ProcessID in the + * snapshot.
    + * To enumerate the modules, see Module32First.
    + * If the function fails with ERROR_BAD_LENGTH, retry the function until it + * succeeds.
    + * 64-bit Windows: Using this flag in a 32-bit process includes the 32-bit + * modules of the process specified in th32ProcessID, while using it in a + * 64-bit process includes the 64-bit modules.
    + * To include the 32-bit modules of the process specified in th32ProcessID + * from a 64-bit process, use the TH32CS_SNAPMODULE32 flag. + * + * @see MSDN {@link https://msdn.microsoft.com/en-us/library/windows/desktop/ms682489(v=vs.85).aspx } */ WinDef.DWORD TH32CS_SNAPMODULE = new WinDef.DWORD(0x00000008); @@ -61,6 +73,8 @@ public interface Tlhelp32 { */ WinDef.DWORD TH32CS_INHERIT = new WinDef.DWORD(0x80000000); + int MAX_MODULE_NAME32 = 255; + /** * Describes an entry from a list of the processes residing in the system address space when a snapshot was taken. */ @@ -137,7 +151,7 @@ public PROCESSENTRY32(Pointer memory) { * retrieve the full path of the executable file for a 64-bit process. */ public char[] szExeFile = new char[WinDef.MAX_PATH]; - + protected List getFieldOrder() { return Arrays.asList(new String[] { "dwSize", "cntUsage", "th32ProcessID", "th32DefaultHeapID", "th32ModuleID", "cntThreads", "th32ParentProcessID", "pcPriClassBase", "dwFlags", "szExeFile" }); } 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 1b4e743859..b0661574ce 100644 --- a/contrib/platform/test/com/sun/jna/platform/win32/Kernel32Test.java +++ b/contrib/platform/test/com/sun/jna/platform/win32/Kernel32Test.java @@ -36,6 +36,7 @@ import com.sun.jna.platform.win32.WinBase.MEMORYSTATUSEX; import com.sun.jna.platform.win32.WinBase.SYSTEM_INFO; import com.sun.jna.platform.win32.WinDef.DWORD; +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.platform.win32.WinNT.HANDLEByReference; @@ -49,12 +50,12 @@ public class Kernel32Test extends TestCase { public static void main(String[] args) { - OSVERSIONINFO lpVersionInfo = new OSVERSIONINFO(); - assertTrue(Kernel32.INSTANCE.GetVersionEx(lpVersionInfo)); - System.out.println("Operating system: " - + lpVersionInfo.dwMajorVersion.longValue() + "." + lpVersionInfo.dwMinorVersion.longValue() - + " (" + lpVersionInfo.dwBuildNumber + ")" - + " [" + Native.toString(lpVersionInfo.szCSDVersion) + "]"); + OSVERSIONINFO lpVersionInfo = new OSVERSIONINFO(); + assertTrue(Kernel32.INSTANCE.GetVersionEx(lpVersionInfo)); + System.out.println("Operating system: " + + lpVersionInfo.dwMajorVersion.longValue() + "." + lpVersionInfo.dwMinorVersion.longValue() + + " (" + lpVersionInfo.dwBuildNumber + ")" + + " [" + Native.toString(lpVersionInfo.szCSDVersion) + "]"); junit.textui.TestRunner.run(Kernel32Test.class); } @@ -205,289 +206,289 @@ public void testConvertHWND_BROADCAST() { } public void testGetComputerName() { - IntByReference lpnSize = new IntByReference(0); - assertFalse(Kernel32.INSTANCE.GetComputerName(null, lpnSize)); - assertEquals(WinError.ERROR_BUFFER_OVERFLOW, Kernel32.INSTANCE.GetLastError()); - char buffer[] = new char[WinBase.MAX_COMPUTERNAME_LENGTH + 1]; - lpnSize.setValue(buffer.length); - assertTrue(Kernel32.INSTANCE.GetComputerName(buffer, lpnSize)); + IntByReference lpnSize = new IntByReference(0); + assertFalse(Kernel32.INSTANCE.GetComputerName(null, lpnSize)); + assertEquals(WinError.ERROR_BUFFER_OVERFLOW, Kernel32.INSTANCE.GetLastError()); + char buffer[] = new char[WinBase.MAX_COMPUTERNAME_LENGTH + 1]; + lpnSize.setValue(buffer.length); + assertTrue(Kernel32.INSTANCE.GetComputerName(buffer, lpnSize)); } public void testGetComputerNameExSameAsGetComputerName() { - IntByReference lpnSize = new IntByReference(0); - char buffer[] = new char[WinBase.MAX_COMPUTERNAME_LENGTH + 1]; - lpnSize.setValue(buffer.length); - assertTrue("Failed to retrieve expected computer name", Kernel32.INSTANCE.GetComputerName(buffer, lpnSize)); + IntByReference lpnSize = new IntByReference(0); + char buffer[] = new char[WinBase.MAX_COMPUTERNAME_LENGTH + 1]; + lpnSize.setValue(buffer.length); + assertTrue("Failed to retrieve expected computer name", Kernel32.INSTANCE.GetComputerName(buffer, lpnSize)); String expected = Native.toString(buffer); // reset - lpnSize.setValue(buffer.length); + lpnSize.setValue(buffer.length); Arrays.fill(buffer, '\0'); - assertTrue("Failed to retrieve extended computer name", Kernel32.INSTANCE.GetComputerNameEx(WinBase.COMPUTER_NAME_FORMAT.ComputerNameNetBIOS, buffer, lpnSize)); + assertTrue("Failed to retrieve extended computer name", Kernel32.INSTANCE.GetComputerNameEx(WinBase.COMPUTER_NAME_FORMAT.ComputerNameNetBIOS, buffer, lpnSize)); String actual = Native.toString(buffer); assertEquals("Mismatched names", expected, actual); } public void testWaitForSingleObject() { - HANDLE handle = Kernel32.INSTANCE.CreateEvent(null, false, false, null); + HANDLE handle = Kernel32.INSTANCE.CreateEvent(null, false, false, null); - // handle runs into timeout since it is not triggered - // WAIT_TIMEOUT = 0x00000102 - assertEquals(WinError.WAIT_TIMEOUT, Kernel32.INSTANCE.WaitForSingleObject( - handle, 1000)); + // handle runs into timeout since it is not triggered + // WAIT_TIMEOUT = 0x00000102 + assertEquals(WinError.WAIT_TIMEOUT, Kernel32.INSTANCE.WaitForSingleObject( + handle, 1000)); - Kernel32.INSTANCE.CloseHandle(handle); - } + Kernel32.INSTANCE.CloseHandle(handle); + } public void testResetEvent() { - HANDLE handle = Kernel32.INSTANCE.CreateEvent(null, true, false, null); + HANDLE handle = Kernel32.INSTANCE.CreateEvent(null, true, false, null); - // set the event to the signaled state - Kernel32.INSTANCE.SetEvent(handle); + // set the event to the signaled state + Kernel32.INSTANCE.SetEvent(handle); - // This should return successfully - assertEquals(WinBase.WAIT_OBJECT_0, Kernel32.INSTANCE.WaitForSingleObject( - handle, 1000)); + // This should return successfully + assertEquals(WinBase.WAIT_OBJECT_0, Kernel32.INSTANCE.WaitForSingleObject( + handle, 1000)); - // now reset it to not signaled - Kernel32.INSTANCE.ResetEvent(handle); + // now reset it to not signaled + Kernel32.INSTANCE.ResetEvent(handle); - // handle runs into timeout since it is not triggered - // WAIT_TIMEOUT = 0x00000102 - assertEquals(WinError.WAIT_TIMEOUT, Kernel32.INSTANCE.WaitForSingleObject( - handle, 1000)); + // handle runs into timeout since it is not triggered + // WAIT_TIMEOUT = 0x00000102 + assertEquals(WinError.WAIT_TIMEOUT, Kernel32.INSTANCE.WaitForSingleObject( + handle, 1000)); - Kernel32.INSTANCE.CloseHandle(handle); - } + Kernel32.INSTANCE.CloseHandle(handle); + } public void testWaitForMultipleObjects(){ - HANDLE[] handles = new HANDLE[2]; + HANDLE[] handles = new HANDLE[2]; - handles[0] = Kernel32.INSTANCE.CreateEvent(null, false, false, null); - handles[1] = Kernel32.INSTANCE.CreateEvent(null, false, false, null); + handles[0] = Kernel32.INSTANCE.CreateEvent(null, false, false, null); + handles[1] = Kernel32.INSTANCE.CreateEvent(null, false, false, null); - // handle runs into timeout since it is not triggered - // WAIT_TIMEOUT = 0x00000102 - assertEquals(WinError.WAIT_TIMEOUT, Kernel32.INSTANCE.WaitForMultipleObjects( - handles.length, handles, false, 1000)); + // handle runs into timeout since it is not triggered + // WAIT_TIMEOUT = 0x00000102 + assertEquals(WinError.WAIT_TIMEOUT, Kernel32.INSTANCE.WaitForMultipleObjects( + handles.length, handles, false, 1000)); - Kernel32.INSTANCE.CloseHandle(handles[0]); - Kernel32.INSTANCE.CloseHandle(handles[1]); + Kernel32.INSTANCE.CloseHandle(handles[0]); + Kernel32.INSTANCE.CloseHandle(handles[1]); - // invalid Handle - handles[0] = WinBase.INVALID_HANDLE_VALUE; - handles[1] = Kernel32.INSTANCE.CreateEvent(null, false, false, null); + // invalid Handle + handles[0] = WinBase.INVALID_HANDLE_VALUE; + handles[1] = Kernel32.INSTANCE.CreateEvent(null, false, false, null); - // returns WAIT_FAILED since handle is invalid - assertEquals(WinBase.WAIT_FAILED, Kernel32.INSTANCE.WaitForMultipleObjects( - handles.length, handles, false, 5000)); + // returns WAIT_FAILED since handle is invalid + assertEquals(WinBase.WAIT_FAILED, Kernel32.INSTANCE.WaitForMultipleObjects( + handles.length, handles, false, 5000)); - Kernel32.INSTANCE.CloseHandle(handles[1]); + Kernel32.INSTANCE.CloseHandle(handles[1]); } public void testGetCurrentThreadId() { - assertTrue(Kernel32.INSTANCE.GetCurrentThreadId() > 0); + assertTrue(Kernel32.INSTANCE.GetCurrentThreadId() > 0); } public void testGetCurrentThread() { - HANDLE h = Kernel32.INSTANCE.GetCurrentThread(); - assertNotNull(h); - assertFalse(h.equals(0)); - // CloseHandle does not need to be called for a thread handle - assertFalse(Kernel32.INSTANCE.CloseHandle(h)); - assertEquals(WinError.ERROR_INVALID_HANDLE, Kernel32.INSTANCE.GetLastError()); + HANDLE h = Kernel32.INSTANCE.GetCurrentThread(); + assertNotNull(h); + assertFalse(h.equals(0)); + // CloseHandle does not need to be called for a thread handle + assertFalse(Kernel32.INSTANCE.CloseHandle(h)); + assertEquals(WinError.ERROR_INVALID_HANDLE, Kernel32.INSTANCE.GetLastError()); } public void testOpenThread() { - HANDLE h = Kernel32.INSTANCE.OpenThread(WinNT.THREAD_ALL_ACCESS, false, - Kernel32.INSTANCE.GetCurrentThreadId()); - assertNotNull(h); - assertFalse(h.equals(0)); - assertTrue(Kernel32.INSTANCE.CloseHandle(h)); + HANDLE h = Kernel32.INSTANCE.OpenThread(WinNT.THREAD_ALL_ACCESS, false, + Kernel32.INSTANCE.GetCurrentThreadId()); + assertNotNull(h); + assertFalse(h.equals(0)); + assertTrue(Kernel32.INSTANCE.CloseHandle(h)); } public void testGetCurrentProcessId() { - assertTrue(Kernel32.INSTANCE.GetCurrentProcessId() > 0); + assertTrue(Kernel32.INSTANCE.GetCurrentProcessId() > 0); } public void testGetCurrentProcess() { - HANDLE h = Kernel32.INSTANCE.GetCurrentProcess(); - assertNotNull(h); - assertFalse(h.equals(0)); - // CloseHandle does not need to be called for a process handle - assertFalse(Kernel32.INSTANCE.CloseHandle(h)); - assertEquals(WinError.ERROR_INVALID_HANDLE, Kernel32.INSTANCE.GetLastError()); + HANDLE h = Kernel32.INSTANCE.GetCurrentProcess(); + assertNotNull(h); + assertFalse(h.equals(0)); + // CloseHandle does not need to be called for a process handle + assertFalse(Kernel32.INSTANCE.CloseHandle(h)); + assertEquals(WinError.ERROR_INVALID_HANDLE, Kernel32.INSTANCE.GetLastError()); } public void testOpenProcess() { - HANDLE h = Kernel32.INSTANCE.OpenProcess(0, false, - Kernel32.INSTANCE.GetCurrentProcessId()); - assertNull(h); - // opening your own process fails with access denied - assertEquals(WinError.ERROR_ACCESS_DENIED, Kernel32.INSTANCE.GetLastError()); + HANDLE h = Kernel32.INSTANCE.OpenProcess(0, false, + Kernel32.INSTANCE.GetCurrentProcessId()); + assertNull(h); + // opening your own process fails with access denied + assertEquals(WinError.ERROR_ACCESS_DENIED, Kernel32.INSTANCE.GetLastError()); } public void testGetTempPath() { - char[] buffer = new char[WinDef.MAX_PATH]; - assertTrue(Kernel32.INSTANCE.GetTempPath(new DWORD(WinDef.MAX_PATH), buffer).intValue() > 0); + char[] buffer = new char[WinDef.MAX_PATH]; + assertTrue(Kernel32.INSTANCE.GetTempPath(new DWORD(WinDef.MAX_PATH), buffer).intValue() > 0); } - public void testGetTickCount() throws InterruptedException { - // Tick count rolls over every 49.7 days, so to safeguard from - // roll-over, we will get two time spans. At least one should - // yield a positive. - int tick1 = Kernel32.INSTANCE.GetTickCount(); - Thread.sleep(10); - int tick2 = Kernel32.INSTANCE.GetTickCount(); - Thread.sleep(10); - int tick3 = Kernel32.INSTANCE.GetTickCount(); + public void testGetTickCount() throws InterruptedException { + // Tick count rolls over every 49.7 days, so to safeguard from + // roll-over, we will get two time spans. At least one should + // yield a positive. + int tick1 = Kernel32.INSTANCE.GetTickCount(); + Thread.sleep(10); + int tick2 = Kernel32.INSTANCE.GetTickCount(); + Thread.sleep(10); + int tick3 = Kernel32.INSTANCE.GetTickCount(); - assertTrue(tick2 > tick1 || tick3 > tick2); - } + assertTrue(tick2 > tick1 || tick3 > tick2); + } public void testGetVersion() { - DWORD version = Kernel32.INSTANCE.GetVersion(); - assertTrue("Version high should be non-zero: 0x" + Integer.toHexString(version.getHigh().intValue()), version.getHigh().intValue() != 0); - assertTrue("Version low should be >= 0: 0x" + Integer.toHexString(version.getLow().intValue()), version.getLow().intValue() >= 0); + DWORD version = Kernel32.INSTANCE.GetVersion(); + assertTrue("Version high should be non-zero: 0x" + Integer.toHexString(version.getHigh().intValue()), version.getHigh().intValue() != 0); + assertTrue("Version low should be >= 0: 0x" + Integer.toHexString(version.getLow().intValue()), version.getLow().intValue() >= 0); } public void testGetVersionEx_OSVERSIONINFO() { - OSVERSIONINFO lpVersionInfo = new OSVERSIONINFO(); - assertEquals(lpVersionInfo.size(), lpVersionInfo.dwOSVersionInfoSize.longValue()); - assertTrue(Kernel32.INSTANCE.GetVersionEx(lpVersionInfo)); - assertTrue(lpVersionInfo.dwMajorVersion.longValue() > 0); - assertTrue(lpVersionInfo.dwMinorVersion.longValue() >= 0); - assertEquals(lpVersionInfo.size(), lpVersionInfo.dwOSVersionInfoSize.longValue()); - assertTrue(lpVersionInfo.dwPlatformId.longValue() > 0); - assertTrue(lpVersionInfo.dwBuildNumber.longValue() > 0); - assertTrue(Native.toString(lpVersionInfo.szCSDVersion).length() >= 0); + OSVERSIONINFO lpVersionInfo = new OSVERSIONINFO(); + assertEquals(lpVersionInfo.size(), lpVersionInfo.dwOSVersionInfoSize.longValue()); + assertTrue(Kernel32.INSTANCE.GetVersionEx(lpVersionInfo)); + assertTrue(lpVersionInfo.dwMajorVersion.longValue() > 0); + assertTrue(lpVersionInfo.dwMinorVersion.longValue() >= 0); + assertEquals(lpVersionInfo.size(), lpVersionInfo.dwOSVersionInfoSize.longValue()); + assertTrue(lpVersionInfo.dwPlatformId.longValue() > 0); + assertTrue(lpVersionInfo.dwBuildNumber.longValue() > 0); + assertTrue(Native.toString(lpVersionInfo.szCSDVersion).length() >= 0); } 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); - 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); + 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); + 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); } public void testGetSystemInfo() { - SYSTEM_INFO lpSystemInfo = new SYSTEM_INFO(); - Kernel32.INSTANCE.GetSystemInfo(lpSystemInfo); - assertTrue(lpSystemInfo.dwNumberOfProcessors.intValue() > 0); + SYSTEM_INFO lpSystemInfo = new SYSTEM_INFO(); + Kernel32.INSTANCE.GetSystemInfo(lpSystemInfo); + assertTrue(lpSystemInfo.dwNumberOfProcessors.intValue() > 0); } public void testIsWow64Process() { - try { - IntByReference isWow64 = new IntByReference(42); - HANDLE hProcess = Kernel32.INSTANCE.GetCurrentProcess(); - assertTrue(Kernel32.INSTANCE.IsWow64Process(hProcess, isWow64)); - assertTrue(0 == isWow64.getValue() || 1 == isWow64.getValue()); - } catch (UnsatisfiedLinkError e) { - // IsWow64Process is not available on this OS - } + try { + IntByReference isWow64 = new IntByReference(42); + HANDLE hProcess = Kernel32.INSTANCE.GetCurrentProcess(); + assertTrue(Kernel32.INSTANCE.IsWow64Process(hProcess, isWow64)); + assertTrue(0 == isWow64.getValue() || 1 == isWow64.getValue()); + } catch (UnsatisfiedLinkError e) { + // IsWow64Process is not available on this OS + } } public void testGetNativeSystemInfo() { - try { - SYSTEM_INFO lpSystemInfo = new SYSTEM_INFO(); - Kernel32.INSTANCE.GetNativeSystemInfo(lpSystemInfo); - assertTrue(lpSystemInfo.dwNumberOfProcessors.intValue() > 0); - } catch (UnsatisfiedLinkError e) { - // only available under WOW64 - } + try { + SYSTEM_INFO lpSystemInfo = new SYSTEM_INFO(); + Kernel32.INSTANCE.GetNativeSystemInfo(lpSystemInfo); + assertTrue(lpSystemInfo.dwNumberOfProcessors.intValue() > 0); + } catch (UnsatisfiedLinkError e) { + // only available under WOW64 + } } public void testGlobalMemoryStatusEx() { - MEMORYSTATUSEX lpBuffer = new MEMORYSTATUSEX(); - assertTrue(Kernel32.INSTANCE.GlobalMemoryStatusEx(lpBuffer)); - assertTrue(lpBuffer.ullTotalPhys.longValue() > 0); - assertTrue(lpBuffer.dwMemoryLoad.intValue() >= 0 && lpBuffer.dwMemoryLoad.intValue() <= 100); - assertEquals(0, lpBuffer.ullAvailExtendedVirtual.intValue()); + MEMORYSTATUSEX lpBuffer = new MEMORYSTATUSEX(); + assertTrue(Kernel32.INSTANCE.GlobalMemoryStatusEx(lpBuffer)); + assertTrue(lpBuffer.ullTotalPhys.longValue() > 0); + assertTrue(lpBuffer.dwMemoryLoad.intValue() >= 0 && lpBuffer.dwMemoryLoad.intValue() <= 100); + assertEquals(0, lpBuffer.ullAvailExtendedVirtual.intValue()); } public void testDeleteFile() { - String filename = Kernel32Util.getTempPath() + "\\FileDoesNotExist.jna"; - assertFalse(Kernel32.INSTANCE.DeleteFile(filename)); - assertEquals(WinError.ERROR_FILE_NOT_FOUND, Kernel32.INSTANCE.GetLastError()); + String filename = Kernel32Util.getTempPath() + "\\FileDoesNotExist.jna"; + assertFalse(Kernel32.INSTANCE.DeleteFile(filename)); + assertEquals(WinError.ERROR_FILE_NOT_FOUND, Kernel32.INSTANCE.GetLastError()); } public void testReadFile() throws IOException { - String expected = "jna - testReadFile"; - File tmp = File.createTempFile("testReadFile", "jna"); - tmp.deleteOnExit(); - - FileWriter fw = new FileWriter(tmp); - try { - fw.append(expected); - } finally { - fw.close(); - } - - HANDLE hFile = Kernel32.INSTANCE.CreateFile(tmp.getAbsolutePath(), WinNT.GENERIC_READ, WinNT.FILE_SHARE_READ, - new WinBase.SECURITY_ATTRIBUTES(), WinNT.OPEN_EXISTING, WinNT.FILE_ATTRIBUTE_NORMAL, null); - assertFalse("Failed to create file handle: " + tmp, WinBase.INVALID_HANDLE_VALUE.equals(hFile)); - - try { + String expected = "jna - testReadFile"; + File tmp = File.createTempFile("testReadFile", "jna"); + tmp.deleteOnExit(); + + FileWriter fw = new FileWriter(tmp); + try { + fw.append(expected); + } finally { + fw.close(); + } + + HANDLE hFile = Kernel32.INSTANCE.CreateFile(tmp.getAbsolutePath(), WinNT.GENERIC_READ, WinNT.FILE_SHARE_READ, + new WinBase.SECURITY_ATTRIBUTES(), WinNT.OPEN_EXISTING, WinNT.FILE_ATTRIBUTE_NORMAL, null); + assertFalse("Failed to create file handle: " + tmp, WinBase.INVALID_HANDLE_VALUE.equals(hFile)); + + try { byte[] readBuffer=new byte[expected.length() + Byte.MAX_VALUE]; - IntByReference lpNumberOfBytesRead = new IntByReference(0); - assertTrue("Failed to read from file", Kernel32.INSTANCE.ReadFile(hFile, readBuffer, readBuffer.length, lpNumberOfBytesRead, null)); + IntByReference lpNumberOfBytesRead = new IntByReference(0); + assertTrue("Failed to read from file", Kernel32.INSTANCE.ReadFile(hFile, readBuffer, readBuffer.length, lpNumberOfBytesRead, null)); - int read = lpNumberOfBytesRead.getValue(); - assertEquals("Mismatched read size", expected.length(), read); + int read = lpNumberOfBytesRead.getValue(); + assertEquals("Mismatched read size", expected.length(), read); - assertEquals("Mismatched read content", expected, new String(readBuffer, 0, read)); - } finally { - assertTrue("Failed to close file", Kernel32.INSTANCE.CloseHandle(hFile)); - } + assertEquals("Mismatched read content", expected, new String(readBuffer, 0, read)); + } finally { + assertTrue("Failed to close file", Kernel32.INSTANCE.CloseHandle(hFile)); + } } public void testSetHandleInformation() throws IOException { - File tmp = File.createTempFile("testSetHandleInformation", "jna"); - tmp.deleteOnExit(); + File tmp = File.createTempFile("testSetHandleInformation", "jna"); + tmp.deleteOnExit(); - HANDLE hFile = Kernel32.INSTANCE.CreateFile(tmp.getAbsolutePath(), WinNT.GENERIC_READ, WinNT.FILE_SHARE_READ, - new WinBase.SECURITY_ATTRIBUTES(), WinNT.OPEN_EXISTING, WinNT.FILE_ATTRIBUTE_NORMAL, null); - assertFalse(hFile == WinBase.INVALID_HANDLE_VALUE); + HANDLE hFile = Kernel32.INSTANCE.CreateFile(tmp.getAbsolutePath(), WinNT.GENERIC_READ, WinNT.FILE_SHARE_READ, + new WinBase.SECURITY_ATTRIBUTES(), WinNT.OPEN_EXISTING, WinNT.FILE_ATTRIBUTE_NORMAL, null); + assertFalse(hFile == WinBase.INVALID_HANDLE_VALUE); - assertTrue(Kernel32.INSTANCE.SetHandleInformation(hFile, WinBase.HANDLE_FLAG_PROTECT_FROM_CLOSE, 0)); - assertTrue(Kernel32.INSTANCE.CloseHandle(hFile)); + assertTrue(Kernel32.INSTANCE.SetHandleInformation(hFile, WinBase.HANDLE_FLAG_PROTECT_FROM_CLOSE, 0)); + assertTrue(Kernel32.INSTANCE.CloseHandle(hFile)); } public void testCreatePipe() { - HANDLEByReference hReadPipe = new HANDLEByReference(); - HANDLEByReference hWritePipe = new HANDLEByReference(); + HANDLEByReference hReadPipe = new HANDLEByReference(); + HANDLEByReference hWritePipe = new HANDLEByReference(); - assertTrue(Kernel32.INSTANCE.CreatePipe(hReadPipe, hWritePipe, null, 0)); - assertTrue(Kernel32.INSTANCE.CloseHandle(hReadPipe.getValue())); - assertTrue(Kernel32.INSTANCE.CloseHandle(hWritePipe.getValue())); + assertTrue(Kernel32.INSTANCE.CreatePipe(hReadPipe, hWritePipe, null, 0)); + assertTrue(Kernel32.INSTANCE.CloseHandle(hReadPipe.getValue())); + assertTrue(Kernel32.INSTANCE.CloseHandle(hWritePipe.getValue())); } public void testGetExitCodeProcess() { - IntByReference lpExitCode = new IntByReference(0); - assertTrue(Kernel32.INSTANCE.GetExitCodeProcess(Kernel32.INSTANCE.GetCurrentProcess(), lpExitCode)); - assertEquals(WinBase.STILL_ACTIVE, lpExitCode.getValue()); + IntByReference lpExitCode = new IntByReference(0); + assertTrue(Kernel32.INSTANCE.GetExitCodeProcess(Kernel32.INSTANCE.GetCurrentProcess(), lpExitCode)); + assertEquals(WinBase.STILL_ACTIVE, lpExitCode.getValue()); } public void testTerminateProcess() throws IOException { - File tmp = File.createTempFile("testTerminateProcess", "jna"); - tmp.deleteOnExit(); - HANDLE hFile = Kernel32.INSTANCE.CreateFile(tmp.getAbsolutePath(), WinNT.GENERIC_READ, WinNT.FILE_SHARE_READ, - new WinBase.SECURITY_ATTRIBUTES(), WinNT.OPEN_EXISTING, WinNT.FILE_ATTRIBUTE_NORMAL, null); + File tmp = File.createTempFile("testTerminateProcess", "jna"); + tmp.deleteOnExit(); + HANDLE hFile = Kernel32.INSTANCE.CreateFile(tmp.getAbsolutePath(), WinNT.GENERIC_READ, WinNT.FILE_SHARE_READ, + new WinBase.SECURITY_ATTRIBUTES(), WinNT.OPEN_EXISTING, WinNT.FILE_ATTRIBUTE_NORMAL, null); - assertFalse(Kernel32.INSTANCE.TerminateProcess(hFile, 1)); - assertEquals(WinError.ERROR_INVALID_HANDLE, Kernel32.INSTANCE.GetLastError()); - assertTrue(Kernel32.INSTANCE.CloseHandle(hFile)); + assertFalse(Kernel32.INSTANCE.TerminateProcess(hFile, 1)); + assertEquals(WinError.ERROR_INVALID_HANDLE, Kernel32.INSTANCE.GetLastError()); + assertTrue(Kernel32.INSTANCE.CloseHandle(hFile)); } public void testGetFileAttributes() { - assertTrue(WinBase.INVALID_FILE_ATTRIBUTES != Kernel32.INSTANCE.GetFileAttributes(".")); + assertTrue(WinBase.INVALID_FILE_ATTRIBUTES != Kernel32.INSTANCE.GetFileAttributes(".")); } public void testCopyFile() throws IOException { @@ -547,8 +548,8 @@ public void testGetSetFileTime() throws IOException { tmp.deleteOnExit(); HANDLE hFile = Kernel32.INSTANCE.CreateFile(tmp.getAbsolutePath(), WinNT.GENERIC_WRITE, WinNT.FILE_SHARE_WRITE, - new WinBase.SECURITY_ATTRIBUTES(), WinNT.OPEN_EXISTING, WinNT.FILE_ATTRIBUTE_NORMAL, null); - assertFalse(hFile == WinBase.INVALID_HANDLE_VALUE); + new WinBase.SECURITY_ATTRIBUTES(), WinNT.OPEN_EXISTING, WinNT.FILE_ATTRIBUTE_NORMAL, null); + assertFalse(hFile == WinBase.INVALID_HANDLE_VALUE); WinBase.FILETIME.ByReference creationTime = new WinBase.FILETIME.ByReference(); WinBase.FILETIME.ByReference accessTime = new WinBase.FILETIME.ByReference(); @@ -710,55 +711,55 @@ public final void testWritePrivateProfileSection() throws IOException { } public final void testCreateRemoteThread() throws IOException { - HANDLE hThrd = Kernel32.INSTANCE.CreateRemoteThread(null, null, 0, null, null, null, null); - assertNull(hThrd); - assertEquals(Kernel32.INSTANCE.GetLastError(), WinError.ERROR_INVALID_HANDLE); + HANDLE hThrd = Kernel32.INSTANCE.CreateRemoteThread(null, null, 0, null, null, null, null); + assertNull(hThrd); + assertEquals(Kernel32.INSTANCE.GetLastError(), WinError.ERROR_INVALID_HANDLE); } public void testWriteProcessMemory() { - Kernel32 kernel = Kernel32.INSTANCE; + Kernel32 kernel = Kernel32.INSTANCE; - boolean successWrite = kernel.WriteProcessMemory(null, Pointer.NULL, Pointer.NULL, 1, null); - assertFalse(successWrite); - assertEquals(kernel.GetLastError(), WinError.ERROR_INVALID_HANDLE); + boolean successWrite = kernel.WriteProcessMemory(null, Pointer.NULL, Pointer.NULL, 1, null); + assertFalse(successWrite); + assertEquals(kernel.GetLastError(), WinError.ERROR_INVALID_HANDLE); - ByteBuffer bufDest = ByteBuffer.allocateDirect(4); - bufDest.put(new byte[]{0,1,2,3}); - ByteBuffer bufSrc = ByteBuffer.allocateDirect(4); - bufSrc.put(new byte[]{5,10,15,20}); - Pointer ptrSrc = Native.getDirectBufferPointer(bufSrc); - Pointer ptrDest = Native.getDirectBufferPointer(bufDest); + ByteBuffer bufDest = ByteBuffer.allocateDirect(4); + bufDest.put(new byte[]{0,1,2,3}); + ByteBuffer bufSrc = ByteBuffer.allocateDirect(4); + bufSrc.put(new byte[]{5,10,15,20}); + Pointer ptrSrc = Native.getDirectBufferPointer(bufSrc); + Pointer ptrDest = Native.getDirectBufferPointer(bufDest); - HANDLE selfHandle = kernel.GetCurrentProcess(); - kernel.WriteProcessMemory(selfHandle, ptrDest, ptrSrc, 3, null);//Write only the first three + HANDLE selfHandle = kernel.GetCurrentProcess(); + kernel.WriteProcessMemory(selfHandle, ptrDest, ptrSrc, 3, null);//Write only the first three - assertEquals(bufDest.get(0),5); - assertEquals(bufDest.get(1),10); - assertEquals(bufDest.get(2),15); - assertEquals(bufDest.get(3),3); - } + assertEquals(bufDest.get(0),5); + assertEquals(bufDest.get(1),10); + assertEquals(bufDest.get(2),15); + assertEquals(bufDest.get(3),3); + } public void testReadProcessMemory() { - Kernel32 kernel = Kernel32.INSTANCE; + Kernel32 kernel = Kernel32.INSTANCE; - boolean successRead = kernel.ReadProcessMemory(null, Pointer.NULL, Pointer.NULL, 1, null); - assertFalse(successRead); - assertEquals(kernel.GetLastError(), WinError.ERROR_INVALID_HANDLE); + boolean successRead = kernel.ReadProcessMemory(null, Pointer.NULL, Pointer.NULL, 1, null); + assertFalse(successRead); + assertEquals(kernel.GetLastError(), WinError.ERROR_INVALID_HANDLE); - ByteBuffer bufSrc = ByteBuffer.allocateDirect(4); - bufSrc.put(new byte[]{5,10,15,20}); - ByteBuffer bufDest = ByteBuffer.allocateDirect(4); - bufDest.put(new byte[]{0,1,2,3}); - Pointer ptrSrc = Native.getDirectBufferPointer(bufSrc); - Pointer ptrDest = Native.getDirectBufferPointer(bufDest); + ByteBuffer bufSrc = ByteBuffer.allocateDirect(4); + bufSrc.put(new byte[]{5,10,15,20}); + ByteBuffer bufDest = ByteBuffer.allocateDirect(4); + bufDest.put(new byte[]{0,1,2,3}); + Pointer ptrSrc = Native.getDirectBufferPointer(bufSrc); + Pointer ptrDest = Native.getDirectBufferPointer(bufDest); - HANDLE selfHandle = kernel.GetCurrentProcess(); - kernel.ReadProcessMemory(selfHandle, ptrSrc, ptrDest, 3, null);//Read only the first three + HANDLE selfHandle = kernel.GetCurrentProcess(); + kernel.ReadProcessMemory(selfHandle, ptrSrc, ptrDest, 3, null);//Read only the first three - assertEquals(bufDest.get(0),5); - assertEquals(bufDest.get(1),10); - assertEquals(bufDest.get(2),15); - assertEquals(bufDest.get(3),3); + assertEquals(bufDest.get(0),5); + assertEquals(bufDest.get(1),10); + assertEquals(bufDest.get(2),15); + assertEquals(bufDest.get(3),3); } public void testVirtualQueryEx() { @@ -767,167 +768,205 @@ public void testVirtualQueryEx() { SIZE_T bytesRead = Kernel32.INSTANCE.VirtualQueryEx(selfHandle, Pointer.NULL, mbi, new SIZE_T(mbi.size())); assertTrue(bytesRead.intValue() > 0); } - - public void testGetCommState() { - WinBase.DCB lpDCB = new WinBase.DCB(); - // Here we test a com port that definitely does not exist! - HANDLE handleSerialPort = Kernel32.INSTANCE.CreateFile("\\\\.\\comDummy", - WinNT.GENERIC_READ | WinNT.GENERIC_WRITE, 0, null, WinNT.OPEN_EXISTING, WinNT.FILE_ATTRIBUTE_NORMAL, - null); - - int lastError = Kernel32.INSTANCE.GetLastError(); - assertEquals(lastError, WinNT.ERROR_FILE_NOT_FOUND); - //try to read the com port state using the invalid handle - assertFalse(Kernel32.INSTANCE.GetCommState(handleSerialPort, lpDCB)); - // Check if we can open a connection to com port1 - // If yes, we try to read the com state - // If no com port exists we have to skip this test - handleSerialPort = Kernel32.INSTANCE.CreateFile("\\\\.\\com1", WinNT.GENERIC_READ | WinNT.GENERIC_WRITE, 0, - null, WinNT.OPEN_EXISTING, WinNT.FILE_ATTRIBUTE_NORMAL, null); - lastError = Kernel32.INSTANCE.GetLastError(); - if (WinNT.NO_ERROR == lastError) { - assertFalse(WinNT.INVALID_HANDLE_VALUE.equals(handleSerialPort)); - try { - lpDCB = new WinBase.DCB(); - assertTrue(Kernel32.INSTANCE.GetCommState(handleSerialPort, lpDCB)); - switch (lpDCB.BaudRate.intValue()) { - case WinBase.CBR_110: - case WinBase.CBR_1200: - case WinBase.CBR_128000: - case WinBase.CBR_14400: - case WinBase.CBR_19200: - case WinBase.CBR_2400: - case WinBase.CBR_256000: - case WinBase.CBR_300: - case WinBase.CBR_38400: - case WinBase.CBR_4800: - case WinBase.CBR_56000: - case WinBase.CBR_600: - case WinBase.CBR_9600: - break; - default: - fail("Received value of WinBase.DCB.BaudRate is not valid"); - } - } finally { - Kernel32.INSTANCE.CloseHandle(handleSerialPort); - } - } - } - - public void testSetCommState() { - WinBase.DCB lpDCB = new WinBase.DCB(); - // Here we test a com port that definitely does not exist! - HANDLE handleSerialPort = Kernel32.INSTANCE.CreateFile("\\\\.\\comDummy", - WinNT.GENERIC_READ | WinNT.GENERIC_WRITE, 0, null, WinNT.OPEN_EXISTING, WinNT.FILE_ATTRIBUTE_NORMAL, - null); - - int lastError = Kernel32.INSTANCE.GetLastError(); - assertEquals(lastError, WinNT.ERROR_FILE_NOT_FOUND); - // try to read the com port state using the invalid handle - assertFalse(Kernel32.INSTANCE.SetCommState(handleSerialPort, lpDCB)); - // Check if we can open a connection to com port1 - // If yes, we try to read the com state - // If no com port exists we have to skip this test - handleSerialPort = Kernel32.INSTANCE.CreateFile("\\\\.\\com1", WinNT.GENERIC_READ | WinNT.GENERIC_WRITE, 0, - null, WinNT.OPEN_EXISTING, WinNT.FILE_ATTRIBUTE_NORMAL, null); - lastError = Kernel32.INSTANCE.GetLastError(); - if (WinNT.NO_ERROR == lastError) { - assertFalse(WinNT.INVALID_HANDLE_VALUE.equals(handleSerialPort)); - try { - lpDCB = new WinBase.DCB(); - assertTrue(Kernel32.INSTANCE.GetCommState(handleSerialPort, lpDCB)); - DWORD oldBaudRate = new DWORD(lpDCB.BaudRate.longValue()); - - lpDCB.BaudRate = new DWORD(WinBase.CBR_110); - - assertTrue(Kernel32.INSTANCE.SetCommState(handleSerialPort, lpDCB)); - WinBase.DCB lpNewDCB = new WinBase.DCB(); - assertTrue(Kernel32.INSTANCE.GetCommState(handleSerialPort, lpNewDCB)); - - assertEquals(WinBase.CBR_110, lpNewDCB.BaudRate.intValue()); - - lpDCB.BaudRate = oldBaudRate; - assertTrue(Kernel32.INSTANCE.SetCommState(handleSerialPort, lpDCB)); - - } finally { - Kernel32.INSTANCE.CloseHandle(handleSerialPort); - } - } - } - - public void testGetCommTimeouts() { - WinBase.COMMTIMEOUTS lpCommTimeouts = new WinBase.COMMTIMEOUTS(); - - // Here we test a com port that definitely does not exist! - HANDLE handleSerialPort = Kernel32.INSTANCE.CreateFile("\\\\.\\comDummy", - WinNT.GENERIC_READ | WinNT.GENERIC_WRITE, 0, null, WinNT.OPEN_EXISTING, WinNT.FILE_ATTRIBUTE_NORMAL, - null); - - int lastError = Kernel32.INSTANCE.GetLastError(); - assertEquals(lastError, WinNT.ERROR_FILE_NOT_FOUND); - // try to read the com port timeouts using the invalid handle - assertFalse(Kernel32.INSTANCE.GetCommTimeouts(handleSerialPort, lpCommTimeouts)); - - // Check if we can open a connection to com port1 - // If yes, we try to read the com state - // If no com port exists we have to skip this test - handleSerialPort = Kernel32.INSTANCE.CreateFile("\\\\.\\com1", WinNT.GENERIC_READ | WinNT.GENERIC_WRITE, 0, - null, WinNT.OPEN_EXISTING, WinNT.FILE_ATTRIBUTE_NORMAL, null); - lastError = Kernel32.INSTANCE.GetLastError(); - if (WinNT.NO_ERROR == lastError) { - assertFalse(WinNT.INVALID_HANDLE_VALUE.equals(handleSerialPort)); - try { - lpCommTimeouts = new WinBase.COMMTIMEOUTS(); - assertTrue(Kernel32.INSTANCE.GetCommTimeouts(handleSerialPort, lpCommTimeouts)); - } finally { - Kernel32.INSTANCE.CloseHandle(handleSerialPort); - } - } - } - - public void testSetCommTimeouts() { - WinBase.COMMTIMEOUTS lpCommTimeouts = new WinBase.COMMTIMEOUTS(); - - // Here we test a com port that definitely does not exist! - HANDLE handleSerialPort = Kernel32.INSTANCE.CreateFile("\\\\.\\comDummy", - WinNT.GENERIC_READ | WinNT.GENERIC_WRITE, 0, null, WinNT.OPEN_EXISTING, WinNT.FILE_ATTRIBUTE_NORMAL, - null); - - int lastError = Kernel32.INSTANCE.GetLastError(); - assertEquals(lastError, WinNT.ERROR_FILE_NOT_FOUND); - // try to store the com port timeouts using the invalid handle - assertFalse(Kernel32.INSTANCE.SetCommTimeouts(handleSerialPort, lpCommTimeouts)); - - // Check if we can open a connection to com port1 - // If yes, we try to store the com timeouts - // If no com port exists we have to skip this test - handleSerialPort = Kernel32.INSTANCE.CreateFile("\\\\.\\com1", WinNT.GENERIC_READ | WinNT.GENERIC_WRITE, 0, - null, WinNT.OPEN_EXISTING, WinNT.FILE_ATTRIBUTE_NORMAL, null); - lastError = Kernel32.INSTANCE.GetLastError(); - if (WinNT.NO_ERROR == lastError) { - assertFalse(WinNT.INVALID_HANDLE_VALUE.equals(handleSerialPort)); - try { - lpCommTimeouts = new WinBase.COMMTIMEOUTS(); - assertTrue(Kernel32.INSTANCE.GetCommTimeouts(handleSerialPort, lpCommTimeouts)); - - DWORD oldReadIntervalTimeout = new DWORD(lpCommTimeouts.ReadIntervalTimeout.longValue()); - - lpCommTimeouts.ReadIntervalTimeout = new DWORD(20); - - assertTrue(Kernel32.INSTANCE.SetCommTimeouts(handleSerialPort, lpCommTimeouts)); - - WinBase.COMMTIMEOUTS lpNewCommTimeouts = new WinBase.COMMTIMEOUTS(); - assertTrue(Kernel32.INSTANCE.GetCommTimeouts(handleSerialPort, lpNewCommTimeouts)); - - assertEquals(20, lpNewCommTimeouts.ReadIntervalTimeout.intValue()); - - lpCommTimeouts.ReadIntervalTimeout = oldReadIntervalTimeout; - - assertTrue(Kernel32.INSTANCE.SetCommTimeouts(handleSerialPort, lpCommTimeouts)); - - } finally { - Kernel32.INSTANCE.CloseHandle(handleSerialPort); - } - } - } + + public void testGetCommState() { + WinBase.DCB lpDCB = new WinBase.DCB(); + // Here we test a com port that definitely does not exist! + HANDLE handleSerialPort = Kernel32.INSTANCE.CreateFile("\\\\.\\comDummy", + WinNT.GENERIC_READ | WinNT.GENERIC_WRITE, 0, null, WinNT.OPEN_EXISTING, WinNT.FILE_ATTRIBUTE_NORMAL, + null); + + int lastError = Kernel32.INSTANCE.GetLastError(); + assertEquals(lastError, WinNT.ERROR_FILE_NOT_FOUND); + //try to read the com port state using the invalid handle + assertFalse(Kernel32.INSTANCE.GetCommState(handleSerialPort, lpDCB)); + // Check if we can open a connection to com port1 + // If yes, we try to read the com state + // If no com port exists we have to skip this test + handleSerialPort = Kernel32.INSTANCE.CreateFile("\\\\.\\com1", WinNT.GENERIC_READ | WinNT.GENERIC_WRITE, 0, + null, WinNT.OPEN_EXISTING, WinNT.FILE_ATTRIBUTE_NORMAL, null); + lastError = Kernel32.INSTANCE.GetLastError(); + if (WinNT.NO_ERROR == lastError) { + assertFalse(WinNT.INVALID_HANDLE_VALUE.equals(handleSerialPort)); + try { + lpDCB = new WinBase.DCB(); + assertTrue(Kernel32.INSTANCE.GetCommState(handleSerialPort, lpDCB)); + switch (lpDCB.BaudRate.intValue()) { + case WinBase.CBR_110: + case WinBase.CBR_1200: + case WinBase.CBR_128000: + case WinBase.CBR_14400: + case WinBase.CBR_19200: + case WinBase.CBR_2400: + case WinBase.CBR_256000: + case WinBase.CBR_300: + case WinBase.CBR_38400: + case WinBase.CBR_4800: + case WinBase.CBR_56000: + case WinBase.CBR_600: + case WinBase.CBR_9600: + break; + default: + fail("Received value of WinBase.DCB.BaudRate is not valid"); + } + } finally { + Kernel32.INSTANCE.CloseHandle(handleSerialPort); + } + } + } + + public void testSetCommState() { + WinBase.DCB lpDCB = new WinBase.DCB(); + // Here we test a com port that definitely does not exist! + HANDLE handleSerialPort = Kernel32.INSTANCE.CreateFile("\\\\.\\comDummy", + WinNT.GENERIC_READ | WinNT.GENERIC_WRITE, 0, null, WinNT.OPEN_EXISTING, WinNT.FILE_ATTRIBUTE_NORMAL, + null); + + int lastError = Kernel32.INSTANCE.GetLastError(); + assertEquals(lastError, WinNT.ERROR_FILE_NOT_FOUND); + // try to read the com port state using the invalid handle + assertFalse(Kernel32.INSTANCE.SetCommState(handleSerialPort, lpDCB)); + // Check if we can open a connection to com port1 + // If yes, we try to read the com state + // If no com port exists we have to skip this test + handleSerialPort = Kernel32.INSTANCE.CreateFile("\\\\.\\com1", WinNT.GENERIC_READ | WinNT.GENERIC_WRITE, 0, + null, WinNT.OPEN_EXISTING, WinNT.FILE_ATTRIBUTE_NORMAL, null); + lastError = Kernel32.INSTANCE.GetLastError(); + if (WinNT.NO_ERROR == lastError) { + assertFalse(WinNT.INVALID_HANDLE_VALUE.equals(handleSerialPort)); + try { + lpDCB = new WinBase.DCB(); + assertTrue(Kernel32.INSTANCE.GetCommState(handleSerialPort, lpDCB)); + DWORD oldBaudRate = new DWORD(lpDCB.BaudRate.longValue()); + + lpDCB.BaudRate = new DWORD(WinBase.CBR_110); + + assertTrue(Kernel32.INSTANCE.SetCommState(handleSerialPort, lpDCB)); + WinBase.DCB lpNewDCB = new WinBase.DCB(); + assertTrue(Kernel32.INSTANCE.GetCommState(handleSerialPort, lpNewDCB)); + + assertEquals(WinBase.CBR_110, lpNewDCB.BaudRate.intValue()); + + lpDCB.BaudRate = oldBaudRate; + assertTrue(Kernel32.INSTANCE.SetCommState(handleSerialPort, lpDCB)); + + } finally { + Kernel32.INSTANCE.CloseHandle(handleSerialPort); + } + } + } + + public void testGetCommTimeouts() { + WinBase.COMMTIMEOUTS lpCommTimeouts = new WinBase.COMMTIMEOUTS(); + + // Here we test a com port that definitely does not exist! + HANDLE handleSerialPort = Kernel32.INSTANCE.CreateFile("\\\\.\\comDummy", + WinNT.GENERIC_READ | WinNT.GENERIC_WRITE, 0, null, WinNT.OPEN_EXISTING, WinNT.FILE_ATTRIBUTE_NORMAL, + null); + + int lastError = Kernel32.INSTANCE.GetLastError(); + assertEquals(lastError, WinNT.ERROR_FILE_NOT_FOUND); + // try to read the com port timeouts using the invalid handle + assertFalse(Kernel32.INSTANCE.GetCommTimeouts(handleSerialPort, lpCommTimeouts)); + + // Check if we can open a connection to com port1 + // If yes, we try to read the com state + // If no com port exists we have to skip this test + handleSerialPort = Kernel32.INSTANCE.CreateFile("\\\\.\\com1", WinNT.GENERIC_READ | WinNT.GENERIC_WRITE, 0, + null, WinNT.OPEN_EXISTING, WinNT.FILE_ATTRIBUTE_NORMAL, null); + lastError = Kernel32.INSTANCE.GetLastError(); + if (WinNT.NO_ERROR == lastError) { + assertFalse(WinNT.INVALID_HANDLE_VALUE.equals(handleSerialPort)); + try { + lpCommTimeouts = new WinBase.COMMTIMEOUTS(); + assertTrue(Kernel32.INSTANCE.GetCommTimeouts(handleSerialPort, lpCommTimeouts)); + } finally { + Kernel32.INSTANCE.CloseHandle(handleSerialPort); + } + } + } + + public void testSetCommTimeouts() { + WinBase.COMMTIMEOUTS lpCommTimeouts = new WinBase.COMMTIMEOUTS(); + + // Here we test a com port that definitely does not exist! + HANDLE handleSerialPort = Kernel32.INSTANCE.CreateFile("\\\\.\\comDummy", + WinNT.GENERIC_READ | WinNT.GENERIC_WRITE, 0, null, WinNT.OPEN_EXISTING, WinNT.FILE_ATTRIBUTE_NORMAL, + null); + + int lastError = Kernel32.INSTANCE.GetLastError(); + assertEquals(lastError, WinNT.ERROR_FILE_NOT_FOUND); + // try to store the com port timeouts using the invalid handle + assertFalse(Kernel32.INSTANCE.SetCommTimeouts(handleSerialPort, lpCommTimeouts)); + + // Check if we can open a connection to com port1 + // If yes, we try to store the com timeouts + // If no com port exists we have to skip this test + handleSerialPort = Kernel32.INSTANCE.CreateFile("\\\\.\\com1", WinNT.GENERIC_READ | WinNT.GENERIC_WRITE, 0, + null, WinNT.OPEN_EXISTING, WinNT.FILE_ATTRIBUTE_NORMAL, null); + lastError = Kernel32.INSTANCE.GetLastError(); + if (WinNT.NO_ERROR == lastError) { + assertFalse(WinNT.INVALID_HANDLE_VALUE.equals(handleSerialPort)); + try { + lpCommTimeouts = new WinBase.COMMTIMEOUTS(); + assertTrue(Kernel32.INSTANCE.GetCommTimeouts(handleSerialPort, lpCommTimeouts)); + + DWORD oldReadIntervalTimeout = new DWORD(lpCommTimeouts.ReadIntervalTimeout.longValue()); + + lpCommTimeouts.ReadIntervalTimeout = new DWORD(20); + + assertTrue(Kernel32.INSTANCE.SetCommTimeouts(handleSerialPort, lpCommTimeouts)); + + WinBase.COMMTIMEOUTS lpNewCommTimeouts = new WinBase.COMMTIMEOUTS(); + assertTrue(Kernel32.INSTANCE.GetCommTimeouts(handleSerialPort, lpNewCommTimeouts)); + + assertEquals(20, lpNewCommTimeouts.ReadIntervalTimeout.intValue()); + + lpCommTimeouts.ReadIntervalTimeout = oldReadIntervalTimeout; + + assertTrue(Kernel32.INSTANCE.SetCommTimeouts(handleSerialPort, lpCommTimeouts)); + + } finally { + Kernel32.INSTANCE.CloseHandle(handleSerialPort); + } + } + } + + public void testProcessIdToSessionId() { + int myProcessID = Kernel32.INSTANCE.GetCurrentProcessId(); + + IntByReference pSessionId = new IntByReference(); + boolean result = Kernel32.INSTANCE.ProcessIdToSessionId(myProcessID, pSessionId); + + // should give us our session ID + assertTrue("ProcessIdToSessionId should return true.", result); + + // on Win Vista and later we'll never be session 0 + // due to service isolation + // anything negative would be a definite error. + assertTrue("Session should be 1 or higher because of service isolation", pSessionId.getValue() > 0); + } + + public void testLoadLibraryEx() { + String winDir = Kernel32Util.getEnvironmentVariable("WINDIR"); + assertNotNull("No WINDIR value returned", winDir); + assertTrue("Specified WINDIR does not exist: " + winDir, new File(winDir).exists()); + + HMODULE hModule = null; + try { + hModule = Kernel32.INSTANCE.LoadLibraryEx(new File(winDir, "explorer.exe").getAbsolutePath(), null, + Kernel32.LOAD_LIBRARY_AS_DATAFILE); + if (hModule == null) { + throw new Win32Exception(Native.getLastError()); + } + assertNotNull("hModule should not be null.", hModule); + } finally { + if (hModule != null) { + if (!Kernel32.INSTANCE.FreeLibrary(hModule)) { + throw new Win32Exception(Native.getLastError()); + } + } + } + } + } diff --git a/contrib/platform/test/com/sun/jna/platform/win32/Kernel32UtilTest.java b/contrib/platform/test/com/sun/jna/platform/win32/Kernel32UtilTest.java index 523d183f2a..49b95cb8c4 100644 --- a/contrib/platform/test/com/sun/jna/platform/win32/Kernel32UtilTest.java +++ b/contrib/platform/test/com/sun/jna/platform/win32/Kernel32UtilTest.java @@ -1,14 +1,14 @@ /* Copyright (c) 2010, 2013 Daniel Doubrovkine, Markus Karg, 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 - * Lesser General Public License for more details. + * Lesser General Public License for more details. */ package com.sun.jna.platform.win32; @@ -30,111 +30,111 @@ * @author markus[at]headcrashing[dot]eu */ public class Kernel32UtilTest extends TestCase { - + public static void main(String[] args) throws Exception { System.out.println("Computer name: " + Kernel32Util.getComputerName()); System.out.println("Temp path: " + Kernel32Util.getTempPath()); // logical drives System.out.println("Logical drives: "); - Collection logicalDrives = Kernel32Util.getLogicalDriveStrings(); - for(String logicalDrive : logicalDrives) { - // drive type - System.out.println(" " + logicalDrive + " (" - + Kernel32.INSTANCE.GetDriveType(logicalDrive) + ")"); - // free space - LARGE_INTEGER.ByReference lpFreeBytesAvailable = new LARGE_INTEGER.ByReference(); - LARGE_INTEGER.ByReference lpTotalNumberOfBytes = new LARGE_INTEGER.ByReference(); - LARGE_INTEGER.ByReference lpTotalNumberOfFreeBytes = new LARGE_INTEGER.ByReference(); - if (Kernel32.INSTANCE.GetDiskFreeSpaceEx(logicalDrive, lpFreeBytesAvailable, lpTotalNumberOfBytes, lpTotalNumberOfFreeBytes)) { - System.out.println(" Total: " + formatBytes(lpTotalNumberOfBytes.getValue())); - System.out.println(" Free: " + formatBytes(lpTotalNumberOfFreeBytes.getValue())); - } - } - - junit.textui.TestRunner.run(Kernel32UtilTest.class); + Collection logicalDrives = Kernel32Util.getLogicalDriveStrings(); + for(String logicalDrive : logicalDrives) { + // drive type + System.out.println(" " + logicalDrive + " (" + + Kernel32.INSTANCE.GetDriveType(logicalDrive) + ")"); + // free space + LARGE_INTEGER.ByReference lpFreeBytesAvailable = new LARGE_INTEGER.ByReference(); + LARGE_INTEGER.ByReference lpTotalNumberOfBytes = new LARGE_INTEGER.ByReference(); + LARGE_INTEGER.ByReference lpTotalNumberOfFreeBytes = new LARGE_INTEGER.ByReference(); + if (Kernel32.INSTANCE.GetDiskFreeSpaceEx(logicalDrive, lpFreeBytesAvailable, lpTotalNumberOfBytes, lpTotalNumberOfFreeBytes)) { + System.out.println(" Total: " + formatBytes(lpTotalNumberOfBytes.getValue())); + System.out.println(" Free: " + formatBytes(lpTotalNumberOfFreeBytes.getValue())); + } + } + + junit.textui.TestRunner.run(Kernel32UtilTest.class); } - /** - * Format bytes. - * @param bytes - * Bytes. - * @return - * Rounded string representation of the byte size. - */ + /** + * Format bytes. + * @param bytes + * Bytes. + * @return + * Rounded string representation of the byte size. + */ private static String formatBytes(long bytes) { - if (bytes == 1) { // bytes - return String.format("%d byte", bytes); - } else if (bytes < 1024) { // bytes - return String.format("%d bytes", bytes); - } else if (bytes < 1048576 && bytes % 1024 == 0) { // Kb - return String.format("%.0f KB", (double) bytes / 1024); - } else if (bytes < 1048576) { // Kb - return String.format("%.1f KB", (double) bytes / 1024); - } else if (bytes % 1048576 == 0 && bytes < 1073741824) { // Mb - return String.format("%.0f MB", (double) bytes / 1048576); - } else if (bytes < 1073741824) { // Mb - return String.format("%.1f MB", (double) bytes / 1048576); - } else if (bytes % 1073741824 == 0 && bytes < 1099511627776L) { // GB - return String.format("%.0f GB", (double) bytes / 1073741824); - } else if (bytes < 1099511627776L ) { - return String.format("%.1f GB", (double) bytes / 1073741824); - } else if (bytes % 1099511627776L == 0 && bytes < 1125899906842624L) { // TB - return String.format("%.0f TB", (double) bytes / 1099511627776L); - } else if (bytes < 1125899906842624L ) { - return String.format("%.1f TB", (double) bytes / 1099511627776L); - } else { - return String.format("%d bytes", bytes); - } + if (bytes == 1) { // bytes + return String.format("%d byte", bytes); + } else if (bytes < 1024) { // bytes + return String.format("%d bytes", bytes); + } else if (bytes < 1048576 && bytes % 1024 == 0) { // Kb + return String.format("%.0f KB", (double) bytes / 1024); + } else if (bytes < 1048576) { // Kb + return String.format("%.1f KB", (double) bytes / 1024); + } else if (bytes % 1048576 == 0 && bytes < 1073741824) { // Mb + return String.format("%.0f MB", (double) bytes / 1048576); + } else if (bytes < 1073741824) { // Mb + return String.format("%.1f MB", (double) bytes / 1048576); + } else if (bytes % 1073741824 == 0 && bytes < 1099511627776L) { // GB + return String.format("%.0f GB", (double) bytes / 1073741824); + } else if (bytes < 1099511627776L ) { + return String.format("%.1f GB", (double) bytes / 1073741824); + } else if (bytes % 1099511627776L == 0 && bytes < 1125899906842624L) { // TB + return String.format("%.0f TB", (double) bytes / 1099511627776L); + } else if (bytes < 1125899906842624L ) { + return String.format("%.1f TB", (double) bytes / 1099511627776L); + } else { + return String.format("%d bytes", bytes); + } + } + + public void testGetComputerName() { + assertTrue(Kernel32Util.getComputerName().length() > 0); + } + + public void testFormatMessageFromLastErrorCode() { + assertEquals("The remote server has been paused or is in the process of being started.", + Kernel32Util.formatMessageFromLastErrorCode(W32Errors.ERROR_SHARING_PAUSED)); + } + + public void testFormatMessageFromHR() { + assertEquals("The operation completed successfully.", + Kernel32Util.formatMessage(W32Errors.S_OK)); + } + + public void testGetTempPath() { + assertTrue(Kernel32Util.getTempPath().length() > 0); + } + + public void testGetLogicalDriveStrings() { + Collection logicalDrives = Kernel32Util.getLogicalDriveStrings(); + assertTrue("No logical drives found", logicalDrives.size() > 0); + for(String logicalDrive : logicalDrives) { + assertTrue("Empty logical drive name in list", logicalDrive.length() > 0); + } + } + + public void testDeleteFile() throws IOException { + String filename = Kernel32Util.getTempPath() + "\\FileDoesNotExist.jna"; + File f = new File(filename); + f.createNewFile(); + Kernel32Util.deleteFile(filename); } - - public void testGetComputerName() { - assertTrue(Kernel32Util.getComputerName().length() > 0); - } - - public void testFormatMessageFromLastErrorCode() { - assertEquals("The remote server has been paused or is in the process of being started.", - Kernel32Util.formatMessageFromLastErrorCode(W32Errors.ERROR_SHARING_PAUSED)); - } - - public void testFormatMessageFromHR() { - assertEquals("The operation completed successfully.", - Kernel32Util.formatMessage(W32Errors.S_OK)); - } - - public void testGetTempPath() { - assertTrue(Kernel32Util.getTempPath().length() > 0); - } - - public void testGetLogicalDriveStrings() { - Collection logicalDrives = Kernel32Util.getLogicalDriveStrings(); - assertTrue("No logical drives found", logicalDrives.size() > 0); - for(String logicalDrive : logicalDrives) { - assertTrue("Empty logical drive name in list", logicalDrive.length() > 0); - } - } - - public void testDeleteFile() throws IOException { - String filename = Kernel32Util.getTempPath() + "\\FileDoesNotExist.jna"; - File f = new File(filename); - f.createNewFile(); - Kernel32Util.deleteFile(filename); - } - - public void testGetFileAttributes() throws IOException { - String filename = Kernel32Util.getTempPath(); - int fileAttributes = Kernel32Util.getFileAttributes(filename); - assertEquals(WinNT.FILE_ATTRIBUTE_DIRECTORY, fileAttributes & WinNT.FILE_ATTRIBUTE_DIRECTORY); - File tempFile = File.createTempFile("jna", "tmp"); - tempFile.deleteOnExit(); - int fileAttributes2 = Kernel32Util.getFileAttributes(tempFile.getAbsolutePath()); - tempFile.delete(); - assertEquals(0, fileAttributes2 & WinNT.FILE_ATTRIBUTE_DIRECTORY); - } - + + public void testGetFileAttributes() throws IOException { + String filename = Kernel32Util.getTempPath(); + int fileAttributes = Kernel32Util.getFileAttributes(filename); + assertEquals(WinNT.FILE_ATTRIBUTE_DIRECTORY, fileAttributes & WinNT.FILE_ATTRIBUTE_DIRECTORY); + File tempFile = File.createTempFile("jna", "tmp"); + tempFile.deleteOnExit(); + int fileAttributes2 = Kernel32Util.getFileAttributes(tempFile.getAbsolutePath()); + tempFile.delete(); + assertEquals(0, fileAttributes2 & WinNT.FILE_ATTRIBUTE_DIRECTORY); + } + public void testGetEnvironmentVariable() { - assertEquals(null, Kernel32Util.getEnvironmentVariable("jna-getenvironment-test")); - Kernel32.INSTANCE.SetEnvironmentVariable("jna-getenvironment-test", "42"); - assertEquals("42", Kernel32Util.getEnvironmentVariable("jna-getenvironment-test")); + assertEquals(null, Kernel32Util.getEnvironmentVariable("jna-getenvironment-test")); + Kernel32.INSTANCE.SetEnvironmentVariable("jna-getenvironment-test", "42"); + assertEquals("42", Kernel32Util.getEnvironmentVariable("jna-getenvironment-test")); } public final void testGetPrivateProfileInt() throws IOException { @@ -173,7 +173,7 @@ public final void testWritePrivateProfileString() throws IOException { Kernel32Util.writePrivateProfileString("Section", "existingKey", "DEF", tmp.getCanonicalPath()); Kernel32Util.writePrivateProfileString("Section", "addedKey", "GHI", tmp.getCanonicalPath()); Kernel32Util.writePrivateProfileString("Section", "removedKey", null, tmp.getCanonicalPath()); - + final BufferedReader reader = new BufferedReader(new FileReader(tmp)); assertEquals(reader.readLine(), "[Section]"); assertTrue(reader.readLine().matches("existingKey\\s*=\\s*DEF")); @@ -181,7 +181,7 @@ public final void testWritePrivateProfileString() throws IOException { assertEquals(reader.readLine(), null); reader.close(); } - + public final void testGetPrivateProfileSection() throws IOException { final File tmp = File.createTempFile("testGetPrivateProfileSection", ".ini"); tmp.deleteOnExit(); @@ -251,6 +251,19 @@ public final void testWritePrivateProfileSection() throws IOException { assertEquals(reader.readLine(), "foo=bar"); } finally { reader.close(); - } + } + } + + public void testGetResource() { + String winDir = Kernel32Util.getEnvironmentVariable("WINDIR"); + assertNotNull("No WINDIR value returned", winDir); + assertTrue("Specified WINDIR does not exist: " + winDir, new File(winDir).exists()); + + // On Windows 7, "14" is the type assigned to the "My Computer" icon + // (which is named "ICO_MYCOMPUTER") + byte[] results = Kernel32Util.getResource(new File(winDir, "explorer.exe").getAbsolutePath(), "14", + "ICO_MYCOMPUTER"); + assertNotNull("The 'ICO_MYCOMPUTER' resource in explorer.exe should have some content.", results); + assertTrue("The 'ICO_MYCOMPUTER' resource in explorer.exe should have some content.", results.length > 0); } }