2 * Virtual MyDocuments Folder
4 * Copyright 2007 Johannes Anderwald
5 * Copyright 2009 Andrew Hill
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.
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.
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
24 WINE_DEFAULT_DEBUG_CHANNEL (mydocs
);
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.
32 /***********************************************************************
33 * MyDocumentsfolder implementation
36 CMyDocsFolder::CMyDocsFolder()
44 CMyDocsFolder::~CMyDocsFolder()
48 HeapFree(GetProcessHeap(), 0, sPathTarget
);
49 m_pisfInner
.Release();
50 m_pisf2Inner
.Release();
53 HRESULT WINAPI
CMyDocsFolder::FinalConstruct()
55 WCHAR szMyPath
[MAX_PATH
];
57 if (!SHGetSpecialFolderPathW(0, szMyPath
, CSIDL_PERSONAL
, TRUE
))
60 pidlRoot
= _ILCreateMyDocuments(); /* my qualified pidl */
61 sPathTarget
= (LPWSTR
)SHAlloc((wcslen(szMyPath
) + 1) * sizeof(WCHAR
));
62 wcscpy(sPathTarget
, szMyPath
);
64 WCHAR szPath
[MAX_PATH
];
65 lstrcpynW(szPath
, sPathTarget
, MAX_PATH
);
68 CComPtr
<IPersistFolder3
> ppf3
;
70 hr
= SHCoCreateInstance(NULL
, &CLSID_ShellFSFolder
, NULL
, IID_PPV_ARG(IShellFolder
, &m_pisfInner
));
74 hr
= m_pisfInner
->QueryInterface(IID_PPV_ARG(IShellFolder2
, &m_pisf2Inner
));
78 hr
= m_pisfInner
->QueryInterface(IID_PPV_ARG(IPersistFolder3
, &ppf3
));
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
);
90 HRESULT WINAPI
CMyDocsFolder::ParseDisplayName(HWND hwndOwner
, LPBC pbc
, LPOLESTR lpszDisplayName
,
91 ULONG
*pchEaten
, PIDLIST_RELATIVE
*ppidl
, ULONG
*pdwAttributes
)
93 return m_pisfInner
->ParseDisplayName(hwndOwner
, pbc
, lpszDisplayName
, pchEaten
, ppidl
, pdwAttributes
);
96 HRESULT WINAPI
CMyDocsFolder::EnumObjects(HWND hwndOwner
, DWORD dwFlags
, LPENUMIDLIST
*ppEnumIDList
)
98 return m_pisfInner
->EnumObjects(hwndOwner
, dwFlags
, ppEnumIDList
);
101 HRESULT WINAPI
CMyDocsFolder::BindToObject(PCUIDLIST_RELATIVE pidl
, LPBC pbcReserved
, REFIID riid
, LPVOID
*ppvOut
)
103 return m_pisfInner
->BindToObject(pidl
, pbcReserved
, riid
, ppvOut
);
106 HRESULT WINAPI
CMyDocsFolder::BindToStorage(PCUIDLIST_RELATIVE pidl
, LPBC pbcReserved
, REFIID riid
, LPVOID
*ppvOut
)
108 return m_pisfInner
->BindToStorage(pidl
, pbcReserved
, riid
, ppvOut
);
111 HRESULT WINAPI
CMyDocsFolder::CompareIDs(LPARAM lParam
, PCUIDLIST_RELATIVE pidl1
, PCUIDLIST_RELATIVE pidl2
)
113 return m_pisfInner
->CompareIDs(lParam
, pidl1
, pidl2
);
116 HRESULT WINAPI
CMyDocsFolder::CreateViewObject(HWND hwndOwner
, REFIID riid
, LPVOID
*ppvOut
)
118 return m_pisfInner
->CreateViewObject(hwndOwner
, riid
, ppvOut
);
121 HRESULT WINAPI
CMyDocsFolder::GetAttributesOf(UINT cidl
, PCUITEMID_CHILD_ARRAY apidl
, DWORD
*rgfInOut
)
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
;
129 return m_pisfInner
->GetAttributesOf(cidl
, apidl
, rgfInOut
);
141 *rgfInOut
&= dwMyDocumentsAttributes
;
143 /* make sure SFGAO_VALIDATE is cleared, some apps depend on that */
144 *rgfInOut
&= ~SFGAO_VALIDATE
;
150 HRESULT WINAPI
CMyDocsFolder::GetUIObjectOf(HWND hwndOwner
, UINT cidl
, PCUITEMID_CHILD_ARRAY apidl
,
151 REFIID riid
, UINT
* prgfInOut
, LPVOID
* ppvOut
)
153 return m_pisfInner
->GetUIObjectOf(hwndOwner
, cidl
, apidl
, riid
, prgfInOut
, ppvOut
);
156 HRESULT WINAPI
CMyDocsFolder::GetDisplayNameOf(PCUITEMID_CHILD pidl
, DWORD dwFlags
, LPSTRRET strRet
)
158 if (!_ILIsSpecialFolder(pidl
))
159 return m_pisfInner
->GetDisplayNameOf(pidl
, dwFlags
, strRet
);
164 TRACE ("(%p)->(pidl=%p,0x%08x,%p)\n", this, pidl
, dwFlags
, strRet
);
170 pszPath
= (LPWSTR
)CoTaskMemAlloc((MAX_PATH
+ 1) * sizeof(WCHAR
));
172 return E_OUTOFMEMORY
;
174 ZeroMemory(pszPath
, (MAX_PATH
+ 1) * sizeof(WCHAR
));
176 if (_ILIsMyDocuments (pidl
) || !pidl
->mkid
.cb
)
178 if ((GET_SHGDN_RELATION (dwFlags
) == SHGDN_NORMAL
) &&
179 (GET_SHGDN_FOR (dwFlags
) & SHGDN_FORPARSING
))
180 wcscpy(pszPath
, sPathTarget
);
182 HCR_GetClassNameW(CLSID_MyDocuments
, pszPath
, MAX_PATH
);
192 strRet
->uType
= STRRET_WSTR
;
193 strRet
->pOleStr
= pszPath
;
196 CoTaskMemFree(pszPath
);
198 TRACE ("-- (%p)->(%s,0x%08x)\n", this, debugstr_w(strRet
->pOleStr
), hr
);
202 HRESULT WINAPI
CMyDocsFolder::SetNameOf(HWND hwndOwner
, PCUITEMID_CHILD pidl
, /* simple pidl */
203 LPCOLESTR lpName
, DWORD dwFlags
, PITEMID_CHILD
*pPidlOut
)
205 return m_pisfInner
->SetNameOf(hwndOwner
, pidl
, lpName
, dwFlags
, pPidlOut
);
208 HRESULT WINAPI
CMyDocsFolder::GetDefaultSearchGUID(GUID
*pguid
)
210 return m_pisf2Inner
->GetDefaultSearchGUID(pguid
);
213 HRESULT WINAPI
CMyDocsFolder::EnumSearches(IEnumExtraSearch
** ppenum
)
215 return m_pisf2Inner
->EnumSearches(ppenum
);
218 HRESULT WINAPI
CMyDocsFolder::GetDefaultColumn(DWORD dwRes
, ULONG
*pSort
, ULONG
*pDisplay
)
220 return m_pisf2Inner
->GetDefaultColumn(dwRes
, pSort
, pDisplay
);
223 HRESULT WINAPI
CMyDocsFolder::GetDefaultColumnState(UINT iColumn
, DWORD
*pcsFlags
)
225 return m_pisf2Inner
->GetDefaultColumnState(iColumn
, pcsFlags
);
228 HRESULT WINAPI
CMyDocsFolder::GetDetailsEx(PCUITEMID_CHILD pidl
, const SHCOLUMNID
*pscid
, VARIANT
*pv
)
230 return m_pisf2Inner
->GetDetailsEx(pidl
, pscid
, pv
);
233 HRESULT WINAPI
CMyDocsFolder::GetDetailsOf(PCUITEMID_CHILD pidl
, UINT iColumn
, SHELLDETAILS
*psd
)
235 return m_pisf2Inner
->GetDetailsOf(pidl
, iColumn
, psd
);
238 HRESULT WINAPI
CMyDocsFolder::MapColumnToSCID(UINT column
, SHCOLUMNID
*pscid
)
240 return m_pisf2Inner
->MapColumnToSCID(column
, pscid
);
243 HRESULT WINAPI
CMyDocsFolder::GetClassID(CLSID
*lpClassId
)
245 TRACE ("(%p)\n", this);
250 memcpy(lpClassId
, &CLSID_MyDocuments
, sizeof(GUID
));
255 HRESULT WINAPI
CMyDocsFolder::Initialize(LPCITEMIDLIST pidl
)
257 TRACE ("(%p)->(%p)\n", this, pidl
);
262 HRESULT WINAPI
CMyDocsFolder::GetCurFolder(LPITEMIDLIST
*pidl
)
264 TRACE ("(%p)->(%p)\n", this, pidl
);
266 if (!pidl
) return E_POINTER
;
267 *pidl
= ILClone (pidlRoot
);