diff --git a/src/main/c/Windows/Makefile b/src/main/c/Windows/Makefile index ae2dceb..d48f882 100644 --- a/src/main/c/Windows/Makefile +++ b/src/main/c/Windows/Makefile @@ -1,12 +1,16 @@ # Compiler tools, commands, and flags -COMPILE_X86 := i686-w64-mingw32-gcc -COMPILE_X64 := x86_64-w64-mingw32-gcc -COMPILE_ARM := armv7-w64-mingw32-gcc -COMPILE_ARM64 := aarch64-w64-mingw32-gcc -CFLAGS := -Os -flto -static-libgcc -mdll -mconsole -U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=0 -LDFLAGS := -Os -flto -static-libgcc -mconsole -shared -fuse-linker-plugin -s -INCLUDES := -I"$(JDK_HOME)/include" -I"$(JDK_HOME)/include/win32" -I"$(JDK_HOME)/include/linux" -I"$(JDK_HOME)/include/darwin" -I"$(JDK_HOME)/include/solaris" -LIBRARIES := -ladvapi32 -lsetupapi +COMPILE_X86 := x86-pc-windows-msvc-cl +COMPILE_X64 := x64-pc-windows-msvc-cl +COMPILE_ARM := aarch-pc-windows-msvc-cl +COMPILE_ARM64 := aarch64-pc-windows-msvc-cl +LINK_X86 := x86-pc-windows-msvc-link +LINK_X64 := x64-pc-windows-msvc-link +LINK_ARM := aarch-pc-windows-msvc-link +LINK_ARM64 := aarch64-pc-windows-msvc-link +CFLAGS := /c /O2 /GF /MT /EHsc /J /nologo /TC +LDFLAGS := /DLL /NOLOGO +INCLUDES := /I"$(JDK_HOME)/include" /I"$(JDK_HOME)/include/win32" /I"$(JDK_HOME)/include/linux" /I"$(JDK_HOME)/include/darwin" /I"$(JDK_HOME)/include/solaris" +LIBRARIES := advapi32.lib setupapi.lib DELETE := @rm MKDIR := @mkdir COPY := @cp @@ -35,7 +39,7 @@ OBJECTSarm64 := $(BUILD_DIR)/aarch64/SerialPort_Windows.o $(BUILD_DIR)/aa # Define phony and suffix rules .PHONY: all win32 win64 winarm winarm64 checkdirs clean .SUFFIXES: -.SUFFIXES: .cpp .c .o .class .java .h +.SUFFIXES: .c .o .class .java .h # Default build target not possible due to different architecture compilers all : win32 win64 winarm winarm64 @@ -69,13 +73,13 @@ $(JAVA_CLASS_DIR) : # Build rules for all libraries $(BUILD_DIR)/x86/$(LIBRARY_NAME) : $(JNI_HEADER) $(OBJECTSx86) - $(COMPILE_X86) $(LDFLAGS) -o $@ $(OBJECTSx86) $(LIBRARIES) + $(LINK_X86) $(LDFLAGS) /OUT:$@ $(OBJECTSx86) $(LIBRARIES) $(BUILD_DIR)/x86_64/$(LIBRARY_NAME) : $(JNI_HEADER) $(OBJECTSx64) - $(COMPILE_X64) $(LDFLAGS) -o $@ $(OBJECTSx64) $(LIBRARIES) + $(LINK_X64) $(LDFLAGS) /OUT:$@ $(OBJECTSx64) $(LIBRARIES) $(BUILD_DIR)/armv7/$(LIBRARY_NAME) : $(JNI_HEADER) $(OBJECTSarm) - $(COMPILE_ARM) $(LDFLAGS) -o $@ $(OBJECTSarm) $(LIBRARIES) + $(LINK_ARM) $(LDFLAGS) /OUT:$@ $(OBJECTSarm) $(LIBRARIES) $(BUILD_DIR)/aarch64/$(LIBRARY_NAME) : $(JNI_HEADER) $(OBJECTSarm64) - $(COMPILE_ARM64) $(LDFLAGS) -o $@ $(OBJECTSarm64) $(LIBRARIES) + $(LINK_ARM64) $(LDFLAGS) /OUT:$@ $(OBJECTSarm64) $(LIBRARIES) # Suffix rules to get from *.c -> *.o $(BUILD_DIR)/x86/%.o : %.c diff --git a/src/main/c/Windows/Makefile.native b/src/main/c/Windows/Makefile.native index f104fa5..4956b1c 100644 --- a/src/main/c/Windows/Makefile.native +++ b/src/main/c/Windows/Makefile.native @@ -11,21 +11,25 @@ MKDIR = @md COPY = @copy /y MOVE = @move /y PRINT = @echo -FULL_CLASS = com.fazecast.jSerialComm.SerialPort -JAVAC = "$(JDK_HOME)\bin\javac" -JFLAGS = -source 1.6 -target 1.6 -Xlint:-options + +# Java and resource definitions LIBRARY_NAME = jSerialComm.dll -SOURCES = SerialPort_Windows.c WindowsHelperFunctions.c -JAVA_SOURCE_DIR = ..\..\..\..\src\main\java\com\fazecast\jSerialComm +BUILD_DIR = ..\..\..\..\build RESOURCE_DIR = ..\..\..\..\src\main\resources\Windows -BUILD_DIR = ..\..\..\..\bin\Windows -JAVA_CLASS_DIR = $(BUILD_DIR)\..\com\fazecast\jSerialComm +JAVA_SOURCE_DIR = ..\..\..\..\src\main\java\com\fazecast\jSerialComm +FULL_CLASS = com.fazecast.jSerialComm.SerialPort +JAVA_CLASS_DIR = $(BUILD_DIR)\com\fazecast\jSerialComm +JNI_HEADER_FILE = com_fazecast_jSerialComm_SerialPort.h +JNI_HEADER = ..\$(JNI_HEADER_FILE) +JAVA_CLASS = $(JAVA_CLASS_DIR)\SerialPort.class +JFLAGS = -source 1.6 -target 1.6 -Xlint:-options +JAVAC = "$(JDK_HOME)\bin\javac" + +# Architecture-dependent library variables OBJECTSx86 = $(BUILD_DIR)\x86\SerialPort_Windows.obj $(BUILD_DIR)\x86\WindowsHelperFunctions.obj OBJECTSx86_64 = $(BUILD_DIR)\x86_64\SerialPort_Windows.obj $(BUILD_DIR)\x86_64\WindowsHelperFunctions.obj OBJECTSarmv7 = $(BUILD_DIR)\armv7\SerialPort_Windows.obj $(BUILD_DIR)\armv7\WindowsHelperFunctions.obj OBJECTSaarch64 = $(BUILD_DIR)\aarch64\SerialPort_Windows.obj $(BUILD_DIR)\aarch64\WindowsHelperFunctions.obj -JNI_HEADER = ..\com_fazecast_jSerialComm_SerialPort.h -JAVA_CLASS = $(JAVA_CLASS_DIR)\SerialPort.class # Define phony and suffix rules .PHONY: all win32 win64 winarm winarm64 checkdirs clean @@ -40,33 +44,27 @@ all : $(PRINT) NOTE: Before attempting to use this Makefile, make sure that you have called 'vcvarsall.bat' for your intended architecture. This file can normally be found in "C:\Program Files (x86)\Microsoft Visual Studio [version]\VC\". $(PRINT). $(PRINT) Example: To build 64-bit Windows libraries, you would call: - $(PRINT) C:\Program Files (x86)\Microsoft Visual Studio 12.0\VC\vcvarsall.bat x64 - $(PRINT) nmake win64 + $(PRINT) C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Auxiliary\Build\vcvarsall.bat x64 + $(PRINT) nmake -f Makefile.native win64 $(PRINT). -# Builds 32-bit Windows libraries +# Build architecture-specific Windows libraries win32 : $(BUILD_DIR)\x86 $(BUILD_DIR)\x86\$(LIBRARY_NAME) $(COPY) $(BUILD_DIR)\x86\*.dll $(RESOURCE_DIR)\x86 - $(DELETE) ..\*.h - $(RMDIR) $(BUILD_DIR)\.. - -# Builds 64-bit Windows libraries + $(DELETE) ..\*.h $(JNI_HEADER_FILE) + $(RMDIR) $(BUILD_DIR) win64 : $(BUILD_DIR)\x86_64 $(BUILD_DIR)\x86_64\$(LIBRARY_NAME) $(COPY) $(BUILD_DIR)\x86_64\*.dll $(RESOURCE_DIR)\x86_64 - $(DELETE) ..\*.h - $(RMDIR) $(BUILD_DIR)\.. - -# Builds armv7 Windows libraries + $(DELETE) ..\*.h $(JNI_HEADER_FILE) + $(RMDIR) $(BUILD_DIR) winarm : $(BUILD_DIR)\armv7 $(BUILD_DIR)\armv7\$(LIBRARY_NAME) $(COPY) $(BUILD_DIR)\armv7\*.dll $(RESOURCE_DIR)\armv7 - $(DELETE) ..\*.h - $(RMDIR) $(BUILD_DIR)\.. - -# Builds arm64 Windows libraries + $(DELETE) ..\*.h $(JNI_HEADER_FILE) + $(RMDIR) $(BUILD_DIR) winarm64 : $(BUILD_DIR)\aarch64 $(BUILD_DIR)\aarch64\$(LIBRARY_NAME) $(COPY) $(BUILD_DIR)\aarch64\*.dll $(RESOURCE_DIR)\aarch64 - $(DELETE) ..\*.h - $(RMDIR) $(BUILD_DIR)\.. + $(DELETE) ..\*.h $(JNI_HEADER_FILE) + $(RMDIR) $(BUILD_DIR) # Rule to create build directories $(BUILD_DIR)\x86 : @@ -78,19 +76,13 @@ $(BUILD_DIR)\armv7 : $(BUILD_DIR)\aarch64 : $(MKDIR) "$@" -# Rule to build 32-bit library +# Build rules for all libraries $(BUILD_DIR)\x86\$(LIBRARY_NAME) : $(JNI_HEADER) $(OBJECTSx86) $(LINK) $(LDFLAGS) /MACHINE:X86 /OUT:$@ $(OBJECTSx86) $(LIBRARIES) - -# Rule to build 64-bit library $(BUILD_DIR)\x86_64\$(LIBRARY_NAME) : $(JNI_HEADER) $(OBJECTSx86_64) $(LINK) $(LDFLAGS) /MACHINE:X64 /OUT:$@ $(OBJECTSx86_64) $(LIBRARIES) - -# Rule to build armv7 library $(BUILD_DIR)\armv7\$(LIBRARY_NAME) : $(JNI_HEADER) $(OBJECTSarmv7) $(LINK) $(LDFLAGS) /MACHINE:ARM /OUT:$@ $(OBJECTSarmv7) $(LIBRARIES) - -# Rule to build arm64 library $(BUILD_DIR)\aarch64\$(LIBRARY_NAME) : $(JNI_HEADER) $(OBJECTSaarch64) $(LINK) $(LDFLAGS) /MACHINE:ARM64 /OUT:$@ $(OBJECTSaarch64) $(LIBRARIES) @@ -106,6 +98,7 @@ $(OBJECTSaarch64) : # Rule to build JNI header file $(JNI_HEADER) : $(JAVA_CLASS) + $(COPY) $@ .\ # Suffix rule to get from *.java -> *.class $(JAVA_CLASS) : diff --git a/src/main/c/Windows/SerialPort_Windows.c b/src/main/c/Windows/SerialPort_Windows.c index 91dcffc..b899aa6 100644 --- a/src/main/c/Windows/SerialPort_Windows.c +++ b/src/main/c/Windows/SerialPort_Windows.c @@ -2,7 +2,7 @@ * SerialPort_Windows.c * * Created on: Feb 25, 2012 - * Last Updated on: Jan 04, 2022 + * Last Updated on: Jan 06, 2022 * Author: Will Hedgecock * * Copyright (C) 2012-2022 Fazecast, Inc. @@ -121,14 +121,16 @@ JNIEXPORT jobjectArray JNICALL Java_com_fazecast_jSerialComm_SerialPort_getCommP if (!SetupDiGetDevicePropertyW(devList, &devInfoData, &DEVPKEY_Device_FriendlyName, &devInfoPropType, (BYTE*)friendlyNameString, friendlyNameLength, NULL, 0) && !SetupDiGetDeviceRegistryPropertyW(devList, &devInfoData, SPDRP_FRIENDLYNAME, NULL, (BYTE*)friendlyNameString, friendlyNameLength, NULL)) { + friendlyNameLength = comPortLength; friendlyNameString = (wchar_t*)realloc(friendlyNameString, comPortLength); - wcscpy(friendlyNameString, comPortString); + wcscpy_s(friendlyNameString, comPortLength / sizeof(wchar_t), comPortString); } } else { + friendlyNameLength = comPortLength; friendlyNameString = (wchar_t*)malloc(comPortLength); - wcscpy(friendlyNameString, comPortString); + wcscpy_s(friendlyNameString, comPortLength / sizeof(wchar_t), comPortString); } // Fetch the bus-reported device description @@ -141,13 +143,13 @@ JNIEXPORT jobjectArray JNICALL Java_com_fazecast_jSerialComm_SerialPort_getCommP if (!SetupDiGetDevicePropertyW(devList, &devInfoData, &DEVPKEY_Device_BusReportedDeviceDesc, &devInfoPropType, (BYTE*)portDescriptionString, portDescriptionLength, NULL, 0)) { portDescriptionString = (wchar_t*)realloc(portDescriptionString, friendlyNameLength); - wcscpy(portDescriptionString, friendlyNameString); + wcscpy_s(portDescriptionString, friendlyNameLength / sizeof(wchar_t), friendlyNameString); } } else { portDescriptionString = (wchar_t*)malloc(friendlyNameLength); - wcscpy(portDescriptionString, friendlyNameString); + wcscpy_s(portDescriptionString, friendlyNameLength / sizeof(wchar_t), friendlyNameString); } // Fetch the physical location for this device @@ -191,7 +193,7 @@ JNIEXPORT jobjectArray JNICALL Java_com_fazecast_jSerialComm_SerialPort_getCommP if (portNumber == -1) portNumber = 0; locationString = (wchar_t*)malloc(32*sizeof(wchar_t)); - _snwprintf(locationString, 32, L"%d-%d.%d", busNumber, hubNumber, portNumber); + _snwprintf_s(locationString, 32, 32, L"%d-%d.%d", busNumber, hubNumber, portNumber); // Check if port is already enumerated serialPort *port = fetchPort(&serialPorts, comPortString); @@ -204,10 +206,10 @@ JNIEXPORT jobjectArray JNICALL Java_com_fazecast_jSerialComm_SerialPort_getCommP if (oldLength != newLength) { port->portLocation = (wchar_t*)realloc(port->portLocation, (1 + newLength) * sizeof(wchar_t)); - wcscpy(port->portLocation, locationString); + wcscpy_s(port->portLocation, 32, locationString); } else if (wcscmp(port->portLocation, locationString)) - wcscpy(port->portLocation, locationString); + wcscpy_s(port->portLocation, 32, locationString); } else pushBack(&serialPorts, comPortString, friendlyNameString, portDescriptionString, locationString); @@ -302,8 +304,8 @@ JNIEXPORT jobjectArray JNICALL Java_com_fazecast_jSerialComm_SerialPort_getCommP { // Create new SerialComm object containing the enumerated values jobject serialCommObject = (*env)->NewObject(env, serialCommClass, serialCommConstructor); - wcscpy(comPort, L"\\\\.\\"); - wcscat(comPort, serialPorts.ports[i]->portPath); + wcscpy_s(comPort, sizeof(comPort) / sizeof(wchar_t), L"\\\\.\\"); + wcscat_s(comPort, sizeof(comPort) / sizeof(wchar_t), serialPorts.ports[i]->portPath); (*env)->SetObjectField(env, serialCommObject, comPortField, (*env)->NewString(env, (jchar*)comPort, wcslen(comPort))); (*env)->SetObjectField(env, serialCommObject, friendlyNameField, (*env)->NewString(env, (jchar*)serialPorts.ports[i]->friendlyName, wcslen(serialPorts.ports[i]->friendlyName))); (*env)->SetObjectField(env, serialCommObject, portDescriptionField, (*env)->NewString(env, (jchar*)serialPorts.ports[i]->portDescription, wcslen(serialPorts.ports[i]->portDescription))); diff --git a/src/main/c/Windows/WindowsHelperFunctions.c b/src/main/c/Windows/WindowsHelperFunctions.c index 00dec3c..7e4ef04 100644 --- a/src/main/c/Windows/WindowsHelperFunctions.c +++ b/src/main/c/Windows/WindowsHelperFunctions.c @@ -2,10 +2,10 @@ * WindowsHelperFunctions.c * * Created on: May 05, 2015 - * Last Updated on: Dec 16, 2021 + * Last Updated on: Jan 06, 2022 * Author: Will Hedgecock * - * Copyright (C) 2012-2021 Fazecast, Inc. + * Copyright (C) 2012-2022 Fazecast, Inc. * * This file is part of jSerialComm. * @@ -59,10 +59,10 @@ serialPort* pushBack(serialPortVector* vector, const wchar_t* key, const wchar_t port->portDescription = (wchar_t*)malloc((wcslen(description)+1)*sizeof(wchar_t)); // Store port strings - wcscpy(port->portPath, key); - wcscpy(port->portLocation, location); - wcscpy(port->friendlyName, friendlyName); - wcscpy(port->portDescription, description); + wcscpy_s(port->portPath, wcslen(key)+1, key); + wcscpy_s(port->portLocation, wcslen(location)+1, location); + wcscpy_s(port->friendlyName, wcslen(friendlyName)+1, friendlyName); + wcscpy_s(port->portDescription, wcslen(description)+1, description); // Return the newly created serial port structure return port; diff --git a/src/main/resources/Windows/aarch64/jSerialComm.dll b/src/main/resources/Windows/aarch64/jSerialComm.dll index 8307839..3a1bd7c 100644 Binary files a/src/main/resources/Windows/aarch64/jSerialComm.dll and b/src/main/resources/Windows/aarch64/jSerialComm.dll differ diff --git a/src/main/resources/Windows/armv7/jSerialComm.dll b/src/main/resources/Windows/armv7/jSerialComm.dll index a183b72..b7bc90a 100644 Binary files a/src/main/resources/Windows/armv7/jSerialComm.dll and b/src/main/resources/Windows/armv7/jSerialComm.dll differ diff --git a/src/main/resources/Windows/x86/jSerialComm.dll b/src/main/resources/Windows/x86/jSerialComm.dll index 4fd98f1..891e0c2 100644 Binary files a/src/main/resources/Windows/x86/jSerialComm.dll and b/src/main/resources/Windows/x86/jSerialComm.dll differ diff --git a/src/main/resources/Windows/x86_64/jSerialComm.dll b/src/main/resources/Windows/x86_64/jSerialComm.dll index 10f57cf..e3910bb 100644 Binary files a/src/main/resources/Windows/x86_64/jSerialComm.dll and b/src/main/resources/Windows/x86_64/jSerialComm.dll differ diff --git a/src/test/java/com/fazecast/jSerialComm/SerialPortTest.java b/src/test/java/com/fazecast/jSerialComm/SerialPortTest.java index 5fee106..1d3ca86 100644 --- a/src/test/java/com/fazecast/jSerialComm/SerialPortTest.java +++ b/src/test/java/com/fazecast/jSerialComm/SerialPortTest.java @@ -88,7 +88,7 @@ public class SerialPortTest System.out.println("\nAvailable Ports:\n"); for (int i = 0; i < ports.length; ++i) System.out.println(" [" + i + "] " + ports[i].getSystemPortName() + ": " + ports[i].getDescriptivePortName() + " - " + ports[i].getPortDescription() + " @ " + ports[i].getPortLocation()); - System.out.println("Re-enumerating ports again in 2 seconds...\n"); + System.out.println("\nRe-enumerating ports again in 2 seconds...\n"); try { Thread.sleep(2000); } catch (Exception e) {} ports = SerialPort.getCommPorts(); System.out.println("Available Ports:\n");