diff --git a/CHANGES.md b/CHANGES.md index d162d61580..0b0048ab39 100755 --- a/CHANGES.md +++ b/CHANGES.md @@ -2,16 +2,40 @@ NOTE: as of JNA 4.0, JNA is now dual-licensed under LGPL and ASL (see LICENSE). NOTE: JNI native support is typically incompatible between minor versions, and almost always incompatible between major versions. +Next release +============ + +Features +-------- +* [#526](https://github.com/java-native-access/jna/pull/526): Added initialization and conversion between Windows SYSTEMTIME and Java Calendar [@lgoldstein](https://github.com/lgoldstein) +* [#532](https://github.com/java-native-access/jna/pull/529): Added `com.sun.jna.platform.win32.Mpr`, `com.sun.jna.platform.win32.LmShare`, and `com.sun.jna.platform.win32.Winnetwk` - [@amarcionek](https://github.com/amarcionek). +* [#532](https://github.com/java-native-access/jna/pull/529): Added `ACCESS_*` definitions to `com.sun.jna.platform.win32.LmAccess` - [@amarcionek](https://github.com/amarcionek). +* [#532](https://github.com/java-native-access/jna/pull/529): Added `NetShareAdd` and `NetShareDel` to `com.sun.jna.platform.win32.Netapi32` - [@amarcionek](https://github.com/amarcionek). +* [#535](https://github.com/java-native-access/jna/pull/535): Added `CreateProcessWithLogonW` to `com.sun.jna.platform.win32.Advapi32` - [@mlfreeman2](https://github.com/mlfreeman2). +* [#535](https://github.com/java-native-access/jna/pull/535): Added `CertAddEncodedCertificateToSystemStore` to `com.sun.jna.platform.win32.Crypt32` - [@mlfreeman2](https://github.com/mlfreeman2). +* [#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). +* [#545](https://github.com/java-native-access/jna/pull/545): Added `EnumResourceTypes` and `EnumResourceNames` to `com.sun.jna.platform.win32.Kernel32` - [@mlfreeman2](https://github.com/mlfreeman2). +* [#547](https://github.com/java-native-access/jna/pull/547): Added `GetSystemTimes` to `com.sun.jna.platform.win32.Kernel32` - [@dbwiddis](https://github.com/dbwiddis). +* [#548](https://github.com/java-native-access/jna/pull/548): Return 64-bit unsigned integer from `com.sun.jna.platform.win32.WinBase.FILETIME` - [@dbwiddis](https://github.com/dbwiddis). + +Bug Fixes +--------- + Release 4.2.1 ============= Features -------- -* [#504](https://github.com/java-native-access/jna/pull/504): Add support for linux-sparcv9 [@alexvsimon](https://github.com/alexvsimon). +* [#504](https://github.com/java-native-access/jna/pull/504): Add support for linux-sparcv9 - [@alexvsimon](https://github.com/alexvsimon). * [#510](https://github.com/java-native-access/jna/pull/510): Added `GetCommState`, `GetCommTimeouts` `SetCommState` and `SetCommTimeouts` to `com.sun.jna.platform.win32.Kernel32`. Added `DCB` structure to `com.sun.jna.platform.win32.WinBase` - [@MBollig](https://github.com/MBollig). * [#512](https://github.com/java-native-access/jna/pull/512): Make loading debug flags mutable [@lwahonen](https://github.com/lwahonen). * [#514](https://github.com/java-native-access/jna/pull/514): Added `host_processor_info` to `com.sun.jna.platform.mac.SystemB` - [@dbwiddis](https://github.com/dbwiddis). * [#519](https://github.com/java-native-access/jna/pull/519): Added JNA functional overview - [@twall](https://github.com/twall). +* [#523](https://github.com/java-native-access/jna/pull/): Add a convenience jar that contains all native dispatch libraries. If you want to hacking on JNA with an IDE, just include native-dispatch-libs.jar to your classpath and create a module from the JNA src directory. - [@lwahonen](https://github.com/lwahonen). +* [#524](https://github.com/java-native-access/jna/pull/524): Added IShellFolder interface plus necessary utility functions to Windows platform, and a sample for enumerating objects in My Computer - [@lwahonen](https://github.com/lwahonen). * [#528](https://github.com/java-native-access/jna/pull/528): Added idea-jar ant task that creates a convenience jar that contains all native dispatch libraries - [@lwahonen](https://github.com/lwahonen). Bug Fixes @@ -87,10 +111,10 @@ Bug Fixes * Remove unsupported JAWT from OSX build - [@twall](https://github.com/twall). * Disable WebStart tests - [@twall](https://github.com/twall). * Dispose all native resources when JNA's native library is unloaded - Paul Grütter, [@twall](https://github.com/twall). -* Weakly hold registered direct-mapped classes - [@twall](https://github.com/twall). +* Weakly hold registered direct-mapped classes - [@twall](https://github.com/twall). * [#382](https://github.com/java-native-access/jna/pull/382): Fixed memory allocation in `com.sun.jna.platform.win32.WTypes.LPWSTR` and `LPSTR` constructors - [@junak-michal](https://github.com/junak-michal). * Fix publish doc links - [@bhamail](https://github.com/bhamail). -* [#388](https://github.com/java-native-access/jna/issues/388): Ensure native library always opened with provided flags - [@zolyfarkas](https://github.com/zolyfarkas). +* [#388](https://github.com/java-native-access/jna/issues/388): Ensure native library always opened with provided flags - [@zolyfarkas](https://github.com/zolyfarkas). * [#403](https://github.com/java-native-access/jna/pull/403): Fix `com.sun.jna.platform.win32.COM.COMUtils.SUCCEEDED` and `FAILED` - [@lwahonen](https://github.com/lwahonen). * [#404](https://github.com/java-native-access/jna/pull/404): Fix `VARIANT` constructors for `int`, `short`, and `long` - [@lwahonen](https://github.com/lwahonen). * [#420](https://github.com/java-native-access/jna/pull/420): Fix structure leaving always one element in ThreadLocal set - [@sjappig](https://github.com/sjappig). diff --git a/build.xml b/build.xml index 6527b36154..8ece41f9bf 100644 --- a/build.xml +++ b/build.xml @@ -307,6 +307,7 @@ + @@ -520,7 +521,7 @@ osname=macosx;processor=x86;processor=x86-64;processor=ppc - + @@ -543,7 +544,7 @@ osname=macosx;processor=x86;processor=x86-64;processor=ppc - + @@ -977,7 +978,10 @@ osname=macosx;processor=x86;processor=x86-64;processor=ppc - + + + + @@ -1031,7 +1035,7 @@ osname=macosx;processor=x86;processor=x86-64;processor=ppc - + diff --git a/contrib/platform/build.xml b/contrib/platform/build.xml index 1658e1b44a..65fd1c1586 100644 --- a/contrib/platform/build.xml +++ b/contrib/platform/build.xml @@ -108,16 +108,17 @@ com.sun.jna.platform.wince Running platform tests: ${test.src.dir} - - - Saving test results in ${build.test.results.dir.abs} - + + + + Saving test results in ${results.junit} + - + - + @@ -151,23 +152,23 @@ com.sun.jna.platform.wince - + - + - - + + - + - + One or more tests failed diff --git a/contrib/platform/src/com/sun/jna/platform/WindowUtils.java b/contrib/platform/src/com/sun/jna/platform/WindowUtils.java index fc8894dc9f..798de335c6 100644 --- a/contrib/platform/src/com/sun/jna/platform/WindowUtils.java +++ b/contrib/platform/src/com/sun/jna/platform/WindowUtils.java @@ -83,8 +83,11 @@ import com.sun.jna.platform.win32.WinDef.HICON; import com.sun.jna.platform.win32.WinDef.HRGN; import com.sun.jna.platform.win32.WinDef.HWND; +import com.sun.jna.platform.win32.WinDef.LPARAM; +import com.sun.jna.platform.win32.WinDef.LRESULT; import com.sun.jna.platform.win32.WinDef.POINT; import com.sun.jna.platform.win32.WinDef.RECT; +import com.sun.jna.platform.win32.WinDef.WPARAM; import com.sun.jna.platform.win32.WinGDI; import com.sun.jna.platform.win32.WinGDI.BITMAP; import com.sun.jna.platform.win32.WinGDI.BITMAPINFO; @@ -1050,205 +1053,215 @@ public boolean outputRange(int x, int y, int w, int h) { setWindowRegion(w, region); } - @Override - public BufferedImage getWindowIcon(final HWND hwnd) { - // request different kind of icons if any solution fails - final DWORDByReference hIconNumber = new DWORDByReference(); - long result = User32.INSTANCE.SendMessageTimeout(hwnd, - WinUser.WM_GETICON, WinUser.ICON_BIG, 0, - WinUser.SMTO_ABORTIFHUNG, 500, hIconNumber); - if (result == 0) - result = User32.INSTANCE.SendMessageTimeout(hwnd, - WinUser.WM_GETICON, WinUser.ICON_SMALL, 0, - WinUser.SMTO_ABORTIFHUNG, 500, hIconNumber); - if (result == 0) - result = User32.INSTANCE.SendMessageTimeout(hwnd, - WinUser.WM_GETICON, WinUser.ICON_SMALL2, 0, - WinUser.SMTO_ABORTIFHUNG, 500, hIconNumber); - if (result == 0) { - result = User32.INSTANCE.GetClassLongPtr(hwnd, - WinUser.GCLP_HICON); - hIconNumber.getValue().setValue(result); - } - if (result == 0) { - result = User32.INSTANCE.GetClassLongPtr(hwnd, - WinUser.GCLP_HICONSM); - hIconNumber.getValue().setValue(result); - } - if (result == 0) - return null; - - // draw native icon into Java image - final HICON hIcon = new HICON(new Pointer(hIconNumber.getValue() - .longValue())); - final Dimension iconSize = getIconSize(hIcon); - if (iconSize.width == 0 || iconSize.height == 0) - return null; - - final int width = iconSize.width; - final int height = iconSize.height; - final short depth = 24; - - final byte[] lpBitsColor = new byte[width * height * depth / 8]; - final Pointer lpBitsColorPtr = new Memory(lpBitsColor.length); - final byte[] lpBitsMask = new byte[width * height * depth / 8]; - final Pointer lpBitsMaskPtr = new Memory(lpBitsMask.length); - final BITMAPINFO bitmapInfo = new BITMAPINFO(); - final BITMAPINFOHEADER hdr = new BITMAPINFOHEADER(); - - bitmapInfo.bmiHeader = hdr; - hdr.biWidth = width; - hdr.biHeight = height; - hdr.biPlanes = 1; - hdr.biBitCount = depth; - hdr.biCompression = 0; - hdr.write(); - bitmapInfo.write(); - - final HDC hDC = User32.INSTANCE.GetDC(null); - final ICONINFO iconInfo = new ICONINFO(); - User32.INSTANCE.GetIconInfo(hIcon, iconInfo); - iconInfo.read(); - GDI32.INSTANCE.GetDIBits(hDC, iconInfo.hbmColor, 0, height, - lpBitsColorPtr, bitmapInfo, 0); - lpBitsColorPtr.read(0, lpBitsColor, 0, lpBitsColor.length); - GDI32.INSTANCE.GetDIBits(hDC, iconInfo.hbmMask, 0, height, - lpBitsMaskPtr, bitmapInfo, 0); - lpBitsMaskPtr.read(0, lpBitsMask, 0, lpBitsMask.length); - final BufferedImage image = new BufferedImage(width, height, - BufferedImage.TYPE_INT_ARGB); - - int r, g, b, a, argb; - int x = 0, y = height - 1; - for (int i = 0; i < lpBitsColor.length; i = i + 3) { - b = lpBitsColor[i] & 0xFF; - g = lpBitsColor[i + 1] & 0xFF; - r = lpBitsColor[i + 2] & 0xFF; - a = 0xFF - lpBitsMask[i] & 0xFF; - argb = (a << 24) | (r << 16) | (g << 8) | b; - image.setRGB(x, y, argb); - x = (x + 1) % width; - if (x == 0) - y--; - } - - User32.INSTANCE.ReleaseDC(null, hDC); - - return image; - } - - @Override - public Dimension getIconSize(final HICON hIcon) { - final ICONINFO iconInfo = new ICONINFO(); - try { - if (!User32.INSTANCE.GetIconInfo(hIcon, iconInfo)) - return new Dimension(); - iconInfo.read(); - - final BITMAP bmp = new BITMAP(); - if (iconInfo.hbmColor != null - && iconInfo.hbmColor.getPointer() != Pointer.NULL) { - final int nWrittenBytes = GDI32.INSTANCE.GetObject( - iconInfo.hbmColor, bmp.size(), bmp.getPointer()); - bmp.read(); - if (nWrittenBytes > 0) - return new Dimension(bmp.bmWidth.intValue(), - bmp.bmHeight.intValue()); - } else if (iconInfo.hbmMask != null - && iconInfo.hbmMask.getPointer() != Pointer.NULL) { - final int nWrittenBytes = GDI32.INSTANCE.GetObject( - iconInfo.hbmMask, bmp.size(), bmp.getPointer()); - bmp.read(); - if (nWrittenBytes > 0) - return new Dimension(bmp.bmWidth.intValue(), bmp.bmHeight.intValue() / 2); - } - } finally { - if (iconInfo.hbmColor != null - && iconInfo.hbmColor.getPointer() != Pointer.NULL) - GDI32.INSTANCE.DeleteObject(iconInfo.hbmColor); - if (iconInfo.hbmMask != null - && iconInfo.hbmMask.getPointer() != Pointer.NULL) - GDI32.INSTANCE.DeleteObject(iconInfo.hbmMask); - } - - return new Dimension(); - } - - @Override - public List getAllWindows( - final boolean onlyVisibleWindows) { - final List result = new LinkedList(); - - final WNDENUMPROC lpEnumFunc = new WNDENUMPROC() { - @Override - public boolean callback(final HWND hwnd, final Pointer arg1) { - try { - final boolean visible = !onlyVisibleWindows - || User32.INSTANCE.IsWindowVisible(hwnd); - if (visible) { - final String title = getWindowTitle(hwnd); - final String filePath = getProcessFilePath(hwnd); - final Rectangle locAndSize = getWindowLocationAndSize(hwnd); - result.add(new DesktopWindow(hwnd, title, filePath, - locAndSize)); - } - } catch (final Exception e) { - e.printStackTrace(); - } - - return true; - } - }; - - if (!User32.INSTANCE.EnumWindows(lpEnumFunc, null)) - throw new Win32Exception(Kernel32.INSTANCE.GetLastError()); - - return result; - } - - @Override - public String getWindowTitle(final HWND hwnd) { - final int requiredLength = User32.INSTANCE - .GetWindowTextLength(hwnd) + 1; - final char[] title = new char[requiredLength]; - final int length = User32.INSTANCE.GetWindowText(hwnd, title, - title.length); - - return Native.toString(Arrays.copyOfRange(title, 0, length)); - } - - @Override - public String getProcessFilePath(final HWND hwnd) { - final char[] filePath = new char[1025]; - final IntByReference pid = new IntByReference(); - User32.INSTANCE.GetWindowThreadProcessId(hwnd, pid); - - final HANDLE process = Kernel32.INSTANCE.OpenProcess( - WinNT.PROCESS_QUERY_INFORMATION | WinNT.PROCESS_VM_READ, - false, pid.getValue()); - if (process == null - && Kernel32.INSTANCE.GetLastError() != WinNT.ERROR_ACCESS_DENIED) - throw new Win32Exception(Kernel32.INSTANCE.GetLastError()); - - final int length = Psapi.INSTANCE.GetModuleFileNameExW(process, - null, filePath, filePath.length); - if (length == 0 - && Kernel32.INSTANCE.GetLastError() != WinNT.ERROR_INVALID_HANDLE) - throw new Win32Exception(Kernel32.INSTANCE.GetLastError()); - - return Native.toString(filePath).trim(); - } - - @Override - public Rectangle getWindowLocationAndSize(final HWND hwnd) { - final RECT lpRect = new RECT(); - if (!User32.INSTANCE.GetWindowRect(hwnd, lpRect)) - throw new Win32Exception(Kernel32.INSTANCE.GetLastError()); - - return new Rectangle(lpRect.left, lpRect.top, Math.abs(lpRect.right - - lpRect.left), Math.abs(lpRect.bottom - lpRect.top)); - } - } + @Override + public BufferedImage getWindowIcon(final HWND hwnd) { + // request different kind of icons if any solution fails + final DWORDByReference hIconNumber = new DWORDByReference(); + LRESULT result = User32.INSTANCE + .SendMessageTimeout(hwnd, + WinUser.WM_GETICON, + new WPARAM(WinUser.ICON_BIG), + new LPARAM(0), + WinUser.SMTO_ABORTIFHUNG, 500, hIconNumber); + if (result.intValue() == 0) + result = User32.INSTANCE + .SendMessageTimeout(hwnd, + WinUser.WM_GETICON, + new WPARAM(WinUser.ICON_SMALL), + new LPARAM(0), + WinUser.SMTO_ABORTIFHUNG, 500, hIconNumber); + if (result.intValue() == 0) + result = User32.INSTANCE + .SendMessageTimeout(hwnd, + WinUser.WM_GETICON, + new WPARAM(WinUser.ICON_SMALL2), + new LPARAM(0), + WinUser.SMTO_ABORTIFHUNG, 500, hIconNumber); + if (result.intValue() == 0) { + result = new LRESULT(User32.INSTANCE + .GetClassLongPtr(hwnd, + WinUser.GCLP_HICON).intValue()); + hIconNumber.getValue().setValue(result.intValue()); + } + if (result.intValue() == 0) { + result = new LRESULT(User32.INSTANCE + .GetClassLongPtr(hwnd, + WinUser.GCLP_HICONSM).intValue()); + hIconNumber.getValue().setValue(result.intValue()); + } + if (result.intValue() == 0) + return null; + + // draw native icon into Java image + final HICON hIcon = new HICON(new Pointer(hIconNumber.getValue() + .longValue())); + final Dimension iconSize = getIconSize(hIcon); + if (iconSize.width == 0 || iconSize.height == 0) + return null; + + final int width = iconSize.width; + final int height = iconSize.height; + final short depth = 24; + + final byte[] lpBitsColor = new byte[width * height * depth / 8]; + final Pointer lpBitsColorPtr = new Memory(lpBitsColor.length); + final byte[] lpBitsMask = new byte[width * height * depth / 8]; + final Pointer lpBitsMaskPtr = new Memory(lpBitsMask.length); + final BITMAPINFO bitmapInfo = new BITMAPINFO(); + final BITMAPINFOHEADER hdr = new BITMAPINFOHEADER(); + + bitmapInfo.bmiHeader = hdr; + hdr.biWidth = width; + hdr.biHeight = height; + hdr.biPlanes = 1; + hdr.biBitCount = depth; + hdr.biCompression = 0; + hdr.write(); + bitmapInfo.write(); + + final HDC hDC = User32.INSTANCE.GetDC(null); + final ICONINFO iconInfo = new ICONINFO(); + User32.INSTANCE.GetIconInfo(hIcon, iconInfo); + iconInfo.read(); + GDI32.INSTANCE.GetDIBits(hDC, iconInfo.hbmColor, 0, height, + lpBitsColorPtr, bitmapInfo, 0); + lpBitsColorPtr.read(0, lpBitsColor, 0, lpBitsColor.length); + GDI32.INSTANCE.GetDIBits(hDC, iconInfo.hbmMask, 0, height, + lpBitsMaskPtr, bitmapInfo, 0); + lpBitsMaskPtr.read(0, lpBitsMask, 0, lpBitsMask.length); + final BufferedImage image = new BufferedImage(width, height, + BufferedImage.TYPE_INT_ARGB); + + int r, g, b, a, argb; + int x = 0, y = height - 1; + for (int i = 0; i < lpBitsColor.length; i = i + 3) { + b = lpBitsColor[i] & 0xFF; + g = lpBitsColor[i + 1] & 0xFF; + r = lpBitsColor[i + 2] & 0xFF; + a = 0xFF - lpBitsMask[i] & 0xFF; + argb = (a << 24) | (r << 16) | (g << 8) | b; + image.setRGB(x, y, argb); + x = (x + 1) % width; + if (x == 0) + y--; + } + + User32.INSTANCE.ReleaseDC(null, hDC); + + return image; + } + + @Override + public Dimension getIconSize(final HICON hIcon) { + final ICONINFO iconInfo = new ICONINFO(); + try { + if (!User32.INSTANCE.GetIconInfo(hIcon, iconInfo)) + return new Dimension(); + iconInfo.read(); + + final BITMAP bmp = new BITMAP(); + if (iconInfo.hbmColor != null + && iconInfo.hbmColor.getPointer() != Pointer.NULL) { + final int nWrittenBytes = GDI32.INSTANCE.GetObject( + iconInfo.hbmColor, bmp.size(), bmp.getPointer()); + bmp.read(); + if (nWrittenBytes > 0) + return new Dimension(bmp.bmWidth.intValue(), + bmp.bmHeight.intValue()); + } else if (iconInfo.hbmMask != null + && iconInfo.hbmMask.getPointer() != Pointer.NULL) { + final int nWrittenBytes = GDI32.INSTANCE.GetObject( + iconInfo.hbmMask, bmp.size(), bmp.getPointer()); + bmp.read(); + if (nWrittenBytes > 0) + return new Dimension(bmp.bmWidth.intValue(), bmp.bmHeight.intValue() / 2); + } + } finally { + if (iconInfo.hbmColor != null + && iconInfo.hbmColor.getPointer() != Pointer.NULL) + GDI32.INSTANCE.DeleteObject(iconInfo.hbmColor); + if (iconInfo.hbmMask != null + && iconInfo.hbmMask.getPointer() != Pointer.NULL) + GDI32.INSTANCE.DeleteObject(iconInfo.hbmMask); + } + + return new Dimension(); + } + + @Override + public List getAllWindows(final boolean onlyVisibleWindows) { + final List result = new LinkedList(); + + final WNDENUMPROC lpEnumFunc = new WNDENUMPROC() { + @Override + public boolean callback(final HWND hwnd, final Pointer arg1) { + try { + final boolean visible = !onlyVisibleWindows + || User32.INSTANCE.IsWindowVisible(hwnd); + if (visible) { + final String title = getWindowTitle(hwnd); + final String filePath = getProcessFilePath(hwnd); + final Rectangle locAndSize = getWindowLocationAndSize(hwnd); + result.add(new DesktopWindow(hwnd, title, filePath, + locAndSize)); + } + } catch (final Exception e) { + // FIXME properly handle whatever error is raised + e.printStackTrace(); + } + + return true; + } + }; + + if (!User32.INSTANCE.EnumWindows(lpEnumFunc, null)) + throw new Win32Exception(Kernel32.INSTANCE.GetLastError()); + + return result; + } + + @Override + public String getWindowTitle(final HWND hwnd) { + final int requiredLength = User32.INSTANCE + .GetWindowTextLength(hwnd) + 1; + final char[] title = new char[requiredLength]; + final int length = User32.INSTANCE.GetWindowText(hwnd, title, + title.length); + + return Native.toString(Arrays.copyOfRange(title, 0, length)); + } + + @Override + public String getProcessFilePath(final HWND hwnd) { + final char[] filePath = new char[2048]; + final IntByReference pid = new IntByReference(); + User32.INSTANCE.GetWindowThreadProcessId(hwnd, pid); + + final HANDLE process = Kernel32.INSTANCE.OpenProcess(WinNT.PROCESS_QUERY_INFORMATION | WinNT.PROCESS_VM_READ, + false, pid.getValue()); + if (process == null + && Kernel32.INSTANCE.GetLastError() != WinNT.ERROR_ACCESS_DENIED) { + throw new Win32Exception(Kernel32.INSTANCE.GetLastError()); + } + final int length = Psapi.INSTANCE.GetModuleFileNameExW(process, + null, filePath, filePath.length); + if (length == 0 + && Kernel32.INSTANCE.GetLastError() != WinNT.ERROR_INVALID_HANDLE) { + throw new Win32Exception(Kernel32.INSTANCE.GetLastError()); + } + return Native.toString(filePath).trim(); + } + + @Override + public Rectangle getWindowLocationAndSize(final HWND hwnd) { + final RECT lpRect = new RECT(); + if (!User32.INSTANCE.GetWindowRect(hwnd, lpRect)) + throw new Win32Exception(Kernel32.INSTANCE.GetLastError()); + + return new Rectangle(lpRect.left, lpRect.top, Math.abs(lpRect.right + - lpRect.left), Math.abs(lpRect.bottom - lpRect.top)); + } + } private static class MacWindowUtils extends NativeWindowUtils { public boolean isWindowAlphaSupported() { @@ -1497,6 +1510,7 @@ private static long getVisualID(GraphicsConfiguration config) { return ((Number)o).longValue(); } catch (Exception e) { + // FIXME properly handle this error e.printStackTrace(); return -1; } diff --git a/contrib/platform/src/com/sun/jna/platform/win32/Advapi32.java b/contrib/platform/src/com/sun/jna/platform/win32/Advapi32.java index 3ad52d0a21..7820917a74 100755 --- a/contrib/platform/src/com/sun/jna/platform/win32/Advapi32.java +++ b/contrib/platform/src/com/sun/jna/platform/win32/Advapi32.java @@ -17,8 +17,10 @@ import com.sun.jna.Structure; import com.sun.jna.WString; import com.sun.jna.platform.win32.WinBase.SECURITY_ATTRIBUTES; +import com.sun.jna.platform.win32.WinBase.STARTUPINFO; import com.sun.jna.platform.win32.WinBase.FE_EXPORT_FUNC; import com.sun.jna.platform.win32.WinBase.FE_IMPORT_FUNC; +import com.sun.jna.platform.win32.WinBase.PROCESS_INFORMATION; import com.sun.jna.platform.win32.WinNT.HANDLE; import com.sun.jna.platform.win32.WinNT.HANDLEByReference; import com.sun.jna.platform.win32.WinNT.PSID; @@ -48,7 +50,7 @@ */ public interface Advapi32 extends StdCallLibrary { Advapi32 INSTANCE = (Advapi32) Native.loadLibrary("Advapi32", - Advapi32.class, W32APIOptions.UNICODE_OPTIONS); + Advapi32.class, W32APIOptions.DEFAULT_OPTIONS); public static final int MAX_KEY_LENGTH = 255; public static final int MAX_VALUE_NAME = 16383; @@ -64,6 +66,36 @@ public interface Advapi32 extends StdCallLibrary { public static final int RRF_RT_REG_QWORD = 0x00000040; public static final int RRF_RT_REG_SZ = 0x00000002; + /** + * LOGON_WITH_PROFILE: 0x00000001
+ * Log on, then load the user profile in the HKEY_USERS registry key.
+ * The function returns after the profile is loaded.
+ * Loading the profile can be time-consuming, so it is best to use this + * value only if you must access the information in the HKEY_CURRENT_USER + * registry key.
+ * Windows Server 2003: The profile is unloaded after the new process is + * terminated, whether or not it has created child processes.
+ * Windows XP: The profile is unloaded after the new process and all child + * processes it has created are terminated.
+ */ + int LOGON_WITH_PROFILE = 0x00000001; + + /** + * LOGON_NETCREDENTIALS_ONLY: 0x00000002
+ * Log on, but use the specified credentials on the network only.
+ * The new process uses the same token as the caller, but the system creates + * a new logon session within LSA, and the process uses the specified + * credentials as the default credentials.
+ * This value can be used to create a process that uses a different set of + * credentials locally than it does remotely.
+ * This is useful in inter-domain scenarios where there is no trust + * relationship.
+ * The system does not validate the specified credentials.
+ * Therefore, the process can start, but it may not have access to network + * resources. + */ + int LOGON_NETCREDENTIALS_ONLY = 0x00000002; + /** * Retrieves the name of the user associated with the current thread. * http://msdn.microsoft.com/en-us/library/ms724432(VS.85).aspx @@ -1549,6 +1581,10 @@ public boolean LookupPrivilegeValue(String lpSystemName, String lpName, * otherwise, none of the descriptor is returned. * @return whether the call succeeded */ + public boolean GetFileSecurity(String lpFileName, + int RequestedInformation, Pointer pointer, int nLength, + IntByReference lpnLengthNeeded); + /** @deprecated Use the String version */ public boolean GetFileSecurity(WString lpFileName, int RequestedInformation, Pointer pointer, int nLength, IntByReference lpnLengthNeeded); @@ -1764,6 +1800,8 @@ public boolean AccessCheck(Pointer pSecurityDescriptor, * function fails, the return value is zero. To get extended error * information, call GetLastError. */ + public boolean EncryptFile(String lpFileName); + /** @deprecated Use the String version */ public boolean EncryptFile(WString lpFileName); /** @@ -1777,6 +1815,8 @@ public boolean AccessCheck(Pointer pSecurityDescriptor, * function fails, the return value is zero. To get extended error * information, call GetLastError. */ + public boolean DecryptFile(String lpFileName, DWORD dwReserved); + /** @deprecated Use the String version */ public boolean DecryptFile(WString lpFileName, DWORD dwReserved); /** @@ -1791,6 +1831,8 @@ public boolean AccessCheck(Pointer pSecurityDescriptor, * function fails, the return value is zero. To get extended error * information, call GetLastError. */ + public boolean FileEncryptionStatus(String lpFileName, DWORDByReference lpStatus); + /** @deprecated Use the String version */ public boolean FileEncryptionStatus(WString lpFileName, DWORDByReference lpStatus); /** @@ -1808,6 +1850,8 @@ public boolean AccessCheck(Pointer pSecurityDescriptor, * function fails, the return value is zero. To get extended error * information, call GetLastError. */ + public boolean EncryptionDisable(String DirPath, boolean Disable); + /** @deprecated Use the String version */ public boolean EncryptionDisable(WString DirPath, boolean Disable); /** @@ -1830,8 +1874,11 @@ public boolean AccessCheck(Pointer pSecurityDescriptor, * FormatMessage with the FORMAT_MESSAGE_FROM_SYSTEM flag to get a generic * text description of the error. */ + public int OpenEncryptedFileRaw(String lpFileName, ULONG ulFlags, + PointerByReference pvContext); + /** @deprecated Use the String version */ public int OpenEncryptedFileRaw(WString lpFileName, ULONG ulFlags, - PointerByReference pvContext); + PointerByReference pvContext); /** * Backs up (export) encrypted files. This is one of a group of Encrypted File @@ -1902,4 +1949,311 @@ public int WriteEncryptedFileRaw(FE_IMPORT_FUNC pfImportCallback, * OpenEncryptedFileRaw function returns the context block. */ public void CloseEncryptedFileRaw(Pointer pvContext); + + /** + * + BOOL WINAPI CreateProcessWithLogonW( + _In_ LPCWSTR lpUsername, + _In_opt_ LPCWSTR lpDomain, + _In_ LPCWSTR lpPassword, + _In_ DWORD dwLogonFlags, + _In_opt_ LPCWSTR lpApplicationName, + _Inout_opt_ LPWSTR lpCommandLine, + _In_ DWORD dwCreationFlags, + _In_opt_ LPVOID lpEnvironment, + _In_opt_ LPCWSTR lpCurrentDirectory, + _In_ LPSTARTUPINFOW lpStartupInfo, + _Out_ LPPROCESS_INFORMATION lpProcessInfo + ); + * + * + * @param lpUsername + * [in]
+ * The name of the user. This is the name of the user account to + * log on to.
+ * If you use the UPN format, user@DNS_domain_name, the lpDomain + * parameter must be NULL.
+ * The user account must have the Log On Locally permission on + * the local computer.
+ * This permission is granted to all users on workstations and + * servers, but only to administrators on domain controllers. + * @param lpDomain + * [in, optional]
+ * The name of the domain or server whose account database + * contains the lpUsername account.
+ * If this parameter is NULL, the user name must be specified in + * UPN format. + * @param lpPassword + * [in]
+ * The clear-text password for the lpUsername account. + * @param dwLogonFlags + * [in]
+ * The logon option. This parameter can be 0 (zero) or one of the + * following values.
+ * LOGON_WITH_PROFILE: 0x00000001
+ * Log on, then load the user profile in the HKEY_USERS registry + * key.
+ * The function returns after the profile is loaded.
+ * Loading the profile can be time-consuming, so it is best to + * use this value only if you must access the information in the + * HKEY_CURRENT_USER registry key.
+ * Windows Server 2003: The profile is unloaded after the new + * process is terminated, whether or not it has created child + * processes.
+ * Windows XP: The profile is unloaded after the new process and + * all child processes it has created are terminated.
+ *
+ * LOGON_NETCREDENTIALS_ONLY: 0x00000002
+ * Log on, but use the specified credentials on the network only. + *
+ * The new process uses the same token as the caller, but the + * system creates a new logon session within LSA, and the process + * uses the specified credentials as the default credentials. + *
+ * This value can be used to create a process that uses a + * different set of credentials locally than it does remotely. + *
+ * This is useful in inter-domain scenarios where there is no + * trust relationship.
+ * The system does not validate the specified credentials.
+ * Therefore, the process can start, but it may not have access + * to network resources. + * @param lpApplicationName + * [in, optional]
+ * The name of the module to be executed. This module can be a + * Windows-based application.
+ * It can be some other type of module (for example, MS-DOS or + * OS/2) if the appropriate subsystem is available on the local + * computer. The string can specify the full path and file name + * of the module to execute or it can specify a partial name. + *
+ * If it is a partial name, the function uses the current drive + * and current directory to complete the specification.
+ * The function does not use the search path. This parameter must + * include the file name extension; no default extension is + * assumed. The lpApplicationName parameter can be NULL, and the + * module name must be the first white space-delimited token in + * the lpCommandLine string.
+ * If you are using a long file name that contains a space, use + * quoted strings to indicate where the file name ends and the + * arguments begin; otherwise, the file name is ambiguous. For + * example, the following string can be interpreted in different + * ways:
+ * "c:\program files\sub dir\program name"
+ * The system tries to interpret the possibilities in the + * following order:
+ *
+ * c:\program.exe files\sub dir\program name
+ * c:\program files\sub.exe dir\program name
+ * c:\program files\sub dir\program.exe name
+ * c:\program files\sub dir\program name.exe
+ *
+ * If the executable module is a 16-bit application, + * lpApplicationName should be NULL, and the string pointed to by + * lpCommandLine should specify the executable module and its + * arguments. + * @param lpCommandLine + * [in, out, optional]
+ * The command line to be executed. The maximum length of this + * string is 1024 characters.
+ * If lpApplicationName is NULL, the module name portion of + * lpCommandLine is limited to MAX_PATH characters.
+ * The function can modify the contents of this string.
+ * Therefore, this parameter cannot be a pointer to read-only + * memory (such as a const variable or a literal string).
+ * If this parameter is a constant string, the function may cause + * an access violation.
+ * The lpCommandLine parameter can be NULL, and the function uses + * the string pointed to by lpApplicationNameas the command line. + *
+ *
+ * If both lpApplicationName and lpCommandLine are non-NULL, + * *lpApplicationName specifies the module to execute, and + * *lpCommandLine specifies the command line.
+ * The new process can use GetCommandLine to retrieve the entire + * command line.
+ * Console processes written in C can use the argc and argv + * arguments to parse the command line.
+ * Because argv[0] is the module name, C programmers typically + * repeat the module name as the first token in the command line. + *
+ * If lpApplicationName is NULL, the first white space-delimited + * token of the command line specifies the module name.
+ * If you are using a long file name that contains a space, use + * quoted strings to indicate where the file name ends and the + * arguments begin (see the explanation for the lpApplicationName + * parameter). If the file name does not contain an extension, + * .exe is appended. Therefore, if the file name extension is + * .com, this parameter must include the .com extension. If the + * file name ends in a period with no extension, or if the file + * name contains a path, .exe is not appended. If the file name + * does not contain a directory path, the system searches for the + * executable file in the following sequence:
+ *
+ * 1. The directory from which the application loaded.
+ * 2. The current directory for the parent process.
+ * 3. The 32-bit Windows system directory. Use the + * GetSystemDirectory function to get the path of this directory. + *
+ * 4. The 16-bit Windows system directory. There is no function + * that obtains the path of this directory, but it is searched. + *
+ * 5. The Windows directory. Use the GetWindowsDirectory function + * to get the path of this directory.
+ * 6. The directories that are listed in the PATH environment + * variable. Note that this function does not search the + * per-application path specified by the App Paths registry key. + * To include this per-application path in the search sequence, + * use the ShellExecute function.
+ *
+ * The system adds a null character to the command line string to + * separate the file name from the arguments. This divides the + * original string into two strings for internal processing.
+ * @param dwCreationFlags + * The flags that control how the process is created.
+ * The CREATE_DEFAULT_ERROR_MODE, CREATE_NEW_CONSOLE, and + * CREATE_NEW_PROCESS_GROUP flags are enabled by default.
+ * Even if you do not set the flag, the system functions as if it + * were set. You can specify additional flags as noted.
+ *
+ * CREATE_DEFAULT_ERROR_MODE: 0x04000000
+ * The new process does not inherit the error mode of the calling + * process.
+ * Instead, CreateProcessWithLogonW gives the new process the + * current default error mode.
+ * An application sets the current default error mode by calling + * SetErrorMode. This flag is enabled by default.
+ *
+ * CREATE_NEW_CONSOLE: 0x00000010
+ * The new process has a new console, instead of inheriting the + * parent's console. This flag cannot be used with the + * DETACHED_PROCESS flag.
+ * This flag is enabled by default.
+ *
+ * CREATE_NEW_PROCESS_GROUP: 0x00000200
+ * The new process is the root process of a new process group. + *
+ * The process group includes all processes that are descendants + * of this root process.
+ * The process identifier of the new process group is the same as + * the process identifier, which is returned in the lpProcessInfo + * parameter.
+ * Process groups are used by the GenerateConsoleCtrlEvent + * function to enable sending a CTRL+C or CTRL+BREAK signal to a + * group of console processes.
+ * This flag is enabled by default.
+ *
+ * CREATE_SEPARATE_WOW_VDM: 0x00000800
+ * This flag is only valid starting a 16-bit Windows-based + * application.
+ * If set, the new process runs in a private Virtual DOS Machine + * (VDM).
+ * By default, all 16-bit Windows-based applications run in a + * single, shared VDM.
+ * The advantage of running separately is that a crash only + * terminates the single VDM; any other programs running in + * distinct VDMs continue to function normally.
+ * Also, 16-bit Windows-based applications that run in separate + * VDMs have separate input queues, which means that if one + * application stops responding momentarily, applications in + * separate VDMs continue to receive input.
+ * CREATE_SUSPENDED: 0x00000004
+ * The primary thread of the new process is created in a + * suspended state, and does not run until the ResumeThread + * function is called.
+ *
+ * CREATE_UNICODE_ENVIRONMENT: 0x00000400
+ * Indicates the format of the lpEnvironment parameter.
+ * If this flag is set, the environment block pointed to by + * lpEnvironment uses Unicode characters.
+ * Otherwise, the environment block uses ANSI characters.
+ * EXTENDED_STARTUPINFO_PRESENT: 0x00080000
+ * The process is created with extended startup information; the + * lpStartupInfo parameter specifies a STARTUPINFOEX structure. + *
+ * Windows Server 2003 and Windows XP: This value is not + * supported.
+ * @param lpEnvironment + * [in, optional]
+ * A pointer to an environment block for the new process.
+ * If this parameter is NULL, the new process uses an environment + * created from the profile of the user specified by lpUsername. + * An environment block consists of a null-terminated block of + * null-terminated strings.
+ * Each string is in the following form:
+ * name=value
+ * Because the equal sign (=) is used as a separator, it must not + * be used in the name of an environment variable.
+ * An environment block can contain Unicode or ANSI characters. + *
+ * If the environment block pointed to by lpEnvironment contains + * Unicode characters, ensure that dwCreationFlags includes + * CREATE_UNICODE_ENVIRONMENT.
+ * If this parameter is NULL and the environment block of the + * parent process contains Unicode characters, you must also + * ensure that dwCreationFlags includes + * CREATE_UNICODE_ENVIRONMENT.
+ * An ANSI environment block is terminated by two 0 (zero) bytes: + * one for the last string and one more to terminate the block. + *
+ * A Unicode environment block is terminated by four zero bytes: + * two for the last string and two more to terminate the block. + *
+ * To retrieve a copy of the environment block for a specific + * user, use the CreateEnvironmentBlock function.
+ * @param lpCurrentDirectory + * [in, optional]
+ * The full path to the current directory for the process.
+ * The string can also specify a UNC path.
+ * If this parameter is NULL, the new process has the same + * current drive and directory as the calling process.
+ * This feature is provided primarily for shells that need to + * start an application, and specify its initial drive and + * working directory.
+ * @param lpStartupInfo + * [in]
+ * A pointer to a STARTUPINFO or STARTUPINFOEX structure.
+ * The application must add permission for the specified user + * account to the specified window station and desktop, even for + * WinSta0\Default.
+ * If the lpDesktop member is NULL or an empty string, the new + * process inherits the desktop and window station of its parent + * process.
+ * The application must add permission for the specified user + * account to the inherited window station and desktop.
+ * Windows XP: CreateProcessWithLogonW adds permission for the + * specified user account to the inherited window station and + * desktop.
+ * Handles in STARTUPINFO or STARTUPINFOEX must be closed with + * CloseHandle when they are no longer needed.
+ * Important If the dwFlags member of the STARTUPINFO structure + * specifies STARTF_USESTDHANDLES, the standard handle fields are + * copied unchanged to the child process without validation.
+ * The caller is responsible for ensuring that these fields + * contain valid handle values. Incorrect values can cause the + * child process to misbehave or crash.
+ * Use the Application Verifier runtime verification tool to + * detect invalid handles. + * @param lpProcessInfo + * [out]
+ * A pointer to a PROCESS_INFORMATION structure that receives + * identification information for the new process, including a + * handle to the process.
+ * Handles in PROCESS_INFORMATION must be closed with the + * CloseHandle function when they are not needed.
+ * @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.
+ * Note that the function returns before the process has finished + * initialization.
+ * If a required DLL cannot be located or fails to initialize, the + * process is terminated.
+ * To get the termination status of a process, call + * GetExitCodeProcess. + * @see MSDN + */ + boolean CreateProcessWithLogonW(String lpUsername, String lpDomain, String lpPassword, int dwLogonFlags, + String lpApplicationName, String lpCommandLine, int dwCreationFlags, Pointer lpEnvironment, + String lpCurrentDirectory, STARTUPINFO lpStartupInfo, PROCESS_INFORMATION lpProcessInfo); + } diff --git a/contrib/platform/src/com/sun/jna/platform/win32/Advapi32Util.java b/contrib/platform/src/com/sun/jna/platform/win32/Advapi32Util.java index 96065f65fa..871801746e 100755 --- a/contrib/platform/src/com/sun/jna/platform/win32/Advapi32Util.java +++ b/contrib/platform/src/com/sun/jna/platform/win32/Advapi32Util.java @@ -2032,8 +2032,8 @@ public static ACCESS_ACEStructure[] getFileSecurity(String fileName, repeat = false; memory = new Memory(nLength); IntByReference lpnSize = new IntByReference(); - boolean succeded = Advapi32.INSTANCE.GetFileSecurity(new WString( - fileName), infoType, memory, nLength, lpnSize); + boolean succeded = Advapi32.INSTANCE.GetFileSecurity( + fileName, infoType, memory, nLength, lpnSize); if (!succeded) { int lastError = Kernel32.INSTANCE.GetLastError(); @@ -2100,7 +2100,7 @@ private static Memory getSecurityDescriptorForFile(final String absoluteFilePath final IntByReference lpnSize = new IntByReference(); boolean succeeded = Advapi32.INSTANCE.GetFileSecurity( - new WString(absoluteFilePath), + absoluteFilePath, infoType, null, 0, lpnSize); @@ -2114,8 +2114,8 @@ private static Memory getSecurityDescriptorForFile(final String absoluteFilePath final int nLength = lpnSize.getValue(); final Memory securityDescriptorMemoryPointer = new Memory(nLength); - succeeded = Advapi32.INSTANCE.GetFileSecurity(new WString( - absoluteFilePath), infoType, securityDescriptorMemoryPointer, nLength, lpnSize); + succeeded = Advapi32.INSTANCE.GetFileSecurity( + absoluteFilePath, infoType, securityDescriptorMemoryPointer, nLength, lpnSize); if (!succeeded) { securityDescriptorMemoryPointer.clear(); @@ -2407,7 +2407,7 @@ public static void setFileSecurityDescriptor( * The file or directory to encrypt. */ public static void encryptFile(File file) { - WString lpFileName = new WString(file.getAbsolutePath()); + String lpFileName = file.getAbsolutePath(); if (!Advapi32.INSTANCE.EncryptFile(lpFileName)) { throw new Win32Exception(Kernel32.INSTANCE.GetLastError()); } @@ -2420,7 +2420,7 @@ public static void encryptFile(File file) { * The file or directory to decrypt. */ public static void decryptFile(File file) { - WString lpFileName = new WString(file.getAbsolutePath()); + String lpFileName = file.getAbsolutePath(); if (!Advapi32.INSTANCE.DecryptFile(lpFileName, new DWORD(0))) { throw new Win32Exception(Kernel32.INSTANCE.GetLastError()); } @@ -2435,7 +2435,7 @@ public static void decryptFile(File file) { */ public static int fileEncryptionStatus(File file) { DWORDByReference status = new DWORDByReference(); - WString lpFileName = new WString(file.getAbsolutePath()); + String lpFileName = file.getAbsolutePath(); if (!Advapi32.INSTANCE.FileEncryptionStatus(lpFileName, status)) { throw new Win32Exception(Kernel32.INSTANCE.GetLastError()); } @@ -2452,7 +2452,7 @@ public static int fileEncryptionStatus(File file) { * TRUE to disable encryption. FALSE to enable it. */ public static void disableEncryption(File directory, boolean disable) { - WString dirPath = new WString(directory.getAbsolutePath()); + String dirPath = directory.getAbsolutePath(); if (!Advapi32.INSTANCE.EncryptionDisable(dirPath, disable)) { throw new Win32Exception(Native.getLastError()); } @@ -2484,7 +2484,7 @@ public static void backupEncryptedFile(File src, File destDir) { } // open encrypted file for export - WString srcFileName = new WString(src.getAbsolutePath()); + String srcFileName = src.getAbsolutePath(); PointerByReference pvContext = new PointerByReference(); if (Advapi32.INSTANCE.OpenEncryptedFileRaw(srcFileName, readFlag, pvContext) != W32Errors.ERROR_SUCCESS) { @@ -2495,9 +2495,9 @@ public static void backupEncryptedFile(File src, File destDir) { final ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); FE_EXPORT_FUNC pfExportCallback = new FE_EXPORT_FUNC() { @Override - public DWORD callback(ByteByReference pbData, Pointer pvCallbackContext, + public DWORD callback(Pointer pbData, Pointer pvCallbackContext, ULONG ulLength) { - byte[] arr = pbData.getPointer().getByteArray(0, ulLength.intValue()); + byte[] arr = pbData.getByteArray(0, ulLength.intValue()); try { outputStream.write(arr); } catch (IOException e) { @@ -2521,8 +2521,8 @@ public DWORD callback(ByteByReference pbData, Pointer pvCallbackContext, Advapi32.INSTANCE.CloseEncryptedFileRaw(pvContext.getValue()); // open file for import - WString destFileName = new WString(destDir.getAbsolutePath() + File.separator - + src.getName()); + String destFileName = destDir.getAbsolutePath() + File.separator + + src.getName(); pvContext = new PointerByReference(); if (Advapi32.INSTANCE.OpenEncryptedFileRaw(destFileName, writeFlag, pvContext) != W32Errors.ERROR_SUCCESS) { @@ -2533,12 +2533,12 @@ public DWORD callback(ByteByReference pbData, Pointer pvCallbackContext, final IntByReference elementsReadWrapper = new IntByReference(0); FE_IMPORT_FUNC pfImportCallback = new FE_IMPORT_FUNC() { @Override - public DWORD callback(ByteByReference pbData, Pointer pvCallbackContext, + public DWORD callback(Pointer pbData, Pointer pvCallbackContext, ULONGByReference ulLength) { int elementsRead = elementsReadWrapper.getValue(); int remainingElements = outputStream.size() - elementsRead; int length = Math.min(remainingElements, ulLength.getValue().intValue()); - pbData.getPointer().write(0, outputStream.toByteArray(), elementsRead, + pbData.write(0, outputStream.toByteArray(), elementsRead, length); elementsReadWrapper.setValue(elementsRead + length); ulLength.setValue(new ULONG(length)); diff --git a/contrib/platform/src/com/sun/jna/platform/win32/BaseTSD.java b/contrib/platform/src/com/sun/jna/platform/win32/BaseTSD.java index a2475f8d8b..e17f05cd58 100644 --- a/contrib/platform/src/com/sun/jna/platform/win32/BaseTSD.java +++ b/contrib/platform/src/com/sun/jna/platform/win32/BaseTSD.java @@ -15,18 +15,18 @@ import com.sun.jna.IntegerType; import com.sun.jna.Pointer; import com.sun.jna.ptr.ByReference; -import com.sun.jna.win32.StdCallLibrary; /** * Based on basetsd.h (various types) * @author dblock[at]dblock[dot]org */ @SuppressWarnings("serial") -public interface BaseTSD extends StdCallLibrary { +public interface BaseTSD { + /** -* Signed long type for pointer precision. -* Use when casting a pointer to a long to perform pointer arithmetic. -*/ + * Signed long type for pointer precision. + * Use when casting a pointer to a long to perform pointer arithmetic. + */ public static class LONG_PTR extends IntegerType { public LONG_PTR() { this(0); @@ -124,4 +124,4 @@ public SIZE_T(long value) { super(value); } } -} \ No newline at end of file +} diff --git a/contrib/platform/src/com/sun/jna/platform/win32/COM/IEnumIDList.java b/contrib/platform/src/com/sun/jna/platform/win32/COM/IEnumIDList.java new file mode 100644 index 0000000000..7887816a35 --- /dev/null +++ b/contrib/platform/src/com/sun/jna/platform/win32/COM/IEnumIDList.java @@ -0,0 +1,229 @@ +package com.sun.jna.platform.win32.COM; + +/* + * @author L W Ahonen, lwahonen@iki.fi + */ + +import com.sun.jna.Function; +import com.sun.jna.Pointer; +import com.sun.jna.platform.win32.Guid; +import com.sun.jna.platform.win32.Guid.IID; +import com.sun.jna.platform.win32.Guid.REFIID; +import com.sun.jna.platform.win32.WinDef; +import com.sun.jna.platform.win32.WinNT; +import com.sun.jna.platform.win32.WinNT.HRESULT; +import com.sun.jna.ptr.IntByReference; +import com.sun.jna.ptr.PointerByReference; + +public interface IEnumIDList { + + /** + * The interface IID for QueryInterface et al + */ + public final static IID IID_IEnumIDList = new IID( + "{000214F2-0000-0000-C000-000000000046}"); + + /** + * + * Retrieves pointers to the supported interfaces on an object. + * This method calls IUnknown::AddRef on the pointer it returns. + * + * @param riid + * The identifier of the interface being requested. + * + * @param ppvObject + * The address of a pointer variable that receives the interface pointer requested in the riid parameter. Upon successful + * return, *ppvObject contains the requested interface pointer to the object. If the object does not support the + * interface, *ppvObject is set to NULL. + * + * @return + * This method returns S_OK if the interface is supported, and E_NOINTERFACE otherwise. If ppvObject is NULL, this method returns E_POINTER. + * For any one object, a specific query for the IUnknown interface on any of the object's interfaces must always return the same pointer value. + * This enables a client to determine whether two pointers point to the same component by calling QueryInterfacewith IID_IUnknown + * and comparing the results. It is specifically not the case that queries for interfaces other than IUnknown (even the same interface + * through the same pointer) must return the same pointer value. + * + * There are four requirements for implementations of QueryInterface (In these cases, "must succeed" means "must succeed barring + * catastrophic failure."): + * The set of interfaces accessible on an object through QueryInterface must be static, not dynamic. This means that if a call + * toQueryInterface for a pointer to a specified interface succeeds the first time, it must succeed again, and if it fails + * the first time, it must fail on all subsequent queries.
 + * + * It must be reflexive: if a client holds a pointer to an interface on an object, and queries for that interface, the call must succeed.
 + * + * It must be symmetric: if a client holding a pointer to one interface queries successfully for another, a query through + * the obtained pointer for the first interface must succeed.
 + * + * It must be transitive: if a client holding a pointer to one interface queries successfully for a second, and through that + * pointer queries successfully for a third interface, a query for the first interface through the pointer for the + * third interface must succeed.
 + * Notes to Implementers + * Implementations of QueryInterface must never check ACLs. The main reason for this rule is that COM requires that an object supporting a + * particular interface always return success when queried for that interface. Another reason is that checking ACLs on QueryInterface + * does not provide any real security because any client who has access to a particular interface can hand it directly to another + * client without any calls back to the server. Also, because COM caches interface pointers, it does not callQueryInterface on + * the server every time a client does a query. + */ + HRESULT QueryInterface( + REFIID riid, + PointerByReference ppvObject); + + /** + * + * Increments the reference count for an interface on an object. This method should be called for every new copy of a pointer to an interface on an object. + * @return + * The method returns the new reference count. This value is intended to be used only for test purposes. + * + * Objects use a reference counting mechanism to ensure that the lifetime of the object includes the lifetime of references to it. You use AddRef + * to stabilize a copy of an interface pointer. It can also be called when the life of a cloned pointer must extend beyond the + * lifetime of the original pointer. The cloned pointer must be released by calling IUnknown::Release. + * + * The internal reference counter that AddRef maintains should be a 32-bit unsigned integer. + * Notes to Callers + * Call this method for every new copy of an interface pointer that you make. For example, if you are passing a copy of a pointer + * back from a method, you must call AddRef on that pointer. You must also call AddRef on a pointer before passing it as an in-out + * parameter to a method; the method will call IUnknown::Release before copying the out-value on top of it. + */ + int AddRef(); + + /** + * Decrements the reference count for an interface on an object. + * + * @return + * The method returns the new reference count. This value is intended to be used only for test purposes. + * + * When the reference count on an object reaches zero, Release must cause the interface pointer to free itself. When the released + * pointer is the only existing reference to an object (whether the object supports single or multiple interfaces), the + * implementation must free the object. + * + * Note that aggregation of objects restricts the ability to recover interface pointers. + * Notes to Callers + * Call this method when you no longer need to use an interface pointer. If you are writing a method that takes an in-out + * parameter, call Release on the pointer you are passing in before copying the out-value on top of it. + */ + int Release(); + + /* + Retrieves the specified number of item identifiers in the enumeration sequence and advances the current position by the number of items retrieved. + * @param celt + * The number of elements in the array referenced by the rgelt parameter. + * @param rgelt + * The address of a pointer to an array of ITEMIDLIST pointers that receive the item identifiers. + * The implementation must allocate these item identifiers using CoTaskMemAlloc. + * The calling application is responsible for freeing the item identifiers using CoTaskMemFree. + * The ITEMIDLIST structures returned in the array are relative to the IShellFolder being enumerated. + * @param pceltFetched + * A pointer to a value that receives a count of the item identifiers actually returned in rgelt. + * The count can be smaller than the value specified in the celt parameter. This parameter can be NULL on entry only if celt = 1, + * because in that case the method can only retrieve one (S_OK) or zero (S_FALSE) items. + * + * @return HRESULT + * Returns S_OK if the method successfully retrieved the requested celt elements. + * This method only returns S_OK if the full count of requested items are successfully retrieved. + * S_FALSE indicates that more items were requested than remained in the enumeration. + * The value pointed to by the pceltFetched parameter specifies the actual number of items retrieved. + * Note that the value will be 0 if there are no more items to retrieve. + * Returns a COM-defined error value otherwise. + * + * If this method returns a Component Object Model (COM) error code (as determined by the COMUtils.FAILED macro), + * then no entries in the rgelt array are valid on exit. If this method returns a success code (such as S_OK or S_FALSE), + * then the ULONG pointed to by the pceltFetched parameter determines how many entries in the rgelt array are valid on exit. + * + * The distinction is important in the case where celt > 1. For example, if you pass celt=10 and there are only 3 elements left, + * *pceltFetched will be 3 and the method will return S_FALSE meaning that you reached the end of the file. + * The three fetched elements will be stored into rgelt and are valid. + */ + HRESULT Next( + int celt, + PointerByReference rgelt, + IntByReference pceltFetched); + + /** + * Skips the specified number of elements in the enumeration sequence. + * @param celt + * The number of item identifiers to skip. + * @return HRESULT + * Returns S_OK if successful, or a COM-defined error value otherwise. + */ + HRESULT Skip( + int celt); + + /** + * Returns to the beginning of the enumeration sequence. + * @return HRESULT + * Returns S_OK if successful, or a COM-defined error value otherwise. + */ + + HRESULT Reset(); + + /** + * Creates a new item enumeration object with the same contents and state as the current one. + * @param ppenum + * The address of a pointer to the new enumeration object. The calling application must eventually free the new object by calling its Release member function. + * @return HRESULT + * Returns S_OK if successful, or a COM-defined error value otherwise. + */ + HRESULT Clone( + PointerByReference ppenum); + + + /* + Use this like: + + PointerByReference pbr=new PointerByReference(); + HRESULT result=SomeCOMObject.QueryInterface(IID_IEnumIDList, pbr); + if(COMUtils.SUCCEEDED(result)) IENumIDList eil=IEnumIDList.Converter.PointerToIEnumIDList(pbr); + + */ + public static class Converter { + public static IEnumIDList PointerToIEnumIDList(final PointerByReference ptr) { + final Pointer interfacePointer = ptr.getValue(); + final Pointer vTablePointer = interfacePointer.getPointer(0); + final Pointer[] vTable = new Pointer[7]; + vTablePointer.read(0, vTable, 0, 7); + return new IEnumIDList() { + + @Override + public WinNT.HRESULT QueryInterface(REFIID byValue, PointerByReference pointerByReference) { + Function f = Function.getFunction(vTable[0], Function.ALT_CONVENTION); + return new WinNT.HRESULT(f.invokeInt(new Object[]{interfacePointer, byValue, pointerByReference})); + } + + @Override + public int AddRef() { + Function f = Function.getFunction(vTable[1], Function.ALT_CONVENTION); + return f.invokeInt(new Object[]{interfacePointer}); + } + + public int Release() { + Function f = Function.getFunction(vTable[2], Function.ALT_CONVENTION); + return f.invokeInt(new Object[]{interfacePointer}); + } + + @Override + public HRESULT Next(int celt, PointerByReference rgelt, IntByReference pceltFetched) { + Function f = Function.getFunction(vTable[3], Function.ALT_CONVENTION); + return new HRESULT(f.invokeInt(new Object[]{interfacePointer, celt, rgelt, pceltFetched})); + } + + @Override + public HRESULT Skip(int celt) { + Function f = Function.getFunction(vTable[4], Function.ALT_CONVENTION); + return new HRESULT(f.invokeInt(new Object[]{interfacePointer, celt})); + } + + @Override + public HRESULT Reset() { + Function f = Function.getFunction(vTable[5], Function.ALT_CONVENTION); + return new HRESULT(f.invokeInt(new Object[]{interfacePointer})); + } + + @Override + public HRESULT Clone(PointerByReference ppenum) { + Function f = Function.getFunction(vTable[6], Function.ALT_CONVENTION); + return new HRESULT(f.invokeInt(new Object[]{interfacePointer, ppenum})); + } + }; + } + } +} diff --git a/contrib/platform/src/com/sun/jna/platform/win32/COM/IShellFolder.java b/contrib/platform/src/com/sun/jna/platform/win32/COM/IShellFolder.java new file mode 100644 index 0000000000..4464eaa9de --- /dev/null +++ b/contrib/platform/src/com/sun/jna/platform/win32/COM/IShellFolder.java @@ -0,0 +1,518 @@ +package com.sun.jna.platform.win32.COM; + +/* + * @author L W Ahonen, lwahonen@iki.fi + */ + +import com.sun.jna.Function; +import com.sun.jna.Pointer; +import com.sun.jna.platform.win32.Guid; +import com.sun.jna.platform.win32.Guid.IID; +import com.sun.jna.platform.win32.Guid.REFIID; +import com.sun.jna.platform.win32.WinDef; +import com.sun.jna.platform.win32.WinNT; +import com.sun.jna.platform.win32.WinNT.HRESULT; +import com.sun.jna.ptr.IntByReference; +import com.sun.jna.ptr.PointerByReference; + +public interface IShellFolder { + + + /** + * The interface IID for QueryInterface et al + */ + public final static IID IID_ISHELLFOLDER = new IID( + "{000214E6-0000-0000-C000-000000000046}"); + + /** + * + * Retrieves pointers to the supported interfaces on an object. + * This method calls IUnknown::AddRef on the pointer it returns. + * + * @param riid + * The identifier of the interface being requested. + * + * @param ppvObject + * The address of a pointer variable that receives the interface pointer requested in the riid parameter. Upon successful + * return, *ppvObject contains the requested interface pointer to the object. If the object does not support the + * interface, *ppvObject is set to NULL. + * + * @return + * This method returns S_OK if the interface is supported, and E_NOINTERFACE otherwise. If ppvObject is NULL, this method returns E_POINTER. + * For any one object, a specific query for the IUnknown interface on any of the object's interfaces must always return the same pointer value. + * This enables a client to determine whether two pointers point to the same component by calling QueryInterfacewith IID_IUnknown + * and comparing the results. It is specifically not the case that queries for interfaces other than IUnknown (even the same interface + * through the same pointer) must return the same pointer value. + * + * There are four requirements for implementations of QueryInterface (In these cases, "must succeed" means "must succeed barring + * catastrophic failure."): + * The set of interfaces accessible on an object through QueryInterface must be static, not dynamic. This means that if a call + * toQueryInterface for a pointer to a specified interface succeeds the first time, it must succeed again, and if it fails + * the first time, it must fail on all subsequent queries.
 + * + * It must be reflexive: if a client holds a pointer to an interface on an object, and queries for that interface, the call must succeed.
 + * + * It must be symmetric: if a client holding a pointer to one interface queries successfully for another, a query through + * the obtained pointer for the first interface must succeed.
 + * + * It must be transitive: if a client holding a pointer to one interface queries successfully for a second, and through that + * pointer queries successfully for a third interface, a query for the first interface through the pointer for the + * third interface must succeed.
 + * Notes to Implementers + * Implementations of QueryInterface must never check ACLs. The main reason for this rule is that COM requires that an object supporting a + * particular interface always return success when queried for that interface. Another reason is that checking ACLs on QueryInterface + * does not provide any real security because any client who has access to a particular interface can hand it directly to another + * client without any calls back to the server. Also, because COM caches interface pointers, it does not callQueryInterface on + * the server every time a client does a query. + */ + HRESULT QueryInterface( + REFIID riid, + PointerByReference ppvObject); + + /** + * + * Increments the reference count for an interface on an object. This method should be called for every new copy of a pointer to an interface on an object. + * @return + * The method returns the new reference count. This value is intended to be used only for test purposes. + * + * Objects use a reference counting mechanism to ensure that the lifetime of the object includes the lifetime of references to it. You use AddRef + * to stabilize a copy of an interface pointer. It can also be called when the life of a cloned pointer must extend beyond the + * lifetime of the original pointer. The cloned pointer must be released by calling IUnknown::Release. + * + * The internal reference counter that AddRef maintains should be a 32-bit unsigned integer. + * Notes to Callers + * Call this method for every new copy of an interface pointer that you make. For example, if you are passing a copy of a pointer + * back from a method, you must call AddRef on that pointer. You must also call AddRef on a pointer before passing it as an in-out + * parameter to a method; the method will call IUnknown::Release before copying the out-value on top of it. + */ + int AddRef(); + + /** + * Decrements the reference count for an interface on an object. + * + * @return + * The method returns the new reference count. This value is intended to be used only for test purposes. + * + * When the reference count on an object reaches zero, Release must cause the interface pointer to free itself. When the released + * pointer is the only existing reference to an object (whether the object supports single or multiple interfaces), the + * implementation must free the object. + * + * Note that aggregation of objects restricts the ability to recover interface pointers. + * Notes to Callers + * Call this method when you no longer need to use an interface pointer. If you are writing a method that takes an in-out + * parameter, call Release on the pointer you are passing in before copying the out-value on top of it. + */ + int Release(); + + /** + * Translates the display name of a file object or a folder into an item identifier list + * + * @param hwnd + * A window handle. The client should provide a window handle if it displays a dialog or message box. Otherwise set hwnd to NULL. + * + * @param pbc + * Optional. A pointer to a bind context used to pass parameters as inputs and outputs to the parsing function. These passed parameters + * are often specific to the data source and are documented by the data source owners. For example, the file system data source accepts + * the name being parsed (as a WIN32_FIND_DATA structure), using the STR_FILE_SYS_BIND_DATA bind context parameter. + * STR_PARSE_PREFER_FOLDER_BROWSING can be passed to indicate that URLs are parsed using the file system data source when possible. + * Construct a bind context object using CreateBindCtx and populate the values using IBindCtx::RegisterObjectParam. See Bind Context + * String Keys for a complete list of these. + * + * If no data is being passed to or received from the parsing function, this value can be NULL. + * + * @param pszDisplayName + * A null-terminated Unicode string with the display name. Because each Shell folder defines its own parsing syntax, the + * form this string can take may vary. The desktop folder, for instance, accepts paths such as "C:\My Docs\My File.txt". + * It also will accept references to items in the namespace that have a GUID associated with them using the "::{GUID}" syntax. + * For example, to retrieve a fully qualified identifier list for the control panel from the desktop folder, you can use the following: + * "::{CLSID for Control Panel}\::{CLSID for printers folder}" + * + * @param pchEaten + * A pointer to a ULONG value that receives the number of characters of the display name that was parsed. If your application + * does not need this information, set pchEaten to NULL, and no value will be returned. + * + * @param ppidl + * When this method returns, contains a pointer to the PIDL for the object. The returned item identifier list specifies the item + * relative to the parsing folder. If the object associated with pszDisplayName is within the parsing folder, the returned item + * identifier list will contain only one SHITEMID structure. If the object is in a subfolder of the parsing folder, the returned + * item identifier list will contain multiple SHITEMID structures. If an error occurs, NULL is returned in this address. + * + * When it is no longer needed, it is the responsibility of the caller to free this resource by calling CoTaskMemFree. + * + * @param pdwAttributes + * The value used to query for file attributes. If not used, it should be set to NULL. To query for one or more attributes, initialize + * this parameter with the SFGAO flags that represent the attributes of interest. On return, those attributes that are true and were requested will be set. + * @return + * If this method succeeds, it returns S_OK. Otherwise, it returns an HRESULT error code. + */ + HRESULT ParseDisplayName( + WinDef.HWND hwnd, + Pointer pbc, + String pszDisplayName, + IntByReference pchEaten, + PointerByReference ppidl, + IntByReference pdwAttributes); + + /** + * Enables a client to determine the contents of a folder by creating an item identifier enumeration object and returning its IEnumIDList interface. + * The methods supported by that interface can then be used to enumerate the folder's contents. + * + * @param hwnd + * If user input is required to perform the enumeration, this window handle should be used by the enumeration object as the parent window + * to take user input. An example would be a dialog box to ask for a password or prompt the user to insert a CD or floppy disk. + * If hwndOwner is set to NULL, the enumerator should not post any messages, and if user input is required, it should silently fail. + * + * @param grfFlags + * Flags indicating which items to include in the enumeration. For a list of possible values, see the SHCONTF enumerated type. + * + * @param ppenumIDList + * The address that receives a pointer to the IEnumIDList interface of the enumeration object created by this method. + * If an error occurs or no suitable subobjects are found, ppenumIDList is set to NULL. + * + * @return + * Returns S_OK if successful, or an error value otherwise. Some implementations may also return S_FALSE, indicating that there + * are no children matching the grfFlags that were passed in. If S_FALSE is returned, ppenumIDList is set to NULL. + * + */ + HRESULT EnumObjects( + WinDef.HWND hwnd, + int grfFlags, + PointerByReference ppenumIDList); + + /** + * + * Retrieves a handler, typically the Shell folder object that implements IShellFolder for a particular item. Optional + * parameters that control the construction of the handler are passed in the bind context. + * @param pidl + * + * The address of an ITEMIDLIST structure (PIDL) that identifies the subfolder. This value can refer to an item at any level below + * the parent folder in the namespace hierarchy. The structure contains one or more SHITEMID structures, followed by a terminating NULL. + * + * @param pbc + * + * A pointer to an IBindCtx interface on a bind context object that can be used to pass parameters to the construction of the handler. + * If this parameter is not used, set it to NULL. Because support for this parameter is optional for folder object implementations, + * some folders may not support the use of bind contexts. + * Information that can be provided in the bind context includes a BIND_OPTS structure that includes a grfMode member that indicates + * the access mode when binding to a stream handler. Other parameters can be set and discovered using IBindCtx::RegisterObjectParam + * and IBindCtx::GetObjectParam. + * + * @param riid + * The identifier of the interface to return. This may be IID_IShellFolder, IID_IStream, or any other interface that identifies a particular handler. + * + * @param ppv + * When this method returns, contains the address of a pointer to the requested interface. If an error occurs, a NULL pointer is returned at this address. + * + * @return + * If this method succeeds, it returns S_OK. Otherwise, it returns an HRESULT error code. + * + */ + HRESULT BindToObject( + Pointer pidl, + Pointer pbc, + REFIID riid, + PointerByReference ppv); + + /** + * Requests a pointer to an object's storage interface. + * @param pidl + * The address of an ITEMIDLIST structure that identifies the subfolder relative to its parent folder. The structure must contain exactly one SHITEMID structure followed by a terminating zero. + * + * @param pbc + * The optional address of an IBindCtx interface on a bind context object to be used during this operation. If this parameter is + * not used, set it to NULL. Because support for pbc is optional for folder object implementations, some folders may not support the use of bind contexts. + * + * @param riid + * The IID of the requested storage interface. To retrieve an IStream, IStorage, or IPropertySetStorage interface pointer, set + * riid to IID_IStream, IID_IStorage, or IID_IPropertySetStorage, respectively. + * + * @param ppv + * The address that receives the interface pointer specified by riid. If an error occurs, a NULL pointer is returned in this address. + * + * @return + * If this method succeeds, it returns S_OK. Otherwise, it returns an HRESULT error code. + * + */ + HRESULT BindToStorage( + Pointer pidl, + Pointer pbc, + REFIID riid, + PointerByReference ppv); + + /** + * Determines the relative order of two file objects or folders, given their item identifier lists. + * @param lParam + * A value that specifies how the comparison should be performed. + * The lower sixteen bits of lParam define the sorting rule. Most applications set the sorting rule to the default value of zero, indicating that the + * two items should be compared by name. The system does not define any other sorting rules. Some folder objects might allow calling applications to + * use the lower sixteen bits of lParam to specify folder-specific sorting rules. The rules and their associated lParam values are defined by the folder. + * + * When the system folder view object calls IShellFolder::CompareIDs, the lower sixteen bits of lParam are used to specify the column to be used for + * the comparison. + * The upper sixteen bits of lParam are used for flags that modify the sorting rule. The system currently defines these modifier flags. + * + * SHCIDS_ALLFIELDS + * Version 5.0. Compare all the information contained in the ITEMIDLIST structure, not just the display names. This flag is valid only for folder objects that support + * the IShellFolder2 interface. For instance, if the two items are files, the folder should compare their names, sizes, file times, attributes, and any other information + * in the structures. If this flag is set, the lower sixteen bits of lParam must be zero. + * + * SHCIDS_CANONICALONLY + * Version 5.0. When comparing by name, compare the system names but not the display names. When this flag is passed, the two items are compared by whatever criteria the + * Shell folder determines are most efficient, as long as it implements a consistent sort function. This flag is useful when comparing for equality or when the results of + * the sort are not displayed to the user. This flag cannot be combined with other flags. + * + * @param pidl1 + * A pointer to the first item's ITEMIDLIST structure. It will be relative to the folder. This ITEMIDLIST structure can contain more than one + * element; therefore, the entire structure must be compared, not just the first element. + * + * @param pidl2 + * A pointer to the second item's ITEMIDLIST structure. It will be relative to the folder. This ITEMIDLIST structure can contain more than one + * element; therefore, the entire structure must be compared, not just the first element. + * + * @return + * If this method is successful, the CODE field of the HRESULT contains one of the following values. For information regarding the extraction of + * the CODE field from the returned HRESULT, see Remarks. If this method is unsuccessful, it returns a COM error code. + * Negative + * A negative return value indicates that the first item should precede the second (pidl1 < pidl2). + * Positive + * A positive return value indicates that the first item should follow the second (pidl1 > pidl2). + * Zero + * A return value of zero indicates that the two items are the same (pidl1 = pidl2). + * Use the HRESULT_CODE macro to extract the CODE field from the HRESULT, then cast the result as a short. + * #define HRESULT_CODE(hr) ((hr) & 0xFFFF) + * + */ + HRESULT CompareIDs( + WinDef.LPARAM lParam, + Pointer pidl1, + Pointer pidl2); + + + /** + * Requests an object that can be used to obtain information from or interact with a folder object. + * + * @param hwndOwner + * A handle to the owner window. If you have implemented a custom folder view object, your folder view window should be created as a child of hwndOwner. + * + * @param riid + * A reference to the IID of the interface to retrieve through ppv, typically IID_IShellView. + * + * @param ppv + * When this method returns successfully, contains the interface pointer requested in riid. This is typically IShellView. See the Remarks section for more details. + * + * @return + * If this method succeeds, it returns S_OK. Otherwise, it returns an HRESULT error code. + * + */ + HRESULT CreateViewObject( + WinDef.HWND hwndOwner, + REFIID riid, + PointerByReference ppv); + + /** + * Gets the attributes of one or more file or folder objects contained in the object represented by IShellFolder. + * + * @param cidl + * The number of items from which to retrieve attributes. + * + * @param apidl + * The address of an array of pointers to ITEMIDLIST structures, each of which uniquely identifies an item relative to the parent folder. + * Each ITEMIDLIST structure must contain exactly one SHITEMID structure followed by a terminating zero. + * + * @param rgfInOut + * Pointer to a single ULONG value that, on entry, contains the bitwise SFGAO attributes that the calling application is requesting. On + * exit, this value contains the requested attributes that are common to all of the specified items. + * + * @return + * If this method succeeds, it returns S_OK. Otherwise, it returns an HRESULT error code. + * + */ + HRESULT GetAttributesOf( + int cidl, + Pointer apidl, + IntByReference rgfInOut); + + /** + * If this method succeeds, it returns S_OK. Otherwise, it returns an HRESULT error code. + * + * @param hwndOwner + * A handle to the owner window that the client should specify if it displays a dialog box or message box. + * + * @param cidl + * The number of file objects or subfolders specified in the apidl parameter. + * + * @param apidl + * The address of an array of pointers to ITEMIDLIST structures, each of which uniquely identifies a file object or subfolder relative to + * the parent folder. Each item identifier list must contain exactly one SHITEMID structure followed by a terminating zero. + * + * @param riid + * A reference to the IID of the interface to retrieve through ppv. This can be any valid interface identifier that can be created for an + * item. The most common identifiers used by the Shell are listed in the comments at the end of this reference. + * + * @param rgfReserved + * Reserved. + * + * @param ppv + * When this method returns successfully, contains the interface pointer requested in riid. + * + * @return + * If this method succeeds, it returns S_OK. Otherwise, it returns an HRESULT error code. + * + */ + HRESULT GetUIObjectOf( + WinDef.HWND hwndOwner, + int cidl, + Pointer apidl, + REFIID riid, + IntByReference rgfReserved, + PointerByReference ppv); + + /** + * Retrieves the display name for the specified file object or subfolder. + * + * @param pidl + * PIDL that uniquely identifies the file object or subfolder relative to the parent folder. + * + * @param flags + * Flags used to request the type of display name to return. For a list of possible values, see the SHGDNF enumerated type. + * + * @param pName + * When this method returns, contains a pointer to a STRRET structure in which to return the display name. The type of name returned in this structure can be the requested type, but the Shell folder might return a different type. + * + * @return + * If this method succeeds, it returns S_OK. Otherwise, it returns an HRESULT error code. + * It is the caller's responsibility to free resources allocated by this function. + * + */ + HRESULT GetDisplayNameOf( + Pointer pidl, + int flags, + PointerByReference pName); + + /** + * Sets the display name of a file object or subfolder, changing the item identifier in the process. + * + * @param hwnd + * A handle to the owner window of any dialog or message box that the client displays. + * + * @param pidl + * A pointer to an ITEMIDLIST structure that uniquely identifies the file object or subfolder relative to the parent folder. + * The structure must contain exactly one SHITEMID structure followed by a terminating zero. + * + * @param pszName + * A pointer to a null-terminated string that specifies the new display name. + * + * @param uFlags + * Flags that indicate the type of name specified by the pszName parameter. For a list of possible values and combinations of values, see SHGDNF. + * + * @param ppidlOut + * Optional. If specified, the address of a pointer to an ITEMIDLIST structure that receives the ITEMIDLIST of the renamed item. The + * caller requests this value by passing a non-null ppidlOut. Implementations of IShellFolder::SetNameOf must return a pointer to the + * new ITEMIDLIST in the ppidlOut parameter. + * + * @return + * If this method succeeds, it returns S_OK. Otherwise, it returns an HRESULT error code. + * + */ + HRESULT SetNameOf( + WinDef.HWND hwnd, + Pointer pidl, + String pszName, + int uFlags, + PointerByReference ppidlOut); + + /* + Use this like: + PointerByReference pbr=new PointerByReference(); + HRESULT result=SomeCOMObject.QueryInterface(IID_ISHELLFOLDER, pbr); + if(COMUtils.SUCCEEDED(result)) IShellFolder isf=IShellFolder.Converter.PointerToIShellFolder(pbr); + */ + + public static class Converter + { + public static IShellFolder PointerToIShellFolder(final PointerByReference ptr) + { + final Pointer interfacePointer = ptr.getValue(); + final Pointer vTablePointer = interfacePointer.getPointer(0); + final Pointer[] vTable = new Pointer[13]; + vTablePointer.read(0, vTable, 0, 13); + return new IShellFolder() { + + @Override + public WinNT.HRESULT QueryInterface(REFIID byValue, PointerByReference pointerByReference) { + Function f = Function.getFunction(vTable[0], Function.ALT_CONVENTION); + return new WinNT.HRESULT(f.invokeInt(new Object[]{interfacePointer, byValue, pointerByReference})); + } + + @Override + public int AddRef() { + Function f = Function.getFunction(vTable[1], Function.ALT_CONVENTION); + return f.invokeInt(new Object[]{interfacePointer}); + } + + public int Release() { + Function f = Function.getFunction(vTable[2], Function.ALT_CONVENTION); + return f.invokeInt(new Object[]{interfacePointer}); + } + + @Override + public WinNT.HRESULT ParseDisplayName(WinDef.HWND hwnd, Pointer pbc, String pszDisplayName, IntByReference pchEaten, PointerByReference ppidl, IntByReference pdwAttributes) { + Function f = Function.getFunction(vTable[3], Function.ALT_CONVENTION); + return new WinNT.HRESULT(f.invokeInt(new Object[]{interfacePointer, hwnd, pbc, pszDisplayName, pchEaten, ppidl, pdwAttributes})); + } + + @Override + public WinNT.HRESULT EnumObjects(WinDef.HWND hwnd, int grfFlags, PointerByReference ppenumIDList) { + Function f = Function.getFunction(vTable[4], Function.ALT_CONVENTION); + return new WinNT.HRESULT( f.invokeInt(new Object[]{interfacePointer, hwnd, grfFlags, ppenumIDList})); + } + + public WinNT.HRESULT BindToObject(Pointer pidl, Pointer pbc, REFIID riid, PointerByReference ppv) { + Function f = Function.getFunction(vTable[5], Function.ALT_CONVENTION); + return new WinNT.HRESULT( f.invokeInt(new Object[]{interfacePointer, pidl, pbc, riid, ppv})); + } + + @Override + public HRESULT BindToStorage(Pointer pidl, Pointer pbc, REFIID riid, PointerByReference ppv) { + Function f = Function.getFunction(vTable[6], Function.ALT_CONVENTION); + return new WinNT.HRESULT( f.invokeInt(new Object[]{interfacePointer, pidl, pbc, riid, ppv})); + } + + @Override + public HRESULT CompareIDs(WinDef.LPARAM lParam, Pointer pidl1, Pointer pidl2) { + Function f = Function.getFunction(vTable[7], Function.ALT_CONVENTION); + return new WinNT.HRESULT( f.invokeInt(new Object[]{interfacePointer, lParam, pidl1, pidl2})); + } + + @Override + public HRESULT CreateViewObject(WinDef.HWND hwndOwner, REFIID riid, PointerByReference ppv) { + Function f = Function.getFunction(vTable[8], Function.ALT_CONVENTION); + return new WinNT.HRESULT( f.invokeInt(new Object[]{interfacePointer, hwndOwner, riid, ppv})); + } + + @Override + public HRESULT GetAttributesOf(int cidl, Pointer apidl, IntByReference rgfInOut) { + Function f = Function.getFunction(vTable[9], Function.ALT_CONVENTION); + return new WinNT.HRESULT( f.invokeInt(new Object[]{interfacePointer, cidl, apidl, rgfInOut})); + } + + @Override + public HRESULT GetUIObjectOf(WinDef.HWND hwndOwner, int cidl, Pointer apidl, REFIID riid, IntByReference rgfReserved, PointerByReference ppv) { + Function f = Function.getFunction(vTable[10], Function.ALT_CONVENTION); + return new WinNT.HRESULT( f.invokeInt(new Object[]{interfacePointer, hwndOwner, cidl, apidl, riid, rgfReserved, ppv})); + } + + public WinNT.HRESULT GetDisplayNameOf(Pointer pidl, int flags, PointerByReference pName){ + Function f = Function.getFunction(vTable[11], Function.ALT_CONVENTION); + return new WinNT.HRESULT( f.invokeInt(new Object[]{interfacePointer, pidl, flags, pName})); + } + + @Override + public HRESULT SetNameOf(WinDef.HWND hwnd, Pointer pidl, String pszName, int uFlags, PointerByReference ppidlOut) { + Function f = Function.getFunction(vTable[12], Function.ALT_CONVENTION); + return new WinNT.HRESULT( f.invokeInt(new Object[]{interfacePointer, hwnd, pidl, pszName, uFlags, ppidlOut})); + } + }; + } + } +} diff --git a/contrib/platform/src/com/sun/jna/platform/win32/COM/TypeLibUtil.java b/contrib/platform/src/com/sun/jna/platform/win32/COM/TypeLibUtil.java index 4c3011411b..92c1adf960 100644 --- a/contrib/platform/src/com/sun/jna/platform/win32/COM/TypeLibUtil.java +++ b/contrib/platform/src/com/sun/jna/platform/win32/COM/TypeLibUtil.java @@ -520,7 +520,7 @@ public String getDocString() { * * @return the help context */ - public long getHelpContext() { + public int getHelpContext() { return helpContext; } diff --git a/contrib/platform/src/com/sun/jna/platform/win32/Crypt32.java b/contrib/platform/src/com/sun/jna/platform/win32/Crypt32.java index 9e5aefa31c..25f5d8f826 100644 --- a/contrib/platform/src/com/sun/jna/platform/win32/Crypt32.java +++ b/contrib/platform/src/com/sun/jna/platform/win32/Crypt32.java @@ -16,6 +16,7 @@ import com.sun.jna.Pointer; import com.sun.jna.platform.win32.WinCrypt.CRYPTPROTECT_PROMPTSTRUCT; import com.sun.jna.platform.win32.WinCrypt.DATA_BLOB; +import com.sun.jna.platform.win32.WinDef.DWORD; import com.sun.jna.ptr.PointerByReference; import com.sun.jna.win32.StdCallLibrary; import com.sun.jna.win32.W32APIOptions; @@ -27,7 +28,7 @@ public interface Crypt32 extends StdCallLibrary { Crypt32 INSTANCE = (Crypt32) Native.loadLibrary("Crypt32", - Crypt32.class, W32APIOptions.UNICODE_OPTIONS); + Crypt32.class, W32APIOptions.DEFAULT_OPTIONS); /** * The CryptProtectData function performs encryption on the data in a DATA_BLOB @@ -109,4 +110,27 @@ public boolean CryptUnprotectData(DATA_BLOB pDataIn, PointerByReference szDataDe CRYPTPROTECT_PROMPTSTRUCT pPromptStruct, int dwFlags, DATA_BLOB pDataOut); + + /** + * The CertAddEncodedCertificateToSystemStore function opens the specified + * system store and adds the encoded certificate to it. + * + * @param szCertStoreName + * A null-terminated string that contains the name of the system + * store for the encoded certificate. + * @param pbCertEncoded + * A pointer to a buffer that contains the encoded certificate to + * add. + * @param cbCertEncoded + * The size, in bytes, of the pbCertEncoded buffer. + * @return If the function succeeds, the return value is TRUE.
+ * If the function fails, the return value is FALSE.
+ * CertAddEncodedCertificateToSystemStore depends on the functions + * listed in the following remarks for error handling.
+ * Refer to those function topics for their respective error + * handling behaviors.
+ * For extended error information, call GetLastError. + * @see MSDN + */ + boolean CertAddEncodedCertificateToSystemStore(String szCertStoreName, Pointer pbCertEncoded, int cbCertEncoded); } diff --git a/contrib/platform/src/com/sun/jna/platform/win32/DBT.java b/contrib/platform/src/com/sun/jna/platform/win32/DBT.java index b747810a74..5380efe27a 100644 --- a/contrib/platform/src/com/sun/jna/platform/win32/DBT.java +++ b/contrib/platform/src/com/sun/jna/platform/win32/DBT.java @@ -22,7 +22,6 @@ import com.sun.jna.platform.win32.WinDef.LONG; import com.sun.jna.platform.win32.WinNT.HANDLE; import com.sun.jna.platform.win32.WinUser.HDEVNOTIFY; -import com.sun.jna.win32.StdCallLibrary; /** * Based on dbt.h (various types) @@ -30,7 +29,7 @@ * @author Tobias Wolf, wolf.tobias@gmx.net */ @SuppressWarnings("serial") -public interface DBT extends StdCallLibrary { +public interface DBT { /** The dbt no disk space. */ int DBT_NO_DISK_SPACE = 0x0047; diff --git a/contrib/platform/src/com/sun/jna/platform/win32/DsGetDC.java b/contrib/platform/src/com/sun/jna/platform/win32/DsGetDC.java index 5e52093ff8..eb84634016 100644 --- a/contrib/platform/src/com/sun/jna/platform/win32/DsGetDC.java +++ b/contrib/platform/src/com/sun/jna/platform/win32/DsGetDC.java @@ -17,7 +17,6 @@ import com.sun.jna.Pointer; import com.sun.jna.Structure; -import com.sun.jna.WString; import com.sun.jna.platform.win32.Guid.GUID; import com.sun.jna.platform.win32.WinNT.PSID; import com.sun.jna.win32.StdCallLibrary; @@ -27,7 +26,7 @@ * * @author dblock[at]dblock.org */ -public interface DsGetDC extends StdCallLibrary { +public interface DsGetDC { /** * The DOMAIN_CONTROLLER_INFO structure is used with the DsGetDcName @@ -48,7 +47,7 @@ public DOMAIN_CONTROLLER_INFO(Pointer memory) { } /** - * Pointer to a null-terminated WString that specifies the computer name + * Pointer to a null-terminated string that specifies the computer name * of the discovered domain controller. The returned computer name is * prefixed with "\\". The DNS-style name, for example, * "\\phoenix.fabrikam.com", is returned, if available. If the DNS-style @@ -57,16 +56,16 @@ public DOMAIN_CONTROLLER_INFO(Pointer memory) { * 4.0 domain or if the domain does not support the IP family of * protocols. */ - public WString DomainControllerName; + public String DomainControllerName; /** - * Pointer to a null-terminated WString that specifies the address of + * Pointer to a null-terminated string that specifies the address of * the discovered domain controller. The address is prefixed with "\\". - * This WString is one of the types defined by the + * This string is one of the types defined by the * DomainControllerAddressType member. */ - public WString DomainControllerAddress; + public String DomainControllerAddress; /** - * Indicates the type of WString that is contained in the + * Indicates the type of string that is contained in the * DomainControllerAddress member. */ public int DomainControllerAddressType; @@ -77,40 +76,40 @@ public DOMAIN_CONTROLLER_INFO(Pointer memory) { */ public GUID DomainGuid; /** - * Pointer to a null-terminated WString that specifies the name of the + * Pointer to a null-terminated string that specifies the name of the * domain. The DNS-style name, for example, "fabrikam.com", is returned * if available. Otherwise, the flat-style name, for example, * "fabrikam", is returned. This name may be different than the * requested domain name if the domain has been renamed. */ - public WString DomainName; + public String DomainName; /** - * Pointer to a null-terminated WString that specifies the name of the + * Pointer to a null-terminated string that specifies the name of the * domain at the root of the DS tree. The DNS-style name, for example, * "fabrikam.com", is returned if available. Otherwise, the flat-style * name, for example, "fabrikam" is returned. */ - public WString DnsForestName; + public String DnsForestName; /** * Contains a set of flags that describe the domain controller. */ public int Flags; /** - * Pointer to a null-terminated WString that specifies the name of the + * Pointer to a null-terminated string that specifies the name of the * site where the domain controller is located. This member may be NULL * if the domain controller is not in a site; for example, the domain * controller is a Windows NT 4.0 domain controller. */ - public WString DcSiteName; + public String DcSiteName; /** - * Pointer to a null-terminated WString that specifies the name of the + * Pointer to a null-terminated string that specifies the name of the * site that the computer belongs to. The computer is specified in the * ComputerName parameter passed to DsGetDcName. This member may be NULL * if the site that contains the computer cannot be found; for example, * if the DS administrator has not associated the subnet that the * computer is in with a valid site. */ - public WString ClientSiteName; + public String ClientSiteName; protected List getFieldOrder() { return Arrays.asList(new String[] { "DomainControllerName", @@ -182,12 +181,12 @@ public static class ByReference extends DS_DOMAIN_TRUSTS implements * Pointer to a null-terminated string that contains the NetBIOS name of * the domain. */ - public WString NetbiosDomainName; + public String NetbiosDomainName; /** * Pointer to a null-terminated string that contains the DNS name of the * domain. This member may be NULL. */ - public WString DnsDomainName; + public String DnsDomainName; /** * Contains a set of flags that specify more data about the domain * trust. diff --git a/contrib/platform/src/com/sun/jna/platform/win32/GDI32.java b/contrib/platform/src/com/sun/jna/platform/win32/GDI32.java index 11de5a5cc3..62af79d769 100644 --- a/contrib/platform/src/com/sun/jna/platform/win32/GDI32.java +++ b/contrib/platform/src/com/sun/jna/platform/win32/GDI32.java @@ -42,6 +42,12 @@ public interface GDI32 extends StdCallLibrary { GDI32 INSTANCE = (GDI32) Native.loadLibrary("gdi32", GDI32.class, W32APIOptions.DEFAULT_OPTIONS); + /** + * Used with BitBlt. Copies the source rectangle directly to the destination + * rectangle. + */ + int SRCCOPY = 0xCC0020; + /** * The ExtCreateRegion function creates a region from the specified region and transformation data. * @param lpXform @@ -430,4 +436,148 @@ HBITMAP CreateDIBSection(HDC hDC, BITMAPINFO pbmi, int iUsage, */ public int GetObject(final HANDLE hgdiobj, final int cbBuffer, final Pointer lpvObject); + + /** + * The BitBlt function performs a bit-block transfer of the color data + * corresponding to a rectangle of pixels from the specified source device + * context into a destination device context. + * + * @param hdcDest + * A handle to the destination device context. + * @param nXDest + * The x-coordinate, in logical units, of the upper-left corner + * of the destination rectangle. + * @param nYDest + * The y-coordinate, in logical units, of the upper-left corner + * of the destination rectangle. + * @param nWidth + * The width, in logical units, of the source and destination + * rectangles. + * @param nHeight + * The height, in logical units, of the source and the + * destination rectangles. + * @param hdcSrc + * A handle to the source device context. + * @param nXSrc + * The x-coordinate, in logical units, of the upper-left corner + * of the source rectangle. + * @param nYSrc + * The y-coordinate, in logical units, of the upper-left corner + * of the source rectangle. + * @param dwRop + * A raster-operation code.
+ * These codes define how the color data for the source rectangle + * is to be combined with the color data for the destination + * rectangle to achieve the final color.
+ * The following list shows some common raster operation codes. + *
+ * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + *
ValueMeaning
BLACKNESSFills the destination rectangle using the color associated + * with index 0 in the physical palette. (This color is black for + * the default physical palette.)
CAPTUREBLTIncludes any windows that are layered on top of your + * window in the resulting image. By default, the image only + * contains your window. Note that this generally cannot be used + * for printing device contexts.
DSTINVERTInverts the destination rectangle.
MERGECOPYMerges the colors of the source rectangle with the brush + * currently selected in hdcDest, by using the Boolean + * AND operator.
MERGEPAINTMerges the colors of the inverted source rectangle with + * the colors of the destination rectangle by using the Boolean + * OR operator.
NOMIRRORBITMAP + * Prevents the bitmap from being mirrored.
NOTSRCCOPYCopies the inverted source rectangle to the destination. + *
NOTSRCERASECombines the colors of the source and destination + * rectangles by using the Boolean OR operator and then inverts + * the resultant color.
PATCOPYCopies the brush currently selected in hdcDest, + * into the destination bitmap.
PATINVERTCombines the colors of the brush currently selected in + * hdcDest, with the colors of the destination rectangle + * by using the Boolean XOR operator.
PATPAINTCombines the colors of the brush currently selected in + * hdcDest, with the colors of the inverted source + * rectangle by using the Boolean OR operator. The result of this + * operation is combined with the colors of the destination + * rectangle by using the Boolean OR operator.
SRCANDCombines the colors of the source and destination + * rectangles by using the Boolean AND operator.
SRCCOPYCopies the source rectangle directly to the destination + * rectangle.
SRCERASECombines the inverted colors of the destination rectangle + * with the colors of the source rectangle by using the Boolean + * AND operator.
SRCINVERTCombines the colors of the source and destination + * rectangles by using the Boolean XOR operator.
SRCPAINTCombines the colors of the source and destination + * rectangles by using the Boolean OR operator.
WHITENESSFills the destination rectangle using the color associated + * with index 1 in the physical palette. (This color is white for + * the default physical palette.)
+ * @return True if the function succeeded, False if not. To get extended + * error information, call GetLastError. + */ + boolean BitBlt(HDC hdcDest, int nXDest, int nYDest, int nWidth, int nHeight, HDC hdcSrc, int nXSrc, int nYSrc, + int dwRop); + } diff --git a/contrib/platform/src/com/sun/jna/platform/win32/GDI32Util.java b/contrib/platform/src/com/sun/jna/platform/win32/GDI32Util.java new file mode 100644 index 0000000000..7acc6dee8a --- /dev/null +++ b/contrib/platform/src/com/sun/jna/platform/win32/GDI32Util.java @@ -0,0 +1,166 @@ +/* Copyright (c) 2015 Michael Freeman, 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. + */ +package com.sun.jna.platform.win32; + +import java.awt.Rectangle; +import java.awt.image.BufferedImage; + +import com.sun.jna.Memory; +import com.sun.jna.Native; +import com.sun.jna.platform.win32.WinDef.HBITMAP; +import com.sun.jna.platform.win32.WinDef.HDC; +import com.sun.jna.platform.win32.WinDef.HWND; +import com.sun.jna.platform.win32.WinDef.RECT; +import com.sun.jna.platform.win32.WinGDI.BITMAPINFO; +import com.sun.jna.platform.win32.WinNT.HANDLE; + +/** + * GDI32 utility API. + * + * @author mlfreeman[at]gmail.com + */ +public class GDI32Util { + /** + * Takes a screenshot of the given window + * + * @param target + * The window to target + * @return the window captured as a screenshot, or null if the BufferedImage doesn't construct properly + * @throws IllegalStateException + * if the rectangle from GetWindowRect has a width and/or height + * of 0.
+ * if the device context acquired from the original HWND doesn't + * release properly + */ + public static BufferedImage getScreenshot(HWND target) { + RECT rect = new RECT(); + if (!User32.INSTANCE.GetWindowRect(target, rect)) { + throw new Win32Exception(Native.getLastError()); + } + Rectangle jRectangle = rect.toRectangle(); + int windowWidth = jRectangle.width; + int windowHeight = jRectangle.height; + + if (windowWidth == 0 || windowHeight == 0) { + throw new IllegalStateException("Window width and/or height were 0 even though GetWindowRect did not appear to fail."); + } + + HDC hdcTarget = User32.INSTANCE.GetDC(target); + if (hdcTarget == null) { + throw new Win32Exception(Native.getLastError()); + } + + Win32Exception we = null; + + // device context used for drawing + HDC hdcTargetMem = null; + + // handle to the bitmap to be drawn to + HBITMAP hBitmap = null; + + // original display surface associated with the device context + HANDLE hOriginal = null; + + // final java image structure we're returning. + BufferedImage image = null; + + try { + image = new BufferedImage(windowWidth, windowHeight, BufferedImage.TYPE_INT_RGB); + + hdcTargetMem = GDI32.INSTANCE.CreateCompatibleDC(hdcTarget); + if (hdcTargetMem == null) { + throw new Win32Exception(Native.getLastError()); + } + + hBitmap = GDI32.INSTANCE.CreateCompatibleBitmap(hdcTarget, windowWidth, windowHeight); + if (hBitmap == null) { + throw new Win32Exception(Native.getLastError()); + } + + hOriginal = GDI32.INSTANCE.SelectObject(hdcTargetMem, hBitmap); + if (hOriginal == null) { + throw new Win32Exception(Native.getLastError()); + } + + // draw to the bitmap + if (!GDI32.INSTANCE.BitBlt(hdcTargetMem, 0, 0, windowWidth, windowHeight, hdcTarget, 0, 0, GDI32.SRCCOPY)) { + throw new Win32Exception(Native.getLastError()); + } + + BITMAPINFO bmi = new BITMAPINFO(); + bmi.bmiHeader.biWidth = windowWidth; + bmi.bmiHeader.biHeight = -windowHeight; + bmi.bmiHeader.biPlanes = 1; + bmi.bmiHeader.biBitCount = 32; + bmi.bmiHeader.biCompression = WinGDI.BI_RGB; + + Memory buffer = new Memory(windowWidth * windowHeight * 4); + int resultOfDrawing = GDI32.INSTANCE.GetDIBits(hdcTarget, hBitmap, 0, windowHeight, buffer, bmi, + WinGDI.DIB_RGB_COLORS); + if (resultOfDrawing == 0 || resultOfDrawing == WinError.ERROR_INVALID_PARAMETER) { + throw new Win32Exception(Native.getLastError()); + } + + image.setRGB(0, 0, windowWidth, windowHeight, buffer.getIntArray(0, windowWidth * windowHeight), 0, + windowWidth); + + } catch (Win32Exception e) { + we = e; + } finally { + if (hOriginal != null) { + // per MSDN, set the display surface back when done drawing + HANDLE result = GDI32.INSTANCE.SelectObject(hdcTargetMem, hOriginal); + // failure modes are null or equal to HGDI_ERROR + if (result == null || WinGDI.HGDI_ERROR.equals(result)) { + Win32Exception ex = new Win32Exception(Native.getLastError()); + if (we != null) { + ex.addSuppressed(we); + } + we = ex; + } + } + + if (hBitmap != null) { + if (!GDI32.INSTANCE.DeleteObject(hBitmap)) { + Win32Exception ex = new Win32Exception(Native.getLastError()); + if (we != null) { + ex.addSuppressed(we); + } + we = ex; + } + } + + if (hdcTargetMem != null) { + // get rid of the device context when done + if (!GDI32.INSTANCE.DeleteDC(hdcTargetMem)) { + Win32Exception ex = new Win32Exception(Native.getLastError()); + if (we != null) { + ex.addSuppressed(we); + } + we = ex; + } + } + + if (hdcTarget != null) { + if (0 == User32.INSTANCE.ReleaseDC(target, hdcTarget)) { + throw new IllegalStateException("Device context did not release properly."); + } + } + } + + if (we != null) { + throw we; + } + return image; + } +} \ No newline at end of file diff --git a/contrib/platform/src/com/sun/jna/platform/win32/GL.java b/contrib/platform/src/com/sun/jna/platform/win32/GL.java index 0638abe6e0..da808ace16 100644 --- a/contrib/platform/src/com/sun/jna/platform/win32/GL.java +++ b/contrib/platform/src/com/sun/jna/platform/win32/GL.java @@ -12,12 +12,10 @@ */ package com.sun.jna.platform.win32; -import com.sun.jna.win32.StdCallLibrary; - /** * Definitions for WinOpenGL */ -public interface GL extends StdCallLibrary { +public interface GL { public final int GL_VENDOR = 0x1F00; public final int GL_RENDERER = 0x1F01; public final int GL_VERSION = 0x1F02; diff --git a/contrib/platform/src/com/sun/jna/platform/win32/Guid.java b/contrib/platform/src/com/sun/jna/platform/win32/Guid.java index 7427dfbe39..a948ad3620 100644 --- a/contrib/platform/src/com/sun/jna/platform/win32/Guid.java +++ b/contrib/platform/src/com/sun/jna/platform/win32/Guid.java @@ -38,7 +38,9 @@ public interface Guid { public static class GUID extends Structure { public static class ByValue extends GUID implements Structure.ByValue { - public ByValue() {} + public ByValue() { + super(); + } public ByValue(GUID guid) { super(guid.getPointer()); @@ -64,6 +66,7 @@ public static class ByReference extends GUID implements * Instantiates a new by reference. */ public ByReference() { + super(); } /** @@ -108,6 +111,7 @@ public ByReference(Pointer memory) { * Instantiates a new guid. */ public GUID() { + super(); } /** @@ -117,6 +121,7 @@ public GUID() { * the guid */ public GUID(GUID guid) { + super(); this.Data1 = guid.Data1; this.Data2 = guid.Data2; this.Data3 = guid.Data3; @@ -392,6 +397,7 @@ public static class ByReference extends GUID { * Instantiates a new by reference. */ public ByReference() { + super(); } /** @@ -411,7 +417,7 @@ public ByReference(GUID guid) { * the memory */ public ByReference(Pointer memory) { - + super(memory); } } @@ -419,6 +425,7 @@ public ByReference(Pointer memory) { * Instantiates a new clsid. */ public CLSID() { + super(); } /** @@ -451,7 +458,7 @@ public class REFIID extends IID { * Instantiates a new refiid. */ public REFIID() { - // TODO Auto-generated constructor stub + super(); } /** @@ -462,7 +469,6 @@ public REFIID() { */ public REFIID(Pointer memory) { super(memory); - // TODO Auto-generated constructor stub } /** @@ -473,9 +479,11 @@ public REFIID(Pointer memory) { */ public REFIID(byte[] data) { super(data); - // TODO Auto-generated constructor stub } + public REFIID(GUID guid) { + super(guid); + } } /** @@ -489,7 +497,7 @@ public class IID extends GUID { * Instantiates a new iid. */ public IID() { - // TODO Auto-generated constructor stub + super(); } /** @@ -500,7 +508,6 @@ public IID() { */ public IID(Pointer memory) { super(memory); - // TODO Auto-generated constructor stub } /** @@ -510,7 +517,6 @@ public IID(Pointer memory) { */ public IID(String iid) { super(iid); - // TODO Auto-generated constructor stub } /** @@ -521,7 +527,11 @@ public IID(String iid) { */ public IID(byte[] data) { super(data); - // TODO Auto-generated constructor stub } + + public IID(GUID guid) { + this(guid.toGuidString()); + } + } } \ No newline at end of file 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 87af3296d5..229c07ad1b 100644 --- a/contrib/platform/src/com/sun/jna/platform/win32/Kernel32.java +++ b/contrib/platform/src/com/sun/jna/platform/win32/Kernel32.java @@ -14,22 +14,48 @@ 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; +import com.sun.jna.win32.StdCallLibrary; /** * Interface definitions for kernel32.dll. Includes additional * alternate mappings from {@link WinNT} which make use of NIO buffers, * {@link Wincon} for console API. */ -public interface Kernel32 extends WinNT, Wincon { +public interface Kernel32 extends StdCallLibrary, WinNT, Wincon { /** The instance. */ Kernel32 INSTANCE = (Kernel32) Native.loadLibrary("kernel32", - Kernel32.class, W32APIOptions.UNICODE_OPTIONS); - + 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 @@ -155,6 +181,32 @@ boolean ReadFile(HANDLE hFile, byte[] lpBuffer, int nNumberOfBytesToRead, */ boolean SetLocalTime(SYSTEMTIME lpSystemTime); + /** + * Retrieves system timing information. On a multiprocessor system, the + * values returned are the sum of the designated times across all + * processors. + * + * @param lpIdleTime + * A pointer to a {@link WinBase.FILETIME} structure that + * receives the amount of time that the system has been idle. + * @param lpKernelTime + * A pointer to a {@link WinBase.FILETIME} structure that + * receives the amount of time that the system has spent + * executing in Kernel mode (including all threads in all + * processes, on all processors). This time value also includes + * the amount of time the system has been idle. + * @param lpUserTime + * A pointer to a {@link WinBase.FILETIME} structure that + * receives the amount of time that the system has spent + * executing in User mode (including all threads in all + * processes, on all processors). + * @return {@code true} if the function succeeds, {@code false} otherwise. + * If the function fails, call {@link #GetLastError()} to get extended error + * information. + * @see GetSystemTimes documentation + */ + boolean GetSystemTimes(WinBase.FILETIME lpIdleTime, WinBase.FILETIME lpKernelTime, WinBase.FILETIME lpUserTime); + /** * The GetTickCount function retrieves the number of milliseconds that have * elapsed since the system was started, up to 49.7 days. @@ -2437,17 +2489,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 + * @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); @@ -2732,85 +2799,474 @@ 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 WinNT.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); + + /** + * Enumerates resource types within a binary module.
+ * Starting with Windows Vista, this is typically a language-neutral + * Portable Executable (LN file), and the enumeration also includes + * resources from one of the corresponding language-specific resource files + * (.mui files)-if one exists-that contain localizable language resources. + * It is also possible to use hModule to specify a .mui file, in which case + * only that file is searched for resource types.
+ * Alternately, applications can call EnumResourceTypesEx, which provides + * more precise control over which resource files to enumerate. + * + * @param hModule + * A handle to a module to be searched.
+ * This handle must be obtained through LoadLibrary or + * LoadLibraryEx.
+ * See Remarks for more information. If this parameter is NULL, + * that is equivalent to passing in a handle to the module used + * to create the current process. + * @param proc + * A pointer to the callback function to be called for each + * enumerated resource type.
+ * For more information, see the EnumResTypeProc function. + * @param lParam + * An application-defined value passed to the callback function. + * @return Returns TRUE if successful; otherwise, FALSE. To get extended + * error information, call GetLastError. + */ + boolean EnumResourceTypes(HMODULE hModule, WinBase.EnumResTypeProc proc, Pointer lParam); + + /** + * Enumerates resources of a specified type within a binary module.
+ * For Windows Vista and later, this is typically a language-neutral + * Portable Executable (LN file), and the enumeration will also include + * resources from the corresponding language-specific resource files (.mui + * files) that contain localizable language resources.
+ * It is also possible for hModule to specify an .mui file, in which case + * only that file is searched for resources. + * + * @param hModule + * A handle to a module to be searched.
+ * Starting with Windows Vista, if this is an LN file, then + * appropriate .mui files (if any exist) are included in the + * search.
+ * If this parameter is NULL, that is equivalent to passing in a + * handle to the module used to create the current process. + * @param type + * The type of the resource for which the name is being + * enumerated.
+ * Alternately, rather than a pointer, this parameter can be + * MAKEINTRESOURCE(ID), where ID is an integer value representing + * a predefined resource type.
+ * For a list of predefined resource types, see Resource Types. + * For more information, see the Remarks section below. + * @param proc + * A pointer to the callback function to be called for each + * enumerated resource name or ID. For more information, see + * EnumResNameProc. + * @param lParam + * An application-defined value passed to the callback function. + * This parameter can be used in error checking. + * @return The return value is TRUE if the function succeeds or FALSE if the + * function does not find a resource of the type specified, or if + * the function fails for another reason. To get extended error + * information, call GetLastError. + */ + boolean EnumResourceNames(HMODULE hModule, Pointer type, WinBase.EnumResNameProc proc, Pointer lParam); } 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..8d1b0dd389 100644 --- a/contrib/platform/src/com/sun/jna/platform/win32/Kernel32Util.java +++ b/contrib/platform/src/com/sun/jna/platform/win32/Kernel32Util.java @@ -1,20 +1,22 @@ /* 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; import java.io.File; import java.io.FileNotFoundException; import java.nio.ByteOrder; +import java.util.ArrayList; +import java.util.LinkedHashMap; import java.util.List; import java.util.Map; import java.util.TreeMap; @@ -31,7 +33,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 +42,7 @@ public abstract class Kernel32Util implements WinDef { /** * Get current computer NetBIOS name. - * + * * @return Netbios name. */ public static String getComputerName() { @@ -55,7 +57,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 +80,7 @@ public static String formatMessage(int code) { /** * Format a message from an HRESULT. - * + * * @param code * HRESULT * @return Formatted message. @@ -98,7 +100,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 +109,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 +140,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 +161,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 +231,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 +267,7 @@ public static Map getEnvironmentVariables() { if (lpszEnvironmentBlock == null) { throw new LastErrorException(Kernel32.INSTANCE.GetLastError()); } - + try { return getEnvironmentVariables(lpszEnvironmentBlock, 0L); } finally { @@ -284,13 +286,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 +307,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 +335,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 +353,7 @@ public static String readEnvironmentStringBlockEntry(Pointer lpszEnvironmentBloc chars[index] = (char) (b & 0x00FF); } } - + return new String(chars); } @@ -388,10 +390,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 +415,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 +428,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 +453,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 +518,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 +545,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 +641,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 +649,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 +662,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 +677,202 @@ 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; + byte[] results = null; + 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."); + } + // have to capture it into a byte array before you free the library, otherwise bad things happen. + results = start.getByteArray(0, length); + } 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 results; + } + + /** + * Gets a list of all resources from the specified executable file + * + * @param path + * The path to the executable file + * @return A map of resource type name/ID => resources.
    + * A map key + a single list item + the path to the executable can + * be handed off to getResource() to actually get the resource. + */ + public static Map> getResourceNames(String path) { + HMODULE target = Kernel32.INSTANCE.LoadLibraryEx(path, null, Kernel32.LOAD_LIBRARY_AS_DATAFILE); + + if (target == null) { + throw new Win32Exception(Kernel32.INSTANCE.GetLastError()); + } + + final List types = new ArrayList(); + final Map> result = new LinkedHashMap>(); + + WinBase.EnumResTypeProc ertp = new WinBase.EnumResTypeProc() { + + @Override + public boolean invoke(HMODULE module, Pointer type, Pointer lParam) { + // simulate IS_INTRESOURCE macro defined in WinUser.h + // basically that means that if "type" is less than or equal to 65,535 + // it assumes it's an ID. + // otherwise it assumes it's a pointer to a string + if (Pointer.nativeValue(type) <= 65535) { + types.add(Pointer.nativeValue(type) + ""); + } else { + types.add(type.getWideString(0)); + } + return true; + } + }; + + WinBase.EnumResNameProc ernp = new WinBase.EnumResNameProc() { + + @Override + public boolean invoke(HMODULE module, Pointer type, Pointer name, Pointer lParam) { + String typeName = ""; + + if (Pointer.nativeValue(type) <= 65535) { + typeName = Pointer.nativeValue(type) + ""; + } else { + typeName = type.getWideString(0); + } + + if (Pointer.nativeValue(name) < 65535) { + result.get(typeName).add(Pointer.nativeValue(name) + ""); + } else { + result.get(typeName).add(name.getWideString(0)); + } + + return true; + } + }; + + + Win32Exception err = null; + try { + if (!Kernel32.INSTANCE.EnumResourceTypes(target, ertp, null)) { + throw new Win32Exception(Kernel32.INSTANCE.GetLastError()); + } + + for (final String typeName : types) { + result.put(typeName, new ArrayList()); + + // simulate MAKEINTRESOURCE macro in WinUser.h + // basically, if the value passed in can be parsed as a number then convert it into one and run with that. + // otherwise, assume it's a string and construct a pointer to said string. + Pointer pointer = null; + try { + pointer = new Pointer(Long.parseLong(typeName)); + } catch (NumberFormatException e) { + pointer = new Memory(Native.WCHAR_SIZE * (typeName.length() + 1)); + pointer.setWideString(0, typeName); + } + + boolean callResult = Kernel32.INSTANCE.EnumResourceNames(target, pointer, ernp, null); + + if (!callResult) { + throw new Win32Exception(Kernel32.INSTANCE.GetLastError()); + } + } + } catch (Win32Exception e) { + err = e; + } 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 result; + } + } diff --git a/contrib/platform/src/com/sun/jna/platform/win32/LMAccess.java b/contrib/platform/src/com/sun/jna/platform/win32/LMAccess.java index ccd7259a31..badd31e365 100644 --- a/contrib/platform/src/com/sun/jna/platform/win32/LMAccess.java +++ b/contrib/platform/src/com/sun/jna/platform/win32/LMAccess.java @@ -17,16 +17,14 @@ import com.sun.jna.Pointer; import com.sun.jna.Structure; -import com.sun.jna.WString; import com.sun.jna.platform.win32.WinNT.PSID; -import com.sun.jna.win32.StdCallLibrary; /** * Ported from LMAccess.h. * Windows SDK 6.0A. * @author dblock[at]dblock.org */ -public interface LMAccess extends StdCallLibrary { +public interface LMAccess { public static class LOCALGROUP_INFO_0 extends Structure { public LOCALGROUP_INFO_0() { @@ -38,7 +36,7 @@ public LOCALGROUP_INFO_0(Pointer memory) { read(); } - public WString lgrui0_name; + public String lgrui0_name; protected List getFieldOrder() { return Arrays.asList(new String[] { "lgrui0_name" }); @@ -55,8 +53,8 @@ public LOCALGROUP_INFO_1(Pointer memory) { read(); } - public WString lgrui1_name; - public WString lgrui1_comment; + public String lgrui1_name; + public String lgrui1_comment; protected List getFieldOrder() { return Arrays.asList(new String[] { "lgrui1_name", "lgrui1_comment" }); } @@ -89,7 +87,7 @@ public USER_INFO_0(Pointer memory) { /** * Pointer to a Unicode string that specifies the name of the user account. */ - public WString usri0_name; + public String usri0_name; protected List getFieldOrder() { return Arrays.asList(new String[] { "usri0_name" }); } @@ -114,12 +112,12 @@ public USER_INFO_1(Pointer memory) { * Pointer to a Unicode string that specifies the name of the user * account. */ - public WString usri1_name; + public String usri1_name; /** * Pointer to a Unicode string that specifies the password of the user * indicated by the usri1_name member. */ - public WString usri1_password; + public String usri1_password; /** * Specifies a DWORD value that indicates the number of seconds that have * elapsed since the usri1_password member was last changed. @@ -134,12 +132,12 @@ public USER_INFO_1(Pointer memory) { * Pointer to a Unicode string specifying the path of the home directory * for the user specified in the usri1_name member. */ - public WString usri1_home_dir; + public String usri1_home_dir; /** * Pointer to a Unicode string that contains a comment to associate with * the user account. */ - public WString usri1_comment; + public String usri1_comment; /** * Specifies a DWORD value that determines several features. */ @@ -148,7 +146,7 @@ public USER_INFO_1(Pointer memory) { * Pointer to a Unicode string specifying the path for the user's * logon script file. */ - public WString usri1_script_path; + public String usri1_script_path; protected List getFieldOrder() { return Arrays.asList(new String[] { "usri1_name", "usri1_password", "usri1_password_age", "usri1_priv", "usri1_home_dir", "usri1_comment", "usri1_flags", "usri1_script_path" }); @@ -178,17 +176,17 @@ public USER_INFO_23(Pointer memory) { * A pointer to a Unicode string that specifies the name of the user account. * Calls to the NetUserSetInfo function ignore this member. */ - public WString usri23_name; + public String usri23_name; /** * A pointer to a Unicode string that contains the full name of the user. * This string can be a null string, or it can have any number of characters before the terminating null character. */ - public WString usri23_full_name; + public String usri23_full_name; /** * A pointer to a Unicode string that contains a comment associated with the user account. * This string can be a null string, or it can have any number of characters before the terminating null character. */ - public WString usri23_comment; + public String usri23_comment; /** * This member can be one or more of the following values. * Note that setting user account control flags may require certain privileges and control access rights. @@ -246,7 +244,7 @@ public GROUP_USERS_INFO_0(Pointer memory) { /** * Pointer to a null-terminated Unicode character string that specifies a name. */ - public WString grui0_name; + public String grui0_name; protected List getFieldOrder() { return Arrays.asList(new String[] { "grui0_name" }); @@ -269,7 +267,7 @@ public LOCALGROUP_USERS_INFO_0(Pointer memory) { /** * Pointer to a Unicode string specifying the name of a local group to which the user belongs. */ - public WString lgrui0_name; + public String lgrui0_name; protected List getFieldOrder() { return Arrays.asList(new String[] { "lgrui0_name" }); @@ -295,7 +293,7 @@ public GROUP_INFO_0(Pointer memory) { * Pointer to a null-terminated Unicode character string that specifies * the name of the global group. */ - public WString grpi0_name; + public String grpi0_name; protected List getFieldOrder() { return Arrays.asList(new String[] { "grpi0_name" }); @@ -320,13 +318,13 @@ public GROUP_INFO_1(Pointer memory) { * Pointer to a null-terminated Unicode character string that specifies * the name of the global group. */ - public WString grpi1_name; + public String grpi1_name; /** * Pointer to a null-terminated Unicode character string that specifies * a remark associated with the global group. This member can be a null * string. The comment can contain MAXCOMMENTSZ characters. */ - public WString grpi1_comment; + public String grpi1_comment; protected List getFieldOrder() { return Arrays.asList(new String[] { "grpi1_name", "grpi1_comment" }); @@ -351,13 +349,13 @@ public GROUP_INFO_2(Pointer memory) { * Pointer to a null-terminated Unicode character string that * specifies the name of the global group. */ - public WString grpi2_name; + public String grpi2_name; /** * Pointer to a null-terminated Unicode character string that contains a * remark associated with the global group. This member can be a null string. * The comment can contain MAXCOMMENTSZ characters. */ - public WString grpi2_comment; + public String grpi2_comment; /** * Specifies a DWORD value that contains the relative identifier (RID) of * the global group. @@ -392,13 +390,13 @@ public GROUP_INFO_3(Pointer memory) { * Pointer to a null-terminated Unicode character string that * specifies the name of the global group. */ - public WString grpi3_name; + public String grpi3_name; /** * Pointer to a null-terminated Unicode character string that * contains a remark associated with the global group. This member can be * a null string. The comment can contain MAXCOMMENTSZ characters. */ - public WString grpi3_comment; + public String grpi3_comment; /** * Pointer to a SID structure that contains the security identifier (SID) that * uniquely identifies the global group. @@ -422,5 +420,22 @@ protected List getFieldOrder() { int USER_PRIV_MASK = 3; int USER_PRIV_GUEST = 0; int USER_PRIV_USER = 1; - int USER_PRIV_ADMIN = 2; + int USER_PRIV_ADMIN = 2; + + // + // Bit values for the access permissions. ACCESS_ALL is a handy + // way to specify maximum permissions. These are used in + // acl_access field of access_list structures. + // + + int ACCESS_NONE = 0x00; + int ACCESS_READ = 0x01; + int ACCESS_WRITE = 0x02; + int ACCESS_CREATE = 0x04; + int ACCESS_EXEC = 0x08; + int ACCESS_DELETE = 0x10; + int ACCESS_ATRIB = 0x20; + int ACCESS_PERM = 0x40; + int ACCESS_ALL = ACCESS_READ | ACCESS_WRITE | ACCESS_CREATE | ACCESS_EXEC | ACCESS_DELETE | ACCESS_ATRIB | ACCESS_PERM; + int ACCESS_GROUP = 0x8000; } diff --git a/contrib/platform/src/com/sun/jna/platform/win32/LMCons.java b/contrib/platform/src/com/sun/jna/platform/win32/LMCons.java index cbfd186efb..dbf8c82575 100644 --- a/contrib/platform/src/com/sun/jna/platform/win32/LMCons.java +++ b/contrib/platform/src/com/sun/jna/platform/win32/LMCons.java @@ -12,14 +12,12 @@ */ package com.sun.jna.platform.win32; -import com.sun.jna.win32.StdCallLibrary; - /** * Ported from LMCons.h. * @author dblock[at]dblock.org * Windows SDK 6.0A */ -public interface LMCons extends StdCallLibrary { +public interface LMCons { int NETBIOS_NAME_LEN = 16; // NetBIOS net name (bytes) /** diff --git a/contrib/platform/src/com/sun/jna/platform/win32/LMErr.java b/contrib/platform/src/com/sun/jna/platform/win32/LMErr.java index cfbd30f95d..4e595e348d 100644 --- a/contrib/platform/src/com/sun/jna/platform/win32/LMErr.java +++ b/contrib/platform/src/com/sun/jna/platform/win32/LMErr.java @@ -12,14 +12,12 @@ */ package com.sun.jna.platform.win32; -import com.sun.jna.win32.StdCallLibrary; - /** * Ported from LMErr.h. * @author dblock[at]dblock.org * Windows SDK 6.0A */ -public interface LMErr extends StdCallLibrary { +public interface LMErr { int NERR_Success = 0; int NERR_BASE = 2100; diff --git a/contrib/platform/src/com/sun/jna/platform/win32/LMJoin.java b/contrib/platform/src/com/sun/jna/platform/win32/LMJoin.java index 2eccc337f6..dab5cc5ddb 100644 --- a/contrib/platform/src/com/sun/jna/platform/win32/LMJoin.java +++ b/contrib/platform/src/com/sun/jna/platform/win32/LMJoin.java @@ -12,14 +12,12 @@ */ package com.sun.jna.platform.win32; -import com.sun.jna.win32.StdCallLibrary; - /** * Ported from LMJoin.h. * Windows SDK 6.0A. * @author dblock[at]dblock.org */ -public interface LMJoin extends StdCallLibrary { +public interface LMJoin { /** * Status of a workstation. diff --git a/contrib/platform/src/com/sun/jna/platform/win32/LMShare.java b/contrib/platform/src/com/sun/jna/platform/win32/LMShare.java new file mode 100644 index 0000000000..bd6ce1a9d5 --- /dev/null +++ b/contrib/platform/src/com/sun/jna/platform/win32/LMShare.java @@ -0,0 +1,225 @@ +/* Copyright (c) 2015 Adam Marcionek, 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. + */ +package com.sun.jna.platform.win32; + +import java.util.Arrays; +import java.util.List; + +import com.sun.jna.Pointer; +import com.sun.jna.Structure; +import com.sun.jna.win32.StdCallLibrary; + +/** + * Ported from LMShare.h. + * Windows SDK 7.1 + * @author amarcionek[at]seven10storage.com + */ +public interface LMShare { + + // + // Share types (shi1_type and shi2_type fields). + // + + /** + * Disk Drive. + */ + int STYPE_DISKTREE = 0; + + /** + * Print Queue. + */ + int STYPE_PRINTQ = 1; + + /** + * Communication device. + */ + int STYPE_DEVICE = 2; + + /** + * Interprocess communication (IPC). + */ + int STYPE_IPC = 3; + + /** + * A temporary share. + */ + int STYPE_TEMPORARY = 0x40000000; + + /** + * Special share reserved for interprocess communication (IPC$) or remote administration of the server (ADMIN$). + * Can also refer to administrative shares such as C$, D$, E$, and so forth. For more information, see the network share functions. + */ + int STYPE_SPECIAL = 0x80000000; + + /** + * Contains information about the shared resource, including name of the resource, type and permissions, number of connections, and other pertinent information. + */ + public static class SHARE_INFO_2 extends Structure { + public SHARE_INFO_2() { + super(); + } + + public SHARE_INFO_2(Pointer memory) { + super(memory); + read(); + } + + /** + * Pointer to a Unicode string specifying the name of a shared resource. Calls to the NetShareSetInfo function ignore this member. + */ + public String shi2_netname; + + /** + * A combination of values that specify the type of share. Calls to the NetShareSetInfo function ignore this member. + * One of the following values may be specified. You can isolate these values by using the STYPE_MASK value. + * STYPE_DISKTREE, STYPE_PRINTQ, STYPE_DEVICE, STYPE_IPC, STYPE_TEMPORARY, STYPE_SPECIAL + */ + public int shi2_type; + + /** + * Pointer to a Unicode string specifying an optional comment about the shared resource. + */ + public String shi2_remark; + + /** + * Specifies a DWORD value that indicates the shared resource's permissions for servers running with share-level security. + * This member is ignored on a server running user-level security. This member can be any of the following values. + * Calls to the NetShareSetInfo function ignore this member. Note that Windows does not support share-level security. + * For more information about controlling access to securable objects, see Access Control, Privileges, and Securable Objects. + * NOTE: Bit masks are defined in LmAccess.Java + */ + public int shi2_permissions; + + /** + * Specifies a DWORD value that indicates the maximum number of concurrent connections that the shared resource can accommodate. + * The number of connections is unlimited if the value specified in this member is -1. + */ + public int shi2_max_uses; + + /** + * Specifies a DWORD value that indicates the number of current connections to the resource. Calls to the NetShareSetInfo function ignore this member. + */ + public int shi2_current_uses; + + /** + * Pointer to a Unicode string that contains the local path for the shared resource. For disks, this member is the path being shared. + * For print queues, this member is the name of the print queue being shared. Calls to the NetShareSetInfo function ignore this member. + */ + public String shi2_path; + + /** + * Pointer to a Unicode string that specifies the share's password (when the server is running with share-level security). If the server is + * running with user-level security, this member is ignored. Note that Windows does not support share-level security. + * This member can be no longer than SHPWLEN+1 bytes (including a terminating null character). Calls to the NetShareSetInfo function ignore this member. + */ + public String shi2_passwd; + + protected List getFieldOrder() { + return Arrays.asList(new String[] { "shi2_netname", + "shi2_type", + "shi2_remark", + "shi2_permissions", + "shi2_max_uses", + "shi2_current_uses", + "shi2_path", + "shi2_passwd" }); + } + } + + /** + * Contains information about the shared resource, including name of the resource, type and permissions, number of connections, and other pertinent information. + */ + public static class SHARE_INFO_502 extends Structure { + public SHARE_INFO_502() { + super(); + } + + public SHARE_INFO_502(Pointer memory) { + super(memory); + read(); + } + + /** + * Pointer to a Unicode string specifying the name of a shared resource. Calls to the NetShareSetInfo function ignore this member. + */ + public String shi502_netname; + + /** + * A combination of values that specify the type of share. Calls to the NetShareSetInfo function ignore this member. + * One of the following values may be specified. You can isolate these values by using the STYPE_MASK value. + * STYPE_DISKTREE, STYPE_PRINTQ, STYPE_DEVICE, STYPE_IPC, STYPE_TEMPORARY, STYPE_SPECIAL + */ + public int shi502_type; + + /** + * Pointer to a Unicode string specifying an optional comment about the shared resource. + */ + public String shi502_remark; + + /** + * Specifies a DWORD value that indicates the shared resource's permissions for servers running with share-level security. + * This member is ignored on a server running user-level security. This member can be any of the following values. + * Calls to the NetShareSetInfo function ignore this member. Note that Windows does not support share-level security. + * For more information about controlling access to securable objects, see Access Control, Privileges, and Securable Objects. + * NOTE: Bit masks are defined in LmAccess.Java + */ + public int shi502_permissions; + + /** + * Specifies a DWORD value that indicates the maximum number of concurrent connections that the shared resource can accommodate. + * The number of connections is unlimited if the value specified in this member is -1. + */ + public int shi502_max_uses; + + /** + * Specifies a DWORD value that indicates the number of current connections to the resource. Calls to the NetShareSetInfo function ignore this member. + */ + public int shi502_current_uses; + + /** + * Pointer to a Unicode string that contains the local path for the shared resource. For disks, this member is the path being shared. + * For print queues, this member is the name of the print queue being shared. Calls to the NetShareSetInfo function ignore this member. + */ + public String shi502_path; + + /** + * Pointer to a Unicode string that specifies the share's password (when the server is running with share-level security). If the server is + * running with user-level security, this member is ignored. Note that Windows does not support share-level security. + * This member can be no longer than SHPWLEN+1 bytes (including a terminating null character). Calls to the NetShareSetInfo function ignore this member. + */ + public String shi502_passwd; + + /** + * Reserved; must be zero. Calls to the NetShareSetInfo function ignore this member. + */ + public int shi502_reserved; + + /** + * Specifies the SECURITY_DESCRIPTOR associated with this share. + */ + public Pointer shi502_security_descriptor; + + protected List getFieldOrder() { + return Arrays.asList(new String[] { "shi502_netname", + "shi502_type", + "shi502_remark", + "shi502_permissions", + "shi502_max_uses", + "shi502_current_uses", + "shi502_path", + "shi502_passwd", + "shi502_reserved", + "shi502_security_descriptor" }); + } + } +} diff --git a/contrib/platform/src/com/sun/jna/platform/win32/Mpr.java b/contrib/platform/src/com/sun/jna/platform/win32/Mpr.java new file mode 100644 index 0000000000..7929d050d4 --- /dev/null +++ b/contrib/platform/src/com/sun/jna/platform/win32/Mpr.java @@ -0,0 +1,420 @@ +/* Copyright (c) 2015 Adam Marcionek, 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. + */ + +package com.sun.jna.platform.win32; + +import com.sun.jna.Native; +import com.sun.jna.Pointer; +import com.sun.jna.platform.win32.WinDef.HWND; +import com.sun.jna.platform.win32.WinNT.HANDLE; +import com.sun.jna.platform.win32.WinNT.HANDLEByReference; +import com.sun.jna.platform.win32.Winnetwk.*; +import com.sun.jna.ptr.IntByReference; +import com.sun.jna.ptr.PointerByReference; +import com.sun.jna.win32.StdCallLibrary; +import com.sun.jna.win32.W32APIOptions; + +/** + * Ported from Winnetwk.h. Microsoft Windows SDK 8.1 + * + * @author amarcionek[at]gmail.com + */ + +public interface Mpr extends StdCallLibrary { + + Mpr INSTANCE = (Mpr) Native.loadLibrary("Mpr", Mpr.class, W32APIOptions.DEFAULT_OPTIONS); + + /** + * The WNetOpenEnum function starts an enumeration of network resources or + * existing connections. You can continue the enumeration by calling the + * WNetEnumResource function. + * + * @param dwScope + * Scope of the enumeration. This parameter can be one of the + * following values from NETRESOURCEScope: RESOURCE_CONNECTED, + * RESOURCE_CONTEXT, RESOURCE_GLOBALNET, RESOURCE_REMEMBERED + * @param dwType + * Resource types to be enumerated. This parameter can be a + * combination of the following values from NETRESOURCEType: + * RESOURCETYPE_ANY, RESOURCETYPE_DISK, RESOURCETYPE_PRINT + * @param dwUsage + * Resource usage type to be enumerated. This parameter can be a + * combination of the following values from NETRESOURCEUsage: 0, + * RESOURCEUSAGE_CONNECTABLE, RESOURCEUSAGE_CONTAINER, + * RESOURCEUSAGE_ATTACHED, RESOURCEUSAGE_ALL + * @param lpNETRESOURCE + * Pointer to a NETRESOURCE structure that specifies the + * container to enumerate. If the dwScope parameter is not + * RESOURCE_GLOBALNET, this parameter must be NULL. If this + * parameter is NULL, the root of the network is assumed. (The + * system organizes a network as a hierarchy; the root is the + * topmost container in the network.) If this parameter is not + * NULL, it must point to a NETRESOURCE structure. This structure + * can be filled in by the application or it can be returned by a + * call to the WNetEnumResource function. The NETRESOURCE + * structure must specify a container resource; that is, the + * RESOURCEUSAGE_CONTAINER value must be specified in the dwUsage + * parameter. To enumerate all network resources, an application + * can begin the enumeration by calling WNetOpenEnum with the + * lpNETRESOURCE parameter set to NULL, and then use the returned + * handle to call WNetEnumResource to enumerate resources. If one + * of the resources in the NETRESOURCE array returned by the + * WNetEnumResource function is a container resource, you can + * call WNetOpenEnum to open the resource for further + * enumeration. + * @param lphEnum + * Pointer to an enumeration handle that can be used in a + * subsequent call to WNetEnumResource. + * @return NO_ERROR if the function succeeds, otherwise a + * system error code. See MSDN documentation for common error + * values: + * https://msdn.microsoft.com/en-us/library/windows/desktop/aa385478 + * (v=vs.85).aspx + */ + public int WNetOpenEnum(int dwScope, int dwType, int dwUsage, NETRESOURCE.ByReference lpNETRESOURCE, HANDLEByReference lphEnum); + + /** + * The WNetEnumResource function continues an enumeration of network + * resources that was started by a call to the WNetOpenEnum function. + * + * @param hEnum + * [in] Handle that identifies an enumeration instance. This + * handle must be returned by the WNetOpenEnum function. + * @param lpcCount + * [in, out] Pointer to a variable specifying the number of + * entries requested. If the number requested is -1, the function + * returns as many entries as possible. If the function succeeds, + * on return the variable pointed to by this parameter contains + * the number of entries actually read. + * @param lpBuffer + * [out] Pointer to the buffer that receives the enumeration + * results. The results are returned as an array of NETRESOURCE + * structures. Note that the buffer you allocate must be large + * enough to hold the structures, plus the strings to which their + * members point. For more information, see the Remarks section + * on MSDN: + * https://msdn.microsoft.com/en-us/library/windows/desktop/ + * aa385449(v=vs.85).aspx The buffer is valid until the next call + * using the handle specified by the hEnum parameter. The order + * of NETRESOURCE structures in the array is not predictable. + * @param lpBufferSize + * [in, out] Pointer to a variable that specifies the size of the + * lpBuffer parameter, in bytes. If the buffer is too small to + * receive even one entry, this parameter receives the required + * size of the buffer. + * @return If the function succeeds, the return value is one of the + * following values: NO_ERROR - The enumeration succeeded, and the + * buffer contains the requested data. The calling application can + * continue to call WNetEnumResource to complete the enumeration. + * ERROR_NO_MORE_ITEMS - There are no more entries. The buffer + * contents are undefined. If the function fails, see MSDN + * documentation for common error values: + * https://msdn.microsoft.com/en-us/library/windows/desktop/aa385478 + * (v=vs.85).aspx + */ + public int WNetEnumResource(HANDLE hEnum, IntByReference lpcCount, Pointer lpBuffer, IntByReference lpBufferSize); + + /** + * The WNetCloseEnum function ends a network resource enumeration started by + * a call to the WNetOpenEnum function. + * + * @param hEnum + * [in] Handle that identifies an enumeration instance. This + * handle must be returned by the WNetOpenEnum function. + * @return NO_ERROR if the function succeeds, otherwise a + * system error code. See MSDN documentation for common error + * values: + * https://msdn.microsoft.com/en-us/library/windows/desktop/aa385431 + * (v=vs.85).aspx + */ + int WNetCloseEnum(HANDLE hEnum); + + /** + * The WNetGetUniversalName function takes a drive-based path for a network + * resource and returns an information structure that contains a more + * universal form of the name. + * + * @param lpLocalPath + * [in] A pointer to a constant null-terminated string that is a + * drive-based path for a network resource. For example, if drive + * H has been mapped to a network drive share, and the network + * resource of interest is a file named Sample.doc in the + * directory \Win32\Examples on that share, the drive-based path + * is H:\Win32\Examples\Sample.doc. + * @param dwInfoLevel + * [in] The type of structure that the function stores in the + * buffer pointed to by the lpBuffer parameter. This parameter + * can be one of the following values defined in the + * Winnetwk.java. UNIVERSAL_NAME_INFO_LEVEL - The function stores + * a UNIVERSAL_NAME_INFO structure in the buffer. + * REMOTE_NAME_INFO_LEVEL - The function stores a + * REMOTE_NAME_INFO structure in the buffer. The + * UNIVERSAL_NAME_INFO structure points to a Universal Naming + * Convention (UNC) name string. The REMOTE_NAME_INFO structure + * points to a UNC name string and two additional connection + * information strings. For more information, see the following + * Remarks section. + * @param lpBuffer + * [out] A pointer to a buffer that receives the structure + * specified by the dwInfoLevel parameter. + * @param lpBufferSize + * [in,out] A pointer to a variable that specifies the size, in + * bytes, of the buffer pointed to by the lpBuffer parameter. If + * the function succeeds, it sets the variable pointed to by + * lpBufferSize to the number of bytes stored in the buffer. If + * the function fails because the buffer is too small, this + * location receives the required buffer size, and the function + * returns ERROR_MORE_DATA. + * @return If the function succeeds, the return value is NO_ERROR, otherwise + * see MSDN for common error codes: + * https://msdn.microsoft.com/en-us/library/windows/desktop/aa385474 + * (v=vs.85).aspx + */ + int WNetGetUniversalName(String lpLocalPath, int dwInfoLevel, Pointer lpBuffer, IntByReference lpBufferSize); + + /** + * The WNetUseConnection function makes a connection to a network resource. + * The function can redirect a local device to a network resource. + * + * The WNetUseConnection function is similar to the WNetAddConnection3 + * function. The main difference is that WNetUseConnection can automatically + * select an unused local device to redirect to the network resource. + * + * @param hwndOwner + * [in] Handle to a window that the provider of network resources + * can use as an owner window for dialog boxes. Use this + * parameter if you set the CONNECT_INTERACTIVE value in the + * dwFlags parameter. + * @param lpNETRESOURCE + * [in] Pointer to a NETRESOURCE structure that specifies details + * of the proposed connection. The structure contains information + * about the network resource, the local device, and the network + * resource provider. + * + * You must specify the following members of the NETRESOURCE + * structure. The WNetUseConnection function ignores the other + * members of the NETRESOURCE structure. For more information, + * see the descriptions following for the dwFlags parameter. + * + * dwType Specifies the type of resource to connect to. It is + * most efficient to specify a resource type in this member, such + * as RESOURCETYPE_DISK or RESOURCETYPE_PRINT. However, if the + * lpLocalName member is NULL, or if it points to an empty string + * and CONNECT_REDIRECT is not set, dwType can be + * RESOURCETYPE_ANY. + * + * This method works only if the function does not automatically + * choose a device to redirect to the network resource. Although + * this member is required, its information may be ignored by the + * network service provider lpLocalName Pointer to a + * null-terminated string that specifies the name of a local + * device to be redirected, such as "F:" or "LPT1". The string is + * treated in a case-insensitive manner. If the string is empty, + * or if lpLocalName is NULL, a connection to the network occurs + * without redirection. If the CONNECT_REDIRECT value is set in + * the dwFlags parameter, or if the network requires a redirected + * local device, the function chooses a local device to redirect + * and returns the name of the device in the lpAccessName + * parameter. lpRemoveName Pointer to a null-terminated string + * that specifies the network resource to connect to. The string + * can be up to MAX_PATH characters in length, and it must follow + * the network provider's naming conventions. lpProvider Pointer + * to a null-terminated string that specifies the network + * provider to connect to. If lpProvider is NULL, or if it points + * to an empty string, the operating system attempts to determine + * the correct provider by parsing the string pointed to by the + * lpRemoteName member. If this member is not NULL, the operating + * system attempts to make a connection only to the named network + * provider. You should set this member only if you know the + * network provider you want to use. Otherwise, let the operating + * system determine which provider the network name maps to. + * @param lpPassword + * [in] Pointer to a constant null-terminated string that + * specifies a password to be used in making the network + * connection. If lpPassword is NULL, the function uses the + * current default password associated with the user specified by + * lpUserID. If lpPassword points to an empty string, the + * function does not use a password. If the connection fails + * because of an invalid password and the CONNECT_INTERACTIVE + * value is set in the dwFlags parameter, the function displays a + * dialog box asking the user to type the password. + * @param lpUserID + * [in] Pointer to a constant null-terminated string that + * specifies a user name for making the connection. If lpUserID + * is NULL, the function uses the default user name. (The user + * context for the process provides the default user name.) The + * lpUserID parameter is specified when users want to connect to + * a network resource for which they have been assigned a user + * name or account other than the default user name or account. + * The user-name string represents a security context. It may be + * specific to a network provider. For security context, see + * https://msdn.microsoft.com/en-us/library/windows/desktop/ + * ms721625(v=vs.85).aspx + * @param dwFlags + * [in] Set of bit flags describing the connection. This + * parameter can be any combination of the values in ConnectFlag. + * @param lpAccessName + * [out] Pointer to a buffer that receives system requests on the + * connection. This parameter can be NULL. If this parameter is + * specified, and the lpLocalName member of the NETRESOURCE + * structure specifies a local device, this buffer receives the + * local device name. If lpLocalName does not specify a device + * and the network requires a local device redirection, or if the + * CONNECT_REDIRECT value is set, this buffer receives the name + * of the redirected local device. Otherwise, the name copied + * into the buffer is that of a remote resource. If specified, + * this buffer must be at least as large as the string pointed to + * by the lpRemoteName member. + * @param lpBufferSize + * [in, out] Pointer to a variable that specifies the size of the + * lpAccessName buffer, in characters. If the call fails because + * the buffer is not large enough, the function returns the + * required buffer size in this location. For more information, + * see the descriptions of the lpAccessName parameter and the + * ERROR_MORE_DATA error code in the Return Values section. + * @param lpResult + * [out] Pointer to a variable that receives additional + * information about the connection. This parameter can be the + * following value: + * + * ConnectFlag.CONNECT_LOCALDRIVE - If this flag is set, the + * connection was made using a local device redirection. If the + * lpAccessName parameter points to a buffer, the local device + * name is copied to the buffer. + * @return NO_ERROR if the function succeeds, otherwise a + * system error code. See MSDN documentation for common error + * values: + * https://msdn.microsoft.com/en-us/library/windows/desktop/aa385482 + * (v=vs.85).aspx + */ + public int WNetUseConnection(HWND hwndOwner, NETRESOURCE lpNETRESOURCE, String lpPassword, String lpUserID, int dwFlags, + PointerByReference lpAccessName, IntByReference lpBufferSize, IntByReference lpResult); + + /** + * The WNetAddConnection3 function makes a connection to a network resource. + * The function can redirect a local device to the network resource. + * + * @param hwndOwner + * [in] Handle to a window that the provider of network resources + * can use as an owner window for dialog boxes. Use this + * parameter if you set the CONNECT_INTERACTIVE value in the + * dwFlags parameter. + * @param lpNETRESOURCE + * [in] Pointer to a NETRESOURCE structure that specifies details + * of the proposed connection. The structure contains information + * about the network resource, the local device, and the network + * resource provider. + * + * You must specify the following members of the NETRESOURCE + * structure. The WNetUseConnection function ignores the other + * members of the NETRESOURCE structure. For more information, + * see the descriptions following for the dwFlags parameter. + * + * dwType Specifies the type of resource to connect to. It is + * most efficient to specify a resource type in this member, such + * as RESOURCETYPE_DISK or RESOURCETYPE_PRINT. However, if the + * lpLocalName member is NULL, or if it points to an empty string + * and CONNECT_REDIRECT is not set, dwType can be + * RESOURCETYPE_ANY. + * + * This method works only if the function does not automatically + * choose a device to redirect to the network resource. Although + * this member is required, its information may be ignored by the + * network service provider lpLocalName Pointer to a + * null-terminated string that specifies the name of a local + * device to be redirected, such as "F:" or "LPT1". The string is + * treated in a case-insensitive manner. If the string is empty, + * or if lpLocalName is NULL, a connection to the network occurs + * without redirection. If the CONNECT_REDIRECT value is set in + * the dwFlags parameter, or if the network requires a redirected + * local device, the function chooses a local device to redirect + * and returns the name of the device in the lpAccessName + * parameter. lpRemoveName Pointer to a null-terminated string + * that specifies the network resource to connect to. The string + * can be up to MAX_PATH characters in length, and it must follow + * the network provider's naming conventions. lpProvider Pointer + * to a null-terminated string that specifies the network + * provider to connect to. If lpProvider is NULL, or if it points + * to an empty string, the operating system attempts to determine + * the correct provider by parsing the string pointed to by the + * lpRemoteName member. If this member is not NULL, the operating + * system attempts to make a connection only to the named network + * provider. You should set this member only if you know the + * network provider you want to use. Otherwise, let the operating + * system determine which provider the network name maps to. + * @param lpPassword + * [in] Pointer to a constant null-terminated string that + * specifies a password to be used in making the network + * connection. If lpPassword is NULL, the function uses the + * current default password associated with the user specified by + * lpUserID. If lpPassword points to an empty string, the + * function does not use a password. If the connection fails + * because of an invalid password and the CONNECT_INTERACTIVE + * value is set in the dwFlags parameter, the function displays a + * dialog box asking the user to type the password. + * @param lpUserID + * [in] Pointer to a constant null-terminated string that + * specifies a user name for making the connection. If lpUserID + * is NULL, the function uses the default user name. (The user + * context for the process provides the default user name.) The + * lpUserID parameter is specified when users want to connect to + * a network resource for which they have been assigned a user + * name or account other than the default user name or account. + * The user-name string represents a security context. It may be + * specific to a network provider. For security context, see + * https://msdn.microsoft.com/en-us/library/windows/desktop/ + * ms721625(v=vs.85).aspx + * @param dwFlags + * [in] Set of bit flags describing the connection. This + * parameter can be any combination of the values in ConnectFlag. + */ + public int WNetAddConnection3(HWND hwndOwner, NETRESOURCE lpNETRESOURCE, String lpPassword, String lpUserID, int dwFlags); + + /** + * The WNetCancelConnection2 function cancels an existing network + * connection. You can also call the function to remove remembered network + * connections that are not currently connected. + * + * @param lpName + * [in] Pointer to a constant null-terminated string that + * specifies the name of either the redirected local device or + * the remote network resource to disconnect from. If this + * parameter specifies a redirected local device, the function + * cancels only the specified device redirection. If the + * parameter specifies a remote network resource, all connections + * without devices are canceled. + * @param dwFlags + * [in] Connection type. The following values are defined. 0 - + * The system does not update information about the connection. + * If the connection was marked as persistent in the registry, + * the system continues to restore the connection at the next + * logon. If the connection was not marked as persistent, the + * function ignores the setting of the CONNECT_UPDATE_PROFILE + * flag. CONNECT_UPDATE_PROFILE - The system updates the user + * profile with the information that the connection is no longer + * a persistent one. The system will not restore this connection + * during subsequent logon operations. (Disconnecting resources + * using remote names has no effect on persistent connections.) + * @param fForce + * [in] Specifies whether the disconnection should occur if there + * are open files or jobs on the connection. If this parameter is + * FALSE, the function fails if there are open files or jobs. + * @return NO_ERROR if the function succeeds, otherwise a + * system error code. See MSDN documentation for common error + * values: + * https://msdn.microsoft.com/en-us/library/windows/desktop/aa385482 + * (v=vs.85).aspx + */ + public int WNetCancelConnection2(String lpName, int dwFlags, boolean fForce); +} diff --git a/contrib/platform/src/com/sun/jna/platform/win32/Msi.java b/contrib/platform/src/com/sun/jna/platform/win32/Msi.java index 2874918569..7fc72b2937 100644 --- a/contrib/platform/src/com/sun/jna/platform/win32/Msi.java +++ b/contrib/platform/src/com/sun/jna/platform/win32/Msi.java @@ -21,7 +21,7 @@ public interface Msi extends StdCallLibrary { Msi INSTANCE = (Msi) - Native.loadLibrary("msi", Msi.class, W32APIOptions.UNICODE_OPTIONS); + Native.loadLibrary("msi", Msi.class, W32APIOptions.DEFAULT_OPTIONS); /** * The component being requested is disabled on the computer. diff --git a/contrib/platform/src/com/sun/jna/platform/win32/NTSecApi.java b/contrib/platform/src/com/sun/jna/platform/win32/NTSecApi.java index c76db51ae2..425f7ab6f1 100644 --- a/contrib/platform/src/com/sun/jna/platform/win32/NTSecApi.java +++ b/contrib/platform/src/com/sun/jna/platform/win32/NTSecApi.java @@ -21,14 +21,13 @@ import com.sun.jna.Union; import com.sun.jna.platform.win32.WinNT.LARGE_INTEGER; import com.sun.jna.platform.win32.WinNT.PSID; -import com.sun.jna.win32.StdCallLibrary; /** * Ported from NTSecApi.h * Windows SDK 6.0A. * @author dblock[at]dblock.org */ -public interface NTSecApi extends StdCallLibrary { +public interface NTSecApi { /** * The LSA_UNICODE_STRING structure is used by various Local Security Authority (LSA) diff --git a/contrib/platform/src/com/sun/jna/platform/win32/Netapi32.java b/contrib/platform/src/com/sun/jna/platform/win32/Netapi32.java index 2bd667ba60..161edd1cc9 100644 --- a/contrib/platform/src/com/sun/jna/platform/win32/Netapi32.java +++ b/contrib/platform/src/com/sun/jna/platform/win32/Netapi32.java @@ -30,7 +30,7 @@ public interface Netapi32 extends StdCallLibrary { Netapi32 INSTANCE = (Netapi32) Native.loadLibrary("Netapi32", - Netapi32.class, W32APIOptions.UNICODE_OPTIONS); + Netapi32.class, W32APIOptions.DEFAULT_OPTIONS); /** * Retrieves join status information for the specified computer. @@ -426,6 +426,44 @@ public int DsEnumerateDomainTrusts(String serverName, int Flags, * @return * If the function succeeds, the return value is NERR_Success. */ - public int NetUserGetInfo( String servername, String username, int level, PointerByReference bufptr ); - + public int NetUserGetInfo(String servername, String username, int level, PointerByReference bufptr); + + /** + * Shares a server resource. + * + * @param servername [in] + * Pointer to a string that specifies the DNS or NetBIOS name of the remote server on which the function is to execute. + * If this parameter is NULL, the local computer is used. + * @param level [in] + * Specifies the information level of the data. This parameter can be one of the following values: + * 2 - Specifies information about the shared resource, including the name of the resource, type and permissions, and number of connections. + * The buf parameter points to a SHARE_INFO_2 structure. + * 502 - Specifies information about the shared resource, including the name of the resource, type and permissions, number of connections, and other pertinent information. + * The buf parameter points to a SHARE_INFO_502 structure. + * 503 - Specifies information about the shared resource, including the name of the resource, type and permissions, number of connections, and other pertinent information. + * The buf parameter points to a SHARE_INFO_503 structure. + * @param buf [in] + * Pointer to the buffer that specifies the data. The format of this data depends on the value of the level parameter. + * For more information, see Network Management Function Buffers (https://msdn.microsoft.com/en-us/library/windows/desktop/aa370676(v=vs.85).aspx) + * @param parm_err [out] + * Pointer to a value that receives the index of the first member of the share information structure that causes the ERROR_INVALID_PARAMETER error. If this parameter is NULL, the + * index is not returned on error. For more information, see the NetShareSetInfo function. + * @return If the function succeeds, the return value is NERR_Success. If the function fails, the return value can be an error code as seen on MSDN. + */ + public int NetShareAdd(String servername, int level, Pointer buf, IntByReference parm_err); + + /** + * Deletes a share name from a server's list of shared resources, disconnecting all connections to the shared resource. + * + * @param servername [in] + * Pointer to a string that specifies the DNS or NetBIOS name of the remote server on which the function is to execute. + * If this parameter is NULL, the local computer is used. + * @param netname [in] + * Pointer to a string that specifies the name of the share to delete. + * @param reserved + * Reserved, must be zero. + * @return If the function succeeds, the return value is LMErr.NERR_Success. + * If the function fails, the return value can be an error code as seen on MSDN. + */ + public int NetShareDel(String servername, String netname, int reserved); } diff --git a/contrib/platform/src/com/sun/jna/platform/win32/NtDll.java b/contrib/platform/src/com/sun/jna/platform/win32/NtDll.java index bd69134ca6..e25e6e7adb 100644 --- a/contrib/platform/src/com/sun/jna/platform/win32/NtDll.java +++ b/contrib/platform/src/com/sun/jna/platform/win32/NtDll.java @@ -26,7 +26,7 @@ public interface NtDll extends StdCallLibrary { NtDll INSTANCE = (NtDll) Native.loadLibrary("NtDll", - NtDll.class, W32APIOptions.UNICODE_OPTIONS); + NtDll.class, W32APIOptions.DEFAULT_OPTIONS); /** * The ZwQueryKey routine provides information about the class of a registry key, @@ -52,4 +52,4 @@ public interface NtDll extends StdCallLibrary { */ public int ZwQueryKey(HANDLE KeyHandle, int KeyInformationClass, Structure KeyInformation, int Length, IntByReference ResultLength); -} \ No newline at end of file +} diff --git a/contrib/platform/src/com/sun/jna/platform/win32/Ole32.java b/contrib/platform/src/com/sun/jna/platform/win32/Ole32.java index 90eb10f0ac..3df89c47af 100644 --- a/contrib/platform/src/com/sun/jna/platform/win32/Ole32.java +++ b/contrib/platform/src/com/sun/jna/platform/win32/Ole32.java @@ -34,7 +34,7 @@ public interface Ole32 extends StdCallLibrary { /** The instance. */ Ole32 INSTANCE = (Ole32) Native.loadLibrary("Ole32", Ole32.class, - W32APIOptions.UNICODE_OPTIONS); + W32APIOptions.DEFAULT_OPTIONS); /** * Creates a GUID, a unique 128-bit integer used for CLSIDs and interface @@ -217,6 +217,8 @@ HRESULT CoCreateInstance(GUID rclsid, Pointer pUnkOuter, int dwClsContext, * * REGDB_E_READREGDB The registry could not be opened for reading. */ + HRESULT CLSIDFromString(String lpsz, CLSID.ByReference pclsid); + /** @deprecated use the String version */ HRESULT CLSIDFromString(WString lpsz, CLSID.ByReference pclsid); /** diff --git a/contrib/platform/src/com/sun/jna/platform/win32/OleAuto.java b/contrib/platform/src/com/sun/jna/platform/win32/OleAuto.java index 4a992ffb33..7cec6e09f7 100644 --- a/contrib/platform/src/com/sun/jna/platform/win32/OleAuto.java +++ b/contrib/platform/src/com/sun/jna/platform/win32/OleAuto.java @@ -100,7 +100,7 @@ public interface OleAuto extends StdCallLibrary { /** The instance. */ OleAuto INSTANCE = (OleAuto) Native.loadLibrary("OleAut32", OleAuto.class, - W32APIOptions.UNICODE_OPTIONS); + W32APIOptions.DEFAULT_OPTIONS); /** * This function allocates a new string and copies the passed string into @@ -473,6 +473,8 @@ public HRESULT LoadRegTypeLib(GUID rguid, int wVerMajor, int wVerMinor, * loaded. * @return status */ + public HRESULT LoadTypeLib(String szFile, PointerByReference pptlib); + /** @deprecated use the String version */ public HRESULT LoadTypeLib(WString szFile, PointerByReference pptlib); /** diff --git a/contrib/platform/src/com/sun/jna/platform/win32/Pdh.java b/contrib/platform/src/com/sun/jna/platform/win32/Pdh.java index 1c28fb02e1..99af9441ae 100644 --- a/contrib/platform/src/com/sun/jna/platform/win32/Pdh.java +++ b/contrib/platform/src/com/sun/jna/platform/win32/Pdh.java @@ -33,7 +33,7 @@ */ public interface Pdh extends StdCallLibrary { Pdh INSTANCE = (Pdh) Native.loadLibrary("Pdh", - Pdh.class, W32APIOptions.UNICODE_OPTIONS); + Pdh.class, W32APIOptions.DEFAULT_OPTIONS); /** Maximum counter name length. */ diff --git a/contrib/platform/src/com/sun/jna/platform/win32/Rasapi32.java b/contrib/platform/src/com/sun/jna/platform/win32/Rasapi32.java index e8388789e6..a0ca394abe 100644 --- a/contrib/platform/src/com/sun/jna/platform/win32/Rasapi32.java +++ b/contrib/platform/src/com/sun/jna/platform/win32/Rasapi32.java @@ -33,7 +33,7 @@ * Rasapi32.dll Interface. */ public interface Rasapi32 extends StdCallLibrary { - Rasapi32 INSTANCE = (Rasapi32) Native.loadLibrary("Rasapi32", Rasapi32.class, W32APIOptions.UNICODE_OPTIONS); + Rasapi32 INSTANCE = (Rasapi32) Native.loadLibrary("Rasapi32", Rasapi32.class, W32APIOptions.DEFAULT_OPTIONS); /** * The RasDial function establishes a RAS connection between a RAS client and a RAS server. diff --git a/contrib/platform/src/com/sun/jna/platform/win32/Secur32.java b/contrib/platform/src/com/sun/jna/platform/win32/Secur32.java index 3444fcc857..c63c203033 100644 --- a/contrib/platform/src/com/sun/jna/platform/win32/Secur32.java +++ b/contrib/platform/src/com/sun/jna/platform/win32/Secur32.java @@ -30,7 +30,7 @@ * @author dblock[at]dblock.org */ public interface Secur32 extends StdCallLibrary { - Secur32 INSTANCE = (Secur32) Native.loadLibrary("Secur32", Secur32.class, W32APIOptions.UNICODE_OPTIONS); + Secur32 INSTANCE = (Secur32) Native.loadLibrary("Secur32", Secur32.class, W32APIOptions.DEFAULT_OPTIONS); /** * Specifies a format for a directory service object name. diff --git a/contrib/platform/src/com/sun/jna/platform/win32/Shell32.java b/contrib/platform/src/com/sun/jna/platform/win32/Shell32.java index a2b839c505..4ff066143f 100644 --- a/contrib/platform/src/com/sun/jna/platform/win32/Shell32.java +++ b/contrib/platform/src/com/sun/jna/platform/win32/Shell32.java @@ -30,8 +30,43 @@ public interface Shell32 extends ShellAPI, StdCallLibrary { Shell32 INSTANCE = (Shell32) Native.loadLibrary("shell32", Shell32.class, - W32APIOptions.UNICODE_OPTIONS); - + W32APIOptions.DEFAULT_OPTIONS); + + /** + * No dialog box confirming the deletion of the objects will be displayed. + */ + int SHERB_NOCONFIRMATION = 0x00000001; + + /** + * No dialog box indicating the progress will be displayed. + */ + int SHERB_NOPROGRESSUI = 0x00000002; + + /** + * No sound will be played when the operation is complete. + */ + int SHERB_NOSOUND = 0x00000004; + + /** + *

    + * SEE_MASK_NOCLOSEPROCESS (0x00000040) + *

    + *

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

    + */ + int SEE_MASK_NOCLOSEPROCESS = 0x00000040; + + /** + * Do not display an error message box if an error occurs. + */ + int SEE_MASK_FLAG_NO_UI = 0x00000400; + /** * This function can be used to copy, move, rename, or delete a file system object. * @param fileop @@ -238,4 +273,66 @@ INT_PTR ShellExecute(HWND hwnd, String lpOperation, String lpFile, String lpPara * */ UINT_PTR SHAppBarMessage( DWORD dwMessage, APPBARDATA pData ); + + /** + * Empties the Recycle Bin on the specified drive. + * + * @param hwnd + * A handle to the parent window of any dialog boxes that might + * be displayed during the operation.
    + * This parameter can be NULL. + * @param pszRootPath + * a null-terminated string of maximum length MAX_PATH that + * contains the path of the root
    + * drive on which the Recycle Bin is located. This parameter can + * contain a string formatted with the drive,
    + * folder, and subfolder names, for example c:\windows\system\, + * etc. It can also contain an empty string or
    + * NULL. If this value is an empty string or NULL, all Recycle + * Bins on all drives will be emptied. + * @param dwFlags + * a bitwise combination of SHERB_NOCONFIRMATION, + * SHERB_NOPROGRESSUI and SHERB_NOSOUND.
    + * @return Returns S_OK (0) if successful, or a COM-defined error value + * otherwise.
    + */ + int SHEmptyRecycleBin(HANDLE hwnd, String pszRootPath, int dwFlags); + + /** + * @param lpExecInfo + *

    + * Type: SHELLEXECUTEINFO* + *

    + *

    + * A pointer to a + * SHELLEXECUTEINFO + * structure that contains and receives information + * about the application being executed. + *

    + * @return + *

    + * Returns TRUE if successful; otherwise, + * FALSE. Call + * GetLastError + * for extended error information. + *

    + */ + boolean ShellExecuteEx(ShellAPI.SHELLEXECUTEINFO lpExecInfo); + + /* + * SHGetSpecialFolderLocation function for getting PIDL reference to My Computer etc + * + * @param hwndOwner + * Reserved. + * @param nFolder + * A CSIDL value that identifies the folder of interest. + * @param ppidl + * A PIDL specifying the folder's location relative to the root of the namespace (the desktop). It is the responsibility of the calling application to free the returned IDList by using CoTaskMemFree. + * + * @return If this function succeeds, it returns S_OK. Otherwise, it returns an HRESULT error code. + * + */ + WinNT.HRESULT SHGetSpecialFolderLocation(WinDef.HWND hwndOwner, int nFolder, PointerByReference ppidl); } diff --git a/contrib/platform/src/com/sun/jna/platform/win32/ShellAPI.java b/contrib/platform/src/com/sun/jna/platform/win32/ShellAPI.java index 5a06f64544..2495c97ee3 100644 --- a/contrib/platform/src/com/sun/jna/platform/win32/ShellAPI.java +++ b/contrib/platform/src/com/sun/jna/platform/win32/ShellAPI.java @@ -18,15 +18,17 @@ import com.sun.jna.Platform; import com.sun.jna.Pointer; import com.sun.jna.Structure; -import com.sun.jna.WString; +import com.sun.jna.TypeMapper; import com.sun.jna.platform.win32.WinDef.DWORD; +import com.sun.jna.platform.win32.WinDef.HINSTANCE; import com.sun.jna.platform.win32.WinDef.HWND; import com.sun.jna.platform.win32.WinDef.LPARAM; import com.sun.jna.platform.win32.WinDef.RECT; import com.sun.jna.platform.win32.WinDef.UINT; import com.sun.jna.platform.win32.WinNT.HANDLE; -import com.sun.jna.platform.win32.WinNT.PSID; +import com.sun.jna.platform.win32.WinReg.HKEY; import com.sun.jna.win32.StdCallLibrary; +import com.sun.jna.win32.W32APITypeMapper; /** * Ported from ShellAPI.h. @@ -36,6 +38,7 @@ public interface ShellAPI extends StdCallLibrary { int STRUCTURE_ALIGNMENT = Platform.is64Bit() ? Structure.ALIGN_DEFAULT : Structure.ALIGN_NONE; + TypeMapper TYPE_MAPPER = Boolean.getBoolean("w32.ascii") ? W32APITypeMapper.ASCII : W32APITypeMapper.UNICODE; int FO_MOVE = 0x0001; int FO_COPY = 0x0002; @@ -81,11 +84,11 @@ public static class SHFILEOPSTRUCT extends Structure { /** * A pointer to one or more source file names, double null-terminated. */ - public WString pFrom; + public String pFrom; /** * A pointer to the destination file or directory name. */ - public WString pTo; + public String pTo; /** * Flags that control the file operation. */ @@ -106,7 +109,7 @@ public static class SHFILEOPSTRUCT extends Structure { /** * A pointer to the title of a progress dialog box. This is a null-terminated string. */ - public WString lpszProgressTitle; + public String lpszProgressTitle; protected List getFieldOrder() { return Arrays.asList(new String[] { "hwnd", "wFunc", "pFrom", "pTo", "fFlags", "fAnyOperationsAborted", "pNameMappings", "lpszProgressTitle" }); @@ -209,4 +212,852 @@ protected List getFieldOrder() { } } + /** + *

    + * Contains information used by + * ShellExecuteEx. + *

    + * + *
    +	 * typedef struct _SHELLEXECUTEINFO {
    +	 *   DWORD     cbSize;
    +	 *   ULONG     fMask;
    +	 *   HWND      hwnd;
    +	 *   LPCTSTR   lpVerb;
    +	 *   LPCTSTR   lpFile;
    +	 *   LPCTSTR   lpParameters;
    +	 *   LPCTSTR   lpDirectory;
    +	 *   int       nShow;
    +	 *   HINSTANCE hInstApp;
    +	 *   LPVOID    lpIDList;
    +	 *   LPCTSTR   lpClass;
    +	 *   HKEY      hkeyClass;
    +	 *   DWORD     dwHotKey;
    +	 *   union {
    +	 *     HANDLE hIcon;
    +	 *     HANDLE hMonitor;
    +	 *   } DUMMYUNIONNAME;
    +	 *   HANDLE    hProcess;
    +	 * } SHELLEXECUTEINFO, *LPSHELLEXECUTEINFO;
    +	 * 
    + * + *

    Remarks

    + *

    + * The SEE_MASK_NOASYNC flag must be specified if the + * thread calling + * ShellExecuteEx + * does not have a message loop or if the thread or process will terminate + * soon after ShellExecuteEx returns. Under such + * conditions, the calling thread will not be available to complete the DDE + * conversation, so it is important that ShellExecuteEx + * complete the conversation before returning control to the calling + * application. Failure to complete the conversation can result in an + * unsuccessful launch of the document. + *

    + *

    + * If the calling thread has a message loop and will exist for some time + * after the call to + * ShellExecuteEx + * returns, the SEE_MASK_NOASYNC flag is optional. If the + * flag is omitted, the calling thread's message pump will be used to + * complete the DDE conversation. The calling application regains control + * sooner, since the DDE conversation can be completed in the background. + *

    + *

    + * When populating the most frequently used program list using the + * SEE_MASK_FLAG_LOG_USAGE flag in fMask, + * counts are made differently for the classic and Windows XP-style + * Start menus. The classic style menu only counts hits to the shortcuts in + * the Program menu. The Windows XP-style menu counts both hits to the + * shortcuts in the Program menu and hits to those shortcuts' targets + * outside of the Program menu. Therefore, setting lpFile + * to myfile.exe would affect the count for the Windows XP-style menu + * regardless of whether that file was launched directly or through a + * shortcut. The classic style-which would require lpFile + * to contain a .lnk file name-would not be affected. + *

    + *

    + * To include double quotation marks in lpParameters, + * enclose each mark in a pair of quotation marks, as in the following + * example. + *

    + *
    + *
    + *
    + * + *
    +	 * sei.lpParameters = "An example: \"\"\"quoted text\"\"\"";
    +	 * 
    + * + *
    + *

    + * In this case, the application receives three parameters: An, + * example:, and "quoted text". + *

    + */ + public class SHELLEXECUTEINFO extends Structure { + + /** + *

    + * Type: DWORD + *

    + *

    + * Required. The size of this structure, in bytes. + *

    + */ + public int cbSize = size(); + + /** + *

    + * Type: ULONG + *

    + *

    + * Flags that indicate the content and validity of the other structure + * members; a combination of the following values: + *

    + *
    + *
    + *

    + * SEE_MASK_DEFAULT (0x00000000) + *

    + *
    + *
    + *

    + * Use default values. + *

    + *
    + *
    + *

    + * SEE_MASK_CLASSNAME (0x00000001) + *

    + *
    + *
    + *

    + * Use the class name given by the lpClass member. If + * both SEE_MASK_CLASSKEY and SEE_MASK_CLASSNAME are set, the class key + * is used. + *

    + *
    + *
    + *

    + * SEE_MASK_CLASSKEY (0x00000003) + *

    + *
    + *
    + *

    + * Use the class key given by the hkeyClass member. If + * both SEE_MASK_CLASSKEY and SEE_MASK_CLASSNAME are set, the class key + * is used. + *

    + *
    + *
    + *

    + * SEE_MASK_IDLIST (0x00000004) + *

    + *
    + *
    + *

    + * Use the item identifier list given by the lpIDList + * member. The lpIDList member must point to an + * structure. + *

    + *
    + *
    + *

    + * SEE_MASK_INVOKEIDLIST (0x0000000C) + *

    + *
    + *
    + *

    + * Use the interface of the selected item's . Use either + * lpFile to identify the item by its file system path + * or lpIDList to identify the item by its PIDL. This + * flag allows applications to use to invoke verbs from shortcut menu + * extensions instead of the static verbs listed in the registry. + *

    + *
    Note + *   SEE_MASK_INVOKEIDLIST overrides and implies + * SEE_MASK_IDLIST.
    + *
    + *

    + * SEE_MASK_ICON (0x00000010) + *

    + *
    + *
    + *

    + * Use the icon given by the hIcon member. This flag + * cannot be combined with SEE_MASK_HMONITOR. + *

    + *
    Note  This flag is used + * only in Windows XP and earlier. It is ignored as of + * Windows Vista.
    + *
    + *

    + * SEE_MASK_HOTKEY (0x00000020) + *

    + *
    + *
    + *

    + * Use the keyboard shortcut given by the dwHotKey + * member. + *

    + *
    + *
    + *

    + * SEE_MASK_NOCLOSEPROCESS (0x00000040) + *

    + *
    + *
    + *

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

    + *
    + *
    + *

    + * SEE_MASK_CONNECTNETDRV (0x00000080) + *

    + *
    + *
    + *

    + * Validate the share and connect to a drive letter. This enables + * reconnection of disconnected network drives. The + * lpFile member is a UNC path of a file on a network. + *

    + *
    + *
    + *

    + * SEE_MASK_NOASYNC (0x00000100) + *

    + *
    + *
    + *

    + * Wait for the execute operation to complete before returning. This + * flag should be used by callers that are using ShellExecute forms that + * might result in an async activation, for example DDE, and create a + * process that might be run on a background thread. (Note: runs on a + * background thread by default if the caller's threading model is not + * Apartment.) Calls to ShellExecuteEx from processes + * already running on background threads should always pass this flag. + * Also, applications that exit immediately after calling + * ShellExecuteEx should specify this flag. + *

    + *

    + * If the execute operation is performed on a background thread and the + * caller did not specify the SEE_MASK_ASYNCOK flag, then the calling + * thread waits until the new process has started before returning. This + * typically means that either has been called, the DDE communication + * has completed, or that the custom execution delegate has notified + * that it is done. If the SEE_MASK_WAITFORINPUTIDLE flag is specified, + * then ShellExecuteEx calls and waits for the new + * process to idle before returning, with a maximum timeout of 1 minute. + *

    + *

    + * For further discussion on when this flag is necessary, see the + * Remarks section. + *

    + *
    + *
    + *

    + * SEE_MASK_FLAG_DDEWAIT (0x00000100) + *

    + *
    + *
    + *

    + * Do not use; use SEE_MASK_NOASYNC instead. + *

    + *
    + *
    + *

    + * SEE_MASK_DOENVSUBST (0x00000200) + *

    + *
    + *
    + *

    + * Expand any environment variables specified in the string given by the + * lpDirectory or lpFile member. + *

    + *
    + *
    + *

    + * SEE_MASK_FLAG_NO_UI (0x00000400) + *

    + *
    + *
    + *

    + * Do not display an error message box if an error occurs. + *

    + *
    + *
    + *

    + * SEE_MASK_UNICODE (0x00004000) + *

    + *
    + *
    + *

    + * Use this flag to indicate a Unicode application. + *

    + *
    + *
    + *

    + * SEE_MASK_NO_CONSOLE (0x00008000) + *

    + *
    + *
    + *

    + * Use to inherit the parent's console for the new process instead of + * having it create a new console. It is the opposite of using a + * CREATE_NEW_CONSOLE flag with . + *

    + *
    + *
    + *

    + * SEE_MASK_ASYNCOK (0x00100000) + *

    + *
    + *
    + *

    + * The execution can be performed on a background thread and the call + * should return immediately without waiting for the background thread + * to finish. Note that in certain cases ignores this flag and waits for + * the process to finish before returning. + *

    + *
    + *
    + *

    + * SEE_MASK_NOQUERYCLASSSTORE (0x01000000) + *

    + *
    + *
    + *

    + * Not used. + *

    + *
    + *
    + *

    + * SEE_MASK_HMONITOR (0x00200000) + *

    + *
    + *
    + *

    + * Use this flag when specifying a monitor on multi-monitor systems. The + * monitor is specified in the hMonitor member. This + * flag cannot be combined with SEE_MASK_ICON. + *

    + *
    + *
    + *

    + * SEE_MASK_NOZONECHECKS (0x00800000) + *

    + *
    + *
    + *

    + * Introduced in Windows XP. Do not perform a zone + * check. This flag allows to bypass zone checking put into place by . + *

    + *
    + *
    + *

    + * SEE_MASK_WAITFORINPUTIDLE (0x02000000) + *

    + *
    + *
    + *

    + * After the new process is created, wait for the process to become idle + * before returning, with a one minute timeout. See for more details. + *

    + *
    + *
    + *

    + * SEE_MASK_FLAG_LOG_USAGE (0x04000000) + *

    + *
    + *
    + *

    + * Introduced in Windows XP. Keep track of the + * number of times this application has been launched. Applications with + * sufficiently high counts appear in the Start Menu's list of most + * frequently used programs. + *

    + *
    + *
    + *

    + * SEE_MASK_FLAG_HINST_IS_SITE (0x08000000) + *

    + *
    + *
    + *

    + * Introduced in Windows 8. The + * hInstApp member is used to specify the of an object + * that implements . This object will be used as a site pointer. The + * site pointer is used to provide services to the function, the handler + * binding process, and invoked verb handlers. + *

    + *
    + *
    + */ + public int fMask; + + /** + *

    + * Type: HWND + *

    + *

    + * Optional. A handle to the parent window, used to display any message + * boxes that the system might produce while executing this function. + * This value can be NULL. + *

    + */ + public HWND hwnd; + + /** + *

    + * Type: LPCTSTR + *

    + * + *
    + *

    + * A string, referred to as a verb, that specifies the action + * to be performed. The set of available verbs depends on the particular + * file or folder. Generally, the actions available from an object's + * shortcut menu are available verbs. This parameter can be + * NULL, in which case the default verb is used if + * available. If not, the "open" verb is used. If neither verb is + * available, the system uses the first verb listed in the registry. The + * following verbs are commonly used: + *

    + *
    + *
    + *

    + * edit + *

    + *
    + *
    + *

    + * Launches an editor and opens the document for editing. If + * lpFile is not a document file, the function will + * fail. + *

    + *
    + *
    + *

    + * explore + *

    + *
    + *
    + *

    + * Explores the folder specified by lpFile. + *

    + *
    + *
    + *

    + * find + *

    + *
    + *
    + *

    + * Initiates a search starting from the specified directory. + *

    + *
    + *
    + *

    + * open + *

    + *
    + *
    + *

    + * Opens the file specified by the lpFile parameter. + * The file can be an executable file, a document file, or a folder. + *

    + *
    + *
    + *

    + * print + *

    + *
    + *
    + *

    + * Prints the document file specified by lpFile. If + * lpFile is not a document file, the function will + * fail. + *

    + *
    + *
    + *

    + * properties + *

    + *
    + *
    + *

    + * Displays the file or folder's properties. + *

    + *
    + *
    + */ + public String lpVerb; + + /** + *

    + * Type: LPCTSTR + *

    + *

    + * The address of a null-terminated string that specifies the name of + * the file or object on which will perform the action specified by the + * lpVerb parameter. The system registry verbs that are + * supported by the ShellExecuteEx function include + * "open" for executable files and document files and "print" for + * document files for which a print handler has been registered. Other + * applications might have added Shell verbs through the system + * registry, such as "play" for .avi and .wav files. To specify a Shell + * namespace object, pass the fully qualified parse name and set the + * SEE_MASK_INVOKEIDLIST flag in the + * fMask parameter. + *

    + *
    Note  If the + * SEE_MASK_INVOKEIDLIST flag is set, you can use + * either lpFile or lpIDList to + * identify the item by its file system path or its PIDL respectively. + * One of the two values-lpFile or + * lpIDList-must be set.
    + *
    Note  If the path is not + * included with the name, the current directory is assumed.
    + */ + public String lpFile; + + /** + *

    + * Type: LPCTSTR + *

    + *

    + * Optional. The address of a null-terminated string that contains the + * application parameters. The parameters must be separated by spaces. + * If the lpFile member specifies a document file, + * lpParameters should be NULL. + *

    + */ + public String lpParameters; + + /** + *

    + * Type: LPCTSTR + *

    + *

    + * Optional. The address of a null-terminated string that specifies the + * name of the working directory. If this member is + * NULL, the current directory is used as the working + * directory. + *

    + */ + public String lpDirectory; + + /** + *

    + * Type: int + *

    + *

    + * Required. Flags that specify how an application is to be shown when + * it is opened; one of the SW_ values listed for the + * ShellExecute + * function. If lpFile specifies a document file, + * the flag is simply passed to the associated application. It is up to + * the application to decide how to handle it. + *

    + */ + public int nShow; + + /** + *

    + * Type: HINSTANCE + *

    + *

    + * [out] If SEE_MASK_NOCLOSEPROCESS is set and the call succeeds, it + * sets this member to a value greater than 32. If the function fails, + * it is set to an SE_ERR_XXX error value that indicates the cause of + * the failure. Although hInstApp is declared as an + * HINSTANCE for compatibility with 16-bit Windows applications, it is + * not a true HINSTANCE. It can be cast only to an int + * and compared to either 32 or the following SE_ERR_XXX error codes. + *

    + *
    + *
    + *

    + * SE_ERR_FNF (2) + *

    + *
    + *
    + *

    + * File not found. + *

    + *
    + *
    + *

    + * SE_ERR_PNF (3) + *

    + *
    + *
    + *

    + * Path not found. + *

    + *
    + *
    + *

    + * SE_ERR_ACCESSDENIED (5) + *

    + *
    + *
    + *

    + * Access denied. + *

    + *
    + *
    + *

    + * SE_ERR_OOM (8) + *

    + *
    + *
    + *

    + * Out of memory. + *

    + *
    + *
    + *

    + * SE_ERR_DLLNOTFOUND (32) + *

    + *
    + *
    + *

    + * Dynamic-link library not found. + *

    + *
    + *
    + *

    + * SE_ERR_SHARE (26) + *

    + *
    + *
    + *

    + * Cannot share an open file. + *

    + *
    + *
    + *

    + * SE_ERR_ASSOCINCOMPLETE (27) + *

    + *
    + *
    + *

    + * File association information not complete. + *

    + *
    + *
    + *

    + * SE_ERR_DDETIMEOUT (28) + *

    + *
    + *
    + *

    + * DDE operation timed out. + *

    + *
    + *
    + *

    + * SE_ERR_DDEFAIL (29) + *

    + *
    + *
    + *

    + * DDE operation failed. + *

    + *
    + *
    + *

    + * SE_ERR_DDEBUSY (30) + *

    + *
    + *
    + *

    + * DDE operation is busy. + *

    + *
    + *
    + *

    + * SE_ERR_NOASSOC (31) + *

    + *
    + *
    + *

    + * File association not available. + *

    + *
    + *
    + */ + public HINSTANCE hInstApp; + + /** + *

    + * Type: LPVOID + *

    + *

    + * The address of an absolute + * ITEMIDLIST + * structure (PCIDLIST_ABSOLUTE) to contain an item identifier list that + * uniquely identifies the file to execute. This member is ignored if + * the fMask member does not include + * SEE_MASK_IDLIST or + * SEE_MASK_INVOKEIDLIST. + *

    + */ + public Pointer lpIDList; + + /** + *

    + * Type: LPCTSTR + *

    + * + *

    + * The address of a null-terminated string that specifies one of the + * following: + *

    + *
      + *
    • A ProgId. For example, "Paint.Picture".
    • + *
    • A URI protocol scheme. For example, "http".
    • + *
    • A file extension. For example, ".txt".
    • + *
    • A registry path under HKEY_CLASSES_ROOT that names a subkey that + * contains one or more Shell verbs. This key will have a subkey that + * conforms to the Shell verb registry schema, such as + *

      + * shell\verb name + *

      + * .
    • + *
    + *

    + * This member is ignored if fMask does not include + * SEE_MASK_CLASSNAME. + *

    + */ + public String lpClass; + + /** + *

    + * Type: HKEY + *

    + *

    + * A handle to the registry key for the file type. The access rights for + * this registry key should be set to KEY_READ. This member is ignored + * if fMask does not include + * SEE_MASK_CLASSKEY. + *

    + */ + public HKEY hKeyClass; + + /** + *

    + * Type: DWORD + *

    + *

    + * A keyboard shortcut to associate with the application. The low-order + * word is the virtual key code, and the high-order word is a modifier + * flag (HOTKEYF_). For a list of modifier flags, see the description of + * the + * WM_SETHOTKEY + * message. This member is ignored if fMask does + * not include SEE_MASK_HOTKEY. + *

    + */ + public int dwHotKey; + + /** + * This is actually a union: + * + *
    +		 * union { HANDLE hIcon; HANDLE hMonitor; } DUMMYUNIONNAME;
    +		 * 
    + * + * DUMMYUNIONNAME + *
    + *
    hIcon
    + *
    + *

    + * Type: HANDLE + *

    + *
    + *
    + *

    + * A handle to the icon for the file type. This member is ignored if + * fMask does not include + * SEE_MASK_ICON. This value is used only in + * Windows XP and earlier. It is ignored as of Windows Vista. + *

    + *
    + *
    hMonitor
    + *
    + *

    + * Type: HANDLE + *

    + *
    + *
    + *

    + * A handle to the monitor upon which the document is to be displayed. + * This member is ignored if fMask does not include + * SEE_MASK_HMONITOR. + *

    + *
    + *
    + */ + public HANDLE hMonitor; + + /** + *

    + * Type: HANDLE + *

    + *

    + * A handle to the newly started application. This member is set on + * return and is always NULL unless + * fMask is set to + * SEE_MASK_NOCLOSEPROCESS. Even if + * fMask is set to + * SEE_MASK_NOCLOSEPROCESS, hProcess + * will be NULL if no process was launched. For + * example, if a document to be launched is a URL and an instance of + * Internet Explorer is already running, it will display the document. + * No new process is launched, and hProcess will be + * NULL. + *

    + *
    Note   + * ShellExecuteEx + * does not always return an hProcess, even if a + * process is launched as the result of the call. For example, an + * hProcess does not return when you use + * SEE_MASK_INVOKEIDLIST to invoke + * IContextMenu + * .
    + */ + public HANDLE hProcess; + + protected List getFieldOrder() { + return Arrays.asList(new String[] { "cbSize", "fMask", "hwnd", "lpVerb", "lpFile", "lpParameters", + "lpDirectory", "nShow", "hInstApp", "lpIDList", "lpClass", "hKeyClass", "dwHotKey", "hMonitor", + "hProcess", }); + } + } + } diff --git a/contrib/platform/src/com/sun/jna/platform/win32/Shlwapi.java b/contrib/platform/src/com/sun/jna/platform/win32/Shlwapi.java new file mode 100644 index 0000000000..b0cbc1ce2b --- /dev/null +++ b/contrib/platform/src/com/sun/jna/platform/win32/Shlwapi.java @@ -0,0 +1,37 @@ +package com.sun.jna.platform.win32; + +/* + * @author L W Ahonen, lwahonen@iki.fi + */ + +import com.sun.jna.Native; +import com.sun.jna.Pointer; +import com.sun.jna.platform.win32.Shell32; +import com.sun.jna.platform.win32.WinNT; +import com.sun.jna.ptr.PointerByReference; +import com.sun.jna.win32.W32APIOptions; + +public interface Shlwapi extends WinNT { + Shlwapi INSTANCE = (Shlwapi) Native.loadLibrary("Shlwapi", Shlwapi.class, W32APIOptions.UNICODE_OPTIONS); + + + /** + * Takes an STRRET structure returned by IShellFolder::GetDisplayNameOf and returns a pointer + * to an allocated string containing the display name. + * + * @param pstr + * A pointer to the STRRET structure. When the function returns, + * this pointer will no longer be valid. + * @param pidl + * A pointer to the item's ITEMIDLIST structure. This value can be NULL. + * + * @param ppszName + * A pointer to an allocated string containing the result. StrRetToStr allocates + * memory for this string with CoTaskMemAlloc. You should free the string + * with CoTaskMemFree when it is no longer needed. + * + * @return If this function succeeds, it returns S_OK. Otherwise, it returns an HRESULT error code. + */ + + HRESULT StrRetToStr(PointerByReference pstr, Pointer pidl, PointerByReference ppszName); +} diff --git a/contrib/platform/src/com/sun/jna/platform/win32/Sspi.java b/contrib/platform/src/com/sun/jna/platform/win32/Sspi.java index 42fde7b374..b249ce2f0c 100644 --- a/contrib/platform/src/com/sun/jna/platform/win32/Sspi.java +++ b/contrib/platform/src/com/sun/jna/platform/win32/Sspi.java @@ -18,15 +18,13 @@ import com.sun.jna.Memory; import com.sun.jna.Pointer; import com.sun.jna.Structure; -import com.sun.jna.WString; -import com.sun.jna.win32.StdCallLibrary; /** * Ported from Sspi.h. * Microsoft Windows SDK 6.0A. * @author dblock[at]dblock.org */ -public interface Sspi extends StdCallLibrary { +public interface Sspi { /** * Maximum size in bytes of a security token. @@ -431,12 +429,12 @@ public static class ByReference extends SecPkgInfo implements Structure.ByRefere /** * Pointer to a null-terminated string that contains the name of the security package. */ - public WString Name; + public String Name; /** * Pointer to a null-terminated string. This can be any additional string passed * back by the package. */ - public WString Comment; + public String Comment; protected List getFieldOrder() { return Arrays.asList(new String[] { "fCapabilities", "wVersion", "wRPCID", "cbMaxToken", "Name", "Comment" }); 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 9c787ec769..ccd671c487 100644 --- a/contrib/platform/src/com/sun/jna/platform/win32/Tlhelp32.java +++ b/contrib/platform/src/com/sun/jna/platform/win32/Tlhelp32.java @@ -15,12 +15,11 @@ import com.sun.jna.Pointer; import com.sun.jna.Structure; -import com.sun.jna.win32.StdCallLibrary; /** * Interface for the Tlhelp32.h header file. */ -public interface Tlhelp32 extends StdCallLibrary { +public interface Tlhelp32 { /** * Includes all heaps of the process specified in th32ProcessID in the snapshot. To enumerate the heaps, see @@ -39,8 +38,20 @@ public interface Tlhelp32 extends StdCallLibrary { 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 */ WinDef.DWORD TH32CS_SNAPMODULE = new WinDef.DWORD(0x00000008); @@ -62,6 +73,8 @@ public interface Tlhelp32 extends StdCallLibrary { */ 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. */ @@ -138,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/src/com/sun/jna/platform/win32/User32.java b/contrib/platform/src/com/sun/jna/platform/win32/User32.java index 6420bbfe01..a1bec435de 100644 --- a/contrib/platform/src/com/sun/jna/platform/win32/User32.java +++ b/contrib/platform/src/com/sun/jna/platform/win32/User32.java @@ -58,6 +58,19 @@ public interface User32 extends StdCallLibrary, WinUser, WinNT { /** The device notify all interface classes. */ int DEVICE_NOTIFY_ALL_INTERFACE_CLASSES = 0x00000004; + /** + *

    + * Sets the show state based on the SW_ value specified in the + * STARTUPINFO + * structure passed to the + * CreateProcess + * function by the program that started the application. + *

    + */ + int SW_SHOWDEFAULT = 10; + /** * This function retrieves a handle to a display device context (DC) for the * client area of the specified window. The display device context can be @@ -1290,6 +1303,8 @@ boolean RedrawWindow(HWND hWnd, RECT lprcUpdate, * If the function fails, the return value is zero. To get extended * error information, call {@link Kernel32#GetLastError}. */ + public boolean UnregisterClass(String lpClassName, HINSTANCE hInstance); + /** @deprecated use the String version */ public boolean UnregisterClass(WString lpClassName, HINSTANCE hInstance); /** @@ -1458,6 +1473,11 @@ boolean RedrawWindow(HWND hWnd, RECT lprcUpdate, * WM_NCCREATE * */ + public HWND CreateWindowEx(int dwExStyle, String lpClassName, + String lpWindowName, int dwStyle, int x, int y, int nWidth, + int nHeight, HWND hWndParent, HMENU hMenu, HINSTANCE hInstance, + LPVOID lpParam); + /** @deprecated use the String version */ public HWND CreateWindowEx(int dwExStyle, WString lpClassName, String lpWindowName, int dwStyle, int x, int y, int nWidth, int nHeight, HWND hWndParent, HMENU hMenu, HINSTANCE hInstance, @@ -1524,7 +1544,7 @@ public HWND CreateWindowEx(int dwExStyle, WString lpClassName, * If the function fails, the return value is zero. To get extended * error information, call {@link Kernel32#GetLastError} . */ - public boolean GetClassInfoEx(HINSTANCE hinst, WString lpszClass, + public boolean GetClassInfoEx(HINSTANCE hinst, String lpszClass, WNDCLASSEX lpwcx); /** @@ -1960,7 +1980,7 @@ HDEVNOTIFY RegisterDeviceNotification(HANDLE hRecipient, * Windows 2000: If {@link Kernel32#GetLastError()} returns 0, then * the function timed out. */ - long SendMessageTimeout(HWND hWnd, int msg, long wParam, long lParam, + LRESULT SendMessageTimeout(HWND hWnd, int msg, WPARAM wParam, LPARAM lParam, int fuFlags, int uTimeout, DWORDByReference lpdwResult); /** @@ -1986,7 +2006,7 @@ long SendMessageTimeout(HWND hWnd, int msg, long wParam, long lParam, * If the function fails, the return value is zero. To get extended * error information, call {@link Kernel32#GetLastError()}.

    */ - long GetClassLongPtr(HWND hWnd, int nIndex); + ULONG_PTR GetClassLongPtr(HWND hWnd, int nIndex); /** * @param pRawInputDeviceList @@ -2011,4 +2031,14 @@ long SendMessageTimeout(HWND hWnd, int msg, long wParam, long lParam, * @see GetRawInputDeviceList */ int GetRawInputDeviceList(RAWINPUTDEVICELIST[] pRawInputDeviceList, IntByReference puiNumDevices, int cbSize); + + + /** + * Retrieves a handle to the desktop window. The desktop window covers the + * entire screen. The desktop window is the area on top of which other + * windows are painted. + * + * @return Type: HWND The return value is a handle to the desktop window. + */ + HWND GetDesktopWindow(); } diff --git a/contrib/platform/src/com/sun/jna/platform/win32/User32Util.java b/contrib/platform/src/com/sun/jna/platform/win32/User32Util.java index 69b5223d64..ef43290a02 100644 --- a/contrib/platform/src/com/sun/jna/platform/win32/User32Util.java +++ b/contrib/platform/src/com/sun/jna/platform/win32/User32Util.java @@ -12,7 +12,6 @@ import java.util.Arrays; import java.util.List; -import com.sun.jna.WString; import com.sun.jna.platform.win32.WinDef.HINSTANCE; import com.sun.jna.platform.win32.WinDef.HMENU; import com.sun.jna.platform.win32.WinDef.HWND; @@ -43,7 +42,7 @@ public static final HWND createWindow(final String className, final String windo public static final HWND createWindowEx(final int exStyle, final String className, final String windowName, final int style, final int x, final int y, final int width, final int height, final HWND parent, final HMENU menu, final HINSTANCE instance, final LPVOID param) { final HWND hWnd = User32.INSTANCE - .CreateWindowEx(exStyle, new WString(className), windowName, style, x, y, width, height, parent, menu, instance, param); + .CreateWindowEx(exStyle, className, windowName, style, x, y, width, height, parent, menu, instance, param); if (hWnd == null) throw new Win32Exception(Kernel32.INSTANCE.GetLastError()); return hWnd; @@ -77,4 +76,4 @@ public static final List GetRawInputDeviceList() { return Arrays.asList(records); } -} \ No newline at end of file +} diff --git a/contrib/platform/src/com/sun/jna/platform/win32/VerRsrc.java b/contrib/platform/src/com/sun/jna/platform/win32/VerRsrc.java index 52e7f39c2e..2b69e978a7 100644 --- a/contrib/platform/src/com/sun/jna/platform/win32/VerRsrc.java +++ b/contrib/platform/src/com/sun/jna/platform/win32/VerRsrc.java @@ -15,12 +15,11 @@ import com.sun.jna.Pointer; import com.sun.jna.Structure; -import com.sun.jna.win32.StdCallLibrary; /** * Interface for the VerRsrc.h header file. */ -public interface VerRsrc extends StdCallLibrary { +public interface VerRsrc { /** * Contains version information for a file. This information is language and code page independent. diff --git a/contrib/platform/src/com/sun/jna/platform/win32/W32FileUtils.java b/contrib/platform/src/com/sun/jna/platform/win32/W32FileUtils.java index d2a0d83e16..fa4dba8eea 100644 --- a/contrib/platform/src/com/sun/jna/platform/win32/W32FileUtils.java +++ b/contrib/platform/src/com/sun/jna/platform/win32/W32FileUtils.java @@ -15,7 +15,6 @@ import java.io.File; import java.io.IOException; -import com.sun.jna.WString; import com.sun.jna.platform.FileUtils; public class W32FileUtils extends FileUtils { @@ -32,7 +31,7 @@ public void moveToTrash(File[] files) throws IOException { for (int i=0;i < paths.length;i++) { paths[i] = files[i].getAbsolutePath(); } - fileop.pFrom = new WString(fileop.encodePaths(paths)); + fileop.pFrom = fileop.encodePaths(paths); fileop.fFlags = ShellAPI.FOF_ALLOWUNDO|ShellAPI.FOF_NO_UI; int ret = shell.SHFileOperation(fileop); if (ret != 0) { diff --git a/contrib/platform/src/com/sun/jna/platform/win32/Wdm.java b/contrib/platform/src/com/sun/jna/platform/win32/Wdm.java index 8dfcb03904..9693f94f5f 100644 --- a/contrib/platform/src/com/sun/jna/platform/win32/Wdm.java +++ b/contrib/platform/src/com/sun/jna/platform/win32/Wdm.java @@ -18,14 +18,13 @@ import com.sun.jna.Native; import com.sun.jna.Pointer; import com.sun.jna.Structure; -import com.sun.jna.win32.StdCallLibrary; /** * Ported from Wdm.h. * Microsoft Windows DDK. * @author dblock[at]dblock.org */ -public interface Wdm extends StdCallLibrary { +public interface Wdm { /** * The KEY_BASIC_INFORMATION structure defines a subset of diff --git a/contrib/platform/src/com/sun/jna/platform/win32/Win32Exception.java b/contrib/platform/src/com/sun/jna/platform/win32/Win32Exception.java index 5886f3f5a2..e87e44dfd0 100644 --- a/contrib/platform/src/com/sun/jna/platform/win32/Win32Exception.java +++ b/contrib/platform/src/com/sun/jna/platform/win32/Win32Exception.java @@ -20,9 +20,9 @@ */ public class Win32Exception extends RuntimeException { - private static final long serialVersionUID = 1L; - - private HRESULT _hr; + private static final long serialVersionUID = 1L; + + private HRESULT _hr; /** * Returns the error code of the error. diff --git a/contrib/platform/src/com/sun/jna/platform/win32/WinBase.java b/contrib/platform/src/com/sun/jna/platform/win32/WinBase.java index 545ddacbb4..7f569d58e9 100755 --- a/contrib/platform/src/com/sun/jna/platform/win32/WinBase.java +++ b/contrib/platform/src/com/sun/jna/platform/win32/WinBase.java @@ -1,18 +1,20 @@ /* Copyright (c) 2010 Daniel Doubrovkine, All Rights Reserved - * + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. - * + * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. + * Lesser General Public License for more details. */ package com.sun.jna.platform.win32; +import java.text.DateFormat; import java.util.Arrays; +import java.util.Calendar; import java.util.Date; import java.util.List; @@ -21,16 +23,18 @@ import com.sun.jna.Pointer; import com.sun.jna.Structure; import com.sun.jna.Union; +import com.sun.jna.platform.win32.WinDef.DWORDLONG; import com.sun.jna.platform.win32.WinNT.HANDLE; import com.sun.jna.ptr.ByteByReference; import com.sun.jna.win32.StdCallLibrary; +import com.sun.jna.win32.StdCallLibrary.StdCallCallback; /** * Ported from Winbase.h (kernel32.dll/kernel services). * Microsoft Windows SDK 6.0A. * @author dblock[at]dblock.org */ -public interface WinBase extends StdCallLibrary, WinDef, BaseTSD { +public interface WinBase extends WinDef, BaseTSD { /** Constant value representing an invalid HANDLE. */ HANDLE INVALID_HANDLE_VALUE = @@ -41,29 +45,29 @@ public interface WinBase extends StdCallLibrary, WinDef, BaseTSD { int WAIT_OBJECT_0 = ((NTStatus.STATUS_WAIT_0 ) + 0 ); int WAIT_ABANDONED = ((NTStatus.STATUS_ABANDONED_WAIT_0 ) + 0 ); int WAIT_ABANDONED_0 = ((NTStatus.STATUS_ABANDONED_WAIT_0 ) + 0 ); - + /** * Maximum computer name length. * The value is 15 on Mac, 31 on everything else. */ int MAX_COMPUTERNAME_LENGTH = Platform.isMac() ? 15 : 31; - + /** - * This logon type is intended for users who will be interactively using the computer, such - * as a user being logged on by a terminal server, remote shell, or similar process. This - * logon type has the additional expense of caching logon information for disconnected operations; - * therefore, it is inappropriate for some client/server applications, such as a mail server. + * This logon type is intended for users who will be interactively using the computer, such + * as a user being logged on by a terminal server, remote shell, or similar process. This + * logon type has the additional expense of caching logon information for disconnected operations; + * therefore, it is inappropriate for some client/server applications, such as a mail server. */ int LOGON32_LOGON_INTERACTIVE = 2; /** - * This logon type is intended for high performance servers to authenticate plaintext passwords. + * This logon type is intended for high performance servers to authenticate plaintext passwords. * The LogonUser function does not cache credentials for this logon type. */ int LOGON32_LOGON_NETWORK = 3; /** - * This logon type is intended for batch servers, where processes may be executing on behalf - * of a user without their direct intervention. This type is also for higher performance servers - * that process many plaintext authentication attempts at a time, such as mail or Web servers. + * This logon type is intended for batch servers, where processes may be executing on behalf + * of a user without their direct intervention. This type is also for higher performance servers + * that process many plaintext authentication attempts at a time, such as mail or Web servers. * The LogonUser function does not cache credentials for this logon type. */ int LOGON32_LOGON_BATCH = 4; @@ -72,32 +76,32 @@ public interface WinBase extends StdCallLibrary, WinDef, BaseTSD { */ int LOGON32_LOGON_SERVICE = 5; /** - * This logon type is for GINA DLLs that log on users who will be interactively using the computer. + * This logon type is for GINA DLLs that log on users who will be interactively using the computer. * This logon type can generate a unique audit record that shows when the workstation was unlocked. */ int LOGON32_LOGON_UNLOCK = 7; /** - * This logon type preserves the name and password in the authentication package, which allows the - * server to make connections to other network servers while impersonating the client. A server can - * accept plaintext credentials from a client, call LogonUser, verify that the user can access the + * This logon type preserves the name and password in the authentication package, which allows the + * server to make connections to other network servers while impersonating the client. A server can + * accept plaintext credentials from a client, call LogonUser, verify that the user can access the * system across the network, and still communicate with other servers. */ int LOGON32_LOGON_NETWORK_CLEARTEXT = 8; /** - * This logon type allows the caller to clone its current token and specify new credentials for - * outbound connections. The new logon session has the same local identifier but uses different - * credentials for other network connections. This logon type is supported only by the + * This logon type allows the caller to clone its current token and specify new credentials for + * outbound connections. The new logon session has the same local identifier but uses different + * credentials for other network connections. This logon type is supported only by the * LOGON32_PROVIDER_WINNT50 logon provider. */ int LOGON32_LOGON_NEW_CREDENTIALS = 9; /** - * Use the standard logon provider for the system. The default security provider is negotiate, - * unless you pass NULL for the domain name and the user name is not in UPN format. In this case, - * the default provider is NTLM. + * Use the standard logon provider for the system. The default security provider is negotiate, + * unless you pass NULL for the domain name and the user name is not in UPN format. In this case, + * the default provider is NTLM. */ int LOGON32_PROVIDER_DEFAULT = 0; - + /** * Use the Windows NT 3.5 logon provider. */ @@ -109,14 +113,14 @@ public interface WinBase extends StdCallLibrary, WinDef, BaseTSD { /** * Use the negotiate logon provider. */ - int LOGON32_PROVIDER_WINNT50 = 3; - + int LOGON32_PROVIDER_WINNT50 = 3; + /** * If this flag is set, a child process created with the bInheritHandles parameter of * CreateProcess set to TRUE will inherit the object handle. */ int HANDLE_FLAG_INHERIT = 1; - + /** * If this flag is set, calling the {@link Kernel32#CloseHandle} function will not * close the object handle. @@ -133,7 +137,7 @@ public interface WinBase extends StdCallLibrary, WinDef, BaseTSD { int STARTF_FORCEONFEEDBACK = 0x040; int STARTF_FORCEOFFFEEDBACK = 0x080; int STARTF_USESTDHANDLES = 0x100; - + // Process Creation flags int DEBUG_PROCESS = 0x00000001; int DEBUG_ONLY_THIS_PROCESS = 0x00000002; @@ -164,24 +168,24 @@ public interface WinBase extends StdCallLibrary, WinDef, BaseTSD { int FILE_USER_DISALLOWED = 7; int FILE_READ_ONLY = 8; int FILE_DIR_DISALOWED = 9; - + /* Open encrypted files raw flags */ int CREATE_FOR_IMPORT = 1; int CREATE_FOR_DIR = 2; int OVERWRITE_HIDDEN = 4; - + /* Invalid return values */ int INVALID_FILE_SIZE = 0xFFFFFFFF; int INVALID_SET_FILE_POINTER = 0xFFFFFFFF; int INVALID_FILE_ATTRIBUTES = 0xFFFFFFFF; - + /** * Return code for a process still active. */ int STILL_ACTIVE = WinNT.STATUS_PENDING; /** - * The FILETIME structure is a 64-bit value representing the number of + * The FILETIME structure is a 64-bit value representing the number of * 100-nanosecond intervals since January 1, 1601 (UTC). * Conversion code in this class Copyright 2002-2004 Apache Software Foundation. * @author Rainer Klute (klute@rainer-klute.de) for the Apache Software Foundation (org.apache.poi.hpsf) @@ -189,8 +193,9 @@ public interface WinBase extends StdCallLibrary, WinDef, BaseTSD { public static class FILETIME extends Structure { public int dwLowDateTime; public int dwHighDateTime; - - protected List getFieldOrder() { + + @Override + protected List getFieldOrder() { return Arrays.asList(new String[] { "dwLowDateTime", "dwHighDateTime" }); } @@ -226,7 +231,7 @@ public FILETIME(Pointer memory) { * operating system is the modern one? :-))

    */ private static final long EPOCH_DIFF = 11644473600000L; - + /** *

    Converts a Windows FILETIME into a {@link Date}. The Windows * FILETIME structure holds a date and time associated with a @@ -245,7 +250,7 @@ public static Date filetimeToDate(final int high, final int low) { final long ms_since_19700101 = ms_since_16010101 - EPOCH_DIFF; return new Date(ms_since_19700101); } - + /** *

    Converts a {@link Date} into a filetime.

    * @@ -259,20 +264,54 @@ public static long dateToFileTime(final Date date) { final long ms_since_16010101 = ms_since_19700101 + EPOCH_DIFF; return ms_since_16010101 * 1000 * 10; } - + + /** + *

    Converts this filetime into a {@link Date}

    + * @return The {@link Date} represented by this filetime. + */ public Date toDate() { return filetimeToDate(dwHighDateTime, dwLowDateTime); } - + + /** + *

    Converts this filetime into a number of milliseconds which have + * passed since January 1, 1970 (UTC).

    + * @return This filetime as a number of milliseconds which have passed + * since January 1, 1970 (UTC) + */ + public long toTime() { + return toDate().getTime(); + } + + /** + *

    Converts this filetime into a number of milliseconds which have + * passed since January 1, 1970 (UTC).

    + * @return This filetime as a number of milliseconds which have passed + * since January 1, 1970 (UTC) + * @deprecated Replaced by {@link #toTime()} + */ + @Deprecated public long toLong() { return toDate().getTime(); } - + + /** + *

    Converts the two 32-bit unsigned integer parts of this filetime + * into a 64-bit unsigned integer representing the number of + * 100-nanosecond intervals since January 1, 1601 (UTC).

    + * @return This filetime as a 64-bit unsigned integer number of + * 100-nanosecond intervals since January 1, 1601 (UTC). + */ + public DWORDLONG toDWordLong() { + return new DWORDLONG((long) dwHighDateTime << 32 | dwLowDateTime & 0xffffffffL); + } + + @Override public String toString() { return super.toString() + ": " + toDate().toString(); //$NON-NLS-1$ } } - + /* Local Memory Flags */ int LMEM_FIXED = 0x0000; int LMEM_MOVEABLE = 0x0002; @@ -289,17 +328,17 @@ public String toString() { /* Flags returned by LocalFlags (in addition to LMEM_DISCARDABLE) */ int LMEM_DISCARDED = 0x4000; - int LMEM_LOCKCOUNT = 0x00FF; - + int LMEM_LOCKCOUNT = 0x00FF; + /** - * Specifies a date and time, using individual members for the month, - * day, year, weekday, hour, minute, second, and millisecond. The time - * is either in coordinated universal time (UTC) or local time, depending + * Specifies a date and time, using individual members for the month, + * day, year, weekday, hour, minute, second, and millisecond. The time + * is either in coordinated universal time (UTC) or local time, depending * on the function that is being called. - * http://msdn.microsoft.com/en-us/library/ms724950(VS.85).aspx + * @see SYSTEMTIME structure */ public static class SYSTEMTIME extends Structure { - // The year. The valid values for this member are 1601 through 30827. + // The year. The valid values for this member are 1601 through 30827. public short wYear; // The month. The valid values for this member are 1 through 12. public short wMonth; @@ -315,12 +354,68 @@ public static class SYSTEMTIME extends Structure { public short wSecond; // The millisecond. The valid values for this member are 0 through 999. public short wMilliseconds; - - protected List getFieldOrder() { + + public SYSTEMTIME() { + super(); + } + + public SYSTEMTIME(Date date) { + this(date.getTime()); + } + + public SYSTEMTIME(long timestamp) { + Calendar cal = Calendar.getInstance(); + cal.setTimeInMillis(timestamp); + fromCalendar(cal); + } + + public SYSTEMTIME(Calendar cal) { + fromCalendar(cal); + } + + public void fromCalendar(Calendar cal) { + wYear = (short) cal.get(Calendar.YEAR); + wMonth = (short) (1 + cal.get(Calendar.MONTH) - Calendar.JANUARY); // 1 = January + wDay = (short) cal.get(Calendar.DAY_OF_MONTH); + wHour = (short) cal.get(Calendar.HOUR_OF_DAY); + wMinute = (short) cal.get(Calendar.MINUTE); + wSecond = (short) cal.get(Calendar.SECOND); + wMilliseconds = (short) cal.get(Calendar.MILLISECOND); + wDayOfWeek = (short) (cal.get(Calendar.DAY_OF_WEEK) - Calendar.SUNDAY); // 0 = Sunday + } + + public Calendar toCalendar() { + Calendar cal = Calendar.getInstance(); + cal.set(Calendar.YEAR, wYear); + cal.set(Calendar.MONTH, Calendar.JANUARY + (wMonth - 1)); + cal.set(Calendar.DAY_OF_MONTH, wDay); + cal.set(Calendar.HOUR_OF_DAY, wHour); + cal.set(Calendar.MINUTE, wMinute); + cal.set(Calendar.SECOND, wSecond); + cal.set(Calendar.MILLISECOND, wMilliseconds); + return cal; + } + + @Override + protected List getFieldOrder() { return Arrays.asList(new String[] { "wYear", "wMonth", "wDayOfWeek", "wDay", "wHour", "wMinute", "wSecond", "wMilliseconds" }); } + + @Override + public String toString() { + // if not initialized, return the default representation + if ((wYear == 0) && (wMonth == 0) && (wDay == 0) + && (wHour == 0) && (wMinute == 0) && (wSecond == 0) + && (wMilliseconds == 0)) { + return super.toString(); + } + + DateFormat dtf = DateFormat.getDateTimeInstance(); + Calendar cal = toCalendar(); + return dtf.format(cal.getTime()); + } } - + /** * Specifies settings for a time zone. * http://msdn.microsoft.com/en-us/library/windows/desktop/ms725481(v=vs.85).aspx @@ -333,54 +428,55 @@ public static class TIME_ZONE_INFORMATION extends Structure { public String DaylightName; public SYSTEMTIME DaylightDate; public LONG DaylightBias; - - protected List getFieldOrder() { + + @Override + protected List getFieldOrder() { return Arrays.asList(new String[] { "Bias", "StandardName", "StandardDate", "StandardBias", "DaylightName", "DaylightDate", "DaylightBias" }); } - } - + } + /** - * The lpBuffer parameter is a pointer to a PVOID pointer, and that the nSize - * parameter specifies the minimum number of TCHARs to allocate for an output - * message buffer. The function allocates a buffer large enough to hold the - * formatted message, and places a pointer to the allocated buffer at the address - * specified by lpBuffer. The caller should use the LocalFree function to free + * The lpBuffer parameter is a pointer to a PVOID pointer, and that the nSize + * parameter specifies the minimum number of TCHARs to allocate for an output + * message buffer. The function allocates a buffer large enough to hold the + * formatted message, and places a pointer to the allocated buffer at the address + * specified by lpBuffer. The caller should use the LocalFree function to free * the buffer when it is no longer needed. */ int FORMAT_MESSAGE_ALLOCATE_BUFFER = 0x00000100; /** * Insert sequences in the message definition are to be ignored and passed through - * to the output buffer unchanged. This flag is useful for fetching a message for + * to the output buffer unchanged. This flag is useful for fetching a message for * later formatting. If this flag is set, the Arguments parameter is ignored. */ int FORMAT_MESSAGE_IGNORE_INSERTS = 0x00000200; /** * The lpSource parameter is a pointer to a null-terminated message definition. - * The message definition may contain insert sequences, just as the message text + * The message definition may contain insert sequences, just as the message text * in a message table resource may. Cannot be used with FORMAT_MESSAGE_FROM_HMODULE * or FORMAT_MESSAGE_FROM_SYSTEM. */ int FORMAT_MESSAGE_FROM_STRING = 0x00000400; /** - * The lpSource parameter is a module handle containing the message-table + * The lpSource parameter is a module handle containing the message-table * resource(s) to search. If this lpSource handle is NULL, the current process's - * application image file will be searched. Cannot be used with + * application image file will be searched. Cannot be used with * FORMAT_MESSAGE_FROM_STRING. */ int FORMAT_MESSAGE_FROM_HMODULE = 0x00000800; /** - * The function should search the system message-table resource(s) for the + * The function should search the system message-table resource(s) for the * requested message. If this flag is specified with FORMAT_MESSAGE_FROM_HMODULE, - * the function searches the system message table if the message is not found in - * the module specified by lpSource. Cannot be used with FORMAT_MESSAGE_FROM_STRING. - * If this flag is specified, an application can pass the result of the + * the function searches the system message table if the message is not found in + * the module specified by lpSource. Cannot be used with FORMAT_MESSAGE_FROM_STRING. + * If this flag is specified, an application can pass the result of the * GetLastError function to retrieve the message text for a system-defined error. */ int FORMAT_MESSAGE_FROM_SYSTEM = 0x00001000; /** * The Arguments parameter is not a va_list structure, but is a pointer to an array - * of values that represent the arguments. This flag cannot be used with 64-bit - * argument values. If you are using 64-bit values, you must use the va_list + * of values that represent the arguments. This flag cannot be used with 64-bit + * argument values. If you are using 64-bit values, you must use the va_list * structure. */ int FORMAT_MESSAGE_ARGUMENT_ARRAY = 0x00002000; @@ -394,7 +490,7 @@ protected List getFieldOrder() { */ int DRIVE_NO_ROOT_DIR = 1; /** - * The drive is a type that has removable media, for example, a floppy drive + * The drive is a type that has removable media, for example, a floppy drive * or removable hard disk. */ int DRIVE_REMOVABLE = 2; @@ -413,10 +509,10 @@ protected List getFieldOrder() { /** * The drive is a RAM disk. */ - int DRIVE_RAMDISK = 6; - + int DRIVE_RAMDISK = 6; + /** - * The OVERLAPPED structure contains information used in + * The OVERLAPPED structure contains information used in * asynchronous (or overlapped) input and output (I/O). */ public static class OVERLAPPED extends Structure { @@ -425,59 +521,61 @@ public static class OVERLAPPED extends Structure { public int Offset; public int OffsetHigh; public HANDLE hEvent; - - protected List getFieldOrder() { + + @Override + protected List getFieldOrder() { return Arrays.asList(new String[] { "Internal", "InternalHigh", "Offset", "OffsetHigh", "hEvent" }); } - } - + } + int INFINITE = 0xFFFFFFFF; /** - * Contains information about the current computer system. This includes the architecture and + * Contains information about the current computer system. This includes the architecture and * type of the processor, the number of processors in the system, the page size, and other such * information. */ public static class SYSTEM_INFO extends Structure { - + /** Unnamed inner structure. */ - public static class PI extends Structure { - + public static class PI extends Structure { + public static class ByReference extends PI implements Structure.ByReference { - + } /** - * System's processor architecture. + * System's processor architecture. * This value can be one of the following values: - * - * PROCESSOR_ARCHITECTURE_UNKNOWN - * PROCESSOR_ARCHITECTURE_INTEL - * PROCESSOR_ARCHITECTURE_IA64 - * PROCESSOR_ARCHITECTURE_AMD64 + * + * PROCESSOR_ARCHITECTURE_UNKNOWN + * PROCESSOR_ARCHITECTURE_INTEL + * PROCESSOR_ARCHITECTURE_IA64 + * PROCESSOR_ARCHITECTURE_AMD64 */ public WORD wProcessorArchitecture; /** * Reserved for future use. */ public WORD wReserved; - - protected List getFieldOrder() { + + @Override + protected List getFieldOrder() { return Arrays.asList(new String[] { "wProcessorArchitecture", "wReserved" }); - } - } - + } + } + /** Unnamed inner union. */ public static class UNION extends Union { - + public static class ByReference extends UNION implements Structure.ByReference { - + } /** * An obsolete member that is retained for compatibility with Windows NT 3.5 and earlier. * New applications should use the wProcessorArchitecture branch of the union. - * Windows Me/98/95: The system always sets this member to zero, the value defined + * Windows Me/98/95: The system always sets this member to zero, the value defined * for PROCESSOR_ARCHITECTURE_INTEL. */ public DWORD dwOemID; @@ -486,7 +584,7 @@ public static class ByReference extends UNION implements Structure.ByReference { */ public PI pi; } - + /** * Processor architecture (unnamed union). */ @@ -496,36 +594,36 @@ public static class ByReference extends UNION implements Structure.ByReference { */ public DWORD dwPageSize; /** - * Pointer to the lowest memory address accessible to applications and dynamic-link libraries (DLLs). + * Pointer to the lowest memory address accessible to applications and dynamic-link libraries (DLLs). */ public Pointer lpMinimumApplicationAddress; /** - * Pointer to the highest memory address accessible to applications and DLLs. + * Pointer to the highest memory address accessible to applications and DLLs. */ public Pointer lpMaximumApplicationAddress; /** - * Mask representing the set of processors configured into the system. Bit 0 is processor 0; bit 31 is processor 31. + * Mask representing the set of processors configured into the system. Bit 0 is processor 0; bit 31 is processor 31. */ public DWORD_PTR dwActiveProcessorMask; /** - * Number of processors in the system. + * Number of processors in the system. */ public DWORD dwNumberOfProcessors; /** - * An obsolete member that is retained for compatibility with Windows NT 3.5 and Windows Me/98/95. - * Use the wProcessorArchitecture, wProcessorLevel, and wProcessorRevision members to determine - * the type of processor. - * PROCESSOR_INTEL_386 - * PROCESSOR_INTEL_486 - * PROCESSOR_INTEL_PENTIUM + * An obsolete member that is retained for compatibility with Windows NT 3.5 and Windows Me/98/95. + * Use the wProcessorArchitecture, wProcessorLevel, and wProcessorRevision members to determine + * the type of processor. + * PROCESSOR_INTEL_386 + * PROCESSOR_INTEL_486 + * PROCESSOR_INTEL_PENTIUM */ - public DWORD dwProcessorType; + public DWORD dwProcessorType; /** * Granularity for the starting address at which virtual memory can be allocated. */ public DWORD dwAllocationGranularity; /** - * System's architecture-dependent processor level. It should be used only for display purposes. + * System's architecture-dependent processor level. It should be used only for display purposes. * To determine the feature set of a processor, use the IsProcessorFeaturePresent function. * If wProcessorArchitecture is PROCESSOR_ARCHITECTURE_INTEL, wProcessorLevel is defined by the CPU vendor. * If wProcessorArchitecture is PROCESSOR_ARCHITECTURE_IA64, wProcessorLevel is set to 1. @@ -535,23 +633,24 @@ public static class ByReference extends UNION implements Structure.ByReference { * Architecture-dependent processor revision. */ public WORD wProcessorRevision; - - protected List getFieldOrder() { + + @Override + protected List getFieldOrder() { return Arrays.asList(new String[] { "processorArchitecture", "dwPageSize", "lpMinimumApplicationAddress", "lpMaximumApplicationAddress", "dwActiveProcessorMask", "dwNumberOfProcessors", "dwProcessorType", "dwAllocationGranularity", "wProcessorLevel", "wProcessorRevision"}); } } - + /** - * Contains information about the current state of both physical and virtual memory, including + * Contains information about the current state of both physical and virtual memory, including * extended memory. The GlobalMemoryStatusEx function stores information in this structure. */ public static class MEMORYSTATUSEX extends Structure { - /** - * The size of the structure, in bytes. - */ + /** + * The size of the structure, in bytes. + */ public DWORD dwLength; /** - * A number between 0 and 100 that specifies the approximate percentage of physical memory + * A number between 0 and 100 that specifies the approximate percentage of physical memory * that is in use (0 indicates no memory use and 100 indicates full memory use). */ public DWORD dwMemoryLoad; @@ -561,12 +660,12 @@ public static class MEMORYSTATUSEX extends Structure { public DWORDLONG ullTotalPhys; /** * The amount of physical memory currently available, in bytes. This is the amount of physical - * memory that can be immediately reused without having to write its contents to disk first. + * memory that can be immediately reused without having to write its contents to disk first. * It is the sum of the size of the standby, free, and zero lists. */ public DWORDLONG ullAvailPhys; /** - * The current committed memory limit for the system or the current process, whichever is smaller, in bytes. + * The current committed memory limit for the system or the current process, whichever is smaller, in bytes. */ public DWORDLONG ullTotalPageFile; /** @@ -579,7 +678,7 @@ public static class MEMORYSTATUSEX extends Structure { */ public DWORDLONG ullTotalVirtual; /** - * The amount of unreserved and uncommitted memory currently in the user-mode portion of the + * The amount of unreserved and uncommitted memory currently in the user-mode portion of the * virtual address space of the calling process, in bytes. */ public DWORDLONG ullAvailVirtual; @@ -587,16 +686,17 @@ public static class MEMORYSTATUSEX extends Structure { * Reserved. This value is always 0. */ public DWORDLONG ullAvailExtendedVirtual; - - protected List getFieldOrder() { + + @Override + protected List getFieldOrder() { return Arrays.asList(new String[] { "dwLength", "dwMemoryLoad", "ullTotalPhys", "ullAvailPhys", "ullTotalPageFile", "ullAvailPageFile", "ullTotalVirtual", "ullAvailVirtual", "ullAvailExtendedVirtual" }); } - + public MEMORYSTATUSEX() { dwLength = new DWORD(size()); } }; - + /** * The SECURITY_ATTRIBUTES structure contains the security descriptor for an * object and specifies whether the handle retrieved by specifying this @@ -605,31 +705,32 @@ public MEMORYSTATUSEX() { * {@link Kernel32#CreatePipe}, or {@link Advapi32#RegCreateKeyEx}. */ public static class SECURITY_ATTRIBUTES extends Structure { - /** - * The size of the structure, in bytes. - */ + /** + * The size of the structure, in bytes. + */ public DWORD dwLength; - + /** * A pointer to a SECURITY_DESCRIPTOR structure that controls access to the object. */ public Pointer lpSecurityDescriptor; - + /** * A Boolean value that specifies whether the returned handle is inherited when * a new process is created */ public boolean bInheritHandle; - - protected List getFieldOrder() { + + @Override + protected List getFieldOrder() { return Arrays.asList(new String[] { "dwLength", "lpSecurityDescriptor", "bInheritHandle" }); } - + public SECURITY_ATTRIBUTES() { dwLength = new DWORD(size()); } } - + /** * Specifies the window station, desktop, standard handles, and appearance of the main * window for a process at creation time. @@ -638,20 +739,20 @@ public static class STARTUPINFO extends Structure { /** * The size of the structure, in bytes. */ - public DWORD cb; - - /** - * Reserved; must be NULL. - */ + public DWORD cb; + + /** + * Reserved; must be NULL. + */ public String lpReserved; - + /** * The name of the desktop, or the name of both the desktop and window station for this process. * A backslash in the string indicates that the string includes both the desktop and window * station names. For more information, see Thread Connection to a Desktop. */ public String lpDesktop; - + /** * For console processes, this is the title displayed in the title bar * if a new console window is created. If NULL, the name of the @@ -660,12 +761,12 @@ public static class STARTUPINFO extends Structure { * console window. */ public String lpTitle; - + /** * If dwFlags specifies STARTF_USEPOSITION, this member is the x offset * of the upper left corner of a window if a new window is created, in * pixels. Otherwise, this member is ignored. - * + * * The offset is from the upper left corner of the screen. For GUI * processes, the specified position is used the first time the new * process calls CreateWindow to create an overlapped window if the x @@ -677,7 +778,7 @@ public static class STARTUPINFO extends Structure { * If dwFlags specifies STARTF_USEPOSITION, this member is the y offset * of the upper left corner of a window if a new window is created, in * pixels. Otherwise, this member is ignored. - * + * * The offset is from the upper left corner of the screen. For GUI * processes, the specified position is used the first time the new * process calls CreateWindow to create an overlapped window if the y @@ -689,18 +790,18 @@ public static class STARTUPINFO extends Structure { * If dwFlags specifies STARTF_USESIZE, this member is the width of the * window if a new window is created, in pixels. Otherwise, this member * is ignored. - * + * * For GUI processes, this is used only the first time the new process * calls CreateWindow to create an overlapped window if the nWidth * parameter of CreateWindow is CW_USEDEFAULT. */ public DWORD dwXSize; - + /** * If dwFlags specifies STARTF_USESIZE, this member is the height of the * window if a new window is created, in pixels. Otherwise, this member * is ignored. - * + * * For GUI processes, this is used only the first time the new process * calls CreateWindow to create an overlapped window if the nHeight * parameter of CreateWindow is CW_USEDEFAULT. @@ -725,13 +826,13 @@ public static class STARTUPINFO extends Structure { * If dwFlags specifies STARTF_USEFILLATTRIBUTE, this member is the * initial text and background colors if a new console window is created * in a console application. Otherwise, this member is ignored. - * + * * This value can be any combination of the following values: * FOREGROUND_BLUE, FOREGROUND_GREEN, FOREGROUND_RED, * FOREGROUND_INTENSITY, BACKGROUND_BLUE, BACKGROUND_GREEN, * BACKGROUND_RED, and BACKGROUND_INTENSITY. For example, the following * combination of values produces red text on a white background: - * + * * FOREGROUND_RED| BACKGROUND_RED| BACKGROUND_GREEN| BACKGROUND_BLUE */ public DWORD dwFillAttribute; @@ -747,7 +848,7 @@ public static class STARTUPINFO extends Structure { * the values that can be specified in the nCmdShow parameter for the * ShowWindow function, except for SW_SHOWDEFAULT. Otherwise, this * member is ignored. - * + * * For GUI processes, the first time ShowWindow is called, its nCmdShow * parameter is ignored wShowWindow specifies the default value. In * subsequent calls to ShowWindow, the wShowWindow member is used if the @@ -769,14 +870,14 @@ public static class STARTUPINFO extends Structure { * If dwFlags specifies STARTF_USESTDHANDLES, this member is the * standard input handle for the process. If STARTF_USESTDHANDLES is not * specified, the default for standard input is the keyboard buffer. - * + * * If dwFlags specifies STARTF_USEHOTKEY, this member specifies a hotkey * value that is sent as the wParam parameter of a WM_SETHOTKEY message * to the first eligible top-level window created by the application * that owns the process. If the window is created with the WS_POPUP * window style, it is not eligible unless the WS_EX_APPWINDOW extended * window style is also set. For more information, see CreateWindowEx. - * + * * Otherwise, this member is ignored. */ public HANDLE hStdInput; @@ -796,11 +897,12 @@ public static class STARTUPINFO extends Structure { * buffer. */ public HANDLE hStdError; - - protected List getFieldOrder() { + + @Override + protected List getFieldOrder() { return Arrays.asList(new String[] { "cb", "lpReserved", "lpDesktop", "lpTitle", "dwX", "dwY", "dwXSize", "dwYSize", "dwXCountChars", "dwYCountChars", "dwFillAttribute", "dwFlags", "wShowWindow", "cbReserved2", "lpReserved2", "hStdInput", "hStdOutput", "hStdError" }); } - + public STARTUPINFO() { cb = new DWORD(size()); } @@ -813,13 +915,13 @@ public STARTUPINFO() { */ public static class PROCESS_INFORMATION extends Structure { - /** + /** * A handle to the newly created process. The handle is used to specify * the process in all functions that perform operations on the process * object. */ public HANDLE hProcess; - + /** * A handle to the primary thread of the newly created process. The * handle is used to specify the thread in all functions that perform @@ -842,8 +944,9 @@ public static class PROCESS_INFORMATION extends Structure { * identifier may be reused. */ public DWORD dwThreadId; - - protected List getFieldOrder() { + + @Override + protected List getFieldOrder() { return Arrays.asList(new String[] { "hProcess", "hThread", "dwProcessId", "dwThreadId" }); } @@ -924,23 +1027,23 @@ public PROCESS_INFORMATION(Pointer memory) { /** * Represents a thread entry point local to this process, as a Callback. */ - public interface THREAD_START_ROUTINE extends Callback{ - public DWORD apply( LPVOID lpParameter ); + public interface THREAD_START_ROUTINE extends StdCallCallback{ + public DWORD apply( LPVOID lpParameter ); } - + /** * Represents a thread entry point in another process. Can only be expressed as a pointer, as * the location has no meaning in the Java process. */ public class FOREIGN_THREAD_START_ROUTINE extends Structure { - LPVOID foreignLocation; + LPVOID foreignLocation; - @Override - protected List getFieldOrder() { + @Override + protected List getFieldOrder() { return Arrays.asList(new String[] { "foreignLocation" }); - } + } } - + /** * Specifies a type of computer name to be retrieved by the GetComputerNameEx function */ @@ -952,18 +1055,18 @@ public static interface COMPUTER_NAME_FORMAT { * "corporate-mail-server", the NetBIOS name would be "corporate-mail-"". */ int ComputerNameNetBIOS = 0; - + /** * The DNS name of the local computer or the cluster associated with the local computer. */ int ComputerNameDnsHostname = 1; - + /** * The name of the DNS domain assigned to the local computer or the cluster associated * with the local computer. */ int ComputerNameDnsDomain = 2; - + /** * The fully qualified DNS name that uniquely identifies the local computer or the cluster * associated with the local computer. This name is a combination of the DNS host name and @@ -972,32 +1075,32 @@ public static interface COMPUTER_NAME_FORMAT { * the fully qualified DNS name is "corporate-mail-server.microsoft.com". */ int ComputerNameDnsFullyQualified = 3; - + /** * The NetBIOS name of the local computer. On a cluster, this is the NetBIOS name of the * local node on the cluster. */ int ComputerNamePhysicalNetBIOS = 4; - + /** * The DNS host name of the local computer. On a cluster, this is the DNS host name of the * local node on the cluster. */ int ComputerNamePhysicalDnsHostname = 5; - + /** * The name of the DNS domain assigned to the local computer. On a cluster, this is the DNS * domain of the local node on the cluster. */ int ComputerNamePhysicalDnsDomain = 6; - + /** * The fully qualified DNS name that uniquely identifies the computer. On a cluster, this is * the fully qualified DNS name of the local node on the cluster. The fully qualified DNS name * is a combination of the DNS host name and the DNS domain name, using the form HostName.DomainName. */ int ComputerNamePhysicalDnsFullyQualified = 7; - + /** * Note used - serves as an upper limit in case one wants to go through all the values */ @@ -1011,8 +1114,8 @@ public static interface COMPUTER_NAME_FORMAT { * ExportCallback writes the encrypted file's data to another storage media, * usually for purposes of backing up the file. */ - public interface FE_EXPORT_FUNC extends Callback { - public DWORD callback(ByteByReference pbData, Pointer pvCallbackContext, + public interface FE_EXPORT_FUNC extends StdCallCallback { + public DWORD callback(Pointer pbData, Pointer pvCallbackContext, ULONG ulLength); } @@ -1023,11 +1126,11 @@ public DWORD callback(ByteByReference pbData, Pointer pvCallbackContext, * backup file sequentially and restores the data, and the system continues * calling it until it has read all of the backup file data. */ - public interface FE_IMPORT_FUNC extends Callback { - public DWORD callback(ByteByReference pbData, Pointer pvCallbackContext, + public interface FE_IMPORT_FUNC extends StdCallCallback { + public DWORD callback(Pointer pbData, Pointer pvCallbackContext, ULONGByReference ulLength); } - + int PIPE_CLIENT_END=0x00000000; int PIPE_SERVER_END=0x00000001; @@ -1035,672 +1138,751 @@ public DWORD callback(ByteByReference pbData, Pointer pvCallbackContext, int PIPE_ACCESS_DUPLEX=0x00000003; int PIPE_ACCESS_INBOUND=0x00000001; int PIPE_ACCESS_OUTBOUND=0x00000002; - + /* Pipe type values */ int PIPE_TYPE_BYTE=0x00000000; int PIPE_TYPE_MESSAGE=0x00000004; - + /* Pipe read modes */ int PIPE_READMODE_BYTE=0x00000000; int PIPE_READMODE_MESSAGE=0x00000002; - + /* Pipe wait modes */ int PIPE_WAIT=0x00000000; int PIPE_NOWAIT=0x00000001; - + int PIPE_ACCEPT_REMOTE_CLIENTS=0x00000000; int PIPE_REJECT_REMOTE_CLIENTS=0x00000008; - + int PIPE_UNLIMITED_INSTANCES=255; - + /* Named pipe pre-defined timeout values */ int NMPWAIT_USE_DEFAULT_WAIT=0x00000000; int NMPWAIT_NOWAIT=0x00000001; int NMPWAIT_WAIT_FOREVER=0xffffffff; - - - - /** - * - * Contains the time-out parameters for a communications device. The - * parameters determine the behavior of - * {@link Kernel32#ReadFile(com.sun.jna.platform.win32.WinNT.HANDLE, java.nio.Buffer, int, com.sun.jna.ptr.IntByReference, com.sun.jna.platform.win32.WinBase.OVERLAPPED)} - * , {@link Kernel32#WriteFile(com.sun.jna.platform.win32.WinNT.HANDLE, - * byte[], int, com.sun.jna.ptr.IntByReference, - * com.sun.jna.platform.win32.WinBase.OVERLAPPED))}, ReadFileEx, and - * WriteFileEx operations on the device.
    - *
    - * - * Remarks
    - * If an application sets ReadIntervalTimeout and ReadTotalTimeoutMultiplier - * to MAXDWORD and sets ReadTotalTimeoutConstant to a value greater than - * zero and less than MAXDWORD, one of the following occurs when the - * ReadFile function is called: - *
  • If there are any bytes in the input buffer, ReadFile returns - * immediately with the bytes in the buffer.
  • - *
  • If there are no bytes in the input buffer, ReadFile waits until a - * byte arrives and then returns immediately.
  • - *
  • If no bytes arrive within the time specified by - * ReadTotalTimeoutConstant, ReadFile times out.
  • - * - * @author Markus - * - */ - public static class COMMTIMEOUTS extends Structure { - /** - * - * The maximum time allowed to elapse before the arrival of the next - * byte on the communications line, in milliseconds. If the interval - * between the arrival of any two bytes exceeds this amount, the - * {@link Kernel32#ReadFile(com.sun.jna.platform.win32.WinNT.HANDLE, java.nio.Buffer, int, com.sun.jna.ptr.IntByReference, com.sun.jna.platform.win32.WinBase.OVERLAPPED)} - * operation is completed and any buffered data is returned. A value of - * zero indicates that interval time-outs are not used. - * - * A value of MAXDWORD, combined with zero values for both the - * {@link COMMTIMEOUTS#ReadTotalTimeoutConstant} and - * {@link COMMTIMEOUTS#ReadTotalTimeoutMultiplier} members, specifies - * that the read operation is to return immediately with the bytes that - * have already been received, even if no bytes have been received. - * - */ - public DWORD ReadIntervalTimeout; - - /** - * The multiplier used to calculate the total time-out period for read - * operations, in milliseconds. For each read operation, this value is - * multiplied by the requested number of bytes to be read. - */ - public DWORD ReadTotalTimeoutMultiplier; - - /** - * A constant used to calculate the total time-out period for read - * operations, in milliseconds. For each read operation, this value is - * added to the product of the - * {@link COMMTIMEOUTS#ReadTotalTimeoutMultiplier} member and the - * requested number of bytes. - * - * A value of zero for both the - * {@link COMMTIMEOUTS#ReadTotalTimeoutMultiplier} and - * {@link COMMTIMEOUTS#ReadTotalTimeoutConstant} members indicates that - * total time-outs are not used for read operations. - */ - public DWORD ReadTotalTimeoutConstant; - - /** - * The multiplier used to calculate the total time-out period for write - * operations, in milliseconds. For each write operation, this value is - * multiplied by the number of bytes to be written. - */ - public DWORD WriteTotalTimeoutMultiplier; - - /** - * A constant used to calculate the total time-out period for write - * operations, in milliseconds. For each write operation, this value is - * added to the product of the - * {@link COMMTIMEOUTS#WriteTotalTimeoutMultiplier} member and the - * number of bytes to be written. - * - * A value of zero for both the - * {@link COMMTIMEOUTS#WriteTotalTimeoutMultiplier} and - * {@link COMMTIMEOUTS#WriteTotalTimeoutConstant} members indicates that - * total time-outs are not used for write operations. - * - */ - public DWORD WriteTotalTimeoutConstant; - - protected List getFieldOrder() { - return Arrays.asList(new String[] { "ReadIntervalTimeout", "ReadTotalTimeoutMultiplier", - "ReadTotalTimeoutConstant", "WriteTotalTimeoutMultiplier", "WriteTotalTimeoutConstant" }); - } - } - - - - /** - * Defines the control setting for a serial communications device. - */ - public static class DCB extends Structure { - - /** - * Type is used to handle the bitfield of the DBC structure. - */ - public static class DCBControllBits extends DWORD { - private static final long serialVersionUID = 8574966619718078579L; - - @Override - public String toString() { - final StringBuilder stringBuilder = new StringBuilder(); - stringBuilder.append('<'); - stringBuilder.append("fBinary:1="); - stringBuilder.append(getfBinary() ? '1' : '0'); - stringBuilder.append(", fParity:1="); - stringBuilder.append(getfParity() ? '1' : '0'); - stringBuilder.append(", fOutxCtsFlow:1="); - stringBuilder.append(getfOutxCtsFlow() ? '1' : '0'); - stringBuilder.append(", fOutxDsrFlow:1="); - stringBuilder.append(getfOutxDsrFlow() ? '1' : '0'); - stringBuilder.append(", fDtrControl:2="); - stringBuilder.append(getfDtrControl()); - stringBuilder.append(", fDsrSensitivity:1="); - stringBuilder.append(getfDsrSensitivity() ? '1' : '0'); - stringBuilder.append(", fTXContinueOnXoff:1="); - stringBuilder.append(getfTXContinueOnXoff() ? '1' : '0'); - stringBuilder.append(", fOutX:1="); - stringBuilder.append(getfOutX() ? '1' : '0'); - stringBuilder.append(", fInX:1="); - stringBuilder.append(getfInX() ? '1' : '0'); - stringBuilder.append(", fErrorChar:1="); - stringBuilder.append(getfErrorChar() ? '1' : '0'); - stringBuilder.append(", fNull:1="); - stringBuilder.append(getfNull() ? '1' : '0'); - stringBuilder.append(", fRtsControl:2="); - stringBuilder.append(getfRtsControl()); - stringBuilder.append(", fAbortOnError:1="); - stringBuilder.append(getfAbortOnError() ? '1' : '0'); - stringBuilder.append(", fDummy2:17="); - stringBuilder.append(getfDummy2()); - stringBuilder.append('>'); - return stringBuilder.toString(); - } - - public boolean getfAbortOnError() { - return (this.intValue() & (0x01 << 14)) != 0x00; - } - - public boolean getfBinary() { - return (this.intValue() & 0x01) != 0x00; - } - - public boolean getfDsrSensitivity() { - return (this.intValue() & (0x01 << 6)) != 0x00; - } - - public int getfDtrControl() { - return (this.intValue() >>> 4) & 0x03; - } - - public boolean getfErrorChar() { - return (this.intValue() & (0x01 << 10)) != 0x00; - } - - public boolean getfInX() { - return (this.intValue() & (0x01 << 9)) != 0x00; - } - - public boolean getfNull() { - return (this.intValue() & (0x01 << 11)) != 0x00; - } - - public boolean getfOutX() { - return (this.intValue() & (0x01 << 8)) != 0x00; - } - - public boolean getfOutxCtsFlow() { - return (this.intValue() & (0x01 << 2)) != 0x00; - } - - public boolean getfOutxDsrFlow() { - return (this.intValue() & (0x01 << 3)) != 0x00; - } - - public boolean getfParity() { - return (this.intValue() & (0x01 << 1)) != 0x00; - } - - public int getfRtsControl() { - return (this.intValue() >>> 12) & 0x03; - } - - public int getfDummy2() { - return (this.intValue()>>>15) & 0x1FFFF; - } - - public boolean getfTXContinueOnXoff() { - return (this.intValue() & (0x01 << 7)) != 0x00; - } - - /** - * If this member is TRUE, the driver terminates all read and write - * operations with an error status if an error occurs.
    - * The driver will not accept any further communications operations - * until the application has acknowledged the error by calling the - * ClearCommError function. - * - * @param fAbortOnError - */ - public void setfAbortOnError(boolean fAbortOnError) { - int tmp = leftShiftMask(fAbortOnError ? 1 : 0, (byte)14, 0x01, this.intValue()); - this.setValue(tmp); - } - - /** - * If this member is TRUE, binary mode is enabled.
    - * Windows does not support nonbinary mode transfers, so this member - * must be TRUE. - * - * @param fBinary - */ - public void setfBinary(boolean fBinary) { - int tmp = leftShiftMask(fBinary ? 1 : 0, (byte)0, 0x01, this.intValue()); - this.setValue(tmp); - } - - /** - * If this member is TRUE, the communications driver is sensitive to the - * state of the DSR signal.
    - * The driver ignores any bytes received, unless the DSR modem input - * line is high. - * - * @param fDsrSensitivity - */ - public void setfDsrSensitivity(boolean fDsrSensitivity) { - int tmp = leftShiftMask(fDsrSensitivity ? 1 : 0, (byte)6, 0x01, this.intValue()); - this.setValue(tmp); - } - - /** - * The DTR (data-terminal-ready) flow control. This member can be one of - * the following values. - *
  • {@link WinBase#DTR_CONTROL_DISABLE}
  • - *
  • {@link WinBase#DTR_CONTROL_ENABLE}
  • - *
  • {@link WinBase#DTR_CONTROL_HANDSHAKE}
  • - * - * @param fOutxDsrFlow - * value to set - */ - public void setfDtrControl(int fOutxDsrFlow) { - int tmp = leftShiftMask(fOutxDsrFlow, (byte)4, 0x03, this.intValue()); - this.setValue(tmp); - } - - /** - * Indicates whether bytes received with parity errors are replaced with - * the character specified by the ErrorChar member.
    - * If this member is TRUE and the fParity member is TRUE, replacement - * occurs. - * - * @param fErrorChar - */ - public void setfErrorChar(boolean fErrorChar) { - int tmp = leftShiftMask(fErrorChar ? 1 : 0, (byte)10, 0x01, this.intValue()); - this.setValue(tmp); - } - - /** - * Indicates whether XON/XOFF flow control is used during reception.
    - * If this member is TRUE, the XoffChar character is sent when the input - * buffer comes within XoffLim bytes of being full, and the XonChar - * character is sent when the input buffer comes within XonLim bytes of - * being empty. - * - * @param fInX - */ - public void setfInX(boolean fInX) { - int tmp = leftShiftMask(fInX ? 1 : 0, (byte)9, 0x01, this.intValue()); - this.setValue(tmp); - } - - /** - * If this member is TRUE, null bytes are discarded when received. - * - * @param fNull - */ - public void setfNull(boolean fNull) { - int tmp = leftShiftMask(fNull ? 1 : 0, (byte)11, 0x01, this.intValue()); - this.setValue(tmp); - } - - /** - * Indicates whether XON/XOFF flow control is used during transmission. - *
    - * If this member is TRUE, transmission stops when the XoffChar - * character is received and starts again when the XonChar character is - * received. - * - * @param fOutX - */ - public void setfOutX(boolean fOutX) { - int tmp = leftShiftMask(fOutX ? 1 : 0, (byte)8, 0x01, this.intValue()); - this.setValue(tmp); - } - - /** - * If this member is TRUE, the CTS (clear-to-send) signal is monitored - * for output flow control.
    - * If this member is TRUE and CTS is turned off, output is suspended - * until CTS is sent again. - * - * @param fOutxCtsFlow - */ - public void setfOutxCtsFlow(boolean fOutxCtsFlow) { - int tmp = leftShiftMask(fOutxCtsFlow ? 1 : 0, (byte)2, 0x01, this.intValue()); - this.setValue(tmp); - } - - /** - * If this member is TRUE, the DSR (data-set-ready) signal is monitored - * for output flow control.
    - * If this member is TRUE and DSR is turned off, output is suspended - * until DSR is sent again. - * - * @param fOutxDsrFlow - */ - public void setfOutxDsrFlow(boolean fOutxDsrFlow) { - int tmp = leftShiftMask(fOutxDsrFlow ? 1 : 0, (byte)3, 0x01, this.intValue()); - this.setValue(tmp); - } - - /** - * If this member is TRUE, parity checking is performed and errors are - * reported. - * - * @param fParity - */ - public void setfParity(boolean fParity) { - int tmp = leftShiftMask(fParity ? 1 : 0, (byte)1, 0x01, this.intValue()); - this.setValue(tmp); - } - - /** - * - * The RTS (request-to-send) flow control. This member can be one of the - * following values. - *
  • {@link WinBase#RTS_CONTROL_DISABLE}
  • - *
  • {@link WinBase#RTS_CONTROL_ENABLE}
  • - *
  • {@link WinBase#RTS_CONTROL_HANDSHAKE}
  • - *
  • {@link WinBase#RTS_CONTROL_TOGGLE}
  • - * - * @param fRtsControl - */ - public void setfRtsControl(int fRtsControl) { - int tmp = leftShiftMask(fRtsControl, (byte)12, 0x03, this.intValue()); - this.setValue(tmp); - } - - /** - * If this member is TRUE, transmission continues after the input buffer - * has come within XoffLim bytes of being full and the driver has - * transmitted the XoffChar character to stop receiving bytes.
    - * If this member is FALSE, transmission does not continue until the - * input buffer is within XonLim bytes of being empty and the driver has - * transmitted the XonChar character to resume reception. - * - * @param fTXContinueOnXoff - */ - public void setfTXContinueOnXoff(boolean fTXContinueOnXoff) { - int tmp = leftShiftMask(fTXContinueOnXoff ? 1 : 0, (byte)7, 0x01, this.intValue()); - this.setValue(tmp); - } - - - private static int leftShiftMask(int valuetoset, byte shift, int mask, int storage) { - int tmp = storage; - tmp &= ~(mask << shift); - tmp |= ((valuetoset & mask) << shift); - return tmp; - } - } - /** - * The length of the structure, in bytes. The caller must set this - * member to sizeof(DCB). - */ - public DWORD DCBlength; - - /** - * - * The baud rate at which the communications device operates. This - * member can be an actual baud rate value, or one of the following - * indexes. - *
  • {@link WinBase#CBR_110}
  • - *
  • {@link WinBase#CBR_300}
  • - *
  • {@link WinBase#CBR_600}
  • - *
  • {@link WinBase#CBR_1200}
  • - *
  • {@link WinBase#CBR_2400}
  • - *
  • {@link WinBase#CBR_4800}
  • - *
  • {@link WinBase#CBR_9600}
  • - *
  • {@link WinBase#CBR_14400}
  • - *
  • {@link WinBase#CBR_19200}
  • - *
  • {@link WinBase#CBR_38400}
  • - *
  • {@link WinBase#CBR_56000}
  • - *
  • {@link WinBase#CBR_128000}
  • - *
  • {@link WinBase#CBR_256000}
  • - * - */ - public DWORD BaudRate; - - /** - * Contains all the bit wise setting entries. - */ - public DCBControllBits controllBits; - - /** - * Reserved; must be zero. - */ - public WORD wReserved; - - /** - * The minimum number of bytes in use allowed in the input buffer before - * flow control is activated to allow transmission by the sender. This - * assumes that either XON/XOFF, RTS, or DTR input flow control is - * specified in the fInX, fRtsControl, or fDtrControl members. - */ - public WORD XonLim; - - /** - * The minimum number of free bytes allowed in the input buffer before - * flow control is activated to inhibit the sender. Note that the sender - * may transmit characters after the flow control signal has been - * activated, so this value should never be zero. This assumes that - * either XON/XOFF, RTS, or DTR input flow control is specified in the - * fInX, fRtsControl, or fDtrControl members. The maximum number of - * bytes in use allowed is calculated by subtracting this value from the - * size, in bytes, of the input buffer. - */ - public WORD XoffLim; - - /** - * The number of bits in the bytes transmitted and received. - */ - public BYTE ByteSize; - - /** - * - * The parity scheme to be used. This member can be one of the following - * values. - *
  • {@link WinBase#EVENPARITY}
  • - *
  • {@link WinBase#ODDPARITY}
  • - *
  • {@link WinBase#NOPARITY}
  • - *
  • {@link WinBase#SPACEPARITY}
  • - *
  • {@link WinBase#MARKPARITY}
  • - */ - public BYTE Parity; - - /** - * The number of stop bits to be used. This member can be one of the - * following values. - *
  • {@link WinBase#ONESTOPBIT}
  • - *
  • {@link WinBase#ONE5STOPBITS}
  • - *
  • {@link WinBase#TWOSTOPBITS}
  • - */ - public BYTE StopBits; - - /** - * The value of the XON character for both transmission and reception. - */ - public char XonChar; - - /** - * The value of the XOFF character for both transmission and reception. - */ - public char XoffChar; - - /** - * The value of the character used to replace bytes received with a - * parity error. - */ - public char ErrorChar; - - /** - * The value of the character used to signal the end of data. - */ - public char EofChar; - - /** - * The value of the character used to signal an event. - */ - public char EvtChar; - - /** - * Reserved; do not use. - */ - public WORD wReserved1; - - public DCB() { - DCBlength = new DWORD(size()); - } - - protected List getFieldOrder() { - return Arrays.asList(new String[] { "DCBlength", "BaudRate", "controllBits", "wReserved", "XonLim", - "XoffLim", "ByteSize", "Parity", "StopBits", "XonChar", "XoffChar", "ErrorChar", "EofChar", - "EvtChar", "wReserved1" }); - } - } - - /** - * No parity. - */ - int NOPARITY = 0; - - /** - * Odd parity. - */ - int ODDPARITY = 1; - - /** - * Even parity. - */ - int EVENPARITY = 2; - - /** - * Mark parity. - */ - int MARKPARITY = 3; - - /** - * Space parity. - */ - int SPACEPARITY = 4; - - /** - * 1 stop bit. - */ - int ONESTOPBIT = 0; - - /** - * 1.5 stop bits. - */ - int ONE5STOPBITS = 1; - /** - * 2 stop bits. - */ - int TWOSTOPBITS = 2; - /** - * 110 bps. - */ - int CBR_110 = 110; - /** - * 300 bps. - */ - int CBR_300 = 300; - /** - * 600 bps. - */ - int CBR_600 = 600; - /** - * 1200 bps. - */ - int CBR_1200 = 1200; - /** - * 2400 bps. - */ - int CBR_2400 = 2400; - /** - * 4800 bps. - */ - int CBR_4800 = 4800; - /** - * 9600 bps. - */ - int CBR_9600 = 9600; - /** - * 14400 bps. - */ - int CBR_14400 = 14400; - /** - * 19200 bps. - */ - int CBR_19200 = 19200; - /** - * 38400 bps. - */ - int CBR_38400 = 38400; - /** - * 56000 bps. - */ - int CBR_56000 = 56000; - - /** - * 128000 bps. - */ - int CBR_128000 = 128000; - - /** - * 256000 bps. - */ - int CBR_256000 = 256000; - - /** - * Disables the DTR line when the device is opened and leaves it disabled. - */ - int DTR_CONTROL_DISABLE = 0; - - /** - * Enables the DTR line when the device is opened and leaves it on. - */ - int DTR_CONTROL_ENABLE = 1; - - /** - * Enables DTR handshaking.
    - * If handshaking is enabled, it is an error for the application to adjust - * the line by using the EscapeCommFunction function. - */ - int DTR_CONTROL_HANDSHAKE = 2; - - /** - * Disables the RTS line when the device is opened and leaves it disabled. - */ - int RTS_CONTROL_DISABLE = 0; - - /** - * Enables the RTS line when the device is opened and leaves it on. - */ - int RTS_CONTROL_ENABLE = 1; - - /** - * Enables RTS handshaking.
    - * The driver raises the RTS line when the "type-ahead" (input) buffer is - * less than one-half full and lowers the RTS line when the buffer is more - * than three-quarters full.
    - * If handshaking is enabled, it is an error for the application to adjust - * the line by using the EscapeCommFunction function. - */ - int RTS_CONTROL_HANDSHAKE = 2; - - /** - * Specifies that the RTS line will be high if bytes are available for - * transmission.
    - * After all buffered bytes have been sent, the RTS line will be low. - */ - int RTS_CONTROL_TOGGLE = 3;; + + + /** + * + * Contains the time-out parameters for a communications device. The + * parameters determine the behavior of + * {@link Kernel32#ReadFile(com.sun.jna.platform.win32.WinNT.HANDLE, java.nio.Buffer, int, com.sun.jna.ptr.IntByReference, com.sun.jna.platform.win32.WinBase.OVERLAPPED)} + * , {@link Kernel32#WriteFile(com.sun.jna.platform.win32.WinNT.HANDLE, + * byte[], int, com.sun.jna.ptr.IntByReference, + * com.sun.jna.platform.win32.WinBase.OVERLAPPED))}, ReadFileEx, and + * WriteFileEx operations on the device.
    + *
    + * + * Remarks
    + * If an application sets ReadIntervalTimeout and ReadTotalTimeoutMultiplier + * to MAXDWORD and sets ReadTotalTimeoutConstant to a value greater than + * zero and less than MAXDWORD, one of the following occurs when the + * ReadFile function is called: + *
  • If there are any bytes in the input buffer, ReadFile returns + * immediately with the bytes in the buffer.
  • + *
  • If there are no bytes in the input buffer, ReadFile waits until a + * byte arrives and then returns immediately.
  • + *
  • If no bytes arrive within the time specified by + * ReadTotalTimeoutConstant, ReadFile times out.
  • + * + * @author Markus + * + */ + public static class COMMTIMEOUTS extends Structure { + /** + * + * The maximum time allowed to elapse before the arrival of the next + * byte on the communications line, in milliseconds. If the interval + * between the arrival of any two bytes exceeds this amount, the + * {@link Kernel32#ReadFile(com.sun.jna.platform.win32.WinNT.HANDLE, java.nio.Buffer, int, com.sun.jna.ptr.IntByReference, com.sun.jna.platform.win32.WinBase.OVERLAPPED)} + * operation is completed and any buffered data is returned. A value of + * zero indicates that interval time-outs are not used. + * + * A value of MAXDWORD, combined with zero values for both the + * {@link COMMTIMEOUTS#ReadTotalTimeoutConstant} and + * {@link COMMTIMEOUTS#ReadTotalTimeoutMultiplier} members, specifies + * that the read operation is to return immediately with the bytes that + * have already been received, even if no bytes have been received. + * + */ + public DWORD ReadIntervalTimeout; + + /** + * The multiplier used to calculate the total time-out period for read + * operations, in milliseconds. For each read operation, this value is + * multiplied by the requested number of bytes to be read. + */ + public DWORD ReadTotalTimeoutMultiplier; + + /** + * A constant used to calculate the total time-out period for read + * operations, in milliseconds. For each read operation, this value is + * added to the product of the + * {@link COMMTIMEOUTS#ReadTotalTimeoutMultiplier} member and the + * requested number of bytes. + * + * A value of zero for both the + * {@link COMMTIMEOUTS#ReadTotalTimeoutMultiplier} and + * {@link COMMTIMEOUTS#ReadTotalTimeoutConstant} members indicates that + * total time-outs are not used for read operations. + */ + public DWORD ReadTotalTimeoutConstant; + + /** + * The multiplier used to calculate the total time-out period for write + * operations, in milliseconds. For each write operation, this value is + * multiplied by the number of bytes to be written. + */ + public DWORD WriteTotalTimeoutMultiplier; + + /** + * A constant used to calculate the total time-out period for write + * operations, in milliseconds. For each write operation, this value is + * added to the product of the + * {@link COMMTIMEOUTS#WriteTotalTimeoutMultiplier} member and the + * number of bytes to be written. + * + * A value of zero for both the + * {@link COMMTIMEOUTS#WriteTotalTimeoutMultiplier} and + * {@link COMMTIMEOUTS#WriteTotalTimeoutConstant} members indicates that + * total time-outs are not used for write operations. + * + */ + public DWORD WriteTotalTimeoutConstant; + + @Override + protected List getFieldOrder() { + return Arrays.asList(new String[] { "ReadIntervalTimeout", "ReadTotalTimeoutMultiplier", + "ReadTotalTimeoutConstant", "WriteTotalTimeoutMultiplier", "WriteTotalTimeoutConstant" }); + } + } + + + + /** + * Defines the control setting for a serial communications device. + */ + public static class DCB extends Structure { + + /** + * Type is used to handle the bitfield of the DBC structure. + */ + public static class DCBControllBits extends DWORD { + private static final long serialVersionUID = 8574966619718078579L; + + @Override + public String toString() { + final StringBuilder stringBuilder = new StringBuilder(); + stringBuilder.append('<'); + stringBuilder.append("fBinary:1="); + stringBuilder.append(getfBinary() ? '1' : '0'); + stringBuilder.append(", fParity:1="); + stringBuilder.append(getfParity() ? '1' : '0'); + stringBuilder.append(", fOutxCtsFlow:1="); + stringBuilder.append(getfOutxCtsFlow() ? '1' : '0'); + stringBuilder.append(", fOutxDsrFlow:1="); + stringBuilder.append(getfOutxDsrFlow() ? '1' : '0'); + stringBuilder.append(", fDtrControl:2="); + stringBuilder.append(getfDtrControl()); + stringBuilder.append(", fDsrSensitivity:1="); + stringBuilder.append(getfDsrSensitivity() ? '1' : '0'); + stringBuilder.append(", fTXContinueOnXoff:1="); + stringBuilder.append(getfTXContinueOnXoff() ? '1' : '0'); + stringBuilder.append(", fOutX:1="); + stringBuilder.append(getfOutX() ? '1' : '0'); + stringBuilder.append(", fInX:1="); + stringBuilder.append(getfInX() ? '1' : '0'); + stringBuilder.append(", fErrorChar:1="); + stringBuilder.append(getfErrorChar() ? '1' : '0'); + stringBuilder.append(", fNull:1="); + stringBuilder.append(getfNull() ? '1' : '0'); + stringBuilder.append(", fRtsControl:2="); + stringBuilder.append(getfRtsControl()); + stringBuilder.append(", fAbortOnError:1="); + stringBuilder.append(getfAbortOnError() ? '1' : '0'); + stringBuilder.append(", fDummy2:17="); + stringBuilder.append(getfDummy2()); + stringBuilder.append('>'); + return stringBuilder.toString(); + } + + public boolean getfAbortOnError() { + return (this.intValue() & (0x01 << 14)) != 0x00; + } + + public boolean getfBinary() { + return (this.intValue() & 0x01) != 0x00; + } + + public boolean getfDsrSensitivity() { + return (this.intValue() & (0x01 << 6)) != 0x00; + } + + public int getfDtrControl() { + return (this.intValue() >>> 4) & 0x03; + } + + public boolean getfErrorChar() { + return (this.intValue() & (0x01 << 10)) != 0x00; + } + + public boolean getfInX() { + return (this.intValue() & (0x01 << 9)) != 0x00; + } + + public boolean getfNull() { + return (this.intValue() & (0x01 << 11)) != 0x00; + } + + public boolean getfOutX() { + return (this.intValue() & (0x01 << 8)) != 0x00; + } + + public boolean getfOutxCtsFlow() { + return (this.intValue() & (0x01 << 2)) != 0x00; + } + + public boolean getfOutxDsrFlow() { + return (this.intValue() & (0x01 << 3)) != 0x00; + } + + public boolean getfParity() { + return (this.intValue() & (0x01 << 1)) != 0x00; + } + + public int getfRtsControl() { + return (this.intValue() >>> 12) & 0x03; + } + + public int getfDummy2() { + return (this.intValue()>>>15) & 0x1FFFF; + } + + public boolean getfTXContinueOnXoff() { + return (this.intValue() & (0x01 << 7)) != 0x00; + } + + /** + * If this member is TRUE, the driver terminates all read and write + * operations with an error status if an error occurs.
    + * The driver will not accept any further communications operations + * until the application has acknowledged the error by calling the + * ClearCommError function. + * + * @param fAbortOnError + */ + public void setfAbortOnError(boolean fAbortOnError) { + int tmp = leftShiftMask(fAbortOnError ? 1 : 0, (byte)14, 0x01, this.intValue()); + this.setValue(tmp); + } + + /** + * If this member is TRUE, binary mode is enabled.
    + * Windows does not support nonbinary mode transfers, so this member + * must be TRUE. + * + * @param fBinary + */ + public void setfBinary(boolean fBinary) { + int tmp = leftShiftMask(fBinary ? 1 : 0, (byte)0, 0x01, this.intValue()); + this.setValue(tmp); + } + + /** + * If this member is TRUE, the communications driver is sensitive to the + * state of the DSR signal.
    + * The driver ignores any bytes received, unless the DSR modem input + * line is high. + * + * @param fDsrSensitivity + */ + public void setfDsrSensitivity(boolean fDsrSensitivity) { + int tmp = leftShiftMask(fDsrSensitivity ? 1 : 0, (byte)6, 0x01, this.intValue()); + this.setValue(tmp); + } + + /** + * The DTR (data-terminal-ready) flow control. This member can be one of + * the following values. + *
  • {@link WinBase#DTR_CONTROL_DISABLE}
  • + *
  • {@link WinBase#DTR_CONTROL_ENABLE}
  • + *
  • {@link WinBase#DTR_CONTROL_HANDSHAKE}
  • + * + * @param fOutxDsrFlow + * value to set + */ + public void setfDtrControl(int fOutxDsrFlow) { + int tmp = leftShiftMask(fOutxDsrFlow, (byte)4, 0x03, this.intValue()); + this.setValue(tmp); + } + + /** + * Indicates whether bytes received with parity errors are replaced with + * the character specified by the ErrorChar member.
    + * If this member is TRUE and the fParity member is TRUE, replacement + * occurs. + * + * @param fErrorChar + */ + public void setfErrorChar(boolean fErrorChar) { + int tmp = leftShiftMask(fErrorChar ? 1 : 0, (byte)10, 0x01, this.intValue()); + this.setValue(tmp); + } + + /** + * Indicates whether XON/XOFF flow control is used during reception.
    + * If this member is TRUE, the XoffChar character is sent when the input + * buffer comes within XoffLim bytes of being full, and the XonChar + * character is sent when the input buffer comes within XonLim bytes of + * being empty. + * + * @param fInX + */ + public void setfInX(boolean fInX) { + int tmp = leftShiftMask(fInX ? 1 : 0, (byte)9, 0x01, this.intValue()); + this.setValue(tmp); + } + + /** + * If this member is TRUE, null bytes are discarded when received. + * + * @param fNull + */ + public void setfNull(boolean fNull) { + int tmp = leftShiftMask(fNull ? 1 : 0, (byte)11, 0x01, this.intValue()); + this.setValue(tmp); + } + + /** + * Indicates whether XON/XOFF flow control is used during transmission. + *
    + * If this member is TRUE, transmission stops when the XoffChar + * character is received and starts again when the XonChar character is + * received. + * + * @param fOutX + */ + public void setfOutX(boolean fOutX) { + int tmp = leftShiftMask(fOutX ? 1 : 0, (byte)8, 0x01, this.intValue()); + this.setValue(tmp); + } + + /** + * If this member is TRUE, the CTS (clear-to-send) signal is monitored + * for output flow control.
    + * If this member is TRUE and CTS is turned off, output is suspended + * until CTS is sent again. + * + * @param fOutxCtsFlow + */ + public void setfOutxCtsFlow(boolean fOutxCtsFlow) { + int tmp = leftShiftMask(fOutxCtsFlow ? 1 : 0, (byte)2, 0x01, this.intValue()); + this.setValue(tmp); + } + + /** + * If this member is TRUE, the DSR (data-set-ready) signal is monitored + * for output flow control.
    + * If this member is TRUE and DSR is turned off, output is suspended + * until DSR is sent again. + * + * @param fOutxDsrFlow + */ + public void setfOutxDsrFlow(boolean fOutxDsrFlow) { + int tmp = leftShiftMask(fOutxDsrFlow ? 1 : 0, (byte)3, 0x01, this.intValue()); + this.setValue(tmp); + } + + /** + * If this member is TRUE, parity checking is performed and errors are + * reported. + * + * @param fParity + */ + public void setfParity(boolean fParity) { + int tmp = leftShiftMask(fParity ? 1 : 0, (byte)1, 0x01, this.intValue()); + this.setValue(tmp); + } + + /** + * + * The RTS (request-to-send) flow control. This member can be one of the + * following values. + *
  • {@link WinBase#RTS_CONTROL_DISABLE}
  • + *
  • {@link WinBase#RTS_CONTROL_ENABLE}
  • + *
  • {@link WinBase#RTS_CONTROL_HANDSHAKE}
  • + *
  • {@link WinBase#RTS_CONTROL_TOGGLE}
  • + * + * @param fRtsControl + */ + public void setfRtsControl(int fRtsControl) { + int tmp = leftShiftMask(fRtsControl, (byte)12, 0x03, this.intValue()); + this.setValue(tmp); + } + + /** + * If this member is TRUE, transmission continues after the input buffer + * has come within XoffLim bytes of being full and the driver has + * transmitted the XoffChar character to stop receiving bytes.
    + * If this member is FALSE, transmission does not continue until the + * input buffer is within XonLim bytes of being empty and the driver has + * transmitted the XonChar character to resume reception. + * + * @param fTXContinueOnXoff + */ + public void setfTXContinueOnXoff(boolean fTXContinueOnXoff) { + int tmp = leftShiftMask(fTXContinueOnXoff ? 1 : 0, (byte)7, 0x01, this.intValue()); + this.setValue(tmp); + } + + + private static int leftShiftMask(int valuetoset, byte shift, int mask, int storage) { + int tmp = storage; + tmp &= ~(mask << shift); + tmp |= ((valuetoset & mask) << shift); + return tmp; + } + } + /** + * The length of the structure, in bytes. The caller must set this + * member to sizeof(DCB). + */ + public DWORD DCBlength; + + /** + * + * The baud rate at which the communications device operates. This + * member can be an actual baud rate value, or one of the following + * indexes. + *
  • {@link WinBase#CBR_110}
  • + *
  • {@link WinBase#CBR_300}
  • + *
  • {@link WinBase#CBR_600}
  • + *
  • {@link WinBase#CBR_1200}
  • + *
  • {@link WinBase#CBR_2400}
  • + *
  • {@link WinBase#CBR_4800}
  • + *
  • {@link WinBase#CBR_9600}
  • + *
  • {@link WinBase#CBR_14400}
  • + *
  • {@link WinBase#CBR_19200}
  • + *
  • {@link WinBase#CBR_38400}
  • + *
  • {@link WinBase#CBR_56000}
  • + *
  • {@link WinBase#CBR_128000}
  • + *
  • {@link WinBase#CBR_256000}
  • + * + */ + public DWORD BaudRate; + + /** + * Contains all the bit wise setting entries. + */ + public DCBControllBits controllBits; + + /** + * Reserved; must be zero. + */ + public WORD wReserved; + + /** + * The minimum number of bytes in use allowed in the input buffer before + * flow control is activated to allow transmission by the sender. This + * assumes that either XON/XOFF, RTS, or DTR input flow control is + * specified in the fInX, fRtsControl, or fDtrControl members. + */ + public WORD XonLim; + + /** + * The minimum number of free bytes allowed in the input buffer before + * flow control is activated to inhibit the sender. Note that the sender + * may transmit characters after the flow control signal has been + * activated, so this value should never be zero. This assumes that + * either XON/XOFF, RTS, or DTR input flow control is specified in the + * fInX, fRtsControl, or fDtrControl members. The maximum number of + * bytes in use allowed is calculated by subtracting this value from the + * size, in bytes, of the input buffer. + */ + public WORD XoffLim; + + /** + * The number of bits in the bytes transmitted and received. + */ + public BYTE ByteSize; + + /** + * + * The parity scheme to be used. This member can be one of the following + * values. + *
  • {@link WinBase#EVENPARITY}
  • + *
  • {@link WinBase#ODDPARITY}
  • + *
  • {@link WinBase#NOPARITY}
  • + *
  • {@link WinBase#SPACEPARITY}
  • + *
  • {@link WinBase#MARKPARITY}
  • + */ + public BYTE Parity; + + /** + * The number of stop bits to be used. This member can be one of the + * following values. + *
  • {@link WinBase#ONESTOPBIT}
  • + *
  • {@link WinBase#ONE5STOPBITS}
  • + *
  • {@link WinBase#TWOSTOPBITS}
  • + */ + public BYTE StopBits; + + /** + * The value of the XON character for both transmission and reception. + */ + public char XonChar; + + /** + * The value of the XOFF character for both transmission and reception. + */ + public char XoffChar; + + /** + * The value of the character used to replace bytes received with a + * parity error. + */ + public char ErrorChar; + + /** + * The value of the character used to signal the end of data. + */ + public char EofChar; + + /** + * The value of the character used to signal an event. + */ + public char EvtChar; + + /** + * Reserved; do not use. + */ + public WORD wReserved1; + + public DCB() { + DCBlength = new DWORD(size()); + } + + @Override + protected List getFieldOrder() { + return Arrays.asList(new String[] { "DCBlength", "BaudRate", "controllBits", "wReserved", "XonLim", + "XoffLim", "ByteSize", "Parity", "StopBits", "XonChar", "XoffChar", "ErrorChar", "EofChar", + "EvtChar", "wReserved1" }); + } + } + + /** + * No parity. + */ + int NOPARITY = 0; + + /** + * Odd parity. + */ + int ODDPARITY = 1; + + /** + * Even parity. + */ + int EVENPARITY = 2; + + /** + * Mark parity. + */ + int MARKPARITY = 3; + + /** + * Space parity. + */ + int SPACEPARITY = 4; + + /** + * 1 stop bit. + */ + int ONESTOPBIT = 0; + + /** + * 1.5 stop bits. + */ + int ONE5STOPBITS = 1; + /** + * 2 stop bits. + */ + int TWOSTOPBITS = 2; + /** + * 110 bps. + */ + int CBR_110 = 110; + /** + * 300 bps. + */ + int CBR_300 = 300; + /** + * 600 bps. + */ + int CBR_600 = 600; + /** + * 1200 bps. + */ + int CBR_1200 = 1200; + /** + * 2400 bps. + */ + int CBR_2400 = 2400; + /** + * 4800 bps. + */ + int CBR_4800 = 4800; + /** + * 9600 bps. + */ + int CBR_9600 = 9600; + /** + * 14400 bps. + */ + int CBR_14400 = 14400; + /** + * 19200 bps. + */ + int CBR_19200 = 19200; + /** + * 38400 bps. + */ + int CBR_38400 = 38400; + /** + * 56000 bps. + */ + int CBR_56000 = 56000; + + /** + * 128000 bps. + */ + int CBR_128000 = 128000; + + /** + * 256000 bps. + */ + int CBR_256000 = 256000; + + /** + * Disables the DTR line when the device is opened and leaves it disabled. + */ + int DTR_CONTROL_DISABLE = 0; + + /** + * Enables the DTR line when the device is opened and leaves it on. + */ + int DTR_CONTROL_ENABLE = 1; + + /** + * Enables DTR handshaking.
    + * If handshaking is enabled, it is an error for the application to adjust + * the line by using the EscapeCommFunction function. + */ + int DTR_CONTROL_HANDSHAKE = 2; + + /** + * Disables the RTS line when the device is opened and leaves it disabled. + */ + int RTS_CONTROL_DISABLE = 0; + + /** + * Enables the RTS line when the device is opened and leaves it on. + */ + int RTS_CONTROL_ENABLE = 1; + + /** + * Enables RTS handshaking.
    + * The driver raises the RTS line when the "type-ahead" (input) buffer is + * less than one-half full and lowers the RTS line when the buffer is more + * than three-quarters full.
    + * If handshaking is enabled, it is an error for the application to adjust + * the line by using the EscapeCommFunction function. + */ + int RTS_CONTROL_HANDSHAKE = 2; + + /** + * Specifies that the RTS line will be high if bytes are available for + * transmission.
    + * After all buffered bytes have been sent, the RTS line will be low. + */ + int RTS_CONTROL_TOGGLE = 3;; + + /** + * An application-defined callback function used with the EnumResourceTypes + * and EnumResourceTypesEx functions.
    + * It receives resource types.
    + * The ENUMRESTYPEPROC type defines a pointer to this callback function. + *
    + * EnumResTypeProc is a placeholder for the application-defined function + * name. + */ + interface EnumResTypeProc extends Callback { + /** + * @param module + * A handle to the module whose executable file contains the + * resources for which the types are to be enumerated.
    + * If this parameter is NULL, the function enumerates the + * resource types in the module used to create the current + * process. + * @param type + * The type of resource for which the type is being + * enumerated.
    + * 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. + * @param lParam + * An application-defined parameter passed to the + * EnumResourceTypes or EnumResourceTypesEx function.
    + * This parameter can be used in error checking. + * @return Returns TRUE to continue enumeration or FALSE to stop + * enumeration. + */ + boolean invoke(HMODULE module, Pointer type, Pointer lParam); + } + + /** + * An application-defined callback function used with the EnumResourceNames + * and EnumResourceNamesEx functions.
    + * It receives the type and name of a resource.
    + * The ENUMRESNAMEPROC type defines a pointer to this callback function. + *
    + * EnumResNameProc is a placeholder for the application-defined function + * name. + */ + interface EnumResNameProc extends Callback { + /** + * @param module + * A handle to the module whose executable file contains the + * resources that are being enumerated.
    + * If this parameter is NULL, the function enumerates the + * resource names in the module used to create the current + * process. + * @param type + * The type of resource for which the name is being + * enumerated.
    + * Alternately, rather than a pointer, this parameter can be + * MAKEINTRESOURCE(ID), where ID is an integer + * value representing a predefined resource type.
    + * For standard resource types, see + * Resource Types.
    + * For more information, see the Remarks section below. + * @param name + * The name of a resource of the type being enumerated.
    + * 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 lParam + * An application-defined parameter passed to the + * EnumResourceNames or EnumResourceNamesEx function.
    + * This parameter can be used in error checking. + * @return Returns TRUE to continue enumeration or FALSE to stop + * enumeration. + */ + boolean invoke(HMODULE module, Pointer type, Pointer name, Pointer lParam); + } } diff --git a/contrib/platform/src/com/sun/jna/platform/win32/WinCrypt.java b/contrib/platform/src/com/sun/jna/platform/win32/WinCrypt.java index 07078abc82..2f3239086a 100644 --- a/contrib/platform/src/com/sun/jna/platform/win32/WinCrypt.java +++ b/contrib/platform/src/com/sun/jna/platform/win32/WinCrypt.java @@ -20,14 +20,13 @@ import com.sun.jna.Pointer; import com.sun.jna.Structure; import com.sun.jna.platform.win32.WinDef.HWND; -import com.sun.jna.win32.StdCallLibrary; /** * Ported from WinCrypt.h. * Microsoft Windows SDK 6.0A. * @author dblock[at]dblock.org */ -public interface WinCrypt extends StdCallLibrary { +public interface WinCrypt { /** * The CryptoAPI CRYPTOAPI_BLOB structure is used for an arbitrary array of bytes. @@ -172,4 +171,118 @@ protected List getFieldOrder() { * Regenerate the local machine protection. */ int CRYPTPROTECT_CRED_REGENERATE = 0x80; + + /** + * ASN.1 Certificate encode/decode return value base + * @see MSDN + */ + int CRYPT_E_ASN1_ERROR = 0x80093100; + + /** + * ASN.1 internal encode or decode error + * @see MSDN + */ + int CRYPT_E_ASN1_INTERNAL = 0x80093101; + + /** + * ASN.1 unexpected end of data + * @see MSDN + */ + int CRYPT_E_ASN1_EOD = 0x80093102; + + /** + * ASN.1 corrupted data + * @see MSDN + */ + int CRYPT_E_ASN1_CORRUPT = 0x80093103; + + /** + * ASN.1 value too large + * @see MSDN + */ + int CRYPT_E_ASN1_LARGE = 0x80093104; + + /** + * ASN.1 constraint violated + * @see MSDN + */ + int CRYPT_E_ASN1_CONSTRAINT = 0x80093105; + + /** + * ASN.1 out of memory + * @see MSDN + */ + int CRYPT_E_ASN1_MEMORY = 0x80093106; + + /** + * ASN.1 buffer overflow + * @see MSDN + */ + int CRYPT_E_ASN1_OVERFLOW = 0x80093107; + + /** + * ASN.1 function not supported for this PDU + * @see MSDN + */ + int CRYPT_E_ASN1_BADPDU = 0x80093108; + + /** + * ASN.1 bad arguments to function call + * @see MSDN + */ + int CRYPT_E_ASN1_BADARGS = 0x80093109; + + /** + * ASN.1 bad real value + * @see MSDN + */ + int CRYPT_E_ASN1_BADREAL = 0x8009310A; + + /** + * ASN.1 bad tag value met + * @see MSDN + */ + int CRYPT_E_ASN1_BADTAG = 0x8009310B; + + /** + * ASN.1 bad choice value + * @see MSDN + */ + int CRYPT_E_ASN1_CHOICE = 0x8009310C; + + /** + * ASN.1 bad encoding rule + * @see MSDN + */ + int CRYPT_E_ASN1_RULE = 0x8009310D; + + /** + * ASN.1 bad Unicode (UTF8) + * @see MSDN + */ + int CRYPT_E_ASN1_UTF8 = 0x8009310E; + + /** + * ASN.1 bad PDU type + * @see MSDN + */ + int CRYPT_E_ASN1_PDU_TYPE = 0x80093133; + + /** + * ASN.1 not yet implemented + * @see MSDN + */ + int CRYPT_E_ASN1_NYI = 0x80093134; + + /** + * ASN.1 skipped unknown extensions + * @see MSDN + */ + int CRYPT_E_ASN1_EXTENDED = 0x80093201; + + /** + * ASN.1 end of data expected + * @see MSDN + */ + int CRYPT_E_ASN1_NOEOD = 0x80093202; } diff --git a/contrib/platform/src/com/sun/jna/platform/win32/WinDef.java b/contrib/platform/src/com/sun/jna/platform/win32/WinDef.java index f2f99a2075..3c531fca88 100644 --- a/contrib/platform/src/com/sun/jna/platform/win32/WinDef.java +++ b/contrib/platform/src/com/sun/jna/platform/win32/WinDef.java @@ -25,7 +25,6 @@ import com.sun.jna.platform.win32.WinNT.HANDLE; import com.sun.jna.platform.win32.WinNT.HANDLEByReference; import com.sun.jna.ptr.ByReference; -import com.sun.jna.win32.StdCallLibrary; /** * Ported from Windef.h (various macros and types). Microsoft Windows SDK 6.0A. @@ -33,7 +32,7 @@ * @author dblock[at]dblock.org */ @SuppressWarnings("serial") -public interface WinDef extends StdCallLibrary { +public interface WinDef { /** The max path. */ int MAX_PATH = 260; diff --git a/contrib/platform/src/com/sun/jna/platform/win32/WinGDI.java b/contrib/platform/src/com/sun/jna/platform/win32/WinGDI.java index c1faa9c005..40e1f38a4c 100644 --- a/contrib/platform/src/com/sun/jna/platform/win32/WinGDI.java +++ b/contrib/platform/src/com/sun/jna/platform/win32/WinGDI.java @@ -21,7 +21,6 @@ import com.sun.jna.platform.win32.WinNT.HANDLE; import com.sun.jna.platform.win32.WinDef.HBITMAP; import com.sun.jna.platform.win32.WinDef.RECT; -import com.sun.jna.win32.StdCallLibrary; /** * Ported from WinGDI.h. @@ -29,10 +28,10 @@ * @author dblock[at]dblock.org * @author Andreas "PAX" Lück, onkelpax-git[at]yahoo.de */ -public interface WinGDI extends StdCallLibrary { - public int RDH_RECTANGLES = 1; +public interface WinGDI { + int RDH_RECTANGLES = 1; - public class RGNDATAHEADER extends Structure { + class RGNDATAHEADER extends Structure { public int dwSize = size(); public int iType = RDH_RECTANGLES; // required public int nCount; @@ -44,7 +43,7 @@ protected List getFieldOrder() { } } - public class RGNDATA extends Structure { + class RGNDATA extends Structure { public RGNDATAHEADER rdh; public byte[] Buffer; @@ -61,50 +60,52 @@ public RGNDATA(int bufferSize) { } } - public int RGN_AND = 1; - public int RGN_OR = 2; - public int RGN_XOR = 3; - public int RGN_DIFF = 4; - public int RGN_COPY = 5; + HANDLE HGDI_ERROR = new HANDLE(Pointer.createConstant(0xFFFFFFFF)); - public int ERROR = 0; - public int NULLREGION = 1; - public int SIMPLEREGION = 2; - public int COMPLEXREGION = 3; + int RGN_AND = 1; + int RGN_OR = 2; + int RGN_XOR = 3; + int RGN_DIFF = 4; + int RGN_COPY = 5; + + int ERROR = 0; + int NULLREGION = 1; + int SIMPLEREGION = 2; + int COMPLEXREGION = 3; - public int ALTERNATE = 1; - public int WINDING = 2; + int ALTERNATE = 1; + int WINDING = 2; - public int BI_RGB = 0; - public int BI_RLE8 = 1; - public int BI_RLE4 = 2; - public int BI_BITFIELDS = 3; - public int BI_JPEG = 4; - public int BI_PNG = 5; + int BI_RGB = 0; + int BI_RLE8 = 1; + int BI_RLE4 = 2; + int BI_BITFIELDS = 3; + int BI_JPEG = 4; + int BI_PNG = 5; - public final int PFD_TYPE_RGBA = 0; - public final int PFD_TYPE_COLORINDEX = 1; + int PFD_TYPE_RGBA = 0; + int PFD_TYPE_COLORINDEX = 1; - public final int PFD_MAIN_PLANE = 0; - public final int PFD_OVERLAY_PLANE = 1; - public final int PFD_UNDERLAY_PLANE = (-1); + int PFD_MAIN_PLANE = 0; + int PFD_OVERLAY_PLANE = 1; + int PFD_UNDERLAY_PLANE = (-1); - public final int PFD_DOUBLEBUFFER = 0x00000001; - public final int PFD_STEREO = 0x00000002; - public final int PFD_DRAW_TO_WINDOW = 0x00000004; - public final int PFD_DRAW_TO_BITMAP = 0x00000008; - public final int PFD_SUPPORT_GDI = 0x00000010; - public final int PFD_SUPPORT_OPENGL = 0x00000020; - public final int PFD_GENERIC_FORMAT = 0x00000040; - public final int PFD_NEED_PALETTE = 0x00000080; - public final int PFD_NEED_SYSTEM_PALETTE = 0x00000100; - public final int PFD_SWAP_EXCHANGE = 0x00000200; - public final int PFD_SWAP_COPY = 0x00000400; - public final int PFD_SWAP_LAYER_BUFFERS = 0x00000800; - public final int PFD_GENERIC_ACCELERATED = 0x00001000; - public final int PFD_SUPPORT_DIRECTDRAW = 0x00002000; + int PFD_DOUBLEBUFFER = 0x00000001; + int PFD_STEREO = 0x00000002; + int PFD_DRAW_TO_WINDOW = 0x00000004; + int PFD_DRAW_TO_BITMAP = 0x00000008; + int PFD_SUPPORT_GDI = 0x00000010; + int PFD_SUPPORT_OPENGL = 0x00000020; + int PFD_GENERIC_FORMAT = 0x00000040; + int PFD_NEED_PALETTE = 0x00000080; + int PFD_NEED_SYSTEM_PALETTE = 0x00000100; + int PFD_SWAP_EXCHANGE = 0x00000200; + int PFD_SWAP_COPY = 0x00000400; + int PFD_SWAP_LAYER_BUFFERS = 0x00000800; + int PFD_GENERIC_ACCELERATED = 0x00001000; + int PFD_SUPPORT_DIRECTDRAW = 0x00002000; - public class BITMAPINFOHEADER extends Structure { + class BITMAPINFOHEADER extends Structure { public int biSize = size(); public int biWidth; public int biHeight; @@ -121,7 +122,7 @@ protected List getFieldOrder() { } } - public class RGBQUAD extends Structure { + class RGBQUAD extends Structure { public byte rgbBlue; public byte rgbGreen; public byte rgbRed; @@ -131,7 +132,7 @@ protected List getFieldOrder() { } } - public class BITMAPINFO extends Structure { + class BITMAPINFO extends Structure { public BITMAPINFOHEADER bmiHeader = new BITMAPINFOHEADER(); public RGBQUAD[] bmiColors = new RGBQUAD[1]; protected List getFieldOrder() { @@ -143,7 +144,7 @@ public BITMAPINFO(int size) { } } - public class ICONINFO extends Structure { + class ICONINFO extends Structure { public boolean fIcon; public int xHotspot; public int yHotspot; @@ -155,7 +156,7 @@ protected List getFieldOrder() { } } - public class BITMAP extends Structure { + class BITMAP extends Structure { public NativeLong bmType; public NativeLong bmWidth; public NativeLong bmHeight; @@ -169,7 +170,7 @@ protected List getFieldOrder() { } } - public class DIBSECTION extends Structure { + class DIBSECTION extends Structure { public BITMAP dsBm; public BITMAPINFOHEADER dsBmih; public int[] dsBitfields = new int[3]; @@ -180,13 +181,13 @@ protected List getFieldOrder() { } } - public int DIB_RGB_COLORS = 0; - public int DIB_PAL_COLORS = 1; + int DIB_RGB_COLORS = 0; + int DIB_PAL_COLORS = 1; /** * The PIXELFORMATDESCRIPTOR structure describes the pixel format of a drawing surface. */ - public static class PIXELFORMATDESCRIPTOR extends Structure { + class PIXELFORMATDESCRIPTOR extends Structure { public PIXELFORMATDESCRIPTOR() { super(); nSize = (short) size(); diff --git a/contrib/platform/src/com/sun/jna/platform/win32/WinNT.java b/contrib/platform/src/com/sun/jna/platform/win32/WinNT.java index efbcd83318..b61585a829 100644 --- a/contrib/platform/src/com/sun/jna/platform/win32/WinNT.java +++ b/contrib/platform/src/com/sun/jna/platform/win32/WinNT.java @@ -26,6 +26,7 @@ import com.sun.jna.Structure; import com.sun.jna.Union; import com.sun.jna.ptr.ByReference; +import com.sun.jna.win32.StdCallLibrary.StdCallCallback; /** * This module defines the 32-Bit Windows types and constants that are defined diff --git a/contrib/platform/src/com/sun/jna/platform/win32/WinRas.java b/contrib/platform/src/com/sun/jna/platform/win32/WinRas.java index 13d8142a03..331042abf0 100644 --- a/contrib/platform/src/com/sun/jna/platform/win32/WinRas.java +++ b/contrib/platform/src/com/sun/jna/platform/win32/WinRas.java @@ -26,12 +26,12 @@ import com.sun.jna.platform.win32.WinDef.HWND; import com.sun.jna.platform.win32.WinNT.HANDLE; import com.sun.jna.platform.win32.WinNT.LUID; -import com.sun.jna.win32.StdCallLibrary; +import com.sun.jna.win32.StdCallLibrary.StdCallCallback; /** * Definitions for RASAPI32 */ -public interface WinRas extends StdCallLibrary { +public interface WinRas { public static final int ERROR_BUFFER_TOO_SMALL = 603; public static final int ERROR_CANNOT_FIND_PHONEBOOK_ENTRY = 623; diff --git a/contrib/platform/src/com/sun/jna/platform/win32/WinReg.java b/contrib/platform/src/com/sun/jna/platform/win32/WinReg.java index c3e7458739..3ef54c876f 100644 --- a/contrib/platform/src/com/sun/jna/platform/win32/WinReg.java +++ b/contrib/platform/src/com/sun/jna/platform/win32/WinReg.java @@ -15,7 +15,6 @@ import com.sun.jna.Pointer; import com.sun.jna.platform.win32.WinNT.HANDLE; import com.sun.jna.ptr.ByReference; -import com.sun.jna.win32.StdCallLibrary; /** * This module contains the function prototypes and constant, type and structure @@ -24,7 +23,7 @@ * Microsoft Windows SDK 6.0A. * @author dblock[at]dblock.org */ -public interface WinReg extends StdCallLibrary { +public interface WinReg { public static class HKEY extends HANDLE { public HKEY() { } diff --git a/contrib/platform/src/com/sun/jna/platform/win32/WinUser.java b/contrib/platform/src/com/sun/jna/platform/win32/WinUser.java index 3d5ab193ac..f85f5ba358 100644 --- a/contrib/platform/src/com/sun/jna/platform/win32/WinUser.java +++ b/contrib/platform/src/com/sun/jna/platform/win32/WinUser.java @@ -19,10 +19,9 @@ import com.sun.jna.Pointer; import com.sun.jna.Structure; import com.sun.jna.Union; -import com.sun.jna.WString; import com.sun.jna.platform.win32.BaseTSD.ULONG_PTR; import com.sun.jna.platform.win32.WinNT.HANDLE; -import com.sun.jna.win32.StdCallLibrary; +import com.sun.jna.win32.StdCallLibrary.StdCallCallback; /** * Ported from WinUser.h Microsoft Windows SDK 6.0A. @@ -30,7 +29,7 @@ * @author dblock[at]dblock.org * @author Andreas "PAX" Lück, onkelpax-git[at]yahoo.de */ -public interface WinUser extends StdCallLibrary, WinDef { +public interface WinUser extends WinDef { HWND HWND_BROADCAST = new HWND(Pointer.createConstant(0xFFFF)); HWND HWND_MESSAGE = new HWND(Pointer.createConstant(-3)); @@ -1039,7 +1038,7 @@ public WNDCLASSEX(Pointer memory) { public String lpszMenuName; /** The lpsz class name. */ - public WString lpszClassName; + public String lpszClassName; /** The h icon sm. */ public HICON hIconSm; @@ -1059,7 +1058,7 @@ protected List getFieldOrder() { * * WindowProc is a placeholder for the application-defined function name. */ - public interface WindowProc extends Callback { + public interface WindowProc extends StdCallCallback { /** * @param hwnd @@ -1260,7 +1259,7 @@ protected List getFieldOrder() * display monitor. You can then paint into the device context in a manner that is optimal for the * display monitor. */ - public interface MONITORENUMPROC extends Callback + public interface MONITORENUMPROC extends StdCallCallback { /** * @param hMonitor A handle to the display monitor. This value will always be non-NULL. diff --git a/contrib/platform/src/com/sun/jna/platform/win32/Winioctl.java b/contrib/platform/src/com/sun/jna/platform/win32/Winioctl.java index 80ade8622d..c697f11a42 100644 --- a/contrib/platform/src/com/sun/jna/platform/win32/Winioctl.java +++ b/contrib/platform/src/com/sun/jna/platform/win32/Winioctl.java @@ -15,12 +15,11 @@ import com.sun.jna.Pointer; import com.sun.jna.Structure; -import com.sun.jna.win32.StdCallLibrary; /** * Interface for the Winioctl.h header file. */ -public interface Winioctl extends StdCallLibrary { +public interface Winioctl { /** * Retrieves the device type, device number, and, for a partitionable device, the partition number of a device. diff --git a/contrib/platform/src/com/sun/jna/platform/win32/Winnetwk.java b/contrib/platform/src/com/sun/jna/platform/win32/Winnetwk.java new file mode 100644 index 0000000000..07933e60f6 --- /dev/null +++ b/contrib/platform/src/com/sun/jna/platform/win32/Winnetwk.java @@ -0,0 +1,455 @@ +/* Copyright (c) 2015 Adam Marcionek, 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. + */ + +package com.sun.jna.platform.win32; + +import java.util.Arrays; +import java.util.List; + +import com.sun.jna.Pointer; +import com.sun.jna.Structure; + +/** + * Ported from AccCtrl.h. Microsoft Windows SDK 7.1 + * + * @author amarcionek[at]gmail.com + */ + +public abstract class Winnetwk { + + /** + * The scope of the enumeration. This member can be one of the following + * values defined in the Winnetwk.h header file. NOTE: This are for the + * dwScope member of NetResource. NOTE: Certain functions allow different + * values of the scope parameter. Consult MSDN for more info. + */ + public class RESOURCESCOPE { + + /** + * Enumerate currently connected resources. The dwUsage member cannot be + * specified. + */ + public static final int RESOURCE_CONNECTED = 1; + + /** + * Enumerate all resources on the network. The dwUsage member is + * specified. + */ + public static final int RESOURCE_GLOBALNET = 2; + + /** + * Enumerate remembered (persistent) connections. The dwUsage member + * cannot be specified. + */ + public static final int RESOURCE_REMEMBERED = 3; + + /** + * NOTE: Definition for this is not defined in Windows Kits nor on MSDN + */ + public static final int RESOURCE_RECENT = 4; + + /** + * Enumerate only resources in the network context of the caller. + * Specify this value for a Network Neighborhood view. The function + * ignores the dwUsage parameter. + */ + public static final int RESOURCE_CONTEXT = 5; + } + + /** + * The type of resource. This member can be one of the following values + * defined in the Winnetwk.h header file. NOTE: This are for the dwType + * member of NetResource + */ + public class RESOURCETYPE { + + /** + * All resources + */ + public static final int RESOURCETYPE_ANY = 0; + + /** + * Disk resources + */ + public static final int RESOURCETYPE_DISK = 1; + + /** + * Print resources + */ + public static final int RESOURCETYPE_PRINT = 2; + + /** + * NOTE: Definition for this is not defined in Windows Kits nor on MSDN + */ + public static final int RESOURCETYPE_RESERVED = 8; + + /** + * The WNetEnumResource function can also return the value + * RESOURCETYPE_UNKNOWN if a resource is neither a disk nor a print + * resource. + */ + public static final int RESOURCETYPE_UNKNOWN = 0xFFFFFFFF; + } + + /** + * The type of resource. This member can be one of the following values + * defined in the Winnetwk.h header file. NOTE: This are for the dwScope + * member of NetResource + */ + public class RESOURCEDISPLAYTYPE { + + /** + * The method used to display the object does not matter. + */ + public static final int RESOURCEDISPLAYTYPE_GENERIC = 0; + + /** + * The object should be displayed as a domain. + */ + public static final int RESOURCEDISPLAYTYPE_DOMAIN = 1; + + /** + * The object should be displayed as a server. + */ + public static final int RESOURCEDISPLAYTYPE_SERVER = 2; + + /** + * The object should be displayed as a share. + */ + public static final int RESOURCEDISPLAYTYPE_SHARE = 3; + + /** + * The object should be displayed as a file. + */ + public static final int RESOURCEDISPLAYTYPE_FILE = 4; + + // TODO: Add the others + } + + /** + * A set of bit flags describing how the resource can be used. Note that + * this member can be specified only if the dwScope member is equal to + * RESOURCE_GLOBALNET. This member can be one of the following values + * defined in the Winnetwk.h header file. NOTE: This are for the dwUsage + * member of NetResource + */ + public class RESOURCEUSAGE { + /** + * The resource is a connectable resource; the name pointed to by the + * lpRemoteName member can be passed to the WNetAddConnection function + * to make a network connection. + */ + public static final int RESOURCEUSAGE_CONNECTABLE = 0x00000001; + + /** + * The resource is a container resource; the name pointed to by the + * lpRemoteName member can be passed to the WNetOpenEnum function to + * enumerate the resources in the container. + */ + public static final int RESOURCEUSAGE_CONTAINER = 0x00000002; + + /** + * The resource is not a local device. + */ + public static final int RESOURCEUSAGE_NOLOCALDEVICE = 0x00000004; + + /** + * The resource is a sibling. This value is not used by Windows. + */ + public static final int RESOURCEUSAGE_SIBLING = 0x00000008; + + /** + * The resource must be attached. This value specifies that a function + * to enumerate resource this should fail if the caller is not + * authenticated, even if the network permits enumeration without + * authentication. + */ + public static final int RESOURCEUSAGE_ATTACHED = 0x00000010; + + /** + * Setting this value is equivalent to setting + * RESOURCEUSAGE_CONNECTABLE, RESOURCEUSAGE_CONTAINER, and + * RESOURCEUSAGE_ATTACHED. + */ + public static final int RESOURCEUSAGE_ALL = RESOURCEUSAGE_CONNECTABLE | RESOURCEUSAGE_CONTAINER | RESOURCEUSAGE_ATTACHED; + } + + /** + * A set of bit flags describing how the resource can be used. Note that + * this member can be specified only if the dwScope member is equal to + * RESOURCE_GLOBALNET. This member can be one of the following values + * defined in the Winnetwk.h header file. NOTE: This are for the dwUsage + * member of NetResource + */ + public class ConnectFlag { + + /** + * This flag instructs the operating system to store the network + * resource connection. If this bit flag is set, the operating system + * automatically attempts to restore the connection when the user logs + * on. The system remembers only successful connections that redirect + * local devices. It does not remember connections that are unsuccessful + * or deviceless connections. (A deviceless connection occurs when + * lpLocalName is NULL or when it points to an empty string.) If this + * bit flag is clear, the operating system does not automatically + * restore the connection at logon. + */ + public static final int CONNECT_UPDATE_PROFILE = 0x00000001; + + /** + * If this flag is set, the operating system may interact with the user + * for authentication purposes. + */ + public static final int CONNECT_INTERACTIVE = 0x00000008; + + /** + * This flag instructs the system not to use any default settings for + * user names or passwords without offering the user the opportunity to + * supply an alternative. This flag is ignored unless + * CONNECT_INTERACTIVE is also set. + */ + public static final int CONNECT_PROMPT = 0x00000010; + + /** + * This flag forces the redirection of a local device when making the + * connection. If the lpLocalName member of NETRESOURCE specifies a + * local device to redirect, this flag has no effect, because the + * operating system still attempts to redirect the specified device. + * When the operating system automatically chooses a local device, the + * dwType member must not be equal to RESOURCETYPE_ANY. If this flag is + * not set, a local device is automatically chosen for redirection only + * if the network requires a local device to be redirected. Windows XP: + * When the system automatically assigns network drive letters, letters + * are assigned beginning with Z:, then Y:, and ending with C:. This + * reduces collision between per-logon drive letters (such as network + * drive letters) and global drive letters (such as disk drives). Note + * that previous releases assigned drive letters beginning with C: and + * ending with Z:. + */ + public static final int CONNECT_REDIRECT = 0x00000080; + + /** + * If this flag is set, the connection was made using a local device + * redirection. If the lpAccessName parameter points to a buffer, the + * local device name is copied to the buffer. + */ + public static final int CONNECT_LOCALDRIVE = 0x00000100; + + /** + * If this flag is set, the operating system prompts the user for + * authentication using the command line instead of a graphical user + * interface (GUI). This flag is ignored unless CONNECT_INTERACTIVE is + * also set. Windows 2000/NT and Windows Me/98/95: This value is not + * supported. + */ + public static final int CONNECT_COMMANDLINE = 0x00000800; + + /** + * If this flag is set, and the operating system prompts for a + * credential, the credential should be saved by the credential manager. + * If the credential manager is disabled for the caller's logon session, + * or if the network provider does not support saving credentials, this + * flag is ignored. This flag is also ignored unless you set the + * CONNECT_COMMANDLINE flag. Windows 2000/NT and Windows Me/98/95: This + * value is not supported. + */ + public static final int CONNECT_CMD_SAVECRED = 0x00001000; + } + + /** + * The NETRESOURCE structure contains information about a network resource. + */ + public static class NETRESOURCE extends Structure { + + public static class ByReference extends NETRESOURCE implements Structure.ByReference { + + public ByReference() { + + } + + public ByReference(Pointer memory) { + super(memory); + } + } + + public NETRESOURCE() { + + } + + public NETRESOURCE(Pointer address) { + super(address); + read(); + } + + @Override + protected List getFieldOrder() { + return Arrays.asList("dwScope", "dwType", "dwDisplayType", "dwUsage", "lpLocalName", "lpRemoteName", "lpComment", "lpProvider"); + } + + /** + * The scope of the enumeration. This member can be one of the values + * defined in class NetResourceSope. + */ + public int dwScope; + + /** + * The type of resource. This member can be one of first 3 values + * defined in the NetResourceType. + */ + public int dwType; + + /** + * The display options for the network object in a network browsing user + * interface. This member can be one of the values defined in the + * NetResourceDisplayType. + */ + public int dwDisplayType; + + /** + * A set of bit flags describing how the resource can be used. + */ + public int dwUsage; + + /** + * If the dwScope member is equal to RESOURCE_CONNECTED or + * RESOURCE_REMEMBERED, this member is a pointer to a null-terminated + * character string that specifies the name of a local device. This + * member is NULL if the connection does not use a device. + */ + public String lpLocalName; + + /** + * If the entry is a network resource, this member is a pointer to a + * null-terminated character string that specifies the remote network + * name. + * + * If the entry is a current or persistent connection, lpRemoteName + * member points to the network name associated with the name pointed to + * by the lpLocalName member. + * + * The string can be MAX_PATH characters in length, and it must follow + * the network provider's naming conventions + */ + public String lpRemoteName; + + /** + * A pointer to a NULL-terminated string that contains a comment + * supplied by the network provider. + */ + public String lpComment; + + /** + * A pointer to a NULL-terminated string that contains the name of the + * provider that owns the resource. This member can be NULL if the + * provider name is unknown. To retrieve the provider name, you can call + * the WNetGetProviderName function. + */ + public String lpProvider; + } + + // + // Universal Naming. + // + public static int UNIVERSAL_NAME_INFO_LEVEL = 0x00000001; + public static int REMOTE_NAME_INFO_LEVEL = 0x00000002; + + /** + * The UNIVERSAL_NAME_INFO structure contains a pointer to a Universal + * Naming Convention (UNC) name string for a network resource. + */ + public static class UNIVERSAL_NAME_INFO extends Structure { + + public static class ByReference extends REMOTE_NAME_INFO implements Structure.ByReference { + + public ByReference() { + + } + + public ByReference(Pointer memory) { + super(memory); + } + } + + public UNIVERSAL_NAME_INFO() { + + } + + public UNIVERSAL_NAME_INFO(Pointer address) { + super(address); + read(); + } + + /** + * Pointer to the null-terminated UNC name string that identifies a + * network resource. + */ + public String lpUniversalName; + + @Override + protected List getFieldOrder() { + return Arrays.asList("lpUniversalName"); + } + } + + /** + * The REMOTE_NAME_INFO structure contains path and name information for a + * network resource. The structure contains a member that points to a + * Universal Naming Convention (UNC) name string for the resource, and two + * members that point to additional network connection information strings. + */ + public static class REMOTE_NAME_INFO extends Structure { + + public static class ByReference extends REMOTE_NAME_INFO implements Structure.ByReference { + + public ByReference() { + + } + + public ByReference(Pointer memory) { + super(memory); + } + } + + public REMOTE_NAME_INFO() { + + } + + public REMOTE_NAME_INFO(Pointer address) { + super(address); + read(); + } + + /** + * Pointer to the null-terminated UNC name string that identifies a + * network resource. + */ + public String lpUniversalName; + + /** + * Pointer to a null-terminated string that is the name of a network + * connection. + */ + public String lpConnectionName; + + /** + * Pointer to a null-terminated name string. + */ + public String lpRemainingPath; + + @Override + protected List getFieldOrder() { + return Arrays.asList("lpUniversalName", "lpConnectionName", "lpRemainingPath"); + } + } +} diff --git a/contrib/platform/src/com/sun/jna/platform/win32/Winspool.java b/contrib/platform/src/com/sun/jna/platform/win32/Winspool.java index 4d3d16167b..822c00e7d9 100644 --- a/contrib/platform/src/com/sun/jna/platform/win32/Winspool.java +++ b/contrib/platform/src/com/sun/jna/platform/win32/Winspool.java @@ -93,7 +93,7 @@ public interface Winspool extends StdCallLibrary { int PRINTER_ENUM_HIDE = 0x01000000; Winspool INSTANCE = (Winspool) Native.loadLibrary("Winspool.drv", - Winspool.class, W32APIOptions.UNICODE_OPTIONS); + Winspool.class, W32APIOptions.DEFAULT_OPTIONS); /** * The EnumPrinters function enumerates available printers, print servers, diff --git a/contrib/platform/src/com/sun/jna/platform/win32/Winsvc.java b/contrib/platform/src/com/sun/jna/platform/win32/Winsvc.java index b5e1916672..cc34077935 100644 --- a/contrib/platform/src/com/sun/jna/platform/win32/Winsvc.java +++ b/contrib/platform/src/com/sun/jna/platform/win32/Winsvc.java @@ -19,7 +19,6 @@ import com.sun.jna.Memory; import com.sun.jna.Structure; import com.sun.jna.platform.win32.WinNT.HANDLE; -import com.sun.jna.win32.StdCallLibrary; /** * This module defines the 32-Bit Windows types and constants that are defined @@ -28,7 +27,7 @@ * Microsoft Windows SDK 7.0A. * @author EugineLev */ -public interface Winsvc extends StdCallLibrary { +public interface Winsvc { /** * Contains status information for a service. The ControlService, EnumDependentServices, diff --git a/contrib/platform/test/com/sun/jna/platform/mac/XAttrUtilTest.java b/contrib/platform/test/com/sun/jna/platform/mac/XAttrUtilTest.java index 8902fe6650..6abd401181 100644 --- a/contrib/platform/test/com/sun/jna/platform/mac/XAttrUtilTest.java +++ b/contrib/platform/test/com/sun/jna/platform/mac/XAttrUtilTest.java @@ -84,7 +84,13 @@ public void testRemoveXAttr() { } public void testUnicode() { - String[] names = new String[] { "中文", "にほんご", "Österreichisch", "Française", "Português" }; + String[] names = new String[] { + "\u4E2D\u6587", + "\u306B\u307B\u3093\u3054", + "\u00D6sterreichisch", + "Fran\u00E7aise", + "Portugu\u00EAs", + }; for (int i = 0; i < names.length; i++) { // set xattr XAttrUtil.setXAttr(testPath, names[i], names[i]); diff --git a/contrib/platform/test/com/sun/jna/platform/win32/Advapi32Test.java b/contrib/platform/test/com/sun/jna/platform/win32/Advapi32Test.java index 54e790578c..e49a253875 100755 --- a/contrib/platform/test/com/sun/jna/platform/win32/Advapi32Test.java +++ b/contrib/platform/test/com/sun/jna/platform/win32/Advapi32Test.java @@ -12,24 +12,54 @@ */ package com.sun.jna.platform.win32; +import static com.sun.jna.platform.win32.WinBase.CREATE_FOR_IMPORT; +import static com.sun.jna.platform.win32.WinBase.FILE_DIR_DISALOWED; +import static com.sun.jna.platform.win32.WinBase.FILE_ENCRYPTABLE; +import static com.sun.jna.platform.win32.WinBase.FILE_IS_ENCRYPTED; +import static com.sun.jna.platform.win32.WinBase.FILE_READ_ONLY; +import static com.sun.jna.platform.win32.WinNT.DACL_SECURITY_INFORMATION; +import static com.sun.jna.platform.win32.WinNT.FILE_ALL_ACCESS; +import static com.sun.jna.platform.win32.WinNT.FILE_GENERIC_EXECUTE; +import static com.sun.jna.platform.win32.WinNT.FILE_GENERIC_READ; +import static com.sun.jna.platform.win32.WinNT.FILE_GENERIC_WRITE; +import static com.sun.jna.platform.win32.WinNT.GENERIC_ALL; +import static com.sun.jna.platform.win32.WinNT.GENERIC_EXECUTE; +import static com.sun.jna.platform.win32.WinNT.GENERIC_READ; +import static com.sun.jna.platform.win32.WinNT.GENERIC_WRITE; +import static com.sun.jna.platform.win32.WinNT.GROUP_SECURITY_INFORMATION; +import static com.sun.jna.platform.win32.WinNT.OWNER_SECURITY_INFORMATION; +import static com.sun.jna.platform.win32.WinNT.SACL_SECURITY_INFORMATION; +import static com.sun.jna.platform.win32.WinNT.SE_RESTORE_NAME; +import static com.sun.jna.platform.win32.WinNT.SE_SECURITY_NAME; +import static com.sun.jna.platform.win32.WinNT.TOKEN_ADJUST_PRIVILEGES; +import static com.sun.jna.platform.win32.WinNT.TOKEN_DUPLICATE; +import static com.sun.jna.platform.win32.WinNT.TOKEN_IMPERSONATE; + import java.io.ByteArrayOutputStream; import java.io.File; import java.io.FileWriter; import java.io.IOException; import java.util.Collection; -import junit.framework.TestCase; - import com.sun.jna.Memory; import com.sun.jna.Native; import com.sun.jna.Pointer; -import com.sun.jna.WString; import com.sun.jna.platform.win32.LMAccess.USER_INFO_1; +import com.sun.jna.platform.win32.WinBase.FE_EXPORT_FUNC; +import com.sun.jna.platform.win32.WinBase.FE_IMPORT_FUNC; import com.sun.jna.platform.win32.WinBase.FILETIME; +import com.sun.jna.platform.win32.WinBase.PROCESS_INFORMATION; +import com.sun.jna.platform.win32.WinBase.STARTUPINFO; +import com.sun.jna.platform.win32.WinDef.BOOLByReference; import com.sun.jna.platform.win32.WinDef.DWORD; +import com.sun.jna.platform.win32.WinDef.DWORDByReference; +import com.sun.jna.platform.win32.WinDef.ULONG; +import com.sun.jna.platform.win32.WinDef.ULONGByReference; import com.sun.jna.platform.win32.WinNT.EVENTLOGRECORD; +import com.sun.jna.platform.win32.WinNT.GENERIC_MAPPING; import com.sun.jna.platform.win32.WinNT.HANDLE; import com.sun.jna.platform.win32.WinNT.HANDLEByReference; +import com.sun.jna.platform.win32.WinNT.PRIVILEGE_SET; import com.sun.jna.platform.win32.WinNT.PSID; import com.sun.jna.platform.win32.WinNT.PSIDByReference; import com.sun.jna.platform.win32.WinNT.SECURITY_IMPERSONATION_LEVEL; @@ -42,11 +72,10 @@ import com.sun.jna.platform.win32.Winsvc.SC_HANDLE; import com.sun.jna.platform.win32.Winsvc.SC_STATUS_TYPE; import com.sun.jna.platform.win32.Winsvc.SERVICE_STATUS_PROCESS; -import com.sun.jna.ptr.ByteByReference; import com.sun.jna.ptr.IntByReference; import com.sun.jna.ptr.PointerByReference; -import static com.sun.jna.platform.win32.WinNT.*; +import junit.framework.TestCase; /** * @author dblock[at]dblock[dot]org @@ -356,8 +385,8 @@ public void testGetTokenGroupsInformation() { public void testImpersonateLoggedOnUser() { USER_INFO_1 userInfo = new USER_INFO_1(); - userInfo.usri1_name = new WString("JNAAdvapi32TestImp"); - userInfo.usri1_password = new WString("!JNAP$$Wrd0"); + userInfo.usri1_name = "JNAAdvapi32TestImp"; + userInfo.usri1_password = "!JNAP$$Wrd0"; userInfo.usri1_priv = LMAccess.USER_PRIV_USER; // ignore test if not able to add user (need to be administrator to do this). if (LMErr.NERR_Success != Netapi32.INSTANCE.NetUserAdd(null, 1, userInfo, null)) { @@ -1275,7 +1304,7 @@ public void testAccessCheck() { public void testEncryptFile() throws Exception { // create a temp file File file = createTempFile(); - WString lpFileName = new WString(file.getAbsolutePath()); + String lpFileName = file.getAbsolutePath(); // encrypt a read only file file.setWritable(false); @@ -1292,7 +1321,7 @@ public void testEncryptFile() throws Exception { public void testDecryptFile() throws Exception { // create an encrypted file File file = createTempFile(); - WString lpFileName = new WString(file.getAbsolutePath()); + String lpFileName = file.getAbsolutePath(); assertTrue(Advapi32.INSTANCE.EncryptFile(lpFileName)); // decrypt a read only file @@ -1312,7 +1341,7 @@ public void testFileEncryptionStatus() throws Exception { // create a temp file File file = createTempFile(); - WString lpFileName = new WString(file.getAbsolutePath()); + String lpFileName = file.getAbsolutePath(); // unencrypted file assertTrue(Advapi32.INSTANCE.FileEncryptionStatus(lpFileName, lpStatus)); @@ -1338,7 +1367,7 @@ public void testEncryptionDisable() throws Exception { // create a temp dir String filePath = System.getProperty("java.io.tmpdir") + File.separator + System.nanoTime(); - WString DirPath = new WString(filePath); + String DirPath = filePath; File dir = new File(filePath); dir.mkdir(); @@ -1366,7 +1395,7 @@ public void testEncryptionDisable() throws Exception { public void testOpenEncryptedFileRaw() throws Exception { // create an encrypted file File file = createTempFile(); - WString lpFileName = new WString(file.getAbsolutePath()); + String lpFileName = file.getAbsolutePath(); assertTrue(Advapi32.INSTANCE.EncryptFile(lpFileName)); // open file for export @@ -1382,7 +1411,7 @@ public void testOpenEncryptedFileRaw() throws Exception { public void testReadEncryptedFileRaw() throws Exception { // create an encrypted file File file = createTempFile(); - WString lpFileName = new WString(file.getAbsolutePath()); + String lpFileName = file.getAbsolutePath(); assertTrue(Advapi32.INSTANCE.EncryptFile(lpFileName)); // open file for export @@ -1395,9 +1424,12 @@ public void testReadEncryptedFileRaw() throws Exception { final ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); FE_EXPORT_FUNC pfExportCallback = new FE_EXPORT_FUNC() { @Override - public DWORD callback(ByteByReference pbData, Pointer + public DWORD callback(Pointer pbData, Pointer pvCallbackContext, ULONG ulLength) { - byte[] arr = pbData.getPointer().getByteArray(0, ulLength.intValue()); + if (pbData == null) { + throw new NullPointerException("Callback data unexpectedly missing"); + } + byte[] arr = pbData.getByteArray(0, ulLength.intValue()); try { outputStream.write(arr); } catch (IOException e) { @@ -1418,7 +1450,7 @@ public DWORD callback(ByteByReference pbData, Pointer public void testWriteEncryptedFileRaw() throws Exception { // create an encrypted file File file = createTempFile(); - WString lpFileName = new WString(file.getAbsolutePath()); + String lpFileName = file.getAbsolutePath(); assertTrue(Advapi32.INSTANCE.EncryptFile(lpFileName)); // open file for export @@ -1431,9 +1463,12 @@ public void testWriteEncryptedFileRaw() throws Exception { final ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); FE_EXPORT_FUNC pfExportCallback = new FE_EXPORT_FUNC() { @Override - public DWORD callback(ByteByReference pbData, Pointer + public DWORD callback(Pointer pbData, Pointer pvCallbackContext, ULONG ulLength) { - byte[] arr = pbData.getPointer().getByteArray(0, ulLength.intValue()); + if (pbData == null) { + throw new NullPointerException("Callback data unexpectedly null"); + } + byte[] arr = pbData.getByteArray(0, ulLength.intValue()); try { outputStream.write(arr); } catch (IOException e) { @@ -1449,8 +1484,8 @@ public DWORD callback(ByteByReference pbData, Pointer Advapi32.INSTANCE.CloseEncryptedFileRaw(pvContext.getValue()); // open file for import - WString lbFileName2 = new WString(System.getProperty("java.io.tmpdir") + - File.separator + "backup-" + file.getName()); + String lbFileName2 = System.getProperty("java.io.tmpdir") + + File.separator + "backup-" + file.getName(); ULONG ulFlags2 = new ULONG(CREATE_FOR_IMPORT); PointerByReference pvContext2 = new PointerByReference(); assertEquals(W32Errors.ERROR_SUCCESS, Advapi32.INSTANCE.OpenEncryptedFileRaw( @@ -1460,13 +1495,12 @@ public DWORD callback(ByteByReference pbData, Pointer final IntByReference elementsReadWrapper = new IntByReference(0); FE_IMPORT_FUNC pfImportCallback = new FE_IMPORT_FUNC() { @Override - public DWORD callback(ByteByReference pbData, Pointer pvCallbackContext, + public DWORD callback(Pointer pbData, Pointer pvCallbackContext, ULONGByReference ulLength) { int elementsRead = elementsReadWrapper.getValue(); int remainingElements = outputStream.size() - elementsRead; int length = Math.min(remainingElements, ulLength.getValue().intValue()); - pbData.getPointer().write(0, outputStream.toByteArray(), elementsRead, - length); + pbData.write(0, outputStream.toByteArray(), elementsRead, length); elementsReadWrapper.setValue(elementsRead + length); ulLength.setValue(new ULONG(length)); return new DWORD(W32Errors.ERROR_SUCCESS); @@ -1493,4 +1527,23 @@ private File createTempFile() throws Exception { fileWriter.close(); return file; } + + public void testCreateProcessWithLogonW() { + String winDir = Kernel32Util.getEnvironmentVariable("WINDIR"); + assertNotNull("No WINDIR value returned", winDir); + assertTrue("Specified WINDIR does not exist: " + winDir, new File(winDir).exists()); + + STARTUPINFO si = new STARTUPINFO(); + si.lpDesktop = null; + PROCESS_INFORMATION results = new PROCESS_INFORMATION(); + + // i have the same combination on my luggage + boolean result = Advapi32.INSTANCE.CreateProcessWithLogonW("A" + System.currentTimeMillis(), "localhost", "12345", Advapi32.LOGON_WITH_PROFILE, new File(winDir, "notepad.exe").getAbsolutePath(), "", 0, null, "", si, results); + + // we tried to run notepad as a bogus user, so it should fail. + assertFalse("CreateProcessWithLogonW should have returned false because the username was bogus.", result); + + // should fail with "the user name or password is incorrect" (error 1326) + assertEquals("GetLastError() should have returned ERROR_LOGON_FAILURE because the username was bogus.", W32Errors.ERROR_LOGON_FAILURE, Native.getLastError()); + } } diff --git a/contrib/platform/test/com/sun/jna/platform/win32/Advapi32UtilTest.java b/contrib/platform/test/com/sun/jna/platform/win32/Advapi32UtilTest.java index 5f0b38db79..0aa0aa6d3f 100755 --- a/contrib/platform/test/com/sun/jna/platform/win32/Advapi32UtilTest.java +++ b/contrib/platform/test/com/sun/jna/platform/win32/Advapi32UtilTest.java @@ -19,7 +19,6 @@ import junit.framework.TestCase; -import com.sun.jna.WString; import com.sun.jna.platform.win32.Advapi32Util.Account; import com.sun.jna.platform.win32.Advapi32Util.EventLogIterator; import com.sun.jna.platform.win32.Advapi32Util.EventLogRecord; @@ -127,8 +126,8 @@ public void testGetCurrentUserGroups() { public void testGetUserGroups() { USER_INFO_1 userInfo = new USER_INFO_1(); - userInfo.usri1_name = new WString("JNANetapi32TestUser"); - userInfo.usri1_password = new WString("!JNAP$$Wrd0"); + userInfo.usri1_name = "JNANetapi32TestUser"; + userInfo.usri1_password = "!JNAP$$Wrd0"; userInfo.usri1_priv = LMAccess.USER_PRIV_USER; // ignore test if not able to add user (need to be administrator to do this). if (LMErr.NERR_Success != Netapi32.INSTANCE.NetUserAdd(null, 1, userInfo, null)) { @@ -161,8 +160,8 @@ public void testGetUserGroups() { public void testGetUserAccount() { USER_INFO_1 userInfo = new USER_INFO_1(); - userInfo.usri1_name = new WString("JNANetapi32TestUser"); - userInfo.usri1_password = new WString("!JNAP$$Wrd0"); + userInfo.usri1_name = "JNANetapi32TestUser"; + userInfo.usri1_password = "!JNAP$$Wrd0"; userInfo.usri1_priv = LMAccess.USER_PRIV_USER; // ignore test if not able to add user (need to be administrator to do this). if (LMErr.NERR_Success != Netapi32.INSTANCE.NetUserAdd(null, 1, userInfo, null)) { diff --git a/contrib/platform/test/com/sun/jna/platform/win32/COM/IShellFolderTest.java b/contrib/platform/test/com/sun/jna/platform/win32/COM/IShellFolderTest.java new file mode 100644 index 0000000000..f76876673d --- /dev/null +++ b/contrib/platform/test/com/sun/jna/platform/win32/COM/IShellFolderTest.java @@ -0,0 +1,82 @@ +package com.sun.jna.platform.win32.COM; + +/* + * @author L W Ahonen, lwahonen@iki.fi + */ + +import junit.framework.TestCase; + + +import com.sun.jna.Pointer; +import com.sun.jna.platform.win32.*; +import com.sun.jna.ptr.PointerByReference; +import junit.framework.TestCase; + +public class IShellFolderTest extends TestCase { + + private IShellFolder psfMyComputer; + + public static WinNT.HRESULT BindToCsidl(int csidl, Guid.REFIID riid, PointerByReference ppv) { + WinNT.HRESULT hr; + PointerByReference pidl = new PointerByReference(); + hr = Shell32.INSTANCE.SHGetSpecialFolderLocation(null, csidl, pidl); + assertTrue(COMUtils.SUCCEEDED(hr)); + PointerByReference psfDesktopPTR = new PointerByReference(); + hr = Shell32.INSTANCE.SHGetDesktopFolder(psfDesktopPTR); + assertTrue(COMUtils.SUCCEEDED(hr)); + IShellFolder psfDesktop = IShellFolder.Converter.PointerToIShellFolder(psfDesktopPTR); + short cb = pidl.getValue().getShort(0); // See http://blogs.msdn.com/b/oldnewthing/archive/2011/08/30/10202076.aspx for explanation about this bit + if (cb != 0) { + hr = psfDesktop.BindToObject(pidl.getValue(), null, riid, ppv); + } else { + hr = psfDesktop.QueryInterface(riid, ppv); + } + psfDesktop.Release(); + Ole32.INSTANCE.CoTaskMemFree(pidl.getValue()); + return hr; + } + + public void setUp() throws Exception { + Ole32.INSTANCE.CoInitialize(null); + int CSIDL_DRIVES = 0x0011; + WinNT.HRESULT hr = Ole32.INSTANCE.CoInitialize(null); + assertTrue(COMUtils.SUCCEEDED(hr)); + PointerByReference psfMyComputerPTR = new PointerByReference(Pointer.NULL); + hr = BindToCsidl(CSIDL_DRIVES, new Guid.REFIID(IShellFolder.IID_ISHELLFOLDER), psfMyComputerPTR); + assertTrue(COMUtils.SUCCEEDED(hr)); + psfMyComputer = IShellFolder.Converter.PointerToIShellFolder(psfMyComputerPTR); + } + + public void tearDown() throws Exception { + psfMyComputer.Release(); + Ole32.INSTANCE.CoUninitialize(); + } + + public void testEnumObjects() throws Exception { + PointerByReference peidlPTR = new PointerByReference(); + int SHCONTF_FOLDERS = 0x20; + int SHCONTF_NONFOLDERS = 0x40; + boolean sawNames = false; + + WinNT.HRESULT hr = psfMyComputer.EnumObjects(null, + SHCONTF_FOLDERS | SHCONTF_NONFOLDERS, peidlPTR); + assertTrue(COMUtils.SUCCEEDED(hr)); + IEnumIDList peidl = IEnumIDList.Converter.PointerToIEnumIDList(peidlPTR); + PointerByReference pidlItem = new PointerByReference(); + while (peidl.Next(1, pidlItem, null).intValue() == COMUtils.S_OK) { + PointerByReference sr = new PointerByReference(); + hr = psfMyComputer.GetDisplayNameOf(pidlItem.getValue(), 0, sr); + assertTrue(COMUtils.SUCCEEDED(hr)); + PointerByReference pszName = new PointerByReference(); + hr = Shlwapi.INSTANCE.StrRetToStr(sr, pidlItem.getValue(), pszName); + assertTrue(COMUtils.SUCCEEDED(hr)); + String wideString = pszName.getValue().getWideString(0); + if (wideString != null && wideString.length() > 0) + sawNames = true; + Ole32.INSTANCE.CoTaskMemFree(pszName.getValue()); + Ole32.INSTANCE.CoTaskMemFree(pidlItem.getValue()); + } + peidl.Release(); + assertTrue(sawNames); // We should see at least one item with a name + } +} \ No newline at end of file diff --git a/contrib/platform/test/com/sun/jna/platform/win32/COM/ShellApplicationWindowsTest.java b/contrib/platform/test/com/sun/jna/platform/win32/COM/ShellApplicationWindowsTest.java new file mode 100644 index 0000000000..9aa53769e8 --- /dev/null +++ b/contrib/platform/test/com/sun/jna/platform/win32/COM/ShellApplicationWindowsTest.java @@ -0,0 +1,190 @@ +package com.sun.jna.platform.win32.COM; + +import java.util.Iterator; +import java.util.NoSuchElementException; + +import com.sun.jna.platform.win32.Variant; +import com.sun.jna.platform.win32.Variant.VARIANT; +import com.sun.jna.platform.win32.WinDef.LONG; + +import junit.framework.TestCase; + +public class ShellApplicationWindowsTest extends TestCase +{ + + @Override + public void setUp() throws Exception + { + // Launch IE in a manner that should ensure it opens even if the system default browser is Chrome, Firefox, or something else. + Runtime.getRuntime().exec("cmd /c start iexplore.exe -nohome \"about:blank\""); + + // Even when going to "about:blank", IE still needs a few seconds to start up and add itself to Shell.Application.Windows + // Removing this delay will cause the test to fail even on the fastest boxes I can find. + Thread.sleep(3000); + } + + public void testWindowsCount() + { + ShellApplication sa = new ShellApplication(); + + // IE is open, so there should be at least one present. + // More may exist if Windows Explorer windows are open. + assertTrue("No shell application windows found", + sa.Windows().Count() > 0); + + boolean pageFound = false; + for (InternetExplorer ie : sa.Windows()) + { + // For reasons unknown, Shell.Application.Windows can have null members inside it. + // All I care about is whether or not the collection contains the window I opened. + if (ie != null && "about:blank".equals(ie.getURL())) + { + pageFound = true; + } + } + + // Finally, did we find our page in the collection? + assertTrue("No IE page was found", pageFound); + } + + @Override + protected void tearDown() throws Exception + { + Runtime.getRuntime().exec("taskkill.exe /f /im iexplore.exe"); + } + + /** + * A COM representation of the Windows shell. + */ + private static class ShellApplication extends COMLateBindingObject + { + public ShellApplication() throws COMException + { + super("Shell.Application", false); + } + + /** + * @return Creates and returns a ShellWindows object.
    + * This object represents a collection of all of the open windows that belong to the Shell. + */ + public ShellWindows Windows() + { + return new ShellWindows((IDispatch) invoke("Windows").getValue()); + } + + /** + * Represents a collection of the open windows that belong to the Shell.
    + * Methods associated with this objects can control and execute commands within the Shell, and obtain other Shell-related objects. + */ + public static class ShellWindows extends COMLateBindingObject implements Iterable + { + + private static class ShellWindowsIterator implements Iterator + { + + private ShellWindows source; + + private int count; + + private int max; + + public ShellWindowsIterator(ShellWindows collection) + { + source = collection; + max = source.Count(); + } + + @Override + public boolean hasNext() + { + return count < max; + } + + @Override + public InternetExplorer next() + { + if (!hasNext()) + { + throw new NoSuchElementException(); + } + return source.Item(count++); + } + + @Override + public void remove() + { + throw new UnsupportedOperationException(); + } + + } + + public ShellWindows(IDispatch iDispatch) + { + super(iDispatch); + } + + /** + * Retrieves an InternetExplorer object that represents the Shell window. + * + * @param idx + * The zero-based index of the item to retrieve.
    + * This value must be less than the value of the Count property. + * @return an InternetExplorer object that represents the Shell window. + */ + public InternetExplorer Item(int idx) + { + VARIANT arg = new VARIANT(); + arg.setValue(Variant.VT_I4, new LONG(idx)); + IDispatch result = (IDispatch) invoke("Item", arg).getValue(); + if (result == null) + { + return null; + } + return new InternetExplorer(result); + } + + /** + * @return the number of items in the collection. + */ + public int Count() + { + return getIntProperty("Count"); + } + + @SuppressWarnings({"unchecked", "rawtypes"}) + @Override + public Iterator iterator() + { + return new ShellWindowsIterator(this); + } + } + + } + + /** + * InternetExplorer / IWebBrowser2 - see http://msdn.microsoft.com/en-us/library/aa752127(v=vs.85).aspx + */ + private static class InternetExplorer extends COMLateBindingObject + { + + public InternetExplorer(IDispatch iDispatch) + { + super(iDispatch); + } + + /** + * IWebBrowser2::get_LocationURL
    + * Read-only COM property.
    + * + * @return the URL of the resource that is currently displayed. + */ + public String getURL() + { + return getStringProperty("LocationURL"); + } + } + + public static void main(String[] args) { + junit.textui.TestRunner.run(ShellApplicationWindowsTest.class); + } +} diff --git a/contrib/platform/test/com/sun/jna/platform/win32/Crypt32Test.java b/contrib/platform/test/com/sun/jna/platform/win32/Crypt32Test.java index 1955e62e73..36f3436687 100644 --- a/contrib/platform/test/com/sun/jna/platform/win32/Crypt32Test.java +++ b/contrib/platform/test/com/sun/jna/platform/win32/Crypt32Test.java @@ -12,11 +12,21 @@ */ package com.sun.jna.platform.win32; -import junit.framework.TestCase; +import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.net.URISyntaxException; +import com.sun.jna.Memory; +import com.sun.jna.Native; +import com.sun.jna.Pointer; import com.sun.jna.platform.win32.WinCrypt.DATA_BLOB; +import com.sun.jna.platform.win32.WinDef.DWORD; import com.sun.jna.ptr.PointerByReference; +import junit.framework.TestCase; + /** * @author dblock[at]dblock[dot]org */ @@ -61,5 +71,12 @@ public void testCryptProtectUnprotectDataWithEntropy() { Kernel32.INSTANCE.LocalFree(pDataEncrypted.pbData); Kernel32.INSTANCE.LocalFree(pDataDecrypted.pbData); Kernel32.INSTANCE.LocalFree(pDescription.getValue()); - } + } + + public void testCertAddEncodedCertificateToSystemStore() { + // try to install a non-existent certificate + assertFalse("Attempting to install a non-existent certificate should have returned false and set GetLastError()", Crypt32.INSTANCE.CertAddEncodedCertificateToSystemStore("ROOT", null, 0)); + // should fail with "unexpected end of data" + assertEquals("GetLastError() should have been set to CRYPT_E_ASN1_EOD ('ASN.1 unexpected end of data' in WinCrypt.h)", WinCrypt.CRYPT_E_ASN1_EOD, Native.getLastError()); + } } \ No newline at end of file diff --git a/contrib/platform/test/com/sun/jna/platform/win32/GDI32UtilTest.java b/contrib/platform/test/com/sun/jna/platform/win32/GDI32UtilTest.java new file mode 100644 index 0000000000..d02dca5d25 --- /dev/null +++ b/contrib/platform/test/com/sun/jna/platform/win32/GDI32UtilTest.java @@ -0,0 +1,56 @@ +/* Copyright (c) 2015 Michael Freeman, 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. + */ +package com.sun.jna.platform.win32; + +import java.awt.image.BufferedImage; +import java.util.ArrayList; +import java.util.List; + +import org.junit.Test; +import org.junit.runner.JUnitCore; + +import com.sun.jna.platform.win32.WinDef.HWND; + +public class GDI32UtilTest extends AbstractWin32TestSupport { + + public static void main(String[] args) { + JUnitCore jUnitCore = new JUnitCore(); + jUnitCore.run(GDI32UtilTest.class); + } + + @Test + public void testGetScreenshot() { + HWND desktopWindow = User32.INSTANCE.GetDesktopWindow(); + assertNotNull("Failed to obtain desktop window handle", desktopWindow); + BufferedImage image = GDI32Util.getScreenshot(desktopWindow); + // Since this test involves taking a whole-desktop screenshot + // we can't be sure what the image will be exactly. + // We'll validate that the image is "good" + // by checking for 20 distinct colors. + // BufferedImages normally start life as one uniform color + // so if that's not the case then some data was indeed copied over as a result of the getScreenshot() function. + List distinctPixels = new ArrayList(); + for (int x = 0; x < image.getWidth(); x++) { + for (int y = 0; y < image.getHeight(); y++) { + int pixel = image.getRGB(x, y); + if (!distinctPixels.contains(pixel)) { + distinctPixels.add(pixel); + } + if (distinctPixels.size() > 20) { + break; + } + } + } + assertTrue("Number of distinct pixels was not above 20.", distinctPixels.size() > 20); + } +} 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..2a47dcad09 100644 --- a/contrib/platform/test/com/sun/jna/platform/win32/Kernel32Test.java +++ b/contrib/platform/test/com/sun/jna/platform/win32/Kernel32Test.java @@ -28,14 +28,17 @@ import java.util.List; import java.util.TimeZone; +import com.sun.jna.Memory; import com.sun.jna.Native; import com.sun.jna.NativeMappedConverter; import com.sun.jna.Platform; import com.sun.jna.Pointer; import com.sun.jna.platform.win32.BaseTSD.SIZE_T; +import com.sun.jna.platform.win32.WinBase.FILETIME; 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 +52,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 +208,305 @@ 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(); - - assertTrue(tick2 > tick1 || tick3 > tick2); - } + 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); + } 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 testGetSystemTimes() { + Kernel32 kernel = Kernel32.INSTANCE; + FILETIME lpIdleTime = new FILETIME(); + FILETIME lpKernelTime = new FILETIME(); + FILETIME lpUserTime = new FILETIME(); + boolean succ = kernel.GetSystemTimes(lpIdleTime, lpKernelTime, lpUserTime); + assertTrue(succ); + long idleTime = lpIdleTime.toDWordLong().longValue(); + long kernelTime = lpKernelTime.toDWordLong().longValue(); + long userTime = lpUserTime.toDWordLong().longValue(); + // All should be >= 0. kernel includes idle. + assertTrue(idleTime >= 0); + assertTrue(kernelTime >= idleTime); + assertTrue(userTime >= 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 +566,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 +729,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 +786,250 @@ 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 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()); + } + } + } + } + + public void testEnumResourceNames() { + // "14" is the type name of the My Computer icon in explorer.exe + Pointer pointer = new Memory(Native.WCHAR_SIZE * 3); + pointer.setWideString(0, "14"); + WinBase.EnumResNameProc ernp = new WinBase.EnumResNameProc() { + + @Override + public boolean invoke(HMODULE module, Pointer type, Pointer name, Pointer lParam) { + + return true; + } + }; + // null HMODULE means use this process / its EXE + // there are no type "14" resources in it. + boolean result = Kernel32.INSTANCE.EnumResourceNames(null, pointer, ernp, null); + assertFalse("EnumResourceNames should have failed.", result); + assertEquals("GetLastError should be set to 1813", WinError.ERROR_RESOURCE_TYPE_NOT_FOUND, Kernel32.INSTANCE.GetLastError()); + } + - 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 testEnumResourceTypes() { + final List types = new ArrayList(); + WinBase.EnumResTypeProc ertp = new WinBase.EnumResTypeProc() { + + @Override + public boolean invoke(HMODULE module, Pointer type, Pointer lParam) { + // simulate IS_INTRESOURCE macro defined in WinUser.h + // basically that means that if "type" is less than or equal to 65,535 + // it assumes it's an ID. + // otherwise it assumes it's a pointer to a string + if (Pointer.nativeValue(type) <= 65535) { + types.add(Pointer.nativeValue(type) + ""); + } else { + types.add(type.getWideString(0)); + } + return true; + } + }; + // null HMODULE means use this process / its EXE + // there are no type "14" resources in it. + boolean result = Kernel32.INSTANCE.EnumResourceTypes(null, ertp, null); + assertTrue("EnumResourceTypes should not have failed.", result); + assertEquals("GetLastError should be set to 0", WinError.ERROR_SUCCESS, Kernel32.INSTANCE.GetLastError()); + assertTrue("EnumResourceTypes should return some resource type names", types.size() > 0); + } } 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..525b77a86f 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; @@ -20,6 +20,8 @@ import java.io.IOException; import java.io.PrintWriter; import java.util.Collection; +import java.util.List; +import java.util.Map; import com.sun.jna.platform.win32.WinNT.LARGE_INTEGER; @@ -30,111 +32,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 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 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 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 +175,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 +183,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 +253,34 @@ 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); + } + + public void testGetResourceNames() { + 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") + Map> names = Kernel32Util.getResourceNames(new File(winDir, "explorer.exe").getAbsolutePath()); + + assertNotNull("explorer.exe should contain some resources in it.", names); + assertTrue("explorer.exe should contain some resource types in it.", names.size() > 0); + assertTrue("explorer.exe should contain a resource of type '14' in it.", names.containsKey("14")); + assertTrue("resource type 14 should have a name named ICO_MYCOMPUTER associated with it.", names.get("14").contains("ICO_MYCOMPUTER")); } } diff --git a/contrib/platform/test/com/sun/jna/platform/win32/MprTest.java b/contrib/platform/test/com/sun/jna/platform/win32/MprTest.java new file mode 100644 index 0000000000..c174136911 --- /dev/null +++ b/contrib/platform/test/com/sun/jna/platform/win32/MprTest.java @@ -0,0 +1,323 @@ +/* Copyright (c) 2015 Adam Marcionek, 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. + */ + +package com.sun.jna.platform.win32; + +import java.io.File; + +import com.sun.jna.Memory; +import com.sun.jna.platform.win32.LMShare.SHARE_INFO_2; +import com.sun.jna.platform.win32.WinNT.HANDLEByReference; +import com.sun.jna.platform.win32.Winnetwk.ConnectFlag; +import com.sun.jna.platform.win32.Winnetwk.NETRESOURCE; +import com.sun.jna.platform.win32.Winnetwk.REMOTE_NAME_INFO; +import com.sun.jna.platform.win32.Winnetwk.RESOURCESCOPE; +import com.sun.jna.platform.win32.Winnetwk.RESOURCETYPE; +import com.sun.jna.platform.win32.Winnetwk.RESOURCEUSAGE; +import com.sun.jna.platform.win32.Winnetwk.UNIVERSAL_NAME_INFO; +import com.sun.jna.ptr.IntByReference; + +import junit.framework.TestCase; + +/** + * @author amarcionek[at]gmail[dot]com + */ +public class MprTest extends TestCase { + + public static void main(String[] args) throws Exception { + junit.textui.TestRunner.run(MprTest.class); + } + + public void testWNetUseConnection() throws Exception { + // First create a share on the local machine + File fileShareFolder = createTempFolder(); + String share = createLocalShare(fileShareFolder); + + NETRESOURCE resource = new NETRESOURCE(); + + resource.dwDisplayType = 0; + resource.dwScope = 0; + resource.dwType = RESOURCETYPE.RESOURCETYPE_DISK; + resource.lpRemoteName = "\\\\" + getLocalComputerName() + "\\" + share; + + try { + // Cancel any existing connections of the same name + Mpr.INSTANCE.WNetCancelConnection2(resource.lpRemoteName, 0, true); + // Establish a new one + assertEquals(WinError.ERROR_SUCCESS, Mpr.INSTANCE.WNetUseConnection(null, resource, null, null, 0, null, null, null)); + } finally { + // Clean up resources + Mpr.INSTANCE.WNetCancelConnection2(resource.lpRemoteName, 0, true); + Netapi32.INSTANCE.NetShareDel(null, share, 0); + fileShareFolder.delete(); + } + } + + public void testWNetAddConnection3() throws Exception { + // First create a share on the local machine + File fileShareFolder = createTempFolder(); + String share = createLocalShare(fileShareFolder); + + NETRESOURCE resource = new NETRESOURCE(); + + resource.dwDisplayType = 0; + resource.dwScope = 0; + resource.dwType = RESOURCETYPE.RESOURCETYPE_DISK; + resource.lpRemoteName = "\\\\" + getLocalComputerName() + "\\" + share; + + try { + // Cancel any existing connections of the same name + Mpr.INSTANCE.WNetCancelConnection2(resource.lpRemoteName, 0, true); + // Establish a new one + assertEquals(WinError.ERROR_SUCCESS, Mpr.INSTANCE.WNetAddConnection3(null, resource, null, null, 0)); + } finally { + // Clean up resources + Mpr.INSTANCE.WNetCancelConnection2(resource.lpRemoteName, 0, true); + Netapi32.INSTANCE.NetShareDel(null, share, 0); + fileShareFolder.delete(); + } + } + + public void testWNetOpenCloseConnection() throws Exception { + HANDLEByReference lphEnum = new HANDLEByReference(); + assertEquals(WinError.ERROR_SUCCESS, Mpr.INSTANCE.WNetOpenEnum(RESOURCESCOPE.RESOURCE_CONNECTED, RESOURCETYPE.RESOURCETYPE_DISK, + RESOURCEUSAGE.RESOURCEUSAGE_ALL, null, lphEnum)); + assertEquals(WinError.ERROR_SUCCESS, Mpr.INSTANCE.WNetCloseEnum(lphEnum.getValue())); + } + + public void testWNetEnumConnection() throws Exception { + int bufferSize = 16 * 1024; // MSDN recommends this as a reasonable size + HANDLEByReference lphEnum = new HANDLEByReference(); + + // Create a local share and connect to it. This ensures the enum will + // find at least one entry. + File fileShareFolder = createTempFolder(); + String share = createLocalShare(fileShareFolder); + // Connect to local share + connectToLocalShare(share, null); + + try { + + // Open an enumeration + assertEquals(WinError.ERROR_SUCCESS, Mpr.INSTANCE.WNetOpenEnum(RESOURCESCOPE.RESOURCE_CONNECTED, RESOURCETYPE.RESOURCETYPE_DISK, + RESOURCEUSAGE.RESOURCEUSAGE_ALL, null, lphEnum)); + + int winError = WinError.ERROR_SUCCESS; + + while (true) { + + Memory memory = new Memory(bufferSize); + + IntByReference lpBufferSize = new IntByReference(bufferSize); + IntByReference lpcCount = new IntByReference(1); + + // Get next value + winError = Mpr.INSTANCE.WNetEnumResource(lphEnum.getValue(), lpcCount, memory, lpBufferSize); + + // Reached end of enumeration + if (winError == WinError.ERROR_NO_MORE_ITEMS) + break; + + // Unlikely, but means our buffer size isn't large enough. + if (winError == WinError.ERROR_MORE_DATA) { + bufferSize = bufferSize * 2; + continue; + } + + // If we get here, it means it has to be a success or our + // programming logic was wrong. + assertEquals(winError, WinError.ERROR_SUCCESS); + + // Asked for one, should only get one. + assertEquals(1, lpcCount.getValue()); + + // Create a NETRESOURCE based on the memory + NETRESOURCE resource = new NETRESOURCE(memory); + + // Assert things we know for sure. + assertNotNull(resource.lpRemoteName); + } + + // Expect ERROR_NO_MORE_ITEMS here. + assertEquals(winError, WinError.ERROR_NO_MORE_ITEMS); + } finally { + // Clean up resources + Mpr.INSTANCE.WNetCloseEnum(lphEnum.getValue()); + disconnectFromLocalShare("\\\\" + getLocalComputerName() + "\\" + share); + deleteLocalShare(share); + fileShareFolder.delete(); + } + } + + public void testWNetGetUniversalName() throws Exception { + int bufferSize = 1024; // MSDN recommends this as a reasonable size + Memory memory = new Memory(bufferSize); + IntByReference lpBufferSize = new IntByReference(bufferSize); + File file = null; + String share = null; + String driveLetter = new String("x:"); + File fileShareFolder = createTempFolder(); + + try { + // Create a local share and connect to it. + share = createLocalShare(fileShareFolder); + // Connect to share using a drive letter. + connectToLocalShare(share, driveLetter); + + // Create a path on local device redirected to the share. + String filePath = new String(driveLetter + "\\testfile.txt"); + file = new File(filePath); + file.createNewFile(); + + // Test WNetGetUniversalName using UNIVERSAL_NAME_INFO_LEVEL + assertEquals(WinError.ERROR_SUCCESS, + Mpr.INSTANCE.WNetGetUniversalName(filePath, Winnetwk.UNIVERSAL_NAME_INFO_LEVEL, memory, lpBufferSize)); + + UNIVERSAL_NAME_INFO uinfo = new UNIVERSAL_NAME_INFO(memory); + assertNotNull(uinfo.lpUniversalName); + + // Test WNetGetUniversalName using REMOTE_NAME_INFO_LEVEL + assertEquals(WinError.ERROR_SUCCESS, + Mpr.INSTANCE.WNetGetUniversalName(filePath, Winnetwk.REMOTE_NAME_INFO_LEVEL, memory, lpBufferSize)); + + REMOTE_NAME_INFO rinfo = new REMOTE_NAME_INFO(memory); + assertNotNull(rinfo.lpUniversalName); + assertNotNull(rinfo.lpConnectionName); + assertNotNull(rinfo.lpRemainingPath); + } finally { + // Clean up resources + if (file != null) + file.delete(); + if (share != null) { + disconnectFromLocalShare(driveLetter); + deleteLocalShare(share); + fileShareFolder.delete(); + } + } + } + + private static File createTempFolder() throws Exception { + String folderPath = System.getProperty("java.io.tmpdir") + File.separatorChar + System.nanoTime(); + File file = new File(folderPath); + file.mkdir(); + return file; + } + + /** + * Get local NETBIOS machine name + * + * @return String with machine name + * @throws Exception + */ + private String getLocalComputerName() throws Exception { + IntByReference lpnSize = new IntByReference(0); + // Get size of char array + Kernel32.INSTANCE.GetComputerName(null, lpnSize); + assertEquals(WinError.ERROR_BUFFER_OVERFLOW, Kernel32.INSTANCE.GetLastError()); + // Allocate character array + char buffer[] = new char[WinBase.MAX_COMPUTERNAME_LENGTH + 1]; + lpnSize.setValue(buffer.length); + assertTrue(Kernel32.INSTANCE.GetComputerName(buffer, lpnSize)); + // Return string with computer name + String computerName = new String(buffer); + computerName = computerName.trim(); + return computerName; + } + + /** + * Create a share on the local machine. Uses a temporary directory and + * shares it out with ACCESS_ALL + * + * @param shareFolder + * the full path local folder to share + * @return String with the share name, essentially the top level folder + * name. + * @throws Exception + * the exception + */ + private String createLocalShare(File shareFolder) throws Exception { + + SHARE_INFO_2 shi = new SHARE_INFO_2(); + shi.shi2_netname = shareFolder.getName(); + shi.shi2_type = LMShare.STYPE_DISKTREE; + shi.shi2_remark = ""; + shi.shi2_permissions = LMAccess.ACCESS_ALL; + shi.shi2_max_uses = -1; + shi.shi2_current_uses = 0; + shi.shi2_path = shareFolder.getAbsolutePath(); + shi.shi2_passwd = ""; + + // Write from struct to native memory. + shi.write(); + + IntByReference parm_err = new IntByReference(0); + assertEquals(LMErr.NERR_Success, Netapi32.INSTANCE.NetShareAdd(null, // Use + // local + // computer + 2, shi.getPointer(), parm_err)); + + return shareFolder.getName(); + } + + /** + * Delete a local share + * + * @param share + */ + private void deleteLocalShare(String share) { + Netapi32.INSTANCE.NetShareDel(null, share, 0); + } + + /** + * Connect to a local share on the local machine. Assumes the share is + * already present + * + * @param share + * name of share on local computer. + * @param lpLocalName + * name of local device to redirect to. E.g. F:. If null, makes a + * connection without redirecting. + * @throws Exception + * the exception + */ + private void connectToLocalShare(String share, String lpLocalName) throws Exception { + NETRESOURCE resource = new NETRESOURCE(); + + resource.dwDisplayType = 0; + resource.dwScope = 0; + resource.dwType = RESOURCETYPE.RESOURCETYPE_DISK; + resource.lpLocalName = lpLocalName; + resource.lpRemoteName = "\\\\" + getLocalComputerName() + "\\" + share; + + // Establish connection + assertEquals(WinError.ERROR_SUCCESS, Mpr.INSTANCE.WNetAddConnection3(null, resource, null, null, 0)); + } + + /** + * Disconnect from a share. + * + * @param lpName + * [in] Pointer to a constant null-terminated string that + * specifies the name of either the redirected local device or + * the remote network resource to disconnect from. If this + * parameter specifies a redirected local device, the function + * cancels only the specified device redirection. If the + * parameter specifies a remote network resource, all connections + * without devices are canceled. + */ + private void disconnectFromLocalShare(String lpName) { + // Remove connection + Mpr.INSTANCE.WNetCancelConnection2(lpName, ConnectFlag.CONNECT_UPDATE_PROFILE, true); + } +} diff --git a/contrib/platform/test/com/sun/jna/platform/win32/Netapi32Test.java b/contrib/platform/test/com/sun/jna/platform/win32/Netapi32Test.java index ca6c47b43a..0e1c269949 100644 --- a/contrib/platform/test/com/sun/jna/platform/win32/Netapi32Test.java +++ b/contrib/platform/test/com/sun/jna/platform/win32/Netapi32Test.java @@ -12,15 +12,16 @@ */ package com.sun.jna.platform.win32; -import junit.framework.TestCase; +import java.io.File; -import com.sun.jna.WString; import com.sun.jna.platform.win32.DsGetDC.DS_DOMAIN_TRUSTS; import com.sun.jna.platform.win32.DsGetDC.PDOMAIN_CONTROLLER_INFO; import com.sun.jna.platform.win32.LMAccess.GROUP_INFO_2; import com.sun.jna.platform.win32.LMAccess.GROUP_USERS_INFO_0; import com.sun.jna.platform.win32.LMAccess.LOCALGROUP_USERS_INFO_0; import com.sun.jna.platform.win32.LMAccess.USER_INFO_1; +import com.sun.jna.platform.win32.LMShare.SHARE_INFO_2; +import com.sun.jna.platform.win32.LMShare.SHARE_INFO_502; import com.sun.jna.platform.win32.NTSecApi.LSA_FOREST_TRUST_RECORD; import com.sun.jna.platform.win32.NTSecApi.PLSA_FOREST_TRUST_INFORMATION; import com.sun.jna.platform.win32.NTSecApi.PLSA_FOREST_TRUST_RECORD; @@ -29,6 +30,8 @@ import com.sun.jna.ptr.IntByReference; import com.sun.jna.ptr.PointerByReference; +import junit.framework.TestCase; + /** * @author dblock[at]dblock[dot]org */ @@ -146,8 +149,8 @@ public void testNetUserEnum() { public void testNetUserAdd() { USER_INFO_1 userInfo = new USER_INFO_1(); - userInfo.usri1_name = new WString("JNANetapi32TestUser"); - userInfo.usri1_password = new WString("!JNAP$$Wrd0"); + userInfo.usri1_name = "JNANetapi32TestUser"; + userInfo.usri1_password = "!JNAP$$Wrd0"; userInfo.usri1_priv = LMAccess.USER_PRIV_USER; // ignore test if not able to add user (need to be administrator to do this). if (LMErr.NERR_Success != Netapi32.INSTANCE.NetUserAdd(Kernel32Util.getComputerName(), 1, userInfo, null)) { @@ -159,8 +162,8 @@ public void testNetUserAdd() { public void testNetUserChangePassword() { USER_INFO_1 userInfo = new USER_INFO_1(); - userInfo.usri1_name = new WString("JNANetapi32TestUser"); - userInfo.usri1_password = new WString("!JNAP$$Wrd0"); + userInfo.usri1_name = "JNANetapi32TestUser"; + userInfo.usri1_password = "!JNAP$$Wrd0"; userInfo.usri1_priv = LMAccess.USER_PRIV_USER; // ignore test if not able to add user (need to be administrator to do this). if (LMErr.NERR_Success != Netapi32.INSTANCE.NetUserAdd(Kernel32Util.getComputerName(), 1, userInfo, null)) { @@ -257,4 +260,98 @@ public void testDsEnumerateDomainTrusts() { assertEquals(W32Errors.ERROR_SUCCESS, Netapi32.INSTANCE.NetApiBufferFree(domainTrustRefs.getPointer())); } + public void testNetShareAddShareInfo2() throws Exception { + + File fileShareFolder = createTempFolder(); + + SHARE_INFO_2 shi = new SHARE_INFO_2(); + shi.shi2_netname = fileShareFolder.getName(); + shi.shi2_type = LMShare.STYPE_DISKTREE; + shi.shi2_remark = ""; + shi.shi2_permissions = LMAccess.ACCESS_ALL; + shi.shi2_max_uses = -1; + shi.shi2_current_uses = 0; + shi.shi2_path = fileShareFolder.getAbsolutePath(); + shi.shi2_passwd = ""; + + // Write from struct to native memory. + shi.write(); + + IntByReference parm_err = new IntByReference(0); + int winError = Netapi32.INSTANCE.NetShareAdd(null, // Use local computer + 2, shi.getPointer(), parm_err); + + if (winError == W32Errors.ERROR_INVALID_PARAMETER) { + // fail with offset. + throw new Exception("testNetShareAddShareInfo2 failed with invalid parameter on structure offset: " + parm_err.getValue()); + } + + assertEquals(LMErr.NERR_Success, winError); + + Netapi32.INSTANCE.NetShareDel(null, shi.shi2_netname, 0); + } + + public void testNetShareAddShareInfo502() throws Exception { + + File fileShareFolder = createTempFolder(); + + SHARE_INFO_502 shi = new SHARE_INFO_502(); + shi.shi502_netname = fileShareFolder.getName(); + shi.shi502_type = LMShare.STYPE_DISKTREE; + shi.shi502_remark = ""; + shi.shi502_permissions = LMAccess.ACCESS_ALL; + shi.shi502_max_uses = -1; + shi.shi502_current_uses = 0; + shi.shi502_path = fileShareFolder.getAbsolutePath(); + shi.shi502_passwd = null; + shi.shi502_reserved = 0; + shi.shi502_security_descriptor = null; + + // Write from struct to native memory. + shi.write(); + + IntByReference parm_err = new IntByReference(0); + int winError = Netapi32.INSTANCE.NetShareAdd(null, // Use local computer + 502, shi.getPointer(), parm_err); + + if (winError == W32Errors.ERROR_INVALID_PARAMETER) { + // fail with offset. + throw new Exception("testNetShareAddShareInfo502 failed with invalid parameter on structure offset: " + parm_err.getValue()); + } + + assertEquals(LMErr.NERR_Success, winError); + + Netapi32.INSTANCE.NetShareDel(null, shi.shi502_netname, 0); + } + + public void testNetShareDel() throws Exception { + + File fileShareFolder = createTempFolder(); + + SHARE_INFO_2 shi = new SHARE_INFO_2(); + shi.shi2_netname = fileShareFolder.getName(); + shi.shi2_type = LMShare.STYPE_DISKTREE; + shi.shi2_remark = ""; + shi.shi2_permissions = LMAccess.ACCESS_ALL; + shi.shi2_max_uses = -1; + shi.shi2_current_uses = 0; + shi.shi2_path = fileShareFolder.getAbsolutePath(); + shi.shi2_passwd = ""; + + // Write from struct to native memory. + shi.write(); + + IntByReference parm_err = new IntByReference(0); + assertEquals(LMErr.NERR_Success, Netapi32.INSTANCE.NetShareAdd(null, // Use local computer + 2, shi.getPointer(), parm_err)); + + assertEquals(LMErr.NERR_Success, Netapi32.INSTANCE.NetShareDel(null, shi.shi2_netname, 0)); + } + + private File createTempFolder() throws Exception { + String folderPath = System.getProperty("java.io.tmpdir") + File.separatorChar + System.nanoTime(); + File file = new File(folderPath); + file.mkdir(); + return file; + } } diff --git a/contrib/platform/test/com/sun/jna/platform/win32/Shell32Test.java b/contrib/platform/test/com/sun/jna/platform/win32/Shell32Test.java index e280be3abc..609166ee59 100644 --- a/contrib/platform/test/com/sun/jna/platform/win32/Shell32Test.java +++ b/contrib/platform/test/com/sun/jna/platform/win32/Shell32Test.java @@ -12,19 +12,23 @@ */ package com.sun.jna.platform.win32; -import junit.framework.TestCase; +import java.io.File; +import java.io.FileWriter; +import java.io.IOException; import com.sun.jna.Native; +import com.sun.jna.WString; import com.sun.jna.platform.win32.Guid.GUID; import com.sun.jna.platform.win32.ShellAPI.APPBARDATA; +import com.sun.jna.platform.win32.ShellAPI.SHELLEXECUTEINFO; import com.sun.jna.platform.win32.WinDef.DWORD; -import com.sun.jna.platform.win32.WinDef.LPVOID; -import com.sun.jna.platform.win32.WinDef.RECT; import com.sun.jna.platform.win32.WinDef.UINT_PTR; import com.sun.jna.platform.win32.WinNT.HANDLE; import com.sun.jna.platform.win32.WinNT.HRESULT; import com.sun.jna.ptr.PointerByReference; +import junit.framework.TestCase; + /** * @author dblock[at]dblock[dot]org @@ -32,7 +36,8 @@ */ public class Shell32Test extends TestCase { - private static final int RESIZE_HEIGHT = 500; + // avoid disrupting the screen _too_ much + private static final int RESIZE_DELTA = 10; private static final int WM_USER = 0x0400; public static void main(String[] args) { @@ -42,8 +47,8 @@ public static void main(String[] args) { public void testSHGetFolderPath() { char[] pszPath = new char[WinDef.MAX_PATH]; assertEquals(W32Errors.S_OK, Shell32.INSTANCE.SHGetFolderPath(null, - ShlObj.CSIDL_PROGRAM_FILES, null, ShlObj.SHGFP_TYPE_CURRENT, - pszPath)); + ShlObj.CSIDL_PROGRAM_FILES, null, ShlObj.SHGFP_TYPE_CURRENT, + pszPath)); assertTrue(Native.toString(pszPath).length() > 0); } @@ -94,7 +99,7 @@ public void testResizeDesktopFromBottom() throws InterruptedException { APPBARDATA data = new APPBARDATA.ByReference(); data.uEdge.setValue(ShellAPI.ABE_BOTTOM); - data.rc.top = User32.INSTANCE.GetSystemMetrics(User32.SM_CYFULLSCREEN) - RESIZE_HEIGHT; + data.rc.top = User32.INSTANCE.GetSystemMetrics(User32.SM_CYFULLSCREEN) - RESIZE_DELTA; data.rc.left = 0; data.rc.bottom = User32.INSTANCE.GetSystemMetrics(User32.SM_CYFULLSCREEN); data.rc.right = User32.INSTANCE.GetSystemMetrics(User32.SM_CXFULLSCREEN); @@ -117,7 +122,7 @@ public void testResizeDesktopFromTop() throws InterruptedException { data.uEdge.setValue(ShellAPI.ABE_TOP); data.rc.top = 0; data.rc.left = 0; - data.rc.bottom = RESIZE_HEIGHT; + data.rc.bottom = User32.INSTANCE.GetSystemMetrics(User32.SM_CXFULLSCREEN) - RESIZE_DELTA; data.rc.right = User32.INSTANCE.GetSystemMetrics(User32.SM_CXFULLSCREEN); queryPos(data); @@ -131,16 +136,93 @@ public void testResizeDesktopFromTop() throws InterruptedException { } - public void testSHGetKnownFolderPath() - { + public void testSHGetKnownFolderPath() { int flags = ShlObj.KNOWN_FOLDER_FLAG.NONE.getFlag(); PointerByReference outPath = new PointerByReference(); HANDLE token = null; GUID guid = KnownFolders.FOLDERID_Fonts; HRESULT hr = Shell32.INSTANCE.SHGetKnownFolderPath(guid, flags, token, outPath); - + Ole32.INSTANCE.CoTaskMemFree(outPath.getValue()); - + assertTrue(W32Errors.SUCCEEDED(hr.intValue())); } + + public void testSHEmptyRecycleBin() { + File file = new File(System.getProperty("java.io.tmpdir"), System.nanoTime() + ".txt"); + try { + // Create a file and immediately send it to the recycle bin. + try { + fillTempFile(file); + W32FileUtils.getInstance().moveToTrash(new File[] { file }); + } catch (IOException e) { + throw new RuntimeException(e); + } + + int result = Shell32.INSTANCE.SHEmptyRecycleBin(null, null, + Shell32.SHERB_NOCONFIRMATION | Shell32.SHERB_NOPROGRESSUI | Shell32.SHERB_NOSOUND); + // for reasons I can not find documented on MSDN, + // the function returns the following: + // 0 when the recycle bin has items in it + // -2147418113 when the recycle bin has no items in it + assertEquals("Result should have been ERROR_SUCCESS when emptying Recycle Bin - there should have been a file in it.", + W32Errors.ERROR_SUCCESS, result); + } finally { + // if the file wasn't sent to the recycle bin, delete it. + if (file.exists()) { + file.delete(); + } + } + } + + public void testShellExecuteEx() { + File file = new File(System.getProperty("java.io.tmpdir"), System.nanoTime() + ".txt"); + try { + try { + fillTempFile(file); + } catch (IOException e) { + throw new RuntimeException(e); + } + + SHELLEXECUTEINFO lpExecInfo = new SHELLEXECUTEINFO(); + // to avoid opening something and having hProcess come up null + // (meaning we opened something but can't close it) + // we will do a negative test with a bogus action. + lpExecInfo.lpVerb = "0p3n"; + lpExecInfo.nShow = User32.SW_SHOWDEFAULT; + lpExecInfo.fMask = Shell32.SEE_MASK_NOCLOSEPROCESS | Shell32.SEE_MASK_FLAG_NO_UI; + lpExecInfo.lpFile = file.getAbsolutePath(); + + assertFalse("ShellExecuteEx should have returned false - action verb was bogus.", + Shell32.INSTANCE.ShellExecuteEx(lpExecInfo)); + assertEquals("GetLastError() should have been set to ERROR_NO_ASSOCIATION because of bogus action", + W32Errors.ERROR_NO_ASSOCIATION, Native.getLastError()); + } finally { + if (file.exists()) { + file.delete(); + } + } + + } + + /** + * Creates (if needed) and fills the specified file with some content (10 lines of the same text) + * + * @param file + * The file to fill with content + * @throws IOException + * If writing the content fails + */ + private void fillTempFile(File file) throws IOException { + file.createNewFile(); + FileWriter fileWriter = new FileWriter(file); + try { + for (int i = 0; i < 10; i++) { + fileWriter.write("Sample line of text"); + fileWriter.write(System.getProperty("line.separator")); + } + } finally { + fileWriter.close(); + } + } } diff --git a/contrib/platform/test/com/sun/jna/platform/win32/User32Test.java b/contrib/platform/test/com/sun/jna/platform/win32/User32Test.java index 21ae47c685..e6b24afa0f 100644 --- a/contrib/platform/test/com/sun/jna/platform/win32/User32Test.java +++ b/contrib/platform/test/com/sun/jna/platform/win32/User32Test.java @@ -35,6 +35,8 @@ import com.sun.jna.platform.win32.WinDef.HICON; import com.sun.jna.platform.win32.WinDef.HWND; import com.sun.jna.platform.win32.WinDef.LPARAM; +import com.sun.jna.platform.win32.WinDef.LRESULT; +import com.sun.jna.platform.win32.WinDef.WPARAM; import com.sun.jna.platform.win32.WinDef.POINT; import com.sun.jna.platform.win32.WinDef.RECT; import com.sun.jna.platform.win32.WinDef.UINT; @@ -45,6 +47,7 @@ import com.sun.jna.platform.win32.WinUser.MONITORENUMPROC; import com.sun.jna.platform.win32.WinUser.MONITORINFO; import com.sun.jna.platform.win32.WinUser.MONITORINFOEX; +import com.sun.jna.platform.win32.BaseTSD.ULONG_PTR; /** * @author dblock[at]dblock[dot]org @@ -243,7 +246,7 @@ public final void testLockWorkStation() { assertTrue(User32.INSTANCE.LockWorkStation().booleanValue()); } - @Ignore("Shutsdown the workstation") + @Ignore("Shuts down the workstation") @Test public final void testExitWindows() { assertTrue(User32.INSTANCE.ExitWindowsEx(new UINT(WinUser.EWX_LOGOFF), new DWORD(0x00030000)).booleanValue()); //This only tries to log off. @@ -281,9 +284,12 @@ public void testSendMessageTimeout() { assertNotNull(explorerProc); final DWORDByReference hIconNumber = new DWORDByReference(); - long result = User32.INSTANCE.SendMessageTimeout( - explorerProc.getHWND(), WinUser.WM_GETICON, WinUser.ICON_BIG, - 0, WinUser.SMTO_ABORTIFHUNG, 500, hIconNumber); + LRESULT result = User32.INSTANCE + .SendMessageTimeout(explorerProc.getHWND(), + WinUser.WM_GETICON, + new WPARAM(WinUser.ICON_BIG), + new LPARAM(0), + WinUser.SMTO_ABORTIFHUNG, 500, hIconNumber); assertNotEquals(0, result); } @@ -292,11 +298,19 @@ public void testSendMessageTimeout() { public void testGetClassLongPtr() { DesktopWindow explorerProc = getWindowByProcessPath("explorer.exe"); - assertNotNull(explorerProc); + assertNotNull("Could not find explorer.exe process", + explorerProc); - long result = User32.INSTANCE.GetClassLongPtr(explorerProc.getHWND(), - WinUser.GCLP_HMODULE); + ULONG_PTR result = User32.INSTANCE + .GetClassLongPtr(explorerProc.getHWND(), + WinUser.GCLP_HMODULE); - assertNotEquals(0, result); + assertNotEquals(0, result.intValue()); + } + + @Test + public void testGetDesktopWindow() { + HWND desktopWindow = User32.INSTANCE.GetDesktopWindow(); + assertNotNull("Failed to get desktop window HWND", desktopWindow); } } diff --git a/contrib/platform/test/com/sun/jna/platform/win32/WinBaseTest.java b/contrib/platform/test/com/sun/jna/platform/win32/WinBaseTest.java index cecb4b3b7d..9224a716f4 100644 --- a/contrib/platform/test/com/sun/jna/platform/win32/WinBaseTest.java +++ b/contrib/platform/test/com/sun/jna/platform/win32/WinBaseTest.java @@ -1,133 +1,192 @@ /* Copyright (c) 2015 Markus Bollig, 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; +import java.util.Calendar; +import java.util.Date; + import com.sun.jna.platform.win32.WinBase.DCB; +import com.sun.jna.platform.win32.WinBase.FILETIME; +import com.sun.jna.platform.win32.WinBase.SYSTEMTIME; import junit.framework.TestCase; public class WinBaseTest extends TestCase { + public WinBaseTest() { + super(); + } + + public WinBaseTest(String name) { + super(name); + } + + public void testFiletime() { + // subtract to convert ms after 1/1/1970 to ms after 1/1/1601 + long epochDiff = 11644473600000L; + // Construct filetimes for ms after 1/1/1601, check for 100-ns after + assertEquals("Mismatched filetime for 2ms", (new FILETIME(new Date(2L - epochDiff))).toDWordLong().longValue(), 2L * 10000); + assertEquals("Mismatched filetime for 2^16ms", (new FILETIME(new Date((1L << 16) - epochDiff))).toDWordLong().longValue(), (1L << 16) * 10000); + assertEquals("Mismatched filetime for 2^32ms", (new FILETIME(new Date((1L << 32) - epochDiff))).toDWordLong().longValue(), (1L << 32) * 10000); + assertEquals("Mismatched filetime for 2^49ms", (new FILETIME(new Date((1L << 49) - epochDiff))).toDWordLong().longValue(), (1L << 49) * 10000); + } + + public void testCalendarToSystemTimeConversion() { + Calendar expected = Calendar.getInstance(); + SYSTEMTIME sysTime = new SYSTEMTIME(); + sysTime.fromCalendar(expected); + + assertEquals("Mismatched systime year", expected.get(Calendar.YEAR), sysTime.wYear); + assertEquals("Mismatched systime month", (1 + expected.get(Calendar.MONTH) - Calendar.JANUARY), sysTime.wMonth); + assertEquals("Mismatched systime day", expected.get(Calendar.DAY_OF_MONTH), sysTime.wDay); + assertEquals("Mismatched systime weekday", expected.get(Calendar.DAY_OF_WEEK) - Calendar.SUNDAY, sysTime.wDayOfWeek); - /** - * Test the mapping of the {@link DCB} structure. - * Particularly the mapping of the bit field is tested. - */ + assertEquals("Mismatched systime hour", expected.get(Calendar.HOUR_OF_DAY), sysTime.wHour); + assertEquals("Mismatched systime minute", expected.get(Calendar.MINUTE), sysTime.wMinute); + assertEquals("Mismatched systime second", expected.get(Calendar.SECOND), sysTime.wSecond); + // NOTE: we do not check millis due to clock granularity issues + + Calendar actual = sysTime.toCalendar(); + assertEquals("Mismatched calendar year", sysTime.wYear, actual.get(Calendar.YEAR)); + assertEquals("Mismatched calendar month", Calendar.JANUARY + (sysTime.wMonth - 1), actual.get(Calendar.MONTH)); + assertEquals("Mismatched calendar day", sysTime.wDay, actual.get(Calendar.DAY_OF_MONTH)); + assertEquals("Mismatched calendar weekday", sysTime.wDayOfWeek, actual.get(Calendar.DAY_OF_WEEK) - Calendar.SUNDAY); + + assertEquals("Mismatched calendar hour", sysTime.wHour, actual.get(Calendar.HOUR_OF_DAY)); + assertEquals("Mismatched calendar minute", sysTime.wMinute, actual.get(Calendar.MINUTE)); + assertEquals("Mismatched calendar second", sysTime.wSecond, actual.get(Calendar.SECOND)); + // NOTE: we do not check millis due to clock granularity issues + + assertEquals("Mismatched reconstructed year", expected.get(Calendar.YEAR), actual.get(Calendar.YEAR)); + assertEquals("Mismatched reconstructed month", expected.get(Calendar.MONTH), actual.get(Calendar.MONTH)); + assertEquals("Mismatched reconstructed day", expected.get(Calendar.DAY_OF_MONTH), actual.get(Calendar.DAY_OF_MONTH)); + assertEquals("Mismatched reconstructed weekday", expected.get(Calendar.DAY_OF_WEEK), actual.get(Calendar.DAY_OF_WEEK)); + + assertEquals("Mismatched reconstructed hour", expected.get(Calendar.HOUR_OF_DAY), actual.get(Calendar.HOUR_OF_DAY)); + assertEquals("Mismatched reconstructed minute", expected.get(Calendar.MINUTE), actual.get(Calendar.MINUTE)); + assertEquals("Mismatched reconstructed second", expected.get(Calendar.SECOND), actual.get(Calendar.SECOND)); + // NOTE: we do not check millis due to clock granularity issues + } + + /** + * Test the mapping of the {@link DCB} structure. + * Particularly the mapping of the bit field is tested. + */ public void testDCBStructureMapping() { - //first we test if the WinBase.DCB bitfiled mapping works as expected. - WinBase.DCB lpDCB = new WinBase.DCB(); - lpDCB.controllBits.setValue(0); - - lpDCB.controllBits.setfBinary(true); - assertEquals(1, lpDCB.controllBits.longValue()); - assertEquals(true, lpDCB.controllBits.getfBinary()); - lpDCB.controllBits.setfBinary(false); - assertEquals(0, lpDCB.controllBits.longValue()); - assertEquals(false, lpDCB.controllBits.getfBinary()); - - lpDCB.controllBits.setfParity(true); - assertEquals(2, lpDCB.controllBits.longValue()); - assertEquals(true, lpDCB.controllBits.getfParity()); - lpDCB.controllBits.setfParity(false); - assertEquals(0, lpDCB.controllBits.longValue()); - assertEquals(false, lpDCB.controllBits.getfParity()); - - lpDCB.controllBits.setfOutxCtsFlow(true); - assertEquals(4, lpDCB.controllBits.longValue()); - assertEquals(true, lpDCB.controllBits.getfOutxCtsFlow()); - lpDCB.controllBits.setfOutxCtsFlow(false); - assertEquals(0, lpDCB.controllBits.longValue()); - assertEquals(false, lpDCB.controllBits.getfOutxCtsFlow()); - - lpDCB.controllBits.setfOutxDsrFlow(true); - assertEquals(8, lpDCB.controllBits.longValue()); - assertEquals(true, lpDCB.controllBits.getfOutxDsrFlow()); - lpDCB.controllBits.setfOutxDsrFlow(false); - assertEquals(0, lpDCB.controllBits.longValue()); - assertEquals(false, lpDCB.controllBits.getfOutxDsrFlow()); - - lpDCB.controllBits.setfDtrControl(WinBase.DTR_CONTROL_ENABLE); - assertEquals(16, lpDCB.controllBits.longValue()); - assertEquals(WinBase.DTR_CONTROL_ENABLE, lpDCB.controllBits.getfDtrControl()); - lpDCB.controllBits.setfDtrControl(WinBase.DTR_CONTROL_HANDSHAKE); - assertEquals(32, lpDCB.controllBits.longValue()); - assertEquals(WinBase.DTR_CONTROL_HANDSHAKE, lpDCB.controllBits.getfDtrControl()); - lpDCB.controllBits.setfDtrControl(WinBase.DTR_CONTROL_DISABLE); - assertEquals(0, lpDCB.controllBits.longValue()); - assertEquals(WinBase.DTR_CONTROL_DISABLE, lpDCB.controllBits.getfDtrControl()); - - lpDCB.controllBits.setfDsrSensitivity(true); - assertEquals(64, lpDCB.controllBits.longValue()); - assertEquals(true, lpDCB.controllBits.getfDsrSensitivity()); - lpDCB.controllBits.setfDsrSensitivity(false); - assertEquals(0, lpDCB.controllBits.longValue()); - assertEquals(false, lpDCB.controllBits.getfDsrSensitivity()); - - lpDCB.controllBits.setfTXContinueOnXoff(true); - assertEquals(128, lpDCB.controllBits.longValue()); - assertEquals(true, lpDCB.controllBits.getfTXContinueOnXoff()); - lpDCB.controllBits.setfTXContinueOnXoff(false); - assertEquals(0, lpDCB.controllBits.longValue()); - assertEquals(false, lpDCB.controllBits.getfTXContinueOnXoff()); - - lpDCB.controllBits.setfOutX(true); - assertEquals(256, lpDCB.controllBits.longValue()); - assertEquals(true, lpDCB.controllBits.getfOutX()); - lpDCB.controllBits.setfOutX(false); - assertEquals(0, lpDCB.controllBits.longValue()); - assertEquals(false, lpDCB.controllBits.getfOutX()); - - lpDCB.controllBits.setfInX(true); - assertEquals(512, lpDCB.controllBits.longValue()); - assertEquals(true, lpDCB.controllBits.getfInX()); - lpDCB.controllBits.setfInX(false); - assertEquals(0, lpDCB.controllBits.longValue()); - assertEquals(false, lpDCB.controllBits.getfInX()); - - lpDCB.controllBits.setfErrorChar(true); - assertEquals(1024, lpDCB.controllBits.longValue()); - assertEquals(true, lpDCB.controllBits.getfErrorChar()); - lpDCB.controllBits.setfErrorChar(false); - assertEquals(0, lpDCB.controllBits.longValue()); - assertEquals(false, lpDCB.controllBits.getfErrorChar()); - - lpDCB.controllBits.setfNull(true); - assertEquals(2048, lpDCB.controllBits.longValue()); - assertEquals(true, lpDCB.controllBits.getfNull()); - lpDCB.controllBits.setfNull(false); - assertEquals(0, lpDCB.controllBits.longValue()); - assertEquals(false, lpDCB.controllBits.getfNull()); - - - lpDCB.controllBits.setfRtsControl(WinBase.RTS_CONTROL_ENABLE); - assertEquals(4096, lpDCB.controllBits.longValue()); - assertEquals(WinBase.RTS_CONTROL_ENABLE, lpDCB.controllBits.getfRtsControl()); - lpDCB.controllBits.setfRtsControl(WinBase.RTS_CONTROL_HANDSHAKE); - assertEquals(8192, lpDCB.controllBits.longValue()); - assertEquals(WinBase.RTS_CONTROL_HANDSHAKE, lpDCB.controllBits.getfRtsControl()); - lpDCB.controllBits.setfRtsControl(WinBase.RTS_CONTROL_TOGGLE); - assertEquals(12288, lpDCB.controllBits.longValue()); - assertEquals(WinBase.RTS_CONTROL_TOGGLE, lpDCB.controllBits.getfRtsControl()); - lpDCB.controllBits.setfRtsControl(WinBase.RTS_CONTROL_DISABLE); - assertEquals(0, lpDCB.controllBits.longValue()); - assertEquals(WinBase.RTS_CONTROL_DISABLE, lpDCB.controllBits.getfRtsControl()); - - - lpDCB.controllBits.setfAbortOnError(true); - assertEquals(16384, lpDCB.controllBits.longValue()); - assertEquals(true, lpDCB.controllBits.getfAbortOnError()); - lpDCB.controllBits.setfAbortOnError(false); - assertEquals(0, lpDCB.controllBits.longValue()); - assertEquals(false, lpDCB.controllBits.getfAbortOnError()); + //first we test if the WinBase.DCB bitfiled mapping works as expected. + WinBase.DCB lpDCB = new WinBase.DCB(); + lpDCB.controllBits.setValue(0); + + lpDCB.controllBits.setfBinary(true); + assertEquals(1, lpDCB.controllBits.longValue()); + assertEquals(true, lpDCB.controllBits.getfBinary()); + lpDCB.controllBits.setfBinary(false); + assertEquals(0, lpDCB.controllBits.longValue()); + assertEquals(false, lpDCB.controllBits.getfBinary()); + + lpDCB.controllBits.setfParity(true); + assertEquals(2, lpDCB.controllBits.longValue()); + assertEquals(true, lpDCB.controllBits.getfParity()); + lpDCB.controllBits.setfParity(false); + assertEquals(0, lpDCB.controllBits.longValue()); + assertEquals(false, lpDCB.controllBits.getfParity()); + + lpDCB.controllBits.setfOutxCtsFlow(true); + assertEquals(4, lpDCB.controllBits.longValue()); + assertEquals(true, lpDCB.controllBits.getfOutxCtsFlow()); + lpDCB.controllBits.setfOutxCtsFlow(false); + assertEquals(0, lpDCB.controllBits.longValue()); + assertEquals(false, lpDCB.controllBits.getfOutxCtsFlow()); + + lpDCB.controllBits.setfOutxDsrFlow(true); + assertEquals(8, lpDCB.controllBits.longValue()); + assertEquals(true, lpDCB.controllBits.getfOutxDsrFlow()); + lpDCB.controllBits.setfOutxDsrFlow(false); + assertEquals(0, lpDCB.controllBits.longValue()); + assertEquals(false, lpDCB.controllBits.getfOutxDsrFlow()); + + lpDCB.controllBits.setfDtrControl(WinBase.DTR_CONTROL_ENABLE); + assertEquals(16, lpDCB.controllBits.longValue()); + assertEquals(WinBase.DTR_CONTROL_ENABLE, lpDCB.controllBits.getfDtrControl()); + lpDCB.controllBits.setfDtrControl(WinBase.DTR_CONTROL_HANDSHAKE); + assertEquals(32, lpDCB.controllBits.longValue()); + assertEquals(WinBase.DTR_CONTROL_HANDSHAKE, lpDCB.controllBits.getfDtrControl()); + lpDCB.controllBits.setfDtrControl(WinBase.DTR_CONTROL_DISABLE); + assertEquals(0, lpDCB.controllBits.longValue()); + assertEquals(WinBase.DTR_CONTROL_DISABLE, lpDCB.controllBits.getfDtrControl()); + + lpDCB.controllBits.setfDsrSensitivity(true); + assertEquals(64, lpDCB.controllBits.longValue()); + assertEquals(true, lpDCB.controllBits.getfDsrSensitivity()); + lpDCB.controllBits.setfDsrSensitivity(false); + assertEquals(0, lpDCB.controllBits.longValue()); + assertEquals(false, lpDCB.controllBits.getfDsrSensitivity()); + + lpDCB.controllBits.setfTXContinueOnXoff(true); + assertEquals(128, lpDCB.controllBits.longValue()); + assertEquals(true, lpDCB.controllBits.getfTXContinueOnXoff()); + lpDCB.controllBits.setfTXContinueOnXoff(false); + assertEquals(0, lpDCB.controllBits.longValue()); + assertEquals(false, lpDCB.controllBits.getfTXContinueOnXoff()); + + lpDCB.controllBits.setfOutX(true); + assertEquals(256, lpDCB.controllBits.longValue()); + assertEquals(true, lpDCB.controllBits.getfOutX()); + lpDCB.controllBits.setfOutX(false); + assertEquals(0, lpDCB.controllBits.longValue()); + assertEquals(false, lpDCB.controllBits.getfOutX()); + + lpDCB.controllBits.setfInX(true); + assertEquals(512, lpDCB.controllBits.longValue()); + assertEquals(true, lpDCB.controllBits.getfInX()); + lpDCB.controllBits.setfInX(false); + assertEquals(0, lpDCB.controllBits.longValue()); + assertEquals(false, lpDCB.controllBits.getfInX()); + + lpDCB.controllBits.setfErrorChar(true); + assertEquals(1024, lpDCB.controllBits.longValue()); + assertEquals(true, lpDCB.controllBits.getfErrorChar()); + lpDCB.controllBits.setfErrorChar(false); + assertEquals(0, lpDCB.controllBits.longValue()); + assertEquals(false, lpDCB.controllBits.getfErrorChar()); + + lpDCB.controllBits.setfNull(true); + assertEquals(2048, lpDCB.controllBits.longValue()); + assertEquals(true, lpDCB.controllBits.getfNull()); + lpDCB.controllBits.setfNull(false); + assertEquals(0, lpDCB.controllBits.longValue()); + assertEquals(false, lpDCB.controllBits.getfNull()); + + + lpDCB.controllBits.setfRtsControl(WinBase.RTS_CONTROL_ENABLE); + assertEquals(4096, lpDCB.controllBits.longValue()); + assertEquals(WinBase.RTS_CONTROL_ENABLE, lpDCB.controllBits.getfRtsControl()); + lpDCB.controllBits.setfRtsControl(WinBase.RTS_CONTROL_HANDSHAKE); + assertEquals(8192, lpDCB.controllBits.longValue()); + assertEquals(WinBase.RTS_CONTROL_HANDSHAKE, lpDCB.controllBits.getfRtsControl()); + lpDCB.controllBits.setfRtsControl(WinBase.RTS_CONTROL_TOGGLE); + assertEquals(12288, lpDCB.controllBits.longValue()); + assertEquals(WinBase.RTS_CONTROL_TOGGLE, lpDCB.controllBits.getfRtsControl()); + lpDCB.controllBits.setfRtsControl(WinBase.RTS_CONTROL_DISABLE); + assertEquals(0, lpDCB.controllBits.longValue()); + assertEquals(WinBase.RTS_CONTROL_DISABLE, lpDCB.controllBits.getfRtsControl()); + + + lpDCB.controllBits.setfAbortOnError(true); + assertEquals(16384, lpDCB.controllBits.longValue()); + assertEquals(true, lpDCB.controllBits.getfAbortOnError()); + lpDCB.controllBits.setfAbortOnError(false); + assertEquals(0, lpDCB.controllBits.longValue()); + assertEquals(false, lpDCB.controllBits.getfAbortOnError()); } public static void main(String[] args) { diff --git a/contrib/platform/test/com/sun/jna/platform/win32/WindowUtilsTest.java b/contrib/platform/test/com/sun/jna/platform/win32/WindowUtilsTest.java index a82c81d425..98c1867afd 100644 --- a/contrib/platform/test/com/sun/jna/platform/win32/WindowUtilsTest.java +++ b/contrib/platform/test/com/sun/jna/platform/win32/WindowUtilsTest.java @@ -26,6 +26,9 @@ import com.sun.jna.platform.win32.WinDef.DWORDByReference; import com.sun.jna.platform.win32.WinDef.HICON; import com.sun.jna.platform.win32.WinDef.HWND; +import com.sun.jna.platform.win32.WinDef.LPARAM; +import com.sun.jna.platform.win32.WinDef.LRESULT; +import com.sun.jna.platform.win32.WinDef.WPARAM; import com.sun.jna.platform.win32.WinUser; public class WindowUtilsTest extends TestCase { @@ -36,9 +39,10 @@ public void testGetAllWindows() { final List allVisibleWindows = WindowUtils .getAllWindows(true); - assertTrue(allWindows.size() > 0); - assertTrue(allVisibleWindows.size() > 0); - assertTrue(allWindows.size() > allVisibleWindows.size()); + assertTrue("Found no windows", allWindows.size() > 0); + assertTrue("Found no visible windows", allVisibleWindows.size() > 0); + assertTrue("Expected more non-visible windows than visible windows", + allWindows.size() > allVisibleWindows.size()); DesktopWindow explorerProc = null; for (final DesktopWindow dw : allWindows) { @@ -48,7 +52,8 @@ public void testGetAllWindows() { } } - assertNotNull(explorerProc); + assertNotNull("explorer.exe was not found among all windows", + explorerProc); explorerProc = null; for (final DesktopWindow dw : allVisibleWindows) { @@ -58,7 +63,8 @@ public void testGetAllWindows() { } } - assertNotNull(explorerProc); + assertNotNull("explorer.exe was not found among visible windows", + explorerProc); } public void testGetWindowIcon() throws Exception { @@ -70,8 +76,9 @@ public void testGetWindowIcon() throws Exception { "/res/test_icon.png").getPath()))); w.setIconImage(expectedIcon); w.setVisible(true); - HWND hwnd = new HWND(); - hwnd.setPointer(Native.getComponentPointer(w)); + Pointer p = Native.getComponentPointer(w); + assertNotNull("Couldn't obtain window HANDLE from JFrame", p); + HWND hwnd = new HWND(p); final BufferedImage obtainedIcon = WindowUtils.getWindowIcon(hwnd); @@ -149,15 +156,18 @@ public void testGetIconSize() throws Exception { .read(new FileInputStream(new File(getClass().getResource("/res/test_icon.png").getPath()))); w.setIconImage(expectedIcon); w.setVisible(true); - HWND hwnd = new HWND(); - hwnd.setPointer(Native.getComponentPointer(w)); + Pointer p = Native.getComponentPointer(w); + assertNotNull("Could not obtain native HANDLE for JFrame", p); + HWND hwnd = new HWND(p); final DWORDByReference hIconNumber = new DWORDByReference(); - long result = User32.INSTANCE.SendMessageTimeout(hwnd, - WinUser.WM_GETICON, WinUser.ICON_BIG, 0, - WinUser.SMTO_ABORTIFHUNG, 500, hIconNumber); + LRESULT result = User32.INSTANCE + .SendMessageTimeout(hwnd, WinUser.WM_GETICON, + new WPARAM(WinUser.ICON_BIG), + new LPARAM(0), + WinUser.SMTO_ABORTIFHUNG, 500, hIconNumber); - assertNotEquals(0, result); + assertNotEquals(0, result.intValue()); final HICON hIcon = new HICON(new Pointer(hIconNumber.getValue() .longValue())); diff --git a/dist/native-dispatch-libs.jar b/dist/native-dispatch-libs.jar new file mode 100644 index 0000000000..3fcb21fcc3 Binary files /dev/null and b/dist/native-dispatch-libs.jar differ