/************************************************************************** * RenderHDROP * * creates a CF_HDROP structure */ HGLOBAL RenderHDROP(LPITEMIDLIST pidlRoot, LPITEMIDLIST * apidl, UINT cidl) { UINT i; int rootlen = 0,size = 0; WCHAR wszRootPath[MAX_PATH]; WCHAR wszFileName[MAX_PATH]; HGLOBAL hGlobal; DROPFILES *pDropFiles; int offset; TRACE("(%p,%p,%u)\n", pidlRoot, apidl, cidl); /* get the size needed */ size = sizeof(DROPFILES); SHGetPathFromIDListW(pidlRoot, wszRootPath); PathAddBackslashW(wszRootPath); rootlen = strlenW(wszRootPath); for (i=0; i<cidl;i++) { _ILSimpleGetTextW(apidl[i], wszFileName, MAX_PATH); size += (rootlen + strlenW(wszFileName) + 1) * sizeof(WCHAR); } size += sizeof(WCHAR); /* Fill the structure */ hGlobal = GlobalAlloc(GHND|GMEM_SHARE, size); if(!hGlobal) return hGlobal; pDropFiles = (DROPFILES *)GlobalLock(hGlobal); offset = (sizeof(DROPFILES) + sizeof(WCHAR) - 1) / sizeof(WCHAR); pDropFiles->pFiles = offset * sizeof(WCHAR); pDropFiles->fWide = TRUE; strcpyW(wszFileName, wszRootPath); for (i=0; i<cidl;i++) { _ILSimpleGetTextW(apidl[i], wszFileName + rootlen, MAX_PATH - rootlen); strcpyW(((WCHAR*)pDropFiles)+offset, wszFileName); offset += strlenW(wszFileName) + 1; } ((WCHAR*)pDropFiles)[offset] = 0; GlobalUnlock(hGlobal); return hGlobal; }
/*********************************************************************** * SHELL32_CoCreateInitSF * * Creates a shell folder and initializes it with a pidl and a root folder * via IPersistFolder3 or IPersistFolder. * * NOTES * pathRoot can be NULL for Folders being a drive. * In this case the absolute path is built from pidlChild (eg. C:) */ static HRESULT SHELL32_CoCreateInitSF (LPCITEMIDLIST pidlRoot, LPCWSTR pathRoot, LPCITEMIDLIST pidlChild, REFCLSID clsid, IShellFolder** ppsfOut) { HRESULT hr; CComPtr<IShellFolder> pShellFolder; TRACE ("%p %s %p\n", pidlRoot, debugstr_w(pathRoot), pidlChild); hr = SHCoCreateInstance(NULL, &clsid, NULL, IID_PPV_ARG(IShellFolder, &pShellFolder)); if (SUCCEEDED (hr)) { LPITEMIDLIST pidlAbsolute = ILCombine (pidlRoot, pidlChild); CComPtr<IPersistFolder> ppf; CComPtr<IPersistFolder3> ppf3; if (SUCCEEDED(pShellFolder->QueryInterface(IID_PPV_ARG(IPersistFolder3, &ppf3)))) { PERSIST_FOLDER_TARGET_INFO ppfti; ZeroMemory (&ppfti, sizeof (ppfti)); /* fill the PERSIST_FOLDER_TARGET_INFO */ ppfti.dwAttributes = -1; ppfti.csidl = -1; /* build path */ if (pathRoot) { lstrcpynW (ppfti.szTargetParsingName, pathRoot, MAX_PATH - 1); PathAddBackslashW(ppfti.szTargetParsingName); /* FIXME: why have drives a backslash here ? */ } if (pidlChild) { int len = wcslen(ppfti.szTargetParsingName); if (!_ILSimpleGetTextW(pidlChild, ppfti.szTargetParsingName + len, MAX_PATH - len)) hr = E_INVALIDARG; } ppf3->InitializeEx(NULL, pidlAbsolute, &ppfti); } else if (SUCCEEDED((hr = pShellFolder->QueryInterface(IID_PPV_ARG(IPersistFolder, &ppf))))) { ppf->Initialize(pidlAbsolute); } ILFree (pidlAbsolute); } *ppsfOut = pShellFolder.Detach(); TRACE ("-- (%p) ret=0x%08x\n", *ppsfOut, hr); return hr; }
/************************************************************************** * ISF_ControlPanel_fnGetDisplayNameOf */ static HRESULT WINAPI ISF_ControlPanel_fnGetDisplayNameOf(IShellFolder2 * iface, LPCITEMIDLIST pidl, DWORD dwFlags, LPSTRRET strRet) { ICPanelImpl *This = (ICPanelImpl *)iface; CHAR szPath[MAX_PATH]; WCHAR wszPath[MAX_PATH+1]; /* +1 for potential backslash */ PIDLCPanelStruct* pcpanel; *szPath = '\0'; TRACE("(%p)->(pidl=%p,0x%08lx,%p)\n", This, pidl, dwFlags, strRet); pdump(pidl); if (!pidl || !strRet) return E_INVALIDARG; pcpanel = _ILGetCPanelPointer(pidl); if (pcpanel) { lstrcpyA(szPath, pcpanel->szName+pcpanel->offsDispName); if (!(dwFlags & SHGDN_FORPARSING)) FIXME("retrieve display name from control panel app\n"); } /* take names of special folders only if its only this folder */ else if (_ILIsSpecialFolder(pidl)) { BOOL bSimplePidl = _ILIsPidlSimple(pidl); if (bSimplePidl) { _ILSimpleGetTextW(pidl, wszPath, MAX_PATH); /* append my own path */ } else { FIXME("special pidl\n"); } if ((dwFlags & SHGDN_FORPARSING) && !bSimplePidl) { /* go deeper if needed */ int len = 0; PathAddBackslashW(wszPath); len = lstrlenW(wszPath); if (!SUCCEEDED (SHELL32_GetDisplayNameOfChild(iface, pidl, dwFlags | SHGDN_INFOLDER, wszPath + len, MAX_PATH + 1 - len))) return E_OUTOFMEMORY; if (!WideCharToMultiByte(CP_ACP, 0, wszPath, -1, szPath, MAX_PATH, NULL, NULL)) wszPath[0] = '\0'; } } strRet->uType = STRRET_CSTR; lstrcpynA(strRet->u.cStr, szPath, MAX_PATH); TRACE("--(%p)->(%s)\n", This, szPath); return S_OK; }
/*********************************************************************** * SHELL32_CoCreateInitSF * * Creates a shell folder and initializes it with a pidl and a root folder * via IPersistFolder3 or IPersistFolder. * * NOTES * pathRoot can be NULL for Folders being a drive. * In this case the absolute path is built from pidlChild (eg. C:) */ static HRESULT SHELL32_CoCreateInitSF (LPCITEMIDLIST pidlRoot, LPCWSTR pathRoot, LPCITEMIDLIST pidlChild, REFCLSID clsid, LPVOID * ppvOut) { HRESULT hr; TRACE ("(%p %s %p %s %p)\n", pidlRoot, debugstr_w(pathRoot), pidlChild, debugstr_guid(clsid), ppvOut); hr = SHCoCreateInstance(NULL, clsid, NULL, &IID_IShellFolder, ppvOut); if (SUCCEEDED (hr)) { LPITEMIDLIST pidlAbsolute = ILCombine (pidlRoot, pidlChild); IPersistFolder *pPF; IPersistFolder3 *ppf; if (_ILIsFolder(pidlChild) && SUCCEEDED (IUnknown_QueryInterface ((IUnknown *) * ppvOut, &IID_IPersistFolder3, (LPVOID *) & ppf))) { PERSIST_FOLDER_TARGET_INFO ppfti; ZeroMemory (&ppfti, sizeof (ppfti)); /* fill the PERSIST_FOLDER_TARGET_INFO */ ppfti.dwAttributes = -1; ppfti.csidl = -1; /* build path */ if (pathRoot) { lstrcpynW (ppfti.szTargetParsingName, pathRoot, MAX_PATH - 1); PathAddBackslashW(ppfti.szTargetParsingName); /* FIXME: why have drives a backslash here ? */ } if (pidlChild) { int len = lstrlenW(ppfti.szTargetParsingName); if (!_ILSimpleGetTextW(pidlChild, ppfti.szTargetParsingName + len, MAX_PATH - len)) hr = E_INVALIDARG; } IPersistFolder3_InitializeEx (ppf, NULL, pidlAbsolute, &ppfti); IPersistFolder3_Release (ppf); } else if (SUCCEEDED ((hr = IUnknown_QueryInterface ((IUnknown *) * ppvOut, &IID_IPersistFolder, (LPVOID *) & pPF)))) { IPersistFolder_Initialize (pPF, pidlAbsolute); IPersistFolder_Release (pPF); } ILFree (pidlAbsolute); } TRACE ("-- (%p) ret=0x%08x\n", *ppvOut, hr); return hr; }
static HRESULT WINAPI ISF_Desktop_ISFHelper_fnGetUniqueName (ISFHelper * iface, LPWSTR pwszName, UINT uLen) { IGenericSFImpl *This = impl_from_ISFHelper(iface); IEnumIDList *penum; HRESULT hr; WCHAR wszText[MAX_PATH]; WCHAR wszNewFolder[25]; const WCHAR wszFormat[] = {'%','s',' ','%','d',0 }; LoadStringW(shell32_hInstance, IDS_NEWFOLDER, wszNewFolder, sizeof(wszNewFolder)/sizeof(WCHAR)); TRACE ("(%p)(%p %u)\n", This, pwszName, uLen); if (uLen < sizeof(wszNewFolder)/sizeof(WCHAR) + 3) return E_POINTER; lstrcpynW (pwszName, wszNewFolder, uLen); hr = IShellFolder_EnumObjects ((IShellFolder2*)This, 0, SHCONTF_FOLDERS | SHCONTF_NONFOLDERS | SHCONTF_INCLUDEHIDDEN, &penum); if (penum) { LPITEMIDLIST pidl; DWORD dwFetched; int i = 1; next: IEnumIDList_Reset (penum); while (S_OK == IEnumIDList_Next (penum, 1, &pidl, &dwFetched) && dwFetched) { _ILSimpleGetTextW (pidl, wszText, MAX_PATH); if (0 == lstrcmpiW (wszText, pwszName)) { _snwprintf (pwszName, uLen, wszFormat, wszNewFolder, i++); if (i > 99) { hr = E_FAIL; break; } goto next; } } IEnumIDList_Release (penum); } return hr; }
HRESULT CDesktopFolder::_GetSFFromPidl(LPCITEMIDLIST pidl, IShellFolder2** psf) { WCHAR szFileName[MAX_PATH]; lstrcpynW(szFileName, sPathTarget, MAX_PATH - 1); PathAddBackslashW(szFileName); int cLen = wcslen(szFileName); if (!_ILSimpleGetTextW(pidl, szFileName + cLen, MAX_PATH - cLen)) return E_FAIL; ERR("%S\n", szFileName); if (GetFileAttributes(szFileName) == INVALID_FILE_ATTRIBUTES) return m_SharedDesktopFSFolder->QueryInterface(IID_PPV_ARG(IShellFolder2, psf)); else return m_DesktopFSFolder->QueryInterface(IID_PPV_ARG(IShellFolder2, psf)); }
void SHELL32_GetCLSIDForDirectory(LPCWSTR pathRoot, LPCITEMIDLIST pidl, CLSID* pclsidFolder) { static const WCHAR wszDotShellClassInfo[] = { '.','S','h','e','l','l','C','l','a','s','s','I','n','f','o',0 }; static const WCHAR wszCLSID[] = {'C','L','S','I','D',0}; WCHAR wszCLSIDValue[CHARS_IN_GUID], wszFolderPath[MAX_PATH], *pwszPathTail = wszFolderPath; /* see if folder CLSID should be overridden by desktop.ini file */ if (pathRoot) { lstrcpynW(wszFolderPath, pathRoot, MAX_PATH); pwszPathTail = PathAddBackslashW(wszFolderPath); } _ILSimpleGetTextW(pidl,pwszPathTail,MAX_PATH - (int)(pwszPathTail - wszFolderPath)); if (SHELL32_GetCustomFolderAttributeFromPath (wszFolderPath, wszDotShellClassInfo, wszCLSID, wszCLSIDValue, CHARS_IN_GUID)) CLSIDFromString (wszCLSIDValue, pclsidFolder); }
/************************************************************************** * ISF_Desktop_fnGetDisplayNameOf * * NOTES * special case: pidl = null gives desktop-name back */ static HRESULT WINAPI ISF_Desktop_fnGetDisplayNameOf (IShellFolder2 * iface, LPCITEMIDLIST pidl, DWORD dwFlags, LPSTRRET strRet) { IDesktopFolderImpl *This = impl_from_IShellFolder2(iface); HRESULT hr = S_OK; LPWSTR pszPath; TRACE ("(%p)->(pidl=%p,0x%08x,%p)\n", This, pidl, dwFlags, strRet); pdump (pidl); if (!strRet) return E_INVALIDARG; pszPath = CoTaskMemAlloc((MAX_PATH +1) * sizeof(WCHAR)); if (!pszPath) return E_OUTOFMEMORY; if (_ILIsDesktop (pidl)) { if ((GET_SHGDN_RELATION (dwFlags) == SHGDN_NORMAL) && (GET_SHGDN_FOR (dwFlags) & SHGDN_FORPARSING)) strcpyW(pszPath, This->sPathTarget); else HCR_GetClassNameW(&CLSID_ShellDesktop, pszPath, MAX_PATH); } else if (_ILIsPidlSimple (pidl)) { GUID const *clsid; if ((clsid = _ILGetGUIDPointer (pidl))) { if (GET_SHGDN_FOR (dwFlags) & SHGDN_FORPARSING) { int bWantsForParsing; /* * We can only get a filesystem path from a shellfolder if the * value WantsFORPARSING in CLSID\\{...}\\shellfolder exists. * * Exception: The MyComputer folder doesn't have this key, * but any other filesystem backed folder it needs it. */ if (IsEqualIID (clsid, &CLSID_MyComputer)) { bWantsForParsing = TRUE; } else { /* get the "WantsFORPARSING" flag from the registry */ static const WCHAR clsidW[] = { 'C','L','S','I','D','\\',0 }; static const WCHAR shellfolderW[] = { '\\','s','h','e','l','l','f','o','l','d','e','r',0 }; static const WCHAR wantsForParsingW[] = { 'W','a','n','t','s','F','o','r','P','a','r','s','i','n', 'g',0 }; WCHAR szRegPath[100]; LONG r; lstrcpyW (szRegPath, clsidW); SHELL32_GUIDToStringW (clsid, &szRegPath[6]); lstrcatW (szRegPath, shellfolderW); r = SHGetValueW(HKEY_CLASSES_ROOT, szRegPath, wantsForParsingW, NULL, NULL, NULL); if (r == ERROR_SUCCESS) bWantsForParsing = TRUE; else bWantsForParsing = FALSE; } if ((GET_SHGDN_RELATION (dwFlags) == SHGDN_NORMAL) && bWantsForParsing) { /* * we need the filesystem path to the destination folder. * Only the folder itself can know it */ hr = SHELL32_GetDisplayNameOfChild (iface, pidl, dwFlags, pszPath, MAX_PATH); } else { /* parsing name like ::{...} */ pszPath[0] = ':'; pszPath[1] = ':'; SHELL32_GUIDToStringW (clsid, &pszPath[2]); } } else { /* user friendly name */ HCR_GetClassNameW (clsid, pszPath, MAX_PATH); } } else { int cLen = 0; /* file system folder or file rooted at the desktop */ if ((GET_SHGDN_FOR(dwFlags) == SHGDN_FORPARSING) && (GET_SHGDN_RELATION(dwFlags) != SHGDN_INFOLDER)) { lstrcpynW(pszPath, This->sPathTarget, MAX_PATH - 1); PathAddBackslashW(pszPath); cLen = lstrlenW(pszPath); } _ILSimpleGetTextW(pidl, pszPath + cLen, MAX_PATH - cLen); if (!_ILIsFolder(pidl)) SHELL_FS_ProcessDisplayFilename(pszPath, dwFlags); } } else { /* a complex pidl, let the subfolder do the work */ hr = SHELL32_GetDisplayNameOfChild (iface, pidl, dwFlags, pszPath, MAX_PATH); } if (SUCCEEDED(hr)) { /* Win9x always returns ANSI strings, NT always returns Unicode strings */ if (GetVersion() & 0x80000000) { strRet->uType = STRRET_CSTR; if (!WideCharToMultiByte(CP_ACP, 0, pszPath, -1, strRet->u.cStr, MAX_PATH, NULL, NULL)) strRet->u.cStr[0] = '\0'; CoTaskMemFree(pszPath); } else { strRet->uType = STRRET_WSTR; strRet->u.pOleStr = pszPath; } } else CoTaskMemFree(pszPath); TRACE ("-- (%p)->(%s,0x%08x)\n", This, strRet->uType == STRRET_CSTR ? strRet->u.cStr : debugstr_w(strRet->u.pOleStr), hr); return hr; }
/************************************************************************** * DoOpenProperties */ static void DoOpenProperties(ItemCmImpl *This, HWND hwnd) { static const UINT MAX_PROP_PAGES = 99; static const WCHAR wszFolder[] = {'F','o','l','d','e','r', 0}; static const WCHAR wszFiletypeAll[] = {'*',0}; LPSHELLFOLDER lpDesktopSF; LPSHELLFOLDER lpSF; LPDATAOBJECT lpDo; WCHAR wszFiletype[MAX_PATH]; WCHAR wszFilename[MAX_PATH]; PROPSHEETHEADERW psh; HPROPSHEETPAGE hpages[MAX_PROP_PAGES]; HPSXA hpsxa; UINT ret; TRACE("(%p)->(wnd=%p)\n", This, hwnd); ZeroMemory(&psh, sizeof(PROPSHEETHEADERW)); psh.dwSize = sizeof (PROPSHEETHEADERW); psh.hwndParent = hwnd; psh.dwFlags = PSH_PROPTITLE; psh.nPages = 0; psh.u3.phpage = hpages; psh.u2.nStartPage = 0; _ILSimpleGetTextW(This->apidl[0], (LPVOID)&wszFilename, MAX_PATH); psh.pszCaption = (LPCWSTR)&wszFilename; /* Find out where to look for the shell extensions */ if (_ILIsValue(This->apidl[0])) { char sTemp[64]; sTemp[0] = 0; if (_ILGetExtension(This->apidl[0], sTemp, 64)) { HCR_MapTypeToValueA(sTemp, sTemp, 64, TRUE); MultiByteToWideChar(CP_ACP, 0, sTemp, -1, wszFiletype, MAX_PATH); } else { wszFiletype[0] = 0; } } else if (_ILIsFolder(This->apidl[0])) { lstrcpynW(wszFiletype, wszFolder, 64); } else if (_ILIsSpecialFolder(This->apidl[0])) { LPGUID folderGUID; static const WCHAR wszclsid[] = {'C','L','S','I','D','\\', 0}; folderGUID = _ILGetGUIDPointer(This->apidl[0]); lstrcpyW(wszFiletype, wszclsid); StringFromGUID2(folderGUID, &wszFiletype[6], MAX_PATH - 6); } else { FIXME("Requested properties for unknown type.\n"); return; } /* Get a suitable DataObject for accessing the files */ SHGetDesktopFolder(&lpDesktopSF); if (_ILIsPidlSimple(This->pidl)) { ret = IShellFolder_GetUIObjectOf(lpDesktopSF, hwnd, This->cidl, (LPCITEMIDLIST*)This->apidl, &IID_IDataObject, NULL, (LPVOID *)&lpDo); IShellFolder_Release(lpDesktopSF); } else { IShellFolder_BindToObject(lpDesktopSF, This->pidl, NULL, &IID_IShellFolder, (LPVOID*) &lpSF); ret = IShellFolder_GetUIObjectOf(lpSF, hwnd, This->cidl, (LPCITEMIDLIST*)This->apidl, &IID_IDataObject, NULL, (LPVOID *)&lpDo); IShellFolder_Release(lpSF); IShellFolder_Release(lpDesktopSF); } if (SUCCEEDED(ret)) { hpsxa = SHCreatePropSheetExtArrayEx(HKEY_CLASSES_ROOT, wszFiletype, MAX_PROP_PAGES - psh.nPages, lpDo); if (hpsxa != NULL) { SHAddFromPropSheetExtArray(hpsxa, Properties_AddPropSheetCallback, (LPARAM)&psh); SHDestroyPropSheetExtArray(hpsxa); } hpsxa = SHCreatePropSheetExtArrayEx(HKEY_CLASSES_ROOT, wszFiletypeAll, MAX_PROP_PAGES - psh.nPages, lpDo); if (hpsxa != NULL) { SHAddFromPropSheetExtArray(hpsxa, Properties_AddPropSheetCallback, (LPARAM)&psh); SHDestroyPropSheetExtArray(hpsxa); } IDataObject_Release(lpDo); } if (psh.nPages) PropertySheetW(&psh); else FIXME("No property pages found.\n"); }
/*********************************************************************** * SHELL32_BindToChild [Internal] * * Common code for IShellFolder_BindToObject. * * PARAMS * pidlRoot [I] The parent shell folder's absolute pidl. * pathRoot [I] Absolute dos path of the parent shell folder. * pidlComplete [I] PIDL of the child. Relative to pidlRoot. * riid [I] GUID of the interface, which ppvOut shall be bound to. * ppvOut [O] A reference to the child's interface (riid). * * NOTES * pidlComplete has to contain at least one non empty SHITEMID. * This function makes special assumptions on the shell namespace, which * means you probably can't use it for your IShellFolder implementation. */ HRESULT SHELL32_BindToChild (LPCITEMIDLIST pidlRoot, LPCWSTR pathRoot, LPCITEMIDLIST pidlComplete, REFIID riid, LPVOID * ppvOut) { GUID const *clsid; IShellFolder *pSF; HRESULT hr; LPITEMIDLIST pidlChild; TRACE("(%p %s %p %s %p)\n", pidlRoot, debugstr_w(pathRoot), pidlComplete, debugstr_guid(riid), ppvOut); if (!pidlRoot || !ppvOut || _ILIsEmpty(pidlComplete)) return E_INVALIDARG; *ppvOut = NULL; pidlChild = ILCloneFirst (pidlComplete); if ((clsid = _ILGetGUIDPointer (pidlChild))) { /* virtual folder */ hr = SHELL32_CoCreateInitSF (pidlRoot, pathRoot, pidlChild, clsid, (LPVOID *)&pSF); } else if (_ILIsValue(pidlChild)) { /* Don't bind to files */ hr = HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND); } else { /* file system folder */ CLSID clsidFolder = CLSID_ShellFSFolder; static const WCHAR wszCLSID[] = {'C','L','S','I','D',0}; WCHAR wszCLSIDValue[CHARS_IN_GUID], wszFolderPath[MAX_PATH], *pwszPathTail = wszFolderPath; /* see if folder CLSID should be overridden by desktop.ini file */ if (pathRoot) { lstrcpynW(wszFolderPath, pathRoot, MAX_PATH); pwszPathTail = PathAddBackslashW(wszFolderPath); } _ILSimpleGetTextW(pidlChild,pwszPathTail,MAX_PATH - (int)(pwszPathTail - wszFolderPath)); if (SHELL32_GetCustomFolderAttributeFromPath (wszFolderPath, wszDotShellClassInfo, wszCLSID, wszCLSIDValue, CHARS_IN_GUID)) CLSIDFromString (wszCLSIDValue, &clsidFolder); hr = SHELL32_CoCreateInitSF (pidlRoot, pathRoot, pidlChild, &clsidFolder, (LPVOID *)&pSF); } ILFree (pidlChild); if (SUCCEEDED (hr)) { if (_ILIsPidlSimple (pidlComplete)) { /* no sub folders */ hr = IShellFolder_QueryInterface (pSF, riid, ppvOut); } else { /* go deeper */ hr = IShellFolder_BindToObject (pSF, ILGetNext (pidlComplete), NULL, riid, ppvOut); } IShellFolder_Release (pSF); } TRACE ("-- returning (%p) 0x%08x\n", *ppvOut, hr); return hr; }
/************************************************************************** * CControlPanelFolder::GetDisplayNameOf */ HRESULT WINAPI CControlPanelFolder::GetDisplayNameOf(PCUITEMID_CHILD pidl, DWORD dwFlags, LPSTRRET strRet) { CHAR szName[MAX_PATH]; WCHAR wszName[MAX_PATH+1]; /* +1 for potential backslash */ PIDLCPanelStruct *pCPanel; HRESULT hr; *szName = '\0'; TRACE("(%p)->(pidl=%p,0x%08x,%p)\n", this, pidl, dwFlags, strRet); pdump(pidl); if (!pidl) return S_FALSE; pCPanel = _ILGetCPanelPointer(pidl); if (pCPanel) { /* copy display name from pidl - it was retrived from applet before; SHGDN_FORPARSING does not need special handling */ lstrcpyA(szName, pCPanel->szName + pCPanel->offsDispName); } /* take names of special folders only if it's only this folder */ else if (_ILIsSpecialFolder(pidl)) { BOOL bSimplePidl = _ILIsPidlSimple(pidl); SFGAOF Attr = SFGAO_FILESYSTEM; SHELL32_GetItemAttributes(this, pidl, &Attr); if (Attr & SFGAO_FILESYSTEM) { hr = SHELL32_GetDisplayNameOfChild(this, pidl, dwFlags, wszName, sizeof(wszName)); if (FAILED(hr)) return hr; } else if (bSimplePidl) { _ILSimpleGetTextW(pidl, wszName, MAX_PATH); /* append my own path */ } else { FIXME("special pidl\n"); if (dwFlags & SHGDN_FORPARSING) { /* go deeper if needed */ int cchName; PathAddBackslashW(wszName); cchName = wcslen(wszName); hr = SHELL32_GetDisplayNameOfChild(this, pidl, dwFlags, wszName + cchName, MAX_PATH + 1 - cchName); if (FAILED(hr)) return hr; } } if (!WideCharToMultiByte(CP_ACP, 0, wszName, -1, szName, MAX_PATH, NULL, NULL)) szName[0] = '\0'; } strRet->uType = STRRET_CSTR; lstrcpynA(strRet->cStr, szName, MAX_PATH); TRACE("--(%p)->(%s)\n", this, szName); return S_OK; }
/************************************************************************** * ISF_Desktop_fnSetNameOf * Changes the name of a file object or subfolder, possibly changing its item * identifier in the process. * * PARAMETERS * HWND hwndOwner, //[in ] Owner window for output * LPCITEMIDLIST pidl, //[in ] simple pidl of item to change * LPCOLESTR lpszName, //[in ] the items new display name * DWORD dwFlags, //[in ] SHGNO formatting flags * LPITEMIDLIST* ppidlOut) //[out] simple pidl returned */ static HRESULT WINAPI ISF_Desktop_fnSetNameOf (IShellFolder2 * iface, HWND hwndOwner, LPCITEMIDLIST pidl, /* simple pidl */ LPCOLESTR lpName, DWORD dwFlags, LPITEMIDLIST * pPidlOut) { IGenericSFImpl *This = (IGenericSFImpl *)iface; IShellFolder2 * psf; HRESULT hr; WCHAR szSrc[MAX_PATH + 1], szDest[MAX_PATH + 1]; LPWSTR ptr; BOOL bIsFolder = _ILIsFolder (ILFindLastID (pidl)); TRACE ("(%p)->(%p,pidl=%p,%s,%u,%p)\n", This, hwndOwner, pidl, debugstr_w (lpName), dwFlags, pPidlOut); if (_ILGetGUIDPointer(pidl)) { if (SUCCEEDED(IShellFolder2_BindToObject(iface, pidl, NULL, &IID_IShellFolder2, (LPVOID*)&psf))) { hr = IShellFolder2_SetNameOf(psf, hwndOwner, pidl, lpName, dwFlags, pPidlOut); IShellFolder2_Release(psf); return hr; } } /* build source path */ lstrcpynW(szSrc, This->sPathTarget, MAX_PATH); ptr = PathAddBackslashW (szSrc); if (ptr) _ILSimpleGetTextW (pidl, ptr, MAX_PATH + 1 - (ptr - szSrc)); /* build destination path */ if (dwFlags == SHGDN_NORMAL || dwFlags & SHGDN_INFOLDER) { lstrcpynW(szDest, This->sPathTarget, MAX_PATH); ptr = PathAddBackslashW (szDest); if (ptr) lstrcpynW(ptr, lpName, MAX_PATH + 1 - (ptr - szDest)); } else lstrcpynW(szDest, lpName, MAX_PATH); if(!(dwFlags & SHGDN_FORPARSING) && SHELL_FS_HideExtension(szSrc)) { WCHAR *ext = PathFindExtensionW(szSrc); if(*ext != '\0') { INT len = wcslen(szDest); lstrcpynW(szDest + len, ext, MAX_PATH - len); } } if (!memcmp(szSrc, szDest, (wcslen(szDest)+1) * sizeof(WCHAR))) { /* src and destination is the same */ hr = S_OK; if (pPidlOut) hr = _ILCreateFromPathW(szDest, pPidlOut); return hr; } TRACE ("src=%s dest=%s\n", debugstr_w(szSrc), debugstr_w(szDest)); if (MoveFileW (szSrc, szDest)) { hr = S_OK; if (pPidlOut) hr = _ILCreateFromPathW(szDest, pPidlOut); SHChangeNotify (bIsFolder ? SHCNE_RENAMEFOLDER : SHCNE_RENAMEITEM, SHCNF_PATHW, szSrc, szDest); return hr; } return E_FAIL; }
/************************************************************************** * CAdminToolsFolder::GetDisplayNameOf * */ HRESULT WINAPI CAdminToolsFolder::GetDisplayNameOf(LPCITEMIDLIST pidl, DWORD dwFlags, LPSTRRET strRet) { HRESULT hr = S_OK; LPWSTR pszPath, pOffset; TRACE ("(%p)->(pidl=%p,0x%08x,%p)\n", this, pidl, dwFlags, strRet); pdump (pidl); if (!strRet) return E_INVALIDARG; pszPath = (LPWSTR)CoTaskMemAlloc((MAX_PATH + 1) * sizeof(WCHAR)); if (!pszPath) return E_OUTOFMEMORY; ZeroMemory(pszPath, (MAX_PATH + 1) * sizeof(WCHAR)); if (!pidl->mkid.cb) { if ((GET_SHGDN_RELATION (dwFlags) == SHGDN_NORMAL) && (GET_SHGDN_FOR (dwFlags) & SHGDN_FORPARSING)) wcscpy(pszPath, szTarget); else if (!HCR_GetClassNameW(CLSID_AdminFolderShortcut, pszPath, MAX_PATH)) hr = E_FAIL; } else if (_ILIsPidlSimple(pidl)) { if ((GET_SHGDN_FOR(dwFlags) & SHGDN_FORPARSING) && (GET_SHGDN_RELATION(dwFlags) != SHGDN_INFOLDER) && szTarget) { wcscpy(pszPath, szTarget); pOffset = PathAddBackslashW(pszPath); if (pOffset) { if (!_ILSimpleGetTextW(pidl, pOffset, MAX_PATH + 1 - (pOffset - pszPath))) hr = E_FAIL; } else hr = E_FAIL; } else { if (_ILSimpleGetTextW(pidl, pszPath, MAX_PATH + 1)) { if (SHELL_FS_HideExtension(pszPath)) PathRemoveExtensionW(pszPath); } else hr = E_FAIL; } } else if (_ILIsSpecialFolder(pidl)) { BOOL bSimplePidl = _ILIsPidlSimple(pidl); if (bSimplePidl) { if (!_ILSimpleGetTextW(pidl, pszPath, MAX_PATH)) hr = E_FAIL; } else if ((dwFlags & SHGDN_FORPARSING) && !bSimplePidl) { int len = 0; wcscpy(pszPath, szTarget); PathAddBackslashW(pszPath); len = wcslen(pszPath); if (!SUCCEEDED(SHELL32_GetDisplayNameOfChild(this, pidl, dwFlags | SHGDN_INFOLDER, pszPath + len, MAX_PATH + 1 - len))) { CoTaskMemFree(pszPath); return E_OUTOFMEMORY; } } } if (SUCCEEDED(hr)) { strRet->uType = STRRET_WSTR; strRet->pOleStr = pszPath; TRACE ("-- (%p)->(%s,0x%08x)\n", this, debugstr_w(strRet->pOleStr), hr); } else CoTaskMemFree(pszPath); return hr; }