mirror of
https://github.com/VARCem/MiniVHD.git
synced 2026-09-25 00:05:12 +00:00
Create cross platform fopen() wrapper
This commit is contained in:
13
minivhd.c
13
minivhd.c
@@ -197,21 +197,10 @@ static VHDError vhd_load_parent(VHDMeta* vhdm, FILE* f, const char* child_filepa
|
||||
/* (Hopefully) get the absolute path of the parent VHD */
|
||||
cwk_path_get_absolute(child_dir, u8_rel_path, abs_path, sizeof abs_path);
|
||||
free(u8_rel_path);
|
||||
#ifdef _WIN32
|
||||
uint16_t w_filemode[3] = {0x0072, 0x0062, 0x0000}; /* "rb" */
|
||||
char *w_abs_path = NULL;
|
||||
vhd_utf_convert(VHD_UTF_16_LE, abs_path, &w_abs_path);
|
||||
FILE* par_f = _wfopen((uint16_t*)w_abs_path, w_filemode);
|
||||
FILE* par_f = vhd_fopen(abs_path, "rb");
|
||||
if (par_f) {
|
||||
vhdm->parent.f = par_f;
|
||||
}
|
||||
free(w_abs_path);
|
||||
#else
|
||||
FILE* par_f = fopen(abs_path, "rb");
|
||||
if (par_f) {
|
||||
vhdm->parent.f = par_f;
|
||||
}
|
||||
#endif
|
||||
vhdm->parent.meta = calloc(1, sizeof(VHDMeta));
|
||||
return VHD_RET_OK;
|
||||
}
|
||||
|
||||
32
vhdutil.c
32
vhdutil.c
@@ -1,12 +1,14 @@
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include "vhdutil.h"
|
||||
#include <error.h>
|
||||
#ifdef _WIN32
|
||||
#include <windows.h>
|
||||
#else
|
||||
#include <iconv.h>
|
||||
#include <error.h>
|
||||
#endif
|
||||
#include "vhdutil.h"
|
||||
|
||||
int vhd_utf_convert(VHDUtfType toUTF, void* in_str, char** out_str)
|
||||
{
|
||||
@@ -56,4 +58,32 @@ size_t vhd_u16_strlen(uint16_t* u16_str) {
|
||||
u16_str += 1;
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
FILE* vhd_fopen(char* utf8_path, char* mode)
|
||||
{
|
||||
#ifdef _WIN32
|
||||
errno_t err = 0;
|
||||
char* u16_path = NULL;
|
||||
WCHAR u16_mode[5] = {0};
|
||||
/* Convert mode to UTF-16LE. Thankfully it's ASCII, which make the conversion simple...
|
||||
Note, we're on Windows, so guaranteed to be little endian, therefore, no byte swapping needed. */
|
||||
int mode_len = strlen(mode);
|
||||
if (mode_len > 0 && mode_len < 5) {
|
||||
for (int i = 0; i < mode_len; i++) {
|
||||
u16_mode[i] = (WCHAR)mode[i];
|
||||
}
|
||||
}
|
||||
/* Convert utf8_path to UTF-16LE */
|
||||
vhd_utf_convert(VHD_UTF_16_LE, utf8_path, &u16_path);
|
||||
FILE* f = _wfopen((LPCWCH)u16_path, u16_mode);
|
||||
if (f == NULL) {_get_errno(&err);}
|
||||
free(u16_path);
|
||||
/* We want to mimic (_w)fopen() behavior */
|
||||
if (err) {_set_errno(err);}
|
||||
return f;
|
||||
#else
|
||||
/* Non-Windows OS's speak UTF-8 for fopen() */
|
||||
return fopen(utf8_path, mode);
|
||||
#endif
|
||||
}
|
||||
@@ -15,4 +15,6 @@ int vhd_utf_convert(VHDUtfType toUTF, void* in_str, char** out_str);
|
||||
/* Count the number of "characters" in a null terminated UTF-16 string. Not a true character count, as surrogate
|
||||
pairs are counted as two "characters". Appears to be the Windows definition of a character for filepath
|
||||
purposes. */
|
||||
size_t vhd_u16_strlen(uint16_t* u16_str);
|
||||
size_t vhd_u16_strlen(uint16_t* u16_str);
|
||||
/* Cross platform function to open a (potentially) non-ascii filepath */
|
||||
FILE* vhd_fopen(char* utf8_path, char* mode);
|
||||
Reference in New Issue
Block a user