diff -pruN 0.11.2-1/.appveyor.yml 0.12.0-1/.appveyor.yml
--- 0.11.2-1/.appveyor.yml	2022-01-03 12:53:10.000000000 +0000
+++ 0.12.0-1/.appveyor.yml	2022-05-25 12:52:59.000000000 +0000
@@ -8,26 +8,22 @@ environment:
     arch: Win32
   - BUILD_ENV: cygwin
 
-install:
-  - cmd: if %BUILD_ENV%==cygwin (
-        C:\cygwin64\setup-x86_64.exe --quiet-mode --no-shortcuts --upgrade-also --packages autoconf,automake )
+for:
+  -
+    matrix:
+      only:
+        - BUILD_ENV: msbuild
 
-build_script:
-  - cmd: if %BUILD_ENV%==msbuild (
-        msbuild .\windows\hidapi.sln /p:Configuration=Release /p:Platform=%arch% /logger:"C:\Program Files\AppVeyor\BuildAgent\Appveyor.MSBuildLogger.dll" )
-  - cmd: if %BUILD_ENV%==cygwin (
-        C:\cygwin64\bin\bash -exlc "cd $APPVEYOR_BUILD_FOLDER; ./bootstrap; ./configure; make" )
+    build_script:
+      - cmd: msbuild .\windows\hidapi.sln /p:Configuration=Release /p:Platform=%arch% /logger:"C:\Program Files\AppVeyor\BuildAgent\Appveyor.MSBuildLogger.dll"
 
-artifacts:
-  # Win32 artifacts
-  - path: .\windows\Release\hidapi.dll
-  - path: .\windows\Release\hidapi.lib
-  - path: .\windows\Release\hidapi.pdb
-  - path: .\windows\Release\hidtest.exe
-  - path: .\windows\Release\hidtest.pdb
-  # x64 artifacts
-  - path: .\windows\x64\Release\hidapi.dll
-  - path: .\windows\x64\Release\hidapi.lib
-  - path: .\windows\x64\Release\hidapi.pdb
-  - path: .\windows\x64\Release\hidtest.exe
-  - path: .\windows\x64\Release\hidtest.pdb
+  -
+    matrix:
+      only:
+        - BUILD_ENV: cygwin
+
+    install:
+      - cmd: C:\cygwin64\setup-x86_64.exe --quiet-mode --no-shortcuts --upgrade-also --packages autoconf,automake
+
+    build_script:
+      - cmd: C:\cygwin64\bin\bash -exlc "cd $APPVEYOR_BUILD_FOLDER; ./bootstrap; ./configure; make"
diff -pruN 0.11.2-1/BUILD.md 0.12.0-1/BUILD.md
--- 0.11.2-1/BUILD.md	2022-01-03 12:53:10.000000000 +0000
+++ 0.12.0-1/BUILD.md	2022-05-25 12:52:59.000000000 +0000
@@ -8,7 +8,7 @@
     * [FreeBSD](#freebsd)
     * [Mac](#mac)
     * [Windows](#windows)
-* [Integrating hidapi directly into your source tree](#integrating-hidapi-directly-into-your-source-tree)
+* [Embedding HIDAPI directly into your source tree](#embedding-hidapi-directly-into-your-source-tree)
 * [Building the manual way on Unix platforms](#building-the-manual-way-on-unix-platforms)
 * [Building on Windows](#building-on-windows)
 
@@ -68,19 +68,30 @@ On Mac make sure you have XCode installe
 On Windows you just need a compiler. You may use Visual Studio or Cygwin/MinGW,
 depending on which environment is best for your needs.
 
-## Integrating HIDAPI directly into your source tree
+## Embedding HIDAPI directly into your source tree
 
-Instead of using one of the provided build systems, you may want to integrate
-HIDAPI directly into your source tree.
-Generally it is not encouraged to do so, but if you must, all you need to do:
-- add a single source file `hid.c` (for a specific backend);
-- setup include directory to `<HIDAPI repo root>/hidapi`;
-- add link libraries, that are specific for each backend.
+Instead of using one of the provided standalone build systems,
+you may want to integrate HIDAPI directly into your source tree.
 
-Check the manual makefiles for a simple example/reference of what are the dependencies of each specific backend.
+---
+If your project uses CMake as a build system, it is safe to add HIDAPI as a [subdirectory](BUILD.cmake.md#hidapi-as-a-subdirectory).
+
+---
+If _the only option_ that works for you is adding HIDAPI sources directly
+to your project's build system, then you need:
+- include a _single source file_ into your project's build system,
+depending on your platform and the backend you want to use:
+    - [`windows\hid.c`](windows/hid.c);
+    - [`linux/hid.c`](linux/hid.c);
+    - [`libusb/hid.c`](libusb/hid.c);
+    - [`mac/hid.c`](mac/hid.c);
+- add a [`hidapi`](hidapi) folder to the include path when building `hid.c`;
+- make the platform/backend specific [dependencies](#prerequisites) available during the compilation/linking, when building `hid.c`;
 
-NOTE: if your have a CMake-based project, you're likely be able to use
-HIDAPI directly as a subdirectory. Check [BUILD.cmake.md](BUILD.cmake.md) for details.
+NOTE: the above doesn't guarantee that having a copy of `<backend>/hid.c` and `hidapi/hidapi.h` is enough to build HIDAPI.
+The only guarantee that `<backend>/hid.c` includes all nesessary sources to compile it as a single file.
+
+Check the manual makefiles for a simple example/reference of what are the dependencies of each specific backend.
 
 ## Building the manual way on Unix platforms
 
@@ -106,5 +117,5 @@ To build HIDAPI using MinGW or Cygwin us
 
 Any windows builds (MSVC or MinGW/Cygwin) are also supported by [CMake](BUILD.cmake.md).
 
-If you are looking for information regarding DDK build of HIDAPI
+If you are looking for information regarding DDK build of HIDAPI:
 - the build has been broken for a while and now the support files are obsolete.
diff -pruN 0.11.2-1/.builds/netbsd.yml 0.12.0-1/.builds/netbsd.yml
--- 0.11.2-1/.builds/netbsd.yml	1970-01-01 00:00:00.000000000 +0000
+++ 0.12.0-1/.builds/netbsd.yml	2022-05-25 12:52:59.000000000 +0000
@@ -0,0 +1,18 @@
+image: netbsd/latest
+packages:
+- cmake
+- pkgconf
+- libusb1
+- libiconv
+sources:
+- https://github.com/libusb/hidapi
+tasks:
+- setup: |
+    cd hidapi
+    mkdir -p build install
+    cmake -B build -S . -DCMAKE_INSTALL_PREFIX=install
+- build: |
+    cd hidapi/build
+    make
+    make install
+    make clean
diff -pruN 0.11.2-1/configure.ac 0.12.0-1/configure.ac
--- 0.11.2-1/configure.ac	2022-01-03 12:53:10.000000000 +0000
+++ 0.12.0-1/configure.ac	2022-05-25 12:52:59.000000000 +0000
@@ -153,7 +153,7 @@ if test "x$os" = xwindows; then
 	AC_DEFINE(OS_WINDOWS, 1, [Windows implementations])
 	AC_SUBST(OS_WINDOWS)
 	LDFLAGS="${LDFLAGS} -no-undefined"
-	LIBS="${LIBS} -lsetupapi"
+	LIBS="${LIBS}"
 fi
 
 if test "x$threads" = xpthreads; then
diff -pruN 0.11.2-1/debian/changelog 0.12.0-1/debian/changelog
--- 0.11.2-1/debian/changelog	2022-02-15 00:17:50.000000000 +0000
+++ 0.12.0-1/debian/changelog	2022-08-03 03:21:16.000000000 +0000
@@ -1,3 +1,10 @@
+hidapi (0.12.0-1) unstable; urgency=medium
+
+  * Update to new upstream release 0.12.0
+  * Update Standards-Version to 4.6.1
+
+ -- Scott Talbert <swt@techie.net>  Tue, 02 Aug 2022 23:21:16 -0400
+
 hidapi (0.11.2-1) unstable; urgency=medium
 
   * Update to new upstream release 0.11.2
diff -pruN 0.11.2-1/debian/control 0.12.0-1/debian/control
--- 0.11.2-1/debian/control	2021-10-07 19:16:12.000000000 +0000
+++ 0.12.0-1/debian/control	2022-08-03 03:20:42.000000000 +0000
@@ -2,7 +2,7 @@ Source: hidapi
 Priority: optional
 Maintainer: Scott Talbert <swt@techie.net>
 Build-Depends: debhelper-compat (= 13), libudev-dev [linux-any], libusb-1.0-0-dev [linux-any], libusb2-dev (>= 10.0-4) [kfreebsd-any], pkg-config
-Standards-Version: 4.6.0
+Standards-Version: 4.6.1
 Section: libs
 Homepage: https://github.com/libusb/hidapi
 Vcs-Git: https://salsa.debian.org/debian/hidapi.git
diff -pruN 0.11.2-1/.github/workflows/builds.yml 0.12.0-1/.github/workflows/builds.yml
--- 0.11.2-1/.github/workflows/builds.yml	2022-01-03 12:53:10.000000000 +0000
+++ 0.12.0-1/.github/workflows/builds.yml	2022-05-25 12:52:59.000000000 +0000
@@ -2,6 +2,10 @@ name: GitHub Builds
 
 on: [push, pull_request]
 
+env:
+  NIX_COMPILE_FLAGS: -Wall -Wextra -pedantic -Werror
+  MSVC_COMPILE_FLAGS: /W4 /WX
+
 jobs:
   macos-automake:
 
@@ -36,8 +40,8 @@ jobs:
     - name: Configure CMake
       run: |
         rm -rf build install
-        cmake -B build/shared -S hidapisrc -DCMAKE_INSTALL_PREFIX=install/shared
-        cmake -B build/framework -S hidapisrc -DCMAKE_INSTALL_PREFIX=install/framework -DCMAKE_FRAMEWORK=ON
+        cmake -B build/shared -S hidapisrc -DCMAKE_INSTALL_PREFIX=install/shared -DHIDAPI_BUILD_HIDTEST=ON "-DCMAKE_C_FLAGS=${NIX_COMPILE_FLAGS}"
+        cmake -B build/framework -S hidapisrc -DCMAKE_INSTALL_PREFIX=install/framework -DCMAKE_FRAMEWORK=ON -DHIDAPI_BUILD_HIDTEST=ON "-DCMAKE_C_FLAGS=${NIX_COMPILE_FLAGS}"
     - name: Build CMake Shared
       working-directory: build/shared
       run: make install
@@ -49,8 +53,10 @@ jobs:
       with:
         files: "install/shared/lib/libhidapi.dylib, \
                 install/shared/include/hidapi/hidapi.h, \
+                install/shared/include/hidapi/hidapi_darwin.h, \
                 install/framework/lib/hidapi.framework/hidapi, \
-                install/framework/lib/hidapi.framework/Headers/hidapi.h"
+                install/framework/lib/hidapi.framework/Headers/hidapi.h, \
+                install/framework/lib/hidapi.framework/Headers/hidapi_darwin.h"
         allow_failure: true
 
   ubuntu-cmake:
@@ -68,8 +74,8 @@ jobs:
     - name: Configure CMake
       run: |
         rm -rf build install
-        cmake -B build/shared -S hidapisrc -DCMAKE_INSTALL_PREFIX=install/shared
-        cmake -B build/static -S hidapisrc -DCMAKE_INSTALL_PREFIX=install/static -DBUILD_SHARED_LIBS=FALSE
+        cmake -B build/shared -S hidapisrc -DCMAKE_INSTALL_PREFIX=install/shared -DHIDAPI_BUILD_HIDTEST=ON "-DCMAKE_C_FLAGS=${NIX_COMPILE_FLAGS}"
+        cmake -B build/static -S hidapisrc -DCMAKE_INSTALL_PREFIX=install/static -DBUILD_SHARED_LIBS=FALSE -DHIDAPI_BUILD_HIDTEST=ON "-DCMAKE_C_FLAGS=${NIX_COMPILE_FLAGS}"
     - name: Build CMake Shared
       working-directory: build/shared
       run: make install
@@ -89,7 +95,7 @@ jobs:
                 install/static/include/hidapi/hidapi_libusb.h"
         allow_failure: true
 
-  windows-cmake-msvc:
+  windows-cmake:
 
     runs-on: windows-latest
 
@@ -97,64 +103,91 @@ jobs:
     - uses: actions/checkout@v2
       with:
         path: hidapisrc
-    - name: Configure CMake
+    - name: Configure CMake MSVC
       shell: cmd
       run: |
-        RMDIR /Q /S build install
-        cmake -B build -S hidapisrc -DCMAKE_INSTALL_PREFIX=install
-    - name: Build CMake
-      working-directory: build
+        cmake -B build\msvc -S hidapisrc -DCMAKE_INSTALL_PREFIX=install\msvc -DHIDAPI_BUILD_HIDTEST=ON "-DCMAKE_C_FLAGS=%MSVC_COMPILE_FLAGS%"
+    - name: Build CMake MSVC
+      working-directory: build/msvc
       run: cmake --build . --target install
-    - name: Check artifacts
+    - name: Check artifacts MSVC
       uses: andstor/file-existence-action@v1
       with:
-        files: "install/lib/hidapi.lib, install/bin/hidapi.dll, install/include/hidapi/hidapi.h"
+        files: "install/msvc/lib/hidapi.lib, \
+                install/msvc/bin/hidapi.dll, \
+                install/msvc/include/hidapi/hidapi.h, \
+                install/msvc/include/hidapi/hidapi_winapi.h"
         allow_failure: true
 
-  windows-cmake-nmake:
-
-    runs-on: windows-latest
-
-    steps:
-    - uses: actions/checkout@v2
-      with:
-        path: hidapisrc
-    - name: Configure CMake
+    - name: Configure CMake NMake
       shell: cmd
       run: |
-        RMDIR /Q /S build install
-        call "C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\VC\Auxiliary\Build\vcvars64.bat"
-        cmake -G"NMake Makefiles" -B build -S hidapisrc -DCMAKE_INSTALL_PREFIX=install
-    - name: Build CMake
-      working-directory: build
+        call "C:\Program Files\Microsoft Visual Studio\2022\Enterprise\VC\Auxiliary\Build\vcvars64.bat"
+        cmake -G"NMake Makefiles" -B build\nmake -S hidapisrc -DCMAKE_INSTALL_PREFIX=install\nmake -DHIDAPI_BUILD_HIDTEST=ON "-DCMAKE_C_FLAGS=%MSVC_COMPILE_FLAGS%"
+    - name: Build CMake NMake
+      working-directory: build\nmake
       shell: cmd
       run: |
-        call "C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\VC\Auxiliary\Build\vcvars64.bat"
+        call "C:\Program Files\Microsoft Visual Studio\2022\Enterprise\VC\Auxiliary\Build\vcvars64.bat"
         nmake install
-    - name: Check artifacts
+    - name: Check artifacts NMake
+      uses: andstor/file-existence-action@v1
+      with:
+        files: "install/nmake/lib/hidapi.lib, \
+                install/nmake/bin/hidapi.dll, \
+                install/nmake/include/hidapi/hidapi.h, \
+                install/nmake/include/hidapi/hidapi_winapi.h"
+        allow_failure: true
+
+    - name: Configure CMake MinGW
+      shell: cmd
+      run: |
+        cmake -G"MinGW Makefiles" -B build\mingw -S hidapisrc -DCMAKE_INSTALL_PREFIX=install\mingw -DHIDAPI_BUILD_HIDTEST=ON "-DCMAKE_C_FLAGS=%NIX_COMPILE_FLAGS%"
+    - name: Build CMake MinGW
+      working-directory: build\mingw
+      run: cmake --build . --target install
+    - name: Check artifacts MinGW
       uses: andstor/file-existence-action@v1
       with:
-        files: "install/lib/hidapi.lib, install/bin/hidapi.dll, install/include/hidapi/hidapi.h"
+        files: "install/mingw/lib/libhidapi.dll.a, \
+                install/mingw/bin/libhidapi.dll, \
+                install/mingw/include/hidapi/hidapi.h, \
+                install/mingw/include/hidapi/hidapi_winapi.h"
         allow_failure: true
 
-  windows-cmake-mingw:
+  windows-msbuild:
 
     runs-on: windows-latest
 
     steps:
     - uses: actions/checkout@v2
+    - uses: microsoft/setup-msbuild@v1.1
+    - name: MSBuild x86
+      run: msbuild windows\hidapi.sln /p:Configuration=Release /p:Platform=Win32
+    - name: Check artifacts x86
+      uses: andstor/file-existence-action@v1
       with:
-        path: hidapisrc
-    - name: Configure CMake
-      shell: cmd
-      run: |
-        RMDIR /Q /S build install
-        cmake -G"MinGW Makefiles" -B build -S hidapisrc -DCMAKE_INSTALL_PREFIX=install
-    - name: Build CMake
-      working-directory: build
-      run: cmake --build . --target install
-    - name: Check artifacts
+        files: "windows/Release/hidapi.dll, windows/Release/hidapi.lib, windows/Release/hidapi.pdb"
+        allow_failure: true
+    - name: MSBuild x64
+      run: msbuild windows\hidapi.sln /p:Configuration=Release /p:Platform=x64
+    - name: Check artifacts x64
       uses: andstor/file-existence-action@v1
       with:
-        files: "install/lib/libhidapi.dll.a, install/bin/libhidapi.dll, install/include/hidapi/hidapi.h"
+        files: "windows/x64/Release/hidapi.dll, windows/x64/Release/hidapi.lib, windows/x64/Release/hidapi.pdb"
         allow_failure: true
+    - name: Gather artifacts
+      run: |
+        md artifacts
+        md artifacts\x86
+        md artifacts\x64
+        md artifacts\include
+        Copy-Item "windows\Release\hidapi.dll","windows\Release\hidapi.lib","windows\Release\hidapi.pdb" -Destination "artifacts\x86"
+        Copy-Item "windows\x64\Release\hidapi.dll","windows\x64\Release\hidapi.lib","windows\x64\Release\hidapi.pdb" -Destination "artifacts\x64"
+        Copy-Item "hidapi\hidapi.h","windows\hidapi_winapi.h" -Destination "artifacts\include"
+    - name: Upload artifacts
+      uses: actions/upload-artifact@v3
+      with:
+        name: hidapi-win
+        path: artifacts/
+        retention-days: ${{ (github.event_name == 'pull_request' || github.ref_name != 'master') && 7 || 90 }}
diff -pruN 0.11.2-1/HACKING.txt 0.12.0-1/HACKING.txt
--- 0.11.2-1/HACKING.txt	2022-01-03 12:53:10.000000000 +0000
+++ 0.12.0-1/HACKING.txt	2022-05-25 12:52:59.000000000 +0000
@@ -8,3 +8,4 @@ Firing a new release:
 1. Update the Version (if not yet updated).
 2. Build hidapi.dll/.lib for x86/x64.
 3. Upload Windows binaries to Github release page.
+4. Make sure to tag the release as: `hidapi-<VERSION>`, where <VERSION> as in VERSION file.
diff -pruN 0.11.2-1/hidapi/hidapi.h 0.12.0-1/hidapi/hidapi.h
--- 0.11.2-1/hidapi/hidapi.h	2022-01-03 12:53:10.000000000 +0000
+++ 0.12.0-1/hidapi/hidapi.h	2022-05-25 12:52:59.000000000 +0000
@@ -5,9 +5,9 @@
  Alan Ott
  Signal 11 Software
 
- 8/22/2009
+ libusb/hidapi Team
 
- Copyright 2009, All Rights Reserved.
+ Copyright 2022, All Rights Reserved.
 
  At the discretion of the user of this library,
  this software may be licensed under the terms of the
@@ -48,18 +48,40 @@
 
 	@ingroup API
 */
-#define HID_API_VERSION_MINOR 11
+#define HID_API_VERSION_MINOR 12
 /** @brief Static/compile-time patch version of the library.
 
 	@ingroup API
 */
-#define HID_API_VERSION_PATCH 2
+#define HID_API_VERSION_PATCH 0
 
 /* Helper macros */
 #define HID_API_AS_STR_IMPL(x) #x
 #define HID_API_AS_STR(x) HID_API_AS_STR_IMPL(x)
 #define HID_API_TO_VERSION_STR(v1, v2, v3) HID_API_AS_STR(v1.v2.v3)
 
+/** @brief Coverts a version as Major/Minor/Patch into a number:
+	<8 bit major><16 bit minor><8 bit patch>.
+
+	This macro was added in version 0.12.0.
+
+	Convenient function to be used for compile-time checks, like:
+	#if HID_API_VERSION >= HID_API_MAKE_VERSION(0, 12, 0)
+
+	@ingroup API
+*/
+#define HID_API_MAKE_VERSION(mj, mn, p) (((mj) << 24) | ((mn) << 8) | (p))
+
+/** @brief Static/compile-time version of the library.
+
+	This macro was added in version 0.12.0.
+
+	@see @ref HID_API_MAKE_VERSION.
+
+	@ingroup API
+*/
+#define HID_API_VERSION HID_API_MAKE_VERSION(HID_API_VERSION_MAJOR, HID_API_VERSION_MINOR, HID_API_VERSION_PATCH)
+
 /** @brief Static/compile-time string version of the library.
 
 	@ingroup API
@@ -369,6 +391,8 @@ extern "C" {
 
 		/** @brief Get a input report from a HID device.
 
+			Since version 0.10.0, @ref HID_API_VERSION >= HID_API_MAKE_VERSION(0, 10, 0)
+
 			Set the first byte of @p data[] to the Report ID of the
 			report to be read. Make sure to allow space for this
 			extra byte in @p data[]. Upon return, the first byte will
diff -pruN 0.11.2-1/hidtest/CMakeLists.txt 0.12.0-1/hidtest/CMakeLists.txt
--- 0.11.2-1/hidtest/CMakeLists.txt	2022-01-03 12:53:10.000000000 +0000
+++ 0.12.0-1/hidtest/CMakeLists.txt	2022-05-25 12:52:59.000000000 +0000
@@ -9,6 +9,7 @@ if(NOT WIN32 AND NOT APPLE AND CMAKE_SYS
     endif()
     if(TARGET hidapi::libusb)
         add_executable(hidtest_libusb test.c)
+        target_compile_definitions(hidtest_libusb PRIVATE USING_HIDAPI_LIBUSB)
         target_link_libraries(hidtest_libusb hidapi::libusb)
         list(APPEND HIDAPI_HIDTEST_TARGETS hidtest_libusb)
     endif()
diff -pruN 0.11.2-1/hidtest/Makefile.am 0.12.0-1/hidtest/Makefile.am
--- 0.11.2-1/hidtest/Makefile.am	2022-01-03 12:53:10.000000000 +0000
+++ 0.12.0-1/hidtest/Makefile.am	2022-05-25 12:52:59.000000000 +0000
@@ -18,3 +18,11 @@ hidtest_SOURCES = test.c
 hidtest_LDADD = $(top_builddir)/$(backend)/libhidapi.la
 
 endif
+
+if OS_DARWIN
+AM_CPPFLAGS += -I$(top_srcdir)/mac/
+endif
+
+if OS_WINDOWS
+AM_CPPFLAGS += -I$(top_srcdir)/windows/
+endif
diff -pruN 0.11.2-1/hidtest/test.c 0.12.0-1/hidtest/test.c
--- 0.11.2-1/hidtest/test.c	2022-01-03 12:53:10.000000000 +0000
+++ 0.12.0-1/hidtest/test.c	2022-05-25 12:52:59.000000000 +0000
@@ -28,6 +28,29 @@
 	#include <unistd.h>
 #endif
 
+// Fallback/example
+#ifndef HID_API_MAKE_VERSION
+#define HID_API_MAKE_VERSION(mj, mn, p) (((mj) << 24) | ((mn) << 8) | (p))
+#endif
+#ifndef HID_API_VERSION
+#define HID_API_VERSION HID_API_MAKE_VERSION(HID_API_VERSION_MAJOR, HID_API_VERSION_MINOR, HID_API_VERSION_PATCH)
+#endif
+
+//
+// Sample using platform-specific headers
+#if defined(__APPLE__) && HID_API_VERSION >= HID_API_MAKE_VERSION(0, 12, 0)
+#include <hidapi_darwin.h>
+#endif
+
+#if defined(_WIN32) && HID_API_VERSION >= HID_API_MAKE_VERSION(0, 12, 0)
+#include <hidapi_winapi.h>
+#endif
+
+#if defined(USING_HIDAPI_LIBUSB) && HID_API_VERSION >= HID_API_MAKE_VERSION(0, 12, 0)
+#include <hidapi_libusb.h>
+#endif
+//
+
 int main(int argc, char* argv[])
 {
 	(void)argc;
@@ -43,7 +66,7 @@ int main(int argc, char* argv[])
 	struct hid_device_info *devs, *cur_dev;
 
 	printf("hidapi test/example tool. Compiled with hidapi version %s, runtime version %s.\n", HID_API_VERSION_STR, hid_version_str());
-	if (hid_version()->major == HID_API_VERSION_MAJOR && hid_version()->minor == HID_API_VERSION_MINOR && hid_version()->patch == HID_API_VERSION_PATCH) {
+	if (HID_API_VERSION == HID_API_MAKE_VERSION(hid_version()->major, hid_version()->minor, hid_version()->patch)) {
 		printf("Compile-time version matches runtime version of hidapi.\n\n");
 	}
 	else {
@@ -53,6 +76,12 @@ int main(int argc, char* argv[])
 	if (hid_init())
 		return -1;
 
+#if defined(__APPLE__) && HID_API_VERSION >= HID_API_MAKE_VERSION(0, 12, 0)
+	// To work properly needs to be called before hid_open/hid_open_path after hid_init.
+	// Best/recommended option - call it right after hid_init.
+	hid_darwin_set_open_exclusive(0);
+#endif
+
 	devs = hid_enumerate(0x0, 0x0);
 	cur_dev = devs;
 	while (cur_dev) {
@@ -143,7 +172,7 @@ int main(int argc, char* argv[])
 		// Print out the returned buffer.
 		printf("Feature Report\n   ");
 		for (i = 0; i < res; i++)
-			printf("%02hhx ", buf[i]);
+			printf("%02x ", (unsigned int) buf[i]);
 		printf("\n");
 	}
 
@@ -186,7 +215,7 @@ int main(int argc, char* argv[])
 	printf("Data read:\n   ");
 	// Print out the returned buffer.
 	for (i = 0; i < res; i++)
-		printf("%02hhx ", buf[i]);
+		printf("%02x ", (unsigned int) buf[i]);
 	printf("\n");
 
 	hid_close(handle);
diff -pruN 0.11.2-1/libusb/CMakeLists.txt 0.12.0-1/libusb/CMakeLists.txt
--- 0.11.2-1/libusb/CMakeLists.txt	2022-01-03 12:53:10.000000000 +0000
+++ 0.12.0-1/libusb/CMakeLists.txt	2022-05-25 12:52:59.000000000 +0000
@@ -19,6 +19,29 @@ endif()
 find_package(Threads REQUIRED)
 target_link_libraries(hidapi_libusb PRIVATE Threads::Threads)
 
+if(HIDAPI_NO_ICONV)
+    target_compile_definitions(hidapi_libusb PRIVATE NO_ICONV)
+else()
+    if(NOT ANDROID AND NOT CMAKE_VERSION VERSION_LESS 3.11)
+        find_package(Iconv REQUIRED)
+        include(CheckCSourceCompiles)
+        target_link_libraries(hidapi_libusb PRIVATE Iconv::Iconv)
+        set(CMAKE_REQUIRED_LIBRARIES "Iconv::Iconv")
+        # check for error: "conflicting types for 'iconv'"
+        check_c_source_compiles("#include<iconv.h>
+            extern size_t iconv (iconv_t cd, const char **inbuf, size_t *inbytesleft, char **outbuf, size_t *outbytesleft);
+            int main() {}"
+        HIDAPI_ICONV_CONST)
+        if(HIDAPI_ICONV_CONST)
+            target_compile_definitions(hidapi_libusb PRIVATE "ICONV_CONST=const")
+        endif()
+    endif()
+    # otherwise there is 3 options:
+    # 1) On Android Iconv is disabled on the code level anyway, so no issue;
+    # 2) iconv is provided by Standard C library and the build will be just fine;
+    # 4) The _user_ has to provide additiona compilation options for this project/target.
+endif()
+
 set_target_properties(hidapi_libusb
     PROPERTIES
         EXPORT_NAME "libusb"
diff -pruN 0.11.2-1/libusb/hidapi_libusb.h 0.12.0-1/libusb/hidapi_libusb.h
--- 0.11.2-1/libusb/hidapi_libusb.h	2022-01-03 12:53:10.000000000 +0000
+++ 0.12.0-1/libusb/hidapi_libusb.h	2022-05-25 12:52:59.000000000 +0000
@@ -19,6 +19,8 @@
 
 /** @file
  * @defgroup API hidapi API
+
+ * Since version 0.11.0, @ref HID_API_VERSION >= HID_API_MAKE_VERSION(0, 11, 0).
  */
 
 #ifndef HIDAPI_LIBUSB_H__
diff -pruN 0.11.2-1/libusb/hid.c 0.12.0-1/libusb/hid.c
--- 0.11.2-1/libusb/hid.c	2022-01-03 12:53:10.000000000 +0000
+++ 0.12.0-1/libusb/hid.c	2022-05-25 12:52:59.000000000 +0000
@@ -5,12 +5,9 @@
  Alan Ott
  Signal 11 Software
 
- 8/22/2009
- Linux Version - 6/2/2010
- Libusb Version - 8/13/2010
- FreeBSD Version - 11/1/2011
+ libusb/hidapi Team
 
- Copyright 2009, All Rights Reserved.
+ Copyright 2022, All Rights Reserved.
 
  At the discretion of the user of this library,
  this software may be licensed under the terms of the
@@ -47,6 +44,9 @@
 #include <libusb.h>
 #if !defined(__ANDROID__) && !defined(NO_ICONV)
 #include <iconv.h>
+#ifndef ICONV_CONST
+#define ICONV_CONST
+#endif
 #endif
 
 #include "hidapi_libusb.h"
@@ -408,7 +408,7 @@ static wchar_t *get_usb_string(libusb_de
 	size_t inbytes;
 	size_t outbytes;
 	size_t res;
-	char *inptr;
+	ICONV_CONST char *inptr;
 	char *outptr;
 #endif
 
@@ -424,7 +424,7 @@ static wchar_t *get_usb_string(libusb_de
 			lang,
 			(unsigned char*)buf,
 			sizeof(buf));
-	if (len < 0)
+	if (len < 2) /* we always skip first 2 bytes */
 		return NULL;
 
 #if defined(__ANDROID__) || defined(NO_ICONV)
@@ -1411,6 +1411,7 @@ void HID_API_EXPORT hid_close(hid_device
 
 	/* Clean up the Transfer objects allocated in read_thread(). */
 	free(dev->transfer->buffer);
+	dev->transfer->buffer = NULL;
 	libusb_free_transfer(dev->transfer);
 
 	/* release the interface */
diff -pruN 0.11.2-1/libusb/Makefile.freebsd 0.12.0-1/libusb/Makefile.freebsd
--- 0.11.2-1/libusb/Makefile.freebsd	2022-01-03 12:53:10.000000000 +0000
+++ 0.12.0-1/libusb/Makefile.freebsd	2022-05-25 12:52:59.000000000 +0000
@@ -15,7 +15,7 @@ CFLAGS   ?= -Wall -g -fPIC
 
 COBJS     = hid.o ../hidtest/test.o
 OBJS      = $(COBJS)
-INCLUDES  = -I../hidapi -I/usr/local/include
+INCLUDES  = -I../hidapi -I. -I/usr/local/include
 LDFLAGS   = -L/usr/local/lib
 LIBS      = -lusb -liconv -pthread
 
diff -pruN 0.11.2-1/libusb/Makefile.haiku 0.12.0-1/libusb/Makefile.haiku
--- 0.11.2-1/libusb/Makefile.haiku	2022-01-03 12:53:10.000000000 +0000
+++ 0.12.0-1/libusb/Makefile.haiku	2022-05-25 12:52:59.000000000 +0000
@@ -15,7 +15,7 @@ CFLAGS   ?= -Wall -g -fPIC
 
 COBJS     = hid.o ../hidtest/test.o
 OBJS      = $(COBJS)
-INCLUDES  = -I../hidapi -I/usr/local/include
+INCLUDES  = -I../hidapi -I. -I/usr/local/include
 LDFLAGS   = -L/usr/local/lib
 LIBS      = -lusb -liconv -pthread
 
diff -pruN 0.11.2-1/libusb/Makefile.linux 0.12.0-1/libusb/Makefile.linux
--- 0.11.2-1/libusb/Makefile.linux	2022-01-03 12:53:10.000000000 +0000
+++ 0.12.0-1/libusb/Makefile.linux	2022-05-25 12:52:59.000000000 +0000
@@ -20,7 +20,7 @@ COBJS = $(COBJS_LIBUSB) ../hidtest/test.
 OBJS      = $(COBJS)
 LIBS_USB  = `pkg-config libusb-1.0 --libs` -lrt -lpthread
 LIBS      = $(LIBS_USB)
-INCLUDES ?= -I../hidapi `pkg-config libusb-1.0 --cflags`
+INCLUDES ?= -I../hidapi -I. `pkg-config libusb-1.0 --cflags`
 
 
 # Console Test Program
diff -pruN 0.11.2-1/linux/hid.c 0.12.0-1/linux/hid.c
--- 0.11.2-1/linux/hid.c	2022-01-03 12:53:10.000000000 +0000
+++ 0.12.0-1/linux/hid.c	2022-05-25 12:52:59.000000000 +0000
@@ -5,10 +5,9 @@
  Alan Ott
  Signal 11 Software
 
- 8/22/2009
- Linux Version - 6/2/2009
+ libusb/hidapi Team
 
- Copyright 2009, All Rights Reserved.
+ Copyright 2022, All Rights Reserved.
 
  At the discretion of the user of this library,
  this software may be licensed under the terms of the
@@ -271,7 +270,7 @@ static int uses_numbered_reports(__u8 *r
 		if (!get_hid_item_size(report_descriptor, i, size, &data_len, &key_size))
 			return 0; /* malformed report */
 
-		/* Skip over this key and it's associated data */
+		/* Skip over this key and its associated data */
 		i += data_len + key_size;
 	}
 
@@ -368,7 +367,7 @@ static int get_next_hid_usage(__u8 *repo
 			break;
 		}
 
-		/* Skip over this key and it's associated data */
+		/* Skip over this key and its associated data */
 		*pos += data_len + key_size;
 
 		/* Return usage pair */
diff -pruN 0.11.2-1/mac/CMakeLists.txt 0.12.0-1/mac/CMakeLists.txt
--- 0.11.2-1/mac/CMakeLists.txt	2022-01-03 12:53:10.000000000 +0000
+++ 0.12.0-1/mac/CMakeLists.txt	2022-05-25 12:52:59.000000000 +0000
@@ -1,5 +1,7 @@
 cmake_minimum_required(VERSION 3.4.3 FATAL_ERROR)
 
+list(APPEND HIDAPI_PUBLIC_HEADERS "hidapi_darwin.h")
+
 add_library(hidapi_darwin
     ${HIDAPI_PUBLIC_HEADERS}
     hid.c
diff -pruN 0.11.2-1/mac/hidapi_darwin.h 0.12.0-1/mac/hidapi_darwin.h
--- 0.11.2-1/mac/hidapi_darwin.h	1970-01-01 00:00:00.000000000 +0000
+++ 0.12.0-1/mac/hidapi_darwin.h	2022-05-25 12:52:59.000000000 +0000
@@ -0,0 +1,98 @@
+/*******************************************************
+ HIDAPI - Multi-Platform library for
+ communication with HID devices.
+
+ libusb/hidapi Team
+
+ Copyright 2022, All Rights Reserved.
+
+ At the discretion of the user of this library,
+ this software may be licensed under the terms of the
+ GNU General Public License v3, a BSD-Style license, or the
+ original HIDAPI license as outlined in the LICENSE.txt,
+ LICENSE-gpl3.txt, LICENSE-bsd.txt, and LICENSE-orig.txt
+ files located at the root of the source distribution.
+ These files may also be found in the public source
+ code repository located at:
+        https://github.com/libusb/hidapi .
+********************************************************/
+
+/** @file
+ * @defgroup API hidapi API
+
+ * Since version 0.12.0, @ref HID_API_VERSION >= HID_API_MAKE_VERSION(0, 12, 0)
+ */
+
+#ifndef HIDAPI_DARWIN_H__
+#define HIDAPI_DARWIN_H__
+
+#include <stdint.h>
+
+#include "hidapi.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+		/** @brief Get the location ID for a HID device.
+
+			Since version 0.12.0, @ref HID_API_VERSION >= HID_API_MAKE_VERSION(0, 12, 0)
+
+			@ingroup API
+			@param dev A device handle returned from hid_open().
+			@param location_id The device's location ID on return.
+
+			@returns
+				This function returns 0 on success and -1 on error.
+		*/
+		int HID_API_EXPORT_CALL hid_darwin_get_location_id(hid_device *dev, uint32_t *location_id);
+
+
+		/** @brief Changes the behavior of all further calls to @ref hid_open or @ref hid_open_path.
+
+			By default on Darwin platform all devices opened by HIDAPI with @ref hid_open or @ref hid_open_path
+			are opened in exclusive mode (see kIOHIDOptionsTypeSeizeDevice).
+
+			Since version 0.12.0, @ref HID_API_VERSION >= HID_API_MAKE_VERSION(0, 12, 0)
+
+			@ingroup API
+			@param open_exclusive When set to 0 - all further devices will be opened
+				in non-exclusive mode. Otherwise - all further devices will be opened
+				in exclusive mode.
+
+			@note During the initialisation by @ref hid_init - this property is set to 1 (TRUE).
+			This is done to preserve full backward compatibility with previous behavior.
+
+			@note Calling this function before @ref hid_init or after @ref hid_exit has no effect.
+		*/
+		void HID_API_EXPORT_CALL hid_darwin_set_open_exclusive(int open_exclusive);
+
+		/** @brief Getter for option set by @ref hid_darwin_set_open_exclusive.
+
+			Since version 0.12.0, @ref HID_API_VERSION >= HID_API_MAKE_VERSION(0, 12, 0)
+
+			@ingroup API
+			@return 1 if all further devices will be opened in exclusive mode.
+
+			@note Value returned by this function before calling to @ref hid_init or after @ref hid_exit
+			is not reliable.
+		*/
+		int HID_API_EXPORT_CALL hid_darwin_get_open_exclusive(void);
+
+		/** @brief Check how the device was opened.
+
+			Since version 0.12.0, @ref HID_API_VERSION >= HID_API_MAKE_VERSION(0, 12, 0)
+
+			@ingroup API
+			@param dev A device to get property from.
+
+			@return 1 if the device is opened in exclusive mode, 0 - opened in non-exclusive,
+			-1 - if dev is invalid.
+		*/
+		int HID_API_EXPORT_CALL hid_darwin_is_device_open_exclusive(hid_device *dev);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff -pruN 0.11.2-1/mac/hid.c 0.12.0-1/mac/hid.c
--- 0.11.2-1/mac/hid.c	2022-01-03 12:53:10.000000000 +0000
+++ 0.12.0-1/mac/hid.c	2022-05-25 12:52:59.000000000 +0000
@@ -5,9 +5,9 @@
  Alan Ott
  Signal 11 Software
 
- 2010-07-03
+ libusb/hidapi Team
 
- Copyright 2010, All Rights Reserved.
+ Copyright 2022, All Rights Reserved.
 
  At the discretion of the user of this library,
  this software may be licensed under the terms of the
@@ -34,7 +34,7 @@
 #include <unistd.h>
 #include <dlfcn.h>
 
-#include "hidapi.h"
+#include "hidapi_darwin.h"
 
 /* As defined in AppKit.h, but we don't need the entire AppKit for a single constant. */
 extern const double NSAppKitVersionNumber;
@@ -108,8 +108,21 @@ struct input_report {
 	struct input_report *next;
 };
 
+static struct hid_api_version api_version = {
+	.major = HID_API_VERSION_MAJOR,
+	.minor = HID_API_VERSION_MINOR,
+	.patch = HID_API_VERSION_PATCH
+};
+
+/* - Run context - */
+static	IOHIDManagerRef hid_mgr = 0x0;
+static	int is_macos_10_10_or_greater = 0;
+static	IOOptionBits device_open_options = 0;
+/* --- */
+
 struct hid_device_ {
 	IOHIDDeviceRef device_handle;
+	IOOptionBits open_options;
 	int blocking;
 	int uses_numbered_reports;
 	int disconnected;
@@ -132,6 +145,7 @@ static hid_device *new_hid_device(void)
 {
 	hid_device *dev = (hid_device*) calloc(1, sizeof(hid_device));
 	dev->device_handle = NULL;
+	dev->open_options = device_open_options;
 	dev->blocking = 1;
 	dev->uses_numbered_reports = 0;
 	dev->disconnected = 0;
@@ -184,23 +198,6 @@ static void free_hid_device(hid_device *
 	free(dev);
 }
 
-static struct hid_api_version api_version = {
-	.major = HID_API_VERSION_MAJOR,
-	.minor = HID_API_VERSION_MINOR,
-	.patch = HID_API_VERSION_PATCH
-};
-
-static	IOHIDManagerRef hid_mgr = 0x0;
-static	int is_macos_10_10_or_greater = 0;
-
-
-#if 0
-static void register_error(hid_device *dev, const char *op)
-{
-
-}
-#endif
-
 static CFArrayRef get_array_property(IOHIDDeviceRef device, CFStringRef key)
 {
 	CFTypeRef ref = IOHIDDeviceGetProperty(device, key);
@@ -345,6 +342,7 @@ int HID_API_EXPORT hid_init(void)
 {
 	if (!hid_mgr) {
 		is_macos_10_10_or_greater = (NSAppKitVersionNumber >= 1343); /* NSAppKitVersionNumber10_10 */
+		hid_darwin_set_open_exclusive(1); /* Backward compatibility */
 		return init_hid_manager();
 	}
 
@@ -381,7 +379,7 @@ static struct hid_device_info *create_de
 	struct hid_device_info *cur_dev;
 	io_object_t iokit_dev;
 	kern_return_t res;
-	uint64_t entry_id;
+	uint64_t entry_id = 0;
 
 	if (dev == NULL) {
 		return NULL;
@@ -792,12 +790,12 @@ static io_registry_entry_t hid_open_serv
 		char *endptr;
 		uint64_t entry_id = strtoull(path + 10, &endptr, 10);
 		if (*endptr == '\0') {
-			return IOServiceGetMatchingService(kIOMasterPortDefault, IORegistryEntryIDMatching(entry_id));
+			return IOServiceGetMatchingService((mach_port_t) 0, IORegistryEntryIDMatching(entry_id));
 		}
 	}
 	else {
 		/* Fallback to older format of the path */
-		return IORegistryEntryFromPath(kIOMasterPortDefault, path);
+		return IORegistryEntryFromPath((mach_port_t) 0, path);
 	}
 
 	return MACH_PORT_NULL;
@@ -830,7 +828,7 @@ hid_device * HID_API_EXPORT hid_open_pat
 	}
 
 	/* Open the IOHIDDevice */
-	ret = IOHIDDeviceOpen(dev->device_handle, kIOHIDOptionsTypeSeizeDevice);
+	ret = IOHIDDeviceOpen(dev->device_handle, dev->open_options);
 	if (ret == kIOReturnSuccess) {
 		char str[32];
 
@@ -905,7 +903,7 @@ static int set_report(hid_device *dev, I
 	                           data_to_send, length_to_send);
 
 	if (res == kIOReturnSuccess) {
-		return length;
+		return (int) length;
 	}
 
 	return -1;
@@ -939,7 +937,7 @@ static int get_report(hid_device *dev, I
 		if (report_id == 0x0) { /* 0 report number still present at the beginning */
 			report_length++;
 		}
-		return report_length;
+		return (int) report_length;
 	}
 
 	return -1;
@@ -961,7 +959,7 @@ static int return_data(hid_device *dev,
 	dev->input_reports = rpt->next;
 	free(rpt->data);
 	free(rpt);
-	return len;
+	return (int) len;
 }
 
 static int cond_wait(const hid_device *dev, pthread_cond_t *cond, pthread_mutex_t *mutex)
@@ -1147,7 +1145,7 @@ void HID_API_EXPORT hid_close(hid_device
 	   Not leaking a resource in all tested environments.
 	*/
 	if (is_macos_10_10_or_greater || !dev->disconnected) {
-		IOHIDDeviceClose(dev->device_handle, kIOHIDOptionsTypeSeizeDevice);
+		IOHIDDeviceClose(dev->device_handle, dev->open_options);
 	}
 
 	/* Clear out the queue of received reports. */
@@ -1188,85 +1186,39 @@ int HID_API_EXPORT_CALL hid_get_indexed_
 	return 0;
 }
 
-
-HID_API_EXPORT const wchar_t * HID_API_CALL  hid_error(hid_device *dev)
+int HID_API_EXPORT_CALL hid_darwin_get_location_id(hid_device *dev, uint32_t *location_id)
 {
-	(void) dev;
-	/* TODO: */
-
-	return L"hid_error is not implemented yet";
+	int res = get_int_property(dev->device_handle, CFSTR(kIOHIDLocationIDKey));
+	if (res != 0) {
+		*location_id = (uint32_t) res;
+		return 0;
+	} else {
+		return -1;
+	}
 }
 
-
-
-
-
-
-
-#if 0
-static int32_t get_location_id(IOHIDDeviceRef device)
+void HID_API_EXPORT_CALL hid_darwin_set_open_exclusive(int open_exclusive)
 {
-	return get_int_property(device, CFSTR(kIOHIDLocationIDKey));
+	device_open_options = (open_exclusive == 0) ? kIOHIDOptionsTypeNone : kIOHIDOptionsTypeSeizeDevice;
 }
 
-static int32_t get_usage(IOHIDDeviceRef device)
+int HID_API_EXPORT_CALL hid_darwin_get_open_exclusive(void)
 {
-	int32_t res;
-	res = get_int_property(device, CFSTR(kIOHIDDeviceUsageKey));
-	if (!res)
-		res = get_int_property(device, CFSTR(kIOHIDPrimaryUsageKey));
-	return res;
+	return (device_open_options == kIOHIDOptionsTypeSeizeDevice) ? 1 : 0;
 }
 
-static int32_t get_usage_page(IOHIDDeviceRef device)
+int HID_API_EXPORT_CALL hid_darwin_is_device_open_exclusive(hid_device *dev)
 {
-	int32_t res;
-	res = get_int_property(device, CFSTR(kIOHIDDeviceUsagePageKey));
-	if (!res)
-		res = get_int_property(device, CFSTR(kIOHIDPrimaryUsagePageKey));
-	return res;
-}
+	if (!dev)
+		return -1;
 
-static int get_transport(IOHIDDeviceRef device, wchar_t *buf, size_t len)
-{
-	return get_string_property(device, CFSTR(kIOHIDTransportKey), buf, len);
+	return (dev->open_options == kIOHIDOptionsTypeSeizeDevice) ? 1 : 0;
 }
 
-
-int main(void)
+HID_API_EXPORT const wchar_t * HID_API_CALL  hid_error(hid_device *dev)
 {
-	IOHIDManagerRef mgr;
-	int i;
-
-	mgr = IOHIDManagerCreate(kCFAllocatorDefault, kIOHIDOptionsTypeNone);
-	IOHIDManagerSetDeviceMatching(mgr, NULL);
-	IOHIDManagerOpen(mgr, kIOHIDOptionsTypeNone);
-
-	CFSetRef device_set = IOHIDManagerCopyDevices(mgr);
-
-	CFIndex num_devices = CFSetGetCount(device_set);
-	IOHIDDeviceRef *device_array = calloc(num_devices, sizeof(IOHIDDeviceRef));
-	CFSetGetValues(device_set, (const void **) device_array);
-
-	for (i = 0; i < num_devices; i++) {
-		IOHIDDeviceRef dev = device_array[i];
-		printf("Device: %p\n", dev);
-		printf("  %04hx %04hx\n", get_vendor_id(dev), get_product_id(dev));
-
-		wchar_t serial[256], buf[256];
-		char cbuf[256];
-		get_serial_number(dev, serial, 256);
-
-
-		printf("  Serial: %ls\n", serial);
-		printf("  Loc: %ld\n", get_location_id(dev));
-		get_transport(dev, buf, 256);
-		printf("  Trans: %ls\n", buf);
-		make_path(dev, cbuf, 256);
-		printf("  Path: %s\n", cbuf);
-
-	}
+	(void) dev;
+	/* TODO: */
 
-	return 0;
+	return L"hid_error is not implemented yet";
 }
-#endif
diff -pruN 0.11.2-1/mac/Makefile-manual 0.12.0-1/mac/Makefile-manual
--- 0.11.2-1/mac/Makefile-manual	2022-01-03 12:53:10.000000000 +0000
+++ 0.12.0-1/mac/Makefile-manual	2022-05-25 12:52:59.000000000 +0000
@@ -11,7 +11,7 @@ all: hidtest
 CC=gcc
 COBJS=hid.o ../hidtest/test.o
 OBJS=$(COBJS)
-CFLAGS+=-I../hidapi -Wall -g -c 
+CFLAGS+=-I../hidapi -I. -Wall -g -c
 LIBS=-framework IOKit -framework CoreFoundation -framework AppKit
 
 
diff -pruN 0.11.2-1/README.md 0.12.0-1/README.md
--- 0.11.2-1/README.md	2022-01-03 12:53:10.000000000 +0000
+++ 0.12.0-1/README.md	2022-05-25 12:52:59.000000000 +0000
@@ -9,8 +9,9 @@
 HIDAPI is a multi-platform library which allows an application to interface
 with USB and Bluetooth HID-Class devices on Windows, Linux, FreeBSD, and macOS.
 HIDAPI can be either built as a shared library (`.so`, `.dll` or `.dylib`) or
-can be embedded directly into a target application by adding a single source
-file (per platform) and a single header.
+can be embedded directly into a target application by adding a _single source_
+file (per platform) and a single header.<br>
+See [remarks](BUILD.md#embedding-hidapi-directly-into-your-source-tree) on embedding _directly_ into your build system.
 
 HIDAPI library was originally developed by Alan Ott ([signal11](https://github.com/signal11)).
 
diff -pruN 0.11.2-1/src/cmake/hidapi-config.cmake.in 0.12.0-1/src/cmake/hidapi-config.cmake.in
--- 0.11.2-1/src/cmake/hidapi-config.cmake.in	2022-01-03 12:53:10.000000000 +0000
+++ 0.12.0-1/src/cmake/hidapi-config.cmake.in	2022-05-25 12:52:59.000000000 +0000
@@ -11,6 +11,7 @@ set(hidapi_FOUND FALSE)
 set(HIDAPI_NEED_EXPORT_THREADS @HIDAPI_NEED_EXPORT_THREADS@)
 set(HIDAPI_NEED_EXPORT_LIBUSB @HIDAPI_NEED_EXPORT_LIBUSB@)
 set(HIDAPI_NEED_EXPORT_LIBUDEV @HIDAPI_NEED_EXPORT_LIBUDEV@)
+set(HIDAPI_NEED_EXPORT_ICONV @HIDAPI_NEED_EXPORT_ICONV@)
 
 if(HIDAPI_NEED_EXPORT_THREADS)
   if(CMAKE_VERSION VERSION_LESS 3.4.3)
@@ -23,7 +24,7 @@ if(HIDAPI_NEED_EXPORT_LIBUSB OR HIDAPI_N
   if(CMAKE_VERSION VERSION_LESS 3.6.3)
     message(FATAL_ERROR "This file relies on consumers using CMake 3.6.3 or greater.")
   endif()
-  include(FindPkgConfig)
+  find_package(PkgConfig)
   if(HIDAPI_NEED_EXPORT_LIBUSB)
     pkg_check_modules(libusb REQUIRED IMPORTED_TARGET libusb-1.0>=1.0.9)
   endif()
@@ -32,7 +33,15 @@ if(HIDAPI_NEED_EXPORT_LIBUSB OR HIDAPI_N
   endif()
 endif()
 
-include("${CMAKE_CURRENT_LIST_DIR}/hidapi.cmake")
+if(HIDAPI_NEED_EXPORT_ICONV)
+  if(CMAKE_VERSION VERSION_LESS 3.11)
+    message(WARNING "HIDAPI requires CMake target Iconv::Iconv, make sure to provide it")
+  else()
+    find_package(Iconv REQUIRED)
+  endif()
+endif()
+
+include("${CMAKE_CURRENT_LIST_DIR}/libhidapi.cmake")
 
 set(hidapi_FOUND TRUE)
 
diff -pruN 0.11.2-1/src/CMakeLists.txt 0.12.0-1/src/CMakeLists.txt
--- 0.11.2-1/src/CMakeLists.txt	2022-01-03 12:53:10.000000000 +0000
+++ 0.12.0-1/src/CMakeLists.txt	2022-05-25 12:52:59.000000000 +0000
@@ -92,12 +92,19 @@ set(EXPORT_COMPONENTS)
 set(HIDAPI_NEED_EXPORT_THREADS FALSE)
 set(HIDAPI_NEED_EXPORT_LIBUSB FALSE)
 set(HIDAPI_NEED_EXPORT_LIBUDEV FALSE)
+set(HIDAPI_NEED_EXPORT_ICONV FALSE)
 
 if(WIN32)
+    target_include_directories(hidapi_include INTERFACE
+        "$<BUILD_INTERFACE:${PROJECT_ROOT}/windows>"
+    )
     add_subdirectory("${PROJECT_ROOT}/windows" windows)
     set(EXPORT_ALIAS winapi)
     list(APPEND EXPORT_COMPONENTS winapi)
 elseif(APPLE)
+    target_include_directories(hidapi_include INTERFACE
+        "$<BUILD_INTERFACE:${PROJECT_ROOT}/mac>"
+    )
     add_subdirectory("${PROJECT_ROOT}/mac" mac)
     set(EXPORT_ALIAS darwin)
     list(APPEND EXPORT_COMPONENTS darwin)
@@ -128,6 +135,9 @@ else()
         target_include_directories(hidapi_include INTERFACE
             "$<BUILD_INTERFACE:${PROJECT_ROOT}/libusb>"
         )
+        if(NOT DEFINED HIDAPI_NO_ICONV)
+            set(HIDAPI_NO_ICONV OFF)
+        endif()
         add_subdirectory("${PROJECT_ROOT}/libusb" libusb)
         list(APPEND EXPORT_COMPONENTS libusb)
         if(NOT EXPORT_ALIAS)
@@ -138,6 +148,9 @@ else()
             if(NOT TARGET usb-1.0)
                 set(HIDAPI_NEED_EXPORT_LIBUSB TRUE)
             endif()
+            if(NOT HIDAPI_NO_ICONV AND NOT ANDROID AND NOT CMAKE_VERSION VERSION_LESS 3.11)
+                set(HIDAPI_NEED_EXPORT_ICONV TRUE)
+            endif()
         endif()
     elseif(NOT TARGET hidapi_hidraw)
         message(FATAL_ERROR "Select at least one option to build: HIDAPI_WITH_LIBUSB or HIDAPI_WITH_HIDRAW")
@@ -150,7 +163,7 @@ if(HIDAPI_INSTALL_TARGETS)
     include(CMakePackageConfigHelpers)
     set(EXPORT_DENERATED_LOCATION "${CMAKE_BINARY_DIR}/export_generated")
     set(EXPORT_DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/hidapi")
-    write_basic_package_version_file("${EXPORT_DENERATED_LOCATION}/hidapi-config-version.cmake"
+    write_basic_package_version_file("${EXPORT_DENERATED_LOCATION}/libhidapi-version.cmake"
         COMPATIBILITY SameMajorVersion
     )
     configure_package_config_file("cmake/hidapi-config.cmake.in" "${EXPORT_DENERATED_LOCATION}/hidapi-config.cmake"
@@ -161,9 +174,10 @@ if(HIDAPI_INSTALL_TARGETS)
     install(EXPORT hidapi
         DESTINATION "${EXPORT_DESTINATION}"
         NAMESPACE hidapi::
+        FILE "libhidapi.cmake"
     )
     install(FILES
-            "${EXPORT_DENERATED_LOCATION}/hidapi-config-version.cmake"
+            "${EXPORT_DENERATED_LOCATION}/libhidapi-version.cmake"
             "${EXPORT_DENERATED_LOCATION}/hidapi-config.cmake"
         DESTINATION "${EXPORT_DESTINATION}"
     )
diff -pruN 0.11.2-1/testgui/Makefile.mingw 0.12.0-1/testgui/Makefile.mingw
--- 0.11.2-1/testgui/Makefile.mingw	2022-01-03 12:53:10.000000000 +0000
+++ 0.12.0-1/testgui/Makefile.mingw	2022-05-25 12:52:59.000000000 +0000
@@ -14,7 +14,7 @@ COBJS=../windows/hid.o
 CPPOBJS=test.o
 OBJS=$(COBJS) $(CPPOBJS)
 CFLAGS=-I../hidapi -I../../hidapi-externals/fox/include -g -c
-LIBS= -mwindows -lsetupapi -L../../hidapi-externals/fox/lib -Wl,-Bstatic -lFOX-1.6 -Wl,-Bdynamic -lgdi32 -Wl,--enable-auto-import -static-libgcc -static-libstdc++ -lkernel32
+LIBS= -mwindows -L../../hidapi-externals/fox/lib -Wl,-Bstatic -lFOX-1.6 -Wl,-Bdynamic -lgdi32 -Wl,--enable-auto-import -static-libgcc -static-libstdc++ -lkernel32
 
 
 hidapi-testgui: $(OBJS)
diff -pruN 0.11.2-1/testgui/testgui.vcproj 0.12.0-1/testgui/testgui.vcproj
--- 0.11.2-1/testgui/testgui.vcproj	2022-01-03 12:53:10.000000000 +0000
+++ 0.12.0-1/testgui/testgui.vcproj	2022-05-25 12:52:59.000000000 +0000
@@ -61,7 +61,7 @@
 			/>
 			<Tool
 				Name="VCLinkerTool"
-				AdditionalDependencies="setupapi.lib fox-1.6.lib"
+				AdditionalDependencies="fox-1.6.lib"
 				OutputFile="$(ProjectName).exe"
 				LinkIncremental="2"
 				AdditionalLibraryDirectories="..\hidapi\objfre_wxp_x86\i386;&quot;..\..\hidapi-externals\fox\lib&quot;"
@@ -139,7 +139,7 @@
 			/>
 			<Tool
 				Name="VCLinkerTool"
-				AdditionalDependencies="setupapi.lib fox-1.6.lib"
+				AdditionalDependencies="fox-1.6.lib"
 				OutputFile="$(ProjectName).exe"
 				LinkIncremental="1"
 				AdditionalLibraryDirectories="..\hidapi\objfre_wxp_x86\i386;&quot;..\..\hidapi-externals\fox\lib&quot;"
diff -pruN 0.11.2-1/VERSION 0.12.0-1/VERSION
--- 0.11.2-1/VERSION	2022-01-03 12:53:10.000000000 +0000
+++ 0.12.0-1/VERSION	2022-05-25 12:52:59.000000000 +0000
@@ -1 +1 @@
-0.11.2
\ No newline at end of file
+0.12.0
diff -pruN 0.11.2-1/windows/CMakeLists.txt 0.12.0-1/windows/CMakeLists.txt
--- 0.11.2-1/windows/CMakeLists.txt	2022-01-03 12:53:10.000000000 +0000
+++ 0.12.0-1/windows/CMakeLists.txt	2022-05-25 12:52:59.000000000 +0000
@@ -1,10 +1,23 @@
+list(APPEND HIDAPI_PUBLIC_HEADERS "hidapi_winapi.h")
+
+set(SOURCES
+    hid.c
+    hidapi_cfgmgr32.h
+    hidapi_hidclass.h
+    hidapi_hidpi.h
+    hidapi_hidsdi.h
+)
+
+if(BUILD_SHARED_LIBS)
+    list(APPEND SOURCES hidapi.rc)
+endif()
+
 add_library(hidapi_winapi
     ${HIDAPI_PUBLIC_HEADERS}
-    hid.c
+    ${SOURCES}
 )
 target_link_libraries(hidapi_winapi
     PUBLIC hidapi_include
-    PRIVATE setupapi
 )
 
 set_target_properties(hidapi_winapi
diff -pruN 0.11.2-1/windows/hidapi_cfgmgr32.h 0.12.0-1/windows/hidapi_cfgmgr32.h
--- 0.11.2-1/windows/hidapi_cfgmgr32.h	1970-01-01 00:00:00.000000000 +0000
+++ 0.12.0-1/windows/hidapi_cfgmgr32.h	2022-05-25 12:52:59.000000000 +0000
@@ -0,0 +1,69 @@
+/*******************************************************
+ HIDAPI - Multi-Platform library for
+ communication with HID devices.
+
+ libusb/hidapi Team
+
+ Copyright 2022, All Rights Reserved.
+
+ At the discretion of the user of this library,
+ this software may be licensed under the terms of the
+ GNU General Public License v3, a BSD-Style license, or the
+ original HIDAPI license as outlined in the LICENSE.txt,
+ LICENSE-gpl3.txt, LICENSE-bsd.txt, and LICENSE-orig.txt
+ files located at the root of the source distribution.
+ These files may also be found in the public source
+ code repository located at:
+        https://github.com/libusb/hidapi .
+********************************************************/
+
+#ifndef HIDAPI_CFGMGR32_H
+#define HIDAPI_CFGMGR32_H
+
+#ifdef HIDAPI_USE_DDK
+
+#include <cfgmgr32.h>
+#include <initguid.h>
+#include <devpkey.h>
+#include <propkey.h>
+
+#else
+
+/* This part of the header mimics cfgmgr32.h,
+    but only what is used by HIDAPI */
+
+typedef DWORD RETURN_TYPE;
+typedef RETURN_TYPE CONFIGRET;
+typedef DWORD DEVNODE, DEVINST;
+typedef DEVNODE* PDEVNODE, * PDEVINST;
+typedef WCHAR* DEVNODEID_W, * DEVINSTID_W;
+
+#define CR_SUCCESS (0x00000000)
+#define CR_BUFFER_SMALL (0x0000001A)
+#define CR_FAILURE (0x00000013)
+
+#define CM_LOCATE_DEVNODE_NORMAL 0x00000000
+
+#define CM_GET_DEVICE_INTERFACE_LIST_PRESENT (0x00000000)
+
+typedef CONFIGRET(__stdcall* CM_Locate_DevNodeW_)(PDEVINST pdnDevInst, DEVINSTID_W pDeviceID, ULONG ulFlags);
+typedef CONFIGRET(__stdcall* CM_Get_Parent_)(PDEVINST pdnDevInst, DEVINST dnDevInst, ULONG ulFlags);
+typedef CONFIGRET(__stdcall* CM_Get_DevNode_PropertyW_)(DEVINST dnDevInst, CONST DEVPROPKEY* PropertyKey, DEVPROPTYPE* PropertyType, PBYTE PropertyBuffer, PULONG PropertyBufferSize, ULONG ulFlags);
+typedef CONFIGRET(__stdcall* CM_Get_Device_Interface_PropertyW_)(LPCWSTR pszDeviceInterface, CONST DEVPROPKEY* PropertyKey, DEVPROPTYPE* PropertyType, PBYTE PropertyBuffer, PULONG PropertyBufferSize, ULONG ulFlags);
+typedef CONFIGRET(__stdcall* CM_Get_Device_Interface_List_SizeW_)(PULONG pulLen, LPGUID InterfaceClassGuid, DEVINSTID_W pDeviceID, ULONG ulFlags);
+typedef CONFIGRET(__stdcall* CM_Get_Device_Interface_ListW_)(LPGUID InterfaceClassGuid, DEVINSTID_W pDeviceID, PZZWSTR Buffer, ULONG BufferLen, ULONG ulFlags);
+
+// from devpkey.h
+static DEVPROPKEY DEVPKEY_NAME = { { 0xb725f130, 0x47ef, 0x101a, {0xa5, 0xf1, 0x02, 0x60, 0x8c, 0x9e, 0xeb, 0xac} }, 10 }; // DEVPROP_TYPE_STRING
+static DEVPROPKEY DEVPKEY_Device_InstanceId = { { 0x78c34fc8, 0x104a, 0x4aca, {0x9e, 0xa4, 0x52, 0x4d, 0x52, 0x99, 0x6e, 0x57} }, 256 }; // DEVPROP_TYPE_STRING
+static DEVPROPKEY DEVPKEY_Device_HardwareIds = { { 0xa45c254e, 0xdf1c, 0x4efd, {0x80, 0x20, 0x67, 0xd1, 0x46, 0xa8, 0x50, 0xe0} }, 3 }; // DEVPROP_TYPE_STRING_LIST
+static DEVPROPKEY DEVPKEY_Device_CompatibleIds = { { 0xa45c254e, 0xdf1c, 0x4efd, {0x80, 0x20, 0x67, 0xd1, 0x46, 0xa8, 0x50, 0xe0} }, 4 }; // DEVPROP_TYPE_STRING_LIST
+static DEVPROPKEY DEVPKEY_Device_ContainerId = { { 0x8c7ed206, 0x3f8a, 0x4827, {0xb3, 0xab, 0xae, 0x9e, 0x1f, 0xae, 0xfc, 0x6c} }, 2 }; // DEVPROP_TYPE_GUID
+
+// from propkey.h
+static PROPERTYKEY PKEY_DeviceInterface_Bluetooth_DeviceAddress = { { 0x2bd67d8b, 0x8beb, 0x48d5, {0x87, 0xe0, 0x6c, 0xda, 0x34, 0x28, 0x04, 0x0a} }, 1 }; // DEVPROP_TYPE_STRING
+static PROPERTYKEY PKEY_DeviceInterface_Bluetooth_Manufacturer = { { 0x2bd67d8b, 0x8beb, 0x48d5, {0x87, 0xe0, 0x6c, 0xda, 0x34, 0x28, 0x04, 0x0a} }, 4 }; // DEVPROP_TYPE_STRING
+
+#endif
+
+#endif /* HIDAPI_CFGMGR32_H */
diff -pruN 0.11.2-1/windows/hidapi_hidclass.h 0.12.0-1/windows/hidapi_hidclass.h
--- 0.11.2-1/windows/hidapi_hidclass.h	1970-01-01 00:00:00.000000000 +0000
+++ 0.12.0-1/windows/hidapi_hidclass.h	2022-05-25 12:52:59.000000000 +0000
@@ -0,0 +1,38 @@
+/*******************************************************
+ HIDAPI - Multi-Platform library for
+ communication with HID devices.
+
+ libusb/hidapi Team
+
+ Copyright 2022, All Rights Reserved.
+
+ At the discretion of the user of this library,
+ this software may be licensed under the terms of the
+ GNU General Public License v3, a BSD-Style license, or the
+ original HIDAPI license as outlined in the LICENSE.txt,
+ LICENSE-gpl3.txt, LICENSE-bsd.txt, and LICENSE-orig.txt
+ files located at the root of the source distribution.
+ These files may also be found in the public source
+ code repository located at:
+        https://github.com/libusb/hidapi .
+********************************************************/
+
+#ifndef HIDAPI_HIDCLASS_H
+#define HIDAPI_HIDCLASS_H
+
+#ifdef HIDAPI_USE_DDK
+
+#include <hidclass.h>
+
+#else
+
+/* This part of the header mimics hidclass.h,
+    but only what is used by HIDAPI */
+
+#define HID_OUT_CTL_CODE(id) CTL_CODE(FILE_DEVICE_KEYBOARD, (id), METHOD_OUT_DIRECT, FILE_ANY_ACCESS)
+#define IOCTL_HID_GET_FEATURE HID_OUT_CTL_CODE(100)
+#define IOCTL_HID_GET_INPUT_REPORT HID_OUT_CTL_CODE(104)
+
+#endif
+
+#endif /* HIDAPI_HIDCLASS_H */
diff -pruN 0.11.2-1/windows/hidapi_hidpi.h 0.12.0-1/windows/hidapi_hidpi.h
--- 0.11.2-1/windows/hidapi_hidpi.h	1970-01-01 00:00:00.000000000 +0000
+++ 0.12.0-1/windows/hidapi_hidpi.h	2022-05-25 12:52:59.000000000 +0000
@@ -0,0 +1,65 @@
+/*******************************************************
+ HIDAPI - Multi-Platform library for
+ communication with HID devices.
+
+ libusb/hidapi Team
+
+ Copyright 2022, All Rights Reserved.
+
+ At the discretion of the user of this library,
+ this software may be licensed under the terms of the
+ GNU General Public License v3, a BSD-Style license, or the
+ original HIDAPI license as outlined in the LICENSE.txt,
+ LICENSE-gpl3.txt, LICENSE-bsd.txt, and LICENSE-orig.txt
+ files located at the root of the source distribution.
+ These files may also be found in the public source
+ code repository located at:
+        https://github.com/libusb/hidapi .
+********************************************************/
+
+#ifndef HIDAPI_HIDPI_H
+#define HIDAPI_HIDPI_H
+
+#ifdef HIDAPI_USE_DDK
+
+#include <hidpi.h>
+
+#else
+
+/* This part of the header mimics hidpi.h,
+    but only what is used by HIDAPI */
+
+typedef struct _HIDP_PREPARSED_DATA * PHIDP_PREPARSED_DATA;
+
+typedef struct _HIDP_CAPS
+{
+    USAGE    Usage;
+    USAGE    UsagePage;
+    USHORT   InputReportByteLength;
+    USHORT   OutputReportByteLength;
+    USHORT   FeatureReportByteLength;
+    USHORT   Reserved[17];
+
+    USHORT   NumberLinkCollectionNodes;
+
+    USHORT   NumberInputButtonCaps;
+    USHORT   NumberInputValueCaps;
+    USHORT   NumberInputDataIndices;
+
+    USHORT   NumberOutputButtonCaps;
+    USHORT   NumberOutputValueCaps;
+    USHORT   NumberOutputDataIndices;
+
+    USHORT   NumberFeatureButtonCaps;
+    USHORT   NumberFeatureValueCaps;
+    USHORT   NumberFeatureDataIndices;
+} HIDP_CAPS, *PHIDP_CAPS;
+
+#define HIDP_STATUS_SUCCESS                0x00110000
+#define HIDP_STATUS_INVALID_PREPARSED_DATA 0xc0110001
+
+typedef NTSTATUS (__stdcall *HidP_GetCaps_)(PHIDP_PREPARSED_DATA preparsed_data, PHIDP_CAPS caps);
+
+#endif
+
+#endif /* HIDAPI_HIDPI_H */
diff -pruN 0.11.2-1/windows/hidapi_hidsdi.h 0.12.0-1/windows/hidapi_hidsdi.h
--- 0.11.2-1/windows/hidapi_hidsdi.h	1970-01-01 00:00:00.000000000 +0000
+++ 0.12.0-1/windows/hidapi_hidsdi.h	2022-05-25 12:52:59.000000000 +0000
@@ -0,0 +1,60 @@
+/*******************************************************
+ HIDAPI - Multi-Platform library for
+ communication with HID devices.
+
+ libusb/hidapi Team
+
+ Copyright 2022, All Rights Reserved.
+
+ At the discretion of the user of this library,
+ this software may be licensed under the terms of the
+ GNU General Public License v3, a BSD-Style license, or the
+ original HIDAPI license as outlined in the LICENSE.txt,
+ LICENSE-gpl3.txt, LICENSE-bsd.txt, and LICENSE-orig.txt
+ files located at the root of the source distribution.
+ These files may also be found in the public source
+ code repository located at:
+        https://github.com/libusb/hidapi .
+********************************************************/
+
+#ifndef HIDAPI_HIDSDI_H
+#define HIDAPI_HIDSDI_H
+
+#ifdef HIDAPI_USE_DDK
+
+#include <hidsdi.h>
+
+#else
+
+/* This part of the header mimics hidsdi.h,
+    but only what is used by HIDAPI */
+
+typedef USHORT USAGE;
+
+#include "hidapi_hidpi.h"
+
+typedef struct _HIDD_ATTRIBUTES{
+	ULONG Size;
+	USHORT VendorID;
+	USHORT ProductID;
+	USHORT VersionNumber;
+} HIDD_ATTRIBUTES, *PHIDD_ATTRIBUTES;
+
+typedef struct _HIDP_PREPARSED_DATA * PHIDP_PREPARSED_DATA;
+
+typedef void (__stdcall *HidD_GetHidGuid_)(LPGUID hid_guid);
+typedef BOOLEAN (__stdcall *HidD_GetAttributes_)(HANDLE device, PHIDD_ATTRIBUTES attrib);
+typedef BOOLEAN (__stdcall *HidD_GetSerialNumberString_)(HANDLE device, PVOID buffer, ULONG buffer_len);
+typedef BOOLEAN (__stdcall *HidD_GetManufacturerString_)(HANDLE handle, PVOID buffer, ULONG buffer_len);
+typedef BOOLEAN (__stdcall *HidD_GetProductString_)(HANDLE handle, PVOID buffer, ULONG buffer_len);
+typedef BOOLEAN (__stdcall *HidD_SetFeature_)(HANDLE handle, PVOID data, ULONG length);
+typedef BOOLEAN (__stdcall *HidD_GetFeature_)(HANDLE handle, PVOID data, ULONG length);
+typedef BOOLEAN (__stdcall *HidD_GetInputReport_)(HANDLE handle, PVOID data, ULONG length);
+typedef BOOLEAN (__stdcall *HidD_GetIndexedString_)(HANDLE handle, ULONG string_index, PVOID buffer, ULONG buffer_len);
+typedef BOOLEAN (__stdcall *HidD_GetPreparsedData_)(HANDLE handle, PHIDP_PREPARSED_DATA *preparsed_data);
+typedef BOOLEAN (__stdcall *HidD_FreePreparsedData_)(PHIDP_PREPARSED_DATA preparsed_data);
+typedef BOOLEAN (__stdcall *HidD_SetNumInputBuffers_)(HANDLE handle, ULONG number_buffers);
+
+#endif
+
+#endif /* HIDAPI_HIDSDI_H */
diff -pruN 0.11.2-1/windows/hidapi.rc 0.12.0-1/windows/hidapi.rc
--- 0.11.2-1/windows/hidapi.rc	1970-01-01 00:00:00.000000000 +0000
+++ 0.12.0-1/windows/hidapi.rc	2022-05-25 12:52:59.000000000 +0000
@@ -0,0 +1,35 @@
+#include "winresrc.h"
+
+#include "hidapi.h"
+
+// English
+LANGUAGE LANG_ENGLISH, SUBLANG_DEFAULT
+VS_VERSION_INFO VERSIONINFO
+ FILEVERSION HID_API_VERSION_MAJOR,HID_API_VERSION_MINOR,HID_API_VERSION_PATCH,0
+ PRODUCTVERSION HID_API_VERSION_MAJOR,HID_API_VERSION_MINOR,HID_API_VERSION_PATCH,0
+ FILEFLAGSMASK VS_FFI_FILEFLAGSMASK
+ FILEFLAGS 0
+#ifdef _DEBUG
+  | VS_FF_DEBUG
+#endif
+ FILEOS VOS_NT_WINDOWS32
+ FILETYPE VFT_DLL
+BEGIN
+	BLOCK "StringFileInfo"
+	BEGIN
+		BLOCK "04090000"
+		BEGIN
+			VALUE "CompanyName", "libusb/hidapi Team"
+			VALUE "FileDescription", "A multi-platform library to interface with HID devices (USB, Bluetooth, etc.)"
+			VALUE "FileVersion", HID_API_VERSION_STR
+			VALUE "ProductName", "HIDAPI"
+			VALUE "ProductVersion", HID_API_VERSION_STR
+			VALUE "Licence", "https://github.com/libusb/hidapi/blob/master/LICENSE.txt"
+			VALUE "Comments", "https://github.com/libusb/hidapi"
+		END
+	END
+	BLOCK "VarFileInfo"
+	BEGIN
+		VALUE "Translation", 0x409, 0
+	END
+END
diff -pruN 0.11.2-1/windows/hidapi.vcproj 0.12.0-1/windows/hidapi.vcproj
--- 0.11.2-1/windows/hidapi.vcproj	2022-01-03 12:53:10.000000000 +0000
+++ 0.12.0-1/windows/hidapi.vcproj	2022-05-25 12:52:59.000000000 +0000
@@ -61,7 +61,6 @@
 			/>
 			<Tool
 				Name="VCLinkerTool"
-				AdditionalDependencies="setupapi.lib"
 				LinkIncremental="2"
 				GenerateDebugInformation="true"
 				SubSystem="2"
diff -pruN 0.11.2-1/windows/hidapi.vcxproj 0.12.0-1/windows/hidapi.vcxproj
--- 0.11.2-1/windows/hidapi.vcxproj	2022-01-03 12:53:10.000000000 +0000
+++ 0.12.0-1/windows/hidapi.vcxproj	2022-05-25 12:52:59.000000000 +0000
@@ -31,6 +31,7 @@
     <PlatformToolset Condition="'$(VisualStudioVersion)'=='14'">v140</PlatformToolset>
     <PlatformToolset Condition="'$(VisualStudioVersion)'=='15'">v141</PlatformToolset>
     <PlatformToolset Condition="'$(VisualStudioVersion)'=='16'">v142</PlatformToolset>
+    <PlatformToolset Condition="'$(VisualStudioVersion)'=='17'">v143</PlatformToolset>
     <CharacterSet>Unicode</CharacterSet>
     <WholeProgramOptimization>true</WholeProgramOptimization>
   </PropertyGroup>
@@ -41,6 +42,7 @@
     <PlatformToolset Condition="'$(VisualStudioVersion)'=='14'">v140</PlatformToolset>
     <PlatformToolset Condition="'$(VisualStudioVersion)'=='15'">v141</PlatformToolset>
     <PlatformToolset Condition="'$(VisualStudioVersion)'=='16'">v142</PlatformToolset>
+    <PlatformToolset Condition="'$(VisualStudioVersion)'=='17'">v143</PlatformToolset>
     <CharacterSet>Unicode</CharacterSet>
     <WholeProgramOptimization>true</WholeProgramOptimization>
   </PropertyGroup>
@@ -51,6 +53,7 @@
     <PlatformToolset Condition="'$(VisualStudioVersion)'=='14'">v140</PlatformToolset>
     <PlatformToolset Condition="'$(VisualStudioVersion)'=='15'">v141</PlatformToolset>
     <PlatformToolset Condition="'$(VisualStudioVersion)'=='16'">v142</PlatformToolset>
+    <PlatformToolset Condition="'$(VisualStudioVersion)'=='17'">v143</PlatformToolset>
     <CharacterSet>Unicode</CharacterSet>
   </PropertyGroup>
   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
@@ -60,6 +63,7 @@
     <PlatformToolset Condition="'$(VisualStudioVersion)'=='14'">v140</PlatformToolset>
     <PlatformToolset Condition="'$(VisualStudioVersion)'=='15'">v141</PlatformToolset>
     <PlatformToolset Condition="'$(VisualStudioVersion)'=='16'">v142</PlatformToolset>
+    <PlatformToolset Condition="'$(VisualStudioVersion)'=='17'">v143</PlatformToolset>
     <CharacterSet>Unicode</CharacterSet>
   </PropertyGroup>
   <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
@@ -98,11 +102,15 @@
       <DebugInformationFormat>EditAndContinue</DebugInformationFormat>
     </ClCompile>
     <Link>
-      <AdditionalDependencies>setupapi.lib;%(AdditionalDependencies)</AdditionalDependencies>
+      <AdditionalDependencies>%(AdditionalDependencies)</AdditionalDependencies>
       <GenerateDebugInformation>true</GenerateDebugInformation>
       <SubSystem>Windows</SubSystem>
       <TargetMachine>MachineX86</TargetMachine>
     </Link>
+    <ResourceCompile>
+      <AdditionalIncludeDirectories>..\hidapi</AdditionalIncludeDirectories>
+      <PreprocessorDefinitions>_DEBUG</PreprocessorDefinitions>
+    </ResourceCompile>
   </ItemDefinitionGroup>
   <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
     <ClCompile>
@@ -117,10 +125,14 @@
       <DebugInformationFormat>EditAndContinue</DebugInformationFormat>
     </ClCompile>
     <Link>
-      <AdditionalDependencies>setupapi.lib;%(AdditionalDependencies)</AdditionalDependencies>
+      <AdditionalDependencies>%(AdditionalDependencies)</AdditionalDependencies>
       <GenerateDebugInformation>true</GenerateDebugInformation>
       <SubSystem>Windows</SubSystem>
     </Link>
+    <ResourceCompile>
+      <AdditionalIncludeDirectories>..\hidapi</AdditionalIncludeDirectories>
+      <PreprocessorDefinitions>_DEBUG</PreprocessorDefinitions>
+    </ResourceCompile>
   </ItemDefinitionGroup>
   <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
     <ClCompile>
@@ -135,13 +147,17 @@
       <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
     </ClCompile>
     <Link>
-      <AdditionalDependencies>setupapi.lib;%(AdditionalDependencies)</AdditionalDependencies>
+      <AdditionalDependencies>%(AdditionalDependencies)</AdditionalDependencies>
       <GenerateDebugInformation>true</GenerateDebugInformation>
       <SubSystem>Windows</SubSystem>
       <OptimizeReferences>true</OptimizeReferences>
       <EnableCOMDATFolding>true</EnableCOMDATFolding>
       <TargetMachine>MachineX86</TargetMachine>
     </Link>
+    <ResourceCompile>
+      <AdditionalIncludeDirectories>..\hidapi</AdditionalIncludeDirectories>
+      <PreprocessorDefinitions>NDEBUG</PreprocessorDefinitions>
+    </ResourceCompile>
   </ItemDefinitionGroup>
   <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
     <ClCompile>
@@ -157,20 +173,28 @@
       <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
     </ClCompile>
     <Link>
-      <AdditionalDependencies>setupapi.lib;%(AdditionalDependencies)</AdditionalDependencies>
+      <AdditionalDependencies>%(AdditionalDependencies)</AdditionalDependencies>
       <GenerateDebugInformation>true</GenerateDebugInformation>
       <SubSystem>Windows</SubSystem>
       <OptimizeReferences>true</OptimizeReferences>
       <EnableCOMDATFolding>true</EnableCOMDATFolding>
     </Link>
+    <ResourceCompile>
+      <AdditionalIncludeDirectories>..\hidapi</AdditionalIncludeDirectories>
+      <PreprocessorDefinitions>NDEBUG</PreprocessorDefinitions>
+    </ResourceCompile>
   </ItemDefinitionGroup>
   <ItemGroup>
     <ClCompile Include="hid.c" />
   </ItemGroup>
   <ItemGroup>
     <ClInclude Include="..\hidapi\hidapi.h" />
+    <ClInclude Include="hidapi_winapi.h" />
+  </ItemGroup>
+  <ItemGroup>
+    <ResourceCompile Include="hidapi.rc" />
   </ItemGroup>
   <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
   <ImportGroup Label="ExtensionTargets">
   </ImportGroup>
-</Project>
+</Project>
\ No newline at end of file
diff -pruN 0.11.2-1/windows/hidapi.vcxproj.filters 0.12.0-1/windows/hidapi.vcxproj.filters
--- 0.11.2-1/windows/hidapi.vcxproj.filters	2022-01-03 12:53:10.000000000 +0000
+++ 0.12.0-1/windows/hidapi.vcxproj.filters	2022-05-25 12:52:59.000000000 +0000
@@ -23,5 +23,13 @@
     <ClInclude Include="..\hidapi\hidapi.h">
       <Filter>Header Files</Filter>
     </ClInclude>
+    <ClInclude Include="hidapi_winapi.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+  </ItemGroup>
+  <ItemGroup>
+    <ResourceCompile Include="hidapi.rc">
+      <Filter>Resource Files</Filter>
+    </ResourceCompile>
   </ItemGroup>
 </Project>
\ No newline at end of file
diff -pruN 0.11.2-1/windows/hidapi_winapi.h 0.12.0-1/windows/hidapi_winapi.h
--- 0.11.2-1/windows/hidapi_winapi.h	1970-01-01 00:00:00.000000000 +0000
+++ 0.12.0-1/windows/hidapi_winapi.h	2022-05-25 12:52:59.000000000 +0000
@@ -0,0 +1,58 @@
+/*******************************************************
+ HIDAPI - Multi-Platform library for
+ communication with HID devices.
+
+ libusb/hidapi Team
+
+ Copyright 2022, All Rights Reserved.
+
+ At the discretion of the user of this library,
+ this software may be licensed under the terms of the
+ GNU General Public License v3, a BSD-Style license, or the
+ original HIDAPI license as outlined in the LICENSE.txt,
+ LICENSE-gpl3.txt, LICENSE-bsd.txt, and LICENSE-orig.txt
+ files located at the root of the source distribution.
+ These files may also be found in the public source
+ code repository located at:
+        https://github.com/libusb/hidapi .
+********************************************************/
+
+/** @file
+ * @defgroup API hidapi API
+ *
+ * Since version 0.12.0, @ref HID_API_VERSION >= HID_API_MAKE_VERSION(0, 12, 0)
+ */
+
+#ifndef HIDAPI_WINAPI_H__
+#define HIDAPI_WINAPI_H__
+
+#include <guiddef.h>
+
+#include "hidapi.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+		/** @brief Get the container ID for a HID device.
+
+			Since version 0.12.0, @ref HID_API_VERSION >= HID_API_MAKE_VERSION(0, 12, 0)
+
+			This function returns the `DEVPKEY_Device_ContainerId` property of
+			the given device. This can be used to correlate different
+			interfaces/ports on the same hardware device.
+
+			@ingroup API
+			@param dev A device handle returned from hid_open().
+			@param guid The device's container ID on return.
+
+			@returns
+				This function returns 0 on success and -1 on error.
+		*/
+		int HID_API_EXPORT_CALL hid_winapi_get_container_id(hid_device *dev, GUID *container_id);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff -pruN 0.11.2-1/windows/hid.c 0.12.0-1/windows/hid.c
--- 0.11.2-1/windows/hid.c	2022-01-03 12:53:10.000000000 +0000
+++ 0.12.0-1/windows/hid.c	2022-05-25 12:52:59.000000000 +0000
@@ -5,9 +5,9 @@
  Alan Ott
  Signal 11 Software
 
- 8/22/2009
+ libusb/hidapi Team
 
- Copyright 2009, All Rights Reserved.
+ Copyright 2022, All Rights Reserved.
 
  At the discretion of the user of this library,
  this software may be licensed under the terms of the
@@ -21,11 +21,17 @@
 ********************************************************/
 
 #if defined(_MSC_VER) && !defined(_CRT_SECURE_NO_WARNINGS)
-// Do not warn about mbsrtowcs and wcsncpy usage.
-// https://docs.microsoft.com/cpp/c-runtime-library/security-features-in-the-crt
+/* Do not warn about wcsncpy usage.
+   https://docs.microsoft.com/cpp/c-runtime-library/security-features-in-the-crt */
 #define _CRT_SECURE_NO_WARNINGS
 #endif
 
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "hidapi.h"
+
 #include <windows.h>
 
 #ifndef _NTDEF_
@@ -33,54 +39,36 @@ typedef LONG NTSTATUS;
 #endif
 
 #ifdef __MINGW32__
-#include <devpropdef.h>
 #include <ntdef.h>
 #include <winbase.h>
+#define WC_ERR_INVALID_CHARS 0x00000080
 #endif
 
 #ifdef __CYGWIN__
 #include <ntdef.h>
+#include <wctype.h>
 #define _wcsdup wcsdup
 #endif
 
-/* The maximum number of characters that can be passed into the
-   HidD_Get*String() functions without it failing.*/
-#define MAX_STRING_WCHARS 0xFFF
-
 /*#define HIDAPI_USE_DDK*/
 
-#ifdef __cplusplus
-extern "C" {
-#endif
-	#include <setupapi.h>
-	#include <winioctl.h>
-	#ifdef HIDAPI_USE_DDK
-		#include <hidsdi.h>
-	#endif
-
-	/* Copied from inc/ddk/hidclass.h, part of the Windows DDK. */
-	#define HID_OUT_CTL_CODE(id)  \
-		CTL_CODE(FILE_DEVICE_KEYBOARD, (id), METHOD_OUT_DIRECT, FILE_ANY_ACCESS)
-	#define IOCTL_HID_GET_FEATURE                   HID_OUT_CTL_CODE(100)
-	#define IOCTL_HID_GET_INPUT_REPORT              HID_OUT_CTL_CODE(104)
-
-#ifdef __cplusplus
-} /* extern "C" */
-#endif
+#include <devpropdef.h>
+#include "hidapi_cfgmgr32.h"
+#include "hidapi_hidclass.h"
+#include "hidapi_hidsdi.h"
 
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
-#include <wctype.h>
-
-#include "hidapi.h"
 
+#ifdef MIN
 #undef MIN
+#endif
 #define MIN(x,y) ((x) < (y)? (x): (y))
 
-#ifdef __cplusplus
-extern "C" {
-#endif
+/* MAXIMUM_USB_STRING_LENGTH from usbspec.h is 255 */
+/* BLUETOOTH_DEVICE_NAME_SIZE from bluetoothapis.h is 256 */
+#define MAX_STRING_WCHARS 256
 
 static struct hid_api_version api_version = {
 	.major = HID_API_VERSION_MAJOR,
@@ -89,88 +77,97 @@ static struct hid_api_version api_versio
 };
 
 #ifndef HIDAPI_USE_DDK
-	/* Since we're not building with the DDK, and the HID header
-	   files aren't part of the SDK, we have to define all this
-	   stuff here. In lookup_functions(), the function pointers
-	   defined below are set. */
-	typedef struct _HIDD_ATTRIBUTES{
-		ULONG Size;
-		USHORT VendorID;
-		USHORT ProductID;
-		USHORT VersionNumber;
-	} HIDD_ATTRIBUTES, *PHIDD_ATTRIBUTES;
-
-	typedef USHORT USAGE;
-	typedef struct _HIDP_CAPS {
-		USAGE Usage;
-		USAGE UsagePage;
-		USHORT InputReportByteLength;
-		USHORT OutputReportByteLength;
-		USHORT FeatureReportByteLength;
-		USHORT Reserved[17];
-		USHORT fields_not_used_by_hidapi[10];
-	} HIDP_CAPS, *PHIDP_CAPS;
-	typedef void* PHIDP_PREPARSED_DATA;
-	#define HIDP_STATUS_SUCCESS 0x110000
-
-	typedef void (__stdcall *HidD_GetHidGuid_)(LPGUID hid_guid);
-	typedef BOOLEAN (__stdcall *HidD_GetAttributes_)(HANDLE device, PHIDD_ATTRIBUTES attrib);
-	typedef BOOLEAN (__stdcall *HidD_GetSerialNumberString_)(HANDLE device, PVOID buffer, ULONG buffer_len);
-	typedef BOOLEAN (__stdcall *HidD_GetManufacturerString_)(HANDLE handle, PVOID buffer, ULONG buffer_len);
-	typedef BOOLEAN (__stdcall *HidD_GetProductString_)(HANDLE handle, PVOID buffer, ULONG buffer_len);
-	typedef BOOLEAN (__stdcall *HidD_SetFeature_)(HANDLE handle, PVOID data, ULONG length);
-	typedef BOOLEAN (__stdcall *HidD_GetFeature_)(HANDLE handle, PVOID data, ULONG length);
-	typedef BOOLEAN (__stdcall *HidD_GetInputReport_)(HANDLE handle, PVOID data, ULONG length);
-	typedef BOOLEAN (__stdcall *HidD_GetIndexedString_)(HANDLE handle, ULONG string_index, PVOID buffer, ULONG buffer_len);
-	typedef BOOLEAN (__stdcall *HidD_GetPreparsedData_)(HANDLE handle, PHIDP_PREPARSED_DATA *preparsed_data);
-	typedef BOOLEAN (__stdcall *HidD_FreePreparsedData_)(PHIDP_PREPARSED_DATA preparsed_data);
-	typedef NTSTATUS (__stdcall *HidP_GetCaps_)(PHIDP_PREPARSED_DATA preparsed_data, HIDP_CAPS *caps);
-	typedef BOOLEAN (__stdcall *HidD_SetNumInputBuffers_)(HANDLE handle, ULONG number_buffers);
-
-	static HidD_GetHidGuid_ HidD_GetHidGuid;
-	static HidD_GetAttributes_ HidD_GetAttributes;
-	static HidD_GetSerialNumberString_ HidD_GetSerialNumberString;
-	static HidD_GetManufacturerString_ HidD_GetManufacturerString;
-	static HidD_GetProductString_ HidD_GetProductString;
-	static HidD_SetFeature_ HidD_SetFeature;
-	static HidD_GetFeature_ HidD_GetFeature;
-	static HidD_GetInputReport_ HidD_GetInputReport;
-	static HidD_GetIndexedString_ HidD_GetIndexedString;
-	static HidD_GetPreparsedData_ HidD_GetPreparsedData;
-	static HidD_FreePreparsedData_ HidD_FreePreparsedData;
-	static HidP_GetCaps_ HidP_GetCaps;
-	static HidD_SetNumInputBuffers_ HidD_SetNumInputBuffers;
-
-	static HMODULE lib_handle = NULL;
-	static BOOLEAN initialized = FALSE;
-
-	typedef DWORD RETURN_TYPE;
-	typedef RETURN_TYPE CONFIGRET;
-	typedef DWORD DEVNODE, DEVINST;
-	typedef DEVNODE* PDEVNODE, * PDEVINST;
-	typedef WCHAR* DEVNODEID_W, * DEVINSTID_W;
-
-#define CR_SUCCESS (0x00000000)
-#define CR_BUFFER_SMALL (0x0000001A)
-
-#define CM_LOCATE_DEVNODE_NORMAL 0x00000000
-
-#define DEVPROP_TYPEMOD_LIST 0x00002000
-
-#define DEVPROP_TYPE_STRING 0x00000012
-#define DEVPROP_TYPE_STRING_LIST (DEVPROP_TYPE_STRING|DEVPROP_TYPEMOD_LIST)
-
-	typedef CONFIGRET(__stdcall* CM_Locate_DevNodeW_)(PDEVINST pdnDevInst, DEVINSTID_W pDeviceID, ULONG ulFlags);
-	typedef CONFIGRET(__stdcall* CM_Get_Parent_)(PDEVINST pdnDevInst, DEVINST dnDevInst, ULONG ulFlags);
-	typedef CONFIGRET(__stdcall* CM_Get_DevNode_PropertyW_)(DEVINST dnDevInst, CONST DEVPROPKEY* PropertyKey, DEVPROPTYPE* PropertyType, PBYTE PropertyBuffer, PULONG PropertyBufferSize, ULONG ulFlags);
-	typedef CONFIGRET(__stdcall* CM_Get_Device_Interface_PropertyW_)(LPCWSTR pszDeviceInterface, CONST DEVPROPKEY* PropertyKey, DEVPROPTYPE* PropertyType, PBYTE PropertyBuffer, PULONG PropertyBufferSize, ULONG ulFlags);
-
-	static CM_Locate_DevNodeW_ CM_Locate_DevNodeW = NULL;
-	static CM_Get_Parent_ CM_Get_Parent = NULL;
-	static CM_Get_DevNode_PropertyW_ CM_Get_DevNode_PropertyW = NULL;
-	static CM_Get_Device_Interface_PropertyW_ CM_Get_Device_Interface_PropertyW = NULL;
+/* Since we're not building with the DDK, and the HID header
+   files aren't part of the Windows SDK, we define what we need ourselves.
+   In lookup_functions(), the function pointers
+   defined below are set. */
+
+static HidD_GetHidGuid_ HidD_GetHidGuid;
+static HidD_GetAttributes_ HidD_GetAttributes;
+static HidD_GetSerialNumberString_ HidD_GetSerialNumberString;
+static HidD_GetManufacturerString_ HidD_GetManufacturerString;
+static HidD_GetProductString_ HidD_GetProductString;
+static HidD_SetFeature_ HidD_SetFeature;
+static HidD_GetFeature_ HidD_GetFeature;
+static HidD_GetInputReport_ HidD_GetInputReport;
+static HidD_GetIndexedString_ HidD_GetIndexedString;
+static HidD_GetPreparsedData_ HidD_GetPreparsedData;
+static HidD_FreePreparsedData_ HidD_FreePreparsedData;
+static HidP_GetCaps_ HidP_GetCaps;
+static HidD_SetNumInputBuffers_ HidD_SetNumInputBuffers;
+
+static CM_Locate_DevNodeW_ CM_Locate_DevNodeW = NULL;
+static CM_Get_Parent_ CM_Get_Parent = NULL;
+static CM_Get_DevNode_PropertyW_ CM_Get_DevNode_PropertyW = NULL;
+static CM_Get_Device_Interface_PropertyW_ CM_Get_Device_Interface_PropertyW = NULL;
+static CM_Get_Device_Interface_List_SizeW_ CM_Get_Device_Interface_List_SizeW = NULL;
+static CM_Get_Device_Interface_ListW_ CM_Get_Device_Interface_ListW = NULL;
+
+static HMODULE hid_lib_handle = NULL;
+static HMODULE cfgmgr32_lib_handle = NULL;
+static BOOLEAN hidapi_initialized = FALSE;
+
+static void free_library_handles()
+{
+	if (hid_lib_handle)
+		FreeLibrary(hid_lib_handle);
+	hid_lib_handle = NULL;
+	if (cfgmgr32_lib_handle)
+		FreeLibrary(cfgmgr32_lib_handle);
+	cfgmgr32_lib_handle = NULL;
+}
+
+static int lookup_functions()
+{
+	hid_lib_handle = LoadLibraryW(L"hid.dll");
+	if (hid_lib_handle == NULL) {
+		goto err;
+	}
+
+	cfgmgr32_lib_handle = LoadLibraryW(L"cfgmgr32.dll");
+	if (cfgmgr32_lib_handle == NULL) {
+		goto err;
+	}
+
+#if defined(__GNUC__)
+# pragma GCC diagnostic push
+# pragma GCC diagnostic ignored "-Wcast-function-type"
+#endif
+#define RESOLVE(lib_handle, x) x = (x##_)GetProcAddress(lib_handle, #x); if (!x) goto err;
+
+	RESOLVE(hid_lib_handle, HidD_GetHidGuid);
+	RESOLVE(hid_lib_handle, HidD_GetAttributes);
+	RESOLVE(hid_lib_handle, HidD_GetSerialNumberString);
+	RESOLVE(hid_lib_handle, HidD_GetManufacturerString);
+	RESOLVE(hid_lib_handle, HidD_GetProductString);
+	RESOLVE(hid_lib_handle, HidD_SetFeature);
+	RESOLVE(hid_lib_handle, HidD_GetFeature);
+	RESOLVE(hid_lib_handle, HidD_GetInputReport);
+	RESOLVE(hid_lib_handle, HidD_GetIndexedString);
+	RESOLVE(hid_lib_handle, HidD_GetPreparsedData);
+	RESOLVE(hid_lib_handle, HidD_FreePreparsedData);
+	RESOLVE(hid_lib_handle, HidP_GetCaps);
+	RESOLVE(hid_lib_handle, HidD_SetNumInputBuffers);
+
+	RESOLVE(cfgmgr32_lib_handle, CM_Locate_DevNodeW);
+	RESOLVE(cfgmgr32_lib_handle, CM_Get_Parent);
+	RESOLVE(cfgmgr32_lib_handle, CM_Get_DevNode_PropertyW);
+	RESOLVE(cfgmgr32_lib_handle, CM_Get_Device_Interface_PropertyW);
+	RESOLVE(cfgmgr32_lib_handle, CM_Get_Device_Interface_List_SizeW);
+	RESOLVE(cfgmgr32_lib_handle, CM_Get_Device_Interface_ListW);
+
+#undef RESOLVE
+#if defined(__GNUC__)
+# pragma GCC diagnostic pop
+#endif
+
+	return 0;
+
+err:
+	free_library_handles();
+	return -1;
+}
 
-	static HMODULE cfgmgr32_lib_handle = NULL;
 #endif /* HIDAPI_USE_DDK */
 
 struct hid_device_ {
@@ -181,8 +178,7 @@ struct hid_device_ {
 		size_t input_report_length;
 		USHORT feature_report_length;
 		unsigned char *feature_buf;
-		void *last_error_str;
-		DWORD last_error_num;
+		wchar_t *last_error_str;
 		BOOL read_pending;
 		char *read_buf;
 		OVERLAPPED ol;
@@ -201,7 +197,6 @@ static hid_device *new_hid_device()
 	dev->feature_report_length = 0;
 	dev->feature_buf = NULL;
 	dev->last_error_str = NULL;
-	dev->last_error_num = 0;
 	dev->read_pending = FALSE;
 	dev->read_buf = NULL;
 	memset(&dev->ol, 0, sizeof(dev->ol));
@@ -218,7 +213,8 @@ static void free_hid_device(hid_device *
 	CloseHandle(dev->ol.hEvent);
 	CloseHandle(dev->write_ol.hEvent);
 	CloseHandle(dev->device_handle);
-	LocalFree(dev->last_error_str);
+	free(dev->last_error_str);
+	dev->last_error_str = NULL;
 	free(dev->write_buf);
 	free(dev->feature_buf);
 	free(dev->read_buf);
@@ -226,101 +222,101 @@ static void free_hid_device(hid_device *
 	free(dev);
 }
 
-static void register_error(hid_device *dev, const char *op)
+static void register_winapi_error_to_buffer(wchar_t **error_buffer, const WCHAR *op)
 {
-	WCHAR *ptr, *msg;
-	(void)op; // unreferenced  param
-	FormatMessageW(FORMAT_MESSAGE_ALLOCATE_BUFFER |
-		FORMAT_MESSAGE_FROM_SYSTEM |
-		FORMAT_MESSAGE_IGNORE_INSERTS,
+	if (!error_buffer)
+		return;
+
+	free(*error_buffer);
+	*error_buffer = NULL;
+
+	/* Only clear out error messages if NULL is passed into op */
+	if (!op) {
+		return;
+	}
+
+	WCHAR system_err_buf[1024];
+	DWORD error_code = GetLastError();
+
+	DWORD system_err_len = FormatMessageW(
+		FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
 		NULL,
-		GetLastError(),
+		error_code,
 		MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
-		(LPWSTR)&msg, 0/*sz*/,
+		system_err_buf, ARRAYSIZE(system_err_buf),
 		NULL);
 
+	DWORD op_len = (DWORD)wcslen(op);
+
+	DWORD op_prefix_len =
+		op_len
+		+ 15 /*: (0x00000000) */
+		;
+	DWORD msg_len =
+		+ op_prefix_len
+		+ system_err_len
+		;
+
+	*error_buffer = (WCHAR *)calloc(msg_len + 1, sizeof (WCHAR));
+	WCHAR *msg = *error_buffer;
+
+	if (!msg)
+		return;
+
+	int printf_written = swprintf(msg, msg_len + 1, L"%.*ls: (0x%08X) %.*ls", op_len, op, error_code, system_err_len, system_err_buf);
+
+	if (printf_written < 0)
+	{
+		/* Highly unlikely */
+		msg[0] = L'\0';
+		return;
+	}
+
 	/* Get rid of the CR and LF that FormatMessage() sticks at the
 	   end of the message. Thanks Microsoft! */
-	ptr = msg;
-	while (*ptr) {
-		if (*ptr == L'\r') {
-			*ptr = L'\0';
-			break;
-		}
-		ptr++;
+	while(msg[msg_len-1] == L'\r' || msg[msg_len-1] == L'\n' || msg[msg_len-1] == L' ')
+	{
+		msg[msg_len-1] = L'\0';
+		msg_len--;
 	}
+}
+
+static void register_winapi_error(hid_device *dev, const WCHAR *op)
+{
+	if (!dev)
+		return;
 
-	/* Store the message off in the Device entry so that
-	   the hid_error() function can pick it up. */
-	LocalFree(dev->last_error_str);
-	dev->last_error_str = msg;
+	register_winapi_error_to_buffer(&dev->last_error_str, op);
 }
 
-#ifndef HIDAPI_USE_DDK
-static int lookup_functions()
+static void register_string_error_to_buffer(wchar_t **error_buffer, const WCHAR *string_error)
 {
-	lib_handle = LoadLibraryA("hid.dll");
-	if (lib_handle) {
-#if defined(__GNUC__)
-# pragma GCC diagnostic push
-# pragma GCC diagnostic ignored "-Wcast-function-type"
-#endif
-#define RESOLVE(x) x = (x##_)GetProcAddress(lib_handle, #x); if (!x) return -1;
-		RESOLVE(HidD_GetHidGuid);
-		RESOLVE(HidD_GetAttributes);
-		RESOLVE(HidD_GetSerialNumberString);
-		RESOLVE(HidD_GetManufacturerString);
-		RESOLVE(HidD_GetProductString);
-		RESOLVE(HidD_SetFeature);
-		RESOLVE(HidD_GetFeature);
-		RESOLVE(HidD_GetInputReport);
-		RESOLVE(HidD_GetIndexedString);
-		RESOLVE(HidD_GetPreparsedData);
-		RESOLVE(HidD_FreePreparsedData);
-		RESOLVE(HidP_GetCaps);
-		RESOLVE(HidD_SetNumInputBuffers);
-#undef RESOLVE
-#if defined(__GNUC__)
-# pragma GCC diagnostic pop
-#endif
-	}
-	else
-		return -1;
+	if (!error_buffer)
+		return;
 
-	cfgmgr32_lib_handle = LoadLibraryA("cfgmgr32.dll");
-	if (cfgmgr32_lib_handle) {
-#if defined(__GNUC__)
-# pragma GCC diagnostic push
-# pragma GCC diagnostic ignored "-Wcast-function-type"
-#endif
-#define RESOLVE(x) x = (x##_)GetProcAddress(cfgmgr32_lib_handle, #x);
-		RESOLVE(CM_Locate_DevNodeW);
-		RESOLVE(CM_Get_Parent);
-		RESOLVE(CM_Get_DevNode_PropertyW);
-		RESOLVE(CM_Get_Device_Interface_PropertyW);
-#undef RESOLVE
-#if defined(__GNUC__)
-# pragma GCC diagnostic pop
-#endif
-	}
-	else {
-		CM_Locate_DevNodeW = NULL;
-		CM_Get_Parent = NULL;
-		CM_Get_DevNode_PropertyW = NULL;
-		CM_Get_Device_Interface_PropertyW = NULL;
+	free(*error_buffer);
+	*error_buffer = NULL;
+
+	if (string_error) {
+		*error_buffer = _wcsdup(string_error);
 	}
+}
 
-	return 0;
+static void register_string_error(hid_device *dev, const WCHAR *string_error)
+{
+	if (!dev)
+		return;
+
+	register_string_error_to_buffer(&dev->last_error_str, string_error);
 }
-#endif
 
-static HANDLE open_device(const char *path, BOOL open_rw)
+static HANDLE open_device(const wchar_t *path, BOOL open_rw)
 {
 	HANDLE handle;
 	DWORD desired_access = (open_rw)? (GENERIC_WRITE | GENERIC_READ): 0;
 	DWORD share_mode = FILE_SHARE_READ|FILE_SHARE_WRITE;
 
-	handle = CreateFileA(path,
+	handle = CreateFileW(path,
 		desired_access,
 		share_mode,
 		NULL,
@@ -344,12 +340,11 @@ HID_API_EXPORT const char* HID_API_CALL
 int HID_API_EXPORT hid_init(void)
 {
 #ifndef HIDAPI_USE_DDK
-	if (!initialized) {
+	if (!hidapi_initialized) {
 		if (lookup_functions() < 0) {
-			hid_exit();
 			return -1;
 		}
-		initialized = TRUE;
+		hidapi_initialized = TRUE;
 	}
 #endif
 	return 0;
@@ -358,57 +353,80 @@ int HID_API_EXPORT hid_init(void)
 int HID_API_EXPORT hid_exit(void)
 {
 #ifndef HIDAPI_USE_DDK
-	if (lib_handle)
-		FreeLibrary(lib_handle);
-	lib_handle = NULL;
-	if (cfgmgr32_lib_handle)
-		FreeLibrary(cfgmgr32_lib_handle);
-	cfgmgr32_lib_handle = NULL;
-	initialized = FALSE;
+	free_library_handles();
+	hidapi_initialized = FALSE;
 #endif
 	return 0;
 }
 
-static void hid_internal_get_ble_info(struct hid_device_info* dev, DEVINST dev_node)
+static void* hid_internal_get_devnode_property(DEVINST dev_node, const DEVPROPKEY* property_key, DEVPROPTYPE expected_property_type)
 {
-	ULONG len;
+	ULONG len = 0;
 	CONFIGRET cr;
 	DEVPROPTYPE property_type;
+	PBYTE property_value = NULL;
+
+	cr = CM_Get_DevNode_PropertyW(dev_node, property_key, &property_type, NULL, &len, 0);
+	if (cr != CR_BUFFER_SMALL || property_type != expected_property_type)
+		return NULL;
+
+	property_value = (PBYTE)calloc(len, sizeof(BYTE));
+	cr = CM_Get_DevNode_PropertyW(dev_node, property_key, &property_type, property_value, &len, 0);
+	if (cr != CR_SUCCESS) {
+		free(property_value);
+		return NULL;
+	}
+
+	return property_value;
+}
+
+static void* hid_internal_get_device_interface_property(const wchar_t* interface_path, const DEVPROPKEY* property_key, DEVPROPTYPE expected_property_type)
+{
+	ULONG len = 0;
+	CONFIGRET cr;
+	DEVPROPTYPE property_type;
+	PBYTE property_value = NULL;
+
+	cr = CM_Get_Device_Interface_PropertyW(interface_path, property_key, &property_type, NULL, &len, 0);
+	if (cr != CR_BUFFER_SMALL || property_type != expected_property_type)
+		return NULL;
+
+	property_value = (PBYTE)calloc(len, sizeof(BYTE));
+	cr = CM_Get_Device_Interface_PropertyW(interface_path, property_key, &property_type, property_value, &len, 0);
+	if (cr != CR_SUCCESS) {
+		free(property_value);
+		return NULL;
+	}
 
-	static DEVPROPKEY DEVPKEY_NAME = { { 0xb725f130, 0x47ef, 0x101a, 0xa5, 0xf1, 0x02, 0x60, 0x8c, 0x9e, 0xeb, 0xac }, 10 }; // DEVPROP_TYPE_STRING
-	static DEVPROPKEY PKEY_DeviceInterface_Bluetooth_DeviceAddress = { { 0x2BD67D8B, 0x8BEB, 0x48D5, 0x87, 0xE0, 0x6C, 0xDA, 0x34, 0x28, 0x04, 0x0A }, 1 }; // DEVPROP_TYPE_STRING
-	static DEVPROPKEY PKEY_DeviceInterface_Bluetooth_Manufacturer = { { 0x2BD67D8B, 0x8BEB, 0x48D5, 0x87, 0xE0, 0x6C, 0xDA, 0x34, 0x28, 0x04, 0x0A }, 4 }; // DEVPROP_TYPE_STRING
+	return property_value;
+}
 
+static void hid_internal_get_ble_info(struct hid_device_info* dev, DEVINST dev_node)
+{
+	wchar_t *manufacturer_string, *serial_number, *product_string;
 	/* Manufacturer String */
-	len = 0;
-	cr = CM_Get_DevNode_PropertyW(dev_node, &PKEY_DeviceInterface_Bluetooth_Manufacturer, &property_type, NULL, &len, 0);
-	if (cr == CR_BUFFER_SMALL && property_type == DEVPROP_TYPE_STRING) {
+	manufacturer_string = hid_internal_get_devnode_property(dev_node, (const DEVPROPKEY*)&PKEY_DeviceInterface_Bluetooth_Manufacturer, DEVPROP_TYPE_STRING);
+	if (manufacturer_string) {
 		free(dev->manufacturer_string);
-		dev->manufacturer_string = (wchar_t*)calloc(len, sizeof(BYTE));
-		CM_Get_DevNode_PropertyW(dev_node, &PKEY_DeviceInterface_Bluetooth_Manufacturer, &property_type, (PBYTE)dev->manufacturer_string, &len, 0);
+		dev->manufacturer_string = manufacturer_string;
 	}
 
 	/* Serial Number String (MAC Address) */
-	len = 0;
-	cr = CM_Get_DevNode_PropertyW(dev_node, &PKEY_DeviceInterface_Bluetooth_DeviceAddress, &property_type, NULL, &len, 0);
-	if (cr == CR_BUFFER_SMALL && property_type == DEVPROP_TYPE_STRING) {
+	serial_number = hid_internal_get_devnode_property(dev_node, (const DEVPROPKEY*)&PKEY_DeviceInterface_Bluetooth_DeviceAddress, DEVPROP_TYPE_STRING);
+	if (serial_number) {
 		free(dev->serial_number);
-		dev->serial_number = (wchar_t*)calloc(len, sizeof(BYTE));
-		CM_Get_DevNode_PropertyW(dev_node, &PKEY_DeviceInterface_Bluetooth_DeviceAddress, &property_type, (PBYTE)dev->serial_number, &len, 0);
+		dev->serial_number = serial_number;
 	}
 
 	/* Get devnode grandparent to reach out Bluetooth LE device node */
-	cr = CM_Get_Parent(&dev_node, dev_node, 0);
-	if (cr != CR_SUCCESS)
+	if (CM_Get_Parent(&dev_node, dev_node, 0) != CR_SUCCESS)
 		return;
 
 	/* Product String */
-	len = 0;
-	cr = CM_Get_DevNode_PropertyW(dev_node, &DEVPKEY_NAME, &property_type, NULL, &len, 0);
-	if (cr == CR_BUFFER_SMALL && property_type == DEVPROP_TYPE_STRING) {
+	product_string = hid_internal_get_devnode_property(dev_node, &DEVPKEY_NAME, DEVPROP_TYPE_STRING);
+	if (product_string) {
 		free(dev->product_string);
-		dev->product_string = (wchar_t*)calloc(len, sizeof(BYTE));
-		CM_Get_DevNode_PropertyW(dev_node, &DEVPKEY_NAME, &property_type, (PBYTE)dev->product_string, &len, 0);
+		dev->product_string = product_string;
 	}
 }
 
@@ -437,43 +455,15 @@ static int hid_internal_get_interface_nu
 	return interface_number;
 }
 
-static void hid_internal_get_info(struct hid_device_info* dev)
+static void hid_internal_get_info(const wchar_t* interface_path, struct hid_device_info* dev)
 {
-	const char *tmp = NULL;
-	wchar_t *interface_path = NULL, *device_id = NULL, *compatible_ids = NULL, *hardware_ids = NULL;
-	mbstate_t state;
-	ULONG len;
+	wchar_t *device_id = NULL, *compatible_ids = NULL, *hardware_ids = NULL;
 	CONFIGRET cr;
-	DEVPROPTYPE property_type;
 	DEVINST dev_node;
 
-	static DEVPROPKEY DEVPKEY_Device_InstanceId = { { 0x78c34fc8, 0x104a, 0x4aca, 0x9e, 0xa4, 0x52, 0x4d, 0x52, 0x99, 0x6e, 0x57 }, 256 }; // DEVPROP_TYPE_STRING
-	static DEVPROPKEY DEVPKEY_Device_HardwareIds = { { 0xa45c254e, 0xdf1c, 0x4efd, 0x80, 0x20, 0x67, 0xd1, 0x46, 0xa8, 0x50, 0xe0}, 3 }; // DEVPROP_TYPE_STRING_LIST
-	static DEVPROPKEY DEVPKEY_Device_CompatibleIds = { { 0xa45c254e, 0xdf1c, 0x4efd, 0x80, 0x20, 0x67, 0xd1, 0x46, 0xa8, 0x50, 0xe0}, 4 }; // DEVPROP_TYPE_STRING_LIST
-
-	if (!CM_Get_Device_Interface_PropertyW ||
-		!CM_Locate_DevNodeW ||
-		!CM_Get_Parent ||
-		!CM_Get_DevNode_PropertyW)
-		goto end;
-
-	tmp = dev->path;
-
-	len = (ULONG)strlen(tmp);
-	interface_path = (wchar_t*)calloc(len + 1, sizeof(wchar_t));
-	memset(&state, 0, sizeof(state));
-
-	if (mbsrtowcs(interface_path, &tmp, len, &state) == (size_t)-1)
-		goto end;
-
 	/* Get the device id from interface path */
-	len = 0;
-	cr = CM_Get_Device_Interface_PropertyW(interface_path, &DEVPKEY_Device_InstanceId, &property_type, NULL, &len, 0);
-	if (cr == CR_BUFFER_SMALL && property_type == DEVPROP_TYPE_STRING) {
-		device_id = (wchar_t*)calloc(len, sizeof(BYTE));
-		cr = CM_Get_Device_Interface_PropertyW(interface_path, &DEVPKEY_Device_InstanceId, &property_type, (PBYTE)device_id, &len, 0);
-	}
-	if (cr != CR_SUCCESS)
+	device_id = hid_internal_get_device_interface_property(interface_path, &DEVPKEY_Device_InstanceId, DEVPROP_TYPE_STRING);
+	if (!device_id)
 		goto end;
 
 	/* Open devnode from device id */
@@ -482,16 +472,11 @@ static void hid_internal_get_info(struct
 		goto end;
 
 	/* Get the hardware ids from devnode */
-	len = 0;
-	cr = CM_Get_DevNode_PropertyW(dev_node, &DEVPKEY_Device_HardwareIds, &property_type, NULL, &len, 0);
-	if (cr == CR_BUFFER_SMALL && property_type == DEVPROP_TYPE_STRING_LIST) {
-		hardware_ids = (wchar_t*)calloc(len, sizeof(BYTE));
-		cr = CM_Get_DevNode_PropertyW(dev_node, &DEVPKEY_Device_HardwareIds, &property_type, (PBYTE)hardware_ids, &len, 0);
-	}
-	if (cr != CR_SUCCESS)
+	hardware_ids = hid_internal_get_devnode_property(dev_node, &DEVPKEY_Device_HardwareIds, DEVPROP_TYPE_STRING_LIST);
+	if (!hardware_ids)
 		goto end;
 
-	// Search for interface number in hardware ids
+	/* Search for interface number in hardware ids */
 	for (wchar_t* hardware_id = hardware_ids; *hardware_id; hardware_id += wcslen(hardware_id) + 1) {
 		/* Normalize to upper case */
 		for (wchar_t* p = hardware_id; *p; ++p) *p = towupper(*p);
@@ -508,13 +493,8 @@ static void hid_internal_get_info(struct
 		goto end;
 
 	/* Get the compatible ids from parent devnode */
-	len = 0;
-	cr = CM_Get_DevNode_PropertyW(dev_node, &DEVPKEY_Device_CompatibleIds, &property_type, NULL, &len, 0);
-	if (cr == CR_BUFFER_SMALL && property_type == DEVPROP_TYPE_STRING_LIST) {
-		compatible_ids = (wchar_t*)calloc(len, sizeof(BYTE));
-		cr = CM_Get_DevNode_PropertyW(dev_node, &DEVPKEY_Device_CompatibleIds, &property_type, (PBYTE)compatible_ids, &len, 0);
-	}
-	if (cr != CR_SUCCESS)
+	compatible_ids = hid_internal_get_devnode_property(dev_node, &DEVPKEY_Device_CompatibleIds, DEVPROP_TYPE_STRING_LIST);
+	if (!compatible_ids)
 		goto end;
 
 	/* Now we can parse parent's compatible IDs to find out the device bus type */
@@ -532,41 +512,52 @@ static void hid_internal_get_info(struct
 		}
 	}
 end:
-	free(interface_path);
 	free(device_id);
 	free(hardware_ids);
 	free(compatible_ids);
 }
 
-static struct hid_device_info *hid_get_device_info(const char *path, HANDLE handle)
+static char *hid_internal_UTF16toUTF8(const wchar_t *src)
 {
-	struct hid_device_info *dev = NULL; /* return object */
+	char *dst = NULL;
+	int len = WideCharToMultiByte(CP_UTF8, WC_ERR_INVALID_CHARS, src, -1, NULL, 0, NULL, NULL);
+	if (len) {
+		dst = (char*)calloc(len, sizeof(char));
+		WideCharToMultiByte(CP_UTF8, WC_ERR_INVALID_CHARS, src, -1, dst, len, NULL, NULL);
+	}
 
-	BOOL res;
+	return dst;
+}
+
+static wchar_t *hid_internal_UTF8toUTF16(const char *src)
+{
+	wchar_t *dst = NULL;
+	int len = MultiByteToWideChar(CP_UTF8, MB_ERR_INVALID_CHARS, src, -1, NULL, 0);
+	if (len) {
+		dst = (wchar_t*)calloc(len, sizeof(wchar_t));
+		MultiByteToWideChar(CP_UTF8, MB_ERR_INVALID_CHARS, src, -1, dst, len);
+	}
+
+	return dst;
+}
+
+static struct hid_device_info *hid_internal_get_device_info(const wchar_t *path, HANDLE handle)
+{
+	struct hid_device_info *dev = NULL; /* return object */
 	HIDD_ATTRIBUTES attrib;
 	PHIDP_PREPARSED_DATA pp_data = NULL;
 	HIDP_CAPS caps;
-
-	#define WSTR_LEN 512
-	wchar_t wstr[WSTR_LEN]; /* TODO: Determine Size */
+	wchar_t string[MAX_STRING_WCHARS];
 
 	/* Create the record. */
 	dev = (struct hid_device_info*)calloc(1, sizeof(struct hid_device_info));
 
 	/* Fill out the record */
 	dev->next = NULL;
-
-	if (path) {
-		size_t len = strlen(path);
-		dev->path = (char*)calloc(len + 1, sizeof(char));
-		memcpy(dev->path, path, len + 1);
-	}
-	else
-		dev->path = NULL;
+	dev->path = hid_internal_UTF16toUTF8(path);
 
 	attrib.Size = sizeof(HIDD_ATTRIBUTES);
-	res = HidD_GetAttributes(handle, &attrib);
-	if (res) {
+	if (HidD_GetAttributes(handle, &attrib)) {
 		/* VID/PID */
 		dev->vendor_id = attrib.VendorID;
 		dev->product_id = attrib.ProductID;
@@ -576,10 +567,8 @@ static struct hid_device_info *hid_get_d
 	}
 
 	/* Get the Usage Page and Usage for this device. */
-	res = HidD_GetPreparsedData(handle, &pp_data);
-	if (res) {
-		NTSTATUS nt_res = HidP_GetCaps(pp_data, &caps);
-		if (nt_res == HIDP_STATUS_SUCCESS) {
+	if (HidD_GetPreparsedData(handle, &pp_data)) {
+		if (HidP_GetCaps(pp_data, &caps) == HIDP_STATUS_SUCCESS) {
 			dev->usage_page = caps.UsagePage;
 			dev->usage = caps.Usage;
 		}
@@ -588,42 +577,36 @@ static struct hid_device_info *hid_get_d
 	}
 
 	/* Serial Number */
-	wstr[0] = L'\0';
-	res = HidD_GetSerialNumberString(handle, wstr, sizeof(wstr));
-	wstr[WSTR_LEN - 1] = L'\0';
-	dev->serial_number = _wcsdup(wstr);
+	string[0] = L'\0';
+	HidD_GetSerialNumberString(handle, string, sizeof(string));
+	string[MAX_STRING_WCHARS - 1] = L'\0';
+	dev->serial_number = _wcsdup(string);
 
 	/* Manufacturer String */
-	wstr[0] = L'\0';
-	res = HidD_GetManufacturerString(handle, wstr, sizeof(wstr));
-	wstr[WSTR_LEN - 1] = L'\0';
-	dev->manufacturer_string = _wcsdup(wstr);
+	string[0] = L'\0';
+	HidD_GetManufacturerString(handle, string, sizeof(string));
+	string[MAX_STRING_WCHARS - 1] = L'\0';
+	dev->manufacturer_string = _wcsdup(string);
 
 	/* Product String */
-	wstr[0] = L'\0';
-	res = HidD_GetProductString(handle, wstr, sizeof(wstr));
-	wstr[WSTR_LEN - 1] = L'\0';
-	dev->product_string = _wcsdup(wstr);
+	string[0] = L'\0';
+	HidD_GetProductString(handle, string, sizeof(string));
+	string[MAX_STRING_WCHARS - 1] = L'\0';
+	dev->product_string = _wcsdup(string);
 
-	hid_internal_get_info(dev);
+	hid_internal_get_info(path, dev);
 
 	return dev;
 }
 
 struct hid_device_info HID_API_EXPORT * HID_API_CALL hid_enumerate(unsigned short vendor_id, unsigned short product_id)
 {
-	BOOL res;
 	struct hid_device_info *root = NULL; /* return object */
 	struct hid_device_info *cur_dev = NULL;
 	GUID interface_class_guid;
-
-	/* Windows objects for interacting with the driver. */
-	SP_DEVINFO_DATA devinfo_data;
-	SP_DEVICE_INTERFACE_DATA device_interface_data;
-	SP_DEVICE_INTERFACE_DETAIL_DATA_A *device_interface_detail_data = NULL;
-	HDEVINFO device_info_set = INVALID_HANDLE_VALUE;
-	char driver_name[256];
-	int device_index = 0;
+	CONFIGRET cr;
+	wchar_t* device_interface_list = NULL;
+	DWORD len;
 
 	if (hid_init() < 0)
 		return NULL;
@@ -632,92 +615,49 @@ struct hid_device_info HID_API_EXPORT *
 	   https://docs.microsoft.com/windows-hardware/drivers/install/guid-devinterface-hid */
 	HidD_GetHidGuid(&interface_class_guid);
 
-	/* Initialize the Windows objects. */
-	memset(&devinfo_data, 0x0, sizeof(devinfo_data));
-	devinfo_data.cbSize = sizeof(SP_DEVINFO_DATA);
-	device_interface_data.cbSize = sizeof(SP_DEVICE_INTERFACE_DATA);
-
-	/* Get information for all the devices belonging to the HID class. */
-	device_info_set = SetupDiGetClassDevsA(&interface_class_guid, NULL, NULL, DIGCF_PRESENT | DIGCF_DEVICEINTERFACE);
-
-	/* Iterate over each device in the HID class, looking for the right one. */
-
-	for (;;) {
-		HANDLE read_handle = INVALID_HANDLE_VALUE;
-		DWORD required_size = 0;
-		HIDD_ATTRIBUTES attrib;
-
-		res = SetupDiEnumDeviceInterfaces(device_info_set,
-			NULL,
-			&interface_class_guid,
-			device_index,
-			&device_interface_data);
-
-		if (!res) {
-			/* A return of FALSE from this function means that
-			   there are no more devices. */
+	/* Get the list of all device interfaces belonging to the HID class. */
+	/* Retry in case of list was changed between calls to
+	  CM_Get_Device_Interface_List_SizeW and CM_Get_Device_Interface_ListW */
+	do {
+		cr = CM_Get_Device_Interface_List_SizeW(&len, &interface_class_guid, NULL, CM_GET_DEVICE_INTERFACE_LIST_PRESENT);
+		if (cr != CR_SUCCESS) {
 			break;
 		}
 
-		/* Call with 0-sized detail size, and let the function
-		   tell us how long the detail struct needs to be. The
-		   size is put in &required_size. */
-		res = SetupDiGetDeviceInterfaceDetailA(device_info_set,
-			&device_interface_data,
-			NULL,
-			0,
-			&required_size,
-			NULL);
-
-		/* Allocate a long enough structure for device_interface_detail_data. */
-		device_interface_detail_data = (SP_DEVICE_INTERFACE_DETAIL_DATA_A*) malloc(required_size);
-		device_interface_detail_data->cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA_A);
-
-		/* Get the detailed data for this device. The detail data gives us
-		   the device path for this device, which is then passed into
-		   CreateFile() to get a handle to the device. */
-		res = SetupDiGetDeviceInterfaceDetailA(device_info_set,
-			&device_interface_data,
-			device_interface_detail_data,
-			required_size,
-			NULL,
-			NULL);
-
-		if (!res) {
-			/* register_error(dev, "Unable to call SetupDiGetDeviceInterfaceDetail");
-			   Continue to the next device. */
-			goto cont;
+		if (device_interface_list != NULL) {
+			free(device_interface_list);
 		}
 
-		/* Populate devinfo_data. This function will return failure
-		   when the device with such index doesn't exist. We've already checked it does. */
-		res = SetupDiEnumDeviceInfo(device_info_set, device_index, &devinfo_data);
-		if (!res)
-			goto cont;
-
+		device_interface_list = (wchar_t*)calloc(len, sizeof(wchar_t));
+		if (device_interface_list == NULL) {
+			return NULL;
+		}
+		cr = CM_Get_Device_Interface_ListW(&interface_class_guid, NULL, device_interface_list, len, CM_GET_DEVICE_INTERFACE_LIST_PRESENT);
+	} while (cr == CR_BUFFER_SMALL);
 
-		/* Make sure this device has a driver bound to it. */
-		res = SetupDiGetDeviceRegistryPropertyA(device_info_set, &devinfo_data,
-			   SPDRP_DRIVER, NULL, (PBYTE)driver_name, sizeof(driver_name), NULL);
-		if (!res)
-			goto cont;
+	if (cr != CR_SUCCESS) {
+		goto end_of_function;
+	}
 
-		//wprintf(L"HandleName: %s\n", device_interface_detail_data->DevicePath);
+	/* Iterate over each device interface in the HID class, looking for the right one. */
+	for (wchar_t* device_interface = device_interface_list; *device_interface; device_interface += wcslen(device_interface) + 1) {
+		HANDLE device_handle = INVALID_HANDLE_VALUE;
+		HIDD_ATTRIBUTES attrib;
 
 		/* Open read-only handle to the device */
-		read_handle = open_device(device_interface_detail_data->DevicePath, FALSE);
+		device_handle = open_device(device_interface, FALSE);
 
-		/* Check validity of read_handle. */
-		if (read_handle == INVALID_HANDLE_VALUE) {
+		/* Check validity of device_handle. */
+		if (device_handle == INVALID_HANDLE_VALUE) {
 			/* Unable to open the device. */
-			//register_error(dev, "CreateFile");
-			goto cont;
+			continue;
 		}
 
 		/* Get the Vendor ID and Product ID for this device. */
 		attrib.Size = sizeof(HIDD_ATTRIBUTES);
-		HidD_GetAttributes(read_handle, &attrib);
-		//wprintf(L"Product/Vendor: %x %x\n", attrib.ProductID, attrib.VendorID);
+		if (!HidD_GetAttributes(device_handle, &attrib)) {
+			goto cont_close;
+		}
 
 		/* Check the VID/PID to see if we should add this
 		   device to the enumeration list. */
@@ -725,7 +665,7 @@ struct hid_device_info HID_API_EXPORT *
 		    (product_id == 0x0 || attrib.ProductID == product_id)) {
 
 			/* VID/PID match. Create the record. */
-			struct hid_device_info *tmp = hid_get_device_info(device_interface_detail_data->DevicePath, read_handle);
+			struct hid_device_info *tmp = hid_internal_get_device_info(device_interface, device_handle);
 
 			if (tmp == NULL) {
 				goto cont_close;
@@ -741,17 +681,11 @@ struct hid_device_info HID_API_EXPORT *
 		}
 
 cont_close:
-		CloseHandle(read_handle);
-cont:
-		/* We no longer need the detail data. It can be freed */
-		free(device_interface_detail_data);
-
-		device_index++;
-
+		CloseHandle(device_handle);
 	}
 
-	/* Close the device information handle. */
-	SetupDiDestroyDeviceInfoList(device_info_set);
+end_of_function:
+	free(device_interface_list);
 
 	return root;
 }
@@ -771,7 +705,6 @@ void  HID_API_EXPORT HID_API_CALL hid_fr
 	}
 }
 
-
 HID_API_EXPORT hid_device * HID_API_CALL hid_open(unsigned short vendor_id, unsigned short product_id, const wchar_t *serial_number)
 {
 	/* TODO: Merge this functions with the Linux version. This function should be platform independent. */
@@ -780,6 +713,10 @@ HID_API_EXPORT hid_device * HID_API_CALL
 	hid_device *handle = NULL;
 
 	devs = hid_enumerate(vendor_id, product_id);
+	if (!devs) {
+		return NULL;
+	}
+
 	cur_dev = devs;
 	while (cur_dev) {
 		if (cur_dev->vendor_id == vendor_id &&
@@ -811,6 +748,7 @@ HID_API_EXPORT hid_device * HID_API_CALL
 HID_API_EXPORT hid_device * HID_API_CALL hid_open_path(const char *path)
 {
 	hid_device *dev = NULL;
+	wchar_t* interface_path = NULL;
 	HANDLE device_handle = INVALID_HANDLE_VALUE;
 	PHIDP_PREPARSED_DATA pp_data = NULL;
 	HIDP_CAPS caps;
@@ -818,8 +756,12 @@ HID_API_EXPORT hid_device * HID_API_CALL
 	if (hid_init() < 0)
 		goto end_of_function;
 
+	interface_path = hid_internal_UTF8toUTF16(path);
+	if (!interface_path)
+		goto end_of_function;
+
 	/* Open a handle to the device */
-	device_handle = open_device(path, TRUE);
+	device_handle = open_device(interface_path, TRUE);
 
 	/* Check validity of write_handle. */
 	if (device_handle == INVALID_HANDLE_VALUE) {
@@ -828,7 +770,7 @@ HID_API_EXPORT hid_device * HID_API_CALL
 		   them.  This is to prevent keyloggers.  However, feature reports
 		   can still be sent and received.  Retry opening the device, but
 		   without read/write access. */
-		device_handle = open_device(path, FALSE);
+		device_handle = open_device(interface_path, FALSE);
 
 		/* Check the validity of the limited device_handle. */
 		if (device_handle == INVALID_HANDLE_VALUE)
@@ -855,11 +797,15 @@ HID_API_EXPORT hid_device * HID_API_CALL
 	dev->input_report_length = caps.InputReportByteLength;
 	dev->feature_report_length = caps.FeatureReportByteLength;
 	dev->read_buf = (char*) malloc(dev->input_report_length);
-	dev->device_info = hid_get_device_info(path, dev->device_handle);
+	dev->device_info = hid_internal_get_device_info(interface_path, dev->device_handle);
 
 end_of_function:
+	free(interface_path);
 	CloseHandle(device_handle);
-	HidD_FreePreparsedData(pp_data);
+
+	if (pp_data) {
+		HidD_FreePreparsedData(pp_data);
+	}
 
 	return dev;
 }
@@ -874,7 +820,7 @@ int HID_API_EXPORT HID_API_CALL hid_writ
 	unsigned char *buf;
 
 	if (!data || (length==0)) {
-		register_error(dev, "Zero length buffer");
+		register_string_error(dev, L"Zero buffer/length");
 		return function_result;
 	}
 
@@ -901,7 +847,7 @@ int HID_API_EXPORT HID_API_CALL hid_writ
 	if (!res) {
 		if (GetLastError() != ERROR_IO_PENDING) {
 			/* WriteFile() failed. Return error. */
-			register_error(dev, "WriteFile");
+			register_winapi_error(dev, L"WriteFile");
 			goto end_of_function;
 		}
 		overlapped = TRUE;
@@ -913,7 +859,7 @@ int HID_API_EXPORT HID_API_CALL hid_writ
 		res = WaitForSingleObject(dev->write_ol.hEvent, 1000);
 		if (res != WAIT_OBJECT_0) {
 			/* There was a Timeout. */
-			register_error(dev, "WriteFile/WaitForSingleObject Timeout");
+			register_winapi_error(dev, L"hid_write/WaitForSingleObject");
 			goto end_of_function;
 		}
 
@@ -924,7 +870,7 @@ int HID_API_EXPORT HID_API_CALL hid_writ
 		}
 		else {
 			/* The Write operation failed. */
-			register_error(dev, "WriteFile");
+			register_winapi_error(dev, L"hid_write/GetOverlappedResult");
 			goto end_of_function;
 		}
 	}
@@ -955,6 +901,7 @@ int HID_API_EXPORT HID_API_CALL hid_read
 			if (GetLastError() != ERROR_IO_PENDING) {
 				/* ReadFile() has failed.
 				   Clean up and return error. */
+				register_winapi_error(dev, L"ReadFile");
 				CancelIo(dev->device_handle);
 				dev->read_pending = FALSE;
 				goto end_of_function;
@@ -1001,10 +948,12 @@ int HID_API_EXPORT HID_API_CALL hid_read
 			memcpy(data, dev->read_buf, copy_len);
 		}
 	}
+	if (!res) {
+		register_winapi_error(dev, L"hid_read_timeout/GetOverlappedResult");
+	}
 
 end_of_function:
 	if (!res) {
-		register_error(dev, "GetOverlappedResult");
 		return -1;
 	}
 
@@ -1048,7 +997,7 @@ int HID_API_EXPORT HID_API_CALL hid_send
 	res = HidD_SetFeature(dev->device_handle, (PVOID)buf, (DWORD) length_to_send);
 
 	if (!res) {
-		register_error(dev, "HidD_SetFeature");
+		register_winapi_error(dev, L"HidD_SetFeature");
 		return -1;
 	}
 
@@ -1072,7 +1021,7 @@ static int hid_get_report(hid_device *de
 	if (!res) {
 		if (GetLastError() != ERROR_IO_PENDING) {
 			/* DeviceIoControl() failed. Return error. */
-			register_error(dev, "Get Input/Feature Report DeviceIoControl");
+			register_winapi_error(dev, L"Get Input/Feature Report DeviceIoControl");
 			return -1;
 		}
 	}
@@ -1082,7 +1031,7 @@ static int hid_get_report(hid_device *de
 	res = GetOverlappedResult(dev->device_handle, &ol, &bytes_returned, TRUE/*wait*/);
 	if (!res) {
 		/* The operation failed. */
-		register_error(dev, "Get Input/Feature Report GetOverLappedResult");
+		register_winapi_error(dev, L"Get Input/Feature Report GetOverLappedResult");
 		return -1;
 	}
 
@@ -1112,39 +1061,69 @@ void HID_API_EXPORT HID_API_CALL hid_clo
 {
 	if (!dev)
 		return;
+
 	CancelIo(dev->device_handle);
 	free_hid_device(dev);
 }
 
 int HID_API_EXPORT_CALL HID_API_CALL hid_get_manufacturer_string(hid_device *dev, wchar_t *string, size_t maxlen)
 {
-	if (!dev->device_info || !string || !maxlen)
+	if (!dev->device_info)
+	{
+		register_string_error(dev, L"NULL device/info");
+		return -1;
+	}
+
+	if (!string || !maxlen)
+	{
+		register_string_error(dev, L"Zero buffer/length");
 		return -1;
+	}
 
 	wcsncpy(string, dev->device_info->manufacturer_string, maxlen);
-	string[maxlen] = L'\0';
+	string[maxlen - 1] = L'\0';
 
 	return 0;
 }
 
 int HID_API_EXPORT_CALL HID_API_CALL hid_get_product_string(hid_device *dev, wchar_t *string, size_t maxlen)
 {
-	if (!dev->device_info || !string || !maxlen)
+	if (!dev->device_info)
+	{
+		register_string_error(dev, L"NULL device/info");
+		return -1;
+	}
+
+	if (!string || !maxlen)
+	{
+		register_string_error(dev, L"Zero buffer/length");
 		return -1;
+	}
+
 
 	wcsncpy(string, dev->device_info->product_string, maxlen);
-	string[maxlen] = L'\0';
+	string[maxlen - 1] = L'\0';
 
 	return 0;
 }
 
 int HID_API_EXPORT_CALL HID_API_CALL hid_get_serial_number_string(hid_device *dev, wchar_t *string, size_t maxlen)
 {
-	if (!dev->device_info || !string || !maxlen)
+	if (!dev->device_info)
+	{
+		register_string_error(dev, L"NULL device/info");
 		return -1;
+	}
+
+	if (!string || !maxlen)
+	{
+		register_string_error(dev, L"Zero buffer/length");
+		return -1;
+	}
+
 
 	wcsncpy(string, dev->device_info->serial_number, maxlen);
-	string[maxlen] = L'\0';
+	string[maxlen - 1] = L'\0';
 
 	return 0;
 }
@@ -1155,92 +1134,78 @@ int HID_API_EXPORT_CALL HID_API_CALL hid
 
 	res = HidD_GetIndexedString(dev->device_handle, string_index, string, sizeof(wchar_t) * (DWORD) MIN(maxlen, MAX_STRING_WCHARS));
 	if (!res) {
-		register_error(dev, "HidD_GetIndexedString");
+		register_winapi_error(dev, L"HidD_GetIndexedString");
 		return -1;
 	}
 
 	return 0;
 }
 
-
-HID_API_EXPORT const wchar_t * HID_API_CALL  hid_error(hid_device *dev)
+int HID_API_EXPORT_CALL hid_winapi_get_container_id(hid_device *dev, GUID *container_id)
 {
-	if (dev) {
-		if (dev->last_error_str == NULL)
-			return L"Success";
-		return (wchar_t*)dev->last_error_str;
-	}
+	wchar_t *interface_path = NULL, *device_id = NULL;
+	CONFIGRET cr = CR_FAILURE;
+	DEVINST dev_node;
+	DEVPROPTYPE property_type;
+	ULONG len;
 
-	// Global error messages are not (yet) implemented on Windows.
-	return L"hid_error for global errors is not implemented yet";
-}
+	if (!container_id)
+	{
+		register_string_error(dev, L"Invalid Container ID");
+		return -1;
+	}
 
+	interface_path = hid_internal_UTF8toUTF16(dev->device_info->path);
+	if (!interface_path)
+	{
+		register_string_error(dev, L"Path conversion failure");
+		goto end;
+	}
 
-/*#define PICPGM*/
-/*#define S11*/
-#define P32
-#ifdef S11
-  unsigned short VendorID = 0xa0a0;
-	unsigned short ProductID = 0x0001;
-#endif
+	/* Get the device id from interface path */
+	device_id = hid_internal_get_device_interface_property(interface_path, &DEVPKEY_Device_InstanceId, DEVPROP_TYPE_STRING);
+	if (!device_id)
+	{
+		register_string_error(dev, L"Failed to get device interface property InstanceId");
+		goto end;
+	}
 
-#ifdef P32
-  unsigned short VendorID = 0x04d8;
-	unsigned short ProductID = 0x3f;
-#endif
+	/* Open devnode from device id */
+	cr = CM_Locate_DevNodeW(&dev_node, (DEVINSTID_W)device_id, CM_LOCATE_DEVNODE_NORMAL);
+	if (cr != CR_SUCCESS)
+	{
+		register_string_error(dev, L"Failed to locate device node");
+		goto end;
+	}
 
+	/* Get the container id from devnode */
+	len = sizeof(*container_id);
+	cr = CM_Get_DevNode_PropertyW(dev_node, &DEVPKEY_Device_ContainerId, &property_type, (PBYTE)container_id, &len, 0);
+	if (cr == CR_SUCCESS && property_type != DEVPROP_TYPE_GUID)
+		cr = CR_FAILURE;
 
-#ifdef PICPGM
-  unsigned short VendorID = 0x04d8;
-  unsigned short ProductID = 0x0033;
-#endif
+	if (cr != CR_SUCCESS)
+		register_string_error(dev, L"Failed to read ContainerId property from device node");
 
+end:
+	free(interface_path);
+	free(device_id);
 
-#if 0
-int __cdecl main(int argc, char* argv[])
-{
-	int res;
-	unsigned char buf[65];
+	return cr == CR_SUCCESS ? 0 : -1;
+}
 
-	UNREFERENCED_PARAMETER(argc);
-	UNREFERENCED_PARAMETER(argv);
 
-	/* Set up the command buffer. */
-	memset(buf,0x00,sizeof(buf));
-	buf[0] = 0;
-	buf[1] = 0x81;
-
-
-	/* Open the device. */
-	int handle = open(VendorID, ProductID, L"12345");
-	if (handle < 0)
-		printf("unable to open device\n");
-
-
-	/* Toggle LED (cmd 0x80) */
-	buf[1] = 0x80;
-	res = write(handle, buf, 65);
-	if (res < 0)
-		printf("Unable to write()\n");
-
-	/* Request state (cmd 0x81) */
-	buf[1] = 0x81;
-	write(handle, buf, 65);
-	if (res < 0)
-		printf("Unable to write() (2)\n");
-
-	/* Read requested state */
-	read(handle, buf, 65);
-	if (res < 0)
-		printf("Unable to read()\n");
-
-	/* Print out the returned buffer. */
-	for (int i = 0; i < 4; i++)
-		printf("buf[%d]: %d\n", i, buf[i]);
+HID_API_EXPORT const wchar_t * HID_API_CALL  hid_error(hid_device *dev)
+{
+	if (dev) {
+		if (dev->last_error_str == NULL)
+			return L"Success";
+		return (wchar_t*)dev->last_error_str;
+	}
 
-	return 0;
+	/* Global error messages are not (yet) implemented on Windows. */
+	return L"hid_error for global errors is not implemented yet";
 }
-#endif
 
 #ifdef __cplusplus
 } /* extern "C" */
diff -pruN 0.11.2-1/windows/hidtest.vcproj 0.12.0-1/windows/hidtest.vcproj
--- 0.11.2-1/windows/hidtest.vcproj	2022-01-03 12:53:10.000000000 +0000
+++ 0.12.0-1/windows/hidtest.vcproj	2022-05-25 12:52:59.000000000 +0000
@@ -40,7 +40,7 @@
 			<Tool
 				Name="VCCLCompilerTool"
 				Optimization="0"
-				AdditionalIncludeDirectories="..\hidapi"
+				AdditionalIncludeDirectories="..\hidapi;."
 				MinimalRebuild="true"
 				BasicRuntimeChecks="3"
 				RuntimeLibrary="3"
@@ -115,7 +115,7 @@
 				Name="VCCLCompilerTool"
 				Optimization="2"
 				EnableIntrinsicFunctions="true"
-				AdditionalIncludeDirectories="..\hidapi"
+				AdditionalIncludeDirectories="..\hidapi;."
 				RuntimeLibrary="2"
 				EnableFunctionLevelLinking="true"
 				WarningLevel="3"
diff -pruN 0.11.2-1/windows/hidtest.vcxproj 0.12.0-1/windows/hidtest.vcxproj
--- 0.11.2-1/windows/hidtest.vcxproj	2022-01-03 12:53:10.000000000 +0000
+++ 0.12.0-1/windows/hidtest.vcxproj	2022-05-25 12:52:59.000000000 +0000
@@ -30,6 +30,7 @@
       <PlatformToolset Condition="'$(VisualStudioVersion)'=='14'">v140</PlatformToolset>
       <PlatformToolset Condition="'$(VisualStudioVersion)'=='15'">v141</PlatformToolset>
       <PlatformToolset Condition="'$(VisualStudioVersion)'=='16'">v142</PlatformToolset>
+      <PlatformToolset Condition="'$(VisualStudioVersion)'=='17'">v143</PlatformToolset>
     <CharacterSet>MultiByte</CharacterSet>
     <WholeProgramOptimization>true</WholeProgramOptimization>
   </PropertyGroup>
@@ -40,6 +41,7 @@
     <PlatformToolset Condition="'$(VisualStudioVersion)'=='14'">v140</PlatformToolset>
     <PlatformToolset Condition="'$(VisualStudioVersion)'=='15'">v141</PlatformToolset>
     <PlatformToolset Condition="'$(VisualStudioVersion)'=='16'">v142</PlatformToolset>
+    <PlatformToolset Condition="'$(VisualStudioVersion)'=='17'">v143</PlatformToolset>
     <CharacterSet>MultiByte</CharacterSet>
     <WholeProgramOptimization>true</WholeProgramOptimization>
   </PropertyGroup>
@@ -50,6 +52,7 @@
     <PlatformToolset Condition="'$(VisualStudioVersion)'=='14'">v140</PlatformToolset>
     <PlatformToolset Condition="'$(VisualStudioVersion)'=='15'">v141</PlatformToolset>
     <PlatformToolset Condition="'$(VisualStudioVersion)'=='16'">v142</PlatformToolset>
+    <PlatformToolset Condition="'$(VisualStudioVersion)'=='17'">v143</PlatformToolset>
     <CharacterSet>MultiByte</CharacterSet>
   </PropertyGroup>
   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
@@ -59,6 +62,7 @@
     <PlatformToolset Condition="'$(VisualStudioVersion)'=='14'">v140</PlatformToolset>
     <PlatformToolset Condition="'$(VisualStudioVersion)'=='15'">v141</PlatformToolset>
     <PlatformToolset Condition="'$(VisualStudioVersion)'=='16'">v142</PlatformToolset>
+    <PlatformToolset Condition="'$(VisualStudioVersion)'=='17'">v143</PlatformToolset>
     <CharacterSet>MultiByte</CharacterSet>
   </PropertyGroup>
   <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
@@ -87,7 +91,7 @@
   <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
     <ClCompile>
       <Optimization>Disabled</Optimization>
-      <AdditionalIncludeDirectories>..\hidapi;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <AdditionalIncludeDirectories>..\hidapi;.;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
       <MinimalRebuild>true</MinimalRebuild>
       <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
       <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
@@ -105,7 +109,7 @@
   <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
     <ClCompile>
       <Optimization>Disabled</Optimization>
-      <AdditionalIncludeDirectories>..\hidapi;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <AdditionalIncludeDirectories>..\hidapi;.;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
       <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
       <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
       <WarningLevel>Level3</WarningLevel>
@@ -122,7 +126,7 @@
     <ClCompile>
       <Optimization>MaxSpeed</Optimization>
       <IntrinsicFunctions>true</IntrinsicFunctions>
-      <AdditionalIncludeDirectories>..\hidapi;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <AdditionalIncludeDirectories>..\hidapi;.;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
       <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
       <FunctionLevelLinking>true</FunctionLevelLinking>
       <WarningLevel>Level3</WarningLevel>
@@ -142,7 +146,7 @@
     <ClCompile>
       <Optimization>MaxSpeed</Optimization>
       <IntrinsicFunctions>true</IntrinsicFunctions>
-      <AdditionalIncludeDirectories>..\hidapi;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <AdditionalIncludeDirectories>..\hidapi;.;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
       <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
       <FunctionLevelLinking>true</FunctionLevelLinking>
       <WarningLevel>Level3</WarningLevel>
diff -pruN 0.11.2-1/windows/Makefile.mingw 0.12.0-1/windows/Makefile.mingw
--- 0.11.2-1/windows/Makefile.mingw	2022-01-03 12:53:10.000000000 +0000
+++ 0.12.0-1/windows/Makefile.mingw	2022-05-25 12:52:59.000000000 +0000
@@ -11,9 +11,9 @@ all: hidtest libhidapi.dll
 CC=gcc
 COBJS=hid.o ../hidtest/test.o
 OBJS=$(COBJS)
-CFLAGS=-I../hidapi -g -c
-LIBS= -lsetupapi
-DLL_LDFLAGS = -mwindows -lsetupapi
+CFLAGS=-I../hidapi -I. -g -c
+LIBS=
+DLL_LDFLAGS = -mwindows
 
 hidtest: $(OBJS)
 	$(CC) -g $^ $(LIBS) -o hidtest
