tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

Shell.cpp (8696B)


      1 // Windows/Shell.cpp
      2 
      3 #include "StdAfx.h"
      4 
      5 #include "../Common/MyCom.h"
      6 #ifndef _UNICODE
      7 #include "../Common/StringConvert.h"
      8 #endif
      9 
     10 #include "COM.h"
     11 #include "Shell.h"
     12 
     13 #ifndef _UNICODE
     14 extern bool g_IsNT;
     15 #endif
     16 
     17 namespace NWindows {
     18 namespace NShell {
     19 
     20 #ifndef UNDER_CE
     21 
     22 // SHGetMalloc is unsupported in Windows Mobile?
     23 
     24 void CItemIDList::Free()
     25 {
     26  if (m_Object == NULL)
     27    return;
     28  CMyComPtr<IMalloc> shellMalloc;
     29  if (::SHGetMalloc(&shellMalloc) != NOERROR)
     30    throw 41099;
     31  shellMalloc->Free(m_Object);
     32  m_Object = NULL;
     33 }
     34 
     35 /*
     36 CItemIDList::(LPCITEMIDLIST itemIDList): m_Object(NULL)
     37  {  *this = itemIDList; }
     38 CItemIDList::(const CItemIDList& itemIDList): m_Object(NULL)
     39  {  *this = itemIDList; }
     40 
     41 CItemIDList& CItemIDList::operator=(LPCITEMIDLIST object)
     42 {
     43  Free();
     44  if (object != 0)
     45  {
     46    UINT32 size = GetSize(object);
     47    m_Object = (LPITEMIDLIST)CoTaskMemAlloc(size);
     48    if (m_Object != NULL)
     49      MoveMemory(m_Object, object, size);
     50  }
     51  return *this;
     52 }
     53 
     54 CItemIDList& CItemIDList::operator=(const CItemIDList &object)
     55 {
     56  Free();
     57  if (object.m_Object != NULL)
     58  {
     59    UINT32 size = GetSize(object.m_Object);
     60    m_Object = (LPITEMIDLIST)CoTaskMemAlloc(size);
     61    if (m_Object != NULL)
     62      MoveMemory(m_Object, object.m_Object, size);
     63  }
     64  return *this;
     65 }
     66 */
     67 
     68 /////////////////////////////
     69 // CDrop
     70 
     71 void CDrop::Attach(HDROP object)
     72 {
     73  Free();
     74  m_Object = object;
     75  m_Assigned = true;
     76 }
     77 
     78 void CDrop::Free()
     79 {
     80  if (m_MustBeFinished && m_Assigned)
     81    Finish();
     82  m_Assigned = false;
     83 }
     84 
     85 UINT CDrop::QueryCountOfFiles()
     86 {
     87  return QueryFile(0xFFFFFFFF, (LPTSTR)NULL, 0);
     88 }
     89 
     90 UString CDrop::QueryFileName(UINT fileIndex)
     91 {
     92  UString fileName;
     93  #ifndef _UNICODE
     94  if (!g_IsNT)
     95  {
     96    AString fileNameA;
     97    UINT bufferSize = QueryFile(fileIndex, (LPTSTR)NULL, 0);
     98    const unsigned len = bufferSize + 2;
     99    QueryFile(fileIndex, fileNameA.GetBuf(len), bufferSize + 1);
    100    fileNameA.ReleaseBuf_CalcLen(len);
    101    fileName = GetUnicodeString(fileNameA);
    102  }
    103  else
    104  #endif
    105  {
    106    UINT bufferSize = QueryFile(fileIndex, (LPWSTR)NULL, 0);
    107    const unsigned len = bufferSize + 2;
    108    QueryFile(fileIndex, fileName.GetBuf(len), bufferSize + 1);
    109    fileName.ReleaseBuf_CalcLen(len);
    110  }
    111  return fileName;
    112 }
    113 
    114 void CDrop::QueryFileNames(UStringVector &fileNames)
    115 {
    116  UINT numFiles = QueryCountOfFiles();
    117  fileNames.ClearAndReserve(numFiles);
    118  for (UINT i = 0; i < numFiles; i++)
    119    fileNames.AddInReserved(QueryFileName(i));
    120 }
    121 
    122 
    123 bool GetPathFromIDList(LPCITEMIDLIST itemIDList, CSysString &path)
    124 {
    125  const unsigned len = MAX_PATH * 2;
    126  bool result = BOOLToBool(::SHGetPathFromIDList(itemIDList, path.GetBuf(len)));
    127  path.ReleaseBuf_CalcLen(len);
    128  return result;
    129 }
    130 
    131 #endif
    132 
    133 #ifdef UNDER_CE
    134 
    135 bool BrowseForFolder(LPBROWSEINFO, CSysString)
    136 {
    137  return false;
    138 }
    139 
    140 bool BrowseForFolder(HWND, LPCTSTR, UINT, LPCTSTR, CSysString &)
    141 {
    142  return false;
    143 }
    144 
    145 bool BrowseForFolder(HWND /* owner */, LPCTSTR /* title */,
    146    LPCTSTR /* initialFolder */, CSysString & /* resultPath */)
    147 {
    148  /*
    149  // SHBrowseForFolder doesn't work before CE 6.0 ?
    150  if (GetProcAddress(LoadLibrary(L"ceshell.dll", L"SHBrowseForFolder") == 0)
    151    MessageBoxW(0, L"no", L"", 0);
    152  else
    153    MessageBoxW(0, L"yes", L"", 0);
    154  */
    155  /*
    156  UString s = "all files";
    157  s += " (*.*)";
    158  return MyGetOpenFileName(owner, title, initialFolder, s, resultPath, true);
    159  */
    160  return false;
    161 }
    162 
    163 #else
    164 
    165 bool BrowseForFolder(LPBROWSEINFO browseInfo, CSysString &resultPath)
    166 {
    167  NWindows::NCOM::CComInitializer comInitializer;
    168  LPITEMIDLIST itemIDList = ::SHBrowseForFolder(browseInfo);
    169  if (itemIDList == NULL)
    170    return false;
    171  CItemIDList itemIDListHolder;
    172  itemIDListHolder.Attach(itemIDList);
    173  return GetPathFromIDList(itemIDList, resultPath);
    174 }
    175 
    176 
    177 int CALLBACK BrowseCallbackProc(HWND hwnd, UINT uMsg, LPARAM /* lp */, LPARAM data)
    178 {
    179  #ifndef UNDER_CE
    180  switch (uMsg)
    181  {
    182    case BFFM_INITIALIZED:
    183    {
    184      SendMessage(hwnd, BFFM_SETSELECTION, TRUE, data);
    185      break;
    186    }
    187    /*
    188    case BFFM_SELCHANGED:
    189    {
    190      TCHAR dir[MAX_PATH];
    191      if (::SHGetPathFromIDList((LPITEMIDLIST) lp , dir))
    192        SendMessage(hwnd, BFFM_SETSTATUSTEXT, 0, (LPARAM)dir);
    193      else
    194        SendMessage(hwnd, BFFM_SETSTATUSTEXT, 0, (LPARAM)TEXT(""));
    195      break;
    196    }
    197    */
    198    default:
    199      break;
    200  }
    201  #endif
    202  return 0;
    203 }
    204 
    205 
    206 bool BrowseForFolder(HWND owner, LPCTSTR title, UINT ulFlags,
    207    LPCTSTR initialFolder, CSysString &resultPath)
    208 {
    209  CSysString displayName;
    210  BROWSEINFO browseInfo;
    211  browseInfo.hwndOwner = owner;
    212  browseInfo.pidlRoot = NULL;
    213 
    214  // there are Unicode/Astring problems in some WinCE SDK ?
    215  /*
    216  #ifdef UNDER_CE
    217  browseInfo.pszDisplayName = (LPSTR)displayName.GetBuf(MAX_PATH);
    218  browseInfo.lpszTitle = (LPCSTR)title;
    219  #else
    220  */
    221  browseInfo.pszDisplayName = displayName.GetBuf(MAX_PATH);
    222  browseInfo.lpszTitle = title;
    223  // #endif
    224  browseInfo.ulFlags = ulFlags;
    225  browseInfo.lpfn = (initialFolder != NULL) ? BrowseCallbackProc : NULL;
    226  browseInfo.lParam = (LPARAM)initialFolder;
    227  return BrowseForFolder(&browseInfo, resultPath);
    228 }
    229 
    230 bool BrowseForFolder(HWND owner, LPCTSTR title,
    231    LPCTSTR initialFolder, CSysString &resultPath)
    232 {
    233  return BrowseForFolder(owner, title,
    234      #ifndef UNDER_CE
    235      BIF_NEWDIALOGSTYLE |
    236      #endif
    237      BIF_RETURNONLYFSDIRS | BIF_STATUSTEXT, initialFolder, resultPath);
    238  // BIF_STATUSTEXT; BIF_USENEWUI   (Version 5.0)
    239 }
    240 
    241 #ifndef _UNICODE
    242 
    243 typedef BOOL (WINAPI * SHGetPathFromIDListWP)(LPCITEMIDLIST pidl, LPWSTR pszPath);
    244 
    245 bool GetPathFromIDList(LPCITEMIDLIST itemIDList, UString &path)
    246 {
    247  path.Empty();
    248  SHGetPathFromIDListWP shGetPathFromIDListW = (SHGetPathFromIDListWP)
    249    ::GetProcAddress(::GetModuleHandleW(L"shell32.dll"), "SHGetPathFromIDListW");
    250  if (shGetPathFromIDListW == 0)
    251    return false;
    252  const unsigned len = MAX_PATH * 2;
    253  bool result = BOOLToBool(shGetPathFromIDListW(itemIDList, path.GetBuf(len)));
    254  path.ReleaseBuf_CalcLen(len);
    255  return result;
    256 }
    257 
    258 typedef LPITEMIDLIST (WINAPI * SHBrowseForFolderWP)(LPBROWSEINFOW lpbi);
    259 
    260 bool BrowseForFolder(LPBROWSEINFOW browseInfo, UString &resultPath)
    261 {
    262  NWindows::NCOM::CComInitializer comInitializer;
    263  SHBrowseForFolderWP shBrowseForFolderW = (SHBrowseForFolderWP)
    264    ::GetProcAddress(::GetModuleHandleW(L"shell32.dll"), "SHBrowseForFolderW");
    265  if (shBrowseForFolderW == 0)
    266    return false;
    267  LPITEMIDLIST itemIDList = shBrowseForFolderW(browseInfo);
    268  if (itemIDList == NULL)
    269    return false;
    270  CItemIDList itemIDListHolder;
    271  itemIDListHolder.Attach(itemIDList);
    272  return GetPathFromIDList(itemIDList, resultPath);
    273 }
    274 
    275 
    276 int CALLBACK BrowseCallbackProc2(HWND hwnd, UINT uMsg, LPARAM /* lp */, LPARAM data)
    277 {
    278  switch (uMsg)
    279  {
    280    case BFFM_INITIALIZED:
    281    {
    282      SendMessageW(hwnd, BFFM_SETSELECTIONW, TRUE, data);
    283      break;
    284    }
    285    /*
    286    case BFFM_SELCHANGED:
    287    {
    288      wchar_t dir[MAX_PATH * 2];
    289 
    290      if (shGetPathFromIDListW((LPITEMIDLIST)lp , dir))
    291        SendMessageW(hwnd, BFFM_SETSTATUSTEXTW, 0, (LPARAM)dir);
    292      else
    293        SendMessageW(hwnd, BFFM_SETSTATUSTEXTW, 0, (LPARAM)L"");
    294      break;
    295    }
    296    */
    297    default:
    298      break;
    299  }
    300  return 0;
    301 }
    302 
    303 
    304 static bool BrowseForFolder(HWND owner, LPCWSTR title, UINT ulFlags,
    305    LPCWSTR initialFolder, UString &resultPath)
    306 {
    307  UString displayName;
    308  BROWSEINFOW browseInfo;
    309  browseInfo.hwndOwner = owner;
    310  browseInfo.pidlRoot = NULL;
    311  browseInfo.pszDisplayName = displayName.GetBuf(MAX_PATH);
    312  browseInfo.lpszTitle = title;
    313  browseInfo.ulFlags = ulFlags;
    314  browseInfo.lpfn = (initialFolder != NULL) ? BrowseCallbackProc2 : NULL;
    315  browseInfo.lParam = (LPARAM)initialFolder;
    316  return BrowseForFolder(&browseInfo, resultPath);
    317 }
    318 
    319 bool BrowseForFolder(HWND owner, LPCWSTR title, LPCWSTR initialFolder, UString &resultPath)
    320 {
    321  if (g_IsNT)
    322    return BrowseForFolder(owner, title,
    323      BIF_NEWDIALOGSTYLE | BIF_RETURNONLYFSDIRS
    324      //  | BIF_STATUSTEXT // This flag is not supported when BIF_NEWDIALOGSTYLE is specified.
    325      , initialFolder, resultPath);
    326  // BIF_STATUSTEXT; BIF_USENEWUI   (Version 5.0)
    327  CSysString s;
    328  bool res = BrowseForFolder(owner, GetSystemString(title),
    329      BIF_NEWDIALOGSTYLE | BIF_RETURNONLYFSDIRS
    330      // | BIF_STATUSTEXT  // This flag is not supported when BIF_NEWDIALOGSTYLE is specified.
    331      , GetSystemString(initialFolder), s);
    332  resultPath = GetUnicodeString(s);
    333  return res;
    334 }
    335 
    336 #endif
    337 
    338 #endif
    339 
    340 }}