Add Windows compatibility

Make build compatible with Windows using MSYS2 MINGW64 compiler. Add a small compatibility file for functions that don't exist in MINGW64.

Signed-off-by: Julien Vanier <jvanier@gmail.com>
This commit is contained in:
Julien Vanier
2025-05-02 09:16:25 -04:00
parent 3a7c00b931
commit b3dccab6a6
11 changed files with 119 additions and 32 deletions

View File

@@ -6,14 +6,14 @@ CFLAGS += -O2 -Wall -g `pkg-config --cflags libxml-2.0 libusb-1.0`
LDFLAGS += `pkg-config --libs libxml-2.0 libusb-1.0`
prefix := /usr/local
QDL_SRCS := firehose.c qdl.c sahara.c util.c patch.c program.c read.c ufs.c usb.c ux.c
QDL_SRCS := firehose.c qdl.c sahara.c util.c patch.c program.c read.c ufs.c usb.c ux.c oscompat.c
QDL_OBJS := $(QDL_SRCS:.c=.o)
RAMDUMP_SRCS := ramdump.c sahara.c usb.c util.c ux.c
RAMDUMP_SRCS := ramdump.c sahara.c usb.c util.c ux.c oscompat.c
RAMDUMP_OBJS := $(RAMDUMP_SRCS:.c=.o)
KS_OUT := ks
KS_SRCS := ks.c sahara.c util.c ux.c
KS_SRCS := ks.c sahara.c util.c ux.c oscompat.c
KS_OBJS := $(KS_SRCS:.c=.o)
default: $(QDL) $(RAMDUMP) $(KS_OUT)

View File

@@ -36,22 +36,20 @@
#include <assert.h>
#include <ctype.h>
#include <dirent.h>
#include <err.h>
#include <errno.h>
#include <fcntl.h>
#include <poll.h>
#include <stdbool.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <termios.h>
#include <time.h>
#include <unistd.h>
#include <libxml/parser.h>
#include <libxml/tree.h>
#include "qdl.h"
#include "ufs.h"
#include "oscompat.h"
enum {
FIREHOSE_ACK = 0,
@@ -534,7 +532,10 @@ static int firehose_read_op(struct qdl_device *qdl, struct read_op *read_op, int
}
left -= chunk_size;
#ifndef _WIN32
// on mac/linux, every other response is empty
expect_empty = true;
#endif
}
ret = firehose_read(qdl, 10000, firehose_generic_parser, NULL);

8
ks.c
View File

@@ -2,20 +2,22 @@
#include <assert.h>
#include <ctype.h>
#include <dirent.h>
#include <err.h>
#include <errno.h>
#include <fcntl.h>
#include <getopt.h>
#include <poll.h>
#include <stdbool.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <termios.h>
#include <unistd.h>
#include "qdl.h"
#include "oscompat.h"
#ifdef _WIN32
const char *__progname = "ks";
#endif
static struct qdl_device qdl;

16
oscompat.c Normal file
View File

@@ -0,0 +1,16 @@
#include "oscompat.h"
#ifdef _WIN32
const char *__progname = "qdl";
void timeradd(const struct timeval *a, const struct timeval *b, struct timeval *result) {
result->tv_sec = a->tv_sec + b->tv_sec;
result->tv_usec = a->tv_usec + b->tv_usec;
if (result->tv_usec >= 1000000) {
result->tv_sec += 1;
result->tv_usec -= 1000000;
}
}
#endif // _WIN32

25
oscompat.h Normal file
View File

@@ -0,0 +1,25 @@
#ifndef __OSCOMPAT_H__
#define __OSCOMPAT_H__
#ifndef _WIN32
#include <err.h>
#else // _WIN32
#include <sys/time.h>
#include <stdbool.h>
// TODO: improve err functions
#define err(code, ...) do { ux_err(__VA_ARGS__); exit(code); } while(false)
#define errx(code, ...) do { ux_err(__VA_ARGS__); exit(code); } while(false)
#define warn(...) ux_info(__VA_ARGS__)
#define warnx(...) ux_info(__VA_ARGS__)
void timeradd(const struct timeval *a, const struct timeval *b, struct timeval *result);
#endif
#endif

View File

@@ -28,6 +28,7 @@
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#define _FILE_OFFSET_BITS 64
#include <errno.h>
#include <fcntl.h>
#include <string.h>

6
qdl.c
View File

@@ -29,7 +29,6 @@
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#include <err.h>
#include <errno.h>
#include <getopt.h>
#include <stdbool.h>
@@ -42,6 +41,11 @@
#include "qdl.h"
#include "patch.h"
#include "ufs.h"
#include "oscompat.h"
#ifdef _WIN32
const char *__progname = "qdl";
#endif
#define MAX_USBFS_BULK_SIZE (16*1024)

View File

@@ -5,6 +5,11 @@
#include "qdl.h"
#ifdef _WIN32
const char *__progname = "ramdump";
#endif
bool qdl_debug;
static void print_usage(void)

View File

@@ -32,20 +32,17 @@
#include <assert.h>
#include <ctype.h>
#include <dirent.h>
#include <err.h>
#include <errno.h>
#include <fcntl.h>
#include <fnmatch.h>
#include <inttypes.h>
#include <poll.h>
#include <stdbool.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <termios.h>
#include <unistd.h>
#include "qdl.h"
#include "oscompat.h"
#define MIN(x, y) ((x) < (y) ? (x) : (y))
@@ -305,7 +302,7 @@ static int sahara_done(struct qdl_device *qdl, struct sahara_pkt *pkt)
static ssize_t sahara_debug64_one(struct qdl_device *qdl,
struct sahara_debug_region64 region,
int ramdump_dir)
const char *ramdump_path)
{
struct sahara_pkt read_req;
uint64_t remain;
@@ -319,7 +316,10 @@ static ssize_t sahara_debug64_one(struct qdl_device *qdl,
if (!buf)
return -1;
fd = openat(ramdump_dir, region.filename, O_WRONLY | O_CREAT, 0644);
char path[PATH_MAX];
snprintf(path, sizeof(path), "%s/%s", ramdump_path, region.filename);
fd = open(path, O_WRONLY | O_CREAT, 0644);
if (fd < 0) {
warn("failed to open \"%s\"", region.filename);
return -1;
@@ -361,6 +361,27 @@ out:
return 0;
}
// simple pattern matching function supporting * and ?
bool pattern_match(const char *pattern, const char *string) {
if (*pattern == '\0' && *string == '\0')
return true;
if (*pattern == '*') {
return pattern_match(pattern + 1, string) ||
(*string != '\0' && pattern_match(pattern, string + 1));
}
if (*pattern == '?') {
return (*string != '\0') && pattern_match(pattern + 1, string + 1);
}
if (*pattern == *string) {
return pattern_match(pattern + 1, string + 1);
}
return false;
}
static bool sahara_debug64_filter(const char *filename, const char *filter)
{
bool anymatch = false;
@@ -373,7 +394,7 @@ static bool sahara_debug64_filter(const char *filename, const char *filter)
tmp = strdup(filter);
for (s = strtok_r(tmp, ",", &ptr); s; s = strtok_r(NULL, ",", &ptr)) {
if (fnmatch(s, filename, 0) == 0) {
if (pattern_match(s, filename)) {
anymatch = true;
break;
}
@@ -384,7 +405,7 @@ static bool sahara_debug64_filter(const char *filename, const char *filter)
}
static void sahara_debug64(struct qdl_device *qdl, struct sahara_pkt *pkt,
int ramdump_dir, const char *filter)
const char *ramdump_path, const char *filter)
{
struct sahara_debug_region64 *table;
struct sahara_pkt read_req;
@@ -418,7 +439,8 @@ static void sahara_debug64(struct qdl_device *qdl, struct sahara_pkt *pkt,
ux_debug("%-2d: type 0x%" PRIx64 " address: 0x%" PRIx64 " length: 0x%" PRIx64 " region: %s filename: %s\n",
i, table[i].type, table[i].addr, table[i].length, table[i].region, table[i].filename);
n = sahara_debug64_one(qdl, table[i], ramdump_dir);
n = sahara_debug64_one(qdl, table[i], ramdump_path);
if (n < 0)
break;
}
@@ -432,18 +454,11 @@ int sahara_run(struct qdl_device *qdl, char *img_arr[], bool single_image,
const char *ramdump_path, const char *ramdump_filter)
{
struct sahara_pkt *pkt;
int ramdump_dir = -1;
char buf[4096];
char tmp[32];
bool done = false;
int n;
if (ramdump_path) {
ramdump_dir = open(ramdump_path, O_DIRECTORY);
if (ramdump_dir < 0)
err(1, "failed to open directory for ramdump output");
}
while (!done) {
n = qdl_read(qdl, buf, sizeof(buf), 1000);
if (n < 0)
@@ -473,7 +488,7 @@ int sahara_run(struct qdl_device *qdl, char *img_arr[], bool single_image,
done = true;
break;
case SAHARA_MEM_DEBUG64_CMD:
sahara_debug64(qdl, pkt, ramdump_dir, ramdump_filter);
sahara_debug64(qdl, pkt, ramdump_path, ramdump_filter);
break;
case SAHARA_READ_DATA64_CMD:
sahara_read64(qdl, pkt, img_arr, single_image);
@@ -490,8 +505,5 @@ int sahara_run(struct qdl_device *qdl, char *img_arr[], bool single_image,
}
}
if (ramdump_dir >= 0)
close(ramdump_dir);
return done ? 0 : -1;
}

3
usb.c
View File

@@ -1,12 +1,11 @@
#include <sys/ioctl.h>
#include <sys/types.h>
#include <err.h>
#include <fcntl.h>
#include <stdbool.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <libusb.h>
#include "oscompat.h"
#include "qdl.h"

22
ux.c
View File

@@ -1,5 +1,9 @@
#include <stdarg.h>
#ifdef _WIN32
#include <windows.h>
#else
#include <sys/ioctl.h>
#endif
#include <sys/time.h>
#include <unistd.h>
@@ -36,6 +40,22 @@ static void ux_clear_line(void)
ux_cur_line_length = 0;
}
#ifdef _WIN32
void ux_init(void)
{
CONSOLE_SCREEN_BUFFER_INFO csbi;
int columns;
HANDLE stdoutHandle = GetStdHandle(STD_OUTPUT_HANDLE);
if (GetConsoleScreenBufferInfo(stdoutHandle, &csbi)) {
columns = csbi.srWindow.Right - csbi.srWindow.Left + 1;
ux_width = MIN(columns, UX_PROGRESS_SIZE_MAX);
}
}
#else
void ux_init(void)
{
struct winsize w;
@@ -46,6 +66,8 @@ void ux_init(void)
ux_width = MIN(w.ws_col, UX_PROGRESS_SIZE_MAX);
}
#endif
void ux_err(const char *fmt, ...)
{
va_list ap;