WINE_DEFAULT_DEBUG_CHANNEL (shell);
+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!
+ CHAR sTemp[MAX_PATH] = "";
+ 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
+ {
+ BOOL found = FALSE;
+
+ if (_ILGetExtension(pidl, sTemp, _countof(sTemp)))
+ {
+ if (HCR_MapTypeToValueA(sTemp, sTemp, _countof(sTemp), TRUE)
+ && HCR_GetIconA(sTemp, sTemp, NULL, _countof(sTemp), &icon_idx))
+ {
+ if (!lstrcmpA("%1", sTemp)) /* icon is in the file */
+ {
+ ILGetDisplayNameExW(psf, pidl, wTemp, 0);
+ icon_idx = 0;
+ }
+ else
+ {
+ MultiByteToWideChar(CP_ACP, 0, sTemp, -1, wTemp, _countof(wTemp));
+ }
+
+ found = TRUE;
+ }
+ else if (!lstrcmpiA(sTemp, "lnkfile"))
+ {
+ /* extract icon from shell shortcut */
+ CComPtr<IShellLinkW> psl;
+ CComPtr<IExtractIconW> pei;
+
+ HRESULT hr = psf->GetUIObjectOf(NULL, 1, &pidl, IID_NULL_PPV_ARG(IShellLinkW, &psl));
+ if (SUCCEEDED(hr))
+ {
+ hr = psl->GetIconLocation(wTemp, _countof(wTemp), &icon_idx);
+ if (FAILED(hr) || !*wTemp)
+ {
+ /* The icon was not found directly, try to retrieve it from the shell link target */
+ hr = psl->QueryInterface(IID_PPV_ARG(IExtractIconW, &pei));
+ if (FAILED(hr) || !pei)
+ TRACE("No IExtractIconW interface!\n");
+ else
+ hr = pei->GetIconLocation(GIL_FORSHELL, wTemp, _countof(wTemp), &icon_idx, &flags);
+ }
+
+ if (SUCCEEDED(hr) && *wTemp)
+ found = TRUE;
+ }
+ }
+ }
+
+ /* FIXME: We should normally use the correct icon format according to 'flags' */
+ if (!found)
+ /* default icon */
+ initIcon->SetNormalIcon(swShell32Name, 0);
+ else
+ initIcon->SetNormalIcon(wTemp, icon_idx);
+ }
+
+ 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 };
+
+ 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);
+ }
+
+ return succeeded;
}
CFSFolder::CFSFolder()
static const shvheader GenericSFHeader[] = {
- {IDS_SHV_COLUMN1, SHCOLSTATE_TYPE_STR | SHCOLSTATE_ONBYDEFAULT, LVCFMT_LEFT, 15},
- {IDS_SHV_COLUMN2, SHCOLSTATE_TYPE_STR | SHCOLSTATE_ONBYDEFAULT, LVCFMT_RIGHT, 10},
- {IDS_SHV_COLUMN3, SHCOLSTATE_TYPE_STR | SHCOLSTATE_ONBYDEFAULT, LVCFMT_LEFT, 10},
- {IDS_SHV_COLUMN4, SHCOLSTATE_TYPE_DATE | SHCOLSTATE_ONBYDEFAULT, LVCFMT_LEFT, 12},
- {IDS_SHV_COLUMN5, SHCOLSTATE_TYPE_STR | SHCOLSTATE_ONBYDEFAULT, LVCFMT_LEFT, 10}
+ {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}
*
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_BindToFS(pidlRoot, sPathTarget, pidl, riid, ppvOut);
+ CComPtr<IShellFolder> pSF;
+ HRESULT hr;
+
+ if (!pidlRoot || !ppvOut || !pidl || !pidl->mkid.cb)
+ return E_INVALIDARG;
+
+ if (_ILIsValue(pidl))
+ {
+ ERR("Binding to file is unimplemented\n");
+ return HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND);
+ }
+ if (!_ILIsFolder(pidl))
+ {
+ ERR("Got an unknown type of pidl!\n");
+ return E_FAIL;
+ }
+
+ *ppvOut = NULL;
+
+ /* Get the pidl data */
+ FileStruct* pData = &_ILGetDataPointer(pidl)->u.file;
+ FileStructW* pDataW = _ILGetFileStructW(pidl);
+
+ /* 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 = CLSID_ShellFSFolder;
+ if ((pData->uFileAttribs & (FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_READONLY)) != 0)
+ SHELL32_GetCLSIDForDirectory(pfti.szTargetParsingName, &clsidFolder);
+
+ 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;
+
}
/**************************************************************************
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 1: /* Size */
+ case 3: /* Size */
result = pData1->u.file.dwFileSize - pData2->u.file.dwFileSize;
break;
- case 3: /* Modified */
+ 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 4: /* Attributes */
+ case 5: /* Attributes */
return SHELL32_CompareDetails(this, lParam, pidl1, pidl2);
}
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);
}
else
{
- hr = IDataObject_Constructor (hwndOwner, pidlRoot, (LPCITEMIDLIST*)&pidlRoot, 1, (IDataObject **)&pObj);
+ hr = E_INVALIDARG;
}
}
else if ((IsEqualIID (riid, IID_IExtractIconA) || IsEqualIID (riid, IID_IExtractIconW)) && (cidl == 1))
HRESULT WINAPI CFSFolder::GetDisplayNameOf(PCUITEMID_CHILD pidl,
DWORD dwFlags, LPSTRRET strRet)
{
- if (!pidl || !strRet)
+ if (!strRet)
return E_INVALIDARG;
/* If it is a complex pidl, let the child handle it */
{
return SHELL32_GetDisplayNameOfChild(this, pidl, dwFlags, strRet);
}
- else if (!pidl->mkid.cb) /* empty pidl */
+ else if (pidl && !pidl->mkid.cb) /* empty pidl */
{
/* If it is an empty pidl return only the path of the folder */
if ((GET_SHGDN_FOR(dwFlags) & SHGDN_FORPARSING) &&
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;
}
{
TRACE("CFSFolder::_LoadDynamicDropTargetHandlerForKey entered\n");
- WCHAR wszName[MAX_PATH], *pwszClsid;
+ WCHAR wszName[MAX_PATH];
DWORD dwSize = sizeof(wszName);
HRESULT hr;
+ LRESULT res;
- if (RegGetValueW(hRootKey, L"shellex\\DropHandler", NULL, RRF_RT_REG_SZ, NULL, wszName, &dwSize) == ERROR_SUCCESS)
- {
- CLSID clsid;
- hr = CLSIDFromString(wszName, &clsid);
- if (hr == S_OK)
- pwszClsid = wszName;
+ res = RegGetValueW(hRootKey, L"shellex\\DropHandler", NULL, RRF_RT_REG_SZ, NULL, wszName, &dwSize);
+ if (res != ERROR_SUCCESS)
+ return S_FALSE;
- 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
+ CLSID clsid;
+ hr = CLSIDFromString(wszName, &clsid);
+ if (FAILED_UNEXPECTEDLY(hr))
+ return hr;
+
+ if (m_bGroupPolicyActive)
+ {
+ res = RegGetValueW(HKEY_LOCAL_MACHINE,
+ L"Software\\Microsoft\\Windows\\CurrentVersion\\Shell Extensions\\Approved",
+ wszName,
+ RRF_RT_REG_SZ,
+ NULL,
+ NULL,
+ NULL);
+ if (res != ERROR_SUCCESS)
{
- hr = _LoadDynamicDropTargetHandler(&clsid, pwcsname, ppvOut);
+ ERR("DropHandler extension %S not approved\n", wszName);
+ return E_FAIL;
}
}
- else
- return E_FAIL;
- return hr;
+
+ hr = _LoadDynamicDropTargetHandler(&clsid, pwcsname, ppvOut);
+ if (FAILED_UNEXPECTEDLY(hr))
+ return hr;
+
+ return S_OK;
}
HRESULT WINAPI CFSFolder::_LoadDynamicDropTargetHandler(const CLSID *pclsid, LPCWSTR pwcsname, LPVOID *ppvOut)
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;
+
+ /* no data object means no selection */
+ if (!pdtobj)
+ {
+ if (uMsg == DFM_INVOKECOMMAND && wParam == DFM_CMD_PROPERTIES)
+ {
+ 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);
+ }
+ else if (uMsg == DFM_MERGECONTEXTMENU)
+ {
+ QCMINFO *pqcminfo = (QCMINFO *)lParam;
+ _InsertMenuItemW(pqcminfo->hmenu, pqcminfo->indexMenu++, TRUE, 0, MFT_SEPARATOR, NULL, 0);
+ _InsertMenuItemW(pqcminfo->hmenu, pqcminfo->indexMenu++, TRUE, FCIDM_SHVIEW_PROPERTIES, MFT_STRING, MAKEINTRESOURCEW(IDS_PROPERTIES), MFS_ENABLED);
+ }
+
+ return S_OK;
+ }
+
if (uMsg != DFM_INVOKECOMMAND || wParam != DFM_CMD_PROPERTIES)
return S_OK;