Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygenfs.cpp
Go to the documentation of this file.
00001 00002 /* 00003 * file system folder 00004 * 00005 * Copyright 1997 Marcus Meissner 00006 * Copyright 1998, 1999, 2002 Juergen Schmied 00007 * 00008 * This library is free software; you can redistribute it and/or 00009 * modify it under the terms of the GNU Lesser General Public 00010 * License as published by the Free Software Foundation; either 00011 * version 2.1 of the License, or (at your option) any later version. 00012 * 00013 * This library is distributed in the hope that it will be useful, 00014 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00015 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00016 * Lesser General Public License for more details. 00017 * 00018 * You should have received a copy of the GNU Lesser General Public 00019 * License along with this library; if not, write to the Free Software 00020 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA 00021 */ 00022 00023 #include <precomp.h> 00024 00025 WINE_DEFAULT_DEBUG_CHANNEL (shell); 00026 00027 /* 00028 CFileSysEnum should do an initial FindFirstFile and do a FindNextFile as each file is 00029 returned by Next. When the enumerator is created, it can do numerous additional operations 00030 including formatting a drive, reconnecting a network share drive, and requesting a disk 00031 be inserted in a removable drive. 00032 */ 00033 00034 /*********************************************************************** 00035 * IShellFolder implementation 00036 */ 00037 00038 class CFileSysEnum : 00039 public IEnumIDListImpl 00040 { 00041 private: 00042 public: 00043 CFileSysEnum(); 00044 ~CFileSysEnum(); 00045 HRESULT WINAPI Initialize(LPWSTR sPathTarget, DWORD dwFlags); 00046 00047 BEGIN_COM_MAP(CFileSysEnum) 00048 COM_INTERFACE_ENTRY_IID(IID_IEnumIDList, IEnumIDList) 00049 END_COM_MAP() 00050 }; 00051 00052 CFileSysEnum::CFileSysEnum() 00053 { 00054 } 00055 00056 CFileSysEnum::~CFileSysEnum() 00057 { 00058 } 00059 00060 HRESULT WINAPI CFileSysEnum::Initialize(LPWSTR sPathTarget, DWORD dwFlags) 00061 { 00062 return CreateFolderEnumList(sPathTarget, dwFlags); 00063 } 00064 00065 /************************************************************************** 00066 * registers clipboardformat once 00067 */ 00068 void CFSFolder::SF_RegisterClipFmt() 00069 { 00070 TRACE ("(%p)\n", this); 00071 00072 if (!cfShellIDList) 00073 cfShellIDList = RegisterClipboardFormatW(CFSTR_SHELLIDLIST); 00074 } 00075 00076 CFSFolder::CFSFolder() 00077 { 00078 pclsid = (CLSID *)&CLSID_ShellFSFolder; 00079 sPathTarget = NULL; 00080 pidlRoot = NULL; 00081 cfShellIDList = 0; 00082 fAcceptFmt = FALSE; 00083 } 00084 00085 CFSFolder::~CFSFolder() 00086 { 00087 TRACE("-- destroying IShellFolder(%p)\n", this); 00088 00089 SHFree(pidlRoot); 00090 SHFree(sPathTarget); 00091 } 00092 00093 00094 static const shvheader GenericSFHeader[] = { 00095 {IDS_SHV_COLUMN1, SHCOLSTATE_TYPE_STR | SHCOLSTATE_ONBYDEFAULT, LVCFMT_RIGHT, 15}, 00096 {IDS_SHV_COLUMN2, SHCOLSTATE_TYPE_STR | SHCOLSTATE_ONBYDEFAULT, LVCFMT_RIGHT, 10}, 00097 {IDS_SHV_COLUMN3, SHCOLSTATE_TYPE_STR | SHCOLSTATE_ONBYDEFAULT, LVCFMT_RIGHT, 10}, 00098 {IDS_SHV_COLUMN4, SHCOLSTATE_TYPE_DATE | SHCOLSTATE_ONBYDEFAULT, LVCFMT_RIGHT, 12}, 00099 {IDS_SHV_COLUMN5, SHCOLSTATE_TYPE_STR | SHCOLSTATE_ONBYDEFAULT, LVCFMT_RIGHT, 5} 00100 }; 00101 00102 #define GENERICSHELLVIEWCOLUMNS 5 00103 00104 /************************************************************************** 00105 * SHELL32_CreatePidlFromBindCtx [internal] 00106 * 00107 * If the caller bound File System Bind Data, assume it is the 00108 * find data for the path. 00109 * This allows binding of paths that don't exist. 00110 */ 00111 LPITEMIDLIST SHELL32_CreatePidlFromBindCtx(IBindCtx *pbc, LPCWSTR path) 00112 { 00113 static WCHAR szfsbc[] = L"File System Bind Data"; 00114 IFileSystemBindData *fsbd = NULL; 00115 LPITEMIDLIST pidl = NULL; 00116 IUnknown *param = NULL; 00117 WIN32_FIND_DATAW wfd; 00118 HRESULT r; 00119 00120 TRACE("%p %s\n", pbc, debugstr_w(path)); 00121 00122 if (!pbc) 00123 return NULL; 00124 00125 /* see if the caller bound File System Bind Data */ 00126 r = pbc->GetObjectParam((LPOLESTR)szfsbc, ¶m); 00127 if (FAILED(r)) 00128 return NULL; 00129 00130 r = param->QueryInterface(IID_IFileSystemBindData, 00131 (LPVOID*)&fsbd ); 00132 if (SUCCEEDED(r)) 00133 { 00134 r = fsbd->GetFindData(&wfd); 00135 if (SUCCEEDED(r)) 00136 { 00137 lstrcpynW(&wfd.cFileName[0], path, MAX_PATH); 00138 pidl = _ILCreateFromFindDataW(&wfd); 00139 } 00140 fsbd->Release(); 00141 } 00142 00143 return pidl; 00144 } 00145 00146 /************************************************************************** 00147 * CFSFolder::ParseDisplayName {SHELL32} 00148 * 00149 * Parse a display name. 00150 * 00151 * PARAMS 00152 * hwndOwner [in] Parent window for any message's 00153 * pbc [in] optional FileSystemBindData context 00154 * lpszDisplayName [in] Unicode displayname. 00155 * pchEaten [out] (unicode) characters processed 00156 * ppidl [out] complex pidl to item 00157 * pdwAttributes [out] items attributes 00158 * 00159 * NOTES 00160 * Every folder tries to parse only its own (the leftmost) pidl and creates a 00161 * subfolder to evaluate the remaining parts. 00162 * Now we can parse into namespaces implemented by shell extensions 00163 * 00164 * Behaviour on win98: lpszDisplayName=NULL -> crash 00165 * lpszDisplayName="" -> returns mycoputer-pidl 00166 * 00167 * FIXME 00168 * pdwAttributes is not set 00169 * pchEaten is not set like in windows 00170 */ 00171 HRESULT WINAPI CFSFolder::ParseDisplayName(HWND hwndOwner, 00172 LPBC pbc, 00173 LPOLESTR lpszDisplayName, 00174 DWORD *pchEaten, LPITEMIDLIST *ppidl, 00175 DWORD *pdwAttributes) 00176 { 00177 HRESULT hr = E_INVALIDARG; 00178 LPCWSTR szNext = NULL; 00179 WCHAR szElement[MAX_PATH]; 00180 WCHAR szPath[MAX_PATH]; 00181 LPITEMIDLIST pidlTemp = NULL; 00182 DWORD len; 00183 00184 TRACE ("(%p)->(HWND=%p,%p,%p=%s,%p,pidl=%p,%p)\n", 00185 this, hwndOwner, pbc, lpszDisplayName, debugstr_w (lpszDisplayName), 00186 pchEaten, ppidl, pdwAttributes); 00187 00188 if (!ppidl) 00189 return E_INVALIDARG; 00190 00191 if (!lpszDisplayName) 00192 { 00193 *ppidl = NULL; 00194 return E_INVALIDARG; 00195 } 00196 00197 *ppidl = NULL; 00198 00199 if (pchEaten) 00200 *pchEaten = 0; /* strange but like the original */ 00201 00202 pidlTemp = SHELL32_CreatePidlFromBindCtx(pbc, lpszDisplayName); 00203 if (!pidlTemp && *lpszDisplayName) 00204 { 00205 /* get the next element */ 00206 szNext = GetNextElementW (lpszDisplayName, szElement, MAX_PATH); 00207 00208 /* build the full pathname to the element */ 00209 lstrcpynW(szPath, sPathTarget, MAX_PATH - 1); 00210 PathAddBackslashW(szPath); 00211 len = wcslen(szPath); 00212 lstrcpynW(szPath + len, szElement, MAX_PATH - len); 00213 00214 /* get the pidl */ 00215 hr = _ILCreateFromPathW(szPath, &pidlTemp); 00216 00217 if (SUCCEEDED(hr)) 00218 { 00219 if (szNext && *szNext) 00220 { 00221 /* try to analyse the next element */ 00222 hr = SHELL32_ParseNextElement(this, hwndOwner, pbc, 00223 &pidlTemp, (LPOLESTR) szNext, pchEaten, pdwAttributes); 00224 } 00225 else 00226 { 00227 /* it's the last element */ 00228 if (pdwAttributes && *pdwAttributes) 00229 hr = SHELL32_GetItemAttributes(this, pidlTemp, pdwAttributes); 00230 } 00231 } 00232 } 00233 00234 if (SUCCEEDED(hr)) 00235 *ppidl = pidlTemp; 00236 else 00237 *ppidl = NULL; 00238 00239 TRACE("(%p)->(-- pidl=%p ret=0x%08x)\n", this, ppidl ? *ppidl : 0, hr); 00240 00241 return hr; 00242 } 00243 00244 /************************************************************************** 00245 * CFSFolder::EnumObjects 00246 * PARAMETERS 00247 * HWND hwndOwner, //[in ] Parent Window 00248 * DWORD grfFlags, //[in ] SHCONTF enumeration mask 00249 * LPENUMIDLIST* ppenumIDList //[out] IEnumIDList interface 00250 */ 00251 HRESULT WINAPI CFSFolder::EnumObjects( 00252 HWND hwndOwner, 00253 DWORD dwFlags, 00254 LPENUMIDLIST *ppEnumIDList) 00255 { 00256 CComObject<CFileSysEnum> *theEnumerator; 00257 CComPtr<IEnumIDList> result; 00258 HRESULT hResult; 00259 00260 TRACE("(%p)->(HWND=%p flags=0x%08x pplist=%p)\n", this, hwndOwner, dwFlags, ppEnumIDList); 00261 00262 if (ppEnumIDList == NULL) 00263 return E_POINTER; 00264 *ppEnumIDList = NULL; 00265 ATLTRY (theEnumerator = new CComObject<CFileSysEnum>); 00266 if (theEnumerator == NULL) 00267 return E_OUTOFMEMORY; 00268 hResult = theEnumerator->QueryInterface (IID_IEnumIDList, (void **)&result); 00269 if (FAILED (hResult)) 00270 { 00271 delete theEnumerator; 00272 return hResult; 00273 } 00274 hResult = theEnumerator->Initialize (sPathTarget, dwFlags); 00275 if (FAILED (hResult)) 00276 return hResult; 00277 *ppEnumIDList = result.Detach(); 00278 00279 TRACE("-- (%p)->(new ID List: %p)\n", this, *ppEnumIDList); 00280 00281 return S_OK; 00282 } 00283 00284 /************************************************************************** 00285 * CFSFolder::BindToObject 00286 * PARAMETERS 00287 * LPCITEMIDLIST pidl, //[in ] relative pidl to open 00288 * LPBC pbc, //[in ] optional FileSystemBindData context 00289 * REFIID riid, //[in ] Initial Interface 00290 * LPVOID* ppvObject //[out] Interface* 00291 */ 00292 HRESULT WINAPI CFSFolder::BindToObject( 00293 LPCITEMIDLIST pidl, 00294 LPBC pbc, 00295 REFIID riid, 00296 LPVOID * ppvOut) 00297 { 00298 TRACE("(%p)->(pidl=%p,%p,%s,%p)\n", this, pidl, pbc, 00299 shdebugstr_guid(&riid), ppvOut); 00300 00301 return SHELL32_BindToChild(pidlRoot, sPathTarget, pidl, riid, ppvOut); 00302 } 00303 00304 /************************************************************************** 00305 * CFSFolder::BindToStorage 00306 * PARAMETERS 00307 * LPCITEMIDLIST pidl, //[in ] complex pidl to store 00308 * LPBC pbc, //[in ] reserved 00309 * REFIID riid, //[in ] Initial storage interface 00310 * LPVOID* ppvObject //[out] Interface* returned 00311 */ 00312 HRESULT WINAPI CFSFolder::BindToStorage( 00313 LPCITEMIDLIST pidl, 00314 LPBC pbcReserved, 00315 REFIID riid, 00316 LPVOID *ppvOut) 00317 { 00318 FIXME("(%p)->(pidl=%p,%p,%s,%p) stub\n", this, pidl, pbcReserved, 00319 shdebugstr_guid (&riid), ppvOut); 00320 00321 *ppvOut = NULL; 00322 return E_NOTIMPL; 00323 } 00324 00325 /************************************************************************** 00326 * CFSFolder::CompareIDs 00327 */ 00328 00329 HRESULT WINAPI CFSFolder::CompareIDs(LPARAM lParam, 00330 LPCITEMIDLIST pidl1, LPCITEMIDLIST pidl2) 00331 { 00332 int nReturn; 00333 00334 TRACE("(%p)->(0x%08lx,pidl1=%p,pidl2=%p)\n", this, lParam, pidl1, pidl2); 00335 nReturn = SHELL32_CompareIDs(this, lParam, pidl1, pidl2); 00336 TRACE("-- %i\n", nReturn); 00337 return nReturn; 00338 } 00339 00340 /************************************************************************** 00341 * CFSFolder::CreateViewObject 00342 */ 00343 HRESULT WINAPI CFSFolder::CreateViewObject(HWND hwndOwner, 00344 REFIID riid, LPVOID * ppvOut) 00345 { 00346 LPSHELLVIEW pShellView; 00347 HRESULT hr = E_INVALIDARG; 00348 00349 TRACE ("(%p)->(hwnd=%p,%s,%p)\n", this, hwndOwner, shdebugstr_guid (&riid), 00350 ppvOut); 00351 00352 if (ppvOut) 00353 { 00354 *ppvOut = NULL; 00355 00356 if (IsEqualIID (riid, IID_IDropTarget)) 00357 hr = this->QueryInterface (IID_IDropTarget, ppvOut); 00358 else if (IsEqualIID (riid, IID_IContextMenu)) 00359 { 00360 FIXME ("IContextMenu not implemented\n"); 00361 hr = E_NOTIMPL; 00362 } 00363 else if (IsEqualIID (riid, IID_IShellView)) 00364 { 00365 hr = IShellView_Constructor ((IShellFolder *)this, &pShellView); 00366 if (pShellView) 00367 { 00368 hr = pShellView->QueryInterface(riid, ppvOut); 00369 pShellView->Release(); 00370 } 00371 } 00372 } 00373 TRACE("-- (%p)->(interface=%p)\n", this, ppvOut); 00374 return hr; 00375 } 00376 00377 /************************************************************************** 00378 * CFSFolder::GetAttributesOf 00379 * 00380 * PARAMETERS 00381 * UINT cidl, //[in ] num elements in pidl array 00382 * LPCITEMIDLIST* apidl, //[in ] simple pidl array 00383 * ULONG* rgfInOut) //[out] result array 00384 * 00385 */ 00386 HRESULT WINAPI CFSFolder::GetAttributesOf(UINT cidl, 00387 LPCITEMIDLIST * apidl, DWORD * rgfInOut) 00388 { 00389 HRESULT hr = S_OK; 00390 00391 TRACE("(%p)->(cidl=%d apidl=%p mask=%p (0x%08x))\n", this, cidl, apidl, 00392 rgfInOut, rgfInOut ? *rgfInOut : 0); 00393 00394 if (!rgfInOut) 00395 return E_INVALIDARG; 00396 if (cidl && !apidl) 00397 return E_INVALIDARG; 00398 00399 if (*rgfInOut == 0) 00400 *rgfInOut = ~0; 00401 00402 if(cidl == 0) 00403 { 00404 IShellFolder *psfParent = NULL; 00405 LPCITEMIDLIST rpidl = NULL; 00406 00407 hr = SHBindToParent(pidlRoot, IID_IShellFolder, (LPVOID*)&psfParent, (LPCITEMIDLIST*)&rpidl); 00408 if(SUCCEEDED(hr)) 00409 { 00410 SHELL32_GetItemAttributes (psfParent, rpidl, rgfInOut); 00411 psfParent->Release(); 00412 } 00413 } 00414 else 00415 { 00416 while (cidl > 0 && *apidl) 00417 { 00418 pdump(*apidl); 00419 SHELL32_GetItemAttributes(this, *apidl, rgfInOut); 00420 apidl++; 00421 cidl--; 00422 } 00423 } 00424 /* make sure SFGAO_VALIDATE is cleared, some apps depend on that */ 00425 *rgfInOut &= ~SFGAO_VALIDATE; 00426 00427 TRACE("-- result=0x%08x\n", *rgfInOut); 00428 00429 return hr; 00430 } 00431 00432 /************************************************************************** 00433 * CFSFolder::GetUIObjectOf 00434 * 00435 * PARAMETERS 00436 * HWND hwndOwner, //[in ] Parent window for any output 00437 * UINT cidl, //[in ] array size 00438 * LPCITEMIDLIST* apidl, //[in ] simple pidl array 00439 * REFIID riid, //[in ] Requested Interface 00440 * UINT* prgfInOut, //[ ] reserved 00441 * LPVOID* ppvObject) //[out] Resulting Interface 00442 * 00443 * NOTES 00444 * This function gets asked to return "view objects" for one or more (multiple 00445 * select) items: 00446 * The viewobject typically is an COM object with one of the following 00447 * interfaces: 00448 * IExtractIcon,IDataObject,IContextMenu 00449 * In order to support icon positions in the default Listview your DataObject 00450 * must implement the SetData method (in addition to GetData :) - the shell 00451 * passes a barely documented "Icon positions" structure to SetData when the 00452 * drag starts, and GetData's it if the drop is in another explorer window that 00453 * needs the positions. 00454 */ 00455 HRESULT WINAPI CFSFolder::GetUIObjectOf(HWND hwndOwner, 00456 UINT cidl, LPCITEMIDLIST * apidl, REFIID riid, 00457 UINT * prgfInOut, LPVOID * ppvOut) 00458 { 00459 LPITEMIDLIST pidl; 00460 IUnknown *pObj = NULL; 00461 HRESULT hr = E_INVALIDARG; 00462 00463 TRACE ("(%p)->(%p,%u,apidl=%p,%s,%p,%p)\n", 00464 this, hwndOwner, cidl, apidl, shdebugstr_guid (&riid), prgfInOut, ppvOut); 00465 00466 if (ppvOut) 00467 { 00468 *ppvOut = NULL; 00469 00470 if (IsEqualIID (riid, IID_IContextMenu) && (cidl >= 1)) 00471 hr = CDefFolderMenu_Create2(pidlRoot, hwndOwner, cidl, apidl, (IShellFolder*)this, NULL, 0, NULL, (IContextMenu**)&pObj); 00472 else if (IsEqualIID (riid, IID_IDataObject)) 00473 { 00474 if (cidl >= 1) { 00475 hr = IDataObject_Constructor (hwndOwner, pidlRoot, apidl, cidl, (IDataObject **)&pObj); 00476 } 00477 else 00478 { 00479 hr = IDataObject_Constructor (hwndOwner, pidlRoot, (LPCITEMIDLIST*)&pidlRoot, 1, (IDataObject **)&pObj); 00480 } 00481 } 00482 else if (IsEqualIID (riid, IID_IExtractIconA) && (cidl == 1)) 00483 { 00484 pidl = ILCombine (pidlRoot, apidl[0]); 00485 pObj = (LPUNKNOWN) IExtractIconA_Constructor (pidl); 00486 SHFree (pidl); 00487 hr = S_OK; 00488 } 00489 else if (IsEqualIID (riid, IID_IExtractIconW) && (cidl == 1)) 00490 { 00491 pidl = ILCombine (pidlRoot, apidl[0]); 00492 pObj = (LPUNKNOWN) IExtractIconW_Constructor (pidl); 00493 SHFree (pidl); 00494 hr = S_OK; 00495 } 00496 else if (IsEqualIID (riid, IID_IDropTarget) && (cidl >= 1)) 00497 hr = this->QueryInterface(IID_IDropTarget, (LPVOID*)&pObj); 00498 else if ((IsEqualIID(riid, IID_IShellLinkW) || 00499 IsEqualIID(riid, IID_IShellLinkA)) && (cidl == 1)) 00500 { 00501 pidl = ILCombine (pidlRoot, apidl[0]); 00502 hr = IShellLink_ConstructFromFile(NULL, riid, pidl, (LPVOID*)&pObj); 00503 SHFree (pidl); 00504 } 00505 else 00506 hr = E_NOINTERFACE; 00507 00508 if (SUCCEEDED(hr) && !pObj) 00509 hr = E_OUTOFMEMORY; 00510 00511 *ppvOut = pObj; 00512 } 00513 TRACE("(%p)->hr=0x%08x\n", this, hr); 00514 return hr; 00515 } 00516 00517 static const WCHAR AdvancedW[] = L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Advanced"; 00518 static const WCHAR HideFileExtW[] = L"HideFileExt"; 00519 static const WCHAR NeverShowExtW[] = L"NeverShowExt"; 00520 00521 /****************************************************************************** 00522 * SHELL_FS_HideExtension [Internal] 00523 * 00524 * Query the registry if the filename extension of a given path should be 00525 * hidden. 00526 * 00527 * PARAMS 00528 * szPath [I] Relative or absolute path of a file 00529 * 00530 * RETURNS 00531 * TRUE, if the filename's extension should be hidden 00532 * FALSE, otherwise. 00533 */ 00534 BOOL SHELL_FS_HideExtension(LPWSTR szPath) 00535 { 00536 HKEY hKey; 00537 DWORD dwData; 00538 DWORD dwDataSize = sizeof (DWORD); 00539 BOOL doHide = FALSE; /* The default value is FALSE (win98 at least) */ 00540 00541 if (!RegCreateKeyExW(HKEY_CURRENT_USER, AdvancedW, 0, 0, 0, KEY_ALL_ACCESS, 0, &hKey, 0)) { 00542 if (!RegQueryValueExW(hKey, HideFileExtW, 0, 0, (LPBYTE) &dwData, &dwDataSize)) 00543 doHide = dwData; 00544 RegCloseKey (hKey); 00545 } 00546 00547 if (!doHide) { 00548 LPWSTR ext = PathFindExtensionW(szPath); 00549 00550 if (*ext != '\0') { 00551 WCHAR classname[MAX_PATH]; 00552 LONG classlen = sizeof(classname); 00553 00554 if (!RegQueryValueW(HKEY_CLASSES_ROOT, ext, classname, &classlen)) 00555 if (!RegOpenKeyW(HKEY_CLASSES_ROOT, classname, &hKey)) { 00556 if (!RegQueryValueExW(hKey, NeverShowExtW, 0, NULL, NULL, NULL)) 00557 doHide = TRUE; 00558 RegCloseKey(hKey); 00559 } 00560 } 00561 } 00562 return doHide; 00563 } 00564 00565 void SHELL_FS_ProcessDisplayFilename(LPWSTR szPath, DWORD dwFlags) 00566 { 00567 /*FIXME: MSDN also mentions SHGDN_FOREDITING which is not yet handled. */ 00568 if (!(dwFlags & SHGDN_FORPARSING) && 00569 ((dwFlags & SHGDN_INFOLDER) || (dwFlags == SHGDN_NORMAL))) { 00570 if (SHELL_FS_HideExtension(szPath) && szPath[0] != '.') 00571 PathRemoveExtensionW(szPath); 00572 } 00573 } 00574 00575 /************************************************************************** 00576 * CFSFolder::GetDisplayNameOf 00577 * Retrieves the display name for the specified file object or subfolder 00578 * 00579 * PARAMETERS 00580 * LPCITEMIDLIST pidl, //[in ] complex pidl to item 00581 * DWORD dwFlags, //[in ] SHGNO formatting flags 00582 * LPSTRRET lpName) //[out] Returned display name 00583 * 00584 * FIXME 00585 * if the name is in the pidl the ret value should be a STRRET_OFFSET 00586 */ 00587 00588 HRESULT WINAPI CFSFolder::GetDisplayNameOf(LPCITEMIDLIST pidl, 00589 DWORD dwFlags, LPSTRRET strRet) 00590 { 00591 LPWSTR pszPath; 00592 00593 HRESULT hr = S_OK; 00594 int len = 0; 00595 00596 TRACE("(%p)->(pidl=%p,0x%08x,%p)\n", this, pidl, dwFlags, strRet); 00597 pdump(pidl); 00598 00599 if (!pidl || !strRet) 00600 return E_INVALIDARG; 00601 00602 pszPath = (LPWSTR)CoTaskMemAlloc((MAX_PATH + 1) * sizeof(WCHAR)); 00603 if (!pszPath) 00604 return E_OUTOFMEMORY; 00605 00606 if (_ILIsDesktop(pidl)) /* empty pidl */ 00607 { 00608 if ((GET_SHGDN_FOR(dwFlags) & SHGDN_FORPARSING) && 00609 (GET_SHGDN_RELATION(dwFlags) != SHGDN_INFOLDER)) 00610 { 00611 if (sPathTarget) 00612 lstrcpynW(pszPath, sPathTarget, MAX_PATH); 00613 } 00614 else 00615 hr = E_INVALIDARG; /* pidl has to contain exactly one non null SHITEMID */ 00616 } 00617 else if (_ILIsPidlSimple(pidl)) 00618 { 00619 if ((GET_SHGDN_FOR(dwFlags) & SHGDN_FORPARSING) && 00620 (GET_SHGDN_RELATION(dwFlags) != SHGDN_INFOLDER) && 00621 sPathTarget) 00622 { 00623 lstrcpynW(pszPath, sPathTarget, MAX_PATH); 00624 PathAddBackslashW(pszPath); 00625 len = wcslen(pszPath); 00626 } 00627 _ILSimpleGetTextW(pidl, pszPath + len, MAX_PATH + 1 - len); 00628 if (!_ILIsFolder(pidl)) SHELL_FS_ProcessDisplayFilename(pszPath, dwFlags); 00629 } else 00630 hr = SHELL32_GetDisplayNameOfChild(this, pidl, dwFlags, pszPath, MAX_PATH); 00631 00632 if (SUCCEEDED(hr)) { 00633 /* Win9x always returns ANSI strings, NT always returns Unicode strings */ 00634 if (GetVersion() & 0x80000000) 00635 { 00636 strRet->uType = STRRET_CSTR; 00637 if (!WideCharToMultiByte(CP_ACP, 0, pszPath, -1, strRet->cStr, MAX_PATH, 00638 NULL, NULL)) 00639 strRet->cStr[0] = '\0'; 00640 CoTaskMemFree(pszPath); 00641 } 00642 else 00643 { 00644 strRet->uType = STRRET_WSTR; 00645 strRet->pOleStr = pszPath; 00646 } 00647 } else 00648 CoTaskMemFree(pszPath); 00649 00650 TRACE ("-- (%p)->(%s)\n", this, strRet->uType == STRRET_CSTR ? strRet->cStr : debugstr_w(strRet->pOleStr)); 00651 return hr; 00652 } 00653 00654 /************************************************************************** 00655 * CFSFolder::SetNameOf 00656 * Changes the name of a file object or subfolder, possibly changing its item 00657 * identifier in the process. 00658 * 00659 * PARAMETERS 00660 * HWND hwndOwner, //[in ] Owner window for output 00661 * LPCITEMIDLIST pidl, //[in ] simple pidl of item to change 00662 * LPCOLESTR lpszName, //[in ] the items new display name 00663 * DWORD dwFlags, //[in ] SHGNO formatting flags 00664 * LPITEMIDLIST* ppidlOut) //[out] simple pidl returned 00665 */ 00666 HRESULT WINAPI CFSFolder::SetNameOf( 00667 HWND hwndOwner, 00668 LPCITEMIDLIST pidl, 00669 LPCOLESTR lpName, 00670 DWORD dwFlags, 00671 LPITEMIDLIST * pPidlOut) 00672 { 00673 WCHAR szSrc[MAX_PATH + 1], szDest[MAX_PATH + 1]; 00674 LPWSTR ptr; 00675 BOOL bIsFolder = _ILIsFolder (ILFindLastID (pidl)); 00676 00677 TRACE ("(%p)->(%p,pidl=%p,%s,%u,%p)\n", this, hwndOwner, pidl, 00678 debugstr_w (lpName), dwFlags, pPidlOut); 00679 00680 /* build source path */ 00681 lstrcpynW(szSrc, sPathTarget, MAX_PATH); 00682 ptr = PathAddBackslashW (szSrc); 00683 if (ptr) 00684 _ILSimpleGetTextW (pidl, ptr, MAX_PATH + 1 - (ptr - szSrc)); 00685 00686 /* build destination path */ 00687 if (dwFlags == SHGDN_NORMAL || dwFlags & SHGDN_INFOLDER) { 00688 lstrcpynW(szDest, sPathTarget, MAX_PATH); 00689 ptr = PathAddBackslashW (szDest); 00690 if (ptr) 00691 lstrcpynW(ptr, lpName, MAX_PATH + 1 - (ptr - szDest)); 00692 } else 00693 lstrcpynW(szDest, lpName, MAX_PATH); 00694 00695 if(!(dwFlags & SHGDN_FORPARSING) && SHELL_FS_HideExtension(szSrc)) { 00696 WCHAR *ext = PathFindExtensionW(szSrc); 00697 if(*ext != '\0') { 00698 INT len = wcslen(szDest); 00699 lstrcpynW(szDest + len, ext, MAX_PATH - len); 00700 } 00701 } 00702 00703 TRACE ("src=%s dest=%s\n", debugstr_w(szSrc), debugstr_w(szDest)); 00704 if (!memcmp(szSrc, szDest, (wcslen(szDest) + 1) * sizeof(WCHAR))) 00705 { 00706 /* src and destination is the same */ 00707 HRESULT hr = S_OK; 00708 if (pPidlOut) 00709 hr = _ILCreateFromPathW(szDest, pPidlOut); 00710 00711 return hr; 00712 } 00713 00714 00715 if (MoveFileW (szSrc, szDest)) 00716 { 00717 HRESULT hr = S_OK; 00718 00719 if (pPidlOut) 00720 hr = _ILCreateFromPathW(szDest, pPidlOut); 00721 00722 SHChangeNotify (bIsFolder ? SHCNE_RENAMEFOLDER : SHCNE_RENAMEITEM, 00723 SHCNF_PATHW, szSrc, szDest); 00724 00725 return hr; 00726 } 00727 00728 return E_FAIL; 00729 } 00730 00731 HRESULT WINAPI CFSFolder::GetDefaultSearchGUID(GUID * pguid) 00732 { 00733 FIXME ("(%p)\n", this); 00734 return E_NOTIMPL; 00735 } 00736 00737 HRESULT WINAPI CFSFolder::EnumSearches(IEnumExtraSearch ** ppenum) 00738 { 00739 FIXME ("(%p)\n", this); 00740 return E_NOTIMPL; 00741 } 00742 00743 HRESULT WINAPI CFSFolder::GetDefaultColumn(DWORD dwRes, 00744 ULONG * pSort, ULONG * pDisplay) 00745 { 00746 TRACE ("(%p)\n", this); 00747 00748 if (pSort) 00749 *pSort = 0; 00750 if (pDisplay) 00751 *pDisplay = 0; 00752 00753 return S_OK; 00754 } 00755 00756 HRESULT WINAPI CFSFolder::GetDefaultColumnState(UINT iColumn, 00757 DWORD * pcsFlags) 00758 { 00759 TRACE ("(%p)\n", this); 00760 00761 if (!pcsFlags || iColumn >= GENERICSHELLVIEWCOLUMNS) 00762 return E_INVALIDARG; 00763 00764 *pcsFlags = GenericSFHeader[iColumn].pcsFlags; 00765 00766 return S_OK; 00767 } 00768 00769 HRESULT WINAPI CFSFolder::GetDetailsEx(LPCITEMIDLIST pidl, 00770 const SHCOLUMNID * pscid, VARIANT * pv) 00771 { 00772 FIXME ("(%p)\n", this); 00773 00774 return E_NOTIMPL; 00775 } 00776 00777 HRESULT WINAPI CFSFolder::GetDetailsOf(LPCITEMIDLIST pidl, 00778 UINT iColumn, SHELLDETAILS * psd) 00779 { 00780 HRESULT hr = E_FAIL; 00781 00782 TRACE ("(%p)->(%p %i %p)\n", this, pidl, iColumn, psd); 00783 00784 if (!psd || iColumn >= GENERICSHELLVIEWCOLUMNS) 00785 return E_INVALIDARG; 00786 00787 if (!pidl) 00788 { 00789 /* the header titles */ 00790 psd->fmt = GenericSFHeader[iColumn].fmt; 00791 psd->cxChar = GenericSFHeader[iColumn].cxChar; 00792 psd->str.uType = STRRET_CSTR; 00793 LoadStringA(shell32_hInstance, GenericSFHeader[iColumn].colnameid, 00794 psd->str.cStr, MAX_PATH); 00795 return S_OK; 00796 } 00797 else 00798 { 00799 hr = S_OK; 00800 psd->str.uType = STRRET_CSTR; 00801 /* the data from the pidl */ 00802 switch (iColumn) 00803 { 00804 case 0: /* name */ 00805 hr = GetDisplayNameOf (pidl, 00806 SHGDN_NORMAL | SHGDN_INFOLDER, &psd->str); 00807 break; 00808 case 1: /* size */ 00809 _ILGetFileSize(pidl, psd->str.cStr, MAX_PATH); 00810 break; 00811 case 2: /* type */ 00812 _ILGetFileType(pidl, psd->str.cStr, MAX_PATH); 00813 break; 00814 case 3: /* date */ 00815 _ILGetFileDate(pidl, psd->str.cStr, MAX_PATH); 00816 break; 00817 case 4: /* attributes */ 00818 _ILGetFileAttributes(pidl, psd->str.cStr, MAX_PATH); 00819 break; 00820 } 00821 } 00822 00823 return hr; 00824 } 00825 00826 HRESULT WINAPI CFSFolder::MapColumnToSCID (UINT column, 00827 SHCOLUMNID * pscid) 00828 { 00829 FIXME ("(%p)\n", this); 00830 return E_NOTIMPL; 00831 } 00832 00833 /**************************************************************************** 00834 * ISFHelper for IShellFolder implementation 00835 */ 00836 00837 /**************************************************************************** 00838 * CFSFolder::GetUniqueName 00839 * 00840 * creates a unique folder name 00841 */ 00842 00843 HRESULT WINAPI CFSFolder::GetUniqueName(LPWSTR pwszName, UINT uLen) 00844 { 00845 IEnumIDList *penum; 00846 HRESULT hr; 00847 WCHAR wszText[MAX_PATH]; 00848 WCHAR wszNewFolder[25]; 00849 const WCHAR wszFormat[] = L"%s %d"; 00850 00851 LoadStringW(shell32_hInstance, IDS_NEWFOLDER, wszNewFolder, _countof(wszNewFolder)); 00852 00853 TRACE ("(%p)(%p %u)\n", this, pwszName, uLen); 00854 00855 if (uLen < _countof(wszNewFolder) + 3) 00856 return E_POINTER; 00857 00858 lstrcpynW (pwszName, wszNewFolder, uLen); 00859 00860 hr = EnumObjects(0, SHCONTF_FOLDERS | SHCONTF_NONFOLDERS | SHCONTF_INCLUDEHIDDEN, &penum); 00861 if (penum) 00862 { 00863 LPITEMIDLIST pidl; 00864 DWORD dwFetched; 00865 int i = 1; 00866 00867 next: 00868 penum->Reset (); 00869 while (S_OK == penum->Next(1, &pidl, &dwFetched) && dwFetched) 00870 { 00871 _ILSimpleGetTextW(pidl, wszText, MAX_PATH); 00872 if (0 == lstrcmpiW(wszText, pwszName)) 00873 { 00874 _snwprintf(pwszName, uLen, wszFormat, wszNewFolder, i++); 00875 if (i > 99) 00876 { 00877 hr = E_FAIL; 00878 break; 00879 } 00880 goto next; 00881 } 00882 } 00883 00884 penum->Release(); 00885 } 00886 return hr; 00887 } 00888 00889 /**************************************************************************** 00890 * CFSFolder::AddFolder 00891 * 00892 * adds a new folder. 00893 */ 00894 00895 HRESULT WINAPI CFSFolder::AddFolder(HWND hwnd, LPCWSTR pwszName, 00896 LPITEMIDLIST * ppidlOut) 00897 { 00898 WCHAR wszNewDir[MAX_PATH]; 00899 DWORD bRes; 00900 HRESULT hres = E_FAIL; 00901 00902 TRACE ("(%p)(%s %p)\n", this, debugstr_w(pwszName), ppidlOut); 00903 00904 wszNewDir[0] = 0; 00905 if (sPathTarget) 00906 lstrcpynW(wszNewDir, sPathTarget, MAX_PATH); 00907 PathAppendW(wszNewDir, pwszName); 00908 00909 bRes = CreateDirectoryW(wszNewDir, NULL); 00910 if (bRes) 00911 { 00912 SHChangeNotify(SHCNE_MKDIR, SHCNF_PATHW, wszNewDir, NULL); 00913 00914 hres = S_OK; 00915 00916 if (ppidlOut) 00917 hres = _ILCreateFromPathW(wszNewDir, ppidlOut); 00918 } 00919 else 00920 { 00921 WCHAR wszText[128 + MAX_PATH]; 00922 WCHAR wszTempText[128]; 00923 WCHAR wszCaption[256]; 00924 00925 /* Cannot Create folder because of permissions */ 00926 LoadStringW(shell32_hInstance, IDS_CREATEFOLDER_DENIED, wszTempText, 00927 _countof(wszTempText)); 00928 LoadStringW(shell32_hInstance, IDS_CREATEFOLDER_CAPTION, wszCaption, 00929 _countof(wszCaption)); 00930 swprintf(wszText, wszTempText, wszNewDir); 00931 MessageBoxW(hwnd, wszText, wszCaption, MB_OK | MB_ICONEXCLAMATION); 00932 } 00933 00934 return hres; 00935 } 00936 00937 /**************************************************************************** 00938 * BuildPathsList 00939 * 00940 * Builds a list of paths like the one used in SHFileOperation from a table of 00941 * PIDLs relative to the given base folder 00942 */ 00943 WCHAR * 00944 BuildPathsList(LPCWSTR wszBasePath, int cidl, LPCITEMIDLIST *pidls) 00945 { 00946 WCHAR *pwszPathsList; 00947 WCHAR *pwszListPos; 00948 int iPathLen, i; 00949 00950 iPathLen = wcslen(wszBasePath); 00951 pwszPathsList = (WCHAR *)HeapAlloc(GetProcessHeap(), 0, MAX_PATH * sizeof(WCHAR) * cidl + 1); 00952 pwszListPos = pwszPathsList; 00953 00954 for (i = 0; i < cidl; i++) 00955 { 00956 if (!_ILIsFolder(pidls[i]) && !_ILIsValue(pidls[i])) 00957 continue; 00958 00959 wcscpy(pwszListPos, wszBasePath); 00960 pwszListPos += iPathLen; 00961 /* FIXME: abort if path too long */ 00962 _ILSimpleGetTextW(pidls[i], pwszListPos, MAX_PATH - iPathLen); 00963 pwszListPos += wcslen(pwszListPos) + 1; 00964 } 00965 *pwszListPos = 0; 00966 return pwszPathsList; 00967 } 00968 00969 /**************************************************************************** 00970 * CFSFolder::DeleteItems 00971 * 00972 * deletes items in folder 00973 */ 00974 HRESULT WINAPI CFSFolder::DeleteItems(UINT cidl, LPCITEMIDLIST *apidl) 00975 { 00976 UINT i; 00977 SHFILEOPSTRUCTW op; 00978 WCHAR wszPath[MAX_PATH]; 00979 WCHAR *wszPathsList; 00980 HRESULT ret; 00981 WCHAR *wszCurrentPath; 00982 00983 TRACE ("(%p)(%u %p)\n", this, cidl, apidl); 00984 if (cidl == 0) return S_OK; 00985 00986 if (sPathTarget) 00987 lstrcpynW(wszPath, sPathTarget, MAX_PATH); 00988 else 00989 wszPath[0] = '\0'; 00990 PathAddBackslashW(wszPath); 00991 wszPathsList = BuildPathsList(wszPath, cidl, apidl); 00992 00993 ZeroMemory(&op, sizeof(op)); 00994 op.hwnd = GetActiveWindow(); 00995 op.wFunc = FO_DELETE; 00996 op.pFrom = wszPathsList; 00997 op.fFlags = FOF_ALLOWUNDO; 00998 if (SHFileOperationW(&op)) 00999 { 01000 WARN("SHFileOperation failed\n"); 01001 ret = E_FAIL; 01002 } 01003 else 01004 ret = S_OK; 01005 01006 /* we currently need to manually send the notifies */ 01007 wszCurrentPath = wszPathsList; 01008 for (i = 0; i < cidl; i++) 01009 { 01010 LONG wEventId; 01011 01012 if (_ILIsFolder(apidl[i])) 01013 wEventId = SHCNE_RMDIR; 01014 else if (_ILIsValue(apidl[i])) 01015 wEventId = SHCNE_DELETE; 01016 else 01017 continue; 01018 01019 /* check if file exists */ 01020 if (GetFileAttributesW(wszCurrentPath) == INVALID_FILE_ATTRIBUTES) 01021 { 01022 LPITEMIDLIST pidl = ILCombine(pidlRoot, apidl[i]); 01023 SHChangeNotify(wEventId, SHCNF_IDLIST, pidl, NULL); 01024 SHFree(pidl); 01025 } 01026 01027 wszCurrentPath += wcslen(wszCurrentPath) + 1; 01028 } 01029 HeapFree(GetProcessHeap(), 0, wszPathsList); 01030 return ret; 01031 } 01032 01033 /**************************************************************************** 01034 * CFSFolder::CopyItems 01035 * 01036 * copies items to this folder 01037 */ 01038 HRESULT WINAPI CFSFolder::CopyItems(IShellFolder * pSFFrom, UINT cidl, 01039 LPCITEMIDLIST * apidl) 01040 { 01041 IPersistFolder2 *ppf2 = NULL; 01042 WCHAR szSrcPath[MAX_PATH]; 01043 WCHAR szTargetPath[MAX_PATH]; 01044 SHFILEOPSTRUCTW op; 01045 LPITEMIDLIST pidl; 01046 LPWSTR pszSrc, pszTarget, pszSrcList, pszTargetList, pszFileName; 01047 int res, length; 01048 HRESULT hr; 01049 STRRET strRet; 01050 01051 TRACE ("(%p)->(%p,%u,%p)\n", this, pSFFrom, cidl, apidl); 01052 01053 hr = pSFFrom->QueryInterface (IID_IPersistFolder2, (LPVOID *) & ppf2); 01054 if (SUCCEEDED(hr)) 01055 { 01056 hr = ppf2->GetCurFolder(&pidl); 01057 if (FAILED(hr)) 01058 { 01059 ppf2->Release(); 01060 return hr; 01061 } 01062 ppf2->Release(); 01063 01064 hr = pSFFrom->GetDisplayNameOf(pidl, SHGDN_FORPARSING, &strRet); 01065 if (FAILED(hr)) 01066 { 01067 SHFree(pidl); 01068 return hr; 01069 } 01070 01071 hr = StrRetToBufW(&strRet, pidl, szSrcPath, MAX_PATH); 01072 if (FAILED(hr)) 01073 { 01074 SHFree(pidl); 01075 return hr; 01076 } 01077 SHFree(pidl); 01078 01079 pszSrc = PathAddBackslashW(szSrcPath); 01080 01081 wcscpy(szTargetPath, sPathTarget); 01082 pszTarget = PathAddBackslashW(szTargetPath); 01083 01084 pszSrcList = BuildPathsList(szSrcPath, cidl, apidl); 01085 pszTargetList = BuildPathsList(szTargetPath, cidl, apidl); 01086 01087 if (!pszSrcList || !pszTargetList) 01088 { 01089 if (pszSrcList) 01090 HeapFree(GetProcessHeap(), 0, pszSrcList); 01091 01092 if (pszTargetList) 01093 HeapFree(GetProcessHeap(), 0, pszTargetList); 01094 01095 SHFree(pidl); 01096 ppf2->Release(); 01097 return E_OUTOFMEMORY; 01098 } 01099 01100 ZeroMemory(&op, sizeof(op)); 01101 if (!pszSrcList[0]) 01102 { 01103 /* remove trailing backslash */ 01104 pszSrc--; 01105 pszSrc[0] = L'\0'; 01106 op.pFrom = szSrcPath; 01107 } 01108 else 01109 { 01110 op.pFrom = pszSrcList; 01111 } 01112 01113 if (!pszTargetList[0]) 01114 { 01115 /* remove trailing backslash */ 01116 if (pszTarget - szTargetPath > 3) 01117 { 01118 pszTarget--; 01119 pszTarget[0] = L'\0'; 01120 } 01121 else 01122 { 01123 pszTarget[1] = L'\0'; 01124 } 01125 01126 op.pTo = szTargetPath; 01127 } 01128 else 01129 { 01130 op.pTo = pszTargetList; 01131 } 01132 op.hwnd = GetActiveWindow(); 01133 op.wFunc = FO_COPY; 01134 op.fFlags = FOF_ALLOWUNDO | FOF_NOCONFIRMMKDIR; 01135 01136 res = SHFileOperationW(&op); 01137 01138 if (res == DE_SAMEFILE) 01139 { 01140 length = wcslen(szTargetPath); 01141 01142 pszFileName = wcsrchr(pszSrcList, '\\'); 01143 pszFileName++; 01144 01145 if (LoadStringW(shell32_hInstance, IDS_COPY_OF, pszTarget, MAX_PATH - length)) 01146 { 01147 wcscat(szTargetPath, L" "); 01148 } 01149 01150 wcscat(szTargetPath, pszFileName); 01151 op.pTo = szTargetPath; 01152 01153 res = SHFileOperationW(&op); 01154 } 01155 01156 HeapFree(GetProcessHeap(), 0, pszSrcList); 01157 HeapFree(GetProcessHeap(), 0, pszTargetList); 01158 01159 if (res) 01160 return E_FAIL; 01161 else 01162 return S_OK; 01163 } 01164 return E_FAIL; 01165 } 01166 01167 /************************************************************************ 01168 * CFSFolder::GetClassID 01169 */ 01170 HRESULT WINAPI CFSFolder::GetClassID(CLSID * lpClassId) 01171 { 01172 TRACE ("(%p)\n", this); 01173 01174 if (!lpClassId) 01175 return E_POINTER; 01176 01177 *lpClassId = *pclsid; 01178 01179 return S_OK; 01180 } 01181 01182 /************************************************************************ 01183 * CFSFolder::Initialize 01184 * 01185 * NOTES 01186 * sPathTarget is not set. Don't know how to handle in a non rooted environment. 01187 */ 01188 HRESULT WINAPI CFSFolder::Initialize(LPCITEMIDLIST pidl) 01189 { 01190 WCHAR wszTemp[MAX_PATH]; 01191 01192 TRACE ("(%p)->(%p)\n", this, pidl); 01193 01194 SHFree (pidlRoot); /* free the old pidl */ 01195 pidlRoot = ILClone (pidl); /* set my pidl */ 01196 01197 SHFree (sPathTarget); 01198 sPathTarget = NULL; 01199 01200 /* set my path */ 01201 if (SHGetPathFromIDListW (pidl, wszTemp)) 01202 { 01203 int len = wcslen(wszTemp); 01204 sPathTarget = (WCHAR *)SHAlloc((len + 1) * sizeof(WCHAR)); 01205 if (!sPathTarget) 01206 return E_OUTOFMEMORY; 01207 memcpy(sPathTarget, wszTemp, (len + 1) * sizeof(WCHAR)); 01208 } 01209 01210 TRACE ("--(%p)->(%s)\n", this, debugstr_w(sPathTarget)); 01211 return S_OK; 01212 } 01213 01214 /************************************************************************** 01215 * CFSFolder::GetCurFolder 01216 */ 01217 HRESULT WINAPI CFSFolder::GetCurFolder(LPITEMIDLIST * pidl) 01218 { 01219 TRACE ("(%p)->(%p)\n", this, pidl); 01220 01221 if (!pidl) 01222 return E_POINTER; 01223 01224 *pidl = ILClone(pidlRoot); 01225 return S_OK; 01226 } 01227 01228 /************************************************************************** 01229 * CFSFolder::InitializeEx 01230 * 01231 * FIXME: error handling 01232 */ 01233 HRESULT WINAPI CFSFolder::InitializeEx(IBindCtx * pbc, LPCITEMIDLIST pidlRootx, 01234 const PERSIST_FOLDER_TARGET_INFO * ppfti) 01235 { 01236 WCHAR wszTemp[MAX_PATH]; 01237 01238 TRACE("(%p)->(%p,%p,%p)\n", this, pbc, pidlRootx, ppfti); 01239 if (ppfti) 01240 TRACE("--%p %s %s 0x%08x 0x%08x\n", 01241 ppfti->pidlTargetFolder, debugstr_w (ppfti->szTargetParsingName), 01242 debugstr_w (ppfti->szNetworkProvider), ppfti->dwAttributes, 01243 ppfti->csidl); 01244 01245 pdump (pidlRootx); 01246 if (ppfti && ppfti->pidlTargetFolder) 01247 pdump(ppfti->pidlTargetFolder); 01248 01249 if (pidlRoot) 01250 __SHFreeAndNil(&pidlRoot); /* free the old */ 01251 if (sPathTarget) 01252 __SHFreeAndNil(&sPathTarget); 01253 01254 /* 01255 * Root path and pidl 01256 */ 01257 pidlRoot = ILClone(pidlRootx); 01258 01259 /* 01260 * the target folder is spezified in csidl OR pidlTargetFolder OR 01261 * szTargetParsingName 01262 */ 01263 if (ppfti) 01264 { 01265 if (ppfti->csidl != -1) 01266 { 01267 if (SHGetSpecialFolderPathW(0, wszTemp, ppfti->csidl, 01268 ppfti->csidl & CSIDL_FLAG_CREATE)) { 01269 int len = wcslen(wszTemp); 01270 sPathTarget = (WCHAR *)SHAlloc((len + 1) * sizeof(WCHAR)); 01271 if (!sPathTarget) 01272 return E_OUTOFMEMORY; 01273 memcpy(sPathTarget, wszTemp, (len + 1) * sizeof(WCHAR)); 01274 } 01275 } 01276 else if (ppfti->szTargetParsingName[0]) 01277 { 01278 int len = wcslen(ppfti->szTargetParsingName); 01279 sPathTarget = (WCHAR *)SHAlloc((len + 1) * sizeof(WCHAR)); 01280 if (!sPathTarget) 01281 return E_OUTOFMEMORY; 01282 memcpy(sPathTarget, ppfti->szTargetParsingName, 01283 (len + 1) * sizeof(WCHAR)); 01284 } 01285 else if (ppfti->pidlTargetFolder) 01286 { 01287 if (SHGetPathFromIDListW(ppfti->pidlTargetFolder, wszTemp)) 01288 { 01289 int len = wcslen(wszTemp); 01290 sPathTarget = (WCHAR *)SHAlloc((len + 1) * sizeof(WCHAR)); 01291 if (!sPathTarget) 01292 return E_OUTOFMEMORY; 01293 memcpy(sPathTarget, wszTemp, (len + 1) * sizeof(WCHAR)); 01294 } 01295 } 01296 } 01297 01298 TRACE("--(%p)->(target=%s)\n", this, debugstr_w(sPathTarget)); 01299 pdump(pidlRoot); 01300 return (sPathTarget) ? S_OK : E_FAIL; 01301 } 01302 01303 HRESULT WINAPI CFSFolder::GetFolderTargetInfo(PERSIST_FOLDER_TARGET_INFO * ppfti) 01304 { 01305 FIXME("(%p)->(%p)\n", this, ppfti); 01306 ZeroMemory(ppfti, sizeof (*ppfti)); 01307 return E_NOTIMPL; 01308 } 01309 01310 /**************************************************************************** 01311 * ISFDropTarget implementation 01312 */ 01313 BOOL CFSFolder::QueryDrop(DWORD dwKeyState, LPDWORD pdwEffect) 01314 { 01315 DWORD dwEffect = *pdwEffect; 01316 01317 *pdwEffect = DROPEFFECT_NONE; 01318 01319 if (fAcceptFmt) { /* Does our interpretation of the keystate ... */ 01320 *pdwEffect = KeyStateToDropEffect (dwKeyState); 01321 01322 /* ... matches the desired effect ? */ 01323 if (dwEffect & *pdwEffect) { 01324 return TRUE; 01325 } 01326 } 01327 return FALSE; 01328 } 01329 01330 HRESULT WINAPI CFSFolder::DragEnter(IDataObject *pDataObject, 01331 DWORD dwKeyState, POINTL pt, DWORD *pdwEffect) 01332 { 01333 FORMATETC fmt; 01334 01335 TRACE("(%p)->(DataObject=%p)\n", this, pDataObject); 01336 01337 InitFormatEtc (fmt, cfShellIDList, TYMED_HGLOBAL); 01338 01339 fAcceptFmt = (S_OK == pDataObject->QueryGetData(&fmt)) ? 01340 TRUE : FALSE; 01341 01342 QueryDrop(dwKeyState, pdwEffect); 01343 01344 return S_OK; 01345 } 01346 01347 HRESULT WINAPI CFSFolder::DragOver(DWORD dwKeyState, POINTL pt, 01348 DWORD *pdwEffect) 01349 { 01350 TRACE("(%p)\n", this); 01351 01352 if (!pdwEffect) 01353 return E_INVALIDARG; 01354 01355 QueryDrop(dwKeyState, pdwEffect); 01356 01357 return S_OK; 01358 } 01359 01360 HRESULT WINAPI CFSFolder::DragLeave() 01361 { 01362 TRACE("(%p)\n", this); 01363 01364 fAcceptFmt = FALSE; 01365 01366 return S_OK; 01367 } 01368 01369 HRESULT WINAPI CFSFolder::Drop(IDataObject *pDataObject, 01370 DWORD dwKeyState, POINTL pt, DWORD *pdwEffect) 01371 { 01372 FIXME("(%p) object dropped\n", this); 01373 01374 return E_NOTIMPL; 01375 } Generated on Sat May 26 2012 04:24:58 for ReactOS by
1.7.6.1
|