Revision: 9411 https://osdn.net/projects/ttssh2/scm/svn/commits/9411 Author: zmatsuo Date: 2021-09-11 00:51:37 +0900 (Sat, 11 Sep 2021) Log Message: ----------- compat_win.cpp に _SHGetKnownFolderPath() を追加 - SHGetKnownFolderPath() - パスの取得 - SHGetSpecialFolderPathW() などの代替 - このAPIで返すパス長には上限がない - Vistaから - _SHGetKnownFolderPath() - SHGetKnownFolderPath() が存在すれば使用する - 存在しなければ、SHGetSpecialFolderLocation() を使用 - ttknownfolders.c,h - FOLDERID_* の定義 - VS2005 など古いSDKを使ってビルドするときに使用 - ttdebug.cpp - _SHGetKnownFolderPath() を利用するよう修正 Modified Paths: -------------- trunk/teraterm/common/CMakeLists.txt trunk/teraterm/common/compat_win.cpp trunk/teraterm/common/compat_win.h trunk/teraterm/teraterm/ttdebug.cpp Added Paths: ----------- trunk/teraterm/common/ttknownfolders.c trunk/teraterm/common/ttknownfolders.h -------------- next part -------------- Modified: trunk/teraterm/common/CMakeLists.txt =================================================================== --- trunk/teraterm/common/CMakeLists.txt 2021-09-10 15:51:25 UTC (rev 9410) +++ trunk/teraterm/common/CMakeLists.txt 2021-09-10 15:51:37 UTC (rev 9411) @@ -31,6 +31,8 @@ tmfc.h tmfc_frame.cpp tmfc_property.cpp + ttknownfolders.h + ttknownfolders.c ttlib.h ttlib_static.c ttlib_static_cpp.cpp Modified: trunk/teraterm/common/compat_win.cpp =================================================================== --- trunk/teraterm/common/compat_win.cpp 2021-09-10 15:51:25 UTC (rev 9410) +++ trunk/teraterm/common/compat_win.cpp 2021-09-10 15:51:37 UTC (rev 9411) @@ -92,6 +92,10 @@ PMINIDUMP_USER_STREAM_INFORMATION UserStreamParam, PMINIDUMP_CALLBACK_INFORMATION CallbackParam); +// shell32.dll +static HRESULT (WINAPI *pSHGetKnownFolderPath)(REFKNOWNFOLDERID rfid, DWORD dwFlags, HANDLE hToken, PWSTR* ppszPath); + + class Initializer { public: Initializer() { @@ -219,6 +223,11 @@ {}, }; +static const APIInfo Lists_shell32[] = { + { "SHGetKnownFolderPath", (void **)&pSHGetKnownFolderPath }, + {}, +}; + static const DllInfo DllInfos[] = { { L"user32.dll", DLL_LOAD_LIBRARY_SYSTEM, DLL_ACCEPT_NOT_EXIST, Lists_user32 }, { L"msimg32.dll", DLL_LOAD_LIBRARY_SYSTEM, DLL_ACCEPT_NOT_EXIST, Lists_msimg32 }, @@ -229,6 +238,7 @@ { L"dnsapi.dll", DLL_LOAD_LIBRARY_SYSTEM, DLL_ACCEPT_NOT_EXIST, Lists_dnsapi }, { L"imagehlp.dll", DLL_LOAD_LIBRARY_SYSTEM, DLL_ACCEPT_NOT_EXIST, Lists_imagehlp }, { L"dbghelp.dll", DLL_LOAD_LIBRARY_SYSTEM, DLL_ACCEPT_NOT_EXIST, Lists_dbghelp }, + { L"shell32.dll", DLL_LOAD_LIBRARY_SYSTEM, DLL_ACCEPT_NOT_EXIST, Lists_shell32 }, {}, }; @@ -492,3 +502,72 @@ } return _myVerSetConditionMask(dwlConditionMask, dwTypeBitMask, dwConditionMask); } + +static BOOL GetCSIDLFromFKNOWNFOLDERID(REFKNOWNFOLDERID rfid, int *csidl) +{ + // TODO GetSpecialFolder() ttmlib.c \x82\xF0\x83J\x83o\x81[\x82ł\xAB\x82\xE9\x82悤\x82ɂ\xB7\x82\xE9 + static const struct { + REFKNOWNFOLDERID rfid; + int csidl; + } list[] = { + { FOLDERID_Desktop, CSIDL_DESKTOPDIRECTORY }, + { FOLDERID_Documents, CSIDL_PERSONAL }, // My Documents + { FOLDERID_LocalAppData, CSIDL_LOCAL_APPDATA }, + }; + + for (size_t i = 0; i < _countof(list); i++) { + if (IsEqualGUID(rfid, list[i].rfid)) { + *csidl = list[i].csidl; + return TRUE; + } + } + return FALSE; +} + +/** + * SHGetKnownFolderPath() \x82̌݊\xB7\x8A\x94 + * + * @param[out] ppszPath \x83p\x83X + * CoTaskMemFree() \x82ł͂Ȃ\xAD\x81Afree() \x82\xF0\x8Eg\x82\xC1\x82ĊJ\x95\xFA\x82\xB7\x82\xE9 + * \x83G\x83\x89\x81[\x82ɊW\x82Ȃ\xAD free() \x82\xB7\x82邱\x82\xC6 + */ +HRESULT _SHGetKnownFolderPath(REFKNOWNFOLDERID rfid, DWORD dwFlags, HANDLE hToken, PWSTR* ppszPath) +{ + if (pSHGetKnownFolderPath != NULL) { + // Vista+ + wchar_t *path; + HRESULT r = pSHGetKnownFolderPath(rfid, dwFlags, hToken, &path); + *ppszPath = _wcsdup(path); + CoTaskMemFree(path); // \x83G\x83\x89\x81[\x82ɊW\x82Ȃ\xAD\x8CĂяo\x82\xB7\x95K\x97v\x82\xA0\x82\xE8 + return r; + } + + int csidl; + if (GetCSIDLFromFKNOWNFOLDERID(rfid, &csidl) == FALSE) { + *ppszPath = _wcsdup(L""); + return E_FAIL; + } + wchar_t path[MAX_PATH]; +#if 0 + // SHGetSpecialFolderLocation() \x82ŃJ\x83o\x81[\x82ł\xAB\x82\xE9? + if (pSHGetSpecialFolderPathW != NULL) { + BOOL create = (dwFlags & KF_FLAG_CREATE) != 0 ? TRUE : FALSE; + BOOL r = SHGetSpecialFolderPathW(NULL, path, csidl, create); + if (!r) { + path[0] = 0; + } + *ppszPath = _wcsdup(path); + return r ? S_OK : E_FAIL; + } +#endif + LPITEMIDLIST pidl; + HRESULT r = SHGetSpecialFolderLocation(NULL, csidl, &pidl); + if (r != NOERROR) { + *ppszPath = _wcsdup(L""); + return E_FAIL; + } + SHGetPathFromIDListW(pidl, path); + CoTaskMemFree(pidl); + *ppszPath = _wcsdup(path); + return S_OK; +} Modified: trunk/teraterm/common/compat_win.h =================================================================== --- trunk/teraterm/common/compat_win.h 2021-09-10 15:51:25 UTC (rev 9410) +++ trunk/teraterm/common/compat_win.h 2021-09-10 15:51:37 UTC (rev 9411) @@ -37,6 +37,7 @@ #include <windows.h> #include <imagehlp.h> // for SymGetLineFromAddr() +#include <shlobj.h> // for SHGetKnownFolderPath() #ifdef __cplusplus extern "C" { @@ -165,6 +166,26 @@ PMINIDUMP_USER_STREAM_INFORMATION UserStreamParam, PMINIDUMP_CALLBACK_INFORMATION CallbackParam); +// shell32.dll +#if !defined(NTDDI_VERSION) || (NTDDI_VERSION < NTDDI_VISTA) +typedef GUID KNOWNFOLDERID; +#ifdef __cplusplus +#define REFKNOWNFOLDERID const KNOWNFOLDERID & +#else // !__cplusplus +#define REFKNOWNFOLDERID const KNOWNFOLDERID * const +#endif // __cplusplus + +#include "ttknownfolders.h" + +typedef enum +{ + KF_FLAG_CREATE = 0x00008000, +} KNOWN_FOLDER_FLAG; + + +#endif +HRESULT _SHGetKnownFolderPath(REFKNOWNFOLDERID rfid, DWORD dwFlags, HANDLE hToken, PWSTR* ppszPath); + void WinCompatInit(); #ifdef __cplusplus Added: trunk/teraterm/common/ttknownfolders.c =================================================================== --- trunk/teraterm/common/ttknownfolders.c (rev 0) +++ trunk/teraterm/common/ttknownfolders.c 2021-09-10 15:51:37 UTC (rev 9411) @@ -0,0 +1,36 @@ +/* + * Copyright (C) 2021- TeraTerm Project + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include <windows.h> + +#if !defined(NTDDI_VERSION) || (NTDDI_VERSION < NTDDI_VISTA) +// FOLDERID_* \x82\xAASDK\x93\xE0\x82ɒ\xE8\x8B`\x82\xB3\x82\xEA\x82Ă\xA2\x82Ȃ\xA2 +// \x82\xB1\x82̃t\x83@\x83C\x83\x8B(*.obj)\x82Ɏ\xC0\x91̂\xF0\x92u\x82\xAD +#define INITGUID +#include "ttknownfolders.h" +#endif Added: trunk/teraterm/common/ttknownfolders.h =================================================================== --- trunk/teraterm/common/ttknownfolders.h (rev 0) +++ trunk/teraterm/common/ttknownfolders.h 2021-09-10 15:51:37 UTC (rev 9411) @@ -0,0 +1,49 @@ +/* + * Copyright (C) 2021- TeraTerm Project + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +// Import from Mingw knowfolders.h + +#pragma once + +/* + * - compat_win \x82Ŏg\x97p + * - VS2008 \x82ȂǂŎg\x82\xA6\x82\xE9\x8CÂ\xA2SDK\x82Ńr\x83\x8B\x83h\x82\xB7\x82\xE9\x82Ƃ\xAB\x82Ɏg\x97p + * - FOLDERID_* \x82\xAASDK\x93\xE0\x82ɒ\xE8\x8B`\x82\xB3\x82\xEA\x82Ă\xA2\x82Ȃ\xA2\x82\xBD\x82\xDF + */ +#ifdef INITGUID +#ifdef __cplusplus +#define DEFINE_KNOWN_FOLDER(name, l, w1, w2, b1, b2, b3, b4, b5, b6, b7, b8) EXTERN_C const GUID DECLSPEC_SELECTANY name = { l, w1, w2,{ b1, b2, b3, b4, b5, b6, b7, b8 } } +#else +#define DEFINE_KNOWN_FOLDER(name, l, w1, w2, b1, b2, b3, b4, b5, b6, b7, b8) const GUID DECLSPEC_SELECTANY name = { l, w1, w2,{ b1, b2, b3, b4, b5, b6, b7, b8 } } +#endif +#else +#define DEFINE_KNOWN_FOLDER(name, l, w1, w2, b1, b2, b3, b4, b5, b6, b7, b8) EXTERN_C const GUID name +#endif + +DEFINE_KNOWN_FOLDER(FOLDERID_Desktop, 0xB4BFCC3A, 0xDB2C, 0x424C, 0xB0, 0x29, 0x7F, 0xE9, 0x9A, 0x87, 0xC6, 0x41); +DEFINE_KNOWN_FOLDER(FOLDERID_Documents, 0xFDD39AD0, 0x238F, 0x46AF, 0xAD, 0xB4, 0x6C, 0x85, 0x48, 0x03, 0x69, 0xC7); +DEFINE_KNOWN_FOLDER(FOLDERID_LocalAppData, 0xF1B32785, 0x6FBA, 0x4FCF, 0x9D, 0x55, 0x7B, 0x8E, 0x7F, 0x15, 0x70, 0x91); Modified: trunk/teraterm/teraterm/ttdebug.cpp =================================================================== --- trunk/teraterm/teraterm/ttdebug.cpp 2021-09-10 15:51:25 UTC (rev 9410) +++ trunk/teraterm/teraterm/ttdebug.cpp 2021-09-10 15:51:37 UTC (rev 9411) @@ -255,8 +255,8 @@ static wchar_t *CreateDumpFilename() { // \x82Ƃ肠\x82\xA6\x82\xB8\x83f\x83X\x83N\x83g\x83b\x83v\x82ɍ쐬 - wchar_t desktop[MAX_PATH]; - SHGetSpecialFolderPathW(NULL, desktop, CSIDL_DESKTOPDIRECTORY, FALSE); + wchar_t *desktop; + _SHGetKnownFolderPath(FOLDERID_Desktop, KF_FLAG_CREATE, NULL, &desktop); SYSTEMTIME local_time; GetLocalTime(&local_time); @@ -268,6 +268,7 @@ local_time.wYear, local_time.wMonth, local_time.wDay, local_time.wHour, local_time.wMinute, local_time.wSecond); + free(desktop); return dump_file; }