WINE_DEFAULT_DEBUG_CHANNEL (shell);
+HKEY OpenKeyFromFileType(PCUIDLIST_RELATIVE pidl, LPCWSTR KeyName)
+{
+ HKEY hkey;
+
+ if (!_ILIsValue(pidl))
+ {
+ ERR("Invalid pidl!\n");
+ return NULL;
+ }
+
+ FileStructW* pDataW = _ILGetFileStructW(pidl);
+ if (!pDataW)
+ {
+ ERR("Invalid pidl!\n");
+ return NULL;
+ }
+
+ LPWSTR pExtension = PathFindExtensionW(pDataW->wszName);
+ if (!pExtension || *pExtension == NULL)
+ {
+ WARN("No extension for %S!\n", pDataW->wszName);
+ return NULL;
+ }
+
+ WCHAR FullName[MAX_PATH];
+ DWORD dwSize = sizeof(FullName);
+ wsprintf(FullName, L"%s\\%s", pExtension, KeyName);
+
+ LONG res = RegOpenKeyExW(HKEY_CLASSES_ROOT, FullName, 0, KEY_READ, &hkey);
+ if (!res)
+ return hkey;
+
+ res = RegGetValueW(HKEY_CLASSES_ROOT, pExtension, NULL, RRF_RT_REG_SZ, NULL, FullName, &dwSize);
+ if (res)
+ {
+ WARN("Failed to get progid for file %S, extension %S (%x), address %x, pidl: %x, error %d\n", pDataW->wszName, pExtension, pExtension, &dwSize, pidl, res);
+ return NULL;
+ }
+
+ wcscat(FullName, L"\\");
+ wcscat(FullName, KeyName);
+
+ hkey = NULL;
+ res = RegOpenKeyExW(HKEY_CLASSES_ROOT, FullName, 0, KEY_READ, &hkey);
+ if (res)
+ WARN("Could not open key %S for extension %S\n", KeyName, pExtension);
+
+ return hkey;
+}
+
+HRESULT GetCLSIDForFileType(PCUIDLIST_RELATIVE pidl, LPCWSTR KeyName, CLSID* pclsid)
+{
+ HKEY hkeyProgId = OpenKeyFromFileType(pidl, KeyName);
+ if (!hkeyProgId)
+ {
+ WARN("OpenKeyFromFileType failed for key %S\n", KeyName);
+ return S_FALSE;
+ }
+
+ WCHAR wszCLSIDValue[CHARS_IN_GUID];
+ DWORD dwSize = sizeof(wszCLSIDValue);
+ if (RegGetValueW(hkeyProgId, NULL, NULL, RRF_RT_REG_SZ, NULL, wszCLSIDValue, &dwSize))
+ {
+ ERR("OpenKeyFromFileType succeeded but RegGetValueW failed\n");
+ return S_FALSE;
+ }
+
+#if 0
+ {
+ res = RegGetValueW(HKEY_LOCAL_MACHINE,
+ L"Software\\Microsoft\\Windows\\CurrentVersion\\Shell Extensions\\Approved",
+ wszCLSIDValue,
+ RRF_RT_REG_SZ,
+ NULL,
+ NULL,
+ NULL);
+ if (res != ERROR_SUCCESS)
+ {
+ ERR("DropHandler extension %S not approved\n", wszName);
+ return E_ACCESSDENIED;
+ }
+ }
+#endif
+
+ HRESULT hres = CLSIDFromString (wszCLSIDValue, pclsid);
+ if (FAILED_UNEXPECTEDLY(hres))
+ return hres;
+
+ return S_OK;
+}
+
+static HRESULT getIconLocationForFolder(IShellFolder * psf, LPCITEMIDLIST pidl, UINT uFlags,
+ LPWSTR szIconFile, UINT cchMax, int *piIndex, UINT *pwFlags)
+{
+ static const WCHAR shellClassInfo[] = { '.', 'S', 'h', 'e', 'l', 'l', 'C', 'l', 'a', 's', 's', 'I', 'n', 'f', 'o', 0 };
+ static const WCHAR iconFile[] = { 'I', 'c', 'o', 'n', 'F', 'i', 'l', 'e', 0 };
+ static const WCHAR clsid[] = { 'C', 'L', 'S', 'I', 'D', 0 };
+ static const WCHAR clsid2[] = { 'C', 'L', 'S', 'I', 'D', '2', 0 };
+ static const WCHAR iconIndex[] = { 'I', 'c', 'o', 'n', 'I', 'n', 'd', 'e', 'x', 0 };
+ static const WCHAR wszDesktopIni[] = { 'd','e','s','k','t','o','p','.','i','n','i',0 };
+ int icon_idx;
+
+ if (!(uFlags & GIL_DEFAULTICON) && (_ILGetFileAttributes(ILFindLastID(pidl), NULL, 0) & (FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_READONLY)) != 0 )
+ {
+ WCHAR wszFolderPath[MAX_PATH];
+
+ if (!ILGetDisplayNameExW(psf, pidl, wszFolderPath, 0))
+ return FALSE;
+
+ PathAppendW(wszFolderPath, wszDesktopIni);
+
+ if (PathFileExistsW(wszFolderPath))
+ {
+ WCHAR wszPath[MAX_PATH];
+ WCHAR wszCLSIDValue[CHARS_IN_GUID];
+
+ if (GetPrivateProfileStringW(shellClassInfo, iconFile, NULL, wszPath, MAX_PATH, wszFolderPath))
+ {
+ ExpandEnvironmentStringsW(wszPath, szIconFile, cchMax);
+
+ *piIndex = GetPrivateProfileIntW(shellClassInfo, iconIndex, 0, wszFolderPath);
+ return S_OK;
+ }
+ else if (GetPrivateProfileStringW(shellClassInfo, clsid, NULL, wszCLSIDValue, CHARS_IN_GUID, wszFolderPath) &&
+ HCR_GetIconW(wszCLSIDValue, szIconFile, NULL, cchMax, &icon_idx))
+ {
+ *piIndex = icon_idx;
+ return S_OK;
+ }
+ else if (GetPrivateProfileStringW(shellClassInfo, clsid2, NULL, wszCLSIDValue, CHARS_IN_GUID, wszFolderPath) &&
+ HCR_GetIconW(wszCLSIDValue, szIconFile, NULL, cchMax, &icon_idx))
+ {
+ *piIndex = icon_idx;
+ return S_OK;
+ }
+ }
+ }
+
+ static const WCHAR folder[] = { 'F', 'o', 'l', 'd', 'e', 'r', 0 };
+
+ if (!HCR_GetIconW(folder, szIconFile, NULL, cchMax, &icon_idx))
+ {
+ lstrcpynW(szIconFile, swShell32Name, cchMax);
+ icon_idx = -IDI_SHELL_FOLDER;
+ }
+
+ if (uFlags & GIL_OPENICON)
+ *piIndex = icon_idx < 0 ? icon_idx - 1 : icon_idx + 1;
+ else
+ *piIndex = icon_idx;
+
+ return S_OK;
+}
+
+HRESULT CFSExtractIcon_CreateInstance(IShellFolder * psf, LPCITEMIDLIST pidl, REFIID iid, LPVOID * ppvOut)
+{
+ CComPtr<IDefaultExtractIconInit> initIcon;
+ HRESULT hr;
+ int icon_idx = 0;
+ UINT flags = 0; // FIXME: Use it!
+ WCHAR wTemp[MAX_PATH] = L"";
+
+ hr = SHCreateDefaultExtractIcon(IID_PPV_ARG(IDefaultExtractIconInit,&initIcon));
+ if (FAILED(hr))
+ return hr;
+
+ if (_ILIsFolder (pidl))
+ {
+ if (SUCCEEDED(getIconLocationForFolder(psf,
+ pidl, 0, wTemp, _countof(wTemp),
+ &icon_idx,
+ &flags)))
+ {
+ initIcon->SetNormalIcon(wTemp, icon_idx);
+ // FIXME: if/when getIconLocationForFolder does something for
+ // GIL_FORSHORTCUT, code below should be uncommented. and
+ // the following line removed.
+ initIcon->SetShortcutIcon(wTemp, icon_idx);
+ }
+ if (SUCCEEDED(getIconLocationForFolder(psf,
+ pidl, GIL_DEFAULTICON, wTemp, _countof(wTemp),
+ &icon_idx,
+ &flags)))
+ {
+ initIcon->SetDefaultIcon(wTemp, icon_idx);
+ }
+ // if (SUCCEEDED(getIconLocationForFolder(psf,
+ // pidl, GIL_FORSHORTCUT, wTemp, _countof(wTemp),
+ // &icon_idx,
+ // &flags)))
+ // {
+ // initIcon->SetShortcutIcon(wTemp, icon_idx);
+ // }
+ if (SUCCEEDED(getIconLocationForFolder(psf,
+ pidl, GIL_OPENICON, wTemp, _countof(wTemp),
+ &icon_idx,
+ &flags)))
+ {
+ initIcon->SetOpenIcon(wTemp, icon_idx);
+ }
+ }
+ else
+ {
+ HKEY hkey = OpenKeyFromFileType(pidl, L"DefaultIcon");
+ if (!hkey)
+ WARN("Could not open DefaultIcon key!\n");
+
+ DWORD dwSize = sizeof(wTemp);
+ if (hkey && !SHQueryValueExW(hkey, NULL, NULL, NULL, wTemp, &dwSize))
+ {
+ WCHAR sNum[5];
+ if (ParseFieldW (wTemp, 2, sNum, 5))
+ icon_idx = _wtoi(sNum);
+ else
+ icon_idx = 0; /* sometimes the icon number is missing */
+ ParseFieldW (wTemp, 1, wTemp, MAX_PATH);
+ PathUnquoteSpacesW(wTemp);
+
+ if (!wcscmp(L"%1", wTemp)) /* icon is in the file */
+ {
+ ILGetDisplayNameExW(psf, pidl, wTemp, 0);
+ icon_idx = 0;
+ }
+
+ initIcon->SetNormalIcon(wTemp, icon_idx);
+ }
+ else
+ {
+ initIcon->SetNormalIcon(swShell32Name, 0);
+ }
+ }
+
+ return initIcon->QueryInterface(iid, ppvOut);
+}
+
/*
CFileSysEnum should do an initial FindFirstFile and do a FindNextFile as each file is
returned by Next. When the enumerator is created, it can do numerous additional operations
{
}
-HRESULT WINAPI CFileSysEnum::Initialize(LPWSTR sPathTarget, DWORD dwFlags)
+HRESULT WINAPI CFileSysEnum::Initialize(LPWSTR lpszPath, DWORD dwFlags)
{
- return CreateFolderEnumList(sPathTarget, dwFlags);
-}
+ WIN32_FIND_DATAW stffile;
+ HANDLE hFile;
+ WCHAR szPath[MAX_PATH];
+ BOOL succeeded = TRUE;
+ static const WCHAR stars[] = { '*','.','*',0 };
+ static const WCHAR dot[] = { '.',0 };
+ static const WCHAR dotdot[] = { '.','.',0 };
-/**************************************************************************
-* registers clipboardformat once
-*/
-void CFSFolder::SF_RegisterClipFmt()
-{
- TRACE ("(%p)\n", this);
+ TRACE("(%p)->(path=%s flags=0x%08x)\n", this, debugstr_w(lpszPath), dwFlags);
+
+ if(!lpszPath || !lpszPath[0]) return FALSE;
+
+ wcscpy(szPath, lpszPath);
+ PathAddBackslashW(szPath);
+ wcscat(szPath,stars);
+
+ hFile = FindFirstFileW(szPath,&stffile);
+ if ( hFile != INVALID_HANDLE_VALUE )
+ {
+ BOOL findFinished = FALSE;
+
+ do
+ {
+ if ( !(stffile.dwFileAttributes & FILE_ATTRIBUTE_HIDDEN)
+ || (dwFlags & SHCONTF_INCLUDEHIDDEN) )
+ {
+ LPITEMIDLIST pidl = NULL;
+
+ if ( (stffile.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) &&
+ dwFlags & SHCONTF_FOLDERS &&
+ strcmpW(stffile.cFileName, dot) && strcmpW(stffile.cFileName, dotdot))
+ {
+ pidl = _ILCreateFromFindDataW(&stffile);
+ succeeded = succeeded && AddToEnumList(pidl);
+ }
+ else if (!(stffile.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
+ && dwFlags & SHCONTF_NONFOLDERS)
+ {
+ pidl = _ILCreateFromFindDataW(&stffile);
+ succeeded = succeeded && AddToEnumList(pidl);
+ }
+ }
+ if (succeeded)
+ {
+ if (!FindNextFileW(hFile, &stffile))
+ {
+ if (GetLastError() == ERROR_NO_MORE_FILES)
+ findFinished = TRUE;
+ else
+ succeeded = FALSE;
+ }
+ }
+ } while (succeeded && !findFinished);
+ FindClose(hFile);
+ }
- if (!cfShellIDList)
- cfShellIDList = RegisterClipboardFormatW(CFSTR_SHELLIDLIST);
+ return succeeded;
}
CFSFolder::CFSFolder()
pclsid = (CLSID *)&CLSID_ShellFSFolder;
sPathTarget = NULL;
pidlRoot = NULL;
- cfShellIDList = 0;
- SF_RegisterClipFmt();
- fAcceptFmt = FALSE;
m_bGroupPolicyActive = 0;
}
static const shvheader GenericSFHeader[] = {
- {IDS_SHV_COLUMN1, SHCOLSTATE_TYPE_STR | SHCOLSTATE_ONBYDEFAULT, LVCFMT_RIGHT, 15},
- {IDS_SHV_COLUMN2, SHCOLSTATE_TYPE_STR | SHCOLSTATE_ONBYDEFAULT, LVCFMT_RIGHT, 10},
- {IDS_SHV_COLUMN3, SHCOLSTATE_TYPE_STR | SHCOLSTATE_ONBYDEFAULT, LVCFMT_RIGHT, 10},
- {IDS_SHV_COLUMN4, SHCOLSTATE_TYPE_DATE | SHCOLSTATE_ONBYDEFAULT, LVCFMT_RIGHT, 12},
- {IDS_SHV_COLUMN5, SHCOLSTATE_TYPE_STR | SHCOLSTATE_ONBYDEFAULT, LVCFMT_RIGHT, 5}
+ {IDS_SHV_COLUMN_NAME, SHCOLSTATE_TYPE_STR | SHCOLSTATE_ONBYDEFAULT, LVCFMT_LEFT, 15},
+ {IDS_SHV_COLUMN_COMMENTS, SHCOLSTATE_TYPE_STR, LVCFMT_LEFT, 0},
+ {IDS_SHV_COLUMN_TYPE, SHCOLSTATE_TYPE_STR | SHCOLSTATE_ONBYDEFAULT, LVCFMT_LEFT, 10},
+ {IDS_SHV_COLUMN_SIZE, SHCOLSTATE_TYPE_STR | SHCOLSTATE_ONBYDEFAULT, LVCFMT_RIGHT, 10},
+ {IDS_SHV_COLUMN_MODIFIED, SHCOLSTATE_TYPE_DATE | SHCOLSTATE_ONBYDEFAULT, LVCFMT_LEFT, 12},
+ {IDS_SHV_COLUMN_ATTRIBUTES, SHCOLSTATE_TYPE_STR | SHCOLSTATE_ONBYDEFAULT, LVCFMT_LEFT, 10}
};
-#define GENERICSHELLVIEWCOLUMNS 5
+#define GENERICSHELLVIEWCOLUMNS 6
/**************************************************************************
* SHELL32_CreatePidlFromBindCtx [internal]
return pidl;
}
+void SHELL32_GetCLSIDForDirectory(LPCWSTR pwszDir, CLSID* pclsidFolder)
+{
+ WCHAR wszCLSIDValue[CHARS_IN_GUID];
+ WCHAR wszDesktopIni[MAX_PATH];
+ StringCchCopyW(wszDesktopIni, MAX_PATH, pwszDir);
+ StringCchCatW(wszDesktopIni, MAX_PATH, L"\\desktop.ini");
+
+ if (GetPrivateProfileStringW(L".ShellClassInfo",
+ L"CLSID",
+ L"",
+ wszCLSIDValue,
+ CHARS_IN_GUID,
+ wszDesktopIni))
+ {
+ CLSIDFromString (wszCLSIDValue, pclsidFolder);
+ }
+}
+
+
+static const DWORD dwSupportedAttr=
+ SFGAO_CANCOPY | /*0x00000001 */
+ SFGAO_CANMOVE | /*0x00000002 */
+ SFGAO_CANLINK | /*0x00000004 */
+ SFGAO_CANRENAME | /*0x00000010 */
+ SFGAO_CANDELETE | /*0x00000020 */
+ SFGAO_HASPROPSHEET | /*0x00000040 */
+ SFGAO_DROPTARGET | /*0x00000100 */
+ SFGAO_LINK | /*0x00010000 */
+ SFGAO_READONLY | /*0x00040000 */
+ SFGAO_HIDDEN | /*0x00080000 */
+ SFGAO_FILESYSANCESTOR | /*0x10000000 */
+ SFGAO_FOLDER | /*0x20000000 */
+ SFGAO_FILESYSTEM | /*0x40000000 */
+ SFGAO_HASSUBFOLDER; /*0x80000000 */
+
+HRESULT SHELL32_GetFSItemAttributes(IShellFolder * psf, LPCITEMIDLIST pidl, LPDWORD pdwAttributes)
+{
+ DWORD dwFileAttributes, dwShellAttributes;
+
+ if (!_ILIsFolder(pidl) && !_ILIsValue(pidl))
+ {
+ ERR("Got wrong type of pidl!\n");
+ *pdwAttributes &= SFGAO_CANLINK;
+ return S_OK;
+ }
+
+ if (*pdwAttributes & ~dwSupportedAttr)
+ {
+ WARN ("attributes 0x%08x not implemented\n", (*pdwAttributes & ~dwSupportedAttr));
+ *pdwAttributes &= dwSupportedAttr;
+ }
+
+ dwFileAttributes = _ILGetFileAttributes(pidl, NULL, 0);
+
+ /* Set common attributes */
+ dwShellAttributes = *pdwAttributes;
+ dwShellAttributes |= SFGAO_FILESYSTEM | SFGAO_DROPTARGET | SFGAO_HASPROPSHEET | SFGAO_CANDELETE |
+ SFGAO_CANRENAME | SFGAO_CANLINK | SFGAO_CANMOVE | SFGAO_CANCOPY;
+
+ if (dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
+ {
+ dwShellAttributes |= (SFGAO_FOLDER | SFGAO_HASSUBFOLDER | SFGAO_FILESYSANCESTOR);
+ }
+ else
+ dwShellAttributes &= ~(SFGAO_FOLDER | SFGAO_HASSUBFOLDER | SFGAO_FILESYSANCESTOR);
+
+ if (dwFileAttributes & FILE_ATTRIBUTE_HIDDEN)
+ dwShellAttributes |= SFGAO_HIDDEN;
+ else
+ dwShellAttributes &= ~SFGAO_HIDDEN;
+
+ if (dwFileAttributes & FILE_ATTRIBUTE_READONLY)
+ dwShellAttributes |= SFGAO_READONLY;
+ else
+ dwShellAttributes &= ~SFGAO_READONLY;
+
+ if (SFGAO_LINK & *pdwAttributes)
+ {
+ char ext[MAX_PATH];
+
+ if (!_ILGetExtension(pidl, ext, MAX_PATH) || lstrcmpiA(ext, "lnk"))
+ dwShellAttributes &= ~SFGAO_LINK;
+ }
+
+ if (SFGAO_HASSUBFOLDER & *pdwAttributes)
+ {
+ CComPtr<IShellFolder> psf2;
+ if (SUCCEEDED(psf->BindToObject(pidl, 0, IID_PPV_ARG(IShellFolder, &psf2))))
+ {
+ CComPtr<IEnumIDList> pEnumIL;
+ if (SUCCEEDED(psf2->EnumObjects(0, SHCONTF_FOLDERS, &pEnumIL)))
+ {
+ if (pEnumIL->Skip(1) != S_OK)
+ dwShellAttributes &= ~SFGAO_HASSUBFOLDER;
+ }
+ }
+ }
+
+ *pdwAttributes &= dwShellAttributes;
+
+ TRACE ("-- 0x%08x\n", *pdwAttributes);
+ return S_OK;
+}
+
/**************************************************************************
* CFSFolder::ParseDisplayName {SHELL32}
*
pidlTemp = SHELL32_CreatePidlFromBindCtx(pbc, szElement);
if (pidlTemp != NULL)
{
+ /* We are creating an id list without ensuring that the items exist.
+ If we have a remaining path, this must be a folder.
+ We have to do it now because it is set as a file by default */
+ if (szNext)
+ {
+ pidlTemp->mkid.abID[0] = PT_FOLDER;
+ }
hr = S_OK;
}
else
DWORD dwFlags,
LPENUMIDLIST *ppEnumIDList)
{
- return ShellObjectCreatorInit<CFileSysEnum>(sPathTarget, dwFlags, IID_IEnumIDList, ppEnumIDList);
+ return ShellObjectCreatorInit<CFileSysEnum>(sPathTarget, dwFlags, IID_PPV_ARG(IEnumIDList, ppEnumIDList));
}
/**************************************************************************
TRACE("(%p)->(pidl=%p,%p,%s,%p)\n", this, pidl, pbc,
shdebugstr_guid(&riid), ppvOut);
- return SHELL32_BindToChild(pidlRoot, sPathTarget, pidl, riid, ppvOut);
+ CComPtr<IShellFolder> pSF;
+ HRESULT hr;
+
+ if (!pidlRoot || !ppvOut || !pidl || !pidl->mkid.cb)
+ {
+ ERR("CFSFolder::BindToObject: Invalid parameters\n");
+ return E_INVALIDARG;
+ }
+
+ if (!_ILIsFolder(pidl) && !_ILIsValue(pidl))
+ {
+ ERR("CFSFolder::BindToObject: Invalid pidl!\n");
+ return E_INVALIDARG;
+ }
+
+ /* Get the pidl data */
+ FileStruct* pData = &_ILGetDataPointer(pidl)->u.file;
+ FileStructW* pDataW = _ILGetFileStructW(pidl);
+
+ if (!pDataW)
+ {
+ ERR("CFSFolder::BindToObject: Invalid pidl!\n");
+ return E_INVALIDARG;
+ }
+
+ *ppvOut = NULL;
+
+ /* Create the target folder info */
+ PERSIST_FOLDER_TARGET_INFO pfti = {0};
+ pfti.dwAttributes = -1;
+ pfti.csidl = -1;
+ PathCombineW(pfti.szTargetParsingName, sPathTarget, pDataW->wszName);
+
+ /* Get the CLSID to bind to */
+ CLSID clsidFolder;
+ if (_ILIsFolder(pidl))
+ {
+ clsidFolder = CLSID_ShellFSFolder;
+
+ if ((pData->uFileAttribs & (FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_READONLY)) != 0)
+ SHELL32_GetCLSIDForDirectory(pfti.szTargetParsingName, &clsidFolder);
+ }
+ else
+ {
+ hr = GetCLSIDForFileType(pidl, L"CLSID", &clsidFolder);
+ if (hr == S_FALSE)
+ return HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND);
+ if (hr != S_OK)
+ return hr;
+ }
+
+ hr = SHELL32_BindToSF(pidlRoot, &pfti, pidl, &clsidFolder, riid, ppvOut);
+ if (FAILED_UNEXPECTEDLY(hr))
+ return hr;
+
+ TRACE ("-- returning (%p) %08x\n", *ppvOut, hr);
+
+ return S_OK;
+
}
/**************************************************************************
PCUIDLIST_RELATIVE pidl1,
PCUIDLIST_RELATIVE pidl2)
{
- int nReturn;
+ LPPIDLDATA pData1 = _ILGetDataPointer(pidl1);
+ LPPIDLDATA pData2 = _ILGetDataPointer(pidl2);
+ FileStructW* pDataW1 = _ILGetFileStructW(pidl1);
+ FileStructW* pDataW2 = _ILGetFileStructW(pidl2);
+ BOOL bIsFolder1 = _ILIsFolder(pidl1);
+ BOOL bIsFolder2 = _ILIsFolder(pidl2);
+ LPWSTR pExtension1, pExtension2;
+
+ if (!pDataW1 || !pDataW2 || LOWORD(lParam) >= GENERICSHELLVIEWCOLUMNS)
+ return E_INVALIDARG;
+
+ /* When sorting between a File and a Folder, the Folder gets sorted first */
+ if (bIsFolder1 != bIsFolder2)
+ {
+ return MAKE_COMPARE_HRESULT(bIsFolder1 ? -1 : 1);
+ }
+
+ int result;
+ switch (LOWORD(lParam))
+ {
+ case 0: /* Name */
+ result = wcsicmp(pDataW1->wszName, pDataW2->wszName);
+ break;
+ case 1: /* Comments */
+ result = 0;
+ break;
+ case 2: /* Type */
+ pExtension1 = PathFindExtensionW(pDataW1->wszName);
+ pExtension2 = PathFindExtensionW(pDataW2->wszName);
+ result = wcsicmp(pExtension1, pExtension2);
+ break;
+ case 3: /* Size */
+ result = pData1->u.file.dwFileSize - pData2->u.file.dwFileSize;
+ break;
+ case 4: /* Modified */
+ result = pData1->u.file.uFileDate - pData2->u.file.uFileDate;
+ if (result == 0)
+ result = pData1->u.file.uFileTime - pData2->u.file.uFileTime;
+ break;
+ case 5: /* Attributes */
+ return SHELL32_CompareDetails(this, lParam, pidl1, pidl2);
+ }
- TRACE("(%p)->(0x%08lx,pidl1=%p,pidl2=%p)\n", this, lParam, pidl1, pidl2);
- nReturn = SHELL32_CompareIDs(this, lParam, pidl1, pidl2);
- TRACE("-- %i\n", nReturn);
- return nReturn;
+ if (result == 0)
+ return SHELL32_CompareChildren(this, lParam, pidl1, pidl2);
+
+ return MAKE_COMPARE_HRESULT(result);
}
/**************************************************************************
*ppvOut = NULL;
if (IsEqualIID (riid, IID_IDropTarget))
- hr = this->QueryInterface (IID_IDropTarget, ppvOut);
+ hr = CFSDropTarget_CreateInstance(sPathTarget, riid, ppvOut);
else if (IsEqualIID (riid, IID_IContextMenu))
{
- FIXME ("IContextMenu not implemented\n");
- hr = E_NOTIMPL;
+ HKEY hKeys[16];
+ UINT cKeys = 0;
+ AddClassKeyToArray(L"Directory\\Background", hKeys, &cKeys);
+
+ DEFCONTEXTMENU dcm;
+ dcm.hwnd = hwndOwner;
+ dcm.pcmcb = this;
+ dcm.pidlFolder = pidlRoot;
+ dcm.psf = this;
+ dcm.cidl = 0;
+ dcm.apidl = NULL;
+ dcm.cKeys = cKeys;
+ dcm.aKeys = hKeys;
+ dcm.punkAssociationInfo = NULL;
+ hr = SHCreateDefaultContextMenu (&dcm, riid, ppvOut);
}
else if (IsEqualIID (riid, IID_IShellView))
{
- hr = CDefView_Constructor(this, riid, ppvOut);
+ SFV_CREATE sfvparams = {sizeof(SFV_CREATE), this};
+ hr = SHCreateShellFolderView(&sfvparams, (IShellView**)ppvOut);
}
}
TRACE("-- (%p)->(interface=%p)\n", this, ppvOut);
REFIID riid, UINT * prgfInOut,
LPVOID * ppvOut)
{
- LPITEMIDLIST pidl;
- IUnknown *pObj = NULL;
+ LPVOID pObj = NULL;
HRESULT hr = E_INVALIDARG;
TRACE ("(%p)->(%p,%u,apidl=%p,%s,%p,%p)\n",
{
*ppvOut = NULL;
+ if (cidl == 1)
+ {
+ hr = _CreateExtensionUIObject(apidl[0], riid, ppvOut);
+ if(hr != S_FALSE)
+ return hr;
+ }
+
if (IsEqualIID(riid, IID_IContextMenu) && (cidl >= 1))
{
- IContextMenu * pCm = NULL;
- hr = CDefFolderMenu_Create2(pidlRoot, hwndOwner, cidl, apidl, static_cast<IShellFolder*>(this), NULL, 0, NULL, &pCm);
- pObj = pCm;
+ HKEY hKeys[16];
+ UINT cKeys = 0;
+ AddFSClassKeysToArray(apidl[0], hKeys, &cKeys);
+
+ DEFCONTEXTMENU dcm;
+ dcm.hwnd = hwndOwner;
+ dcm.pcmcb = this;
+ dcm.pidlFolder = pidlRoot;
+ dcm.psf = this;
+ dcm.cidl = cidl;
+ dcm.apidl = apidl;
+ dcm.cKeys = cKeys;
+ dcm.aKeys = hKeys;
+ dcm.punkAssociationInfo = NULL;
+ hr = SHCreateDefaultContextMenu (&dcm, riid, &pObj);
}
else if (IsEqualIID (riid, IID_IDataObject))
{
}
else
{
- hr = IDataObject_Constructor (hwndOwner, pidlRoot, (LPCITEMIDLIST*)&pidlRoot, 1, (IDataObject **)&pObj);
+ hr = E_INVALIDARG;
}
}
- else if (IsEqualIID (riid, IID_IExtractIconA) && (cidl == 1))
+ else if ((IsEqualIID (riid, IID_IExtractIconA) || IsEqualIID (riid, IID_IExtractIconW)) && (cidl == 1))
{
- pidl = ILCombine (pidlRoot, apidl[0]);
- pObj = IExtractIconA_Constructor (pidl);
- SHFree (pidl);
- hr = S_OK;
- }
- else if (IsEqualIID (riid, IID_IExtractIconW) && (cidl == 1))
- {
- pidl = ILCombine (pidlRoot, apidl[0]);
- pObj = IExtractIconW_Constructor (pidl);
- SHFree (pidl);
- hr = S_OK;
+ hr = _GetIconHandler(apidl[0], riid, (LPVOID*)&pObj);
+ if (hr != S_OK)
+ hr = CFSExtractIcon_CreateInstance(this, apidl[0], riid, &pObj);
}
else if (IsEqualIID (riid, IID_IDropTarget))
{
/* only interested in attempting to bind to shell folders, not files (except exe), so if we fail, rebind to root */
if (cidl != 1 || FAILED(hr = this->_GetDropTarget(apidl[0], (LPVOID*) &pObj)))
{
- IDropTarget * pDt = NULL;
- hr = this->QueryInterface(IID_PPV_ARG(IDropTarget, &pDt));
- pObj = pDt;
+ hr = CFSDropTarget_CreateInstance(sPathTarget, riid, (LPVOID*) &pObj);
}
}
- else if ((IsEqualIID(riid, IID_IShellLinkW) ||
- IsEqualIID(riid, IID_IShellLinkA)) && (cidl == 1))
- {
- pidl = ILCombine (pidlRoot, apidl[0]);
- hr = IShellLink_ConstructFromFile(NULL, riid, pidl, (LPVOID*)&pObj);
- SHFree (pidl);
- }
else
hr = E_NOINTERFACE;
HRESULT WINAPI CFSFolder::GetDisplayNameOf(PCUITEMID_CHILD pidl,
DWORD dwFlags, LPSTRRET strRet)
{
- LPWSTR pszPath;
-
- HRESULT hr = S_OK;
- int len = 0;
-
- TRACE("(%p)->(pidl=%p,0x%08x,%p)\n", this, pidl, dwFlags, strRet);
- pdump(pidl);
-
- if (!pidl || !strRet)
+ if (!strRet)
return E_INVALIDARG;
- pszPath = (LPWSTR)CoTaskMemAlloc((MAX_PATH + 1) * sizeof(WCHAR));
- if (!pszPath)
- return E_OUTOFMEMORY;
-
- if (_ILIsDesktop(pidl)) /* empty pidl */
+ /* If it is a complex pidl, let the child handle it */
+ if (!_ILIsPidlSimple (pidl)) /* complex pidl */
{
- if ((GET_SHGDN_FOR(dwFlags) & SHGDN_FORPARSING) &&
- (GET_SHGDN_RELATION(dwFlags) != SHGDN_INFOLDER))
- {
- if (sPathTarget)
- lstrcpynW(pszPath, sPathTarget, MAX_PATH);
- }
- else
- hr = E_INVALIDARG; /* pidl has to contain exactly one non null SHITEMID */
+ return SHELL32_GetDisplayNameOfChild(this, pidl, dwFlags, strRet);
}
- else if (_ILIsPidlSimple(pidl))
+ else if (pidl && !pidl->mkid.cb) /* empty pidl */
{
- if ((GET_SHGDN_FOR(dwFlags) & SHGDN_FORPARSING) &&
- (GET_SHGDN_RELATION(dwFlags) != SHGDN_INFOLDER) &&
- sPathTarget)
+ /* If it is an empty pidl return only the path of the folder */
+ if ((GET_SHGDN_FOR(dwFlags) & SHGDN_FORPARSING) &&
+ (GET_SHGDN_RELATION(dwFlags) != SHGDN_INFOLDER) &&
+ sPathTarget)
{
- lstrcpynW(pszPath, sPathTarget, MAX_PATH);
- PathAddBackslashW(pszPath);
- len = wcslen(pszPath);
+ return SHSetStrRet(strRet, sPathTarget);
}
- _ILSimpleGetTextW(pidl, pszPath + len, MAX_PATH + 1 - len);
- if (!_ILIsFolder(pidl)) SHELL_FS_ProcessDisplayFilename(pszPath, dwFlags);
- } else
- hr = SHELL32_GetDisplayNameOfChild(this, pidl, dwFlags, pszPath, MAX_PATH);
+ return E_INVALIDARG;
+ }
+
+ int len = 0;
+ LPWSTR pszPath = (LPWSTR)CoTaskMemAlloc((MAX_PATH + 1) * sizeof(WCHAR));
+ if (!pszPath)
+ return E_OUTOFMEMORY;
- 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->cStr, MAX_PATH,
- NULL, NULL))
- strRet->cStr[0] = '\0';
- CoTaskMemFree(pszPath);
- }
- else
- {
- strRet->uType = STRRET_WSTR;
- strRet->pOleStr = pszPath;
- }
- } else
- CoTaskMemFree(pszPath);
+ if ((GET_SHGDN_FOR(dwFlags) & SHGDN_FORPARSING) &&
+ (GET_SHGDN_RELATION(dwFlags) != SHGDN_INFOLDER) &&
+ sPathTarget)
+ {
+ lstrcpynW(pszPath, sPathTarget, MAX_PATH);
+ PathAddBackslashW(pszPath);
+ len = wcslen(pszPath);
+ }
+ _ILSimpleGetTextW(pidl, pszPath + len, MAX_PATH + 1 - len);
+ if (!_ILIsFolder(pidl)) SHELL_FS_ProcessDisplayFilename(pszPath, dwFlags);
+
+ strRet->uType = STRRET_WSTR;
+ strRet->pOleStr = pszPath;
TRACE ("-- (%p)->(%s)\n", this, strRet->uType == STRRET_CSTR ? strRet->cStr : debugstr_w(strRet->pOleStr));
- return hr;
+ return S_OK;
}
/**************************************************************************
/* the header titles */
psd->fmt = GenericSFHeader[iColumn].fmt;
psd->cxChar = GenericSFHeader[iColumn].cxChar;
- psd->str.uType = STRRET_CSTR;
- LoadStringA(shell32_hInstance, GenericSFHeader[iColumn].colnameid,
- psd->str.cStr, MAX_PATH);
- return S_OK;
+ return SHSetStrRet(&psd->str, GenericSFHeader[iColumn].colnameid);
}
else
{
switch (iColumn)
{
case 0: /* name */
- hr = GetDisplayNameOf (pidl,
- SHGDN_NORMAL | SHGDN_INFOLDER, &psd->str);
+ hr = GetDisplayNameOf (pidl, SHGDN_NORMAL | SHGDN_INFOLDER, &psd->str);
break;
- case 1: /* size */
- _ILGetFileSize(pidl, psd->str.cStr, MAX_PATH);
+ case 1: /* FIXME: comments */
+ psd->str.cStr[0] = 0;
break;
case 2: /* type */
_ILGetFileType(pidl, psd->str.cStr, MAX_PATH);
break;
- case 3: /* date */
+ case 3: /* size */
+ _ILGetFileSize(pidl, psd->str.cStr, MAX_PATH);
+ break;
+ case 4: /* date */
_ILGetFileDate(pidl, psd->str.cStr, MAX_PATH);
break;
- case 4: /* attributes */
+ case 5: /* attributes */
_ILGetFileAttributes(pidl, psd->str.cStr, MAX_PATH);
break;
}
return E_NOTIMPL;
}
-/****************************************************************************
- * ISFHelper for IShellFolder implementation
- */
-
-/****************************************************************************
- * CFSFolder::GetUniqueName
- *
- * creates a unique folder name
+/************************************************************************
+ * CFSFolder::GetClassID
*/
-
-HRESULT WINAPI CFSFolder::GetUniqueName(LPWSTR pwszName, UINT uLen)
+HRESULT WINAPI CFSFolder::GetClassID(CLSID * lpClassId)
{
- CComPtr<IEnumIDList> penum;
- HRESULT hr;
- WCHAR wszText[MAX_PATH];
- WCHAR wszNewFolder[25];
- const WCHAR wszFormat[] = L"%s %d";
-
- LoadStringW(shell32_hInstance, IDS_NEWFOLDER, wszNewFolder, _countof(wszNewFolder));
-
- TRACE ("(%p)(%p %u)\n", this, pwszName, uLen);
+ TRACE ("(%p)\n", this);
- if (uLen < _countof(wszNewFolder) + 3)
- return E_POINTER;
-
- lstrcpynW (pwszName, wszNewFolder, uLen);
-
- hr = EnumObjects(0, SHCONTF_FOLDERS | SHCONTF_NONFOLDERS | SHCONTF_INCLUDEHIDDEN, &penum);
- if (penum)
- {
- LPITEMIDLIST pidl;
- DWORD dwFetched;
- int i = 1;
-
-next:
- penum->Reset ();
- while (S_OK == penum->Next(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;
- }
- }
- }
- return hr;
-}
-
-/****************************************************************************
- * CFSFolder::AddFolder
- *
- * adds a new folder.
- */
-
-HRESULT WINAPI CFSFolder::AddFolder(HWND hwnd, LPCWSTR pwszName,
- LPITEMIDLIST * ppidlOut)
-{
- WCHAR wszNewDir[MAX_PATH];
- DWORD bRes;
- HRESULT hres = E_FAIL;
-
- TRACE ("(%p)(%s %p)\n", this, debugstr_w(pwszName), ppidlOut);
-
- wszNewDir[0] = 0;
- if (sPathTarget)
- lstrcpynW(wszNewDir, sPathTarget, MAX_PATH);
- PathAppendW(wszNewDir, pwszName);
-
- bRes = CreateDirectoryW(wszNewDir, NULL);
- if (bRes)
- {
- SHChangeNotify(SHCNE_MKDIR, SHCNF_PATHW, wszNewDir, NULL);
-
- hres = S_OK;
-
- if (ppidlOut)
- hres = _ILCreateFromPathW(wszNewDir, ppidlOut);
- }
- else
- {
- WCHAR wszText[128 + MAX_PATH];
- WCHAR wszTempText[128];
- WCHAR wszCaption[256];
-
- /* Cannot Create folder because of permissions */
- LoadStringW(shell32_hInstance, IDS_CREATEFOLDER_DENIED, wszTempText,
- _countof(wszTempText));
- LoadStringW(shell32_hInstance, IDS_CREATEFOLDER_CAPTION, wszCaption,
- _countof(wszCaption));
- swprintf(wszText, wszTempText, wszNewDir);
- MessageBoxW(hwnd, wszText, wszCaption, MB_OK | MB_ICONEXCLAMATION);
- }
-
- return hres;
-}
-
-/****************************************************************************
- * BuildPathsList
- *
- * Builds a list of paths like the one used in SHFileOperation from a table of
- * PIDLs relative to the given base folder
- */
-WCHAR *
-BuildPathsList(LPCWSTR wszBasePath, int cidl, LPCITEMIDLIST *pidls)
-{
- WCHAR *pwszPathsList;
- WCHAR *pwszListPos;
- int iPathLen, i;
-
- iPathLen = wcslen(wszBasePath);
- pwszPathsList = (WCHAR *)HeapAlloc(GetProcessHeap(), 0, MAX_PATH * sizeof(WCHAR) * cidl + 1);
- pwszListPos = pwszPathsList;
-
- for (i = 0; i < cidl; i++)
- {
- if (!_ILIsFolder(pidls[i]) && !_ILIsValue(pidls[i]))
- continue;
-
- wcscpy(pwszListPos, wszBasePath);
- pwszListPos += iPathLen;
- /* FIXME: abort if path too long */
- _ILSimpleGetTextW(pidls[i], pwszListPos, MAX_PATH - iPathLen);
- pwszListPos += wcslen(pwszListPos) + 1;
- }
- *pwszListPos = 0;
- return pwszPathsList;
-}
-
-/****************************************************************************
- * CFSFolder::DeleteItems
- *
- * deletes items in folder
- */
-HRESULT WINAPI CFSFolder::DeleteItems(UINT cidl, LPCITEMIDLIST *apidl)
-{
- UINT i;
- SHFILEOPSTRUCTW op;
- WCHAR wszPath[MAX_PATH];
- WCHAR *wszPathsList;
- HRESULT ret;
- WCHAR *wszCurrentPath;
-
- TRACE ("(%p)(%u %p)\n", this, cidl, apidl);
- if (cidl == 0) return S_OK;
-
- if (sPathTarget)
- lstrcpynW(wszPath, sPathTarget, MAX_PATH);
- else
- wszPath[0] = '\0';
- PathAddBackslashW(wszPath);
- wszPathsList = BuildPathsList(wszPath, cidl, apidl);
-
- ZeroMemory(&op, sizeof(op));
- op.hwnd = GetActiveWindow();
- op.wFunc = FO_DELETE;
- op.pFrom = wszPathsList;
- op.fFlags = FOF_ALLOWUNDO;
- if (SHFileOperationW(&op))
- {
- WARN("SHFileOperation failed\n");
- ret = E_FAIL;
- }
- else
- ret = S_OK;
-
- /* we currently need to manually send the notifies */
- wszCurrentPath = wszPathsList;
- for (i = 0; i < cidl; i++)
- {
- LONG wEventId;
-
- if (_ILIsFolder(apidl[i]))
- wEventId = SHCNE_RMDIR;
- else if (_ILIsValue(apidl[i]))
- wEventId = SHCNE_DELETE;
- else
- continue;
-
- /* check if file exists */
- if (GetFileAttributesW(wszCurrentPath) == INVALID_FILE_ATTRIBUTES)
- {
- LPITEMIDLIST pidl = ILCombine(pidlRoot, apidl[i]);
- SHChangeNotify(wEventId, SHCNF_IDLIST, pidl, NULL);
- SHFree(pidl);
- }
-
- wszCurrentPath += wcslen(wszCurrentPath) + 1;
- }
- HeapFree(GetProcessHeap(), 0, wszPathsList);
- return ret;
-}
-
-/****************************************************************************
- * CFSFolder::CopyItems
- *
- * copies items to this folder
- */
-HRESULT WINAPI CFSFolder::CopyItems(IShellFolder * pSFFrom, UINT cidl,
- LPCITEMIDLIST * apidl, BOOL bCopy)
-{
- CComPtr<IPersistFolder2> ppf2 = NULL;
- WCHAR szSrcPath[MAX_PATH];
- WCHAR szTargetPath[MAX_PATH];
- SHFILEOPSTRUCTW op;
- LPITEMIDLIST pidl;
- LPWSTR pszSrc, pszTarget, pszSrcList, pszTargetList, pszFileName;
- int res, length;
- HRESULT hr;
- STRRET strRet;
-
- TRACE ("(%p)->(%p,%u,%p)\n", this, pSFFrom, cidl, apidl);
-
- hr = pSFFrom->QueryInterface (IID_PPV_ARG(IPersistFolder2, &ppf2));
- if (SUCCEEDED(hr))
- {
- hr = ppf2->GetCurFolder(&pidl);
- if (FAILED(hr))
- {
- return hr;
- }
-
- hr = pSFFrom->GetDisplayNameOf(pidl, SHGDN_FORPARSING, &strRet);
- if (FAILED(hr))
- {
- SHFree(pidl);
- return hr;
- }
-
- hr = StrRetToBufW(&strRet, pidl, szSrcPath, MAX_PATH);
- if (FAILED(hr))
- {
- SHFree(pidl);
- return hr;
- }
- SHFree(pidl);
-
- pszSrc = PathAddBackslashW(szSrcPath);
-
- wcscpy(szTargetPath, sPathTarget);
- pszTarget = PathAddBackslashW(szTargetPath);
-
- pszSrcList = BuildPathsList(szSrcPath, cidl, apidl);
- pszTargetList = BuildPathsList(szTargetPath, cidl, apidl);
-
- if (!pszSrcList || !pszTargetList)
- {
- if (pszSrcList)
- HeapFree(GetProcessHeap(), 0, pszSrcList);
-
- if (pszTargetList)
- HeapFree(GetProcessHeap(), 0, pszTargetList);
-
- SHFree(pidl);
- return E_OUTOFMEMORY;
- }
-
- ZeroMemory(&op, sizeof(op));
- if (!pszSrcList[0])
- {
- /* remove trailing backslash */
- pszSrc--;
- pszSrc[0] = L'\0';
- op.pFrom = szSrcPath;
- }
- else
- {
- op.pFrom = pszSrcList;
- }
-
- if (!pszTargetList[0])
- {
- /* remove trailing backslash */
- if (pszTarget - szTargetPath > 3)
- {
- pszTarget--;
- pszTarget[0] = L'\0';
- }
- else
- {
- pszTarget[1] = L'\0';
- }
-
- op.pTo = szTargetPath;
- op.fFlags = 0;
- }
- else
- {
- op.pTo = pszTargetList;
- op.fFlags = FOF_MULTIDESTFILES;
- }
- op.hwnd = GetActiveWindow();
- op.wFunc = bCopy ? FO_COPY : FO_MOVE;
- op.fFlags |= FOF_ALLOWUNDO | FOF_NOCONFIRMMKDIR;
-
- res = SHFileOperationW(&op);
-
- if (res == DE_SAMEFILE)
- {
- length = wcslen(szTargetPath);
-
- pszFileName = wcsrchr(pszSrcList, '\\');
- pszFileName++;
-
- if (LoadStringW(shell32_hInstance, IDS_COPY_OF, pszTarget, MAX_PATH - length))
- {
- wcscat(szTargetPath, L" ");
- }
-
- wcscat(szTargetPath, pszFileName);
- op.pTo = szTargetPath;
-
- res = SHFileOperationW(&op);
- }
-
- HeapFree(GetProcessHeap(), 0, pszSrcList);
- HeapFree(GetProcessHeap(), 0, pszTargetList);
-
- if (res)
- return E_FAIL;
- else
- return S_OK;
- }
- return E_FAIL;
-}
-
-/************************************************************************
- * CFSFolder::GetClassID
- */
-HRESULT WINAPI CFSFolder::GetClassID(CLSID * lpClassId)
-{
- TRACE ("(%p)\n", this);
-
- if (!lpClassId)
+ if (!lpClassId)
return E_POINTER;
*lpClassId = *pclsid;
return E_NOTIMPL;
}
-BOOL
-CFSFolder::GetUniqueFileName(LPWSTR pwszBasePath, LPCWSTR pwszExt, LPWSTR pwszTarget, BOOL bShortcut)
+HRESULT CFSFolder::_CreateExtensionUIObject(PCUIDLIST_RELATIVE pidl, REFIID riid, LPVOID *ppvOut)
{
- WCHAR wszLink[40];
+ static const WCHAR formatW[] = {'S','h','e','l','l','E','x','\\',
+ '{','%','0','8','x','-','%','0','4','x','-','%','0','4','x','-',
+ '%','0','2','x','%','0','2','x','-','%','0','2','x','%','0','2','x',
+ '%','0','2','x','%','0','2','x','%','0','2','x','%','0','2','x','}',0};
+ WCHAR buf[MAX_PATH];
- if (!bShortcut)
- {
- if (!LoadStringW(shell32_hInstance, IDS_LNK_FILE, wszLink, _countof(wszLink)))
- wszLink[0] = L'\0';
- }
+ sprintfW(buf, formatW, riid.Data1, riid.Data2, riid.Data3,
+ riid.Data4[0], riid.Data4[1], riid.Data4[2], riid.Data4[3],
+ riid.Data4[4], riid.Data4[5], riid.Data4[6], riid.Data4[7]);
- if (!bShortcut)
- swprintf(pwszTarget, L"%s%s%s", wszLink, pwszBasePath, pwszExt);
- else
- swprintf(pwszTarget, L"%s%s", pwszBasePath, pwszExt);
+ CLSID clsid;
+ HRESULT hr;
- for (UINT i = 2; PathFileExistsW(pwszTarget); ++i)
- {
- if (!bShortcut)
- swprintf(pwszTarget, L"%s%s (%u)%s", wszLink, pwszBasePath, i, pwszExt);
- else
- swprintf(pwszTarget, L"%s (%u)%s", pwszBasePath, i, pwszExt);
- }
+ hr = GetCLSIDForFileType(pidl, buf, &clsid);
+ if (hr != S_OK)
+ return hr;
+
+ hr = _CreateShellExtInstance(&clsid, pidl, riid, ppvOut);
+ if (FAILED_UNEXPECTEDLY(hr))
+ return hr;
- return TRUE;
+ return S_OK;
}
-/****************************************************************************
- * IDropTarget implementation
- */
-BOOL CFSFolder::QueryDrop(DWORD dwKeyState, LPDWORD pdwEffect)
+HRESULT CFSFolder::_GetDropTarget(LPCITEMIDLIST pidl, LPVOID *ppvOut)
{
- /* TODO Windows does different drop effects if dragging across drives.
- i.e., it will copy instead of move if the directories are on different disks. */
-
- DWORD dwEffect = DROPEFFECT_MOVE;
-
- *pdwEffect = DROPEFFECT_NONE;
+ HRESULT hr;
- if (fAcceptFmt) { /* Does our interpretation of the keystate ... */
- *pdwEffect = KeyStateToDropEffect (dwKeyState);
+ TRACE("CFSFolder::_GetDropTarget entered\n");
- if (*pdwEffect == DROPEFFECT_NONE)
- *pdwEffect = dwEffect;
+ if (_ILIsFolder (pidl))
+ {
+ CComPtr<IShellFolder> psfChild;
+ hr = this->BindToObject(pidl, NULL, IID_PPV_ARG(IShellFolder, &psfChild));
+ if (FAILED_UNEXPECTEDLY(hr))
+ return hr;
- /* ... matches the desired effect ? */
- if (dwEffect & *pdwEffect) {
- return TRUE;
- }
+ return psfChild->CreateViewObject(NULL, IID_IDropTarget, ppvOut);
}
- return FALSE;
-}
-
-HRESULT WINAPI CFSFolder::DragEnter(IDataObject *pDataObject,
- DWORD dwKeyState, POINTL pt, DWORD *pdwEffect)
-{
- TRACE("(%p)->(DataObject=%p)\n", this, pDataObject);
- FORMATETC fmt;
- FORMATETC fmt2;
- fAcceptFmt = FALSE;
- InitFormatEtc (fmt, cfShellIDList, TYMED_HGLOBAL);
- InitFormatEtc (fmt2, CF_HDROP, TYMED_HGLOBAL);
+ CLSID clsid;
+ hr = GetCLSIDForFileType(pidl, L"shellex\\DropHandler", &clsid);
+ if (hr != S_OK)
+ return hr;
- if (SUCCEEDED(pDataObject->QueryGetData(&fmt)))
- fAcceptFmt = TRUE;
- else if (SUCCEEDED(pDataObject->QueryGetData(&fmt2)))
- fAcceptFmt = TRUE;
+ hr = _CreateShellExtInstance(&clsid, pidl, IID_IDropTarget, ppvOut);
+ if (FAILED_UNEXPECTEDLY(hr))
+ return S_FALSE;
- QueryDrop(dwKeyState, pdwEffect);
return S_OK;
}
-HRESULT WINAPI CFSFolder::DragOver(DWORD dwKeyState, POINTL pt,
- DWORD *pdwEffect)
+HRESULT CFSFolder::_GetIconHandler(LPCITEMIDLIST pidl, REFIID riid, LPVOID *ppvOut)
{
- TRACE("(%p)\n", this);
-
- if (!pdwEffect)
- return E_INVALIDARG;
-
- QueryDrop(dwKeyState, pdwEffect);
-
- return S_OK;
-}
+ CLSID clsid;
+ HRESULT hr;
-HRESULT WINAPI CFSFolder::DragLeave()
-{
- TRACE("(%p)\n", this);
+ hr = GetCLSIDForFileType(pidl, L"shellex\\IconHandler", &clsid);
+ if (hr != S_OK)
+ return hr;
- fAcceptFmt = FALSE;
+ hr = _CreateShellExtInstance(&clsid, pidl, riid, ppvOut);
+ if (FAILED_UNEXPECTEDLY(hr))
+ return S_FALSE;
return S_OK;
}
-HRESULT WINAPI CFSFolder::Drop(IDataObject *pDataObject,
- DWORD dwKeyState, POINTL pt, DWORD *pdwEffect)
-{
- TRACE("(%p) object dropped, effect %u\n", this, *pdwEffect);
-
- BOOL fIsOpAsync = FALSE;
- CComPtr<IAsyncOperation> pAsyncOperation;
-
- if (SUCCEEDED(pDataObject->QueryInterface(IID_PPV_ARG(IAsyncOperation, &pAsyncOperation))))
- {
- if (SUCCEEDED(pAsyncOperation->GetAsyncMode(&fIsOpAsync)) && fIsOpAsync)
- {
- _DoDropData *data = static_cast<_DoDropData*>(HeapAlloc(GetProcessHeap(), 0, sizeof(_DoDropData)));
- data->This = this;
- // Need to maintain this class in case the window is closed or the class exists temporarily (when dropping onto a folder).
- pDataObject->AddRef();
- pAsyncOperation->StartOperation(NULL);
- CoMarshalInterThreadInterfaceInStream(IID_IDataObject, pDataObject, &data->pStream);
- this->AddRef();
- data->dwKeyState = dwKeyState;
- data->pt = pt;
- // Need to dereference as pdweffect gets freed.
- data->pdwEffect = *pdwEffect;
- SHCreateThread(CFSFolder::_DoDropThreadProc, data, NULL, NULL);
- return S_OK;
- }
- }
- return this->_DoDrop(pDataObject, dwKeyState, pt, pdwEffect);
-}
-
-HRESULT WINAPI CFSFolder::_DoDrop(IDataObject *pDataObject,
- DWORD dwKeyState, POINTL pt, DWORD *pdwEffect)
+HRESULT CFSFolder::_CreateShellExtInstance(const CLSID *pclsid, LPCITEMIDLIST pidl, REFIID riid, LPVOID *ppvOut)
{
- TRACE("(%p) performing drop, effect %u\n", this, *pdwEffect);
- FORMATETC fmt;
- FORMATETC fmt2;
- STGMEDIUM medium;
-
- InitFormatEtc (fmt, cfShellIDList, TYMED_HGLOBAL);
- InitFormatEtc (fmt2, CF_HDROP, TYMED_HGLOBAL);
-
HRESULT hr;
- bool bCopy = TRUE;
- bool bLinking = FALSE;
+ WCHAR wszPath[MAX_PATH];
- /* Figure out what drop operation we're doing */
- if (pdwEffect)
+ FileStructW* pDataW = _ILGetFileStructW(pidl);
+ if (!pDataW)
{
- TRACE("Current drop effect flag %i\n", *pdwEffect);
- if ((*pdwEffect & DROPEFFECT_MOVE) == DROPEFFECT_MOVE)
- bCopy = FALSE;
- if ((*pdwEffect & DROPEFFECT_LINK) == DROPEFFECT_LINK)
- bLinking = TRUE;
+ ERR("Got garbage pidl\n");
+ return E_INVALIDARG;
}
- if (SUCCEEDED(pDataObject->QueryGetData(&fmt)))
- {
- hr = pDataObject->GetData(&fmt, &medium);
- TRACE("CFSTR_SHELLIDLIST.\n");
-
- /* lock the handle */
- LPIDA lpcida = (LPIDA)GlobalLock(medium.hGlobal);
- if (!lpcida)
- {
- ReleaseStgMedium(&medium);
- return E_FAIL;
- }
-
- /* convert the data into pidl */
- LPITEMIDLIST pidl;
- LPITEMIDLIST *apidl = _ILCopyCidaToaPidl(&pidl, lpcida);
- if (!apidl)
- {
- ReleaseStgMedium(&medium);
- return E_FAIL;
- }
-
- CComPtr<IShellFolder> psfDesktop;
- CComPtr<IShellFolder> psfFrom = NULL;
- CComPtr<IShellFolder> psfTarget = NULL;
-
- hr = this->QueryInterface(IID_PPV_ARG(IShellFolder, &psfTarget));
- if (FAILED(hr))
- {
- ERR("psfTarget setting failed\n");
- SHFree(pidl);
- _ILFreeaPidl(apidl, lpcida->cidl);
- ReleaseStgMedium(&medium);
- return E_FAIL;
- }
-
- /* Grab the desktop shell folder */
- hr = SHGetDesktopFolder(&psfDesktop);
- if (FAILED(hr))
- {
- ERR("SHGetDesktopFolder failed\n");
- SHFree(pidl);
- _ILFreeaPidl(apidl, lpcida->cidl);
- ReleaseStgMedium(&medium);
- return E_FAIL;
- }
+ PathCombineW(wszPath, sPathTarget, pDataW->wszName);
- /* Find source folder, this is where the clipboard data was copied from */
- if (_ILIsDesktop(pidl))
- {
- /* use desktop shell folder */
- psfFrom = psfDesktop;
- }
- else
- {
- hr = psfDesktop->BindToObject(pidl, NULL, IID_PPV_ARG(IShellFolder, &psfFrom));
- if (FAILED(hr))
- {
- ERR("no IShellFolder\n");
- SHFree(pidl);
- _ILFreeaPidl(apidl, lpcida->cidl);
- ReleaseStgMedium(&medium);
- return E_FAIL;
- }
- }
-
- if (bLinking)
- {
- CComPtr<IPersistFolder2> ppf2 = NULL;
- STRRET strFile;
- WCHAR wszTargetPath[MAX_PATH];
- LPITEMIDLIST targetpidl;
- WCHAR wszPath[MAX_PATH];
- WCHAR wszTarget[MAX_PATH];
-
- hr = this->QueryInterface(IID_PPV_ARG(IPersistFolder2, &ppf2));
- if (SUCCEEDED(hr))
- {
- hr = ppf2->GetCurFolder(&targetpidl);
- if (SUCCEEDED(hr))
- {
- hr = psfDesktop->GetDisplayNameOf(targetpidl, SHGDN_FORPARSING, &strFile);
- ILFree(targetpidl);
- if (SUCCEEDED(hr))
- {
- hr = StrRetToBufW(&strFile, NULL, wszTargetPath, _countof(wszTargetPath));
- }
- }
- }
-
- if (FAILED(hr))
- {
- ERR("Error obtaining target path");
- }
-
- TRACE("target path = %s", debugstr_w(wszTargetPath));
-
- /* We need to create a link for each pidl in the copied items, so step through the pidls from the clipboard */
- for (UINT i = 0; i < lpcida->cidl; i++)
- {
- //Find out which file we're copying
- STRRET strFile;
- hr = psfFrom->GetDisplayNameOf(apidl[i], SHGDN_FORPARSING, &strFile);
- if (FAILED(hr))
- {
- ERR("Error source obtaining path");
- break;
- }
-
- hr = StrRetToBufW(&strFile, apidl[i], wszPath, _countof(wszPath));
- if (FAILED(hr))
- {
- ERR("Error putting source path into buffer");
- break;
- }
- TRACE("source path = %s", debugstr_w(wszPath));
-
- // Creating a buffer to hold the combined path
- WCHAR buffer_1[MAX_PATH] = L"";
- WCHAR *lpStr1;
- lpStr1 = buffer_1;
-
- LPWSTR pwszFileName = PathFindFileNameW(wszPath);
- LPWSTR pwszExt = PathFindExtensionW(wszPath);
- LPWSTR placementPath = PathCombineW(lpStr1, wszTargetPath, pwszFileName);
- CComPtr<IPersistFile> ppf;
+ CComPtr<IPersistFile> pp;
+ hr = SHCoCreateInstance(NULL, pclsid, NULL, IID_PPV_ARG(IPersistFile, &pp));
+ if (FAILED_UNEXPECTEDLY(hr))
+ return hr;
- //Check to see if it's already a link.
- if (!wcsicmp(pwszExt, L".lnk"))
- {
- //It's a link so, we create a new one which copies the old.
- if(!GetUniqueFileName(placementPath, pwszExt, wszTarget, TRUE))
- {
- ERR("Error getting unique file name");
- hr = E_FAIL;
- break;
- }
- hr = IShellLink_ConstructFromFile(NULL, IID_IPersistFile, ILCombine(pidl, apidl[i]), (LPVOID*)&ppf);
- if (FAILED(hr)) {
- ERR("Error constructing link from file");
- break;
- }
-
- hr = ppf->Save(wszTarget, FALSE);
- if (FAILED(hr))
- break;
- SHChangeNotify(SHCNE_CREATE, SHCNF_PATHW, wszTarget, NULL);
- }
- else
- {
- //It's not a link, so build a new link using the creator class and fill it in.
- //Create a file name for the link
- if (!GetUniqueFileName(placementPath, L".lnk", wszTarget, TRUE))
- {
- ERR("Error creating unique file name");
- hr = E_FAIL;
- break;
- }
-
- CComPtr<IShellLinkW> pLink;
- hr = CShellLink::_CreatorClass::CreateInstance(NULL, IID_PPV_ARG(IShellLinkW, &pLink));
- if (FAILED(hr)) {
- ERR("Error instantiating IShellLinkW");
- break;
- }
-
- WCHAR szDirPath[MAX_PATH], *pwszFile;
- GetFullPathName(wszPath, MAX_PATH, szDirPath, &pwszFile);
- if (pwszFile) pwszFile[0] = 0;
-
- hr = pLink->SetPath(wszPath);
- if(FAILED(hr))
- break;
-
- hr = pLink->SetWorkingDirectory(szDirPath);
- if(FAILED(hr))
- break;
-
- hr = pLink->QueryInterface(IID_PPV_ARG(IPersistFile, &ppf));
- if(FAILED(hr))
- break;
-
- hr = ppf->Save(wszTarget, TRUE);
- if (FAILED(hr))
- break;
- SHChangeNotify(SHCNE_CREATE, SHCNF_PATHW, wszTarget, NULL);
- }
- }
- }
- else
- {
- hr = this->CopyItems(psfFrom, lpcida->cidl, (LPCITEMIDLIST*)apidl, bCopy);
- }
+ pp->Load(wszPath, 0);
- SHFree(pidl);
- _ILFreeaPidl(apidl, lpcida->cidl);
- ReleaseStgMedium(&medium);
- }
- else if (SUCCEEDED(pDataObject->QueryGetData(&fmt2)))
+ hr = pp->QueryInterface(riid, ppvOut);
+ if (hr != S_OK)
{
- FORMATETC fmt2;
- InitFormatEtc (fmt2, CF_HDROP, TYMED_HGLOBAL);
- if (SUCCEEDED(pDataObject->GetData(&fmt2, &medium)) /* && SUCCEEDED(pDataObject->GetData(&fmt2, &medium))*/)
- {
- CComPtr<IPersistFolder2> ppf2 = NULL;
- STRRET strFile;
- WCHAR wszTargetPath[MAX_PATH + 1];
- LPWSTR pszSrcList;
- LPITEMIDLIST targetpidl;
- CComPtr<IShellFolder> psfDesktop = NULL;
- hr = SHGetDesktopFolder(&psfDesktop);
- if (FAILED(hr))
- {
- ERR("SHGetDesktopFolder failed\n");
- return E_FAIL;
- }
-
- hr = this->QueryInterface(IID_PPV_ARG(IPersistFolder2, &ppf2));
- if (SUCCEEDED(hr))
- {
- hr = ppf2->GetCurFolder(&targetpidl);
- if (SUCCEEDED(hr))
- {
- hr = psfDesktop->GetDisplayNameOf(targetpidl, SHGDN_FORPARSING, &strFile);
- ILFree(targetpidl);
- if (SUCCEEDED(hr))
- {
- hr = StrRetToBufW(&strFile, NULL, wszTargetPath, _countof(wszTargetPath));
- //Double NULL terminate.
- wszTargetPath[wcslen(wszTargetPath) + 1] = '\0';
- }
- }
- }
- if (FAILED(hr))
- {
- ERR("Error obtaining target path");
- return E_FAIL;
- }
-
- LPDROPFILES lpdf = (LPDROPFILES) GlobalLock(medium.hGlobal);
- if (!lpdf)
- {
- ERR("Error locking global\n");
- return E_FAIL;
- }
- pszSrcList = (LPWSTR) (((byte*) lpdf) + lpdf->pFiles);
- TRACE("Source file (just the first) = %s\n", debugstr_w(pszSrcList));
- TRACE("Target path = %s\n", debugstr_w(wszTargetPath));
-
- SHFILEOPSTRUCTW op;
- ZeroMemory(&op, sizeof(op));
- op.pFrom = pszSrcList;
- op.pTo = wszTargetPath;
- op.hwnd = GetActiveWindow();
- op.wFunc = bCopy ? FO_COPY : FO_MOVE;
- op.fFlags = FOF_ALLOWUNDO | FOF_NOCONFIRMMKDIR;
- hr = SHFileOperationW(&op);
- return hr;
- }
- ERR("Error calling GetData\n");
- hr = E_FAIL;
+ ERR("Failed to query for interface IID_IShellExtInit hr %x pclsid %s\n", hr, wine_dbgstr_guid(pclsid));
+ return hr;
}
- else
- {
- ERR("No viable drop format.\n");
- hr = E_FAIL;
- }
return hr;
}
-DWORD WINAPI CFSFolder::_DoDropThreadProc(LPVOID lpParameter) {
- CoInitialize(NULL);
- _DoDropData *data = static_cast<_DoDropData*>(lpParameter);
- CComPtr<IDataObject> pDataObject;
- HRESULT hr = CoGetInterfaceAndReleaseStream (data->pStream, IID_PPV_ARG(IDataObject, &pDataObject));
+HRESULT WINAPI CFSFolder::CallBack(IShellFolder *psf, HWND hwndOwner, IDataObject *pdtobj, UINT uMsg, WPARAM wParam, LPARAM lParam)
+{
+ if (uMsg != DFM_MERGECONTEXTMENU && uMsg != DFM_INVOKECOMMAND)
+ return S_OK;
- if (SUCCEEDED(hr))
+ /* no data object means no selection */
+ if (!pdtobj)
{
- CComPtr<IAsyncOperation> pAsyncOperation;
- hr = data->This->_DoDrop(pDataObject, data->dwKeyState, data->pt, &data->pdwEffect);
- if (SUCCEEDED(pDataObject->QueryInterface(IID_PPV_ARG(IAsyncOperation, &pAsyncOperation))))
+ if (uMsg == DFM_INVOKECOMMAND && wParam == 0)
{
- pAsyncOperation->EndOperation(hr, NULL, data->pdwEffect);
+ PUITEMID_CHILD pidlChild = ILClone(ILFindLastID(pidlRoot));
+ LPITEMIDLIST pidlParent = ILClone(pidlRoot);
+ ILRemoveLastID(pidlParent);
+ HRESULT hr = SH_ShowPropertiesDialog(sPathTarget, pidlParent, &pidlChild);
+ if (FAILED(hr))
+ ERR("SH_ShowPropertiesDialog failed\n");
+ ILFree(pidlChild);
+ ILFree(pidlParent);
}
- }
- //Release the CFSFolder and data object holds in the copying thread.
- data->This->Release();
- //Release the parameter from the heap.
- HeapFree(GetProcessHeap(), 0, data);
- CoUninitialize();
- return 0;
-}
-
-HRESULT WINAPI CFSFolder::_GetDropTarget(LPCITEMIDLIST pidl, LPVOID *ppvOut) {
- HKEY hKey;
- HRESULT hr;
-
- TRACE("CFSFolder::_GetDropTarget entered\n");
-
- if (_ILGetGUIDPointer (pidl) || _ILIsFolder (pidl))
- return this->BindToObject(pidl, NULL, IID_IDropTarget, ppvOut);
-
- STRRET strFile;
- hr = this->GetDisplayNameOf(pidl, SHGDN_FORPARSING, &strFile);
- if (hr == S_OK)
- {
- WCHAR wszPath[MAX_PATH];
- hr = StrRetToBufW(&strFile, pidl, wszPath, _countof(wszPath));
-
- if (hr == S_OK)
+ else if (uMsg == DFM_MERGECONTEXTMENU)
{
- LPCWSTR pwszExt = PathFindExtensionW(wszPath);
- if (pwszExt[0])
- {
- /* enumerate dynamic/static for a given file class */
- if (RegOpenKeyExW(HKEY_CLASSES_ROOT, pwszExt, 0, KEY_READ, &hKey) == ERROR_SUCCESS)
- {
- /* load dynamic extensions from file extension key, for example .jpg */
- _LoadDynamicDropTargetHandlerForKey(hKey, wszPath, ppvOut);
- RegCloseKey(hKey);
- }
-
- WCHAR wszTemp[40];
- DWORD dwSize = sizeof(wszTemp);
- if (RegGetValueW(HKEY_CLASSES_ROOT, pwszExt, NULL, RRF_RT_REG_SZ, NULL, wszTemp, &dwSize) == ERROR_SUCCESS)
- {
- if (RegOpenKeyExW(HKEY_CLASSES_ROOT, wszTemp, 0, KEY_READ, &hKey) == ERROR_SUCCESS)
- {
- /* load dynamic extensions from progid key, for example jpegfile */
- _LoadDynamicDropTargetHandlerForKey(hKey, wszPath, ppvOut);
- RegCloseKey(hKey);
- }
- }
- }
+ QCMINFO *pqcminfo = (QCMINFO *)lParam;
+ HMENU hpopup = CreatePopupMenu();
+ _InsertMenuItemW(hpopup, 0, TRUE, 0, MFT_STRING, MAKEINTRESOURCEW(IDS_PROPERTIES), MFS_ENABLED);
+ Shell_MergeMenus(pqcminfo->hmenu, hpopup, pqcminfo->indexMenu++, pqcminfo->idCmdFirst, pqcminfo->idCmdLast, MM_ADDSEPARATOR);
+ DestroyMenu(hpopup);
}
+
+ return S_OK;
}
- else
- ERR("GetDisplayNameOf failed: %x\n", hr);
- return hr;
-}
+ if (uMsg != DFM_INVOKECOMMAND || wParam != DFM_CMD_PROPERTIES)
+ return S_OK;
-HRESULT WINAPI CFSFolder::_LoadDynamicDropTargetHandlerForKey(HKEY hRootKey, LPCWSTR pwcsname, LPVOID *ppvOut)
-{
- TRACE("CFSFolder::_LoadDynamicDropTargetHandlerForKey entered\n");
+ PIDLIST_ABSOLUTE pidlFolder;
+ PUITEMID_CHILD *apidl;
+ UINT cidl;
+ HRESULT hr = SH_GetApidlFromDataObject(pdtobj, &pidlFolder, &apidl, &cidl);
+ if (FAILED_UNEXPECTEDLY(hr))
+ return hr;
- WCHAR wszName[MAX_PATH], *pwszClsid;
- DWORD dwSize = sizeof(wszName);
- HRESULT hr;
+ if (cidl > 1)
+ ERR("SHMultiFileProperties is not yet implemented\n");
- if (RegGetValueW(hRootKey, L"shellex\\DropHandler", NULL, RRF_RT_REG_SZ, NULL, wszName, &dwSize) == ERROR_SUCCESS)
+ STRRET strFile;
+ hr = GetDisplayNameOf(apidl[0], SHGDN_FORPARSING, &strFile);
+ if (SUCCEEDED(hr))
{
- CLSID clsid;
- hr = CLSIDFromString(wszName, &clsid);
- if (hr == S_OK)
- pwszClsid = wszName;
-
- if (m_bGroupPolicyActive)
- {
- if (RegGetValueW(HKEY_LOCAL_MACHINE,
- L"Software\\Microsoft\\Windows\\CurrentVersion\\Shell Extensions\\Approved",
- pwszClsid,
- RRF_RT_REG_SZ,
- NULL,
- NULL,
- NULL) == ERROR_SUCCESS)
- {
- hr = _LoadDynamicDropTargetHandler(&clsid, pwcsname, ppvOut);
- }
- }
- else
- {
- hr = _LoadDynamicDropTargetHandler(&clsid, pwcsname, ppvOut);
- }
+ hr = SH_ShowPropertiesDialog(strFile.pOleStr, pidlFolder, apidl);
+ if (FAILED(hr))
+ ERR("SH_ShowPropertiesDialog failed\n");
}
else
- return E_FAIL;
- return hr;
-}
-
-HRESULT WINAPI CFSFolder::_LoadDynamicDropTargetHandler(const CLSID *pclsid, LPCWSTR pwcsname, LPVOID *ppvOut)
-{
- TRACE("CFSFolder::_LoadDynamicDropTargetHandler entered\n");
- HRESULT hr;
-
- CComPtr<IPersistFile> pp;
- hr = SHCoCreateInstance(NULL, pclsid, NULL, IID_PPV_ARG(IPersistFile, &pp));
- if (hr != S_OK)
{
- ERR("SHCoCreateInstance failed %x\n", GetLastError());
+ ERR("Failed to get display name\n");
}
- pp->Load(pwcsname, 0);
- hr = pp->QueryInterface(IID_PPV_ARG(IDropTarget, (IDropTarget**) ppvOut));
- if (hr != S_OK)
- {
- ERR("Failed to query for interface IID_IShellExtInit hr %x pclsid %s\n", hr, wine_dbgstr_guid(pclsid));
- return hr;
- }
+ SHFree(pidlFolder);
+ _ILFreeaPidl(apidl, cidl);
+
return hr;
-}
\ No newline at end of file
+}