Skip to content

Commit abc684a

Browse files
authored
Merge pull request #104 from mikeller/windows-msvc
2 parents 56071af + e36b90a commit abc684a

7 files changed

Lines changed: 187 additions & 52 deletions

File tree

.github/workflows/build.yml

Lines changed: 33 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,7 @@ jobs:
8787
sudo apt-get install gcc-mingw-w64 binutils-mingw-w64 mingw-w64-tools
8888
- name: Install libusb
8989
env:
90-
LIBUSB_VERSION: 1.0.26
90+
LIBUSB_VERSION: 1.0.29
9191
run: |
9292
wget -c https://github.com/libusb/libusb/archive/refs/tags/v${LIBUSB_VERSION}.tar.gz
9393
tar xzf v${LIBUSB_VERSION}.tar.gz
@@ -99,13 +99,13 @@ jobs:
9999
popd
100100
- name: Install hidapi
101101
env:
102-
HIDAPI_VERSION: 0.12.0
102+
HIDAPI_VERSION: 0.15.0
103103
run: |
104104
wget -c https://github.com/libusb/hidapi/archive/refs/tags/hidapi-${HIDAPI_VERSION}.tar.gz
105105
tar xzf hidapi-${HIDAPI_VERSION}.tar.gz
106106
pushd hidapi-hidapi-${HIDAPI_VERSION}
107107
autoreconf --install --force
108-
./configure --host=${{ matrix.arch }}-w64-mingw32 LDFLAGS='-static-libgcc'
108+
./configure --host=${{ matrix.arch }}-w64-mingw32
109109
make
110110
make install DESTDIR=$PWD/../artifacts
111111
popd
@@ -127,36 +127,36 @@ jobs:
127127
name: ${{ github.job }}-${{ matrix.arch }}
128128
path: ${{ github.job }}-${{ matrix.arch }}.tar.gz
129129

130-
# msvc:
131-
#
132-
# name: Visual Studio
133-
#
134-
# runs-on: windows-latest
135-
#
136-
# strategy:
137-
# fail-fast: false
138-
# matrix:
139-
# platform: [x86, x64]
140-
#
141-
# env:
142-
# CONFIGURATION: Release
143-
#
144-
# steps:
145-
# - uses: actions/checkout@v4
146-
# - uses: msys2/setup-msys2@v2
147-
# with:
148-
# install: autoconf automake libtool pkg-config make gcc
149-
# - run: |
150-
# autoreconf --install --force
151-
# ./configure
152-
# make -C src revision.h
153-
# shell: msys2 {0}
154-
# - uses: microsoft/setup-msbuild@v2
155-
# - run: msbuild -m -p:Platform=${{ matrix.platform }} -p:Configuration=${{ env.CONFIGURATION }} contrib/msvc/libdivecomputer.vcxproj
156-
# - uses: actions/upload-artifact@v4
157-
# with:
158-
# name: ${{ github.job }}-${{ matrix.platform }}
159-
# path: contrib/msvc/${{ matrix.platform }}/${{ env.CONFIGURATION }}/bin
130+
msvc:
131+
132+
name: Visual Studio
133+
134+
runs-on: windows-latest
135+
136+
strategy:
137+
fail-fast: false
138+
matrix:
139+
platform: [x86, x64]
140+
141+
env:
142+
CONFIGURATION: Release
143+
144+
steps:
145+
- uses: actions/checkout@v4
146+
- uses: msys2/setup-msys2@v2
147+
with:
148+
install: autoconf automake libtool pkg-config make gcc
149+
- run: |
150+
autoreconf --install --force
151+
./configure
152+
make -C src revision.h
153+
shell: msys2 {0}
154+
- uses: microsoft/setup-msbuild@v2
155+
- run: msbuild -m -p:Platform=${{ matrix.platform }} -p:Configuration=${{ env.CONFIGURATION }} contrib/msvc/libdivecomputer.vcxproj
156+
- uses: actions/upload-artifact@v4
157+
with:
158+
name: ${{ github.job }}-${{ matrix.platform }}
159+
path: contrib/msvc/${{ matrix.platform }}/${{ env.CONFIGURATION }}/bin
160160

161161
android:
162162

contrib/msvc/libdivecomputer.vcxproj

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -207,6 +207,9 @@
207207
<ClCompile Include="..\..\src\divesoft_freedom_parser.c" />
208208
<ClCompile Include="..\..\src\divesystem_idive.c" />
209209
<ClCompile Include="..\..\src\divesystem_idive_parser.c" />
210+
<ClCompile Include="..\..\src\field-cache.c" />
211+
<ClCompile Include="..\..\src\garmin.c" />
212+
<ClCompile Include="..\..\src\garmin_parser.c" />
210213
<ClCompile Include="..\..\src\halcyon_symbios.c" />
211214
<ClCompile Include="..\..\src\halcyon_symbios_parser.c" />
212215
<ClCompile Include="..\..\src\hdlc.c" />
@@ -280,6 +283,7 @@
280283
<ClCompile Include="..\..\src\tecdiving_divecomputereu_parser.c" />
281284
<ClCompile Include="..\..\src\timer.c" />
282285
<ClCompile Include="..\..\src\usb.c" />
286+
<ClCompile Include="..\..\src\usb_storage.c" />
283287
<ClCompile Include="..\..\src\usbhid.c" />
284288
<ClCompile Include="..\..\src\uwatec_aladin.c" />
285289
<ClCompile Include="..\..\src\uwatec_memomouse.c" />
@@ -340,6 +344,8 @@
340344
<ClInclude Include="..\..\src\diverite_nitekq.h" />
341345
<ClInclude Include="..\..\src\divesoft_freedom.h" />
342346
<ClInclude Include="..\..\src\divesystem_idive.h" />
347+
<ClInclude Include="..\..\src\field-cache.h" />
348+
<ClInclude Include="..\..\src\garmin.h" />
343349
<ClInclude Include="..\..\src\halcyon_symbios.h" />
344350
<ClInclude Include="..\..\src\hdlc.h" />
345351
<ClInclude Include="..\..\src\hw_frog.h" />

src/field-cache.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
#include <stdarg.h>
33
#include <string.h>
44

5+
#include "platform.h"
56
#include "parser-private.h"
67
#include "field-cache.h"
78

src/garmin.c

Lines changed: 111 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -22,14 +22,39 @@
2222
#include <stdio.h>
2323
#include <stdlib.h>
2424
#include <string.h>
25-
#include <dirent.h>
26-
#include <sys/types.h>
25+
26+
#ifdef _WIN32
27+
#define WIN32_LEAN_AND_MEAN
28+
#define NOGDI
29+
#include <windows.h>
30+
#include <io.h>
31+
#include <fcntl.h>
32+
#ifndef PATH_MAX
33+
#define PATH_MAX MAX_PATH
34+
#endif
35+
#define dc_open _open
36+
#define dc_read _read
37+
#define dc_close _close
38+
#define DC_O_RDONLY _O_RDONLY
39+
#define DC_O_BINARY _O_BINARY
40+
#else
2741
#include <dirent.h>
2842
#include <sys/types.h>
2943
#include <sys/stat.h>
3044
#include <fcntl.h>
3145
#include <unistd.h>
46+
#define dc_open open
47+
#define dc_read read
48+
#define dc_close close
49+
#define DC_O_RDONLY O_RDONLY
50+
#ifdef O_BINARY
51+
#define DC_O_BINARY O_BINARY
52+
#else
53+
#define DC_O_BINARY 0
54+
#endif
55+
#endif
3256

57+
#include "platform.h"
3358
#include "garmin.h"
3459
#include "context-private.h"
3560
#include "device-private.h"
@@ -275,6 +300,54 @@ add_name(struct file_list *files, const char *name, unsigned int mtp_id)
275300
entry->mtp_id = mtp_id;
276301
}
277302

303+
#ifdef _WIN32
304+
static dc_status_t
305+
get_file_list(dc_device_t *abstract, const char *pathname, struct file_list *files)
306+
{
307+
WIN32_FIND_DATAA findData;
308+
HANDLE hFind;
309+
char searchPath[PATH_MAX];
310+
311+
DEBUG(abstract->context, "Iterating over Garmin files");
312+
313+
// Create search pattern (pathname\*.fit)
314+
snprintf(searchPath, sizeof(searchPath), "%s\\*", pathname);
315+
316+
hFind = FindFirstFileA(searchPath, &findData);
317+
if (hFind == INVALID_HANDLE_VALUE) {
318+
return DC_STATUS_IO;
319+
}
320+
321+
do {
322+
// Skip directories
323+
if (findData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
324+
continue;
325+
326+
if (!check_filename(abstract, findData.cFileName))
327+
continue;
328+
329+
dc_status_t rc = make_space(files);
330+
if (rc != DC_STATUS_SUCCESS) {
331+
FindClose(hFind);
332+
return rc;
333+
}
334+
add_name(files, findData.cFileName, 0);
335+
} while (FindNextFileA(hFind, &findData));
336+
337+
if (GetLastError() != ERROR_NO_MORE_FILES) {
338+
FindClose(hFind);
339+
return DC_STATUS_IO;
340+
}
341+
342+
FindClose(hFind);
343+
344+
DEBUG(abstract->context, "Found %d files", files->nr);
345+
346+
if (files->array)
347+
qsort(files->array, files->nr, sizeof(struct fit_file), name_cmp);
348+
return DC_STATUS_SUCCESS;
349+
}
350+
#else
278351
static dc_status_t
279352
get_file_list(dc_device_t *abstract, DIR *dir, struct file_list *files)
280353
{
@@ -296,6 +369,7 @@ get_file_list(dc_device_t *abstract, DIR *dir, struct file_list *files)
296369
qsort(files->array, files->nr, sizeof(struct fit_file), name_cmp);
297370
return DC_STATUS_SUCCESS;
298371
}
372+
#endif
299373

300374
#ifdef HAVE_LIBMTP
301375
static unsigned int
@@ -438,18 +512,14 @@ mtp_read_file(garmin_device_t *device, unsigned int file_id, dc_buffer_t *file)
438512
}
439513
#endif /* HAVE_LIBMTP */
440514

441-
#ifndef O_BINARY
442-
#define O_BINARY 0
443-
#endif
444-
445515
static dc_status_t
446516
read_file(char *pathname, int pathlen, const char *name, dc_buffer_t *file)
447517
{
448518
int fd, rc;
449519

450520
pathname[pathlen] = '/';
451521
memcpy(pathname+pathlen+1, name, FILE_NAME_SIZE);
452-
fd = open(pathname, O_RDONLY | O_BINARY);
522+
fd = dc_open(pathname, DC_O_RDONLY | DC_O_BINARY);
453523

454524
if (fd < 0)
455525
return DC_STATUS_IO;
@@ -459,7 +529,7 @@ read_file(char *pathname, int pathlen, const char *name, dc_buffer_t *file)
459529
char buffer[4096];
460530
int n;
461531

462-
n = read(fd, buffer, sizeof(buffer));
532+
n = dc_read(fd, buffer, sizeof(buffer));
463533
if (!n)
464534
break;
465535
if (n > 0) {
@@ -470,7 +540,7 @@ read_file(char *pathname, int pathlen, const char *name, dc_buffer_t *file)
470540
break;
471541
}
472542

473-
close(fd);
543+
dc_close(fd);
474544
return rc;
475545
}
476546

@@ -488,7 +558,9 @@ garmin_device_foreach (dc_device_t *abstract, dc_dive_callback_t callback, void
488558
NULL // array of file names / ids
489559
};
490560
dc_buffer_t *file;
561+
#ifndef _WIN32
491562
DIR *dir;
563+
#endif
492564
dc_status_t rc;
493565

494566
// Read the directory name from the iostream
@@ -526,6 +598,35 @@ garmin_device_foreach (dc_device_t *abstract, dc_dive_callback_t callback, void
526598
} else
527599
#endif
528600
{ // slight coding style violation to deal with the non-MTP case
601+
#ifdef _WIN32
602+
// On Windows, get_file_list takes the pathname directly
603+
rc = get_file_list(abstract, pathname, &files);
604+
if (rc != DC_STATUS_SUCCESS) {
605+
if (rc == DC_STATUS_NOMEMORY) {
606+
free(files.array);
607+
return rc;
608+
}
609+
610+
free(files.array);
611+
files.nr = 0;
612+
files.allocated = 0;
613+
files.array = NULL;
614+
615+
// Try the input path directly
616+
rc = get_file_list(abstract, pathname_input, &files);
617+
if (rc != DC_STATUS_SUCCESS) {
618+
ERROR (abstract->context, "Failed to open directory '%s' or '%s'.", pathname, pathname_input);
619+
free(files.array);
620+
return rc;
621+
}
622+
strcpy(pathname, pathname_input);
623+
pathlen = strlen(pathname);
624+
}
625+
if (!files.nr) {
626+
free(files.array);
627+
return rc;
628+
}
629+
#else
529630
dir = opendir(pathname);
530631
if (!dir) {
531632
dir = opendir(pathname_input);
@@ -543,6 +644,7 @@ garmin_device_foreach (dc_device_t *abstract, dc_dive_callback_t callback, void
543644
free(files.array);
544645
return rc;
545646
}
647+
#endif
546648
}
547649
// We found at least one file
548650
// Can we find the fingerprint entry?

src/garmin_parser.c

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1217,9 +1217,16 @@ static const struct {
12171217
#define MSG_NAME_LEN 16
12181218
static const struct msg_desc *lookup_msg_desc(unsigned short msg, int local, const char **namep)
12191219
{
1220-
static struct msg_desc local_array[16];
1220+
/*
1221+
* msg_desc has a flexible array member, so we can't create an array of them.
1222+
* Use a compatible struct for local "fake" descriptors that have no fields.
1223+
*/
1224+
struct msg_desc_stub {
1225+
unsigned char maxfield;
1226+
};
1227+
static struct msg_desc_stub local_array[16];
12211228
static char local_name[16][MSG_NAME_LEN];
1222-
struct msg_desc *desc;
1229+
struct msg_desc_stub *stub;
12231230
char *name;
12241231

12251232
/* Do we have a real one? */
@@ -1229,13 +1236,13 @@ static const struct msg_desc *lookup_msg_desc(unsigned short msg, int local, con
12291236
}
12301237

12311238
/* If not, fake it */
1232-
desc = &local_array[local];
1233-
memset(desc, 0, sizeof(*desc));
1239+
stub = &local_array[local];
1240+
memset(stub, 0, sizeof(*stub));
12341241

12351242
name = local_name[local];
12361243
snprintf(name, MSG_NAME_LEN, "msg-%d", msg);
12371244
*namep = name;
1238-
return desc;
1245+
return (const struct msg_desc *)stub;
12391246
}
12401247

12411248
static int all_data_inval(const unsigned char *data, int base_type, int len)

src/platform.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ extern "C" {
4848
#ifdef _MSC_VER
4949
#define strcasecmp _stricmp
5050
#define strncasecmp _strnicmp
51+
#define strdup _strdup
5152
#if _MSC_VER < 1800
5253
// The rint() function is only available in MSVC 2013 and later
5354
// versions. Our replacement macro isn't entirely correct, because the

0 commit comments

Comments
 (0)