aboutsummaryrefslogtreecommitdiff
path: root/Src/nu/AutoWideFn.h
diff options
context:
space:
mode:
authorJef <jef@targetspot.com>2024-09-24 08:54:57 -0400
committerJef <jef@targetspot.com>2024-09-24 08:54:57 -0400
commit20d28e80a5c861a9d5f449ea911ab75b4f37ad0d (patch)
tree12f17f78986871dd2cfb0a56e5e93b545c1ae0d0 /Src/nu/AutoWideFn.h
parent537bcbc86291b32fc04ae4133ce4d7cac8ebe9a7 (diff)
downloadwinamp-20d28e80a5c861a9d5f449ea911ab75b4f37ad0d.tar.gz
Initial community commit
Diffstat (limited to 'Src/nu/AutoWideFn.h')
-rw-r--r--Src/nu/AutoWideFn.h191
1 files changed, 191 insertions, 0 deletions
diff --git a/Src/nu/AutoWideFn.h b/Src/nu/AutoWideFn.h
new file mode 100644
index 00000000..5d44dee3
--- /dev/null
+++ b/Src/nu/AutoWideFn.h
@@ -0,0 +1,191 @@
+#ifndef NULLSOFT_UTILITY_AUTOWIDEFN_H
+#define NULLSOFT_UTILITY_AUTOWIDEFN_H
+
+
+/* Winamp defines this, but this little block lets us use this thing outside of Winamp */
+#ifndef FILENAME_SIZE
+#define FILENAME_SIZE (MAX_PATH*4)
+#define REMOVE_FILENAME_SIZE
+#endif
+
+#include <windows.h>
+#include "AutoWide.h"
+#include "AutoChar.h"
+#include <shlwapi.h>
+/*
+Tries to find a filename that underwent a destructive Unicode-to-ANSI conversion
+*/
+
+#pragma warning(push)
+#pragma warning(disable:4995)
+class AutoWideFn
+{
+public:
+ AutoWideFn(const char *narrowFn)
+ {
+ wideFn[0]=0;
+ if (!narrowFn)
+ return;
+ CreateFile_HACK(narrowFn, wideFn);
+ }
+
+ operator wchar_t *() { return wideFn; }
+ bool unicode_find(/*char *path,*/ char *pattern, wchar_t *out, UINT out_ptr, bool dir, HANDLE *f)
+ {
+ WIN32_FIND_DATAW fd = {0};
+
+ if (*f == INVALID_HANDLE_VALUE)
+ {
+ lstrcpyW(out + out_ptr, L"*");
+ *f = FindFirstFileW(out, &fd);
+ out[out_ptr] = 0;
+ if (*f == INVALID_HANDLE_VALUE) return 0;
+ }
+ else
+ {
+ if (!FindNextFileW(*f, &fd))
+ {
+ FindClose(*f);
+ *f = INVALID_HANDLE_VALUE;
+ return 0;
+ }
+ }
+
+ if (*f == INVALID_HANDLE_VALUE) return 0;
+ char temp[MAX_PATH*2 + 1] = {0};
+ do
+ {
+ if (dir)
+ {
+ if (!(fd.dwFileAttributes&FILE_ATTRIBUTE_DIRECTORY)) continue;
+ }
+ else
+ {
+ if (fd.dwFileAttributes&FILE_ATTRIBUTE_DIRECTORY) continue;
+ }
+ WideCharToMultiByte(CP_ACP, 0, fd.cFileName, -1, temp, sizeof(temp), 0, 0);
+ //wcstombs(temp,fd.cFileName,sizeof(temp));
+ if (!_stricmp(temp, pattern))
+ { //found
+ lstrcpyW(out + out_ptr, fd.cFileName);
+ return 1;
+ }
+
+ WideCharToMultiByte(CP_ACP, 0, fd.cAlternateFileName, -1, temp, sizeof(temp), 0, 0);
+ if (!_stricmp(temp, pattern))
+ { //found
+ lstrcpyW(out + out_ptr, fd.cFileName);
+ return 1;
+ }
+ }
+ while (FindNextFileW(*f, &fd));
+ FindClose(*f);
+ *f = INVALID_HANDLE_VALUE;
+
+ return 0;
+ }
+
+ bool unicode_open_recur(char *path, char *ptr, wchar_t *out, UINT out_ptr)
+ {
+ char * next = strchr(ptr, '\\');
+ if (next)
+ { //dig another dir
+ HANDLE f = INVALID_HANDLE_VALUE;
+ bool found;
+ do
+ {
+ next[0] = 0;
+ char * zz = _strdup(ptr);
+ char bk = *ptr;
+ *ptr = 0;
+ found = unicode_find(/*path,*/ zz, out, out_ptr, 1, &f);
+ free(zz);
+ *ptr = bk;
+ next[0] = '\\';
+ if (found)
+ {
+ UINT op_bk = out_ptr;
+ while (out_ptr < FILENAME_SIZE && out[out_ptr]) out_ptr++;
+ out[out_ptr++] = '\\';
+ if (unicode_open_recur(path, next + 1, out, out_ptr))
+ {
+ if (f != INVALID_HANDLE_VALUE) FindClose(f);
+ return 1;
+ }
+ out_ptr = op_bk;
+ out[out_ptr] = 0;
+ }
+ } while (found);
+ }
+ else
+ { //final dir
+ HANDLE f = INVALID_HANDLE_VALUE;
+ char * zz = _strdup(ptr);
+ char bk = *ptr;
+ *ptr = 0;
+ bool found = unicode_find(/*path,*/ zz, out, out_ptr, 0, &f);
+ if (!found)
+ {
+ if (f != INVALID_HANDLE_VALUE)
+ {
+ FindClose(f);
+ f = INVALID_HANDLE_VALUE;
+ }
+ found = unicode_find(/*path,*/ zz, out, out_ptr, 1, &f);
+ }
+ free(zz);
+ *ptr = bk;
+ if (f != INVALID_HANDLE_VALUE) FindClose(f);
+ return found;
+ }
+ return 0;
+ }
+
+
+ void CreateFile_HACK(const char * path, wchar_t out[FILENAME_SIZE])
+ {
+ MultiByteToWideChar(CP_ACP, 0, path, -1, out, FILENAME_SIZE);
+
+ if (PathIsURLW(out))
+ return ;
+
+ if (!StrChrW(out, L'?'))
+ return ; // no unconvertables? Great!
+
+// if (PathFileExistsW(out))
+ // return ; // no unconvertables? Great!
+
+ bool found = false;
+
+ memset(out, 0, FILENAME_SIZE * sizeof(wchar_t));
+
+ char * _p = _strdup(path);
+ char * t = strchr(_p, '\\');
+
+ if (t)
+ {
+ char bk = t[1];
+ t[1] = 0;
+ UINT o = MultiByteToWideChar(CP_ACP, 0, _p, -1, out, FILENAME_SIZE);
+ o--;
+ t[1] = bk;
+ found = unicode_open_recur(_p, t + 1, out, o);
+ }
+ else
+ found = unicode_open_recur(_p, _p, out, 0);
+ free(_p);
+
+ if (!found)
+ MultiByteToWideChar(CP_ACP, 0, path, -1, out, FILENAME_SIZE);
+ }
+private:
+ wchar_t wideFn[FILENAME_SIZE];
+};
+
+#pragma warning(pop)
+
+#ifdef REMOVE_FILENAME_SIZE
+#undef FILENAME_SIZE
+#endif
+
+#endif