Skip to content

Commit 5f58cf5

Browse files
committed
make Subsurface extensions compile with MSVC
The Garmin / usb-storage code uses a bunch of POSIX functions that need Windows workarounds. Also, msvc throws up on arrays of structures with variable fields. So work around that. And the vcxproj file was of course missing the new files that we had added for our fork. Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
1 parent 51cfeb7 commit 5f58cf5

4 files changed

Lines changed: 136 additions & 19 deletions

File tree

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/garmin.c

Lines changed: 95 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -22,13 +22,37 @@
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

3357
#include "garmin.h"
3458
#include "context-private.h"
@@ -275,6 +299,49 @@ add_name(struct file_list *files, const char *name, unsigned int mtp_id)
275299
entry->mtp_id = mtp_id;
276300
}
277301

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

300368
#ifdef HAVE_LIBMTP
301369
static unsigned int
@@ -438,18 +506,14 @@ mtp_read_file(garmin_device_t *device, unsigned int file_id, dc_buffer_t *file)
438506
}
439507
#endif /* HAVE_LIBMTP */
440508

441-
#ifndef O_BINARY
442-
#define O_BINARY 0
443-
#endif
444-
445509
static dc_status_t
446510
read_file(char *pathname, int pathlen, const char *name, dc_buffer_t *file)
447511
{
448512
int fd, rc;
449513

450514
pathname[pathlen] = '/';
451515
memcpy(pathname+pathlen+1, name, FILE_NAME_SIZE);
452-
fd = open(pathname, O_RDONLY | O_BINARY);
516+
fd = dc_open(pathname, DC_O_RDONLY | DC_O_BINARY);
453517

454518
if (fd < 0)
455519
return DC_STATUS_IO;
@@ -459,7 +523,7 @@ read_file(char *pathname, int pathlen, const char *name, dc_buffer_t *file)
459523
char buffer[4096];
460524
int n;
461525

462-
n = read(fd, buffer, sizeof(buffer));
526+
n = dc_read(fd, buffer, sizeof(buffer));
463527
if (!n)
464528
break;
465529
if (n > 0) {
@@ -470,7 +534,7 @@ read_file(char *pathname, int pathlen, const char *name, dc_buffer_t *file)
470534
break;
471535
}
472536

473-
close(fd);
537+
dc_close(fd);
474538
return rc;
475539
}
476540

@@ -488,7 +552,9 @@ garmin_device_foreach (dc_device_t *abstract, dc_dive_callback_t callback, void
488552
NULL // array of file names / ids
489553
};
490554
dc_buffer_t *file;
555+
#ifndef _WIN32
491556
DIR *dir;
557+
#endif
492558
dc_status_t rc;
493559

494560
// Read the directory name from the iostream
@@ -526,6 +592,25 @@ garmin_device_foreach (dc_device_t *abstract, dc_dive_callback_t callback, void
526592
} else
527593
#endif
528594
{ // slight coding style violation to deal with the non-MTP case
595+
#ifdef _WIN32
596+
// On Windows, get_file_list takes the pathname directly
597+
rc = get_file_list(abstract, pathname, &files);
598+
if (rc != DC_STATUS_SUCCESS) {
599+
// Try the input path directly
600+
rc = get_file_list(abstract, pathname_input, &files);
601+
if (rc != DC_STATUS_SUCCESS) {
602+
ERROR (abstract->context, "Failed to open directory '%s' or '%s'.", pathname, pathname_input);
603+
free(files.array);
604+
return DC_STATUS_IO;
605+
}
606+
strcpy(pathname, pathname_input);
607+
pathlen = strlen(pathname);
608+
}
609+
if (!files.nr) {
610+
free(files.array);
611+
return rc;
612+
}
613+
#else
529614
dir = opendir(pathname);
530615
if (!dir) {
531616
dir = opendir(pathname_input);
@@ -543,6 +628,7 @@ garmin_device_foreach (dc_device_t *abstract, dc_dive_callback_t callback, void
543628
free(files.array);
544629
return rc;
545630
}
631+
#endif
546632
}
547633
// We found at least one file
548634
// 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/usb_storage.c

Lines changed: 23 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -23,13 +23,31 @@
2323
#include "config.h"
2424
#endif
2525

26+
#include <stdlib.h>
27+
#include <string.h>
28+
#include <errno.h>
29+
30+
#ifdef _WIN32
31+
#define WIN32_LEAN_AND_MEAN
32+
#define NOGDI
33+
#include <windows.h>
34+
#include <sys/types.h>
35+
#include <sys/stat.h>
36+
#ifndef PATH_MAX
37+
#define PATH_MAX MAX_PATH
38+
#endif
39+
#define dc_stat _stat
40+
#define dc_stat_t struct _stat
41+
#define DC_S_ISDIR(mode) (((mode) & _S_IFMT) == _S_IFDIR)
42+
#else
2643
#include <limits.h>
2744
#include <sys/types.h>
2845
#include <sys/stat.h>
2946
#include <fcntl.h>
30-
#include <stdlib.h>
31-
#include <string.h>
32-
#include <errno.h>
47+
#define dc_stat stat
48+
#define dc_stat_t struct stat
49+
#define DC_S_ISDIR(mode) S_ISDIR(mode)
50+
#endif
3351

3452
#include "common-private.h"
3553
#include "context-private.h"
@@ -70,7 +88,7 @@ dc_status_t
7088
dc_usb_storage_open (dc_iostream_t **out, dc_context_t *context, const char *name)
7189
{
7290
dc_usbstorage_t *device = NULL;
73-
struct stat st;
91+
dc_stat_t st;
7492

7593
if (out == NULL || name == NULL)
7694
return DC_STATUS_INVALIDARGS;
@@ -80,7 +98,7 @@ dc_usb_storage_open (dc_iostream_t **out, dc_context_t *context, const char *nam
8098
INFO (context, "Open MTP device");
8199
} else {
82100
INFO (context, "Open: name=%s", name);
83-
if (stat(name, &st) < 0 || !S_ISDIR(st.st_mode))
101+
if (dc_stat(name, &st) < 0 || !DC_S_ISDIR(st.st_mode))
84102
return DC_STATUS_NODEVICE;
85103
}
86104
// Allocate memory.

0 commit comments

Comments
 (0)