1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345
|
diff --git a/src/iowin32.c b/src/iowin32.c
index 13a7dd73..56afa364 100644
--- a/src/iowin32.c
+++ b/src/iowin32.c
@@ -94,8 +94,16 @@ voidpf ZCALLBACK win32_open64_file_func (voidpf opaque,const void* filename,int
win32_translate_open_mode(mode,&dwDesiredAccess,&dwCreationDisposition,&dwShareMode,&dwFlagsAndAttributes);
+ // CreateFile has to be replaced with CreateFile2 because CreateFile can actually do a number of potentially unsafe (read: malware) things
+ // see: https://social.msdn.microsoft.com/Forums/office/en-US/e44eaf00-5be2-4683-868f-aca54dd658e0/u81not-able-to-create-file-using-universal-app-?forum=wpdevelop
if ((filename!=NULL) && (dwDesiredAccess != 0))
+ {
+#ifndef _WIN_EXT
hFile = CreateFile((LPCTSTR)filename, dwDesiredAccess, dwShareMode, NULL, dwCreationDisposition, dwFlagsAndAttributes, NULL);
+#else
+ hFile = CreateFile2((LPCTSTR)filename, dwDesiredAccess, dwShareMode, dwCreationDisposition, NULL);
+#endif
+ }
return win32_build_iowin(hFile);
}
@@ -110,7 +118,13 @@ voidpf ZCALLBACK win32_open64_file_funcA (voidpf opaque,const void* filename,int
win32_translate_open_mode(mode,&dwDesiredAccess,&dwCreationDisposition,&dwShareMode,&dwFlagsAndAttributes);
if ((filename!=NULL) && (dwDesiredAccess != 0))
+ {
+#ifndef _WIN_EXT
hFile = CreateFileA((LPCSTR)filename, dwDesiredAccess, dwShareMode, NULL, dwCreationDisposition, dwFlagsAndAttributes, NULL);
+#else
+ hFile = CreateFile2((LPCTSTR)filename, dwDesiredAccess, dwShareMode, dwCreationDisposition, NULL);
+#endif
+ }
return win32_build_iowin(hFile);
}
@@ -125,7 +139,13 @@ voidpf ZCALLBACK win32_open64_file_funcW (voidpf opaque,const void* filename,int
win32_translate_open_mode(mode,&dwDesiredAccess,&dwCreationDisposition,&dwShareMode,&dwFlagsAndAttributes);
if ((filename!=NULL) && (dwDesiredAccess != 0))
+ {
+#ifndef _WIN_EXT
hFile = CreateFileW((LPCWSTR)filename, dwDesiredAccess, dwShareMode, NULL, dwCreationDisposition, dwFlagsAndAttributes, NULL);
+#else
+ hFile = CreateFile2((LPCTSTR)filename, dwDesiredAccess, dwShareMode, dwCreationDisposition, NULL);
+#endif
+ }
return win32_build_iowin(hFile);
}
@@ -140,7 +160,13 @@ voidpf ZCALLBACK win32_open_file_func (voidpf opaque,const char* filename,int mo
win32_translate_open_mode(mode,&dwDesiredAccess,&dwCreationDisposition,&dwShareMode,&dwFlagsAndAttributes);
if ((filename!=NULL) && (dwDesiredAccess != 0))
+ {
+#ifndef _WIN_EXT
hFile = CreateFile((LPCTSTR)filename, dwDesiredAccess, dwShareMode, NULL, dwCreationDisposition, dwFlagsAndAttributes, NULL);
+#else
+ hFile = CreateFile2((LPCTSTR)filename, dwDesiredAccess, dwShareMode, dwCreationDisposition, NULL);
+#endif
+ }
return win32_build_iowin(hFile);
}
@@ -197,7 +223,15 @@ long ZCALLBACK win32_tell_file_func (voidpf opaque,voidpf stream)
hFile = ((WIN32FILE_IOWIN*)stream) -> hf;
if (hFile != NULL)
{
- DWORD dwSet = SetFilePointer(hFile, 0, NULL, FILE_CURRENT);
+ DWORD dwSet;
+#ifndef _WIN_EXT
+ dwSet = SetFilePointer(hFile, 0, NULL, FILE_CURRENT);
+#else
+ LARGE_INTEGER outPointer;
+ LARGE_INTEGER zero;
+ zero.QuadPart = 0;
+ dwSet = SetFilePointerEx(hFile, zero, &outPointer, FILE_CURRENT) ? outPointer.u.LowPart : INVALID_SET_FILE_POINTER;
+#endif
if (dwSet == INVALID_SET_FILE_POINTER)
{
DWORD dwErr = GetLastError();
@@ -221,7 +255,14 @@ ZPOS64_T ZCALLBACK win32_tell64_file_func (voidpf opaque, voidpf stream)
{
LARGE_INTEGER li;
li.QuadPart = 0;
+#ifndef _WIN_EXT
li.u.LowPart = SetFilePointer(hFile, li.u.LowPart, &li.u.HighPart, FILE_CURRENT);
+#else
+ LARGE_INTEGER zero;
+ LARGE_INTEGER outPointer;
+ zero.QuadPart = 0;
+ li.u.LowPart = SetFilePointerEx(hFile, zero, &outPointer, FILE_CURRENT) ? outPointer.u.LowPart : INVALID_SET_FILE_POINTER;
+#endif
if ( (li.LowPart == 0xFFFFFFFF) && (GetLastError() != NO_ERROR))
{
DWORD dwErr = GetLastError();
@@ -259,7 +300,15 @@ long ZCALLBACK win32_seek_file_func (voidpf opaque,voidpf stream,uLong offset,in
if (hFile != NULL)
{
+#ifndef _WIN_EXT
DWORD dwSet = SetFilePointer(hFile, offset, NULL, dwMoveMethod);
+#else
+ LARGE_INTEGER outPointer;
+ LARGE_INTEGER loffset;
+ loffset.QuadPart = 0;
+ loffset.u.LowPart = offset;
+ DWORD dwSet = SetFilePointerEx(hFile, loffset, &outPointer, dwMoveMethod) ? outPointer.u.LowPart : INVALID_SET_FILE_POINTER;
+#endif
if (dwSet == INVALID_SET_FILE_POINTER)
{
DWORD dwErr = GetLastError();
@@ -297,8 +346,14 @@ long ZCALLBACK win32_seek64_file_func (voidpf opaque, voidpf stream,ZPOS64_T off
if (hFile)
{
+#ifndef _WIN_EXT
LARGE_INTEGER* li = (LARGE_INTEGER*)&offset;
DWORD dwSet = SetFilePointer(hFile, li->u.LowPart, &li->u.HighPart, dwMoveMethod);
+#else
+ LARGE_INTEGER outPointer;
+ LARGE_INTEGER* li = (LARGE_INTEGER*)&offset;
+ DWORD dwSet = SetFilePointerEx(hFile, *li, &outPointer, dwMoveMethod) ? outPointer.u.LowPart : INVALID_SET_FILE_POINTER;
+#endif
if (dwSet == INVALID_SET_FILE_POINTER)
{
DWORD dwErr = GetLastError();
diff --git a/src/unpack.c b/src/unpack.c
index df4600ac..39589b21 100644
--- a/src/unpack.c
+++ b/src/unpack.c
@@ -65,11 +65,46 @@ tm_unz tmu_date;
HANDLE hFile;
FILETIME ftm, ftLocal, ftCreate, ftLastAcc, ftLastWrite;
+#ifndef _WIN_EXT
hFile = CreateFileA(filename, GENERIC_READ | GENERIC_WRITE,
0, NULL, OPEN_EXISTING, 0, NULL);
+#else
+ hFile = CreateFile2((LPCTSTR)filename, GENERIC_READ | GENERIC_WRITE, 0, OPEN_EXISTING, NULL);
+#endif
GetFileTime(hFile, &ftCreate, &ftLastAcc, &ftLastWrite);
+#ifndef _WIN_EXT
DosDateTimeToFileTime((WORD) (dosdate >> 16), (WORD) dosdate, &ftLocal);
LocalFileTimeToFileTime(&ftLocal, &ftm);
+#else
+ SYSTEMTIME systime;
+ /*
+ OMG, it's so lowlevel, but I'll try :)
+ wFatDate[in]
+ The MS - DOS date.The date is a packed value with the following format.
+ Bits Description
+ 0 - 4 Day of the month(1-31)
+ 5 - 8 Month(1 = January, 2 = February, and so on)
+ 9 - 15 Year offset from 1980 (add 1980 to get actual year)
+
+ wFatTime[in]
+ The MS - DOS time.The time is a packed value with the following format.
+ Bits Description
+ 0 - 4 Second divided by 2
+ 5 - 10 Minute(0-59)
+ 11 - 15 Hour(0-23 on a 24 - hour clock)
+ */
+ WORD wFatDate = (WORD)(dosdate >> 16);
+ WORD wFatTime = (WORD)dosdate;
+ systime.wYear = (WORD)((wFatDate >> 8) + 1980);
+ systime.wMonth = (WORD)(((BYTE)wFatDate) >> 4);
+ systime.wDayOfWeek = 0; // ignored
+ systime.wDay = (WORD)(0x000F & wFatDate);
+ systime.wHour = (WORD)(wFatTime >> 10);
+ systime.wMinute = (WORD)((wFatTime >> 4) & 0x003F);
+ systime.wSecond = (WORD)(wFatTime & 0x000F) * 2;
+ systime.wMilliseconds = 0;
+ SystemTimeToFileTime(&systime, &ftm);
+#endif
SetFileTime(hFile, &ftm, &ftLastAcc, &ftm);
CloseHandle(hFile);
#else
@@ -156,10 +191,23 @@ const char *newdir;
return 1;
}
-static int do_extract_currentfile(uf, password)
+static __inline char *get_full_path(full_path_buffer, dirname, filename)
+char *full_path_buffer;
+const char *dirname;
+const char *filename;
+{
+ strcpy(full_path_buffer, dirname);
+ strcat(full_path_buffer, "/");
+ strcat(full_path_buffer, filename);
+ return full_path_buffer;
+}
+
+static int do_extract_currentfile(uf, password, dirname)
unzFile uf;
const char *password;
+const char *dirname;
{
+ char full_path_buffer[PATH_MAX];
char filename_inzip[256];
char dir_inzip[256];
char *filename_withoutpath;
@@ -205,7 +253,7 @@ const char *password;
goto out;
}
fprintf(stderr, "creating directory: %s\n", filename_inzip);
- mymkdir(filename_inzip);
+ mymkdir(get_full_path(full_path_buffer, dirname, filename_inzip));
if (!*zip_game_dirname)
strcpy(zip_game_dirname, dir_inzip);
} else {
@@ -222,16 +270,16 @@ const char *password;
}
if (skip == 0) {
- fout = fopen64(write_filename, "wb");
+ fout = fopen64(get_full_path(full_path_buffer, dirname, write_filename), "wb");
/* some zipfile don't contain directory alone before file */
if ((fout == NULL)
&& (filename_withoutpath != (char *)filename_inzip)) {
char c = *(filename_withoutpath - 1);
*(filename_withoutpath - 1) = '\0';
- makedir(write_filename);
+ makedir(get_full_path(full_path_buffer, dirname, write_filename));
*(filename_withoutpath - 1) = c;
- fout = fopen64(write_filename, "wb");
+ fout = fopen64(get_full_path(full_path_buffer, dirname, write_filename), "wb");
}
if (fout == NULL) {
@@ -269,7 +317,7 @@ const char *password;
fclose(fout);
if (err == 0)
- change_file_date(write_filename,
+ change_file_date(get_full_path(full_path_buffer, dirname, write_filename),
file_info.dosDate,
file_info.tmu_date);
}
@@ -309,9 +357,10 @@ out:
return err;
}
-static int do_extract(uf, password)
+static int do_extract(uf, password, dirname)
unzFile uf;
const char *password;
+const char *dirname;
{
uLong i;
unz_global_info64 gi;
@@ -321,7 +370,7 @@ const char *password;
fprintf(stderr, "error %d with zipfile in unzGetGlobalInfo \n", err);
for (i = 0; i < gi.number_entry; i++) {
- if (do_extract_currentfile(uf, password) != UNZ_OK)
+ if (do_extract_currentfile(uf, password, dirname) != UNZ_OK)
return -1;
if ((i + 1) < gi.number_entry) {
@@ -391,7 +440,7 @@ int unpack(const char *zipfilename, const char *dirname)
fprintf(stderr, "Error changing dir to %s, aborting\n", dirname);
goto out;
}
- ret_value = do_extract(uf, NULL);
+ ret_value = do_extract(uf, NULL, dirname);
out:
unzClose(uf);
#ifdef _WIN32
diff --git a/src/unzip.c b/src/unzip.c
index 6116f3b9..411c600c 100644
--- a/src/unzip.c
+++ b/src/unzip.c
@@ -612,12 +612,18 @@ local unzFile unzOpenInternal (const void *path,
us.z_filefunc = *pzlib_filefunc64_32_def;
us.is64bitOpenFunction = is64bitOpenFunction;
-
+ void *_path = path;
+#ifdef _WIDE_CHARS
+ wchar_t wpath[_MAX_PATH];
+ mbstowcs(wpath, path, _MAX_PATH);
+ _path = (void*)wpath;
+#endif
us.filestream = ZOPEN64(us.z_filefunc,
- path,
+ _path,
ZLIB_FILEFUNC_MODE_READ |
ZLIB_FILEFUNC_MODE_EXISTING);
+
if (us.filestream==NULL)
return NULL;
diff --git a/src/winrt.c b/src/winrt.c
index d3764322..f3bf9ec8 100644
--- a/src/winrt.c
+++ b/src/winrt.c
@@ -258,3 +258,45 @@ int debug_init(void)
void debug_done()
{
}
+
+
+BOOL GetFileTime(
+ HANDLE hFile,
+ LPFILETIME lpCreationTime,
+ LPFILETIME lpLastAccessTime,
+ LPFILETIME lpLastWriteTime
+)
+{
+ // stub
+ return 1;
+}
+
+BOOL SetFileTime(
+ HANDLE hFile,
+ const FILETIME *lpCreationTime,
+ const FILETIME *lpLastAccessTime,
+ const FILETIME *lpLastWriteTime
+)
+{
+ // stub
+ return 1;
+}
+
+// see https://docs.microsoft.com/en-us/cpp/cppcx/crt-functions-not-supported-in-universal-windows-platform-apps
+// The concept of a working directory doesn't apply to Windows 8.x Store apps. Use full paths instead.
+char *_getcwd(
+ char *buffer,
+ int maxlen
+)
+{
+ // stub
+ return buffer;
+}
+
+int _chdir(
+ const char *dirname
+)
+{
+ // stub
+ return 0;
+}
|