Author: rharabien Date: Sun Jan 15 19:45:02 2012 New Revision: 54979
URL: http://svn.reactos.org/svn/reactos?rev=54979&view=rev Log: [SHELL32] - Improve code readability in defcontextmenu.cpp - Fix few leaks - Properly handle reference count when creating objects
Modified: trunk/reactos/dll/win32/shell32/defcontextmenu.cpp trunk/reactos/dll/win32/shell32/drive.cpp trunk/reactos/dll/win32/shell32/fprop.cpp
Modified: trunk/reactos/dll/win32/shell32/defcontextmenu.cpp URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/shell32/defcontex... ============================================================================== --- trunk/reactos/dll/win32/shell32/defcontextmenu.cpp [iso-8859-1] (original) +++ trunk/reactos/dll/win32/shell32/defcontextmenu.cpp [iso-8859-1] Sun Jan 15 19:45:02 2012 @@ -24,15 +24,15 @@ UINT iIdCmdFirst; UINT NumIds; CLSID ClassID; - IContextMenu *CMenu; - struct _DynamicShellEntry_ *Next; + IContextMenu *pCM; + struct _DynamicShellEntry_ *pNext; } DynamicShellEntry, *PDynamicShellEntry;
typedef struct _StaticShellEntry_ { LPWSTR szVerb; LPWSTR szClass; - struct _StaticShellEntry_ *Next; + struct _StaticShellEntry_ *pNext; } StaticShellEntry, *PStaticShellEntry;
class CDefaultContextMenu : @@ -51,15 +51,15 @@ UINT m_iIdSCMFirst; /* first static used id */ UINT m_iIdSCMLast; /* last static used id */
- void AddStaticEntry(const WCHAR *szVerb, const WCHAR *szClass); - void AddStaticEntryForKey(HKEY hKey, const WCHAR *szClass); - void AddStaticEntryForFileClass(const WCHAR *szExt); - BOOL IsShellExtensionAlreadyLoaded(const CLSID *szClass); - HRESULT LoadDynamicContextMenuHandler(HKEY hKey, const CLSID *szClass, BOOL bExternalInit); - UINT EnumerateDynamicContextHandlerForKey(HKEY hRootKey); - UINT InsertMenuItemsOfDynamicContextMenuExtension(HMENU hMenu, UINT indexMenu, UINT idCmdFirst, UINT idCmdLast); + void AddStaticEntry(LPCWSTR pwszVerb, LPCWSTR pwszClass); + void AddStaticEntryForKey(HKEY hKey, LPCWSTR pwszClass); + void AddStaticEntryForFileClass(LPCWSTR pwszExt); + BOOL IsShellExtensionAlreadyLoaded(const CLSID *pclsid); + HRESULT LoadDynamicContextMenuHandler(HKEY hKey, const CLSID *pclsid); + BOOL EnumerateDynamicContextHandlerForKey(HKEY hRootKey); + UINT InsertMenuItemsOfDynamicContextMenuExtension(HMENU hMenu, UINT IndexMenu, UINT idCmdFirst, UINT idCmdLast); UINT BuildBackgroundContextMenu(HMENU hMenu, UINT iIdCmdFirst, UINT iIdCmdLast, UINT uFlags); - UINT AddStaticContextMenusToMenu(HMENU hMenu, UINT indexMenu); + UINT AddStaticContextMenusToMenu(HMENU hMenu, UINT IndexMenu); UINT BuildShellItemContextMenu(HMENU hMenu, UINT iIdCmdFirst, UINT iIdCmdLast, UINT uFlags); HRESULT DoPaste(LPCMINVOKECOMMANDINFO lpcmi); HRESULT DoOpenOrExplore(LPCMINVOKECOMMANDINFO lpcmi); @@ -107,28 +107,25 @@
CDefaultContextMenu::~CDefaultContextMenu() { - PDynamicShellEntry dEntry, dNext; - PStaticShellEntry sEntry, sNext; - /* Free dynamic shell extension entries */ - dEntry = m_pDynamicEntries; - while (dEntry) - { - dNext = dEntry->Next; - dEntry->CMenu->Release(); - HeapFree(GetProcessHeap(), 0, dEntry); - dEntry = dNext; + PDynamicShellEntry pDynamicEntry = m_pDynamicEntries, pNextDynamic; + while (pDynamicEntry) + { + pNextDynamic = pDynamicEntry->pNext; + pDynamicEntry->pCM->Release(); + HeapFree(GetProcessHeap(), 0, pDynamicEntry); + pDynamicEntry = pNextDynamic; }
/* Free static shell extension entries */ - sEntry = m_pStaticEntries; - while (sEntry) - { - sNext = sEntry->Next; - HeapFree(GetProcessHeap(), 0, sEntry->szClass); - HeapFree(GetProcessHeap(), 0, sEntry->szVerb); - HeapFree(GetProcessHeap(), 0, sEntry); - sEntry = sNext; + PStaticShellEntry pStaticEntry = m_pStaticEntries, pNextStatic; + while (pStaticEntry) + { + pNextStatic = pStaticEntry->pNext; + HeapFree(GetProcessHeap(), 0, pStaticEntry->szClass); + HeapFree(GetProcessHeap(), 0, pStaticEntry->szVerb); + HeapFree(GetProcessHeap(), 0, pStaticEntry); + pStaticEntry = pNextStatic; }
if (m_pidlFolder) @@ -170,67 +167,60 @@ void CDefaultContextMenu::AddStaticEntry(const WCHAR *szVerb, const WCHAR *szClass) { - PStaticShellEntry curEntry; - PStaticShellEntry lastEntry = NULL; - - curEntry = m_pStaticEntries; - while(curEntry) - { - if (!wcsicmp(curEntry->szVerb, szVerb)) + PStaticShellEntry pEntry = m_pStaticEntries, pLastEntry = NULL; + while(pEntry) + { + if (!wcsicmp(pEntry->szVerb, szVerb)) { /* entry already exists */ return; } - lastEntry = curEntry; - curEntry = curEntry->Next; + pLastEntry = pEntry; + pEntry = pEntry->pNext; }
TRACE("adding verb %s szClass %s\n", debugstr_w(szVerb), debugstr_w(szClass));
- curEntry = (StaticShellEntry *)HeapAlloc(GetProcessHeap(), 0, sizeof(StaticShellEntry)); - if (curEntry) - { - curEntry->Next = NULL; - curEntry->szVerb = (LPWSTR)HeapAlloc(GetProcessHeap(), 0, (wcslen(szVerb) + 1) * sizeof(WCHAR)); - if (curEntry->szVerb) - wcscpy(curEntry->szVerb, szVerb); - curEntry->szClass = (LPWSTR)HeapAlloc(GetProcessHeap(), 0, (wcslen(szClass) + 1) * sizeof(WCHAR)); - if (curEntry->szClass) - wcscpy(curEntry->szClass, szClass); + pEntry = (StaticShellEntry *)HeapAlloc(GetProcessHeap(), 0, sizeof(StaticShellEntry)); + if (pEntry) + { + pEntry->pNext = NULL; + pEntry->szVerb = (LPWSTR)HeapAlloc(GetProcessHeap(), 0, (wcslen(szVerb) + 1) * sizeof(WCHAR)); + if (pEntry->szVerb) + wcscpy(pEntry->szVerb, szVerb); + pEntry->szClass = (LPWSTR)HeapAlloc(GetProcessHeap(), 0, (wcslen(szClass) + 1) * sizeof(WCHAR)); + if (pEntry->szClass) + wcscpy(pEntry->szClass, szClass); }
if (!wcsicmp(szVerb, L"open")) { /* open verb is always inserted in front */ - curEntry->Next = m_pStaticEntries; - m_pStaticEntries = curEntry; - } - else if (lastEntry) - lastEntry->Next = curEntry; + pEntry->pNext = m_pStaticEntries; + m_pStaticEntries = pEntry; + } + else if (pLastEntry) + pLastEntry->pNext = pEntry; else - m_pStaticEntries = curEntry; + m_pStaticEntries = pEntry; }
void CDefaultContextMenu::AddStaticEntryForKey(HKEY hKey, const WCHAR *pwszClass) { - LONG result; - DWORD dwIndex; WCHAR wszName[40]; - DWORD dwSize; + DWORD cchName, dwIndex = 0;
TRACE("AddStaticEntryForKey %x %ls\n", hKey, pwszClass);
- dwIndex = 0; - do - { - dwSize = sizeof(wszName) / sizeof(WCHAR); - result = RegEnumKeyExW(hKey, dwIndex, wszName, &dwSize, NULL, NULL, NULL, NULL); - if (result == ERROR_SUCCESS) - AddStaticEntry(wszName, pwszClass); - - dwIndex++; - } while(result == ERROR_SUCCESS); + while(TRUE) + { + cchName = _countof(wszName); + if (RegEnumKeyExW(hKey, dwIndex++, wszName, &cchName, NULL, NULL, NULL, NULL) != ERROR_SUCCESS) + break; + + AddStaticEntry(wszName, pwszClass); + } }
void @@ -303,28 +293,28 @@ BOOL HasClipboardData() { - BOOL ret = FALSE; - IDataObject * pda; - - if(SUCCEEDED(OleGetClipboard(&pda))) + BOOL bRet = FALSE; + IDataObject *pDataObj; + + if(SUCCEEDED(OleGetClipboard(&pDataObj))) { STGMEDIUM medium; FORMATETC formatetc;
- TRACE("pda=%p\n", pda); + TRACE("pDataObj=%p\n", pDataObj);
/* Set the FORMATETC structure*/ InitFormatEtc(formatetc, RegisterClipboardFormatW(CFSTR_SHELLIDLIST), TYMED_HGLOBAL); - if(SUCCEEDED(pda->GetData(&formatetc, &medium))) - { - ret = TRUE; + if(SUCCEEDED(pDataObj->GetData(&formatetc, &medium))) + { + bRet = TRUE; ReleaseStgMedium(&medium); }
- pda->Release(); - } - - return ret; + pDataObj->Release(); + } + + return bRet; }
static @@ -342,188 +332,173 @@ }
BOOL -CDefaultContextMenu::IsShellExtensionAlreadyLoaded(const CLSID * szClass) -{ - PDynamicShellEntry curEntry = m_pDynamicEntries; - - while(curEntry) - { - if (!memcmp(&curEntry->ClassID, szClass, sizeof(CLSID))) +CDefaultContextMenu::IsShellExtensionAlreadyLoaded(const CLSID *pclsid) +{ + PDynamicShellEntry pEntry = m_pDynamicEntries; + + while (pEntry) + { + if (!memcmp(&pEntry->ClassID, pclsid, sizeof(CLSID))) return TRUE; - curEntry = curEntry->Next; - } + pEntry = pEntry->pNext; + } + return FALSE; }
- -HRESULT -CDefaultContextMenu::LoadDynamicContextMenuHandler(HKEY hKey, const CLSID *pClass, BOOL bExternalInit) +HRESULT +CDefaultContextMenu::LoadDynamicContextMenuHandler(HKEY hKey, const CLSID *pclsid) { HRESULT hr; - IContextMenu *cmobj; - IShellExtInit *shext; - PDynamicShellEntry curEntry; - LPOLESTR pstr; - - StringFromCLSID(*pClass, &pstr); - - TRACE("LoadDynamicContextMenuHandler entered with This %p hKey %p pClass %s bExternalInit %u\n", this, hKey, wine_dbgstr_guid(pClass), bExternalInit); - - if (IsShellExtensionAlreadyLoaded(pClass)) + + TRACE("LoadDynamicContextMenuHandler entered with This %p hKey %p pclsid %s\n", this, hKey, wine_dbgstr_guid(pclsid)); + + if (IsShellExtensionAlreadyLoaded(pclsid)) return S_OK;
- hr = SHCoCreateInstance(NULL, pClass, NULL, IID_IContextMenu, (void**)&cmobj); + IContextMenu *pcm; + hr = SHCoCreateInstance(NULL, pclsid, NULL, IID_IContextMenu, (void**)&pcm); if (hr != S_OK) { ERR("SHCoCreateInstance failed %x\n", GetLastError()); return hr; }
- if (bExternalInit) - { - hr = cmobj->QueryInterface(IID_IShellExtInit, (void**)&shext); - if (hr != S_OK) - { - ERR("Failed to query for interface IID_IShellExtInit hr %x pClass %s\n", hr, wine_dbgstr_guid(pClass)); - cmobj->Release(); - return hr; - } - - hr = shext->Initialize(m_pidlFolder, m_pDataObj, hKey); - shext->Release(); - if (hr != S_OK) - { - TRACE("Failed to initialize shell extension error %x pClass %s\n", hr, wine_dbgstr_guid(pClass)); - cmobj->Release(); - return hr; - } - } - - curEntry = (DynamicShellEntry *)HeapAlloc(GetProcessHeap(), 0, sizeof(DynamicShellEntry)); - if(!curEntry) - { - cmobj->Release(); + IShellExtInit *pExtInit; + hr = pcm->QueryInterface(IID_IShellExtInit, (void**)&pExtInit); + if (hr != S_OK) + { + ERR("Failed to query for interface IID_IShellExtInit hr %x pclsid %s\n", hr, wine_dbgstr_guid(pclsid)); + pcm->Release(); + return hr; + } + + hr = pExtInit->Initialize(m_pidlFolder, m_pDataObj, hKey); + pExtInit->Release(); + if (hr != S_OK) + { + TRACE("Failed to initialize shell extension error %x pclsid %s\n", hr, wine_dbgstr_guid(pclsid)); + pcm->Release(); + return hr; + } + + PDynamicShellEntry pEntry = (DynamicShellEntry *)HeapAlloc(GetProcessHeap(), 0, sizeof(DynamicShellEntry)); + if (!pEntry) + { + pcm->Release(); return E_OUTOFMEMORY; }
- curEntry->iIdCmdFirst = 0; - curEntry->Next = NULL; - curEntry->NumIds = 0; - curEntry->CMenu = cmobj; - memcpy(&curEntry->ClassID, pClass, sizeof(CLSID)); + pEntry->iIdCmdFirst = 0; + pEntry->pNext = NULL; + pEntry->NumIds = 0; + pEntry->pCM = pcm; + memcpy(&pEntry->ClassID, pclsid, sizeof(CLSID));
if (m_pDynamicEntries) { - PDynamicShellEntry pEntry = m_pDynamicEntries; - - while (pEntry->Next) - pEntry = pEntry->Next; - - pEntry->Next = curEntry; + PDynamicShellEntry pLastEntry = m_pDynamicEntries; + + while (pLastEntry->pNext) + pLastEntry = pLastEntry->pNext; + + pLastEntry->pNext = pEntry; } else - m_pDynamicEntries = curEntry; - - return hr; -} - -UINT + m_pDynamicEntries = pEntry; + + return S_OK; +} + +BOOL CDefaultContextMenu::EnumerateDynamicContextHandlerForKey(HKEY hRootKey) { - WCHAR szKey[MAX_PATH] = {0}; - WCHAR szName[MAX_PATH] = {0}; - DWORD dwIndex, dwName; - LONG res; - HRESULT hResult; - UINT index; - CLSID clsid; + + WCHAR wszName[MAX_PATH], wszBuf[MAX_PATH], *pwszClsid; + DWORD cchName; + HRESULT hr; HKEY hKey;
if (RegOpenKeyExW(hRootKey, L"shellex\ContextMenuHandlers", 0, KEY_READ, &hKey) != ERROR_SUCCESS) { - TRACE("RegOpenKeyExW failed for key %s\n", debugstr_w(szKey)); - return 0; - } - - dwIndex = 0; - index = 0; - do - { - dwName = MAX_PATH; - res = RegEnumKeyExW(hKey, dwIndex, szName, &dwName, NULL, NULL, NULL, NULL); - if (res == ERROR_SUCCESS) - { - hResult = CLSIDFromString(szName, &clsid); - if (hResult != S_OK) + TRACE("RegOpenKeyExW failed\n"); + return FALSE; + } + + DWORD dwIndex = 0; + while (TRUE) + { + cchName = _countof(wszName); + if (RegEnumKeyExW(hKey, dwIndex++, wszName, &cchName, NULL, NULL, NULL, NULL) != ERROR_SUCCESS) + break; + + /* Key name or key value is CLSID */ + CLSID clsid; + hr = CLSIDFromString(wszName, &clsid); + if (hr == S_OK) + pwszClsid = wszName; + else + { + DWORD cchBuf = _countof(wszBuf); + if (RegGetValueW(hKey, wszName, NULL, RRF_RT_REG_SZ, NULL, wszBuf, &cchBuf) == ERROR_SUCCESS) + hr = CLSIDFromString(wszBuf, &clsid); + pwszClsid = wszBuf; + } + if (SUCCEEDED(hr)) + { + if (m_bGroupPolicyActive) { - dwName = MAX_PATH; - if (RegGetValueW(hKey, szName, NULL, RRF_RT_REG_SZ, NULL, szKey, &dwName) == ERROR_SUCCESS) + if (RegGetValueW(HKEY_LOCAL_MACHINE, + L"Software\Microsoft\Windows\CurrentVersion\Shell Extensions\Approved", + pwszClsid, + RRF_RT_REG_SZ, + NULL, + NULL, + NULL) == ERROR_SUCCESS) { - hResult = CLSIDFromString(szKey, &clsid); + LoadDynamicContextMenuHandler(hKey, &clsid); } } - if (SUCCEEDED(hResult)) - { - if (m_bGroupPolicyActive) - { - if (RegGetValueW(HKEY_LOCAL_MACHINE, - L"Software\Microsoft\Windows\CurrentVersion\Shell Extensions\Approved", - szKey, - RRF_RT_REG_SZ, - NULL, - NULL, - &dwName) == ERROR_SUCCESS) - { - LoadDynamicContextMenuHandler(hKey, &clsid, TRUE); - } - } - else - { - LoadDynamicContextMenuHandler(hKey, &clsid, TRUE); - } - } - } - dwIndex++; - } while(res == ERROR_SUCCESS); + else + LoadDynamicContextMenuHandler(hKey, &clsid); + } + }
RegCloseKey(hKey); - return index; + return TRUE; }
UINT -CDefaultContextMenu::InsertMenuItemsOfDynamicContextMenuExtension(HMENU hMenu, UINT indexMenu, UINT idCmdFirst, UINT idCmdLast) -{ - PDynamicShellEntry curEntry; - HRESULT hResult; - +CDefaultContextMenu::InsertMenuItemsOfDynamicContextMenuExtension(HMENU hMenu, UINT IndexMenu, UINT idCmdFirst, UINT idCmdLast) +{ if (!m_pDynamicEntries) { m_iIdSHEFirst = 0; m_iIdSHELast = 0; - return indexMenu; - } - - curEntry = m_pDynamicEntries; + return IndexMenu; + } + + PDynamicShellEntry pEntry = m_pDynamicEntries; idCmdFirst = 0x5000; idCmdLast = 0x6000; m_iIdSHEFirst = idCmdFirst; do { - hResult = curEntry->CMenu->QueryContextMenu(hMenu, indexMenu++, idCmdFirst, idCmdLast, CMF_NORMAL); - if (SUCCEEDED(hResult)) - { - curEntry->iIdCmdFirst = idCmdFirst; - curEntry->NumIds = LOWORD(hResult); - indexMenu += curEntry->NumIds; - idCmdFirst += curEntry->NumIds + 0x10; - } - TRACE("curEntry %p hresult %x contextmenu %p cmdfirst %x num ids %x\n", curEntry, hResult, curEntry->CMenu, curEntry->iIdCmdFirst, curEntry->NumIds); - curEntry = curEntry->Next; - } while(curEntry); + HRESULT hr = pEntry->pCM->QueryContextMenu(hMenu, IndexMenu++, idCmdFirst, idCmdLast, CMF_NORMAL); + if (SUCCEEDED(hr)) + { + pEntry->iIdCmdFirst = idCmdFirst; + pEntry->NumIds = LOWORD(hr); + IndexMenu += pEntry->NumIds; + idCmdFirst += pEntry->NumIds + 0x10; + } + TRACE("pEntry %p hr %x contextmenu %p cmdfirst %x num ids %x\n", pEntry, hr, pEntry->pCM, pEntry->iIdCmdFirst, pEntry->NumIds); + pEntry = pEntry->pNext; + } while (pEntry);
m_iIdSHELast = idCmdFirst; TRACE("SH_LoadContextMenuHandlers first %x last %x\n", m_iIdSHEFirst, m_iIdSHELast); - return indexMenu; + return IndexMenu; }
UINT @@ -533,45 +508,41 @@ UINT iIdCmdLast, UINT uFlags) { - MENUITEMINFOW mii; - WCHAR szBuffer[MAX_PATH]; - UINT indexMenu = 0; + UINT IndexMenu = 0; HMENU hSubMenu; - HKEY hKey; - - ZeroMemory(&mii, sizeof(mii));
TRACE("BuildBackgroundContextMenu entered\n");
if (!_ILIsDesktop(m_Dcm.pidlFolder)) { + WCHAR wszBuf[MAX_PATH]; + /* view option is only available in browsing mode */ - hSubMenu = LoadMenuA(shell32_hInstance, "MENU_001"); - if (hSubMenu) - { - szBuffer[0] = 0; - LoadStringW(shell32_hInstance, FCIDM_SHVIEW_VIEW, szBuffer, MAX_PATH); - szBuffer[MAX_PATH-1] = 0; - - TRACE("szBuffer %s\n", debugstr_w(szBuffer)); - + hSubMenu = LoadMenuW(shell32_hInstance, L"MENU_001"); + if (hSubMenu && LoadStringW(shell32_hInstance, FCIDM_SHVIEW_VIEW, wszBuf, _countof(wszBuf))) + { + TRACE("wszBuf %s\n", debugstr_w(wszBuf)); + + MENUITEMINFOW mii; + ZeroMemory(&mii, sizeof(mii)); mii.cbSize = sizeof(mii); mii.fMask = MIIM_TYPE | MIIM_STATE | MIIM_SUBMENU | MIIM_ID; mii.fType = MFT_STRING; mii.wID = iIdCmdFirst++; - mii.dwTypeData = szBuffer; - mii.cch = wcslen( mii.dwTypeData ); + mii.dwTypeData = wszBuf; + mii.cch = wcslen(mii.dwTypeData); mii.fState = MFS_ENABLED; mii.hSubMenu = hSubMenu; - InsertMenuItemW(hMenu, indexMenu++, TRUE, &mii); + InsertMenuItemW(hMenu, IndexMenu++, TRUE, &mii); DestroyMenu(hSubMenu); } } + hSubMenu = LoadMenuW(shell32_hInstance, L"MENU_002"); if (hSubMenu) { /* merge general background context menu in */ - iIdCmdFirst = Shell_MergeMenus(hMenu, GetSubMenu(hSubMenu, 0), indexMenu, 0, 0xFFFF, MM_DONTREMOVESEPS | MM_SUBMENUSHAVEIDS) + 1; + iIdCmdFirst = Shell_MergeMenus(hMenu, GetSubMenu(hSubMenu, 0), IndexMenu, 0, 0xFFFF, MM_DONTREMOVESEPS | MM_SUBMENUSHAVEIDS) + 1; DestroyMenu(hSubMenu); }
@@ -582,6 +553,7 @@ }
/* Load context menu handlers */ + HKEY hKey; if (RegOpenKeyExW(HKEY_CLASSES_ROOT, L"Directory\Background", 0, KEY_READ, &hKey) == ERROR_SUCCESS) { EnumerateDynamicContextHandlerForKey(hKey); @@ -600,92 +572,88 @@ UINT CDefaultContextMenu::AddStaticContextMenusToMenu( HMENU hMenu, - UINT indexMenu) + UINT IndexMenu) { MENUITEMINFOW mii; UINT idResource; - PStaticShellEntry curEntry; - WCHAR szVerb[40]; - DWORD dwSize; + WCHAR wszVerb[40]; UINT fState; - UINT Length;
mii.cbSize = sizeof(mii); mii.fMask = MIIM_ID | MIIM_TYPE | MIIM_STATE | MIIM_DATA; mii.fType = MFT_STRING; - mii.fState = MFS_ENABLED; mii.wID = 0x4000; mii.dwTypeData = NULL; m_iIdSCMFirst = mii.wID;
- curEntry = m_pStaticEntries; - - while(curEntry) + PStaticShellEntry pEntry = m_pStaticEntries; + + while (pEntry) { fState = MFS_ENABLED; mii.dwTypeData = NULL;
- if (!wcsicmp(curEntry->szVerb, L"open")) + if (!wcsicmp(pEntry->szVerb, L"open")) { fState |= MFS_DEFAULT; idResource = IDS_OPEN_VERB; } - else if (!wcsicmp(curEntry->szVerb, L"explore")) + else if (!wcsicmp(pEntry->szVerb, L"explore")) idResource = IDS_EXPLORE_VERB; - else if (!wcsicmp(curEntry->szVerb, L"runas")) + else if (!wcsicmp(pEntry->szVerb, L"runas")) idResource = IDS_RUNAS_VERB; - else if (!wcsicmp(curEntry->szVerb, L"edit")) + else if (!wcsicmp(pEntry->szVerb, L"edit")) idResource = IDS_EDIT_VERB; - else if (!wcsicmp(curEntry->szVerb, L"find")) + else if (!wcsicmp(pEntry->szVerb, L"find")) idResource = IDS_FIND_VERB; - else if (!wcsicmp(curEntry->szVerb, L"print")) + else if (!wcsicmp(pEntry->szVerb, L"print")) idResource = IDS_PRINT_VERB; - else if (!wcsicmp(curEntry->szVerb, L"printto")) - { - curEntry = curEntry->Next; + else if (!wcsicmp(pEntry->szVerb, L"printto")) + { + pEntry = pEntry->pNext; continue; } else idResource = 0;
+ /* By default use verb for menu item name */ + mii.dwTypeData = pEntry->szVerb; + if (idResource > 0) { - if (LoadStringW(shell32_hInstance, idResource, szVerb, sizeof(szVerb) / sizeof(WCHAR))) - mii.dwTypeData = szVerb; /* use translated verb */ + if (LoadStringW(shell32_hInstance, idResource, wszVerb, _countof(wszVerb))) + mii.dwTypeData = wszVerb; /* use translated verb */ else - ERR("Failed to load string, defaulting to NULL value for mii.dwTypeData\n"); + ERR("Failed to load string\n"); } else { WCHAR wszKey[256]; - Length = wcslen(curEntry->szClass) + wcslen(curEntry->szVerb) + 8; - if (Length < sizeof(wszKey) / sizeof(WCHAR)) + HRESULT hr = StringCbPrintfW(wszKey, sizeof(wszKey), L"%s\shell\%s", pEntry->szClass, pEntry->szVerb); + + if (SUCCEEDED(hr)) { - wcscpy(wszKey, curEntry->szClass); - wcscat(wszKey, L"\shell\"); - wcscat(wszKey, curEntry->szVerb); - dwSize = sizeof(szVerb); - - if (RegGetValueW(HKEY_CLASSES_ROOT, wszKey, NULL, RRF_RT_REG_SZ, NULL, szVerb, &dwSize) == ERROR_SUCCESS) - mii.dwTypeData = szVerb; /* use description for the menu entry */ - else - mii.dwTypeData = curEntry->szVerb; /* use verb for the menu entry */ + DWORD cbVerb = sizeof(wszVerb); + + if (RegGetValueW(HKEY_CLASSES_ROOT, wszKey, NULL, RRF_RT_REG_SZ, NULL, wszVerb, &cbVerb) == ERROR_SUCCESS) + mii.dwTypeData = wszVerb; /* use description for the menu entry */ } }
mii.cch = wcslen(mii.dwTypeData); mii.fState = fState; - InsertMenuItemW(hMenu, indexMenu++, TRUE, &mii); + InsertMenuItemW(hMenu, IndexMenu++, TRUE, &mii);
mii.wID++; - curEntry = curEntry->Next; - } + pEntry = pEntry->pNext; + } + m_iIdSCMLast = mii.wID - 1; - return indexMenu; + return IndexMenu; }
void WINAPI _InsertMenuItemW( - HMENU hmenu, + HMENU hMenu, UINT indexMenu, BOOL fByPosition, UINT wID, @@ -694,24 +662,19 @@ UINT fState) { MENUITEMINFOW mii; - WCHAR szText[100]; + WCHAR wszText[100];
ZeroMemory(&mii, sizeof(mii)); mii.cbSize = sizeof(mii); if (fType == MFT_SEPARATOR) - { mii.fMask = MIIM_ID | MIIM_TYPE; - } else if (fType == MFT_STRING) { mii.fMask = MIIM_ID | MIIM_TYPE | MIIM_STATE; if ((ULONG_PTR)HIWORD((ULONG_PTR)dwTypeData) == 0) { - if (LoadStringW(shell32_hInstance, LOWORD((ULONG_PTR)dwTypeData), szText, sizeof(szText) / sizeof(WCHAR))) - { - szText[(sizeof(szText)/sizeof(WCHAR))-1] = 0; - mii.dwTypeData = szText; - } + if (LoadStringW(shell32_hInstance, LOWORD((ULONG_PTR)dwTypeData), wszText, _countof(wszText))) + mii.dwTypeData = wszText; else { ERR("failed to load string %p\n", dwTypeData); @@ -719,15 +682,13 @@ } } else - { - mii.dwTypeData = (LPWSTR) dwTypeData; - } + mii.dwTypeData = (LPWSTR)dwTypeData; mii.fState = fState; }
mii.wID = wID; mii.fType = fType; - InsertMenuItemW( hmenu, indexMenu, fByPosition, &mii); + InsertMenuItemW(hMenu, indexMenu, fByPosition, &mii); }
UINT @@ -737,53 +698,50 @@ UINT iIdCmdLast, UINT uFlags) { - WCHAR szPath[MAX_PATH]; - WCHAR szTemp[40]; HKEY hKey; - UINT indexMenu; - SFGAOF rfg; HRESULT hr; - BOOL bAddSep = FALSE; - GUID * guid; - BOOL bClipboardData; - STRRET strFile; - LPWSTR pOffset; - DWORD dwSize;
TRACE("BuildShellItemContextMenu entered\n"); ASSERT(m_Dcm.cidl >= 1);
+ STRRET strFile; hr = m_Dcm.psf->GetDisplayNameOf(m_Dcm.apidl[0], SHGDN_FORPARSING, &strFile); if (hr == S_OK) { - hr = StrRetToBufW(&strFile, m_Dcm.apidl[0], szPath, MAX_PATH); + WCHAR wszPath[MAX_PATH]; + hr = StrRetToBufW(&strFile, m_Dcm.apidl[0], wszPath, _countof(wszPath)); if (hr == S_OK) { - pOffset = wcsrchr(szPath, L'.'); - if (pOffset) + LPCWSTR pwszExt = PathFindExtensionW(wszPath); + if (pwszExt[0]) { /* enumerate dynamic/static for a given file class */ - if (RegOpenKeyExW(HKEY_CLASSES_ROOT, pOffset, 0, KEY_READ, &hKey) == ERROR_SUCCESS) + if (RegOpenKeyExW(HKEY_CLASSES_ROOT, pwszExt, 0, KEY_READ, &hKey) == ERROR_SUCCESS) { /* add static verbs */ - AddStaticEntryForFileClass(pOffset); + AddStaticEntryForFileClass(pwszExt); + /* load dynamic extensions from file extension key */ EnumerateDynamicContextHandlerForKey(hKey); RegCloseKey(hKey); } - dwSize = sizeof(szTemp); - if (RegGetValueW(HKEY_CLASSES_ROOT, pOffset, NULL, RRF_RT_REG_SZ, NULL, szTemp, &dwSize) == ERROR_SUCCESS) + + 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, szTemp, 0, KEY_READ, &hKey) == ERROR_SUCCESS) + if (RegOpenKeyExW(HKEY_CLASSES_ROOT, wszTemp, 0, KEY_READ, &hKey) == ERROR_SUCCESS) { /* add static verbs from progid key */ - AddStaticEntryForFileClass(szTemp); + AddStaticEntryForFileClass(wszTemp); + /* load dynamic extensions from progid key */ EnumerateDynamicContextHandlerForKey(hKey); RegCloseKey(hKey); } } } + if (RegOpenKeyExW(HKEY_CLASSES_ROOT, L"*", 0, KEY_READ, &hKey) == ERROR_SUCCESS) { /* load default extensions */ @@ -795,14 +753,14 @@ else ERR("GetDisplayNameOf failed: %x\n", hr);
- guid = _ILGetGUIDPointer(m_Dcm.apidl[0]); - if (guid) + GUID *pGuid = _ILGetGUIDPointer(m_Dcm.apidl[0]); + if (pGuid) { LPOLESTR pwszCLSID; WCHAR buffer[60];
wcscpy(buffer, L"CLSID\"); - hr = StringFromCLSID(*guid, &pwszCLSID); + hr = StringFromCLSID(*pGuid, &pwszCLSID); if (hr == S_OK) { wcscpy(&buffer[6], pwszCLSID); @@ -829,7 +787,7 @@ }
/* add static actions */ - rfg = SFGAO_BROWSABLE | SFGAO_CANCOPY | SFGAO_CANLINK | SFGAO_CANMOVE | SFGAO_CANDELETE | SFGAO_CANRENAME | SFGAO_HASPROPSHEET | SFGAO_FILESYSTEM | SFGAO_FOLDER; + SFGAOF rfg = SFGAO_BROWSABLE | SFGAO_CANCOPY | SFGAO_CANLINK | SFGAO_CANMOVE | SFGAO_CANDELETE | SFGAO_CANRENAME | SFGAO_HASPROPSHEET | SFGAO_FILESYSTEM | SFGAO_FOLDER; hr = m_Dcm.psf->GetAttributesOf(m_Dcm.cidl, m_Dcm.apidl, &rfg); if (FAILED(hr)) { @@ -865,31 +823,32 @@ }
/* add static context menu handlers */ - indexMenu = AddStaticContextMenusToMenu(hMenu, 0); + UINT IndexMenu = AddStaticContextMenusToMenu(hMenu, 0); + /* now process dynamic context menu handlers */ - indexMenu = InsertMenuItemsOfDynamicContextMenuExtension(hMenu, indexMenu, iIdCmdFirst, iIdCmdLast); - TRACE("indexMenu %d\n", indexMenu); + BOOL bAddSep = FALSE; + IndexMenu = InsertMenuItemsOfDynamicContextMenuExtension(hMenu, IndexMenu, iIdCmdFirst, iIdCmdLast); + TRACE("IndexMenu %d\n", IndexMenu);
if (_ILIsDrive(m_Dcm.apidl[0])) { /* The 'Format' option must be always available, - * thus it is not registered as a static shell extension - */ - _InsertMenuItemW(hMenu, indexMenu++, TRUE, 0, MFT_SEPARATOR, NULL, 0); - _InsertMenuItemW(hMenu, indexMenu++, TRUE, 0x7ABC, MFT_STRING, MAKEINTRESOURCEW(IDS_FORMATDRIVE), MFS_ENABLED); + * thus it is not registered as a static shell extension */ + _InsertMenuItemW(hMenu, IndexMenu++, TRUE, 0, MFT_SEPARATOR, NULL, 0); + _InsertMenuItemW(hMenu, IndexMenu++, TRUE, 0x7ABC, MFT_STRING, MAKEINTRESOURCEW(IDS_FORMATDRIVE), MFS_ENABLED); bAddSep = TRUE; }
- bClipboardData = (HasClipboardData() && (rfg & SFGAO_FILESYSTEM)); + BOOL bClipboardData = (HasClipboardData() && (rfg & SFGAO_FILESYSTEM)); if (rfg & (SFGAO_CANCOPY | SFGAO_CANMOVE) || bClipboardData) { - _InsertMenuItemW(hMenu, indexMenu++, TRUE, 0, MFT_SEPARATOR, NULL, 0); + _InsertMenuItemW(hMenu, IndexMenu++, TRUE, 0, MFT_SEPARATOR, NULL, 0); if (rfg & SFGAO_CANMOVE) - _InsertMenuItemW(hMenu, indexMenu++, TRUE, FCIDM_SHVIEW_CUT, MFT_STRING, MAKEINTRESOURCEW(IDS_CUT), MFS_ENABLED); + _InsertMenuItemW(hMenu, IndexMenu++, TRUE, FCIDM_SHVIEW_CUT, MFT_STRING, MAKEINTRESOURCEW(IDS_CUT), MFS_ENABLED); if (rfg & SFGAO_CANCOPY) - _InsertMenuItemW(hMenu, indexMenu++, TRUE, FCIDM_SHVIEW_COPY, MFT_STRING, MAKEINTRESOURCEW(IDS_COPY), MFS_ENABLED); + _InsertMenuItemW(hMenu, IndexMenu++, TRUE, FCIDM_SHVIEW_COPY, MFT_STRING, MAKEINTRESOURCEW(IDS_COPY), MFS_ENABLED); if (bClipboardData) - _InsertMenuItemW(hMenu, indexMenu++, TRUE, FCIDM_SHVIEW_INSERT, MFT_STRING, MAKEINTRESOURCEW(IDS_INSERT), MFS_ENABLED); + _InsertMenuItemW(hMenu, IndexMenu++, TRUE, FCIDM_SHVIEW_INSERT, MFT_STRING, MAKEINTRESOURCEW(IDS_INSERT), MFS_ENABLED);
bAddSep = TRUE; } @@ -897,8 +856,8 @@ if (rfg & SFGAO_CANLINK) { bAddSep = FALSE; - _InsertMenuItemW(hMenu, indexMenu++, TRUE, 0, MFT_SEPARATOR, NULL, 0); - _InsertMenuItemW(hMenu, indexMenu++, TRUE, FCIDM_SHVIEW_CREATELINK, MFT_STRING, MAKEINTRESOURCEW(IDS_CREATELINK), MFS_ENABLED); + _InsertMenuItemW(hMenu, IndexMenu++, TRUE, 0, MFT_SEPARATOR, NULL, 0); + _InsertMenuItemW(hMenu, IndexMenu++, TRUE, FCIDM_SHVIEW_CREATELINK, MFT_STRING, MAKEINTRESOURCEW(IDS_CREATELINK), MFS_ENABLED); }
if (rfg & SFGAO_CANDELETE) @@ -906,25 +865,25 @@ if (bAddSep) { bAddSep = FALSE; - _InsertMenuItemW(hMenu, indexMenu++, TRUE, 0, MFT_SEPARATOR, NULL, 0); - } - _InsertMenuItemW(hMenu, indexMenu++, TRUE, FCIDM_SHVIEW_DELETE, MFT_STRING, MAKEINTRESOURCEW(IDS_DELETE), MFS_ENABLED); + _InsertMenuItemW(hMenu, IndexMenu++, TRUE, 0, MFT_SEPARATOR, NULL, 0); + } + _InsertMenuItemW(hMenu, IndexMenu++, TRUE, FCIDM_SHVIEW_DELETE, MFT_STRING, MAKEINTRESOURCEW(IDS_DELETE), MFS_ENABLED); }
if (rfg & SFGAO_CANRENAME) { if (bAddSep) { - _InsertMenuItemW(hMenu, indexMenu++, TRUE, 0, MFT_SEPARATOR, NULL, 0); - } - _InsertMenuItemW(hMenu, indexMenu++, TRUE, FCIDM_SHVIEW_RENAME, MFT_STRING, MAKEINTRESOURCEW(IDS_RENAME), MFS_ENABLED); + _InsertMenuItemW(hMenu, IndexMenu++, TRUE, 0, MFT_SEPARATOR, NULL, 0); + } + _InsertMenuItemW(hMenu, IndexMenu++, TRUE, FCIDM_SHVIEW_RENAME, MFT_STRING, MAKEINTRESOURCEW(IDS_RENAME), MFS_ENABLED); bAddSep = TRUE; }
if (rfg & SFGAO_HASPROPSHEET) { - _InsertMenuItemW(hMenu, indexMenu++, TRUE, 0, MFT_SEPARATOR, NULL, 0); - _InsertMenuItemW(hMenu, indexMenu++, TRUE, FCIDM_SHVIEW_PROPERTIES, MFT_STRING, MAKEINTRESOURCEW(IDS_PROPERTIES), MFS_ENABLED); + _InsertMenuItemW(hMenu, IndexMenu++, TRUE, 0, MFT_SEPARATOR, NULL, 0); + _InsertMenuItemW(hMenu, IndexMenu++, TRUE, FCIDM_SHVIEW_PROPERTIES, MFT_STRING, MAKEINTRESOURCEW(IDS_PROPERTIES), MFS_ENABLED); }
return iIdCmdLast; @@ -933,16 +892,16 @@ HRESULT WINAPI CDefaultContextMenu::QueryContextMenu( - HMENU hmenu, - UINT indexMenu, + HMENU hMenu, + UINT IndexMenu, UINT idCmdFirst, UINT idCmdLast, UINT uFlags) { if (m_Dcm.cidl) - idCmdFirst = BuildShellItemContextMenu(hmenu, idCmdFirst, idCmdLast, uFlags); + idCmdFirst = BuildShellItemContextMenu(hMenu, idCmdFirst, idCmdLast, uFlags); else - idCmdFirst = BuildBackgroundContextMenu(hmenu, idCmdFirst, idCmdLast, uFlags); + idCmdFirst = BuildBackgroundContextMenu(hMenu, idCmdFirst, idCmdLast, uFlags);
return S_OK; } @@ -951,28 +910,25 @@ HRESULT NotifyShellViewWindow(LPCMINVOKECOMMANDINFO lpcmi, BOOL bRefresh) { - LPSHELLBROWSER lpSB; + /* Note: CWM_GETISHELLBROWSER returns not referenced object */ + LPSHELLBROWSER lpSB = (LPSHELLBROWSER)SendMessageA(lpcmi->hwnd, CWM_GETISHELLBROWSER, 0, 0); + if (!lpSB) + return E_FAIL; + LPSHELLVIEW lpSV = NULL; - HWND hwndSV = NULL; - - if((lpSB = (LPSHELLBROWSER)SendMessageA(lpcmi->hwnd, CWM_GETISHELLBROWSER, 0, 0))) - { - if(SUCCEEDED(lpSB->QueryActiveShellView(&lpSV))) - { - lpSV->GetWindow(&hwndSV); - } - } + if (FAILED(lpSB->QueryActiveShellView(&lpSV))) + return E_FAIL;
if (LOWORD(lpcmi->lpVerb) == FCIDM_SHVIEW_REFRESH || bRefresh) - { - if (lpSV) - lpSV->Refresh(); - - return S_OK; - } - - SendMessageW(hwndSV, WM_COMMAND, MAKEWPARAM(LOWORD(lpcmi->lpVerb), 0), 0); - + lpSV->Refresh(); + else + { + HWND hwndSV = NULL; + if (SUCCEEDED(lpSV->GetWindow(&hwndSV))) + SendMessageW(hwndSV, WM_COMMAND, MAKEWPARAM(LOWORD(lpcmi->lpVerb), 0), 0); + } + + lpSV->Release(); return S_OK; }
@@ -980,19 +936,14 @@ CDefaultContextMenu::DoPaste( LPCMINVOKECOMMANDINFO lpcmi) { - IDataObject * pda; + HRESULT hr; + + IDataObject *pda; + if (OleGetClipboard(&pda) != S_OK) + return E_FAIL; + STGMEDIUM medium; FORMATETC formatetc; - LPITEMIDLIST * apidl; - LPITEMIDLIST pidl; - IShellFolder *psfFrom = NULL, *psfDesktop, *psfTarget = NULL; - LPIDA lpcida; - ISFHelper *psfhlpdst, *psfhlpsrc; - HRESULT hr; - - if (OleGetClipboard(&pda) != S_OK) - return E_FAIL; - InitFormatEtc(formatetc, RegisterClipboardFormatW(CFSTR_SHELLIDLIST), TYMED_HGLOBAL); hr = pda->GetData(&formatetc, &medium);
@@ -1003,7 +954,7 @@ }
/* lock the handle */ - lpcida = (LPIDA)GlobalLock(medium.hGlobal); + LPIDA lpcida = (LPIDA)GlobalLock(medium.hGlobal); if (!lpcida) { ReleaseStgMedium(&medium); @@ -1012,11 +963,13 @@ }
/* convert the data into pidl */ - apidl = _ILCopyCidaToaPidl(&pidl, lpcida); + LPITEMIDLIST pidl; + LPITEMIDLIST *apidl = _ILCopyCidaToaPidl(&pidl, lpcida);
if (!apidl) return E_FAIL;
+ IShellFolder *psfDesktop; if (FAILED(SHGetDesktopFolder(&psfDesktop))) { SHFree(pidl); @@ -1026,6 +979,8 @@ return E_FAIL; }
+ /* Find source folder */ + IShellFolder *psfFrom = NULL; if (_ILIsDesktop(pidl)) { /* use desktop shellfolder */ @@ -1044,6 +999,8 @@ return E_FAIL; }
+ /* Find target folder */ + IShellFolder *psfTarget = NULL; if (m_Dcm.cidl) { psfDesktop->Release(); @@ -1092,6 +1049,7 @@ }
/* get source and destination shellfolder */ + ISFHelper *psfhlpdst; if (FAILED(psfTarget->QueryInterface(IID_ISFHelper, (LPVOID*)&psfhlpdst))) { ERR("no IID_ISFHelper for destination\n"); @@ -1106,6 +1064,7 @@ return E_FAIL; }
+ ISFHelper *psfhlpsrc; if (FAILED(psfFrom->QueryInterface(IID_ISFHelper, (LPVOID*)&psfhlpsrc))) { ERR("no IID_ISFHelper for source\n"); @@ -1146,42 +1105,30 @@ }
BOOL -GetUniqueFileName(LPWSTR szBasePath, LPWSTR szExt, LPWSTR szTarget, BOOL bShortcut) -{ - UINT RetryCount = 0, Length; - WCHAR szLnk[40]; - HANDLE hFile; +GetUniqueFileName(LPWSTR pwszBasePath, LPCWSTR pwszExt, LPWSTR pwszTarget, BOOL bShortcut) +{ + WCHAR wszLink[40];
if (!bShortcut) - Length = LoadStringW(shell32_hInstance, IDS_LNK_FILE, szLnk, sizeof(szLnk) / sizeof(WCHAR)); - - do + { + if (!LoadStringW(shell32_hInstance, IDS_LNK_FILE, wszLink, _countof(wszLink))) + wszLink[0] = L'\0'; + } + + if (!bShortcut) + swprintf(pwszTarget, L"%s%s%s", wszLink, pwszBasePath, pwszExt); + else + swprintf(pwszTarget, L"%s%s", pwszBasePath, pwszExt); + + for (UINT i = 2; PathFileExistsW(pwszTarget); ++i) { if (!bShortcut) - { - if (RetryCount) - swprintf(szTarget, L"%s%s(%u).%s", szLnk, szBasePath, RetryCount, szExt); - else - swprintf(szTarget, L"%s%s.%s", szLnk, szBasePath, szExt); - } + swprintf(pwszTarget, L"%s%s (%u)%s", wszLink, pwszBasePath, i, pwszExt); else - { - if (RetryCount) - swprintf(szTarget, L"%s(%u).%s", szBasePath, RetryCount, szExt); - else - swprintf(szTarget, L"%s.%s", szBasePath, szExt); - } - - hFile = CreateFileW(szTarget, GENERIC_WRITE, 0, NULL, CREATE_NEW, FILE_ATTRIBUTE_NORMAL, NULL); - if (hFile != INVALID_HANDLE_VALUE) - { - CloseHandle(hFile); - return TRUE; - } - - } while(RetryCount++ < 100); - - return FALSE; + swprintf(pwszTarget, L"%s (%u)%s", pwszBasePath, i, pwszExt); + } + + return TRUE;
}
@@ -1189,16 +1136,10 @@ CDefaultContextMenu::DoCreateLink( LPCMINVOKECOMMANDINFO lpcmi) { - WCHAR szPath[MAX_PATH]; - WCHAR szTarget[MAX_PATH] = {0}; - WCHAR szDirPath[MAX_PATH]; - LPWSTR pszFile; + WCHAR wszTarget[MAX_PATH]; + IPersistFile *ppf; + HRESULT hr; STRRET strFile; - LPWSTR pszExt; - HRESULT hr; - IShellLinkW * nLink; - IPersistFile * ipf; - static WCHAR szLnk[] = L"lnk";
if (m_Dcm.psf->GetDisplayNameOf(m_Dcm.apidl[0], SHGDN_FORPARSING, &strFile) != S_OK) { @@ -1206,47 +1147,50 @@ return E_FAIL; }
- if (StrRetToBufW(&strFile, m_Dcm.apidl[0], szPath, MAX_PATH) != S_OK) - return E_FAIL; - - pszExt = wcsrchr(szPath, L'.'); - - if (pszExt && !wcsicmp(pszExt + 1, szLnk)) - { - if (!GetUniqueFileName(szPath, pszExt + 1, szTarget, TRUE)) + WCHAR wszPath[MAX_PATH]; + if (StrRetToBufW(&strFile, m_Dcm.apidl[0], wszPath, _countof(wszPath)) != S_OK) + return E_FAIL; + + LPWSTR pwszExt = PathFindExtensionW(wszPath); + + if (!wcsicmp(pwszExt, L".lnk")) + { + if (!GetUniqueFileName(wszPath, pwszExt, wszTarget, TRUE)) return E_FAIL;
- hr = IShellLink_ConstructFromFile(NULL, IID_IPersistFile, m_Dcm.apidl[0], (LPVOID*)&ipf); + hr = IShellLink_ConstructFromFile(NULL, IID_IPersistFile, m_Dcm.apidl[0], (LPVOID*)&ppf); if (hr != S_OK) return hr;
- hr = ipf->Save(szTarget, FALSE); - ipf->Release(); + hr = ppf->Save(wszTarget, FALSE); + ppf->Release(); NotifyShellViewWindow(lpcmi, TRUE); return hr; } else { - if (!GetUniqueFileName(szPath, szLnk, szTarget, TRUE)) + if (!GetUniqueFileName(wszPath, L".lnk", wszTarget, TRUE)) return E_FAIL;
- hr = CShellLink::_CreatorClass::CreateInstance(NULL, IID_IShellLinkW, (void**)&nLink); + IShellLinkW *pLink; + hr = CShellLink::_CreatorClass::CreateInstance(NULL, IID_IShellLinkW, (void**)&pLink); if (hr != S_OK) return hr;
- GetFullPathName(szPath, MAX_PATH, szDirPath, &pszFile); - if (pszFile) pszFile[0] = 0; - - if (SUCCEEDED(nLink->SetPath(szPath)) && - SUCCEEDED(nLink->SetWorkingDirectory(szDirPath))) - { - if (SUCCEEDED(nLink->QueryInterface(IID_IPersistFile, (LPVOID*)&ipf))) + WCHAR szDirPath[MAX_PATH], *pwszFile; + GetFullPathName(wszPath, MAX_PATH, szDirPath, &pwszFile); + if (pwszFile) pwszFile[0] = 0; + + if (SUCCEEDED(pLink->SetPath(wszPath)) && + SUCCEEDED(pLink->SetWorkingDirectory(szDirPath))) + { + if (SUCCEEDED(pLink->QueryInterface(IID_IPersistFile, (LPVOID*)&ppf))) { - hr = ipf->Save(szTarget, TRUE); - ipf->Release(); + hr = ppf->Save(wszTarget, TRUE); + ppf->Release(); } } - nLink->Release(); + pLink->Release(); NotifyShellViewWindow(lpcmi, TRUE); return hr; } @@ -1256,24 +1200,16 @@ CDefaultContextMenu::DoDelete( LPCMINVOKECOMMANDINFO lpcmi) { - HRESULT hr; STRRET strTemp; - WCHAR szPath[MAX_PATH]; - LPWSTR wszPath, wszPos; - SHFILEOPSTRUCTW op; - int ret; - LPSHELLBROWSER lpSB; - HWND hwnd; - - - hr = m_Dcm.psf->GetDisplayNameOf(m_Dcm.apidl[0], SHGDN_FORPARSING, &strTemp); + HRESULT hr = m_Dcm.psf->GetDisplayNameOf(m_Dcm.apidl[0], SHGDN_FORPARSING, &strTemp); if(hr != S_OK) { ERR("IShellFolder_GetDisplayNameOf failed with %x\n", hr); return hr; } - ZeroMemory(szPath, sizeof(szPath)); - hr = StrRetToBufW(&strTemp, m_Dcm.apidl[0], szPath, MAX_PATH); + + WCHAR wszPath[MAX_PATH]; + hr = StrRetToBufW(&strTemp, m_Dcm.apidl[0], wszPath, _countof(wszPath)); if (hr != S_OK) { ERR("StrRetToBufW failed with %x\n", hr); @@ -1281,43 +1217,45 @@ }
/* Only keep the base path */ - wszPos = strrchrW(szPath, '\'); - if (wszPos != NULL) - { - *(wszPos + 1) = '\0'; - } - - wszPath = BuildPathsList(szPath, m_Dcm.cidl, m_Dcm.apidl); - - ZeroMemory(&op, sizeof(op)); - op.hwnd = GetActiveWindow(); - op.wFunc = FO_DELETE; - op.pFrom = wszPath; - op.fFlags = FOF_ALLOWUNDO; - ret = SHFileOperationW(&op); - - if (ret) - { - ERR("SHFileOperation failed with 0x%x for %s\n", GetLastError(), debugstr_w(wszPath)); + LPWSTR pwszFilename = PathFindFileNameW(wszPath); + *pwszFilename = L'\0'; + + /* Build paths list */ + LPWSTR pwszPaths = BuildPathsList(wszPath, m_Dcm.cidl, m_Dcm.apidl); + if (!pwszPaths) + return E_FAIL; + + /* Delete them */ + SHFILEOPSTRUCTW FileOp; + ZeroMemory(&FileOp, sizeof(FileOp)); + FileOp.hwnd = GetActiveWindow(); + FileOp.wFunc = FO_DELETE; + FileOp.pFrom = pwszPaths; + FileOp.fFlags = FOF_ALLOWUNDO; + + if (SHFileOperationW(&FileOp) != 0) + { + ERR("SHFileOperation failed with 0x%x for %s\n", GetLastError(), debugstr_w(pwszPaths)); return S_OK; }
- /* get the active IShellView */ - if ((lpSB = (LPSHELLBROWSER)SendMessageA(lpcmi->hwnd, CWM_GETISHELLBROWSER, 0, 0))) - { - /* is the treeview focused */ + /* Get the active IShellView */ + LPSHELLBROWSER lpSB = (LPSHELLBROWSER)SendMessageW(lpcmi->hwnd, CWM_GETISHELLBROWSER, 0, 0); + if (lpSB) + { + /* Is the treeview focused */ + HWND hwnd; if (SUCCEEDED(lpSB->GetControlWindow(FCW_TREE, &hwnd))) { + /* Remove selected items from treeview */ HTREEITEM hItem = TreeView_GetSelection(hwnd); if (hItem) - { (void)TreeView_DeleteItem(hwnd, hItem); - } } } NotifyShellViewWindow(lpcmi, TRUE);
- HeapFree(GetProcessHeap(), 0, wszPath); + HeapFree(GetProcessHeap(), 0, pwszPaths); return S_OK;
} @@ -1327,8 +1265,6 @@ LPCMINVOKECOMMANDINFO lpcmi, BOOL bCopy) { - LPSHELLBROWSER lpSB; - LPSHELLVIEW lpSV; LPDATAOBJECT pDataObj; HRESULT hr;
@@ -1339,79 +1275,78 @@ return hr; }
- lpSB = (LPSHELLBROWSER)SendMessageA(lpcmi->hwnd, CWM_GETISHELLBROWSER, 0, 0); + /* Note: CWM_GETISHELLBROWSER returns not referenced object */ + LPSHELLBROWSER lpSB = (LPSHELLBROWSER)SendMessageA(lpcmi->hwnd, CWM_GETISHELLBROWSER, 0, 0); if (!lpSB) { - TRACE("failed to get shellbrowser\n"); - return E_FAIL; - } - + ERR("failed to get shellbrowser\n"); + return E_FAIL; + } + + LPSHELLVIEW lpSV; hr = lpSB->QueryActiveShellView(&lpSV); if (FAILED(hr)) { - TRACE("failed to query the active shellview\n"); + ERR("failed to query the active shellview\n"); return hr; }
hr = lpSV->GetItemObject(SVGIO_SELECTION, IID_IDataObject, (LPVOID*)&pDataObj); + if (SUCCEEDED(hr)) + { + hr = OleSetClipboard(pDataObj); + if (FAILED(hr)) + ERR("OleSetClipboard failed"); + pDataObj->Release(); + } else + ERR("failed to get item object\n"); + + lpSV->Release(); + return hr; +} + +HRESULT +CDefaultContextMenu::DoRename( + LPCMINVOKECOMMANDINFO lpcmi) +{ + /* get the active IShellView. Note: CWM_GETISHELLBROWSER returns not referenced object */ + LPSHELLBROWSER lpSB = (LPSHELLBROWSER)SendMessageA(lpcmi->hwnd, CWM_GETISHELLBROWSER, 0, 0); + if (!lpSB) + { + ERR("CWM_GETISHELLBROWSER failed\n"); + return E_FAIL; + } + + /* is the treeview focused */ + HWND hwnd; + if (SUCCEEDED(lpSB->GetControlWindow(FCW_TREE, &hwnd))) + { + HTREEITEM hItem = TreeView_GetSelection(hwnd); + if (hItem) + (void)TreeView_EditLabel(hwnd, hItem); + } + + LPSHELLVIEW lpSV; + HRESULT hr = lpSB->QueryActiveShellView(&lpSV); if (FAILED(hr)) { - TRACE("failed to get item object\n"); + ERR("CWM_GETISHELLBROWSER failed\n"); return hr; }
- hr = OleSetClipboard(pDataObj); - if (FAILED(hr)) - { - WARN("OleSetClipboard failed"); - } - pDataObj->Release(); + lpSV->SelectItem(m_Dcm.apidl[0], + SVSI_DESELECTOTHERS | SVSI_EDIT | SVSI_ENSUREVISIBLE | SVSI_FOCUSED | SVSI_SELECT); lpSV->Release(); return S_OK; }
HRESULT -CDefaultContextMenu::DoRename( - LPCMINVOKECOMMANDINFO lpcmi) -{ - LPSHELLBROWSER lpSB; - LPSHELLVIEW lpSV; - HWND hwnd; - - /* get the active IShellView */ - if ((lpSB = (LPSHELLBROWSER)SendMessageA(lpcmi->hwnd, CWM_GETISHELLBROWSER, 0, 0))) - { - /* is the treeview focused */ - if (SUCCEEDED(lpSB->GetControlWindow(FCW_TREE, &hwnd))) - { - HTREEITEM hItem = TreeView_GetSelection(hwnd); - if (hItem) - { - (void)TreeView_EditLabel(hwnd, hItem); - } - } - - if(SUCCEEDED(lpSB->QueryActiveShellView(&lpSV))) - { - lpSV->SelectItem(m_Dcm.apidl[0], - SVSI_DESELECTOTHERS | SVSI_EDIT | SVSI_ENSUREVISIBLE | SVSI_FOCUSED | SVSI_SELECT); - lpSV->Release(); - return S_OK; - } - } - return E_FAIL; -} - -HRESULT CDefaultContextMenu::DoProperties( LPCMINVOKECOMMANDINFO lpcmi) { - WCHAR wszBuf[MAX_PATH]; - STRRET strFile; - const ITEMIDLIST *pidlParent, *pidlChild; HRESULT hr = S_OK; - - pidlParent = m_Dcm.pidlFolder; + const ITEMIDLIST *pidlParent = m_Dcm.pidlFolder, *pidlChild; + if (!pidlParent) { IPersistFolder2 *pf; @@ -1448,6 +1383,7 @@ } else if (_ILIsDrive(pidlChild)) { + WCHAR wszBuf[MAX_PATH]; ILGetDisplayName(pidlChild, wszBuf); if (!SH_ShowDriveProperties(wszBuf, pidlParent, &pidlChild)) hr = E_FAIL; @@ -1471,9 +1407,11 @@ if (m_Dcm.cidl > 1) WARN("SHMultiFileProperties is not yet implemented\n");
+ STRRET strFile; hr = m_Dcm.psf->GetDisplayNameOf(pidlChild, SHGDN_FORPARSING, &strFile); if (SUCCEEDED(hr)) { + WCHAR wszBuf[MAX_PATH]; hr = StrRetToBufW(&strFile, pidlChild, wszBuf, _countof(wszBuf)); if (SUCCEEDED(hr)) hr = SH_ShowPropertiesDialog(wszBuf, pidlParent, &pidlChild); @@ -1497,15 +1435,15 @@ CDefaultContextMenu::DoFormat( LPCMINVOKECOMMANDINFO lpcmi) { - char sDrive[5] = {0}; - - if (!_ILGetDrive(m_Dcm.apidl[0], sDrive, sizeof(sDrive))) + char szDrive[8] = {0}; + + if (!_ILGetDrive(m_Dcm.apidl[0], szDrive, sizeof(szDrive))) { ERR("pidl is not a drive\n"); return E_FAIL; }
- SHFormatDrive(lpcmi->hwnd, sDrive[0] - 'A', SHFMT_ID_DEFAULT, 0); + SHFormatDrive(lpcmi->hwnd, szDrive[0] - 'A', SHFMT_ID_DEFAULT, 0); return S_OK; }
@@ -1513,22 +1451,22 @@ CDefaultContextMenu::DoDynamicShellExtensions( LPCMINVOKECOMMANDINFO lpcmi) { - UINT verb = LOWORD(lpcmi->lpVerb); - PDynamicShellEntry pCurrent = m_pDynamicEntries; + UINT idCmd = LOWORD(lpcmi->lpVerb); + PDynamicShellEntry pEntry = m_pDynamicEntries;
TRACE("verb %p first %x last %x", lpcmi->lpVerb, m_iIdSHEFirst, m_iIdSHELast);
- while(pCurrent && verb > pCurrent->iIdCmdFirst + pCurrent->NumIds) - pCurrent = pCurrent->Next; - - if (!pCurrent) - return E_FAIL; - - if (verb >= pCurrent->iIdCmdFirst && verb <= pCurrent->iIdCmdFirst + pCurrent->NumIds) + while(pEntry && idCmd > pEntry->iIdCmdFirst + pEntry->NumIds) + pEntry = pEntry->pNext; + + if (!pEntry) + return E_FAIL; + + if (idCmd >= pEntry->iIdCmdFirst && idCmd <= pEntry->iIdCmdFirst + pEntry->NumIds) { /* invoke the dynamic context menu */ - lpcmi->lpVerb = MAKEINTRESOURCEA(verb - pCurrent->iIdCmdFirst); - return pCurrent->CMenu->InvokeCommand(lpcmi); + lpcmi->lpVerb = MAKEINTRESOURCEA(idCmd - pEntry->iIdCmdFirst); + return pEntry->pCM->InvokeCommand(lpcmi); }
return E_FAIL; @@ -1539,20 +1477,17 @@ CDefaultContextMenu::DoStaticShellExtensions( LPCMINVOKECOMMANDINFO lpcmi) { + PStaticShellEntry pEntry = m_pStaticEntries; + INT iCmd = LOWORD(lpcmi->lpVerb) - m_iIdSCMFirst; + HRESULT hr; + + while (pEntry && (iCmd--) > 0) + pEntry = pEntry->pNext; + + if (iCmd > 0) + return E_FAIL; + STRRET strFile; - WCHAR szPath[MAX_PATH]; - WCHAR szDir[MAX_PATH]; - SHELLEXECUTEINFOW sei; - PStaticShellEntry pCurrent = m_pStaticEntries; - int verb = LOWORD(lpcmi->lpVerb) - m_iIdSCMFirst; - HRESULT hr; - - while(pCurrent && verb-- > 0) - pCurrent = pCurrent->Next; - - if (verb > 0) - return E_FAIL; - hr = m_Dcm.psf->GetDisplayNameOf(m_Dcm.apidl[0], SHGDN_FORPARSING, &strFile); if (hr != S_OK) { @@ -1560,22 +1495,25 @@ return hr; }
- hr = StrRetToBufW(&strFile, m_Dcm.apidl[0], szPath, MAX_PATH); + WCHAR wszPath[MAX_PATH]; + hr = StrRetToBufW(&strFile, m_Dcm.apidl[0], wszPath, MAX_PATH); if (hr != S_OK) return hr;
- wcscpy(szDir, szPath); - PathRemoveFileSpec(szDir); - + WCHAR wszDir[MAX_PATH]; + wcscpy(wszDir, wszPath); + PathRemoveFileSpec(wszDir); + + SHELLEXECUTEINFOW sei; ZeroMemory(&sei, sizeof(sei)); sei.cbSize = sizeof(sei); sei.fMask = SEE_MASK_CLASSNAME; - sei.lpClass = pCurrent->szClass; + sei.lpClass = pEntry->szClass; sei.hwnd = lpcmi->hwnd; sei.nShow = SW_SHOWNORMAL; - sei.lpVerb = pCurrent->szVerb; - sei.lpFile = szPath; - sei.lpDirectory = szDir; + sei.lpVerb = pEntry->szVerb; + sei.lpFile = wszPath; + sei.lpDirectory = wszDir; ShellExecuteExW(&sei); return S_OK; } @@ -1623,17 +1561,13 @@ if (m_iIdSHEFirst && m_iIdSHELast) { if (LOWORD(lpcmi->lpVerb) >= m_iIdSHEFirst && LOWORD(lpcmi->lpVerb) <= m_iIdSHELast) - { return DoDynamicShellExtensions(lpcmi); - } }
if (m_iIdSCMFirst && m_iIdSCMLast) { if (LOWORD(lpcmi->lpVerb) >= m_iIdSCMFirst && LOWORD(lpcmi->lpVerb) <= m_iIdSCMLast) - { return DoStaticShellExtensions(lpcmi); - } }
FIXME("Unhandled Verb %xl\n", LOWORD(lpcmi->lpVerb)); @@ -1669,27 +1603,34 @@ REFIID riid, void **ppv) { - CComObject<CDefaultContextMenu> *theContextMenu; - CComPtr<IUnknown> result; - HRESULT hResult; - if (ppv == NULL) return E_POINTER; *ppv = NULL; - ATLTRY (theContextMenu = new CComObject<CDefaultContextMenu>); - if (theContextMenu == NULL) - return E_OUTOFMEMORY; - hResult = theContextMenu->QueryInterface(riid, (void **)&result); - if (FAILED(hResult)) - { - delete theContextMenu; - return hResult; - } - hResult = theContextMenu->Initialize(pdcm); - if (FAILED(hResult)) - return hResult; - *ppv = result.Detach(); - TRACE("This(%p)(%x) cidl %u\n", *ppv, hResult, pdcm->cidl); + + CComObject<CDefaultContextMenu> *pCM; + HRESULT hr = CComObject<CDefaultContextMenu>::CreateInstance(&pCM); + if (FAILED(hr)) + return hr; + pCM->AddRef(); // CreateInstance returns object with 0 ref count */ + + CComPtr<IUnknown> pResult; + hr = pCM->QueryInterface(riid, (void **)&pResult); + if (FAILED(hr)) + { + pCM->Release(); + return hr; + } + + hr = pCM->Initialize(pdcm); + if (FAILED(hr)) + { + pCM->Release(); + return hr; + } + + *ppv = pResult.Detach(); + pCM->Release(); + TRACE("This(%p) cidl %u\n", *ppv, pdcm->cidl); return S_OK; }
@@ -1705,10 +1646,8 @@ REFIID riid, void **ppv) { - HRESULT hr = E_FAIL; - *ppv = NULL; - hr = IDefaultContextMenu_Constructor(pdcm, riid, ppv); + HRESULT hr = IDefaultContextMenu_Constructor(pdcm, riid, ppv); if (FAILED(hr)) ERR("IDefaultContextMenu_Constructor failed: %x\n", hr); TRACE("pcm %p hr %x\n", pdcm, hr); @@ -1734,8 +1673,6 @@ IContextMenu **ppcm) { DEFCONTEXTMENU pdcm; - HRESULT hr; - pdcm.hwnd = hwnd; pdcm.pcmcb = NULL; pdcm.pidlFolder = pidlFolder; @@ -1746,7 +1683,7 @@ pdcm.cKeys = nKeys; pdcm.aKeys = ahkeyClsKeys;
- hr = SHCreateDefaultContextMenu(&pdcm, IID_IContextMenu, (void**)ppcm); + HRESULT hr = SHCreateDefaultContextMenu(&pdcm, IID_IContextMenu, (void**)ppcm); return hr; }
Modified: trunk/reactos/dll/win32/shell32/drive.cpp URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/shell32/drive.cpp... ============================================================================== --- trunk/reactos/dll/win32/shell32/drive.cpp [iso-8859-1] (original) +++ trunk/reactos/dll/win32/shell32/drive.cpp [iso-8859-1] Sun Jan 15 19:45:02 2012 @@ -123,11 +123,9 @@ { HPSXA hpsx = NULL; HPROPSHEETPAGE hpsp[MAX_PROPERTY_SHEET_PAGE]; - WCHAR wszName[256]; PROPSHEETHEADERW psh; - HRESULT hr; CComObject<CDrvDefExt> *pDrvDefExt = NULL; - + ZeroMemory(&psh, sizeof(PROPSHEETHEADERW)); psh.dwSize = sizeof(PROPSHEETHEADERW); psh.dwFlags = 0; // FIXME: make it modeless @@ -135,6 +133,7 @@ psh.nStartPage = 0; psh.phpage = hpsp;
+ WCHAR wszName[256]; if (GetVolumeInformationW(pwszDrive, wszName, sizeof(wszName) / sizeof(WCHAR), NULL, NULL, NULL, NULL, 0)) { psh.pszCaption = wszName; @@ -148,13 +147,14 @@ }
CComPtr<IDataObject> pDataObj; - hr = SHCreateDataObject(pidlFolder, 1, apidl, NULL, IID_IDataObject, (LPVOID *)&pDataObj); + HRESULT hr = SHCreateDataObject(pidlFolder, 1, apidl, NULL, IID_IDataObject, (LPVOID *)&pDataObj);
if (SUCCEEDED(hr)) { - ATLTRY(pDrvDefExt = new CComObject<CDrvDefExt>); - if (pDrvDefExt) - { + hr = CComObject<CDrvDefExt>::CreateInstance(&pDrvDefExt); + if (SUCCEEDED(hr)) + { + pDrvDefExt->AddRef(); // CreateInstance returns object with 0 ref count hr = pDrvDefExt->Initialize(pidlFolder, pDataObj, NULL); if (SUCCEEDED(hr)) {
Modified: trunk/reactos/dll/win32/shell32/fprop.cpp URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/shell32/fprop.cpp... ============================================================================== --- trunk/reactos/dll/win32/shell32/fprop.cpp [iso-8859-1] (original) +++ trunk/reactos/dll/win32/shell32/fprop.cpp [iso-8859-1] Sun Jan 15 19:45:02 2012 @@ -97,8 +97,6 @@ BOOL SH_ShowPropertiesDialog(LPCWSTR pwszPath, LPCITEMIDLIST pidlFolder, LPCITEMIDLIST *apidl) { - HRESULT hr; - HPROPSHEETPAGE hppages[MAX_PROPERTY_SHEET_PAGE]; HPSXA hpsxa[3] = {NULL, NULL, NULL}; CComObject<CFileDefExt> *pFileDefExt = NULL;
@@ -107,6 +105,7 @@ if (pwszPath == NULL || !wcslen(pwszPath)) return FALSE;
+ HPROPSHEETPAGE hppages[MAX_PROPERTY_SHEET_PAGE]; memset(hppages, 0x0, sizeof(HPROPSHEETPAGE) * MAX_PROPERTY_SHEET_PAGE);
/* Make a copy of path */ @@ -129,13 +128,14 @@ Header.pszCaption = PathFindFileNameW(wszPath);
CComPtr<IDataObject> pDataObj; - hr = SHCreateDataObject(pidlFolder, 1, apidl, NULL, IID_IDataObject, (LPVOID *)&pDataObj); + HRESULT hr = SHCreateDataObject(pidlFolder, 1, apidl, NULL, IID_IDataObject, (LPVOID *)&pDataObj);
if (SUCCEEDED(hr)) { - ATLTRY(pFileDefExt = new CComObject<CFileDefExt>); - if (pFileDefExt) + hr = CComObject<CFileDefExt>::CreateInstance(&pFileDefExt); + if (SUCCEEDED(hr)) { + pFileDefExt->AddRef(); // CreateInstance returns object with 0 ref count hr = pFileDefExt->Initialize(pidlFolder, pDataObj, NULL); if (SUCCEEDED(hr)) {