diff options
author | sof <unknown> | 2005-03-19 02:03:28 +0000 |
---|---|---|
committer | sof <unknown> | 2005-03-19 02:03:28 +0000 |
commit | cbe4c3a7cc2b1e627b308aff520a9f354f7a730b (patch) | |
tree | 554a61d689291c4f4b24e7723660b0cdd98f5fd3 /ghc/lib/compat/cbits | |
parent | c0eed017436c7d36dd163547ea95d3f8b36645d4 (diff) | |
download | haskell-cbe4c3a7cc2b1e627b308aff520a9f354f7a730b.tar.gz |
[project @ 2005-03-19 02:03:26 by sof]
[Windows only]
for System.Directory / Compat.Directory functionality that probes the OS
for local details re: misc user directories, perform late binding of
SHGetFolderPath() from shell32.dll, as it may not be present.
(cf. ghc-6.4's failure to operate on Win9x / NT boxes.) If the API isn't
there, fail with UnsupportedOperation.
Packages.readPackageConfigs: gracefully handle excns from getAppUserDataDirectory.
Merge to STABLE.
Diffstat (limited to 'ghc/lib/compat/cbits')
-rw-r--r-- | ghc/lib/compat/cbits/directory.c | 142 |
1 files changed, 92 insertions, 50 deletions
diff --git a/ghc/lib/compat/cbits/directory.c b/ghc/lib/compat/cbits/directory.c index af09655965..cca7b2c6e0 100644 --- a/ghc/lib/compat/cbits/directory.c +++ b/ghc/lib/compat/cbits/directory.c @@ -1,50 +1,92 @@ -#include "../../../includes/ghcconfig.h"
-
-#include "HsFFI.h"
-
-#if HAVE_LIMITS_H
-#include <limits.h>
-#endif
-#if HAVE_WINDOWS_H
-#include <windows.h>
-#endif
-
-#define INLINE /* nothing */
-
-/*
- * Following code copied from libraries/base/includes/HsBase.h
- */
-
-#ifdef PATH_MAX
-/* A size that will contain many path names, but not necessarily all
- * (PATH_MAX is not defined on systems with unlimited path length,
- * e.g. the Hurd).
- */
-INLINE HsInt __compat_long_path_size() { return PATH_MAX; }
-#else
-INLINE HsInt __compat_long_path_size() { return 4096; }
-#endif
-
-#if defined(mingw32_HOST_OS)
-
-/* Make sure we've got the reqd CSIDL_ constants in scope;
- * w32api header files are lagging a bit in defining the full set.
- */
-#if !defined(CSIDL_APPDATA)
-#define CSIDL_APPDATA 0x001a
-#endif
-#if !defined(CSIDL_PERSONAL)
-#define CSIDL_PERSONAL 0x0005
-#endif
-#if !defined(CSIDL_PROFILE)
-#define CSIDL_PROFILE 0x0028
-#endif
-#if !defined(CSIDL_WINDOWS)
-#define CSIDL_WINDOWS 0x0024
-#endif
-
-INLINE int __hscore_CSIDL_PROFILE() { return CSIDL_PROFILE; }
-INLINE int __hscore_CSIDL_APPDATA() { return CSIDL_APPDATA; }
-INLINE int __hscore_CSIDL_WINDOWS() { return CSIDL_WINDOWS; }
-INLINE int __hscore_CSIDL_PERSONAL() { return CSIDL_PERSONAL; }
-#endif
+#include "../../../includes/ghcconfig.h" + +#include "HsFFI.h" + +#if HAVE_LIMITS_H +#include <limits.h> +#endif +#if HAVE_WINDOWS_H +#include <windows.h> +#endif +#include "directory.h" + +#define INLINE /* nothing */ + +/* + * Following code copied from libraries/base/includes/HsBase.h + */ + +#ifdef PATH_MAX +/* A size that will contain many path names, but not necessarily all + * (PATH_MAX is not defined on systems with unlimited path length, + * e.g. the Hurd). + */ +INLINE HsInt __compat_long_path_size() { return PATH_MAX; } +#else +INLINE HsInt __compat_long_path_size() { return 4096; } +#endif + +#if defined(mingw32_HOST_OS) + +/* Make sure we've got the reqd CSIDL_ constants in scope; + * w32api header files are lagging a bit in defining the full set. + */ +#if !defined(CSIDL_APPDATA) +#define CSIDL_APPDATA 0x001a +#endif +#if !defined(CSIDL_PERSONAL) +#define CSIDL_PERSONAL 0x0005 +#endif +#if !defined(CSIDL_PROFILE) +#define CSIDL_PROFILE 0x0028 +#endif +#if !defined(CSIDL_WINDOWS) +#define CSIDL_WINDOWS 0x0024 +#endif + +INLINE int __hscore_CSIDL_PROFILE() { return CSIDL_PROFILE; } +INLINE int __hscore_CSIDL_APPDATA() { return CSIDL_APPDATA; } +INLINE int __hscore_CSIDL_WINDOWS() { return CSIDL_WINDOWS; } +INLINE int __hscore_CSIDL_PERSONAL() { return CSIDL_PERSONAL; } + +/* + * Function: __hscore_getFolderPath() + * + * Late-bound version of SHGetFolderPath(), coping with OS versions + * that have shell32's lacking that particular API. + * + */ +typedef HRESULT (*HSCORE_GETAPPFOLDERFUNTY)(HWND,int,HANDLE,DWORD,char*); +int +__hscore_getFolderPath(HWND hwndOwner, + int nFolder, + HANDLE hToken, + DWORD dwFlags, + char* pszPath) +{ + static int loaded_dll = 0; + static HMODULE hMod = (HMODULE)NULL; + static HSCORE_GETAPPFOLDERFUNTY funcPtr = NULL; + + if (loaded_dll < 0) { + return (-1); + } else if (loaded_dll == 0) { + hMod = LoadLibrary("shell32.dll"); + if (hMod == NULL) { + loaded_dll = (-1); + return (-1); + } else { + funcPtr = (HSCORE_GETAPPFOLDERFUNTY)GetProcAddress(hMod, "SHGetFolderPathA"); + if (!funcPtr) { + loaded_dll = (-1); + return (-1); + } else { + loaded_dll = 1; + } + } + } + /* OK, if we got this far the function has been bound */ + return (int)funcPtr(hwndOwner,nFolder,hToken,dwFlags,pszPath); + /* ToDo: unload the DLL? */ +} +#endif |