X-Git-Url: http://git.osdn.net/view?a=blobdiff_plain;f=src%2FOSSupport_Win32.cpp;h=dde3443aa6ae04f8638675f5f5f1571ba5f67e3b;hb=670d4dc36c2f507d2443d88757d4e56fa2045573;hp=be00e9508dd15cfcb90b85a529c2c9f663d95218;hpb=b926f98ee777182bbd497ad841daa0734ed40e9a;p=mutilities%2FMUtilities.git diff --git a/src/OSSupport_Win32.cpp b/src/OSSupport_Win32.cpp index be00e95..dde3443 100644 --- a/src/OSSupport_Win32.cpp +++ b/src/OSSupport_Win32.cpp @@ -40,11 +40,11 @@ #include #include #include "CriticalSection_Win32.h" +#include "Utils_Win32.h" //Qt #include #include -#include #include #include #include @@ -486,17 +486,8 @@ static QReadWriteLock g_wine_lock; static const bool detect_wine(void) { - bool is_wine = false; - - QLibrary ntdll("ntdll.dll"); - if(ntdll.load()) - { - if(ntdll.resolve("wine_nt_to_unix_file_name") != NULL) is_wine = true; - if(ntdll.resolve("wine_get_version") != NULL) is_wine = true; - ntdll.unload(); - } - - return is_wine; + void *const ptr = MUtils::Win32Utils::resolve(QLatin1String("ntdll"), QLatin1String("wine_get_version")); + return (ptr != NULL); } const bool &MUtils::OS::running_on_wine(void) @@ -531,11 +522,9 @@ const bool &MUtils::OS::running_on_wine(void) typedef QMap KFMap; typedef HRESULT (WINAPI *SHGetKnownFolderPath_t)(const GUID &rfid, DWORD dwFlags, HANDLE hToken, PWSTR *ppszPath); -typedef HRESULT (WINAPI *SHGetFolderPath_t)(HWND hwndOwner, int nFolder, HANDLE hToken, DWORD dwFlags, LPWSTR pszPath); +typedef HRESULT (WINAPI *SHGetFolderPath_t) (HWND hwndOwner, int nFolder, HANDLE hToken, DWORD dwFlags, LPWSTR pszPath); static QScopedPointer g_known_folders_map; -static SHGetKnownFolderPath_t g_known_folders_fpGetKnownFolderPath; -static SHGetFolderPath_t g_known_folders_fpGetFolderPath; static QReadWriteLock g_known_folders_lock; const QString &MUtils::OS::known_folder(known_folder_t folder_id) @@ -598,22 +587,16 @@ const QString &MUtils::OS::known_folder(known_folder_t folder_id) //Initialize on first call if(g_known_folders_map.isNull()) { - QLibrary shell32("shell32.dll"); - if(shell32.load()) - { - g_known_folders_fpGetFolderPath = (SHGetFolderPath_t) shell32.resolve("SHGetFolderPathW"); - g_known_folders_fpGetKnownFolderPath = (SHGetKnownFolderPath_t) shell32.resolve("SHGetKnownFolderPath"); - } g_known_folders_map.reset(new QMap()); } QString folderPath; //Now try to get the folder path! - if(g_known_folders_fpGetKnownFolderPath) + if(const SHGetKnownFolderPath_t known_folders_fpGetKnownFolderPath = MUtils::Win32Utils::resolve(QLatin1String("shell32"), QLatin1String("SHGetKnownFolderPath"))) { WCHAR *path = NULL; - if(g_known_folders_fpGetKnownFolderPath(s_folders[folderId].guid, KF_FLAG_CREATE, NULL, &path) == S_OK) + if(known_folders_fpGetKnownFolderPath(s_folders[folderId].guid, KF_FLAG_CREATE, NULL, &path) == S_OK) { //MessageBoxW(0, path, L"SHGetKnownFolderPath", MB_TOPMOST); QDir folderTemp = QDir(QDir::fromNativeSeparators(MUTILS_QSTR(path))); @@ -624,10 +607,10 @@ const QString &MUtils::OS::known_folder(known_folder_t folder_id) CoTaskMemFree(path); } } - else if(g_known_folders_fpGetFolderPath) + else if(const SHGetFolderPath_t known_folders_fpGetFolderPath = MUtils::Win32Utils::resolve(QLatin1String("shell32"), QLatin1String("SHGetFolderPathW"))) { QScopedArrayPointer path(new WCHAR[4096]); - if(g_known_folders_fpGetFolderPath(NULL, s_folders[folderId].csidl | CSIDL_FLAG_CREATE, NULL, NULL, path.data()) == S_OK) + if(known_folders_fpGetFolderPath(NULL, s_folders[folderId].csidl | CSIDL_FLAG_CREATE, NULL, NULL, path.data()) == S_OK) { //MessageBoxW(0, path, L"SHGetFolderPathW", MB_TOPMOST); QDir folderTemp = QDir(QDir::fromNativeSeparators(MUTILS_QSTR(path.data()))); @@ -716,6 +699,115 @@ quint64 MUtils::OS::current_file_time(void) } /////////////////////////////////////////////////////////////////////////////// +// FILE PATH FROM FD +/////////////////////////////////////////////////////////////////////////////// + +typedef DWORD(_stdcall *GetPathNameByHandleFun)(HANDLE hFile, LPWSTR lpszFilePath, DWORD cchFilePath, DWORD dwFlags); + +static QString get_file_path_drive_list(void) +{ + QString list; + const DWORD len = GetLogicalDriveStringsW(0, NULL); + if (len > 0) + { + if (wchar_t *const buffer = (wchar_t*) _malloca(sizeof(wchar_t) * len)) + { + const DWORD ret = GetLogicalDriveStringsW(len, buffer); + if ((ret > 0) && (ret < len)) + { + const wchar_t *ptr = buffer; + while (const size_t current_len = wcslen(ptr)) + { + list.append(QChar(*reinterpret_cast(ptr))); + ptr += (current_len + 1); + } + } + _freea(buffer); + } + } + return list; +} + +static QString &get_file_path_translate(QString &path) +{ + static const DWORD BUFSIZE = 4096; + wchar_t buffer[BUFSIZE], drive[3]; + + const QString driveList = get_file_path_drive_list(); + wcscpy_s(drive, 3, L"?:"); + for (const wchar_t *current = MUTILS_WCHR(driveList); *current; current++) + { + drive[0] = (*current); + if (QueryDosDeviceW(drive, buffer, MAX_PATH)) + { + const QString prefix = MUTILS_QSTR(buffer); + if (path.startsWith(prefix, Qt::CaseInsensitive)) + { + path.remove(0, prefix.length()).prepend(QLatin1Char(':')).prepend(QChar(*reinterpret_cast(current))); + break; + } + } + } + + return path; +} + +static QString get_file_path_fallback(const HANDLE &hFile) +{ + QString filePath; + + const HANDLE hFileMap = CreateFileMappingW(hFile, NULL, PAGE_READONLY, 0, 1, NULL); + if (hFileMap) + { + void* pMem = MapViewOfFile(hFileMap, FILE_MAP_READ, 0, 0, 1); + if (pMem) + { + static const DWORD BUFSIZE = 4096; + wchar_t buffer[BUFSIZE]; + if (GetMappedFileNameW(GetCurrentProcess(), pMem, buffer, BUFSIZE)) + { + filePath = get_file_path_translate(MUTILS_QSTR(buffer)); + } + UnmapViewOfFile(pMem); + } + CloseHandle(hFileMap); + } + + return filePath; +} + +QString MUtils::OS::get_file_path(const int &fd) +{ + if (fd >= 0) + { + const GetPathNameByHandleFun getPathNameByHandleFun = MUtils::Win32Utils::resolve(QLatin1String("kernel32"), QLatin1String("GetFinalPathNameByHandleW")); + if (!getPathNameByHandleFun) + { + qWarning("MUtils::OS::get_file_path() --> fallback!"); + return get_file_path_fallback((HANDLE)_get_osfhandle(fd)); + } + + const HANDLE handle = (HANDLE) _get_osfhandle(fd); + const DWORD len = getPathNameByHandleFun(handle, NULL, 0, FILE_NAME_OPENED); + if (len > 0) + { + if (wchar_t *const buffer = (wchar_t*)_malloca(sizeof(wchar_t) * len)) + { + const DWORD ret = getPathNameByHandleFun(handle, buffer, len, FILE_NAME_OPENED); + if ((ret > 0) && (ret < len)) + { + const QString path(MUTILS_QSTR(buffer)); + return path.startsWith(QLatin1String("\\\\?\\")) ? path.mid(4) : path; + } + _freea(buffer); + } + } + } + + return QString(); +} + +/////////////////////////////////////////////////////////////////////////////// // PROCESS ELEVATION /////////////////////////////////////////////////////////////////////////////// @@ -1270,67 +1362,28 @@ void MUtils::OS::shell_change_notification(void) typedef BOOL (_stdcall *Wow64DisableWow64FsRedirectionFun)(void *OldValue); typedef BOOL (_stdcall *Wow64RevertWow64FsRedirectionFun )(void *OldValue); -static QReadWriteLock g_wow64redir_lock; -static QScopedPointer g_wow64redir_kernel32; -static Wow64DisableWow64FsRedirectionFun g_wow64redir_disable = NULL; -static Wow64RevertWow64FsRedirectionFun g_wow64redir_revert = NULL; - -static bool wow64fsredir_init() +bool MUtils::OS::wow64fsredir_disable(void *oldValue) { - QWriteLocker writeLock(&g_wow64redir_lock); - if(g_wow64redir_disable && g_wow64redir_revert) - { - return true; /*already initialized*/ - } - - if(g_wow64redir_kernel32.isNull()) - { - g_wow64redir_kernel32.reset(new QLibrary("kernel32.dll")); - } - - if(!g_wow64redir_kernel32->isLoaded()) + const Wow64DisableWow64FsRedirectionFun wow64redir_disable = MUtils::Win32Utils::resolve(QLatin1String("kernel32"), QLatin1String("Wow64DisableWow64FsRedirection")); + if(wow64redir_disable) { - if(!g_wow64redir_kernel32->load()) + if (wow64redir_disable(oldValue)) { - return false; /*faild to load kernel32.dll*/ + return true; } } - - g_wow64redir_disable = (Wow64DisableWow64FsRedirectionFun) g_wow64redir_kernel32->resolve("Wow64DisableWow64FsRedirection"); - g_wow64redir_revert = (Wow64RevertWow64FsRedirectionFun) g_wow64redir_kernel32->resolve("Wow64RevertWow64FsRedirection"); - - return (g_wow64redir_disable && g_wow64redir_revert); -} - -#define WOW64FSREDIR_INIT(RDLOCK) do \ -{ \ - while(!(g_wow64redir_disable && g_wow64redir_revert)) \ - { \ - (RDLOCK).unlock(); \ - if(!wow64fsredir_init()) return false; \ - (RDLOCK).relock(); \ - } \ -} \ -while(0) - -bool MUtils::OS::wow64fsredir_disable(void *oldValue) -{ - QReadLocker readLock(&g_wow64redir_lock); - WOW64FSREDIR_INIT(readLock); - if(g_wow64redir_disable(oldValue)) - { - return true; - } return false; } bool MUtils::OS::wow64fsredir_revert(void *oldValue) { - QReadLocker readLock(&g_wow64redir_lock); - WOW64FSREDIR_INIT(readLock); - if(g_wow64redir_revert(oldValue)) + const Wow64RevertWow64FsRedirectionFun wow64redir_disable = MUtils::Win32Utils::resolve(QLatin1String("kernel32"), QLatin1String("Wow64RevertWow64FsRedirection")); + if (wow64redir_disable) { - return true; + if (wow64redir_disable(oldValue)) + { + return true; + } } return false; }