diff --git a/.gitignore b/.gitignore index 3a49783..c0baedf 100644 --- a/.gitignore +++ b/.gitignore @@ -7,6 +7,8 @@ *.lo *.o *~ +.vs/ +CMakeSettings.json Doxyfile INSTALL aclocal.m4 diff --git a/.travis.yml b/.travis.yml index b331309..79d024b 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,20 +1,81 @@ language: c -compiler: - - clang - - gcc +matrix: + include: + - os: windows + compiler: + - clang + before_install: + - mkdir build && cd build && wget "https://sourceforge.net/projects/libusb-win32/files/libusb-win32-releases/1.2.6.0/libusb-win32-bin-1.2.6.0.zip" && 7z x libusb-win32-bin-1.2.6.0.zip -o"$PROGRAMFILES" && mv "$PROGRAMFILES/libusb-win32-bin-1.2.6.0" "$PROGRAMFILES/libusb-win32" + install: + choco install doxygen.install ninja + script: + cmake -GNinja .. && cmake --build . -env: - - BLD=cmake - - BLD=autoconf + - os: linux + dist: bionic + compiler: + - clang + addons: + apt: + packages: + - libusb-dev + - doxygen + - cmake + script: + - mkdir build && cd build && cmake -DCMAKE_INSTALL_PREFIX=~/.local .. && make -j2 && make install + + - os: linux + dist: bionic + compiler: + - clang + addons: + apt: + packages: + - libusb-dev + - doxygen + script: + - autoreconf -vfi && mkdir build && cd build && ../configure --prefix=$HOME/.local/ && make -j2 && make install -addons: - apt: - packages: - - libusb-dev - - doxygen - - cmake + - os: linux + dist: bionic + compiler: + - gcc + addons: + apt: + packages: + - libusb-dev + - doxygen + - cmake + script: + - mkdir build && cd build && cmake -DCMAKE_INSTALL_PREFIX=~/.local .. && make -j2 && make install -script: - - if [ $BLD == autoconf ]; then autoreconf -vfi && mkdir build && cd build && ../configure --prefix=$HOME/.local/ && make -j2 && make install; fi - - if [ $BLD == cmake ]; then mkdir build && cd build && cmake -DCMAKE_INSTALL_PREFIX=~/.local .. && make -j2 && make install; fi + - os: linux + dist: bionic + compiler: + - gcc + addons: + apt: + packages: + - libusb-dev + - doxygen + script: + - autoreconf -vfi && mkdir build && cd build && ../configure --prefix=$HOME/.local/ && make -j2 && make install + + - os: osx + osx_image: xcode12 + compiler: + - clang + before_install: + - brew install doxygen libusb-compat + script: + - mkdir build && cd build && cmake -DCMAKE_INSTALL_PREFIX=~/.local .. && make -j2 && make install + + - os: osx + osx_image: xcode12 + compiler: + - clang + before_install: + - brew install doxygen libusb-compat m4 + script: + - autoreconf -vfi && mkdir build && cd build && ../configure --prefix=$HOME/.local/ && make -j2 && make install diff --git a/CMakeLists.txt b/CMakeLists.txt index 48db870..908d649 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -18,9 +18,12 @@ SET(PACKAGE_STRING "${PACKAGE_NAME} ${PACKAGE_VERSION}") # config.h IF(WIN32) + SET(LIBNFC_SYSCONFDIR "./config" CACHE PATH "libnfc configuration directory") CONFIGURE_FILE(${CMAKE_CURRENT_SOURCE_DIR}/cmake/config_windows.h.cmake ${CMAKE_CURRENT_BINARY_DIR}/config.h) - SET(LIBNFC_SYSCONFDIR "${CMAKE_INSTALL_PREFIX}/config" CACHE PATH "libnfc configuration directory") INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR}/contrib/win32) + IF(NOT MINGW) + SET(CMAKE_C_FLAGS "-D_CRT_SECURE_NO_WARNINGS -D_CRT_NONSTDC_NO_DEPRECATE ${CMAKE_C_FLAGS}") + ENDIF(NOT MINGW) ELSE(WIN32) SET(_XOPEN_SOURCE 600) SET(SYSCONFDIR "/etc" CACHE PATH "System configuration directory") @@ -138,9 +141,12 @@ IF(NOT WIN32) IF(LIBNFC_DRIVER_PN53X_USB) SET(PKG_REQ ${PKG_REQ} "libusb") ENDIF(LIBNFC_DRIVER_PN53X_USB) + IF(LIBNFC_DRIVER_ACR122_USB) + SET(PKG_REQ ${PKG_REQ} "libusb") + ENDIF(LIBNFC_DRIVER_ACR122_USB) IF(LIBNFC_DRIVER_PCSC) SET(PKG_REQ ${PKG_REQ} "libpcsclite") - ENDIF(LIBNFC_DRIVER_ACR122) + ENDIF(LIBNFC_DRIVER_PCSC) IF(LIBNFC_DRIVER_ACR122_PCSC) SET(PKG_REQ ${PKG_REQ} "libpcsclite") ENDIF(LIBNFC_DRIVER_ACR122_PCSC) @@ -201,7 +207,7 @@ IF(WIN32) SET(RC_COMMENT "${PACKAGE_NAME} library") SET(RC_INTERNAL_NAME "${PACKAGE_NAME} ${WIN32_MODE}") SET(RC_ORIGINAL_NAME ${PACKAGE_NAME}.dll) - SET(RC_FILE_TYPE VFT_DLL) + SET(RC_FILE_TYPE 0x00000002L) CONFIGURE_FILE(${CMAKE_CURRENT_SOURCE_DIR}/contrib/win32/version.rc.in ${CMAKE_CURRENT_BINARY_DIR}/windows/libnfc.rc @ONLY) ENDIF(WIN32) diff --git a/cmake/modules/FindLIBUSB.cmake b/cmake/modules/FindLIBUSB.cmake index 14b5f98..4afd8af 100644 --- a/cmake/modules/FindLIBUSB.cmake +++ b/cmake/modules/FindLIBUSB.cmake @@ -26,9 +26,15 @@ ENDIF(CMAKE_SYSTEM_NAME MATCHES FreeBSD) IF(NOT LIBUSB_FOUND) IF(WIN32) - FIND_PATH(LIBUSB_INCLUDE_DIRS lusb0_usb.h "$ENV{ProgramFiles}/LibUSB-Win32/include" NO_SYSTEM_ENVIRONMENT_PATH) - FIND_LIBRARY(LIBUSB_LIBRARIES NAMES libusb PATHS "$ENV{ProgramFiles}/LibUSB-Win32/lib/gcc") - SET(LIBUSB_LIBRARY_DIR "$ENV{ProgramFiles}/LibUSB-Win32/bin/x86/") + IF(MINGW) + FIND_PATH(LIBUSB_INCLUDE_DIRS lusb0_usb.h "${CMAKE_CURRENT_BINARY_DIR}/LibUSB-Win32/include" NO_SYSTEM_ENVIRONMENT_PATH) + FIND_LIBRARY(LIBUSB_LIBRARIES NAMES libusb PATHS "${CMAKE_CURRENT_BINARY_DIR}/LibUSB-Win32/lib/gcc") + SET(LIBUSB_LIBRARY_DIR "${CMAKE_CURRENT_BINARY_DIR}/LibUSB-Win32/bin/x86/") + ELSE(MINGW) + FIND_PATH(LIBUSB_INCLUDE_DIRS lusb0_usb.h "$ENV{ProgramW6432}/libusb-win32/include" NO_SYSTEM_ENVIRONMENT_PATH) + FIND_LIBRARY(LIBUSB_LIBRARIES NAMES libusb PATHS "$ENV{ProgramW6432}/libusb-win32/lib/msvc_x64") + SET(LIBUSB_LIBRARY_DIR "$ENV{ProgramW6432}/libusb-win32/bin/amd64/") + ENDIF(MINGW) # Must fix up variable to avoid backslashes during packaging STRING(REGEX REPLACE "\\\\" "/" LIBUSB_LIBRARY_DIR ${LIBUSB_LIBRARY_DIR}) ELSE(WIN32) diff --git a/cmake/modules/LibnfcDrivers.cmake b/cmake/modules/LibnfcDrivers.cmake index e3806d4..7dc2503 100644 --- a/cmake/modules/LibnfcDrivers.cmake +++ b/cmake/modules/LibnfcDrivers.cmake @@ -3,13 +3,13 @@ SET(LIBNFC_DRIVER_ACR122_PCSC OFF CACHE BOOL "Enable ACR122 support (Depends on SET(LIBNFC_DRIVER_ACR122_USB ON CACHE BOOL "Enable ACR122 support (Direct USB connection)") SET(LIBNFC_DRIVER_ACR122S ON CACHE BOOL "Enable ACR122S support (Use serial port)") SET(LIBNFC_DRIVER_ARYGON ON CACHE BOOL "Enable ARYGON support (Use serial port)") -IF(WIN32) - SET(LIBNFC_DRIVER_PN532_I2C OFF CACHE BOOL "Enable PN532 I2C support (Use I2C bus)") - SET(LIBNFC_DRIVER_PN532_SPI OFF CACHE BOOL "Enable PN532 SPI support (Use SPI bus)") -ELSE(WIN32) +IF(UNIX AND NOT APPLE) SET(LIBNFC_DRIVER_PN532_I2C ON CACHE BOOL "Enable PN532 I2C support (Use I2C bus)") SET(LIBNFC_DRIVER_PN532_SPI ON CACHE BOOL "Enable PN532 SPI support (Use SPI bus)") -ENDIF(WIN32) +ELSE(UNIX AND NOT APPLE) + SET(LIBNFC_DRIVER_PN532_I2C OFF CACHE BOOL "Enable PN532 I2C support (Use I2C bus)") + SET(LIBNFC_DRIVER_PN532_SPI OFF CACHE BOOL "Enable PN532 SPI support (Use SPI bus)") +ENDIF(UNIX AND NOT APPLE) SET(LIBNFC_DRIVER_PN532_UART ON CACHE BOOL "Enable PN532 UART support (Use serial port)") SET(LIBNFC_DRIVER_PN53X_USB ON CACHE BOOL "Enable PN531 and PN531 USB support (Depends on libusb)") @@ -68,4 +68,11 @@ IF(LIBNFC_DRIVER_PN53X_USB) SET(USB_REQUIRED TRUE) ENDIF(LIBNFC_DRIVER_PN53X_USB) +IF(LIBNFC_DRIVER_ACR122_USB) + FIND_PACKAGE(LIBUSB REQUIRED) + ADD_DEFINITIONS("-DDRIVER_ACR122_USB_ENABLED") + SET(DRIVERS_SOURCES ${DRIVERS_SOURCES} "drivers/acr122_usb") + SET(USB_REQUIRED TRUE) +ENDIF(LIBNFC_DRIVER_ACR122_USB) + INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR}/libnfc/drivers) diff --git a/contrib/win32/dirent.h b/contrib/win32/dirent.h new file mode 100644 index 0000000..9cd7556 --- /dev/null +++ b/contrib/win32/dirent.h @@ -0,0 +1,870 @@ +/* + * Dirent interface for Microsoft Visual Studio + * + * Copyright (C) 2006-2012 Toni Ronkko + * This file is part of dirent. Dirent may be freely distributed + * under the MIT license. For all details and documentation, see + * https://github.com/tronkko/dirent + */ +#ifndef DIRENT_H +#define DIRENT_H + +/* + * Include windows.h without Windows Sockets 1.1 to prevent conflicts with + * Windows Sockets 2.0. + */ +#ifndef WIN32_LEAN_AND_MEAN +# define WIN32_LEAN_AND_MEAN +#endif +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* Indicates that d_type field is available in dirent structure */ +#define _DIRENT_HAVE_D_TYPE + +/* Indicates that d_namlen field is available in dirent structure */ +#define _DIRENT_HAVE_D_NAMLEN + +/* Entries missing from MSVC 6.0 */ +#if !defined(FILE_ATTRIBUTE_DEVICE) +# define FILE_ATTRIBUTE_DEVICE 0x40 +#endif + +/* File type and permission flags for stat(), general mask */ +#if !defined(S_IFMT) +# define S_IFMT _S_IFMT +#endif + +/* Directory bit */ +#if !defined(S_IFDIR) +# define S_IFDIR _S_IFDIR +#endif + +/* Character device bit */ +#if !defined(S_IFCHR) +# define S_IFCHR _S_IFCHR +#endif + +/* Pipe bit */ +#if !defined(S_IFFIFO) +# define S_IFFIFO _S_IFFIFO +#endif + +/* Regular file bit */ +#if !defined(S_IFREG) +# define S_IFREG _S_IFREG +#endif + +/* Read permission */ +#if !defined(S_IREAD) +# define S_IREAD _S_IREAD +#endif + +/* Write permission */ +#if !defined(S_IWRITE) +# define S_IWRITE _S_IWRITE +#endif + +/* Execute permission */ +#if !defined(S_IEXEC) +# define S_IEXEC _S_IEXEC +#endif + +/* Pipe */ +#if !defined(S_IFIFO) +# define S_IFIFO _S_IFIFO +#endif + +/* Block device */ +#if !defined(S_IFBLK) +# define S_IFBLK 0 +#endif + +/* Link */ +#if !defined(S_IFLNK) +# define S_IFLNK 0 +#endif + +/* Socket */ +#if !defined(S_IFSOCK) +# define S_IFSOCK 0 +#endif + +/* Read user permission */ +#if !defined(S_IRUSR) +# define S_IRUSR S_IREAD +#endif + +/* Write user permission */ +#if !defined(S_IWUSR) +# define S_IWUSR S_IWRITE +#endif + +/* Execute user permission */ +#if !defined(S_IXUSR) +# define S_IXUSR 0 +#endif + +/* Read group permission */ +#if !defined(S_IRGRP) +# define S_IRGRP 0 +#endif + +/* Write group permission */ +#if !defined(S_IWGRP) +# define S_IWGRP 0 +#endif + +/* Execute group permission */ +#if !defined(S_IXGRP) +# define S_IXGRP 0 +#endif + +/* Read others permission */ +#if !defined(S_IROTH) +# define S_IROTH 0 +#endif + +/* Write others permission */ +#if !defined(S_IWOTH) +# define S_IWOTH 0 +#endif + +/* Execute others permission */ +#if !defined(S_IXOTH) +# define S_IXOTH 0 +#endif + +/* Maximum length of file name */ +#if !defined(PATH_MAX) +# define PATH_MAX MAX_PATH +#endif +#if !defined(FILENAME_MAX) +# define FILENAME_MAX MAX_PATH +#endif +#if !defined(NAME_MAX) +# define NAME_MAX FILENAME_MAX +#endif + +/* File type flags for d_type */ +#define DT_UNKNOWN 0 +#define DT_REG S_IFREG +#define DT_DIR S_IFDIR +#define DT_FIFO S_IFIFO +#define DT_SOCK S_IFSOCK +#define DT_CHR S_IFCHR +#define DT_BLK S_IFBLK +#define DT_LNK S_IFLNK + +/* Macros for converting between st_mode and d_type */ +#define IFTODT(mode) ((mode) & S_IFMT) +#define DTTOIF(type) (type) + +/* + * File type macros. Note that block devices, sockets and links cannot be + * distinguished on Windows and the macros S_ISBLK, S_ISSOCK and S_ISLNK are + * only defined for compatibility. These macros should always return false + * on Windows. + */ +#if !defined(S_ISFIFO) +# define S_ISFIFO(mode) (((mode) & S_IFMT) == S_IFIFO) +#endif +#if !defined(S_ISDIR) +# define S_ISDIR(mode) (((mode) & S_IFMT) == S_IFDIR) +#endif +#if !defined(S_ISREG) +# define S_ISREG(mode) (((mode) & S_IFMT) == S_IFREG) +#endif +#if !defined(S_ISLNK) +# define S_ISLNK(mode) (((mode) & S_IFMT) == S_IFLNK) +#endif +#if !defined(S_ISSOCK) +# define S_ISSOCK(mode) (((mode) & S_IFMT) == S_IFSOCK) +#endif +#if !defined(S_ISCHR) +# define S_ISCHR(mode) (((mode) & S_IFMT) == S_IFCHR) +#endif +#if !defined(S_ISBLK) +# define S_ISBLK(mode) (((mode) & S_IFMT) == S_IFBLK) +#endif + +/* Return the exact length of the file name without zero terminator */ +#define _D_EXACT_NAMLEN(p) ((p)->d_namlen) + +/* Return the maximum size of a file name */ +#define _D_ALLOC_NAMLEN(p) ((PATH_MAX)+1) + + +#ifdef __cplusplus +extern "C" { +#endif + + +/* Wide-character version */ +struct _wdirent { + /* Always zero */ + long d_ino; + + /* File position within stream */ + long d_off; + + /* Structure size */ + unsigned short d_reclen; + + /* Length of name without \0 */ + size_t d_namlen; + + /* File type */ + int d_type; + + /* File name */ + wchar_t d_name[PATH_MAX+1]; +}; +typedef struct _wdirent _wdirent; + +struct _WDIR { + /* Current directory entry */ + struct _wdirent ent; + + /* Private file data */ + WIN32_FIND_DATAW data; + + /* True if data is valid */ + int cached; + + /* Win32 search handle */ + HANDLE handle; + + /* Initial directory name */ + wchar_t *patt; +}; +typedef struct _WDIR _WDIR; + +/* Multi-byte character version */ +struct dirent { + /* Always zero */ + long d_ino; + + /* File position within stream */ + long d_off; + + /* Structure size */ + unsigned short d_reclen; + + /* Length of name without \0 */ + size_t d_namlen; + + /* File type */ + int d_type; + + /* File name */ + char d_name[PATH_MAX+1]; +}; +typedef struct dirent dirent; + +struct DIR { + struct dirent ent; + struct _WDIR *wdirp; +}; +typedef struct DIR DIR; + + +/* Dirent functions */ +static DIR *opendir (const char *dirname); +static _WDIR *_wopendir (const wchar_t *dirname); + +static struct dirent *readdir (DIR *dirp); + +static int readdir_r( + DIR *dirp, struct dirent *entry, struct dirent **result); + +static int closedir (DIR *dirp); +static int _wclosedir (_WDIR *dirp); + +/* For compatibility with Symbian */ +#define wdirent _wdirent +#define WDIR _WDIR +#define wopendir _wopendir +#define wreaddir _wreaddir +#define wclosedir _wclosedir +#define wrewinddir _wrewinddir + + +/* Internal utility functions */ +static WIN32_FIND_DATAW *dirent_first (_WDIR *dirp); +static WIN32_FIND_DATAW *dirent_next (_WDIR *dirp); + +static int dirent_mbstowcs_s( + size_t *pReturnValue, + wchar_t *wcstr, + size_t sizeInWords, + const char *mbstr, + size_t count); + +static int dirent_wcstombs_s( + size_t *pReturnValue, + char *mbstr, + size_t sizeInBytes, + const wchar_t *wcstr, + size_t count); + +static void dirent_set_errno (int error); + + +/* + * Open directory stream DIRNAME for read and return a pointer to the + * internal working area that is used to retrieve individual directory + * entries. + */ +static _WDIR* +_wopendir( + const wchar_t *dirname) +{ + _WDIR *dirp = NULL; + int error; + + /* Must have directory name */ + if (dirname == NULL || dirname[0] == '\0') { + dirent_set_errno (ENOENT); + return NULL; + } + + /* Allocate new _WDIR structure */ + dirp = (_WDIR*) malloc (sizeof (struct _WDIR)); + if (dirp != NULL) { + DWORD n; + + /* Reset _WDIR structure */ + dirp->handle = INVALID_HANDLE_VALUE; + dirp->patt = NULL; + dirp->cached = 0; + + /* Compute the length of full path plus zero terminator + * + * Note that on WinRT there's no way to convert relative paths + * into absolute paths, so just assume it is an absolute path. + */ +# if defined(WINAPI_FAMILY) && (WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP) + n = wcslen(dirname); +# else + n = GetFullPathNameW (dirname, 0, NULL, NULL); +# endif + + /* Allocate room for absolute directory name and search pattern */ + dirp->patt = (wchar_t*) malloc (sizeof (wchar_t) * n + 16); + if (dirp->patt) { + + /* + * Convert relative directory name to an absolute one. This + * allows rewinddir() to function correctly even when current + * working directory is changed between opendir() and rewinddir(). + * + * Note that on WinRT there's no way to convert relative paths + * into absolute paths, so just assume it is an absolute path. + */ +# if defined(WINAPI_FAMILY) && (WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP) + wcsncpy_s(dirp->patt, n+1, dirname, n); +# else + n = GetFullPathNameW (dirname, n, dirp->patt, NULL); +# endif + if (n > 0) { + wchar_t *p; + + /* Append search pattern \* to the directory name */ + p = dirp->patt + n; + if (dirp->patt < p) { + switch (p[-1]) { + case '\\': + case '/': + case ':': + /* Directory ends in path separator, e.g. c:\temp\ */ + /*NOP*/; + break; + + default: + /* Directory name doesn't end in path separator */ + *p++ = '\\'; + } + } + *p++ = '*'; + *p = '\0'; + + /* Open directory stream and retrieve the first entry */ + if (dirent_first (dirp)) { + /* Directory stream opened successfully */ + error = 0; + } else { + /* Cannot retrieve first entry */ + error = 1; + dirent_set_errno (ENOENT); + } + + } else { + /* Cannot retrieve full path name */ + dirent_set_errno (ENOENT); + error = 1; + } + + } else { + /* Cannot allocate memory for search pattern */ + error = 1; + } + + } else { + /* Cannot allocate _WDIR structure */ + error = 1; + } + + /* Clean up in case of error */ + if (error && dirp) { + _wclosedir (dirp); + dirp = NULL; + } + + return dirp; +} + +/* + * Close directory stream opened by opendir() function. This invalidates the + * DIR structure as well as any directory entry read previously by + * _wreaddir(). + */ +static int +_wclosedir( + _WDIR *dirp) +{ + int ok; + if (dirp) { + + /* Release search handle */ + if (dirp->handle != INVALID_HANDLE_VALUE) { + FindClose (dirp->handle); + dirp->handle = INVALID_HANDLE_VALUE; + } + + /* Release search pattern */ + if (dirp->patt) { + free (dirp->patt); + dirp->patt = NULL; + } + + /* Release directory structure */ + free (dirp); + ok = /*success*/0; + + } else { + + /* Invalid directory stream */ + dirent_set_errno (EBADF); + ok = /*failure*/-1; + + } + return ok; +} + +/* Get first directory entry (internal) */ +static WIN32_FIND_DATAW* +dirent_first( + _WDIR *dirp) +{ + WIN32_FIND_DATAW *datap; + + /* Open directory and retrieve the first entry */ + dirp->handle = FindFirstFileExW( + dirp->patt, FindExInfoStandard, &dirp->data, + FindExSearchNameMatch, NULL, 0); + if (dirp->handle != INVALID_HANDLE_VALUE) { + + /* a directory entry is now waiting in memory */ + datap = &dirp->data; + dirp->cached = 1; + + } else { + + /* Failed to re-open directory: no directory entry in memory */ + dirp->cached = 0; + datap = NULL; + + } + return datap; +} + +/* + * Get next directory entry (internal). + * + * Returns + */ +static WIN32_FIND_DATAW* +dirent_next( + _WDIR *dirp) +{ + WIN32_FIND_DATAW *p; + + /* Get next directory entry */ + if (dirp->cached != 0) { + + /* A valid directory entry already in memory */ + p = &dirp->data; + dirp->cached = 0; + + } else if (dirp->handle != INVALID_HANDLE_VALUE) { + + /* Get the next directory entry from stream */ + if (FindNextFileW (dirp->handle, &dirp->data) != FALSE) { + /* Got a file */ + p = &dirp->data; + } else { + /* The very last entry has been processed or an error occurred */ + FindClose (dirp->handle); + dirp->handle = INVALID_HANDLE_VALUE; + p = NULL; + } + + } else { + + /* End of directory stream reached */ + p = NULL; + + } + + return p; +} + +/* + * Open directory stream using plain old C-string. + */ +static DIR* +opendir( + const char *dirname) +{ + struct DIR *dirp; + int error; + + /* Must have directory name */ + if (dirname == NULL || dirname[0] == '\0') { + dirent_set_errno (ENOENT); + return NULL; + } + + /* Allocate memory for DIR structure */ + dirp = (DIR*) malloc (sizeof (struct DIR)); + if (dirp) { + wchar_t wname[PATH_MAX + 1]; + size_t n; + + /* Convert directory name to wide-character string */ + error = dirent_mbstowcs_s( + &n, wname, PATH_MAX + 1, dirname, PATH_MAX + 1); + if (!error) { + + /* Open directory stream using wide-character name */ + dirp->wdirp = _wopendir (wname); + if (dirp->wdirp) { + /* Directory stream opened */ + error = 0; + } else { + /* Failed to open directory stream */ + error = 1; + } + + } else { + /* + * Cannot convert file name to wide-character string. This + * occurs if the string contains invalid multi-byte sequences or + * the output buffer is too small to contain the resulting + * string. + */ + error = 1; + } + + } else { + /* Cannot allocate DIR structure */ + error = 1; + } + + /* Clean up in case of error */ + if (error && dirp) { + free (dirp); + dirp = NULL; + } + + return dirp; +} + +/* + * Read next directory entry. + */ +static struct dirent* +readdir( + DIR *dirp) +{ + struct dirent *entry; + + /* + * Read directory entry to buffer. We can safely ignore the return value + * as entry will be set to NULL in case of error. + */ + (void) readdir_r (dirp, &dirp->ent, &entry); + + /* Return pointer to statically allocated directory entry */ + return entry; +} + +/* + * Read next directory entry into called-allocated buffer. + * + * Returns zero on success. If the end of directory stream is reached, then + * sets result to NULL and returns zero. + */ +static int +readdir_r( + DIR *dirp, + struct dirent *entry, + struct dirent **result) +{ + WIN32_FIND_DATAW *datap; + + /* Read next directory entry */ + datap = dirent_next (dirp->wdirp); + if (datap) { + size_t n; + int error; + + /* Attempt to convert file name to multi-byte string */ + error = dirent_wcstombs_s( + &n, entry->d_name, PATH_MAX + 1, datap->cFileName, PATH_MAX + 1); + + /* + * If the file name cannot be represented by a multi-byte string, + * then attempt to use old 8+3 file name. This allows traditional + * Unix-code to access some file names despite of unicode + * characters, although file names may seem unfamiliar to the user. + * + * Be ware that the code below cannot come up with a short file + * name unless the file system provides one. At least + * VirtualBox shared folders fail to do this. + */ + if (error && datap->cAlternateFileName[0] != '\0') { + error = dirent_wcstombs_s( + &n, entry->d_name, PATH_MAX + 1, + datap->cAlternateFileName, PATH_MAX + 1); + } + + if (!error) { + DWORD attr; + + /* Length of file name excluding zero terminator */ + entry->d_namlen = n - 1; + + /* File attributes */ + attr = datap->dwFileAttributes; + if ((attr & FILE_ATTRIBUTE_DEVICE) != 0) { + entry->d_type = DT_CHR; + } else if ((attr & FILE_ATTRIBUTE_DIRECTORY) != 0) { + entry->d_type = DT_DIR; + } else { + entry->d_type = DT_REG; + } + + /* Reset dummy fields */ + entry->d_ino = 0; + entry->d_off = 0; + entry->d_reclen = sizeof (struct dirent); + + } else { + + /* + * Cannot convert file name to multi-byte string so construct + * an erroneous directory entry and return that. Note that + * we cannot return NULL as that would stop the processing + * of directory entries completely. + */ + entry->d_name[0] = '?'; + entry->d_name[1] = '\0'; + entry->d_namlen = 1; + entry->d_type = DT_UNKNOWN; + entry->d_ino = 0; + entry->d_off = -1; + entry->d_reclen = 0; + + } + + /* Return pointer to directory entry */ + *result = entry; + + } else { + + /* No more directory entries */ + *result = NULL; + + } + + return /*OK*/0; +} + +/* + * Close directory stream. + */ +static int +closedir( + DIR *dirp) +{ + int ok; + if (dirp) { + + /* Close wide-character directory stream */ + ok = _wclosedir (dirp->wdirp); + dirp->wdirp = NULL; + + /* Release multi-byte character version */ + free (dirp); + + } else { + + /* Invalid directory stream */ + dirent_set_errno (EBADF); + ok = /*failure*/-1; + + } + return ok; +} + +/* Convert multi-byte string to wide character string */ +static int +dirent_mbstowcs_s( + size_t *pReturnValue, + wchar_t *wcstr, + size_t sizeInWords, + const char *mbstr, + size_t count) +{ + int error; + +#if defined(_MSC_VER) && _MSC_VER >= 1400 + + /* Microsoft Visual Studio 2005 or later */ + error = mbstowcs_s (pReturnValue, wcstr, sizeInWords, mbstr, count); + +#else + + /* Older Visual Studio or non-Microsoft compiler */ + size_t n; + + /* Convert to wide-character string (or count characters) */ + n = mbstowcs (wcstr, mbstr, sizeInWords); + if (!wcstr || n < count) { + + /* Zero-terminate output buffer */ + if (wcstr && sizeInWords) { + if (n >= sizeInWords) { + n = sizeInWords - 1; + } + wcstr[n] = 0; + } + + /* Length of resulting multi-byte string WITH zero terminator */ + if (pReturnValue) { + *pReturnValue = n + 1; + } + + /* Success */ + error = 0; + + } else { + + /* Could not convert string */ + error = 1; + + } + +#endif + + return error; +} + +/* Convert wide-character string to multi-byte string */ +static int +dirent_wcstombs_s( + size_t *pReturnValue, + char *mbstr, + size_t sizeInBytes, /* max size of mbstr */ + const wchar_t *wcstr, + size_t count) +{ + int error; + +#if defined(_MSC_VER) && _MSC_VER >= 1400 + + /* Microsoft Visual Studio 2005 or later */ + error = wcstombs_s (pReturnValue, mbstr, sizeInBytes, wcstr, count); + +#else + + /* Older Visual Studio or non-Microsoft compiler */ + size_t n; + + /* Convert to multi-byte string (or count the number of bytes needed) */ + n = wcstombs (mbstr, wcstr, sizeInBytes); + if (!mbstr || n < count) { + + /* Zero-terminate output buffer */ + if (mbstr && sizeInBytes) { + if (n >= sizeInBytes) { + n = sizeInBytes - 1; + } + mbstr[n] = '\0'; + } + + /* Length of resulting multi-bytes string WITH zero-terminator */ + if (pReturnValue) { + *pReturnValue = n + 1; + } + + /* Success */ + error = 0; + + } else { + + /* Cannot convert string */ + error = 1; + + } + +#endif + + return error; +} + +/* Set errno variable */ +static void +dirent_set_errno( + int error) +{ +#if defined(_MSC_VER) && _MSC_VER >= 1400 + + /* Microsoft Visual Studio 2005 and later */ + _set_errno (error); + +#else + + /* Non-Microsoft compiler or older Microsoft compiler */ + errno = error; + +#endif +} + + +#ifdef __cplusplus +} +#endif +#endif /*DIRENT_H*/ + diff --git a/contrib/win32/getopt.c b/contrib/win32/getopt.c new file mode 100644 index 0000000..808be80 --- /dev/null +++ b/contrib/win32/getopt.c @@ -0,0 +1,106 @@ +#include "getopt.h" // make sure you construct the header file as dictated above + +/* +* Copyright (c) 1987, 1993, 1994 +* The Regents of the University of California. All rights reserved. +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions +* are met: +* 1. Redistributions of source code must retain the above copyright +* notice, this list of conditions and the following disclaimer. +* 2. Redistributions in binary form must reproduce the above copyright +* notice, this list of conditions and the following disclaimer in the +* documentation and/or other materials provided with the distribution. +* 3. All advertising materials mentioning features or use of this software +* must display the following acknowledgement: +* This product includes software developed by the University of +* California, Berkeley and its contributors. +* 4. Neither the name of the University nor the names of its contributors +* may be used to endorse or promote products derived from this software +* without specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND +* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE +* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +* SUCH DAMAGE. +*/ + +#include +#include + +int opterr = 1, /* if error message should be printed */ + optind = 1, /* index into parent argv vector */ + optopt, /* character checked for validity */ + optreset; /* reset getopt */ +char *optarg; /* argument associated with option */ + +#define BADCH (int)'?' +#define BADARG (int)':' +#define EMSG "" + +/* + * getopt -- + * Parse argc/argv argument vector. + */ +int getopt(int nargc, char * const nargv[], const char *ostr) +{ + static char *place = EMSG; /* option letter processing */ + const char *oli; /* option letter list index */ + + if (optreset || !*place) { /* update scanning pointer */ + optreset = 0; + if (optind >= nargc || *(place = nargv[optind]) != '-') { + place = EMSG; + return (-1); + } + if (place[1] && *++place == '-') { /* found "--" */ + ++optind; + place = EMSG; + return (-1); + } + } /* option letter okay? */ + if ((optopt = (int)*place++) == (int)':' || + !(oli = strchr(ostr, optopt))) { + /* + * if the user didn't specify '-' as an option, + * assume it means -1. + */ + if (optopt == (int)'-') + return (-1); + if (!*place) + ++optind; + if (opterr && *ostr != ':') + (void)printf("illegal option -- %c\n", optopt); + return (BADCH); + } + if (*++oli != ':') { /* don't need argument */ + optarg = NULL; + if (!*place) + ++optind; + } + else { /* need an argument */ + if (*place) /* no white space */ + optarg = place; + else if (nargc <= ++optind) { /* no arg */ + place = EMSG; + if (*ostr == ':') + return (BADARG); + if (opterr) + (void)printf("option requires an argument -- %c\n", optopt); + return (BADCH); + } + else /* white space */ + optarg = nargv[optind]; + place = EMSG; + ++optind; + } + return (optopt); /* dump back option letter */ +} diff --git a/contrib/win32/getopt.h b/contrib/win32/getopt.h new file mode 100644 index 0000000..c895616 --- /dev/null +++ b/contrib/win32/getopt.h @@ -0,0 +1,13 @@ +#ifndef GETOPT_H + +#define GETOPT_H + +extern int opterr; /* if error message should be printed */ +extern int optind; /* index into parent argv vector */ +extern int optopt; /* character checked for validity */ +extern int optreset; /* reset getopt */ +extern char *optarg; /* argument associated with option */ + +int getopt(int nargc, char * const nargv[], const char *ostr); + +#endif diff --git a/contrib/win32/nfc.def b/contrib/win32/nfc.def index 5ed4097..2259817 100644 --- a/contrib/win32/nfc.def +++ b/contrib/win32/nfc.def @@ -39,6 +39,7 @@ EXPORTS nfc_device_get_supported_baud_rate_target_mode nfc_device_set_property_int nfc_device_set_property_bool + nfc_emulate_target iso14443a_crc iso14443a_crc_append iso14443b_crc @@ -50,3 +51,7 @@ EXPORTS str_nfc_modulation_type str_nfc_baud_rate str_nfc_target + pn53x_transceive + pn532_SAMConfiguration + pn53x_read_register + pn53x_write_register diff --git a/contrib/win32/nfc_msvc.def b/contrib/win32/nfc_msvc.def new file mode 100644 index 0000000..ec4dc80 --- /dev/null +++ b/contrib/win32/nfc_msvc.def @@ -0,0 +1,57 @@ +LIBRARY nfc +VERSION 1.7 + +EXPORTS + nfc_init + nfc_exit + nfc_register_driver + nfc_open + nfc_close + nfc_abort_command + nfc_list_devices + nfc_idle + nfc_initiator_init + nfc_initiator_init_secure_element + nfc_initiator_select_passive_target + nfc_initiator_list_passive_targets + nfc_initiator_poll_target + nfc_initiator_select_dep_target + nfc_initiator_poll_dep_target + nfc_initiator_deselect_target + nfc_initiator_transceive_bytes + nfc_initiator_transceive_bits + nfc_initiator_transceive_bytes_timed + nfc_initiator_transceive_bits_timed + nfc_initiator_target_is_present + nfc_target_init + nfc_target_send_bytes + nfc_target_receive_bytes + nfc_target_send_bits + nfc_target_receive_bits + nfc_strerror + nfc_strerror_r + nfc_perror + nfc_device_get_last_error + nfc_device_get_name + nfc_device_get_connstring + nfc_device_get_supported_modulation + nfc_device_get_supported_baud_rate + nfc_device_get_supported_baud_rate_target_mode + nfc_device_set_property_int + nfc_device_set_property_bool + nfc_emulate_target + iso14443a_crc + iso14443a_crc_append + iso14443b_crc + iso14443b_crc_append + iso14443a_locate_historical_bytes + nfc_free + nfc_version + nfc_device_get_information_about + str_nfc_modulation_type + str_nfc_baud_rate + str_nfc_target + pn53x_transceive + pn532_SAMConfiguration + pn53x_read_register + pn53x_write_register diff --git a/contrib/win32/version.rc.in b/contrib/win32/version.rc.in index 473d579..30f7b83 100644 --- a/contrib/win32/version.rc.in +++ b/contrib/win32/version.rc.in @@ -1,15 +1,9 @@ -#include "windows.h" - 1 VERSIONINFO FILEVERSION @VERSION_MAJOR@,@VERSION_MINOR@,@VERSION_PATCH@,0 PRODUCTVERSION @VERSION_MAJOR@,@VERSION_MINOR@,@VERSION_PATCH@,0 FILEFLAGSMASK 0x3fL -#ifdef _DEBUG - FILEFLAGS VS_FF_DEBUG|VS_FF_PRERELEASE -#else - FILEFLAGS 0L -#endif - FILEOS VOS_NT_WINDOWS32 + FILEFLAGS 0x0L + FILEOS 0x00040004L FILETYPE @RC_FILE_TYPE@ FILESUBTYPE 0x0L BEGIN diff --git a/contrib/windows.h b/contrib/windows.h index 88817db..3928d6e 100644 --- a/contrib/windows.h +++ b/contrib/windows.h @@ -48,7 +48,9 @@ # define ENOTSUP WSAEOPNOTSUPP # define ECONNABORTED WSAECONNABORTED # else +#ifndef _MSC_VER # define snprintf sprintf_s +#endif # define strdup _strdup # endif diff --git a/examples/CMakeLists.txt b/examples/CMakeLists.txt index 35a852b..1713a0c 100644 --- a/examples/CMakeLists.txt +++ b/examples/CMakeLists.txt @@ -23,7 +23,7 @@ FOREACH(source ${EXAMPLES-SOURCES}) SET(RC_COMMENT "${PACKAGE_NAME} example") SET(RC_INTERNAL_NAME ${source}) SET(RC_ORIGINAL_NAME ${source}.exe) - SET(RC_FILE_TYPE VFT_APP) + SET(RC_FILE_TYPE 0x00000001L) CONFIGURE_FILE(${CMAKE_CURRENT_SOURCE_DIR}/../contrib/win32/version.rc.in ${CMAKE_CURRENT_BINARY_DIR}/../windows/${source}.rc @ONLY) LIST(APPEND TARGETS ${CMAKE_CURRENT_BINARY_DIR}/../windows/${source}.rc) ENDIF(WIN32) diff --git a/libnfc/CMakeLists.txt b/libnfc/CMakeLists.txt index 514f60d..2867d4e 100644 --- a/libnfc/CMakeLists.txt +++ b/libnfc/CMakeLists.txt @@ -5,6 +5,9 @@ IF(WIN32) # Add in the rc for version information in the dll LIST(APPEND WINDOWS_SOURCES ${CMAKE_CURRENT_BINARY_DIR}/../windows/libnfc.rc) + IF (NOT MINGW) + LIST(APPEND WINDOWS_SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/../contrib/win32/nfc_msvc.def) + ENDIF() ENDIF(WIN32) # Library's chips @@ -26,23 +29,23 @@ IF(UART_REQUIRED) ENDIF(UART_REQUIRED) IF(I2C_REQUIRED) - IF(WIN32) - # Windows is not supported at the moment - #LIST(APPEND BUSES_SOURCES ../contrib/win32/libnfc/buses/i2c) - MESSAGE( FATAL_ERROR "I2C not (yet) supported under Windows!" ) - ELSE(WIN32) + IF(UNIX AND NOT APPLE) LIST(APPEND BUSES_SOURCES buses/i2c) - ENDIF(WIN32) + ELSE(UNIX AND NOT APPLE) + # Only Linux is supported at the moment + #LIST(APPEND BUSES_SOURCES ../contrib/win32/libnfc/buses/i2c) + MESSAGE( FATAL_ERROR "I2C is only (yet) supported in Linux!" ) + ENDIF(UNIX AND NOT APPLE) ENDIF(I2C_REQUIRED) IF(SPI_REQUIRED) - IF(WIN32) - # Windows is not supported at the moment - #LIST(APPEND BUSES_SOURCES ../contrib/win32/libnfc/buses/spi) - MESSAGE( FATAL_ERROR "SPI not (yet) supported under Windows!" ) - ELSE(WIN32) + IF(UNIX AND NOT APPLE) LIST(APPEND BUSES_SOURCES buses/spi) - ENDIF(WIN32) + ELSE(UNIX AND NOT APPLE) + # Only Linux is supported at the moment + #LIST(APPEND BUSES_SOURCES ../contrib/win32/libnfc/buses/spi) + MESSAGE( FATAL_ERROR "SPI is only (yet) supported in Linux!" ) + ENDIF(UNIX AND NOT APPLE) ENDIF(SPI_REQUIRED) INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR}/buses) @@ -63,7 +66,9 @@ INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR}) IF(LIBNFC_LOG) IF(WIN32) - SET(CMAKE_C_FLAGS "-fgnu89-inline ${CMAKE_C_FLAGS}") + IF(MINGW) + SET(CMAKE_C_FLAGS "-fgnu89-inline ${CMAKE_C_FLAGS}") + ENDIF(MINGW) LIST(APPEND LIBRARY_SOURCES log ../contrib/win32/libnfc/log-internal) ELSE(WIN32) LIST(APPEND LIBRARY_SOURCES log log-internal) @@ -88,13 +93,16 @@ SET_TARGET_PROPERTIES(nfc PROPERTIES SOVERSION 6 VERSION 6.0.0) IF(WIN32) # Libraries that are windows specific TARGET_LINK_LIBRARIES(nfc wsock32) - - ADD_CUSTOM_COMMAND( - OUTPUT libnfc.lib - COMMAND ${DLLTOOL} -d ${CMAKE_CURRENT_SOURCE_DIR}/../contrib/win32/nfc.def -l ${CMAKE_CURRENT_BINARY_DIR}/libnfc.lib ${CMAKE_CURRENT_BINARY_DIR}/libnfc.dll - DEPENDS nfc ${CMAKE_CURRENT_SOURCE_DIR}/../contrib/win32/nfc.def - ) - ADD_CUSTOM_TARGET(win32lib ALL DEPENDS libnfc.lib) + IF(MINGW) + ADD_CUSTOM_COMMAND( + OUTPUT libnfc.lib + COMMAND ${DLLTOOL} -d ${CMAKE_CURRENT_SOURCE_DIR}/../contrib/win32/nfc.def -l ${CMAKE_CURRENT_BINARY_DIR}/libnfc.lib ${CMAKE_CURRENT_BINARY_DIR}/libnfc.dll + DEPENDS nfc ${CMAKE_CURRENT_SOURCE_DIR}/../contrib/win32/nfc.def + ) + ADD_CUSTOM_TARGET(win32lib ALL DEPENDS libnfc.lib) + ELSE() + ADD_LIBRARY(win32lib ALIAS nfc) + ENDIF() # On Windows the shared (runtime) library should be either in the same # directory as the excutables or in the path, we add it to same directory diff --git a/libnfc/buses/uart.h b/libnfc/buses/uart.h index 49b822a..39d8d2f 100644 --- a/libnfc/buses/uart.h +++ b/libnfc/buses/uart.h @@ -33,7 +33,9 @@ #ifndef __NFC_BUS_UART_H__ # define __NFC_BUS_UART_H__ +#if !defined(_MSC_VER) # include +#endif # include # include diff --git a/libnfc/chips/pn53x.c b/libnfc/chips/pn53x.c index abf6682..d2b9396 100644 --- a/libnfc/chips/pn53x.c +++ b/libnfc/chips/pn53x.c @@ -1208,7 +1208,7 @@ pn53x_initiator_select_passive_target_ext(struct nfc_device *pnd, // send ICLASS_ACTIVATE_ALL command - will get timeout as we don't expect response uint8_t abtReqt[] = { 0x0a }; // iClass ACTIVATE_ALL uint8_t abtAnticol[11]; - if ((res = pn53x_initiator_transceive_bytes(pnd, abtReqt, sizeof(abtReqt), NULL, 0, timeout)) < 0) { + if (pn53x_initiator_transceive_bytes(pnd, abtReqt, sizeof(abtReqt), NULL, 0, timeout) < 0) { log_put(LOG_GROUP, LOG_CATEGORY, NFC_LOG_PRIORITY_DEBUG, "got expected timeout on iClass activate all"); //if ((res == NFC_ERFTRANS) && (CHIP_DATA(pnd)->last_status_byte == 0x01)) { // Chip timeout // continue; @@ -2064,7 +2064,7 @@ static int pn53x_ISO14443A_Barcode_is_present(struct nfc_device *pnd) } uint8_t abtRx[PN53x_EXTENDED_FRAME__DATA_MAX_LEN]; uint8_t abtRxPar[PN53x_EXTENDED_FRAME__DATA_MAX_LEN]; - if ((ret = nfc_initiator_transceive_bits(pnd, NULL, 0, NULL, abtRx, sizeof(abtRx), abtRxPar)) < 1) { + if (nfc_initiator_transceive_bits(pnd, NULL, 0, NULL, abtRx, sizeof(abtRx), abtRxPar) < 1) { failures++; } else { nfc_device_set_property_bool(pnd, NP_HANDLE_CRC, true); diff --git a/libnfc/conf.c b/libnfc/conf.c index 85a49cf..785c310 100644 --- a/libnfc/conf.c +++ b/libnfc/conf.c @@ -195,6 +195,8 @@ conf_parse_file(const char *filename, free(key); free(value); } else { + free(key); + free(value); log_put(LOG_GROUP, LOG_CATEGORY, NFC_LOG_PRIORITY_DEBUG, "Parse error on line #%d: %s", lineno, line); } } diff --git a/libnfc/drivers/acr122_usb.c b/libnfc/drivers/acr122_usb.c index b42af0e..17ae5fb 100644 --- a/libnfc/drivers/acr122_usb.c +++ b/libnfc/drivers/acr122_usb.c @@ -60,7 +60,9 @@ Thanks to d18c7db and Okko for example code #include #include #include - +#ifdef _MSC_VER +#include +#endif #include #include "nfc-internal.h" diff --git a/libnfc/drivers/pn53x_usb.c b/libnfc/drivers/pn53x_usb.c index d179666..5277878 100644 --- a/libnfc/drivers/pn53x_usb.c +++ b/libnfc/drivers/pn53x_usb.c @@ -43,7 +43,9 @@ Thanks to d18c7db and Okko for example code #include #include #include - +#ifdef _MSC_VER +#include +#endif #include #include "nfc-internal.h" @@ -817,7 +819,7 @@ pn53x_usb_set_property_bool(nfc_device *pnd, const nfc_property property, const if (NP_ACTIVATE_FIELD == property) { /* Switch on/off LED2 and Progressive Field GPIO according to ACTIVATE_FIELD option */ log_put(LOG_GROUP, LOG_CATEGORY, NFC_LOG_PRIORITY_DEBUG, "Switch progressive field %s", bEnable ? "On" : "Off"); - if ((res = pn53x_write_register(pnd, PN53X_SFR_P3, _BV(P31) | _BV(P34), bEnable ? _BV(P34) : _BV(P31))) < 0) + if (pn53x_write_register(pnd, PN53X_SFR_P3, _BV(P31) | _BV(P34), bEnable ? _BV(P34) : _BV(P31)) < 0) return NFC_ECHIP; } break; diff --git a/libnfc/nfc-internal.h b/libnfc/nfc-internal.h index 4fa2fc2..e9015ff 100644 --- a/libnfc/nfc-internal.h +++ b/libnfc/nfc-internal.h @@ -34,7 +34,9 @@ #include #include +#if !defined(_MSC_VER) # include +#endif #include "nfc/nfc.h" diff --git a/libnfc/nfc.c b/libnfc/nfc.c index 2d56bf6..6f58a71 100644 --- a/libnfc/nfc.c +++ b/libnfc/nfc.c @@ -565,24 +565,30 @@ nfc_initiator_select_passive_target(nfc_device *pnd, nfc_target *pnt) { uint8_t *abtInit = NULL; - uint8_t abtTmpInit[MAX(12, szInitData)]; + uint8_t maxAbt = MAX(12, szInitData); + uint8_t *abtTmpInit = malloc(sizeof(uint8_t) * maxAbt); size_t szInit = 0; int res; - if ((res = nfc_device_validate_modulation(pnd, N_INITIATOR, &nm)) != NFC_SUCCESS) + if ((res = nfc_device_validate_modulation(pnd, N_INITIATOR, &nm)) != NFC_SUCCESS) { + free(abtTmpInit); return res; + } if (szInitData == 0) { // Provide default values, if any prepare_initiator_data(nm, &abtInit, &szInit); + free(abtTmpInit); } else if (nm.nmt == NMT_ISO14443A) { abtInit = abtTmpInit; iso14443_cascade_uid(pbtInitData, szInitData, abtInit, &szInit); } else { abtInit = abtTmpInit; memcpy(abtInit, pbtInitData, szInitData); + free(abtTmpInit); szInit = szInitData; } - HAL(initiator_select_passive_target, pnd, nm, abtInit, szInit, pnt); + + free(abtTmpInit); } /** @ingroup initiator diff --git a/utils/CMakeLists.txt b/utils/CMakeLists.txt index 0e03880..c385552 100644 --- a/utils/CMakeLists.txt +++ b/utils/CMakeLists.txt @@ -23,7 +23,7 @@ FOREACH(source ${UTILS-SOURCES}) SET(RC_COMMENT "${PACKAGE_NAME} utility") SET(RC_INTERNAL_NAME ${source}) SET(RC_ORIGINAL_NAME ${source}.exe) - SET(RC_FILE_TYPE VFT_APP) + SET(RC_FILE_TYPE 0x00000001L) CONFIGURE_FILE(${CMAKE_CURRENT_SOURCE_DIR}/../contrib/win32/version.rc.in ${CMAKE_CURRENT_BINARY_DIR}/../windows/${source}.rc @ONLY) LIST(APPEND TARGETS ${CMAKE_CURRENT_BINARY_DIR}/../windows/${source}.rc) ENDIF(WIN32) @@ -41,6 +41,9 @@ FOREACH(source ${UTILS-SOURCES}) LIST(APPEND TARGETS ../contrib/win32/stdlib) INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR}/../contrib/win32) ENDIF(${source} MATCHES "nfc-scan-device") + IF(${source} MATCHES "nfc-read-forum-tag3") + LIST(APPEND TARGETS ${CMAKE_CURRENT_SOURCE_DIR}/../contrib/win32/getopt.c) + ENDIF() ENDIF(WIN32) ADD_EXECUTABLE(${source} ${TARGETS}) diff --git a/utils/nfc-read-forum-tag3.c b/utils/nfc-read-forum-tag3.c index bfa372b..52c6c2f 100644 --- a/utils/nfc-read-forum-tag3.c +++ b/utils/nfc-read-forum-tag3.c @@ -62,7 +62,7 @@ #include "nfc-utils.h" -#if defined(WIN32) && defined(__GNUC__) /* mingw compiler */ +#if defined(WIN32) /* mingw compiler */ #include #endif