/*********************************************************************** * SHELL32_GetDisplayNameOfChild * * Retrieves the display name of a child object of a shellfolder. * * For a pidl eg. [subpidl1][subpidl2][subpidl3]: * - it binds to the child shellfolder [subpidl1] * - asks it for the displayname of [subpidl2][subpidl3] * * Is possible the pidl is a simple pidl. In this case it asks the * subfolder for the displayname of an empty pidl. The subfolder * returns the own displayname eg. "::{guid}". This is used for * virtual folders with the registry key WantsFORPARSING set. */ HRESULT SHELL32_GetDisplayNameOfChild (IShellFolder2 * psf, LPCITEMIDLIST pidl, DWORD dwFlags, LPWSTR szOut, DWORD dwOutLen) { LPITEMIDLIST pidlFirst; HRESULT hr; TRACE ("(%p)->(pidl=%p 0x%08x %p 0x%08x)\n", psf, pidl, dwFlags, szOut, dwOutLen); pdump (pidl); pidlFirst = ILCloneFirst (pidl); if (pidlFirst) { IShellFolder2 *psfChild; hr = IShellFolder2_BindToObject (psf, pidlFirst, NULL, &IID_IShellFolder, (LPVOID *) & psfChild); if (SUCCEEDED (hr)) { STRRET strTemp; LPITEMIDLIST pidlNext = ILGetNext (pidl); hr = IShellFolder2_GetDisplayNameOf (psfChild, pidlNext, dwFlags, &strTemp); if (SUCCEEDED (hr)) { if(!StrRetToStrNW (szOut, dwOutLen, &strTemp, pidlNext)) hr = E_FAIL; } IShellFolder2_Release (psfChild); } ILFree (pidlFirst); } else hr = E_OUTOFMEMORY; TRACE ("-- ret=0x%08x %s\n", hr, debugstr_w(szOut)); return hr; }
/************************************************************************** * ISF_MyComputer_Constructor */ HRESULT WINAPI ISF_MyComputer_Constructor (IUnknown * pUnkOuter, REFIID riid, LPVOID * ppv) { IMyComputerFolderImpl *sf; TRACE ("unkOut=%p %s\n", pUnkOuter, shdebugstr_guid (riid)); if (!ppv) return E_POINTER; if (pUnkOuter) return CLASS_E_NOAGGREGATION; sf = LocalAlloc (LMEM_ZEROINIT, sizeof (IMyComputerFolderImpl)); if (!sf) return E_OUTOFMEMORY; sf->ref = 0; sf->IShellFolder2_iface.lpVtbl = &vt_ShellFolder2; sf->IPersistFolder2_iface.lpVtbl = &vt_PersistFolder2; sf->pidlRoot = _ILCreateMyComputer (); /* my qualified pidl */ if (FAILED (IShellFolder2_QueryInterface (&sf->IShellFolder2_iface, riid, ppv))) { IShellFolder2_Release (&sf->IShellFolder2_iface); return E_NOINTERFACE; } TRACE ("--(%p)\n", sf); return S_OK; }
/************************************************************************** * ISF_NetworkPlaces_Constructor */ HRESULT WINAPI ISF_NetworkPlaces_Constructor (IUnknown * pUnkOuter, REFIID riid, LPVOID * ppv) { IGenericSFImpl *sf; TRACE ("unkOut=%p %s\n", pUnkOuter, shdebugstr_guid (riid)); if (!ppv) return E_POINTER; if (pUnkOuter) return CLASS_E_NOAGGREGATION; sf = HeapAlloc (GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof (IGenericSFImpl)); if (!sf) return E_OUTOFMEMORY; sf->ref = 0; sf->IShellFolder2_iface.lpVtbl = &vt_ShellFolder2; sf->IPersistFolder2_iface.lpVtbl = &vt_NP_PersistFolder2; sf->pidlRoot = _ILCreateNetHood(); /* my qualified pidl */ if (FAILED (IShellFolder2_QueryInterface (&sf->IShellFolder2_iface, riid, ppv))) { IShellFolder2_Release (&sf->IShellFolder2_iface); return E_NOINTERFACE; } TRACE ("--(%p)\n", sf); return S_OK; }
/************************************************************************** * IControlPanel_Constructor */ HRESULT WINAPI IControlPanel_Constructor(IUnknown* pUnkOuter, REFIID riid, LPVOID * ppv) { ICPanelImpl *sf; TRACE("unkOut=%p %s\n", pUnkOuter, shdebugstr_guid(riid)); if (!ppv) return E_POINTER; if (pUnkOuter && !IsEqualIID (riid, &IID_IUnknown)) return CLASS_E_NOAGGREGATION; sf = LocalAlloc(LMEM_ZEROINIT, sizeof(ICPanelImpl)); if (!sf) return E_OUTOFMEMORY; sf->ref = 0; sf->IShellFolder2_iface.lpVtbl = &vt_ShellFolder2; sf->IPersistFolder2_iface.lpVtbl = &vt_PersistFolder2; sf->IShellExecuteHookW_iface.lpVtbl = &vt_ShellExecuteHookW; sf->IShellExecuteHookA_iface.lpVtbl = &vt_ShellExecuteHookA; sf->pidlRoot = _ILCreateControlPanel(); /* my qualified pidl */ sf->pUnkOuter = pUnkOuter ? pUnkOuter : (IUnknown *)&sf->IShellFolder2_iface; if (FAILED(IShellFolder2_QueryInterface(&sf->IShellFolder2_iface, riid, ppv))) { IShellFolder2_Release(&sf->IShellFolder2_iface); return E_NOINTERFACE; } TRACE("--(%p)\n", sf); return S_OK; }
/************************************************************************ * ISFPersistFolder_Release */ static ULONG WINAPI INPFldr_PersistFolder2_Release (IPersistFolder2 * iface) { IGenericSFImpl *This = impl_from_IPersistFolder2(iface); TRACE ("(%p)->(count=%u)\n", This, This->ref); return IShellFolder2_Release (&This->IShellFolder2_iface); }
static ULONG WINAPI ISF_Desktop_IPersistFolder2_fnRelease( IPersistFolder2 *iface) { IDesktopFolderImpl *This = impl_from_IPersistFolder2( iface ); return IShellFolder2_Release(&This->IShellFolder2_iface); }
static void test_printers_folder(void) { IShellFolder2 *folder; IPersistFolder2 *pf; SHELLDETAILS details; SHCOLSTATEF state; LPITEMIDLIST pidl1, pidl2; HRESULT hr; INT i; CoInitialize( NULL ); hr = CoCreateInstance(&CLSID_Printers, NULL, CLSCTX_INPROC_SERVER, &IID_IShellFolder2, (void**)&folder); if (hr != S_OK) { win_skip("Failed to created IShellFolder2 for Printers folder\n"); CoUninitialize(); return; } if (0) { /* crashes on XP */ hr = IShellFolder2_GetDetailsOf(folder, NULL, 0, NULL); hr = IShellFolder2_GetDefaultColumnState(folder, 0, NULL); hr = IPersistFolder2_GetCurFolder(pf, NULL); } /* 5 columns defined */ hr = IShellFolder2_GetDetailsOf(folder, NULL, 6, &details); ok(hr == E_NOTIMPL, "got 0x%08x\n", hr); hr = IShellFolder2_GetDefaultColumnState(folder, 6, &state); ok(broken(hr == E_NOTIMPL) || hr == E_INVALIDARG /* Win7 */, "got 0x%08x\n", hr); hr = IShellFolder2_GetDetailsOf(folder, NULL, 0, &details); ok(hr == S_OK || broken(E_NOTIMPL) /* W2K */, "got 0x%08x\n", hr); /* test every column if method is implemented */ if (hr == S_OK) { ok(details.str.uType == STRRET_WSTR, "got %d\n", details.str.uType); for(i = 0; i < 6; i++) { hr = IShellFolder2_GetDetailsOf(folder, NULL, i, &details); ok(hr == S_OK, "got 0x%08x\n", hr); /* all columns are left-aligned */ ok(details.fmt == LVCFMT_LEFT, "got 0x%x\n", details.fmt); /* can't be on w9x at this point, IShellFolder2 unsupported there, check present for running Wine with w9x setup */ if (SHELL_OsIsUnicode()) SHFree(details.str.u.pOleStr); hr = IShellFolder2_GetDefaultColumnState(folder, i, &state); ok(hr == S_OK, "got 0x%08x\n", hr); /* all columns are string except document count */ if (i == 1) ok(state == (SHCOLSTATE_TYPE_INT | SHCOLSTATE_ONBYDEFAULT), "got 0x%x\n", state); else ok(state == (SHCOLSTATE_TYPE_STR | SHCOLSTATE_ONBYDEFAULT), "got 0x%x\n", state); } } /* default pidl */ hr = IShellFolder2_QueryInterface(folder, &IID_IPersistFolder2, (void**)&pf); ok(hr == S_OK, "got 0x%08x\n", hr); /* not initialized */ pidl1 = (void*)0xdeadbeef; hr = IPersistFolder2_GetCurFolder(pf, &pidl1); ok(hr == S_FALSE, "got 0x%08x\n", hr); ok(pidl1 == NULL, "got %p\n", pidl1); hr = SHGetSpecialFolderLocation(NULL, CSIDL_PRINTERS, &pidl2); ok(hr == S_OK, "got 0x%08x\n", hr); hr = IPersistFolder2_Initialize(pf, pidl2); ok(hr == S_OK, "got 0x%08x\n", hr); hr = IPersistFolder2_GetCurFolder(pf, &pidl1); ok(hr == S_OK, "got 0x%08x\n", hr); ok(ILIsEqual(pidl1, pidl2), "expected same PIDL\n"); IPersistFolder2_Release(pf); ILFree(pidl1); ILFree(pidl2); IShellFolder2_Release(folder); CoUninitialize(); }
/************************************************************************** * 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; }