Skip to content

Commit 318147f

Browse files
committed
Fix handling for directories with extended characters
* Closes #3
1 parent 35794da commit 318147f

File tree

4 files changed

+99
-22
lines changed

4 files changed

+99
-22
lines changed

cdecrypt.c

+3-3
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
cdecrypt - Decrypt Wii U NUS content files
33
44
Copyright © 2013-2015 crediar <https://code.google.com/p/cdecrypt/>
5-
Copyright © 2020 VitaSmith <https://github.com/VitaSmith/cdecrypt>
5+
Copyright © 2020-2021 VitaSmith <https://github.com/VitaSmith/cdecrypt>
66
77
This program is free software: you can redistribute it and/or modify
88
it under the terms of the GNU General Public License as published by
@@ -366,13 +366,13 @@ int main_utf8(int argc, char** argv)
366366

367367
if (argc < 2) {
368368
printf("%s %s - Wii U NUS content file decrypter\n"
369-
"Copyright (c) 2020 VitaSmith, Copyright (c) 2013-2015 crediar\n"
369+
"Copyright (c) 2020-2021 VitaSmith, Copyright (c) 2013-2015 crediar\n"
370370
"Visit https://github.com/VitaSmith/cdecrypt for official source and downloads.\n\n"
371371
"Usage: %s <file or directory>\n\n"
372372
"This program is free software; you can redistribute it and/or modify it under\n"
373373
"the terms of the GNU General Public License as published by the Free Software\n"
374374
"Foundation; either version 3 of the License or any later version.\n",
375-
appname(argv[0]), APP_VERSION_STR, appname(argv[0]));
375+
_appname(argv[0]), APP_VERSION_STR, _appname(argv[0]));
376376
return EXIT_SUCCESS;
377377
}
378378

utf8.h

+9
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,15 @@ static __inline int stat64_utf8(const char* path, struct stat64* buffer)
111111
return r;
112112
}
113113

114+
static __inline BOOL CreateDirectory_utf8(const char* path, LPSECURITY_ATTRIBUTES attrs)
115+
{
116+
BOOL r;
117+
wchar_t* path16 = utf8_to_utf16(path);
118+
r = CreateDirectoryW(path16, attrs);
119+
free(path16);
120+
return r;
121+
}
122+
114123
#define CALL_MAIN int wmain(int argc, wchar_t** argv16) { \
115124
SetConsoleOutputCP(CP_UTF8); \
116125
char** argv = calloc(argc, sizeof(char*)); \

util.c

+74-3
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
/*
22
Common code for Gust (Koei/Tecmo) PC games tools
3-
Copyright © 2019-2020 VitaSmith
3+
Copyright © 2019-2021 VitaSmith
44
55
This program is free software: you can redistribute it and/or modify
66
it under the terms of the GNU General Public License as published by
@@ -28,12 +28,18 @@ bool create_path(char* path)
2828
{
2929
bool result = true;
3030
struct stat64_t st;
31+
#if defined(_WIN32)
32+
// Ignore Windows drive names
33+
if ((strlen(path) == 2) && (path[1] == ':'))
34+
return true;
35+
#endif
3136
if (stat64_utf8(path, &st) != 0) {
3237
// Directory doesn't exist, create it
3338
size_t pos = 0;
3439
for (size_t n = strlen(path); n > 0; n--) {
3540
if (path[n] == PATH_SEP) {
36-
pos = n;
41+
while ((n > 0) && (path[--n] == PATH_SEP));
42+
pos = n + 1;
3743
break;
3844
}
3945
}
@@ -61,6 +67,71 @@ bool create_path(char* path)
6167
return result;
6268
}
6369

70+
// dirname/basename, that *PRESERVE* the string parameter.
71+
// Note that these calls are not concurrent, meaning that you MUST be done
72+
// using the returned string from a previous call before invoking again.
73+
#if defined(_WIN32)
74+
char* _basename_win32(const char* path, bool remove_extension)
75+
{
76+
static char basename[128];
77+
static char ext[64];
78+
ext[0] = 0;
79+
_splitpath_s(path, NULL, 0, NULL, 0, basename, sizeof(basename), ext, sizeof(ext));
80+
if ((ext[0] != 0) && !remove_extension)
81+
strncat(basename, ext, sizeof(basename) - strlen(basename));
82+
return basename;
83+
}
84+
85+
// This call should behave pretty similar to UNIX' dirname
86+
char* _dirname_win32(const char* path)
87+
{
88+
static char dir[PATH_MAX];
89+
static char drive[4];
90+
int found_sep = 0;
91+
memset(drive, 0, sizeof(drive));
92+
_splitpath_s(path, drive, sizeof(drive), dir, sizeof(dir) - 3, NULL, 0, NULL, 0);
93+
// Only deal with drives that are one letter
94+
drive[2] = 0;
95+
drive[3] = 0;
96+
if (drive[1] != ':')
97+
drive[0] = 0;
98+
// Removing trailing path separators
99+
for (int32_t n = (int32_t)strlen(dir) - 1; (n > 0) && ((dir[n] == '/') || (dir[n] == '\\')); n--) {
100+
dir[n] = 0;
101+
found_sep++;
102+
}
103+
if (dir[0] == 0) {
104+
if (drive[0] == 0)
105+
return found_sep ? "\\" : ".";
106+
drive[2] = '\\';
107+
return drive;
108+
}
109+
if (drive[0] != 0) {
110+
// Add the drive
111+
memmove(&dir[2], dir, strlen(dir) + 1);
112+
memcpy(dir, drive, strlen(drive));
113+
dir[2] = '\\';
114+
}
115+
return dir;
116+
}
117+
#else
118+
char* _basename_unix(const char* path)
119+
{
120+
static char path_copy[PATH_MAX];
121+
strncpy(path_copy, path, sizeof(path_copy));
122+
path_copy[PATH_MAX - 1] = 0;
123+
return basename(path_copy);
124+
}
125+
126+
char* _dirname_unix(const char* path)
127+
{
128+
static char path_copy[PATH_MAX];
129+
strncpy(path_copy, path, sizeof(path_copy));
130+
path_copy[PATH_MAX - 1] = 0;
131+
return dirname(path_copy);
132+
}
133+
#endif
134+
64135
bool is_file(const char* path)
65136
{
66137
struct stat64_t st;
@@ -76,7 +147,7 @@ bool is_directory(const char* path)
76147
char* change_extension(const char* path, const char* extension)
77148
{
78149
static char new_path[PATH_MAX];
79-
strncpy(new_path, basename((char*)path), sizeof(new_path) - 1);
150+
strncpy(new_path, _basename((char*)path), sizeof(new_path) - 1);
80151
for (size_t i = 0; i < sizeof(new_path); i++) {
81152
if (new_path[i] == '.')
82153
new_path[i] = 0;

util.h

+13-16
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
/*
22
Common code for Gust (Koei/Tecmo) PC games tools
3-
Copyright © 2019-2020 VitaSmith
3+
Copyright © 2019-2021 VitaSmith
44
55
This program is free software: you can redistribute it and/or modify
66
it under the terms of the GNU General Public License as published by
@@ -22,7 +22,7 @@
2222
#include <crtdbg.h>
2323
#endif
2424

25-
#if defined(__APPLE__)
25+
#if !defined(_WIN32)
2626
#include <libgen.h>
2727
#endif
2828
#include <stdbool.h>
@@ -50,7 +50,7 @@
5050
#if !defined(S_ISREG)
5151
#define S_ISREG(ST_MODE) (((ST_MODE) & _S_IFMT) == _S_IFREG)
5252
#endif
53-
#define CREATE_DIR(path) CreateDirectoryA(path, NULL)
53+
#define CREATE_DIR(path) CreateDirectory_utf8(path, NULL)
5454
#define PATH_SEP '\\'
5555
#else
5656
#if defined(__APPLE__)
@@ -85,20 +85,17 @@
8585
#endif
8686

8787
#if defined(_WIN32)
88-
static __inline char* _basename(const char* path, bool remove_extension)
89-
{
90-
static char basename[128];
91-
static char ext[64];
92-
ext[0] = 0;
93-
_splitpath_s(path, NULL, 0, NULL, 0, basename, sizeof(basename), ext, sizeof(ext));
94-
if ((ext[0] != 0) && !remove_extension)
95-
strncat(basename, ext, sizeof(basename) - strlen(basename));
96-
return basename;
97-
}
98-
#define basename(path) _basename(path, false)
99-
#define appname(path) _basename(path, true)
88+
char* _basename_win32(const char* path, bool remove_extension);
89+
char* _dirname_win32(const char* path);
90+
#define _basename(path) _basename_win32(path, false)
91+
#define _appname(path) _basename_win32(path, true)
92+
#define _dirname(path) _dirname_win32(path)
10093
#else
101-
#define appname(path) basename(path)
94+
char* _basename_unix(const char* path);
95+
char* _dirname_unix(const char* path);
96+
#define _basename(path) _basename_unix(path)
97+
#define _appname(path) _basename_unix(path)
98+
#define _dirname(path) _dirname_unix(path)
10299
#endif
103100

104101
#if defined (_MSC_VER)

0 commit comments

Comments
 (0)