ReactOS Fundraising Campaign 2012
 
€ 4,410 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

fs.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, &param);
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 doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.