(svn r7460) -Fix (r7337): [win32] If the underlying OS didn't have support for SHGetFolderPath the

application failed to run. Now test if the function exists and if not try a different
 approach using our own OTTDSHGetFolderPath wrapper.
This commit is contained in:
Darkvater 2006-12-09 23:55:56 +00:00
parent 5f8f0e4e47
commit 74106ce6e9
2 changed files with 59 additions and 0 deletions

50
win32.c
View File

@ -14,6 +14,7 @@
#include <wininet.h> #include <wininet.h>
#include <io.h> #include <io.h>
#include <fcntl.h> #include <fcntl.h>
#include <shlobj.h> // SHGetFolderPath
#include "variables.h" #include "variables.h"
#include "win32.h" #include "win32.h"
#include "fios.h" // opendir/readdir/closedir #include "fios.h" // opendir/readdir/closedir
@ -1092,3 +1093,52 @@ const char *FS2OTTD(const wchar_t *name)
static char utf8_buf[512]; static char utf8_buf[512];
return convert_from_fs(name, utf8_buf, lengthof(utf8_buf)); return convert_from_fs(name, utf8_buf, lengthof(utf8_buf));
} }
/** Our very own SHGetFolderPath function for support of windows operating
* systems that don't have this function (eg Win9x, etc.). We try using the
* native function, and if that doesn't exist we will try a more crude approach
* of environment variables and hope for the best */
HRESULT OTTDSHGetFolderPath(HWND hwnd, int csidl, HANDLE hToken, DWORD dwFlags, LPTSTR pszPath)
{
static HRESULT (WINAPI *SHGetFolderPath)(HWND, int, HANDLE, DWORD, LPTSTR) = NULL;
static bool first_time = true;
/* We only try to load the library one time; if it fails, it fails */
if (first_time) {
#if defined(UNICODE)
# define W(x) x "W"
#else
# define W(x) x "A"
#endif
if (!LoadLibraryList((Function*)&SHGetFolderPath, "SHFolder.dll\0" W("SHGetFolderPath") "\0\0")) {
DEBUG(misc, 0) ("Unable to load " W("SHGetFolderPath") "from SHFolder.dll");
}
#undef W
first_time = false;
}
if (SHGetFolderPath != NULL) return SHGetFolderPath(hwnd, csidl, hToken, dwFlags, pszPath);
/* SHGetFolderPath doesn't exist, try a more conservative approach,
* eg environment variables. This is only included for legacy modes
* MSDN says: that 'pszPath' is a "Pointer to a null-terminated string of
* length MAX_PATH which will receive the path" so let's assume that
* Windows 95 with Internet Explorer 5.0, Windows 98 with Internet Explorer 5.0,
* Windows 98 Second Edition (SE), Windows NT 4.0 with Internet Explorer 5.0,
* Windows NT 4.0 with Service Pack 4 (SP4) */
{
DWORD ret;
switch (csidl) {
case CSIDL_FONTS: /* Get the system font path, eg %WINDIR%\Fonts */
ret = GetEnvironmentVariable(_T("WINDIR"), pszPath, MAX_PATH * sizeof(TCHAR));
if (ret == 0) break;
_tcsncat(pszPath, _T("\\Fonts"), MAX_PATH * sizeof(TCHAR));
return (HRESULT)0;
break;
/* XXX - other types to go here when needed... */
}
}
return E_INVALIDARG;
}

View File

@ -3,6 +3,7 @@
#ifndef WIN32_H #ifndef WIN32_H
#define WIN32_H #define WIN32_H
#include <windows.h>
bool MyShowCursor(bool show); bool MyShowCursor(bool show);
typedef void (*Function)(int); typedef void (*Function)(int);
@ -23,6 +24,14 @@ wchar_t *convert_to_fs(const char *name, wchar_t *utf16_buf, size_t buflen);
# define WIDE_TO_MB_BUFFER(str, buffer, buflen) (str) # define WIDE_TO_MB_BUFFER(str, buffer, buflen) (str)
#endif #endif
/* Override SHGetFolderPath with our custom implementation */
#if defined(SHGetFolderPath)
#undef SHGetFolderPath
#endif
#define SHGetFolderPath OTTDSHGetFolderPath
HRESULT OTTDSHGetFolderPath(HWND, int, HANDLE, DWORD, LPTSTR);
#if defined(__MINGW32__) #if defined(__MINGW32__)
#define SHGFP_TYPE_CURRENT 0 #define SHGFP_TYPE_CURRENT 0
#endif /* __MINGW32__ */ #endif /* __MINGW32__ */