123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191 |
- #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
|