Revert an unwanted change from r66575.
[reactos.git] / reactos / dll / win32 / shell32 / folders / CMyDocsFolder.cpp
1 /*
2 * Virtual MyDocuments Folder
3 *
4 * Copyright 2007 Johannes Anderwald
5 * Copyright 2009 Andrew Hill
6 *
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
11 *
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
16 *
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
20 */
21
22 #include <precomp.h>
23
24 WINE_DEFAULT_DEBUG_CHANNEL (mydocs);
25
26 /*
27 CFileSysEnumX should not exist. CMyDocsFolder should aggregate a CFSFolder which always
28 maps the contents of CSIDL_PERSONAL. Therefore, CMyDocsFolder::EnumObjects simply calls
29 CFSFolder::EnumObjects.
30 */
31
32 /***********************************************************************
33 * MyDocumentsfolder implementation
34 */
35
36 CMyDocsFolder::CMyDocsFolder()
37 {
38 m_pisfInner = NULL;
39 m_pisf2Inner = NULL;
40 pidlRoot = NULL;
41 sPathTarget = NULL;
42 }
43
44 CMyDocsFolder::~CMyDocsFolder()
45 {
46 SHFree(pidlRoot);
47 if (sPathTarget)
48 HeapFree(GetProcessHeap(), 0, sPathTarget);
49 m_pisfInner.Release();
50 m_pisf2Inner.Release();
51 }
52
53 HRESULT WINAPI CMyDocsFolder::FinalConstruct()
54 {
55 WCHAR szMyPath[MAX_PATH];
56
57 if (!SHGetSpecialFolderPathW(0, szMyPath, CSIDL_PERSONAL, TRUE))
58 return E_UNEXPECTED;
59
60 pidlRoot = _ILCreateMyDocuments(); /* my qualified pidl */
61 sPathTarget = (LPWSTR)SHAlloc((wcslen(szMyPath) + 1) * sizeof(WCHAR));
62 wcscpy(sPathTarget, szMyPath);
63
64 WCHAR szPath[MAX_PATH];
65 lstrcpynW(szPath, sPathTarget, MAX_PATH);
66
67 HRESULT hr;
68 CComPtr<IPersistFolder3> ppf3;
69
70 hr = SHCoCreateInstance(NULL, &CLSID_ShellFSFolder, NULL, IID_PPV_ARG(IShellFolder, &m_pisfInner));
71 if (FAILED(hr))
72 return hr;
73
74 hr = m_pisfInner->QueryInterface(IID_PPV_ARG(IShellFolder2, &m_pisf2Inner));
75 if (FAILED(hr))
76 return hr;
77
78 hr = m_pisfInner->QueryInterface(IID_PPV_ARG(IPersistFolder3, &ppf3));
79 if (FAILED(hr))
80 return hr;
81
82 PERSIST_FOLDER_TARGET_INFO info;
83 ZeroMemory(&info, sizeof(PERSIST_FOLDER_TARGET_INFO));
84 info.csidl = CSIDL_PERSONAL;
85 hr = ppf3->InitializeEx(NULL, pidlRoot, &info);
86
87 return hr;
88 }
89
90 HRESULT WINAPI CMyDocsFolder::ParseDisplayName(HWND hwndOwner, LPBC pbc, LPOLESTR lpszDisplayName,
91 ULONG *pchEaten, PIDLIST_RELATIVE *ppidl, ULONG *pdwAttributes)
92 {
93 return m_pisfInner->ParseDisplayName(hwndOwner, pbc, lpszDisplayName, pchEaten, ppidl, pdwAttributes);
94 }
95
96 HRESULT WINAPI CMyDocsFolder::EnumObjects(HWND hwndOwner, DWORD dwFlags, LPENUMIDLIST *ppEnumIDList)
97 {
98 return m_pisfInner->EnumObjects(hwndOwner, dwFlags, ppEnumIDList);
99 }
100
101 HRESULT WINAPI CMyDocsFolder::BindToObject(PCUIDLIST_RELATIVE pidl, LPBC pbcReserved, REFIID riid, LPVOID *ppvOut)
102 {
103 return m_pisfInner->BindToObject(pidl, pbcReserved, riid, ppvOut);
104 }
105
106 HRESULT WINAPI CMyDocsFolder::BindToStorage(PCUIDLIST_RELATIVE pidl, LPBC pbcReserved, REFIID riid, LPVOID *ppvOut)
107 {
108 return m_pisfInner->BindToStorage(pidl, pbcReserved, riid, ppvOut);
109 }
110
111 HRESULT WINAPI CMyDocsFolder::CompareIDs(LPARAM lParam, PCUIDLIST_RELATIVE pidl1, PCUIDLIST_RELATIVE pidl2)
112 {
113 return m_pisfInner->CompareIDs(lParam, pidl1, pidl2);
114 }
115
116 HRESULT WINAPI CMyDocsFolder::CreateViewObject(HWND hwndOwner, REFIID riid, LPVOID *ppvOut)
117 {
118 return m_pisfInner->CreateViewObject(hwndOwner, riid, ppvOut);
119 }
120
121 HRESULT WINAPI CMyDocsFolder::GetAttributesOf(UINT cidl, PCUITEMID_CHILD_ARRAY apidl, DWORD *rgfInOut)
122 {
123 static const DWORD dwMyDocumentsAttributes =
124 SFGAO_STORAGE | SFGAO_HASPROPSHEET | SFGAO_STORAGEANCESTOR | SFGAO_CANCOPY |
125 SFGAO_FILESYSANCESTOR | SFGAO_FOLDER | SFGAO_FILESYSTEM | SFGAO_HASSUBFOLDER | SFGAO_CANRENAME | SFGAO_CANDELETE;
126
127 if(cidl)
128 {
129 return m_pisfInner->GetAttributesOf(cidl, apidl, rgfInOut);
130 }
131 else
132 {
133 if (!rgfInOut)
134 return E_INVALIDARG;
135 if (cidl && !apidl)
136 return E_INVALIDARG;
137
138 if (*rgfInOut == 0)
139 *rgfInOut = ~0;
140
141 *rgfInOut &= dwMyDocumentsAttributes;
142
143 /* make sure SFGAO_VALIDATE is cleared, some apps depend on that */
144 *rgfInOut &= ~SFGAO_VALIDATE;
145
146 return S_OK;
147 }
148 }
149
150 HRESULT WINAPI CMyDocsFolder::GetUIObjectOf(HWND hwndOwner, UINT cidl, PCUITEMID_CHILD_ARRAY apidl,
151 REFIID riid, UINT * prgfInOut, LPVOID * ppvOut)
152 {
153 return m_pisfInner->GetUIObjectOf(hwndOwner, cidl, apidl, riid, prgfInOut, ppvOut);
154 }
155
156 HRESULT WINAPI CMyDocsFolder::GetDisplayNameOf(PCUITEMID_CHILD pidl, DWORD dwFlags, LPSTRRET strRet)
157 {
158 if (!_ILIsSpecialFolder(pidl))
159 return m_pisfInner->GetDisplayNameOf(pidl, dwFlags, strRet);
160
161 HRESULT hr = S_OK;
162 LPWSTR pszPath;
163
164 TRACE ("(%p)->(pidl=%p,0x%08x,%p)\n", this, pidl, dwFlags, strRet);
165 pdump (pidl);
166
167 if (!strRet)
168 return E_INVALIDARG;
169
170 pszPath = (LPWSTR)CoTaskMemAlloc((MAX_PATH + 1) * sizeof(WCHAR));
171 if (!pszPath)
172 return E_OUTOFMEMORY;
173
174 ZeroMemory(pszPath, (MAX_PATH + 1) * sizeof(WCHAR));
175
176 if (_ILIsMyDocuments (pidl) || !pidl->mkid.cb)
177 {
178 if ((GET_SHGDN_RELATION (dwFlags) == SHGDN_NORMAL) &&
179 (GET_SHGDN_FOR (dwFlags) & SHGDN_FORPARSING))
180 wcscpy(pszPath, sPathTarget);
181 else
182 HCR_GetClassNameW(CLSID_MyDocuments, pszPath, MAX_PATH);
183 TRACE("CP\n");
184 }
185 else
186 {
187 hr = E_INVALIDARG;
188 }
189
190 if (SUCCEEDED(hr))
191 {
192 strRet->uType = STRRET_WSTR;
193 strRet->pOleStr = pszPath;
194 }
195 else
196 CoTaskMemFree(pszPath);
197
198 TRACE ("-- (%p)->(%s,0x%08x)\n", this, debugstr_w(strRet->pOleStr), hr);
199 return hr;
200 }
201
202 HRESULT WINAPI CMyDocsFolder::SetNameOf(HWND hwndOwner, PCUITEMID_CHILD pidl, /* simple pidl */
203 LPCOLESTR lpName, DWORD dwFlags, PITEMID_CHILD *pPidlOut)
204 {
205 return m_pisfInner->SetNameOf(hwndOwner, pidl, lpName, dwFlags, pPidlOut);
206 }
207
208 HRESULT WINAPI CMyDocsFolder::GetDefaultSearchGUID(GUID *pguid)
209 {
210 return m_pisf2Inner->GetDefaultSearchGUID(pguid);
211 }
212
213 HRESULT WINAPI CMyDocsFolder::EnumSearches(IEnumExtraSearch ** ppenum)
214 {
215 return m_pisf2Inner->EnumSearches(ppenum);
216 }
217
218 HRESULT WINAPI CMyDocsFolder::GetDefaultColumn(DWORD dwRes, ULONG *pSort, ULONG *pDisplay)
219 {
220 return m_pisf2Inner->GetDefaultColumn(dwRes, pSort, pDisplay);
221 }
222
223 HRESULT WINAPI CMyDocsFolder::GetDefaultColumnState(UINT iColumn, DWORD *pcsFlags)
224 {
225 return m_pisf2Inner->GetDefaultColumnState(iColumn, pcsFlags);
226 }
227
228 HRESULT WINAPI CMyDocsFolder::GetDetailsEx(PCUITEMID_CHILD pidl, const SHCOLUMNID *pscid, VARIANT *pv)
229 {
230 return m_pisf2Inner->GetDetailsEx(pidl, pscid, pv);
231 }
232
233 HRESULT WINAPI CMyDocsFolder::GetDetailsOf(PCUITEMID_CHILD pidl, UINT iColumn, SHELLDETAILS *psd)
234 {
235 return m_pisf2Inner->GetDetailsOf(pidl, iColumn, psd);
236 }
237
238 HRESULT WINAPI CMyDocsFolder::MapColumnToSCID(UINT column, SHCOLUMNID *pscid)
239 {
240 return m_pisf2Inner->MapColumnToSCID(column, pscid);
241 }
242
243 HRESULT WINAPI CMyDocsFolder::GetClassID(CLSID *lpClassId)
244 {
245 TRACE ("(%p)\n", this);
246
247 if (!lpClassId)
248 return E_POINTER;
249
250 memcpy(lpClassId, &CLSID_MyDocuments, sizeof(GUID));
251
252 return S_OK;
253 }
254
255 HRESULT WINAPI CMyDocsFolder::Initialize(LPCITEMIDLIST pidl)
256 {
257 TRACE ("(%p)->(%p)\n", this, pidl);
258
259 return E_NOTIMPL;
260 }
261
262 HRESULT WINAPI CMyDocsFolder::GetCurFolder(LPITEMIDLIST *pidl)
263 {
264 TRACE ("(%p)->(%p)\n", this, pidl);
265
266 if (!pidl) return E_POINTER;
267 *pidl = ILClone (pidlRoot);
268 return S_OK;
269 }