[SHELL32]

- Fix broken code in drive.cpp. Spotted by r3ddr4g0n.
- General code improvements
- Don't try to create static open handler in registry when file properties are opened. Fixes two "Open" items in shortcuts context menu after opening properties window.
See issue #6746 for more details.

svn path=/trunk/; revision=54722
This commit is contained in:
Rafal Harabien 2011-12-20 22:30:55 +00:00
parent 1aeee458ae
commit ec80415b49
4 changed files with 133 additions and 143 deletions

View file

@ -40,19 +40,16 @@ class CDefaultContextMenu :
public IContextMenu2 public IContextMenu2
{ {
private: private:
DEFCONTEXTMENU dcm; DEFCONTEXTMENU m_Dcm;
IDataObject *pDataObj; IDataObject *m_pDataObj;
DWORD bGroupPolicyActive; DWORD m_bGroupPolicyActive;
PDynamicShellEntry dhead; /* first dynamic shell extension entry */ PDynamicShellEntry m_pDynamicEntries; /* first dynamic shell extension entry */
UINT iIdSHEFirst; /* first used id */ UINT m_iIdSHEFirst; /* first used id */
UINT iIdSHELast; /* last used id */ UINT m_iIdSHELast; /* last used id */
PStaticShellEntry shead; /* first static shell extension entry */ PStaticShellEntry m_pStaticEntries; /* first static shell extension entry */
UINT iIdSCMFirst; /* first static used id */ UINT m_iIdSCMFirst; /* first static used id */
UINT iIdSCMLast; /* last static used id */ UINT m_iIdSCMLast; /* last static used id */
public:
CDefaultContextMenu();
~CDefaultContextMenu();
HRESULT WINAPI Initialize(const DEFCONTEXTMENU *pdcm);
void AddStaticEntry(const WCHAR *szVerb, const WCHAR *szClass); void AddStaticEntry(const WCHAR *szVerb, const WCHAR *szClass);
void AddStaticEntryForKey(HKEY hKey, const WCHAR *szClass); void AddStaticEntryForKey(HKEY hKey, const WCHAR *szClass);
void AddStaticEntryForFileClass(const WCHAR *szExt); void AddStaticEntryForFileClass(const WCHAR *szExt);
@ -74,6 +71,11 @@ class CDefaultContextMenu :
HRESULT DoDynamicShellExtensions(LPCMINVOKECOMMANDINFO lpcmi); HRESULT DoDynamicShellExtensions(LPCMINVOKECOMMANDINFO lpcmi);
HRESULT DoStaticShellExtensions(LPCMINVOKECOMMANDINFO lpcmi); HRESULT DoStaticShellExtensions(LPCMINVOKECOMMANDINFO lpcmi);
public:
CDefaultContextMenu();
~CDefaultContextMenu();
HRESULT WINAPI Initialize(const DEFCONTEXTMENU *pdcm);
// IContextMenu // IContextMenu
virtual HRESULT WINAPI QueryContextMenu(HMENU hMenu, UINT indexMenu, UINT idCmdFirst, UINT idCmdLast, UINT uFlags); virtual HRESULT WINAPI QueryContextMenu(HMENU hMenu, UINT indexMenu, UINT idCmdFirst, UINT idCmdLast, UINT uFlags);
virtual HRESULT WINAPI InvokeCommand(LPCMINVOKECOMMANDINFO lpcmi); virtual HRESULT WINAPI InvokeCommand(LPCMINVOKECOMMANDINFO lpcmi);
@ -90,15 +92,15 @@ class CDefaultContextMenu :
CDefaultContextMenu::CDefaultContextMenu() CDefaultContextMenu::CDefaultContextMenu()
{ {
memset (&dcm, 0, sizeof(dcm)); memset (&m_Dcm, 0, sizeof(m_Dcm));
pDataObj = NULL; m_pDataObj = NULL;
bGroupPolicyActive = 0; m_bGroupPolicyActive = 0;
dhead = NULL; m_pDynamicEntries = NULL;
iIdSHEFirst = 0; m_iIdSHEFirst = 0;
iIdSHELast = 0; m_iIdSHELast = 0;
shead = NULL; m_pStaticEntries = NULL;
iIdSCMFirst = 0; m_iIdSCMFirst = 0;
iIdSCMLast = 0; m_iIdSCMLast = 0;
} }
CDefaultContextMenu::~CDefaultContextMenu() CDefaultContextMenu::~CDefaultContextMenu()
@ -107,7 +109,7 @@ CDefaultContextMenu::~CDefaultContextMenu()
PStaticShellEntry sEntry, sNext; PStaticShellEntry sEntry, sNext;
/* free dynamic shell extension entries */ /* free dynamic shell extension entries */
dEntry = dhead; dEntry = m_pDynamicEntries;
while (dEntry) while (dEntry)
{ {
dNext = dEntry->Next; dNext = dEntry->Next;
@ -116,7 +118,7 @@ CDefaultContextMenu::~CDefaultContextMenu()
dEntry = dNext; dEntry = dNext;
} }
/* free static shell extension entries */ /* free static shell extension entries */
sEntry = shead; sEntry = m_pStaticEntries;
while (sEntry) while (sEntry)
{ {
sNext = sEntry->Next; sNext = sEntry->Next;
@ -129,12 +131,12 @@ CDefaultContextMenu::~CDefaultContextMenu()
HRESULT WINAPI CDefaultContextMenu::Initialize(const DEFCONTEXTMENU *pdcm) HRESULT WINAPI CDefaultContextMenu::Initialize(const DEFCONTEXTMENU *pdcm)
{ {
IDataObject *newDataObj; IDataObject *pDataObj;
TRACE("cidl %u\n", dcm.cidl); TRACE("cidl %u\n", pdcm->cidl);
if (SUCCEEDED(SHCreateDataObject(pdcm->pidlFolder, pdcm->cidl, pdcm->apidl, NULL, IID_IDataObject, (void**)&newDataObj))) if (SUCCEEDED(SHCreateDataObject(pdcm->pidlFolder, pdcm->cidl, pdcm->apidl, NULL, IID_IDataObject, (void**)&pDataObj)))
pDataObj = newDataObj; m_pDataObj = pDataObj;
CopyMemory(&dcm, pdcm, sizeof(DEFCONTEXTMENU)); CopyMemory(&m_Dcm, pdcm, sizeof(DEFCONTEXTMENU));
return S_OK; return S_OK;
} }
@ -144,7 +146,7 @@ CDefaultContextMenu::AddStaticEntry(const WCHAR *szVerb, const WCHAR *szClass)
PStaticShellEntry curEntry; PStaticShellEntry curEntry;
PStaticShellEntry lastEntry = NULL; PStaticShellEntry lastEntry = NULL;
curEntry = shead; curEntry = m_pStaticEntries;
while(curEntry) while(curEntry)
{ {
if (!wcsicmp(curEntry->szVerb, szVerb)) if (!wcsicmp(curEntry->szVerb, szVerb))
@ -173,33 +175,32 @@ CDefaultContextMenu::AddStaticEntry(const WCHAR *szVerb, const WCHAR *szClass)
if (!wcsicmp(szVerb, L"open")) if (!wcsicmp(szVerb, L"open"))
{ {
/* open verb is always inserted in front */ /* open verb is always inserted in front */
curEntry->Next = shead; curEntry->Next = m_pStaticEntries;
shead = curEntry; m_pStaticEntries = curEntry;
return;
} }
else if (lastEntry)
if (lastEntry)
lastEntry->Next = curEntry; lastEntry->Next = curEntry;
else else
shead = curEntry; m_pStaticEntries = curEntry;
} }
void void
CDefaultContextMenu::AddStaticEntryForKey(HKEY hKey, const WCHAR * szClass) CDefaultContextMenu::AddStaticEntryForKey(HKEY hKey, const WCHAR *pwszClass)
{ {
LONG result; LONG result;
DWORD dwIndex; DWORD dwIndex;
WCHAR szName[40]; WCHAR wszName[40];
DWORD dwSize; DWORD dwSize;
TRACE("AddStaticEntryForKey %x %ls\n", hKey, pwszClass);
dwIndex = 0; dwIndex = 0;
do do
{ {
szName[0] = 0; dwSize = sizeof(wszName) / sizeof(WCHAR);
dwSize = sizeof(szName) / sizeof(WCHAR); result = RegEnumKeyExW(hKey, dwIndex, wszName, &dwSize, NULL, NULL, NULL, NULL);
result = RegEnumKeyExW(hKey, dwIndex, szName, &dwSize, NULL, NULL, NULL, NULL);
if (result == ERROR_SUCCESS) if (result == ERROR_SUCCESS)
AddStaticEntry(szName, szClass); AddStaticEntry(wszName, pwszClass);
dwIndex++; dwIndex++;
} while(result == ERROR_SUCCESS); } while(result == ERROR_SUCCESS);
@ -316,7 +317,7 @@ DisablePasteOptions(HMENU hMenu)
BOOL BOOL
CDefaultContextMenu::IsShellExtensionAlreadyLoaded(const CLSID * szClass) CDefaultContextMenu::IsShellExtensionAlreadyLoaded(const CLSID * szClass)
{ {
PDynamicShellEntry curEntry = dhead; PDynamicShellEntry curEntry = m_pDynamicEntries;
while(curEntry) while(curEntry)
{ {
@ -361,7 +362,7 @@ CDefaultContextMenu::LoadDynamicContextMenuHandler(HKEY hKey, const CLSID *pClas
return hr; return hr;
} }
hr = shext->Initialize(NULL, pDataObj, hKey); hr = shext->Initialize(NULL, m_pDataObj, hKey);
shext->Release(); shext->Release();
if (hr != S_OK) if (hr != S_OK)
{ {
@ -384,9 +385,9 @@ CDefaultContextMenu::LoadDynamicContextMenuHandler(HKEY hKey, const CLSID *pClas
curEntry->CMenu = cmobj; curEntry->CMenu = cmobj;
memcpy(&curEntry->ClassID, pClass, sizeof(CLSID)); memcpy(&curEntry->ClassID, pClass, sizeof(CLSID));
if (dhead) if (m_pDynamicEntries)
{ {
PDynamicShellEntry pEntry = dhead; PDynamicShellEntry pEntry = m_pDynamicEntries;
while (pEntry->Next) while (pEntry->Next)
pEntry = pEntry->Next; pEntry = pEntry->Next;
@ -394,7 +395,7 @@ CDefaultContextMenu::LoadDynamicContextMenuHandler(HKEY hKey, const CLSID *pClas
pEntry->Next = curEntry; pEntry->Next = curEntry;
} }
else else
dhead = curEntry; m_pDynamicEntries = curEntry;
return hr; return hr;
} }
@ -436,7 +437,7 @@ CDefaultContextMenu::EnumerateDynamicContextHandlerForKey(HKEY hRootKey)
} }
if (SUCCEEDED(hResult)) if (SUCCEEDED(hResult))
{ {
if (bGroupPolicyActive) if (m_bGroupPolicyActive)
{ {
if (RegGetValueW(HKEY_LOCAL_MACHINE, if (RegGetValueW(HKEY_LOCAL_MACHINE,
L"Software\\Microsoft\\Windows\\CurrentVersion\\Shell Extensions\\Approved", L"Software\\Microsoft\\Windows\\CurrentVersion\\Shell Extensions\\Approved",
@ -468,17 +469,17 @@ CDefaultContextMenu::InsertMenuItemsOfDynamicContextMenuExtension(HMENU hMenu, U
PDynamicShellEntry curEntry; PDynamicShellEntry curEntry;
HRESULT hResult; HRESULT hResult;
if (!dhead) if (!m_pDynamicEntries)
{ {
iIdSHEFirst = 0; m_iIdSHEFirst = 0;
iIdSHELast = 0; m_iIdSHELast = 0;
return indexMenu; return indexMenu;
} }
curEntry = dhead; curEntry = m_pDynamicEntries;
idCmdFirst = 0x5000; idCmdFirst = 0x5000;
idCmdLast = 0x6000; idCmdLast = 0x6000;
iIdSHEFirst = idCmdFirst; m_iIdSHEFirst = idCmdFirst;
do do
{ {
hResult = curEntry->CMenu->QueryContextMenu(hMenu, indexMenu++, idCmdFirst, idCmdLast, CMF_NORMAL); hResult = curEntry->CMenu->QueryContextMenu(hMenu, indexMenu++, idCmdFirst, idCmdLast, CMF_NORMAL);
@ -493,8 +494,8 @@ CDefaultContextMenu::InsertMenuItemsOfDynamicContextMenuExtension(HMENU hMenu, U
curEntry = curEntry->Next; curEntry = curEntry->Next;
} while(curEntry); } while(curEntry);
iIdSHELast = idCmdFirst; m_iIdSHELast = idCmdFirst;
TRACE("SH_LoadContextMenuHandlers first %x last %x\n", iIdSHEFirst, iIdSHELast); TRACE("SH_LoadContextMenuHandlers first %x last %x\n", m_iIdSHEFirst, m_iIdSHELast);
return indexMenu; return indexMenu;
} }
@ -515,7 +516,7 @@ CDefaultContextMenu::BuildBackgroundContextMenu(
TRACE("BuildBackgroundContextMenu entered\n"); TRACE("BuildBackgroundContextMenu entered\n");
if (!_ILIsDesktop(dcm.pidlFolder)) if (!_ILIsDesktop(m_Dcm.pidlFolder))
{ {
/* view option is only available in browsing mode */ /* view option is only available in browsing mode */
hSubMenu = LoadMenuA(shell32_hInstance, "MENU_001"); hSubMenu = LoadMenuA(shell32_hInstance, "MENU_001");
@ -602,9 +603,9 @@ CDefaultContextMenu::AddStaticContextMenusToMenu(
mii.fState = MFS_ENABLED; mii.fState = MFS_ENABLED;
mii.wID = 0x4000; mii.wID = 0x4000;
mii.dwTypeData = NULL; mii.dwTypeData = NULL;
iIdSCMFirst = mii.wID; m_iIdSCMFirst = mii.wID;
curEntry = shead; curEntry = m_pStaticEntries;
while(curEntry) while(curEntry)
{ {
@ -666,7 +667,7 @@ CDefaultContextMenu::AddStaticContextMenusToMenu(
mii.wID++; mii.wID++;
curEntry = curEntry->Next; curEntry = curEntry->Next;
} }
iIdSCMLast = mii.wID - 1; m_iIdSCMLast = mii.wID - 1;
return indexMenu; return indexMenu;
} }
@ -738,10 +739,10 @@ CDefaultContextMenu::BuildShellItemContextMenu(
TRACE("BuildShellItemContextMenu entered\n"); TRACE("BuildShellItemContextMenu entered\n");
hr = dcm.psf->GetDisplayNameOf(dcm.apidl[0], SHGDN_FORPARSING, &strFile); hr = m_Dcm.psf->GetDisplayNameOf(m_Dcm.apidl[0], SHGDN_FORPARSING, &strFile);
if (hr == S_OK) if (hr == S_OK)
{ {
hr = StrRetToBufW(&strFile, dcm.apidl[0], szPath, MAX_PATH); hr = StrRetToBufW(&strFile, m_Dcm.apidl[0], szPath, MAX_PATH);
if (hr == S_OK) if (hr == S_OK)
{ {
pOffset = wcsrchr(szPath, L'.'); pOffset = wcsrchr(szPath, L'.');
@ -780,7 +781,7 @@ CDefaultContextMenu::BuildShellItemContextMenu(
else else
ERR("GetDisplayNameOf failed: %x\n", hr); ERR("GetDisplayNameOf failed: %x\n", hr);
guid = _ILGetGUIDPointer(dcm.apidl[0]); guid = _ILGetGUIDPointer(m_Dcm.apidl[0]);
if (guid) if (guid)
{ {
LPOLESTR pwszCLSID; LPOLESTR pwszCLSID;
@ -802,7 +803,7 @@ CDefaultContextMenu::BuildShellItemContextMenu(
} }
} }
if (_ILIsDrive(dcm.apidl[0])) if (_ILIsDrive(m_Dcm.apidl[0]))
{ {
AddStaticEntryForFileClass(L"Drive"); AddStaticEntryForFileClass(L"Drive");
if (RegOpenKeyExW(HKEY_CLASSES_ROOT, L"Drive", 0, KEY_READ, &hKey) == ERROR_SUCCESS) if (RegOpenKeyExW(HKEY_CLASSES_ROOT, L"Drive", 0, KEY_READ, &hKey) == ERROR_SUCCESS)
@ -815,14 +816,14 @@ CDefaultContextMenu::BuildShellItemContextMenu(
/* add static actions */ /* add static actions */
rfg = SFGAO_BROWSABLE | SFGAO_CANCOPY | SFGAO_CANLINK | SFGAO_CANMOVE | SFGAO_CANDELETE | SFGAO_CANRENAME | SFGAO_HASPROPSHEET | SFGAO_FILESYSTEM | SFGAO_FOLDER; rfg = SFGAO_BROWSABLE | SFGAO_CANCOPY | SFGAO_CANLINK | SFGAO_CANMOVE | SFGAO_CANDELETE | SFGAO_CANRENAME | SFGAO_HASPROPSHEET | SFGAO_FILESYSTEM | SFGAO_FOLDER;
hr = dcm.psf->GetAttributesOf(dcm.cidl, dcm.apidl, &rfg); hr = m_Dcm.psf->GetAttributesOf(m_Dcm.cidl, m_Dcm.apidl, &rfg);
if (FAILED(hr)) if (FAILED(hr))
{ {
ERR("GetAttributesOf failed: %x\n", hr); ERR("GetAttributesOf failed: %x\n", hr);
rfg = 0; rfg = 0;
} }
if ((rfg & SFGAO_FOLDER) || _ILIsControlPanel(dcm.apidl[dcm.cidl])) if ((rfg & SFGAO_FOLDER) || _ILIsControlPanel(m_Dcm.apidl[m_Dcm.cidl]))
{ {
/* add the default verbs open / explore */ /* add the default verbs open / explore */
AddStaticEntryForFileClass(L"Folder"); AddStaticEntryForFileClass(L"Folder");
@ -855,7 +856,7 @@ CDefaultContextMenu::BuildShellItemContextMenu(
indexMenu = InsertMenuItemsOfDynamicContextMenuExtension(hMenu, indexMenu, iIdCmdFirst, iIdCmdLast); indexMenu = InsertMenuItemsOfDynamicContextMenuExtension(hMenu, indexMenu, iIdCmdFirst, iIdCmdLast);
TRACE("indexMenu %d\n", indexMenu); TRACE("indexMenu %d\n", indexMenu);
if (_ILIsDrive(dcm.apidl[0])) if (_ILIsDrive(m_Dcm.apidl[0]))
{ {
/* The 'Format' option must be always available, /* The 'Format' option must be always available,
* thus it is not registered as a static shell extension * thus it is not registered as a static shell extension
@ -924,7 +925,7 @@ CDefaultContextMenu::QueryContextMenu(
UINT idCmdLast, UINT idCmdLast,
UINT uFlags) UINT uFlags)
{ {
if (dcm.cidl) if (m_Dcm.cidl)
{ {
idCmdFirst = BuildShellItemContextMenu(hmenu, idCmdFirst, idCmdLast, uFlags); idCmdFirst = BuildShellItemContextMenu(hmenu, idCmdFirst, idCmdLast, uFlags);
} }
@ -1033,10 +1034,10 @@ CDefaultContextMenu::DoPaste(
return E_FAIL; return E_FAIL;
} }
if (dcm.cidl) if (m_Dcm.cidl)
{ {
psfDesktop->Release(); psfDesktop->Release();
hr = dcm.psf->BindToObject(dcm.apidl[0], NULL, IID_IShellFolder, (LPVOID*)&psfTarget); hr = m_Dcm.psf->BindToObject(m_Dcm.apidl[0], NULL, IID_IShellFolder, (LPVOID*)&psfTarget);
} }
else else
{ {
@ -1044,7 +1045,7 @@ CDefaultContextMenu::DoPaste(
LPITEMIDLIST pidl; LPITEMIDLIST pidl;
/* cidl is zero due to explorer view */ /* cidl is zero due to explorer view */
hr = dcm.psf->QueryInterface(IID_IPersistFolder2, (LPVOID *) &ppf2); hr = m_Dcm.psf->QueryInterface(IID_IPersistFolder2, (LPVOID *) &ppf2);
if (SUCCEEDED(hr)) if (SUCCEEDED(hr))
{ {
hr = ppf2->GetCurFolder(&pidl); hr = ppf2->GetCurFolder(&pidl);
@ -1189,13 +1190,13 @@ CDefaultContextMenu::DoCreateLink(
IPersistFile * ipf; IPersistFile * ipf;
static WCHAR szLnk[] = L"lnk"; static WCHAR szLnk[] = L"lnk";
if (dcm.psf->GetDisplayNameOf(dcm.apidl[0], SHGDN_FORPARSING, &strFile) != S_OK) if (m_Dcm.psf->GetDisplayNameOf(m_Dcm.apidl[0], SHGDN_FORPARSING, &strFile) != S_OK)
{ {
ERR("IShellFolder_GetDisplayNameOf failed for apidl\n"); ERR("IShellFolder_GetDisplayNameOf failed for apidl\n");
return E_FAIL; return E_FAIL;
} }
if (StrRetToBufW(&strFile, dcm.apidl[0], szPath, MAX_PATH) != S_OK) if (StrRetToBufW(&strFile, m_Dcm.apidl[0], szPath, MAX_PATH) != S_OK)
return E_FAIL; return E_FAIL;
pszExt = wcsrchr(szPath, L'.'); pszExt = wcsrchr(szPath, L'.');
@ -1205,7 +1206,7 @@ CDefaultContextMenu::DoCreateLink(
if (!GetUniqueFileName(szPath, pszExt + 1, szTarget, TRUE)) if (!GetUniqueFileName(szPath, pszExt + 1, szTarget, TRUE))
return E_FAIL; return E_FAIL;
hr = IShellLink_ConstructFromFile(NULL, IID_IPersistFile, dcm.apidl[0], (LPVOID*)&ipf); hr = IShellLink_ConstructFromFile(NULL, IID_IPersistFile, m_Dcm.apidl[0], (LPVOID*)&ipf);
if (hr != S_OK) if (hr != S_OK)
return hr; return hr;
@ -1255,14 +1256,14 @@ CDefaultContextMenu::DoDelete(
HWND hwnd; HWND hwnd;
hr = dcm.psf->GetDisplayNameOf(dcm.apidl[0], SHGDN_FORPARSING, &strTemp); hr = m_Dcm.psf->GetDisplayNameOf(m_Dcm.apidl[0], SHGDN_FORPARSING, &strTemp);
if(hr != S_OK) if(hr != S_OK)
{ {
ERR("IShellFolder_GetDisplayNameOf failed with %x\n", hr); ERR("IShellFolder_GetDisplayNameOf failed with %x\n", hr);
return hr; return hr;
} }
ZeroMemory(szPath, sizeof(szPath)); ZeroMemory(szPath, sizeof(szPath));
hr = StrRetToBufW(&strTemp, dcm.apidl[0], szPath, MAX_PATH); hr = StrRetToBufW(&strTemp, m_Dcm.apidl[0], szPath, MAX_PATH);
if (hr != S_OK) if (hr != S_OK)
{ {
ERR("StrRetToBufW failed with %x\n", hr); ERR("StrRetToBufW failed with %x\n", hr);
@ -1276,7 +1277,7 @@ CDefaultContextMenu::DoDelete(
*(wszPos + 1) = '\0'; *(wszPos + 1) = '\0';
} }
wszPath = BuildPathsList(szPath, dcm.cidl, dcm.apidl); wszPath = BuildPathsList(szPath, m_Dcm.cidl, m_Dcm.apidl);
ZeroMemory(&op, sizeof(op)); ZeroMemory(&op, sizeof(op));
op.hwnd = GetActiveWindow(); op.hwnd = GetActiveWindow();
@ -1321,7 +1322,7 @@ CDefaultContextMenu::DoCopyOrCut(
LPDATAOBJECT pDataObj; LPDATAOBJECT pDataObj;
HRESULT hr; HRESULT hr;
if (SUCCEEDED(SHCreateDataObject(dcm.pidlFolder, dcm.cidl, dcm.apidl, NULL, IID_IDataObject, (void**)&pDataObj))) if (SUCCEEDED(SHCreateDataObject(m_Dcm.pidlFolder, m_Dcm.cidl, m_Dcm.apidl, NULL, IID_IDataObject, (void**)&pDataObj)))
{ {
hr = OleSetClipboard(pDataObj); hr = OleSetClipboard(pDataObj);
pDataObj->Release(); pDataObj->Release();
@ -1382,7 +1383,7 @@ CDefaultContextMenu::DoRename(
if(SUCCEEDED(lpSB->QueryActiveShellView(&lpSV))) if(SUCCEEDED(lpSB->QueryActiveShellView(&lpSV)))
{ {
lpSV->SelectItem(dcm.apidl[0], lpSV->SelectItem(m_Dcm.apidl[0],
SVSI_DESELECTOTHERS | SVSI_EDIT | SVSI_ENSUREVISIBLE | SVSI_FOCUSED | SVSI_SELECT); SVSI_DESELECTOTHERS | SVSI_EDIT | SVSI_ENSUREVISIBLE | SVSI_FOCUSED | SVSI_SELECT);
lpSV->Release(); lpSV->Release();
return S_OK; return S_OK;
@ -1398,23 +1399,23 @@ CDefaultContextMenu::DoProperties(
WCHAR szDrive[MAX_PATH]; WCHAR szDrive[MAX_PATH];
STRRET strFile; STRRET strFile;
if (dcm.cidl && _ILIsMyComputer(dcm.apidl[0])) if (m_Dcm.cidl && _ILIsMyComputer(m_Dcm.apidl[0]))
{ {
ShellExecuteW(lpcmi->hwnd, L"open", L"rundll32.exe shell32.dll,Control_RunDLL sysdm.cpl", NULL, NULL, SW_SHOWNORMAL); ShellExecuteW(lpcmi->hwnd, L"open", L"rundll32.exe shell32.dll,Control_RunDLL sysdm.cpl", NULL, NULL, SW_SHOWNORMAL);
return S_OK; return S_OK;
} }
else if (dcm.cidl == 0 && dcm.pidlFolder != NULL && _ILIsDesktop(dcm.pidlFolder)) else if (m_Dcm.cidl == 0 && m_Dcm.pidlFolder != NULL && _ILIsDesktop(m_Dcm.pidlFolder))
{ {
ShellExecuteW(lpcmi->hwnd, L"open", L"rundll32.exe shell32.dll,Control_RunDLL desk.cpl", NULL, NULL, SW_SHOWNORMAL); ShellExecuteW(lpcmi->hwnd, L"open", L"rundll32.exe shell32.dll,Control_RunDLL desk.cpl", NULL, NULL, SW_SHOWNORMAL);
return S_OK; return S_OK;
} }
else if (_ILIsDrive(dcm.apidl[0])) else if (_ILIsDrive(m_Dcm.apidl[0]))
{ {
ILGetDisplayName(dcm.apidl[0], szDrive); ILGetDisplayName(m_Dcm.apidl[0], szDrive);
SH_ShowDriveProperties(szDrive, dcm.pidlFolder, dcm.apidl); SH_ShowDriveProperties(szDrive, m_Dcm.pidlFolder, m_Dcm.apidl);
return S_OK; return S_OK;
} }
else if (_ILIsNetHood(dcm.apidl[0])) else if (_ILIsNetHood(m_Dcm.apidl[0]))
{ {
//FIXME path! //FIXME path!
ShellExecuteW(NULL, L"open", L"explorer.exe", ShellExecuteW(NULL, L"open", L"explorer.exe",
@ -1422,7 +1423,7 @@ CDefaultContextMenu::DoProperties(
NULL, SW_SHOWDEFAULT); NULL, SW_SHOWDEFAULT);
return S_OK; return S_OK;
} }
else if (_ILIsBitBucket(dcm.apidl[0])) else if (_ILIsBitBucket(m_Dcm.apidl[0]))
{ {
/* FIXME /* FIXME
* detect the drive path of bitbucket if appropiate * detect the drive path of bitbucket if appropiate
@ -1432,19 +1433,19 @@ CDefaultContextMenu::DoProperties(
return S_OK; return S_OK;
} }
if (dcm.cidl > 1) if (m_Dcm.cidl > 1)
WARN("SHMultiFileProperties is not yet implemented\n"); WARN("SHMultiFileProperties is not yet implemented\n");
if (dcm.psf->GetDisplayNameOf(dcm.apidl[0], SHGDN_FORPARSING, &strFile) != S_OK) if (m_Dcm.psf->GetDisplayNameOf(m_Dcm.apidl[0], SHGDN_FORPARSING, &strFile) != S_OK)
{ {
ERR("IShellFolder_GetDisplayNameOf failed for apidl\n"); ERR("IShellFolder_GetDisplayNameOf failed for apidl\n");
return E_FAIL; return E_FAIL;
} }
if (StrRetToBufW(&strFile, dcm.apidl[0], szDrive, MAX_PATH) != S_OK) if (StrRetToBufW(&strFile, m_Dcm.apidl[0], szDrive, MAX_PATH) != S_OK)
return E_FAIL; return E_FAIL;
return SH_ShowPropertiesDialog(szDrive, dcm.pidlFolder, dcm.apidl); return SH_ShowPropertiesDialog(szDrive, m_Dcm.pidlFolder, m_Dcm.apidl);
} }
HRESULT HRESULT
@ -1453,7 +1454,7 @@ CDefaultContextMenu::DoFormat(
{ {
char sDrive[5] = {0}; char sDrive[5] = {0};
if (!_ILGetDrive(dcm.apidl[0], sDrive, sizeof(sDrive))) if (!_ILGetDrive(m_Dcm.apidl[0], sDrive, sizeof(sDrive)))
{ {
ERR("pidl is not a drive\n"); ERR("pidl is not a drive\n");
return E_FAIL; return E_FAIL;
@ -1468,9 +1469,9 @@ CDefaultContextMenu::DoDynamicShellExtensions(
LPCMINVOKECOMMANDINFO lpcmi) LPCMINVOKECOMMANDINFO lpcmi)
{ {
UINT verb = LOWORD(lpcmi->lpVerb); UINT verb = LOWORD(lpcmi->lpVerb);
PDynamicShellEntry pCurrent = dhead; PDynamicShellEntry pCurrent = m_pDynamicEntries;
TRACE("verb %p first %x last %x", lpcmi->lpVerb, iIdSHEFirst, iIdSHELast); TRACE("verb %p first %x last %x", lpcmi->lpVerb, m_iIdSHEFirst, m_iIdSHELast);
while(pCurrent && verb > pCurrent->iIdCmdFirst + pCurrent->NumIds) while(pCurrent && verb > pCurrent->iIdCmdFirst + pCurrent->NumIds)
pCurrent = pCurrent->Next; pCurrent = pCurrent->Next;
@ -1497,8 +1498,8 @@ CDefaultContextMenu::DoStaticShellExtensions(
WCHAR szPath[MAX_PATH]; WCHAR szPath[MAX_PATH];
WCHAR szDir[MAX_PATH]; WCHAR szDir[MAX_PATH];
SHELLEXECUTEINFOW sei; SHELLEXECUTEINFOW sei;
PStaticShellEntry pCurrent = shead; PStaticShellEntry pCurrent = m_pStaticEntries;
int verb = LOWORD(lpcmi->lpVerb) - iIdSCMFirst; int verb = LOWORD(lpcmi->lpVerb) - m_iIdSCMFirst;
HRESULT hr; HRESULT hr;
while(pCurrent && verb-- > 0) while(pCurrent && verb-- > 0)
@ -1507,14 +1508,14 @@ CDefaultContextMenu::DoStaticShellExtensions(
if (verb > 0) if (verb > 0)
return E_FAIL; return E_FAIL;
hr = dcm.psf->GetDisplayNameOf(dcm.apidl[0], SHGDN_FORPARSING, &strFile); hr = m_Dcm.psf->GetDisplayNameOf(m_Dcm.apidl[0], SHGDN_FORPARSING, &strFile);
if (hr != S_OK) if (hr != S_OK)
{ {
ERR("IShellFolder_GetDisplayNameOf failed for apidl\n"); ERR("IShellFolder_GetDisplayNameOf failed for apidl\n");
return hr; return hr;
} }
hr = StrRetToBufW(&strFile, dcm.apidl[0], szPath, MAX_PATH); hr = StrRetToBufW(&strFile, m_Dcm.apidl[0], szPath, MAX_PATH);
if (hr != S_OK) if (hr != S_OK)
return hr; return hr;
@ -1574,17 +1575,17 @@ CDefaultContextMenu::InvokeCommand(
return DoFormat(lpcmi); return DoFormat(lpcmi);
} }
if (iIdSHEFirst && iIdSHELast) if (m_iIdSHEFirst && m_iIdSHELast)
{ {
if (LOWORD(lpcmi->lpVerb) >= iIdSHEFirst && LOWORD(lpcmi->lpVerb) <= iIdSHELast) if (LOWORD(lpcmi->lpVerb) >= m_iIdSHEFirst && LOWORD(lpcmi->lpVerb) <= m_iIdSHELast)
{ {
return DoDynamicShellExtensions(lpcmi); return DoDynamicShellExtensions(lpcmi);
} }
} }
if (iIdSCMFirst && iIdSCMLast) if (m_iIdSCMFirst && m_iIdSCMLast)
{ {
if (LOWORD(lpcmi->lpVerb) >= iIdSCMFirst && LOWORD(lpcmi->lpVerb) <= iIdSCMLast) if (LOWORD(lpcmi->lpVerb) >= m_iIdSCMFirst && LOWORD(lpcmi->lpVerb) <= m_iIdSCMLast)
{ {
return DoStaticShellExtensions(lpcmi); return DoStaticShellExtensions(lpcmi);
} }

View file

@ -107,23 +107,23 @@ static const GUID GUID_DEVCLASS_DISKDRIVE = {0x4d36e967L, 0xe325, 0x11ce, {0xbf,
static VOID static VOID
GetDriveNameWithLetter(LPWSTR szText, UINT cchTextMax, WCHAR Drive) GetDriveNameWithLetter(LPWSTR szText, UINT cchTextMax, WCHAR wchDrive)
{ {
WCHAR szDrive[] = L"C:\\"; WCHAR szDrive[] = L"C:\\";
DWORD dwMaxComp, dwFileSys, cchText = 0; DWORD dwMaxComp, dwFileSys, cchText = 0;
szDrive[0] = Drive; szDrive[0] = wchDrive;
if (GetVolumeInformationW(szDrive, szText, cchTextMax, NULL, &dwMaxComp, &dwFileSys, NULL, 0)) if (GetVolumeInformationW(szDrive, szText, cchTextMax, NULL, &dwMaxComp, &dwFileSys, NULL, 0))
{ {
cchText = wcslen(szText); cchText = wcslen(szText);
if (cchText == cchText) if (cchText == 0)
{ {
/* load default volume label */ /* load default volume label */
cchText = LoadStringW(shell32_hInstance, IDS_DRIVE_FIXED, &szText[cchTextMax+1], (sizeof(szText) / sizeof(WCHAR)) - cchTextMax - 2); cchText = LoadStringW(shell32_hInstance, IDS_DRIVE_FIXED, szText, cchTextMax);
} }
} }
StringCchPrintfW(szText + cchText, cchTextMax - cchText, L" (%c)", Drive); StringCchPrintfW(szText + cchText, cchTextMax - cchText, L" (%c)", wchDrive);
} }
static VOID static VOID

View file

@ -32,39 +32,30 @@ typedef struct _LANGANDCODEPAGE_
EXTERN_C HPSXA WINAPI SHCreatePropSheetExtArrayEx(HKEY hKey, LPCWSTR pszSubKey, UINT max_iface, IDataObject *pDataObj); EXTERN_C HPSXA WINAPI SHCreatePropSheetExtArrayEx(HKEY hKey, LPCWSTR pszSubKey, UINT max_iface, IDataObject *pDataObj);
static LONG SH_GetAssociatedApplication(WCHAR *fileext, WCHAR *wAssocApp) static LONG SH_GetAssociatedApplication(WCHAR *pwszFileExt, WCHAR *pwszAssocApp)
{ {
WCHAR wDataType[MAX_PATH] = {0}; WCHAR wszBuf[MAX_PATH] = {0};
HKEY hkey;
LONG result; LONG result;
DWORD dwLen = MAX_PATH * sizeof(WCHAR); DWORD dwSize = sizeof(wszBuf);
wAssocApp[0] = '\0'; result = RegGetValueW(HKEY_CLASSES_ROOT, pwszFileExt, L"", RRF_RT_REG_SZ, NULL, wszBuf, &dwSize);
RegCreateKeyExW(HKEY_CLASSES_ROOT, fileext, 0, NULL, 0, KEY_READ, NULL, &hkey, NULL);
result = RegQueryValueExW(hkey, L"", NULL, NULL, (LPBYTE)wDataType, &dwLen);
RegCloseKey(hkey);
if (result == ERROR_SUCCESS) if (result == ERROR_SUCCESS)
{ {
wcscat(wDataType, L"\\shell\\open\\command"); StringCbCat(wszBuf, sizeof(wszBuf), L"\\shell\\open\\command");
dwLen = MAX_PATH * sizeof(WCHAR); dwSize = MAX_PATH * sizeof(WCHAR);
RegCreateKeyExW(HKEY_CLASSES_ROOT, wDataType, 0, NULL, 0, KEY_READ, NULL, &hkey, NULL); result = RegGetValueW(HKEY_CLASSES_ROOT, wszBuf, L"", RRF_RT_REG_SZ, NULL, pwszAssocApp, &dwSize);
result = (RegQueryValueExW(hkey, NULL, NULL, NULL, (LPBYTE)wAssocApp, &dwLen));
RegCloseKey(hkey);
if (result != ERROR_SUCCESS)
{
/* FIXME: Make it return full path instead of /* FIXME: Make it return full path instead of
notepad.exe "%1" notepad.exe "%1"
%systemroot%\notepad.exe "%1" %systemroot%\notepad.exe "%1"
etc etc
Maybe there is code to do that somewhere? Maybe there is code to do that somewhere?
dll\win32\shell32\shlexec.c for example? dll\win32\shell32\shlexec.c for example? */
*/
wAssocApp[0] = '\0';
}
} }
if (result != ERROR_SUCCESS)
pwszAssocApp[0] = '\0';
return result; return result;
} }

View file

@ -1810,36 +1810,34 @@ HRESULT WINAPI CShellLink::Initialize(LPCITEMIDLIST pidlFolder, IDataObject *pdt
return r; return r;
} }
HRESULT WINAPI CShellLink::QueryContextMenu(HMENU hmenu, UINT indexMenu, UINT idCmdFirst, UINT idCmdLast, UINT uFlags) HRESULT WINAPI CShellLink::QueryContextMenu(HMENU hMenu, UINT indexMenu, UINT idCmdFirst, UINT idCmdLast, UINT uFlags)
{ {
WCHAR szOpen[20]; WCHAR wszOpen[20];
MENUITEMINFOW mii; MENUITEMINFOW mii;
int id = 1; int id = 1;
TRACE("%p %p %u %u %u %u\n", this, TRACE("%p %p %u %u %u %u\n", this,
hmenu, indexMenu, idCmdFirst, idCmdLast, uFlags ); hMenu, indexMenu, idCmdFirst, idCmdLast, uFlags );
if ( !hmenu ) if (!hMenu)
return E_INVALIDARG; return E_INVALIDARG;
if (!LoadStringW(shell32_hInstance, IDS_OPEN_VERB, szOpen, sizeof(szOpen)/sizeof(WCHAR))) if (!LoadStringW(shell32_hInstance, IDS_OPEN_VERB, wszOpen, sizeof(wszOpen)/sizeof(WCHAR)))
szOpen[0] = L'\0'; wszOpen[0] = L'\0';
else
szOpen[(sizeof(szOpen)/sizeof(WCHAR))-1] = L'\0';
memset( &mii, 0, sizeof(mii) ); memset( &mii, 0, sizeof(mii) );
mii.cbSize = sizeof (mii); mii.cbSize = sizeof (mii);
mii.fMask = MIIM_TYPE | MIIM_ID | MIIM_STATE; mii.fMask = MIIM_TYPE | MIIM_ID | MIIM_STATE;
mii.dwTypeData = (LPWSTR)szOpen; mii.dwTypeData = wszOpen;
mii.cch = wcslen( mii.dwTypeData ); mii.cch = wcslen(mii.dwTypeData);
mii.wID = idCmdFirst + id++; mii.wID = idCmdFirst + id++;
mii.fState = MFS_DEFAULT | MFS_ENABLED; mii.fState = MFS_DEFAULT | MFS_ENABLED;
mii.fType = MFT_STRING; mii.fType = MFT_STRING;
if (!InsertMenuItemW( hmenu, indexMenu, TRUE, &mii )) if (!InsertMenuItemW(hMenu, indexMenu, TRUE, &mii))
return E_FAIL; return E_FAIL;
iIdOpen = 1; iIdOpen = 1;
return MAKE_HRESULT( SEVERITY_SUCCESS, 0, id ); return MAKE_HRESULT(SEVERITY_SUCCESS, 0, id);
} }
static LPWSTR static LPWSTR