Skip to content

Commit

Permalink
Found and fixed duplicate method definitions for the same API
Browse files Browse the repository at this point in the history
  • Loading branch information
Lyor Goldstein committed Aug 6, 2015
1 parent ab7eea6 commit 00e6184
Show file tree
Hide file tree
Showing 8 changed files with 995 additions and 982 deletions.
584 changes: 235 additions & 349 deletions contrib/platform/src/com/sun/jna/platform/win32/Kernel32.java

Large diffs are not rendered by default.

607 changes: 270 additions & 337 deletions contrib/platform/src/com/sun/jna/platform/win32/User32.java

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -12,17 +12,52 @@
*/
package com.sun.jna.platform.win32;

import java.lang.reflect.Method;
import java.util.Collection;
import java.util.HashSet;
import java.util.Set;

import com.sun.jna.platform.AbstractPlatformTestSupport;
import com.sun.jna.platform.win32.WinNT.HANDLE;

/**
* @author lgoldstein
*/
public abstract class AbstractWin32TestSupport extends AbstractPlatformTestSupport {
protected AbstractWin32TestSupport() {
super();
}

/**
* Makes sure that the method names (which represent APIs) do not repeat
* themselves. This check is in order where APIs are WIN32 API <U>functions</U>
* since these are C functions - which means no overloading is possible.
*
* @param ifc The interface (not checked) class to test
* @see #detectDuplicateMethods(Class)
*/
public static final void assertNoDuplicateMethodsNames(Class<?> ifc) {
Collection<String> dupSet = detectDuplicateMethods(ifc);
assertTrue("Duplicate names found in " + ifc.getSimpleName() + ": " + dupSet, dupSet.isEmpty());
}

/**
* Checks if there are methods with the same name - regardless of the signature
*
* @param ifc The interface (not checked) class to test
* @return The {@link Set} of duplicate names - empty if no duplicates
*/
public static final Set<String> detectDuplicateMethods(Class<?> ifc) {
Method[] methods = ifc.getMethods();
Set<String> nameSet = new HashSet<String>(methods.length);
Set<String> dupSet = new HashSet<String>();
for (Method m : methods) {
String name = m.getName();
if (!nameSet.add(name)) {
dupSet.add(name);
}
}

return dupSet;
}

/**
* Checks if the API call result is {@code true}. If not, then calls
* {@link Kernel32#GetLastError()} and fails with the error code.
Expand All @@ -35,15 +70,15 @@ public static final void assertCallSucceeded(String message, boolean result) {
if (result) {
return;
}

int hr = Kernel32.INSTANCE.GetLastError();
if (hr == WinError.ERROR_SUCCESS) {
fail(message + " failed with unknown reason code");
} else {
fail(message + " failed: hr=" + hr + " - 0x" + Integer.toHexString(hr));
}
}

/**
* Checks if the status code is ERROR_SUCCESS
* @param message Message to display if code is an error
Expand All @@ -59,7 +94,7 @@ public static final void assertErrorSuccess(String message, int statusCode, bool
assertEquals(message, WinError.ERROR_SUCCESS, statusCode);
}
}

/**
* Makes sure that the handle argument is not {@code null} or {@link WinBase#INVALID_HANDLE_VALUE}.
* If invalid handle detected, then it invokes {@link Kernel32#GetLastError()}
Expand Down
370 changes: 194 additions & 176 deletions contrib/platform/test/com/sun/jna/platform/win32/Advapi32Test.java

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@
/* Copyright (c) 2007 Timothy Wall, 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 java.util.List;

import org.junit.Test;

import com.sun.jna.platform.win32.WinDef.DWORD;
import com.sun.jna.platform.win32.WinDef.DWORDByReference;
import com.sun.jna.platform.win32.WinNT.LARGE_INTEGER;

public class Kernel32DiskManagementFunctionsTest extends AbstractWin32TestSupport {
public Kernel32DiskManagementFunctionsTest() {
super();
}

@Test
public void testGetDiskFreeSpaceEx() {
List<String> driveList = Kernel32Util.getLogicalDriveStrings();
for (int index = (-1); index < driveList.size(); index++) {
String driveName = (index < 0) ? null : driveList.get(index);
if (driveName != null) {
// according to the documentation must end with a backslash
if (driveName.charAt(driveName.length() - 1) != File.separatorChar) {
driveName += File.separator;
}

int driveType = Kernel32.INSTANCE.GetDriveType(driveName);
/*
* Don't try DVD or network drives since they may yield errors
* for the test - e.g., DEVICE_NOT_READY
*/
if (driveType != WinNT.DRIVE_FIXED) {
continue;
}
}

testGetDiskFreeSpaceEx(driveName);
}
}

private void testGetDiskFreeSpaceEx(String lpDirectoryName) {
LARGE_INTEGER.ByReference lpFreeBytesAvailable = new LARGE_INTEGER.ByReference();
LARGE_INTEGER.ByReference lpTotalNumberOfBytes = new LARGE_INTEGER.ByReference();
LARGE_INTEGER.ByReference lpTotalNumberOfFreeBytes = new LARGE_INTEGER.ByReference();
assertCallSucceeded("GetDiskFreeSpaceEx(" + lpDirectoryName + ")",
Kernel32.INSTANCE.GetDiskFreeSpaceEx(lpDirectoryName,
lpFreeBytesAvailable, lpTotalNumberOfBytes, lpTotalNumberOfFreeBytes));

// System.out.append(getCurrentTestName()).append('[').append(lpDirectoryName).println(']');
// System.out.append('\t').append("FreeBytesAvailable: ").println(lpFreeBytesAvailable);
// System.out.append('\t').append("TotalNumberOfBytes: ").println(lpTotalNumberOfBytes);
// System.out.append('\t').append("TotalNumberOfFreeBytes: ").println(lpTotalNumberOfFreeBytes);

assertTrue("No free size for " + lpDirectoryName, lpTotalNumberOfFreeBytes.getValue() > 0L);
assertTrue("Free size (" + lpTotalNumberOfFreeBytes + ")"
+ " not below total size (" + lpTotalNumberOfBytes + ")"
+ " for " + lpDirectoryName,
lpTotalNumberOfFreeBytes.getValue() < lpTotalNumberOfBytes.getValue());
}

@Test
public void testGetDiskFreeSpace() {
List<String> driveList = Kernel32Util.getLogicalDriveStrings();
for (int index = (-1); index < driveList.size(); index++) {
String driveName = (index < 0) ? null : driveList.get(index);
if (driveName != null) {
// according to the documentation must end with a backslash
if (driveName.charAt(driveName.length() - 1) != File.separatorChar) {
driveName += File.separator;
}

int driveType = Kernel32.INSTANCE.GetDriveType(driveName);
/*
* Don't try DVD or network drives since they may yield errors
* for the test - e.g., DEVICE_NOT_READY
*/
if (driveType != WinNT.DRIVE_FIXED) {
continue;
}
}

testGetDiskFreeSpace(driveName);
}
}

private void testGetDiskFreeSpace(String lpRootPathName) {
DWORDByReference lpSectorsPerCluster = new DWORDByReference();
DWORDByReference lpBytesPerSector = new DWORDByReference();
DWORDByReference lpNumberOfFreeClusters = new DWORDByReference();
DWORDByReference lpTotalNumberOfClusters = new DWORDByReference();
assertCallSucceeded("GetDiskFreeSpace(" + lpRootPathName + ")",
Kernel32.INSTANCE.GetDiskFreeSpace(lpRootPathName,
lpSectorsPerCluster, lpBytesPerSector, lpNumberOfFreeClusters, lpTotalNumberOfClusters));

// System.out.append(getCurrentTestName()).append('[').append(lpRootPathName).println(']');
// System.out.append('\t').append("SectorsPerCluster: ").println(lpSectorsPerCluster.getValue());
// System.out.append('\t').append("BytesPerSector: ").println(lpBytesPerSector.getValue());
// System.out.append('\t').append("NumberOfFreeClusters: ").println(lpNumberOfFreeClusters.getValue());
// System.out.append('\t').append("TotalNumberOfClusters: ").println(lpTotalNumberOfClusters.getValue());

DWORD freeSize = lpNumberOfFreeClusters.getValue();
assertTrue("No free clusters for " + lpRootPathName, freeSize.longValue() > 0L);

DWORD totalSize = lpTotalNumberOfClusters.getValue();
assertTrue("Free clusters (" + freeSize + ") not below total (" + totalSize + ") for " + lpRootPathName, freeSize.longValue() < totalSize.longValue());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@
*/
package com.sun.jna.platform.win32;

import java.nio.ByteBuffer;
import java.util.Arrays;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
Expand Down Expand Up @@ -71,94 +70,92 @@ public void testNamedPipeServerAPI() {

@Test
public void testMultiThreadedNamedPipe() {
final String pipeName="\\\\.\\pipe\\" + getCurrentTestName();
final Logger logger=Logger.getLogger(getClass().getName());
final int MAX_BUFFER_SIZE=1024;
ExecutorService executors=Executors.newFixedThreadPool(2);
final String pipeName = "\\\\.\\pipe\\" + getCurrentTestName();
final Logger logger = Logger.getLogger(getClass().getName());
final int MAX_BUFFER_SIZE=1024;
ExecutorService executors = Executors.newFixedThreadPool(2);
try {
Future<?> server=executors.submit(new Runnable() {
Future<?> server = executors.submit(new Runnable() {
@Override
public void run() {
// based on https://msdn.microsoft.com/en-us/library/windows/desktop/aa365588(v=vs.85).aspx
HANDLE hNamedPipe=Kernel32.INSTANCE.CreateNamedPipe(pipeName,
HANDLE hNamedPipe = assertValidHandle("CreateNamedPipe", Kernel32.INSTANCE.CreateNamedPipe(pipeName,
WinBase.PIPE_ACCESS_DUPLEX, // dwOpenMode
WinBase.PIPE_TYPE_MESSAGE | WinBase.PIPE_READMODE_MESSAGE | WinBase.PIPE_WAIT, // dwPipeMode
1, // nMaxInstances,
MAX_BUFFER_SIZE, // nOutBufferSize,
MAX_BUFFER_SIZE, // nInBufferSize,
(int) TimeUnit.SECONDS.toMillis(30L), // nDefaultTimeOut,
null); // lpSecurityAttributes
assertCallSucceeded("CreateNamedPipe", !WinBase.INVALID_HANDLE_VALUE.equals(hNamedPipe));
null // lpSecurityAttributes
));

try {
logger.info("Await client connection");
assertCallSucceeded("ConnectNamedPipe", Kernel32.INSTANCE.ConnectNamedPipe(hNamedPipe, null));
logger.info("Client connected");
ByteBuffer readBuffer=ByteBuffer.allocate(MAX_BUFFER_SIZE);
IntByReference lpNumberOfBytesRead=new IntByReference(0);
assertCallSucceeded("ReadFile", Kernel32.INSTANCE.ReadFile(hNamedPipe, readBuffer, MAX_BUFFER_SIZE, lpNumberOfBytesRead, null));
int readSize=lpNumberOfBytesRead.getValue();

byte[] readBuffer = new byte[MAX_BUFFER_SIZE];
IntByReference lpNumberOfBytesRead = new IntByReference(0);
assertCallSucceeded("ReadFile", Kernel32.INSTANCE.ReadFile(hNamedPipe, readBuffer, readBuffer.length, lpNumberOfBytesRead, null));

int readSize = lpNumberOfBytesRead.getValue();
logger.info("Received client data - length=" + readSize);
assertTrue("No data receieved from client", readSize > 0);

byte[] writeBuffer=new byte[readSize];
readBuffer.get(writeBuffer);

IntByReference lpNumberOfBytesWritten=new IntByReference(0);
assertCallSucceeded("WriteFile", Kernel32.INSTANCE.WriteFile(hNamedPipe, writeBuffer, readSize, lpNumberOfBytesWritten, null));

IntByReference lpNumberOfBytesWritten = new IntByReference(0);
assertCallSucceeded("WriteFile", Kernel32.INSTANCE.WriteFile(hNamedPipe, readBuffer, readSize, lpNumberOfBytesWritten, null));
logger.info("Echoed client data - length=" + lpNumberOfBytesWritten.getValue());
assertEquals("Mismatched write buffer size", readSize, lpNumberOfBytesWritten.getValue());

// Flush the pipe to allow the client to read the pipe's contents before disconnecting
assertCallSucceeded("FlushFileBuffers", Kernel32.INSTANCE.FlushFileBuffers(hNamedPipe));
logger.info("Disconnecting");
assertCallSucceeded("DisconnectNamedPipe", Kernel32.INSTANCE.DisconnectNamedPipe(hNamedPipe));
logger.info("Disconnected");
logger.info("Disconnecting");
assertCallSucceeded("DisconnectNamedPipe", Kernel32.INSTANCE.DisconnectNamedPipe(hNamedPipe));
logger.info("Disconnected");
} finally { // clean up
assertCallSucceeded("Named pipe handle close", Kernel32.INSTANCE.CloseHandle(hNamedPipe));
}
}
});
logger.info("Started server - handle=" + server);

Future<?> client=executors.submit(new Runnable() {
Future<?> client = executors.submit(new Runnable() {
@Override
public void run() {
// based on https://msdn.microsoft.com/en-us/library/windows/desktop/aa365592(v=vs.85).aspx
assertCallSucceeded("WaitNamedPipe", Kernel32.INSTANCE.WaitNamedPipe(pipeName, (int) TimeUnit.SECONDS.toMillis(15L)));
logger.info("Connected to server");

HANDLE hPipe=Kernel32.INSTANCE.CreateFile(pipeName,
WinNT.GENERIC_READ | WinNT.GENERIC_WRITE,
0, // no sharing
HANDLE hPipe = assertValidHandle("CreateNamedPipe", Kernel32.INSTANCE.CreateFile(pipeName,
WinNT.GENERIC_READ | WinNT.GENERIC_WRITE,
0, // no sharing
null, // default security attributes
WinNT.OPEN_EXISTING, // opens existing pipe
0, // default attributes
null); // no template file
assertCallSucceeded("CreateNamedPipe", !WinBase.INVALID_HANDLE_VALUE.equals(hPipe));
WinNT.OPEN_EXISTING, // opens existing pipe
0, // default attributes
null // no template file
));

try {
IntByReference lpMode=new IntByReference(WinBase.PIPE_READMODE_MESSAGE);
IntByReference lpMode = new IntByReference(WinBase.PIPE_READMODE_MESSAGE);
assertCallSucceeded("SetNamedPipeHandleState", Kernel32.INSTANCE.SetNamedPipeHandleState(hPipe, lpMode, null, null));
String expMessage=Thread.currentThread().getName() + " says hello";
byte[] expData=expMessage.getBytes();
IntByReference lpNumberOfBytesWritten=new IntByReference(0);

String expMessage = Thread.currentThread().getName() + " says hello";
byte[] expData = expMessage.getBytes();
IntByReference lpNumberOfBytesWritten = new IntByReference(0);
assertCallSucceeded("WriteFile", Kernel32.INSTANCE.WriteFile(hPipe, expData, expData.length, lpNumberOfBytesWritten, null));
logger.info("Sent hello message");
assertEquals("Mismatched write buffer size", expData.length, lpNumberOfBytesWritten.getValue());

ByteBuffer readBuffer=ByteBuffer.allocate(MAX_BUFFER_SIZE);
IntByReference lpNumberOfBytesRead=new IntByReference(0);
assertCallSucceeded("ReadFile", Kernel32.INSTANCE.ReadFile(hPipe, readBuffer, MAX_BUFFER_SIZE, lpNumberOfBytesRead, null));

int readSize=lpNumberOfBytesRead.getValue();
byte[] readBuffer = new byte[MAX_BUFFER_SIZE];
IntByReference lpNumberOfBytesRead = new IntByReference(0);
assertCallSucceeded("ReadFile", Kernel32.INSTANCE.ReadFile(hPipe, readBuffer, readBuffer.length, lpNumberOfBytesRead, null));

int readSize = lpNumberOfBytesRead.getValue();
logger.info("Received server data - length=" + readSize);
assertTrue("No data receieved from server", readSize > 0);

byte[] actData=new byte[readSize];
readBuffer.get(actData);
assertArrayEquals("Mismatched server data", expData, actData);
String actMessage = new String(readBuffer, 0, readSize);
assertEquals("Mismatched server data", expMessage, actMessage);
} finally { // clean up
assertCallSucceeded("Named pipe handle close", Kernel32.INSTANCE.CloseHandle(hPipe));
}
Expand Down
Loading

0 comments on commit 00e6184

Please sign in to comment.