Fix broken build in last commit
[TortoiseGit.git] / src / TortoiseShell / ItemIDList.cpp
blob1a8557f9af1da4ec279e4652dbcd058f9db659f6
1 // TortoiseGit - a Windows shell extension for easy version control
3 // Copyright (C) 2003-2006,2009,2011 - TortoiseSVN
5 // This program is free software; you can redistribute it and/or
6 // modify it under the terms of the GNU General Public License
7 // as published by the Free Software Foundation; either version 2
8 // of the License, or (at your option) any later version.
10 // This program is distributed in the hope that it will be useful,
11 // but WITHOUT ANY WARRANTY; without even the implied warranty of
12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 // GNU General Public License for more details.
15 // You should have received a copy of the GNU General Public License
16 // along with this program; if not, write to the Free Software Foundation,
17 // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
19 #include "stdafx.h"
20 #include "ShellExt.h"
21 #include "ItemIDList.h"
24 ItemIDList::ItemIDList(LPCITEMIDLIST item, LPCITEMIDLIST parent) :
25 item_ (item)
26 , parent_ (parent)
27 , count_ (-1)
31 ItemIDList::~ItemIDList()
35 int ItemIDList::size() const
37 if (count_ == -1)
39 count_ = 0;
40 if (item_)
42 LPCSHITEMID ptr = &item_->mkid;
43 while (ptr != 0 && ptr->cb != 0)
45 ++count_;
46 LPBYTE byte = (LPBYTE) ptr;
47 byte += ptr->cb;
48 ptr = (LPCSHITEMID) byte;
52 return count_;
55 LPCSHITEMID ItemIDList::get(int index) const
57 int count = 0;
59 if (item_ == NULL)
60 return NULL;
61 LPCSHITEMID ptr = &item_->mkid;
62 if (ptr == NULL)
63 return NULL;
64 while (ptr->cb != 0)
66 if (count == index)
67 break;
69 ++count;
70 LPBYTE byte = (LPBYTE) ptr;
71 byte += ptr->cb;
72 ptr = (LPCSHITEMID) byte;
74 return ptr;
77 stdstring ItemIDList::toString(bool resolveLibraries /*= true*/)
79 IShellFolder *shellFolder = NULL;
80 IShellFolder *parentFolder = NULL;
81 STRRET name;
82 TCHAR * szDisplayName = NULL;
83 stdstring ret;
84 HRESULT hr;
86 hr = ::SHGetDesktopFolder(&shellFolder);
87 if (!SUCCEEDED(hr))
88 return ret;
89 if (parent_)
91 hr = shellFolder->BindToObject(parent_, 0, IID_IShellFolder, (void**) &parentFolder);
92 if (!SUCCEEDED(hr))
93 parentFolder = shellFolder;
95 else
97 parentFolder = shellFolder;
100 if ((parentFolder != 0)&&(item_ != 0))
102 hr = parentFolder->GetDisplayNameOf(item_, SHGDN_NORMAL | SHGDN_FORPARSING, &name);
103 if (!SUCCEEDED(hr))
105 parentFolder->Release();
106 return ret;
108 hr = StrRetToStr (&name, item_, &szDisplayName);
109 if (!SUCCEEDED(hr))
110 return ret;
112 parentFolder->Release();
113 if (szDisplayName == NULL)
115 CoTaskMemFree(szDisplayName);
116 return ret;
118 ret = szDisplayName;
119 CoTaskMemFree(szDisplayName);
120 if ((resolveLibraries) &&
121 (_tcsncmp(ret.c_str(), _T("::{"), 3)==0))
123 CComPtr<IShellLibrary> plib;
124 HRESULT hr = CoCreateInstance(CLSID_ShellLibrary,
125 NULL,
126 CLSCTX_INPROC_SERVER,
127 IID_PPV_ARGS(&plib));
128 if (SUCCEEDED(hr))
130 typedef HRESULT STDAPICALLTYPE SHCreateItemFromParsingNameFN(__in PCWSTR pszPath, __in_opt IBindCtx *pbc, __in REFIID riid, __deref_out void **ppv);
131 CAutoLibrary hShell = AtlLoadSystemLibraryUsingFullPath(_T("shell32.dll"));
132 if (hShell)
134 SHCreateItemFromParsingNameFN *pfnSHCreateItemFromParsingName = (SHCreateItemFromParsingNameFN*)GetProcAddress(hShell, "SHCreateItemFromParsingName");
135 if (pfnSHCreateItemFromParsingName)
137 CComPtr<IShellItem> psiLibrary;
138 hr = pfnSHCreateItemFromParsingName(ret.c_str(), NULL, IID_PPV_ARGS(&psiLibrary));
139 if (SUCCEEDED(hr))
141 hr = plib->LoadLibraryFromItem(psiLibrary, STGM_READ|STGM_SHARE_DENY_NONE);
142 if (SUCCEEDED(hr))
144 CComPtr<IShellItem> psiSaveLocation;
145 hr = plib->GetDefaultSaveFolder(DSFT_DETECT, IID_PPV_ARGS(&psiSaveLocation));
146 if (SUCCEEDED(hr))
148 PWSTR pszName = NULL;
149 hr = psiSaveLocation->GetDisplayName(SIGDN_FILESYSPATH, &pszName);
150 if (SUCCEEDED(hr))
152 ret = pszName;
153 CoTaskMemFree(pszName);
162 return ret;
165 LPCITEMIDLIST ItemIDList::operator& ()
167 return item_;