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