Author: rharabien
Date: Thu Jan 5 23:04:06 2012
New Revision: 54848
URL:
http://svn.reactos.org/svn/reactos?rev=54848&view=rev
Log:
[SHELL32]
- Fix few leaks and possible buffer overflows in New menu code
- Add icons of folder and shortcut to New menu
- Display message if file can't be created
Modified:
trunk/reactos/dll/win32/shell32/newmenu.cpp
trunk/reactos/dll/win32/shell32/newmenu.h
Modified: trunk/reactos/dll/win32/shell32/newmenu.cpp
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/shell32/newmenu.…
==============================================================================
--- trunk/reactos/dll/win32/shell32/newmenu.cpp [iso-8859-1] (original)
+++ trunk/reactos/dll/win32/shell32/newmenu.cpp [iso-8859-1] Thu Jan 5 23:04:06 2012
@@ -23,172 +23,194 @@
WINE_DEFAULT_DEBUG_CHANNEL(shell);
-static WCHAR szNew[MAX_PATH];
-
CNewMenu::CNewMenu()
{
- szPath = NULL;
- s_SnHead = NULL;
- fSite = NULL;
-}
-
+ m_wszPath = NULL;
+ m_pShellItems = NULL;
+ m_pSite = NULL;
+}
CNewMenu::~CNewMenu()
{
UnloadShellItems();
-}
-
-void CNewMenu::UnloadItem(SHELLNEW_ITEM *item)
+ if (m_hSubMenu)
+ CleanupMenu();
+}
+
+void CNewMenu::CleanupMenu()
+{
+ INT Count, Index;
+ MENUITEMINFOW mii;
+
+ /* get item count */
+ Count = GetMenuItemCount(m_hSubMenu);
+ if (Count == -1)
+ return;
+
+ /* setup menuitem info */
+ ZeroMemory(&mii, sizeof(mii));
+ mii.cbSize = sizeof(mii);
+ mii.fMask = MIIM_DATA | MIIM_FTYPE | MIIM_CHECKMARKS;
+
+ for(Index = 0; Index < Count; Index++)
+ {
+ if (GetMenuItemInfoW(m_hSubMenu, Index, TRUE, &mii))
+ {
+ if (mii.hbmpChecked)
+ DeleteObject(mii.hbmpChecked);
+ }
+ }
+}
+
+void CNewMenu::UnloadItem(SHELLNEW_ITEM *pItem)
{
// bail if the item is clearly invalid
- if (NULL == item)
+ if (NULL == pItem)
return;
- if (NULL != item->szTarget)
- free(item->szTarget);
-
- free(item->szDesc);
- free(item->szIcon);
- free(item->szExt);
-
- HeapFree(GetProcessHeap(), 0, item);
+ if (NULL != pItem->pwszTarget)
+ free(pItem->pwszTarget);
+
+ free(pItem->pwszDesc);
+ free(pItem->pwszIcon);
+ free(pItem->pwszExt);
+
+ HeapFree(GetProcessHeap(), 0, pItem);
}
void CNewMenu::UnloadShellItems()
{
SHELLNEW_ITEM *pCurItem;
- while (s_SnHead)
- {
- pCurItem = s_SnHead;
- s_SnHead = s_SnHead->Next;
+ while (m_pShellItems)
+ {
+ pCurItem = m_pShellItems;
+ m_pShellItems = m_pShellItems->pNext;
UnloadItem(pCurItem);
}
-
- s_SnHead = NULL;
-}
-
-static
-BOOL
-GetKeyDescription(LPWSTR szKeyName, LPWSTR szResult)
+}
+
+BOOL CNewMenu::GetKeyDescription(LPCWSTR pwszExt, LPWSTR pwszResult)
{
HKEY hKey;
- DWORD dwDesc, dwError;
- WCHAR szDesc[100];
-
- TRACE("GetKeyDescription: keyname %s\n", debugstr_w(szKeyName));
-
- if (RegOpenKeyExW(HKEY_CLASSES_ROOT, szKeyName, 0, KEY_READ | KEY_QUERY_VALUE,
&hKey) != ERROR_SUCCESS)
+ DWORD cbDesc;
+ WCHAR wszDesc[100];
+ LONG Result;
+
+ TRACE("GetKeyDescription: keyname %s\n", debugstr_w(pwszExt));
+
+ if (RegOpenKeyExW(HKEY_CLASSES_ROOT, pwszExt, 0, KEY_READ, &hKey) !=
ERROR_SUCCESS)
return FALSE;
- if (RegLoadMUIStringW(hKey, L"\\FriendlyTypeName", szResult, MAX_PATH,
&dwDesc, 0, NULL) == ERROR_SUCCESS)
- {
- TRACE("result %s\n", debugstr_w(szResult));
+ /* Get user friendly name */
+ if (RegLoadMUIStringW(hKey, L"\\FriendlyTypeName", pwszResult, MAX_PATH,
&cbDesc, 0, NULL) == ERROR_SUCCESS)
+ {
+ TRACE("result %s\n", debugstr_w(pwszResult));
RegCloseKey(hKey);
return TRUE;
}
- /* fetch default value */
- dwDesc = sizeof(szDesc);
- dwError = RegGetValueW(hKey, NULL, NULL, RRF_RT_REG_SZ, NULL, szDesc, &dwDesc);
- if(dwError == ERROR_SUCCESS)
- {
- if (wcsncmp(szKeyName, szDesc, dwDesc / sizeof(WCHAR)))
+
+ /* Fetch default value */
+ cbDesc = sizeof(wszDesc);
+ Result = RegGetValueW(hKey, NULL, L"", RRF_RT_REG_SZ, NULL, wszDesc,
&cbDesc);
+ if(Result == ERROR_SUCCESS)
+ {
+ if (wcscmp(pwszExt, wszDesc) != 0)
{
/* recurse for to a linked key */
- if (!GetKeyDescription(szDesc, szResult))
+ if (!GetKeyDescription(wszDesc, pwszResult))
{
/* use description */
- wcscpy(szResult, szDesc);
+ wcscpy(pwszResult, wszDesc);
}
}
else
{
/* use default value as description */
- wcscpy(szResult, szDesc);
+ wcscpy(pwszResult, wszDesc);
}
}
else
{
/* registry key w/o default key?? */
- TRACE("RegGetValue failed with %x\n", dwError);
- wcscpy(szResult, szKeyName);
+ ERR("RegGetValue failed with %x\n", Result);
+ wcscpy(pwszResult, pwszExt);
}
RegCloseKey(hKey);
return TRUE;
}
-CNewMenu::SHELLNEW_ITEM *CNewMenu::LoadItem(LPWSTR szKeyName)
+CNewMenu::SHELLNEW_ITEM *CNewMenu::LoadItem(LPCWSTR pwszExt)
{
HKEY hKey;
DWORD dwIndex = 0;
- WCHAR szName[MAX_PATH];
- WCHAR szCommand[MAX_PATH];
- WCHAR szDesc[MAX_PATH] = L"";
- WCHAR szIcon[MAX_PATH] = L"";
- DWORD dwName, dwCommand;
- LONG result;
+ WCHAR wszBuf[MAX_PATH];
+ WCHAR wszCommand[MAX_PATH];
+ WCHAR wszDesc[MAX_PATH] = L"";
+ WCHAR wszIcon[MAX_PATH] = L"";
+ DWORD cchName, cbCommand;
SHELLNEW_ITEM *pNewItem = NULL;
- wcscpy(szName, szKeyName);
- GetKeyDescription(szKeyName, szDesc);
- wcscat(szName, L"\\ShellNew");
- result = RegOpenKeyExW(HKEY_CLASSES_ROOT, szName, 0, KEY_READ, &hKey);
-
- TRACE("LoadItem dwName %d keyname %s szName %s szDesc %s szIcon %s\n",
dwName, debugstr_w(szKeyName), debugstr_w(szName), debugstr_w(szDesc),
debugstr_w(szIcon));
-
- if (result != ERROR_SUCCESS)
+ StringCbPrintfW(wszBuf, sizeof(wszBuf), L"%s\\ShellNew", pwszExt);
+
+ TRACE("LoadItem Keyname %s Name %s\n", debugstr_w(pwszExt),
debugstr_w(wszBuf));
+
+ if (RegOpenKeyExW(HKEY_CLASSES_ROOT, wszBuf, 0, KEY_READ, &hKey) !=
ERROR_SUCCESS)
{
TRACE("Failed to open key\n");
return NULL;
}
- do
- {
- dwName = MAX_PATH;
- dwCommand = MAX_PATH;
- result = RegEnumValueW(hKey, dwIndex, szName, &dwName, NULL, NULL,
(LPBYTE)szCommand, &dwCommand);
- if (result == ERROR_SUCCESS)
- {
- SHELLNEW_TYPE type = SHELLNEW_TYPE_INVALID;
- LPWSTR szTarget = szCommand;
-
- TRACE("szName %s szCommand %s\n", debugstr_w(szName),
debugstr_w(szCommand));
-
- if (!wcsicmp(szName, L"Command"))
- type = SHELLNEW_TYPE_COMMAND;
- else if (!wcsicmp(szName, L"Data"))
- type = SHELLNEW_TYPE_DATA;
- else if (!wcsicmp(szName, L"FileName"))
- type = SHELLNEW_TYPE_FILENAME;
- else if (!wcsicmp(szName, L"NullFile"))
- {
- type = SHELLNEW_TYPE_NULLFILE;
- szTarget = NULL;
- }
-
- if (type != SHELLNEW_TYPE_INVALID)
- {
- pNewItem = (SHELLNEW_ITEM *)HeapAlloc(GetProcessHeap(), 0,
sizeof(SHELLNEW_ITEM));
- if (!pNewItem)
- break;
-
- pNewItem->Type = type;
- if (szTarget)
- pNewItem->szTarget = _wcsdup(szTarget);
- else
- pNewItem->szTarget = NULL;
-
- pNewItem->szDesc = _wcsdup(szDesc);
- pNewItem->szIcon = _wcsdup(szIcon);
- pNewItem->szExt = _wcsdup(szKeyName);
- pNewItem->Next = NULL;
+ /* Find first valid value */
+ while (TRUE)
+ {
+ cchName = _countof(wszBuf);
+ cbCommand = sizeof(wszCommand);
+ if (RegEnumValueW(hKey, dwIndex++, wszBuf, &cchName, NULL, NULL,
(LPBYTE)wszCommand, &cbCommand) != ERROR_SUCCESS)
+ break;
+
+ SHELLNEW_TYPE Type = SHELLNEW_TYPE_INVALID;
+ LPWSTR pwszTarget = wszCommand;
+
+ TRACE("wszBuf %s wszCommand %s\n", debugstr_w(wszBuf),
debugstr_w(wszCommand));
+
+ /* Handle different types */
+ if (!wcsicmp(wszBuf, L"Command"))
+ Type = SHELLNEW_TYPE_COMMAND;
+ else if (!wcsicmp(wszBuf, L"Data"))
+ Type = SHELLNEW_TYPE_DATA;
+ else if (!wcsicmp(wszBuf, L"FileName"))
+ Type = SHELLNEW_TYPE_FILENAME;
+ else if (!wcsicmp(wszBuf, L"NullFile"))
+ {
+ Type = SHELLNEW_TYPE_NULLFILE;
+ pwszTarget = NULL;
+ }
+
+ /* Create new item */
+ if (Type != SHELLNEW_TYPE_INVALID)
+ {
+ pNewItem = (SHELLNEW_ITEM *)HeapAlloc(GetProcessHeap(), 0,
sizeof(SHELLNEW_ITEM));
+ if (!pNewItem)
break;
- }
- }
- dwIndex++;
- } while(result != ERROR_NO_MORE_ITEMS);
+
+ pNewItem->Type = Type;
+ if (pwszTarget)
+ pNewItem->pwszTarget = _wcsdup(pwszTarget);
+ else
+ pNewItem->pwszTarget = NULL;
+
+ GetKeyDescription(pwszExt, wszDesc);
+ pNewItem->pwszDesc = _wcsdup(wszDesc);
+ pNewItem->pwszIcon = _wcsdup(wszIcon);
+ pNewItem->pwszExt = _wcsdup(pwszExt);
+ pNewItem->pNext = NULL;
+ break;
+ }
+ }
+
RegCloseKey(hKey);
return pNewItem;
}
@@ -196,71 +218,87 @@
BOOL
CNewMenu::LoadShellNewItems()
{
- DWORD dwIndex;
- WCHAR szName[MAX_PATH];
- LONG result;
+ DWORD dwIndex = 0;
+ WCHAR wszName[MAX_PATH];
SHELLNEW_ITEM *pNewItem;
SHELLNEW_ITEM *pCurItem = NULL;
- /* insert do new folder action */
- if (!LoadStringW(shell32_hInstance, FCIDM_SHVIEW_NEW, szNew, sizeof(szNew) /
sizeof(WCHAR)))
- szNew[0] = 0;
-
+ /* If there are any unload them */
UnloadShellItems();
- dwIndex = 0;
- do
- {
- result = RegEnumKeyW(HKEY_CLASSES_ROOT, dwIndex, szName, MAX_PATH);
- if (result == ERROR_SUCCESS)
- {
- pNewItem = LoadItem(szName);
- if (pNewItem)
- {
- if (!wcsicmp(pNewItem->szExt, L".lnk"))
+ /* Enumerate all extesions */
+ while (RegEnumKeyW(HKEY_CLASSES_ROOT, dwIndex++, wszName, _countof(wszName)) ==
ERROR_SUCCESS)
+ {
+ if (wszName[0] != '.' || wcsicmp(wszName, L".lnk") == 0)
+ continue;
+
+ pNewItem = LoadItem(wszName);
+ if (pNewItem)
+ {
+ if (!wcsicmp(pNewItem->pwszExt, L".lnk"))
+ {
+ /* FIXME: Should we load them?
+ Add lnk handlers to begin of the list */
+ if (m_pShellItems)
{
- if (s_SnHead)
- {
- pNewItem->Next = s_SnHead;
- s_SnHead = pNewItem;
- }
- else
- {
- s_SnHead = pCurItem = pNewItem;
- }
+ pNewItem->pNext = m_pShellItems;
+ m_pShellItems = pNewItem;
}
else
+ m_pShellItems = pCurItem = pNewItem;
+ }
+ else
+ {
+ /* Add at the end of list */
+ if (pCurItem)
{
- if (pCurItem)
- {
- pCurItem->Next = pNewItem;
- pCurItem = pNewItem;
- }
- else
- {
- pCurItem = s_SnHead = pNewItem;
- }
+ pCurItem->pNext = pNewItem;
+ pCurItem = pNewItem;
}
- }
- }
- dwIndex++;
- } while(result != ERROR_NO_MORE_ITEMS);
-
- if (s_SnHead == NULL)
+ else
+ pCurItem = m_pShellItems = pNewItem;
+ }
+ }
+ }
+
+ if (m_pShellItems == NULL)
return FALSE;
else
return TRUE;
}
+static HBITMAP IconToBitmap(HICON hIcon)
+{
+ HDC hdc, hdcScr;
+ HBITMAP hbm, hbmOld;
+ RECT rc;
+
+ hdcScr = GetDC(NULL);
+ hdc = CreateCompatibleDC(hdcScr);
+ SetRect(&rc, 0, 0, GetSystemMetrics(SM_CXMENUCHECK),
GetSystemMetrics(SM_CYMENUCHECK));
+ hbm = CreateCompatibleBitmap(hdcScr, rc.right, rc.bottom);
+ ReleaseDC(NULL, hdcScr);
+
+ hbmOld = (HBITMAP)SelectObject(hdc, hbm);
+ FillRect(hdc, &rc, (HBRUSH)(COLOR_MENU + 1));
+ if (!DrawIconEx(hdc, 0, 0, hIcon, rc.right, rc.bottom, 0, NULL, DI_NORMAL))
+ ERR("DrawIcon failed: %x\n", GetLastError());
+ SelectObject(hdc, hbmOld);
+
+ DeleteDC(hdc);
+
+ return hbm;
+}
+
UINT
-CNewMenu::InsertShellNewItems(HMENU hMenu, UINT idFirst, UINT idMenu)
+CNewMenu::InsertShellNewItems(HMENU hMenu, UINT idCmdFirst, UINT Pos)
{
MENUITEMINFOW mii;
- SHELLNEW_ITEM *pCurItem;
- UINT i;
- WCHAR szBuffer[MAX_PATH];
-
- if (s_SnHead == NULL)
+ WCHAR wszBuf[256];
+ HICON hIcon;
+ UINT idCmd = idCmdFirst;
+
+ if (m_pShellItems == NULL)
{
if (!LoadShellNewItems())
return 0;
@@ -269,334 +307,279 @@
ZeroMemory(&mii, sizeof(mii));
mii.cbSize = sizeof(mii);
- /* insert do new shortcut action */
- if (!LoadStringW(shell32_hInstance, FCIDM_SHVIEW_NEWFOLDER, szBuffer,
sizeof(szBuffer) / sizeof(szBuffer[0])))
- szBuffer[0] = 0;
- szBuffer[MAX_PATH-1] = 0;
+ /* Insert new folder action */
+ if (!LoadStringW(shell32_hInstance, FCIDM_SHVIEW_NEWFOLDER, wszBuf,
_countof(wszBuf)))
+ wszBuf[0] = 0;
mii.fMask = MIIM_ID | MIIM_TYPE | MIIM_STATE | MIIM_DATA;
mii.fType = MFT_STRING;
- mii.dwTypeData = szBuffer;
+ mii.dwTypeData = wszBuf;
mii.cch = wcslen(mii.dwTypeData);
- mii.wID = idFirst++;
- InsertMenuItemW(hMenu, idMenu++, TRUE, &mii);
-
- /* insert do new shortcut action */
- if (!LoadStringW(shell32_hInstance, FCIDM_SHVIEW_NEWLINK, szBuffer, sizeof(szBuffer)
/ sizeof(szBuffer[0])))
- szBuffer[0] = 0;
- szBuffer[MAX_PATH-1] = 0;
- mii.dwTypeData = szBuffer;
+ mii.wID = idCmd;
+ hIcon = (HICON)LoadImage(shell32_hInstance, MAKEINTRESOURCE(IDI_SHELL_FOLDER),
IMAGE_ICON, 0, 0, 0);
+ if (hIcon)
+ {
+ mii.fMask |= MIIM_CHECKMARKS;
+ mii.hbmpChecked = mii.hbmpUnchecked = IconToBitmap(hIcon);
+ }
+ if (InsertMenuItemW(hMenu, Pos++, TRUE, &mii))
+ ++idCmd;
+
+ /* Insert new shortcut action */
+ if (!LoadStringW(shell32_hInstance, FCIDM_SHVIEW_NEWLINK, wszBuf, _countof(wszBuf)))
+ wszBuf[0] = 0;
+ mii.dwTypeData = wszBuf;
mii.cch = wcslen(mii.dwTypeData);
- mii.wID = idFirst++;
- InsertMenuItemW(hMenu, idMenu++, TRUE, &mii);
-
- /* insert seperator for custom new action */
+ mii.wID = idCmdFirst++;
+ hIcon = (HICON)LoadImage(shell32_hInstance, MAKEINTRESOURCE(IDI_SHELL_SHORTCUT),
IMAGE_ICON, 0, 0, 0);
+ if (hIcon)
+ {
+ mii.fMask |= MIIM_CHECKMARKS;
+ mii.hbmpChecked = mii.hbmpUnchecked = IconToBitmap(hIcon);
+ }
+ if (InsertMenuItemW(hMenu, Pos++, TRUE, &mii))
+ ++idCmd;
+
+ /* Insert seperator for custom new action */
mii.fMask = MIIM_TYPE | MIIM_ID;
mii.fType = MFT_SEPARATOR;
mii.wID = -1;
- InsertMenuItemW(hMenu, idMenu++, TRUE, &mii);
-
+ InsertMenuItemW(hMenu, Pos++, TRUE, &mii);
+
+ /* Insert rest of items */
mii.fMask = MIIM_ID | MIIM_TYPE | MIIM_STATE | MIIM_DATA;
/*
- * FIXME
+ * FIXME:
* implement loading of icons
* and using MFT_OWNERDRAWN
*/
mii.fType = MFT_STRING;
mii.fState = MFS_ENABLED;
- pCurItem = s_SnHead;
- i = 0;
-
- while(pCurItem)
- {
- if (i >= 1)
- {
- TRACE("szDesc %s\n", debugstr_w(pCurItem->szDesc));
- mii.dwTypeData = pCurItem->szDesc;
- mii.cch = wcslen(mii.dwTypeData);
- mii.wID = idFirst++;
- InsertMenuItemW(hMenu, idMenu++, TRUE, &mii);
- }
- pCurItem = pCurItem->Next;
- i++;
- }
- return (i + 2);
+ SHELLNEW_ITEM *pCurItem = m_pShellItems;
+ while (pCurItem)
+ {
+ TRACE("szDesc %s\n", debugstr_w(pCurItem->pwszDesc));
+ mii.dwTypeData = pCurItem->pwszDesc;
+ mii.cch = wcslen(mii.dwTypeData);
+ mii.wID = idCmd;
+ if (InsertMenuItemW(hMenu, Pos++, TRUE, &mii))
+ ++idCmd;
+ pCurItem = pCurItem->pNext;
+ }
+
+ return idCmd - idCmdFirst;
}
HRESULT
CNewMenu::DoShellNewCmd(LPCMINVOKECOMMANDINFO lpcmi, IShellView *psv)
{
- SHELLNEW_ITEM *pCurItem = s_SnHead;
- IPersistFolder3 * psf;
+ SHELLNEW_ITEM *pCurItem = m_pShellItems;
LPITEMIDLIST pidl;
STRRET strTemp;
- WCHAR szTemp[MAX_PATH];
- WCHAR szBuffer[MAX_PATH];
- WCHAR szPath[MAX_PATH];
- STARTUPINFOW sInfo;
- PROCESS_INFORMATION pi;
- UINT i, target;
- HANDLE hFile;
- DWORD dwWritten, dwError;
- CComPtr<IFolderView> folderView;
- CComPtr<IShellFolder> parentFolder;
- HRESULT hResult;
-
- i = 1;
- target = LOWORD(lpcmi->lpVerb);
-
- while(pCurItem)
- {
- if (i == target)
+ WCHAR wszBuf[MAX_PATH];
+ WCHAR wszPath[MAX_PATH];
+ UINT i, idCmd = LOWORD(lpcmi->lpVerb);
+ CComPtr<IFolderView> pFolderView;
+ CComPtr<IShellFolder> pParentFolder;
+ CComPtr<IPersistFolder3> psf;
+ HRESULT hr;
+
+ /* Find shell new item */
+ for (i = 1; pCurItem; ++i)
+ {
+ if (i == idCmd)
break;
- pCurItem = pCurItem->Next;
- i++;
+ pCurItem = pCurItem->pNext;
}
if (!pCurItem)
return E_UNEXPECTED;
-
- //if (fSite == NULL)
+ //if (m_pSite == NULL)
// return E_FAIL;
- hResult = IUnknown_QueryService(psv, SID_IFolderView, IID_IFolderView, (void
**)&folderView);
- if (FAILED(hResult))
- return hResult;
- hResult = folderView->GetFolder(IID_IShellFolder, (void **)&parentFolder);
- if (FAILED(hResult))
- return hResult;
-
- if (parentFolder->QueryInterface(IID_IPersistFolder2, (LPVOID*)&psf) != S_OK)
+
+ /* Get current folder */
+ hr = IUnknown_QueryService(psv, SID_IFolderView, IID_IFolderView, (void
**)&pFolderView);
+ if (FAILED(hr))
+ return hr;
+
+ hr = pFolderView->GetFolder(IID_IShellFolder, (void **)&pParentFolder);
+ if (FAILED(hr))
+ return hr;
+
+ if (pParentFolder->QueryInterface(IID_IPersistFolder2, (LPVOID*)&psf) !=
S_OK)
{
ERR("Failed to get interface IID_IPersistFolder2\n");
return E_FAIL;
}
+
if (psf->GetCurFolder(&pidl) != S_OK)
{
ERR("IPersistFolder2_GetCurFolder failed\n");
return E_FAIL;
}
- if (parentFolder == NULL || parentFolder->GetDisplayNameOf(pidl, SHGDN_FORPARSING,
&strTemp) != S_OK)
+ /* Get folder path */
+ if (pParentFolder == NULL || pParentFolder->GetDisplayNameOf(pidl,
SHGDN_FORPARSING, &strTemp) != S_OK)
{
ERR("IShellFolder_GetDisplayNameOf failed\n");
return E_FAIL;
}
- StrRetToBufW(&strTemp, pidl, szPath, MAX_PATH);
-
- switch(pCurItem->Type)
+ StrRetToBufW(&strTemp, pidl, wszPath, _countof(wszPath));
+
+ switch (pCurItem->Type)
{
case SHELLNEW_TYPE_COMMAND:
{
- LPWSTR ptr;
- LPWSTR szCmd;
-
- if (!ExpandEnvironmentStringsW(pCurItem->szTarget, szBuffer, MAX_PATH))
+ LPWSTR Ptr, pwszCmd;
+ WCHAR wszTemp[MAX_PATH];
+ STARTUPINFOW si;
+ PROCESS_INFORMATION pi;
+
+ if (!ExpandEnvironmentStringsW(pCurItem->pwszTarget, wszBuf, MAX_PATH))
{
TRACE("ExpandEnvironmentStrings failed\n");
break;
}
- ptr = wcsstr(szBuffer, L"%1");
- if (ptr)
- {
- ptr[1] = 's';
- swprintf(szTemp, szBuffer, szPath);
- ptr = szTemp;
+ /* Expand command parameter, FIXME: there can be more modifiers */
+ Ptr = wcsstr(wszBuf, L"%1");
+ if (Ptr)
+ {
+ Ptr[1] = 's';
+ StringCbPrintfW(wszTemp, sizeof(wszTemp), wszBuf, wszPath);
+ pwszCmd = wszTemp;
}
else
- {
- ptr = szBuffer;
- }
-
- ZeroMemory(&sInfo, sizeof(sInfo));
- sInfo.cb = sizeof(sInfo);
- szCmd = _wcsdup(ptr);
- if (!szCmd)
- break;
- if (CreateProcessW(NULL, szCmd, NULL, NULL, FALSE, 0, NULL, NULL, &sInfo,
&pi))
- {
- CloseHandle( pi.hProcess );
- CloseHandle( pi.hThread );
- }
- free(szCmd);
+ pwszCmd = wszBuf;
+
+ /* Create process */
+ ZeroMemory(&si, sizeof(si));
+ si.cb = sizeof(si);
+ if (CreateProcessW(NULL, pwszCmd, NULL, NULL, FALSE, 0, NULL, NULL, &si,
&pi))
+ {
+ CloseHandle(pi.hProcess);
+ CloseHandle(pi.hThread);
+ } else
+ ERR("Failed to create process\n");
break;
}
case SHELLNEW_TYPE_DATA:
case SHELLNEW_TYPE_FILENAME:
case SHELLNEW_TYPE_NULLFILE:
{
- i = 2;
-
- PathAddBackslashW(szPath);
- wcscat(szPath, szNew);
- wcscat(szPath, L" ");
- wcscat(szPath, pCurItem->szDesc);
- wcscpy(szBuffer, szPath);
- wcscat(szBuffer, pCurItem->szExt);
- do
- {
- hFile = CreateFileW(szBuffer, GENERIC_WRITE, 0, NULL, CREATE_NEW,
FILE_ATTRIBUTE_NORMAL, NULL);
+ BOOL bSuccess = TRUE;
+ LPWSTR pwszFilename = NULL;
+ size_t cchFilenameMax = 0;
+
+ /* Build new file name */
+ LoadStringW(shell32_hInstance, FCIDM_SHVIEW_NEW, wszBuf, _countof(wszBuf));
+ StringCchCatExW(wszPath, _countof(wszPath), L"\\",
&pwszFilename, &cchFilenameMax, 0);
+ StringCchPrintfW(pwszFilename, cchFilenameMax, L"%s %s%s", wszBuf,
pCurItem->pwszDesc, pCurItem->pwszExt);
+
+ /* Find unique name */
+ for (i = 2; PathFileExistsW(wszPath); ++i)
+ {
+ StringCchPrintfW(pwszFilename, cchFilenameMax, L"%s %s (%u)%s",
wszBuf, pCurItem->pwszDesc, i, pCurItem->pwszExt);
+ TRACE("New Filename %ls\n", pwszFilename);
+ }
+
+ if (pCurItem->Type == SHELLNEW_TYPE_DATA || pCurItem->Type ==
SHELLNEW_TYPE_NULLFILE)
+ {
+ /* Create new file */
+ HANDLE hFile = CreateFileW(wszPath, GENERIC_WRITE, 0, NULL, CREATE_NEW,
FILE_ATTRIBUTE_NORMAL, NULL);
if (hFile != INVALID_HANDLE_VALUE)
- break;
- dwError = GetLastError();
-
- TRACE("FileName %s szBuffer %s i %u error %x\n",
debugstr_w(szBuffer), debugstr_w(szPath), i, dwError);
- swprintf(szBuffer, L"%s (%d)%s", szPath, i,
pCurItem->szExt);
- i++;
- } while(hFile == INVALID_HANDLE_VALUE && dwError ==
ERROR_FILE_EXISTS);
-
- if (hFile == INVALID_HANDLE_VALUE)
- return E_FAIL;
-
- if (pCurItem->Type == SHELLNEW_TYPE_DATA)
- {
- i = WideCharToMultiByte(CP_ACP, 0, pCurItem->szTarget, -1,
(LPSTR)szTemp, MAX_PATH * 2, NULL, NULL);
- if (i)
{
- WriteFile(hFile, (LPCVOID)szTemp, i, &dwWritten, NULL);
+ if (pCurItem->Type == SHELLNEW_TYPE_DATA)
+ {
+ /* Write a content */
+ CHAR szTemp[256];
+ DWORD cbWritten, cbTemp = WideCharToMultiByte(CP_ACP, 0,
pCurItem->pwszTarget, -1, szTemp, _countof(szTemp), NULL, NULL);
+ if (cbTemp)
+ WriteFile(hFile, (LPCVOID)szTemp, cbTemp, &cbWritten,
NULL);
+ else
+ ERR("WideCharToMultiByte failed\n");
+ }
+
+ /* Close file now */
+ CloseHandle(hFile);
}
- }
- CloseHandle(hFile);
- if (pCurItem->Type == SHELLNEW_TYPE_FILENAME)
- {
- if (!CopyFileW(pCurItem->szTarget, szBuffer, FALSE))
- break;
- }
- TRACE("Notifying fs %s\n", debugstr_w(szBuffer));
- SHChangeNotify(SHCNE_CREATE, SHCNF_PATHW, (LPCVOID)szBuffer, NULL);
+ else bSuccess = FALSE;
+ }
+ else if (pCurItem->Type == SHELLNEW_TYPE_FILENAME)
+ {
+ /* Copy file */
+ bSuccess = CopyFileW(pCurItem->pwszTarget, wszPath, FALSE);
+ }
+
+ /* Show message if we failed */
+ if (bSuccess)
+ {
+ TRACE("Notifying fs %s\n", debugstr_w(wszPath));
+ SHChangeNotify(SHCNE_CREATE, SHCNF_PATHW, (LPCVOID)wszPath, NULL);
+ }
+ else
+ {
+ StringCbPrintfW(wszBuf, sizeof(wszBuf), L"Cannot create file:
%s", pwszFilename);
+ MessageBoxW(NULL, wszBuf, L"Cannot create file",
MB_OK|MB_ICONERROR); // FIXME
+ }
break;
- case SHELLNEW_TYPE_INVALID:
- break;
- }
+ }
+ case SHELLNEW_TYPE_INVALID:
+ ERR("Invalid type\n");
+ break;
}
return S_OK;
}
-/**************************************************************************
-* DoMeasureItem
-*/
-HRESULT
-CNewMenu::DoMeasureItem(HWND hWnd, MEASUREITEMSTRUCT * lpmis)
-{
- SHELLNEW_ITEM *pCurItem;
- SHELLNEW_ITEM *pItem;
- UINT i;
- HDC hDC;
- SIZE size;
-
- TRACE("DoMeasureItem entered with id %x\n", lpmis->itemID);
-
- pCurItem = s_SnHead;
-
- i = 1;
- pItem = NULL;
- while(pCurItem)
- {
- if (i == lpmis->itemID)
- {
- pItem = pCurItem;
- break;
- }
- pCurItem = pCurItem->Next;
- i++;
- }
-
- if (!pItem)
- {
- TRACE("DoMeasureItem no item found\n");
- return E_FAIL;
- }
- hDC = GetDC(hWnd);
- GetTextExtentPoint32W(hDC, pCurItem->szDesc, wcslen(pCurItem->szDesc),
&size);
- lpmis->itemWidth = size.cx + 32;
- lpmis->itemHeight = max(size.cy, 20);
- ReleaseDC (hWnd, hDC);
- return S_OK;
-}
-/**************************************************************************
-* DoDrawItem
-*/
-HRESULT
-CNewMenu::DoDrawItem(HWND hWnd, DRAWITEMSTRUCT * drawItem)
-{
- SHELLNEW_ITEM *pCurItem;
- SHELLNEW_ITEM *pItem;
- UINT i;
- pCurItem = s_SnHead;
-
- TRACE("DoDrawItem entered with id %x\n", drawItem->itemID);
-
- i = 1;
- pItem = NULL;
- while(pCurItem)
- {
- if (i == drawItem->itemID)
- {
- pItem = pCurItem;
- break;
- }
- pCurItem = pCurItem->Next;
- i++;
- }
-
- if (!pItem)
- return E_FAIL;
-
- drawItem->rcItem.left += 20;
-
- DrawTextW(drawItem->hDC, pCurItem->szDesc, wcslen(pCurItem->szDesc),
&drawItem->rcItem, 0);
- return S_OK;
-}
-
-/**************************************************************************
-* DoNewFolder
-*/
-void CNewMenu::DoNewFolder(
- IShellView *psv)
-{
- ISFHelper *psfhlp;
+
+void CNewMenu::CreateNewFolder(IShellView *psv)
+{
WCHAR wszName[MAX_PATH];
- CComPtr<IFolderView> folderView;
- CComPtr<IShellFolder> parentFolder;
- HRESULT hResult;
-
- //if (fSite == NULL)
+ CComPtr<ISFHelper> psfhlp;
+ CComPtr<IFolderView> pFolderView;
+ CComPtr<IShellFolder> pParentFolder;
+ HRESULT hr;
+
+ //if (m_pSite == NULL)
// return;
- hResult = IUnknown_QueryService(psv, SID_IFolderView, IID_IFolderView, (void
**)&folderView);
- if (FAILED(hResult))
+
+ /* Get current folder */
+ hr = IUnknown_QueryService(psv, SID_IFolderView, IID_IFolderView, (void
**)&pFolderView);
+ if (FAILED(hr))
return;
- hResult = folderView->GetFolder(IID_IShellFolder, (void **)&parentFolder);
- if (FAILED(hResult))
+
+ hr = pFolderView->GetFolder(IID_IShellFolder, (void **)&pParentFolder);
+ if (FAILED(hr))
return;
- parentFolder->QueryInterface(IID_ISFHelper, (LPVOID*)&psfhlp);
- if (psfhlp)
+ hr = pParentFolder->QueryInterface(IID_ISFHelper, (LPVOID*)&psfhlp);
+ if (SUCCEEDED(hr))
{
LPITEMIDLIST pidl;
- if (psfhlp->GetUniqueName(wszName, MAX_PATH) != S_OK)
+ /* Get unique name and create a folder */
+ if (psfhlp->GetUniqueName(wszName, _countof(wszName)) != S_OK)
return;
if (psfhlp->AddFolder(0, wszName, &pidl) != S_OK)
+ {
+ WCHAR wszBuf[256];
+ StringCbPrintfW(wszBuf, sizeof(wszBuf), L"Cannot create folder:
%s", wszName);
+ MessageBoxW(NULL, wszBuf, L"Cannot create folder",
MB_OK|MB_ICONERROR);
return;
-
- if(psv)
- {
- psv->Refresh();
- /* if we are in a shellview do labeledit */
- psv->SelectItem(
- pidl, (SVSI_DESELECTOTHERS | SVSI_EDIT | SVSI_ENSUREVISIBLE
- | SVSI_FOCUSED | SVSI_SELECT));
- psv->Refresh();
- }
+ }
+
+ /* Do a labeledit */
+ psv->Refresh();
+ psv->SelectItem(pidl, SVSI_DESELECTOTHERS | SVSI_EDIT | SVSI_ENSUREVISIBLE |
+ SVSI_FOCUSED | SVSI_SELECT);
+
SHFree(pidl);
-
- psfhlp->Release();
}
}
HRESULT STDMETHODCALLTYPE CNewMenu::SetSite(IUnknown *pUnkSite)
{
- fSite = pUnkSite;
+ m_pSite = pUnkSite;
return S_OK;
}
@@ -604,52 +587,51 @@
{
if (ppvSite == NULL)
return E_POINTER;
- *ppvSite = fSite;
- if (fSite != NULL)
- fSite->AddRef();
+ *ppvSite = m_pSite;
+ if (m_pSite != NULL)
+ m_pSite->AddRef();
return S_OK;
}
HRESULT
WINAPI
-CNewMenu::QueryContextMenu(HMENU hmenu,
+CNewMenu::QueryContextMenu(HMENU hMenu,
UINT indexMenu,
UINT idCmdFirst,
UINT idCmdLast,
UINT uFlags)
{
- WCHAR szBuffer[200];
+ WCHAR wszNew[200];
MENUITEMINFOW mii;
- HMENU hSubMenu;
- int id = 1;
+ UINT cItems = 0;
TRACE("%p %p %u %u %u %u\n", this,
- hmenu, indexMenu, idCmdFirst, idCmdLast, uFlags );
-
- if (!LoadStringW(shell32_hInstance, FCIDM_SHVIEW_NEW, szBuffer, _countof(szBuffer)))
- szBuffer[0] = 0;
-
- hSubMenu = CreateMenu();
- memset( &mii, 0, sizeof(mii) );
- mii.cbSize = sizeof (mii);
+ hMenu, indexMenu, idCmdFirst, idCmdLast, uFlags);
+
+ if (!LoadStringW(shell32_hInstance, FCIDM_SHVIEW_NEW, wszNew, _countof(wszNew)))
+ return E_FAIL;
+
+ m_hSubMenu = CreateMenu();
+ memset(&mii, 0, sizeof(mii));
+ mii.cbSize = sizeof(mii);
mii.fMask = MIIM_TYPE | MIIM_ID | MIIM_STATE;
mii.fType = MFT_STRING;
- mii.wID = idCmdFirst + id++;
- mii.dwTypeData = szBuffer;
+ mii.wID = -1;
+ mii.dwTypeData = wszNew;
mii.cch = wcslen(mii.dwTypeData);
mii.fState = MFS_ENABLED;
- if (hSubMenu)
- {
- id += InsertShellNewItems(hSubMenu, idCmdFirst, 0);
+ if (m_hSubMenu)
+ {
+ cItems = InsertShellNewItems(m_hSubMenu, idCmdFirst, 0);
mii.fMask |= MIIM_SUBMENU;
- mii.hSubMenu = hSubMenu;
- }
-
- if (!InsertMenuItemW(hmenu, indexMenu, TRUE, &mii))
+ mii.hSubMenu = m_hSubMenu;
+ }
+
+ if (!InsertMenuItemW(hMenu, indexMenu, TRUE, &mii))
return E_FAIL;
- return MAKE_HRESULT(SEVERITY_SUCCESS, 0, id);
+ return MAKE_HRESULT(SEVERITY_SUCCESS, 0, cItems);
}
HRESULT
@@ -660,24 +642,21 @@
LPSHELLVIEW lpSV = NULL;
HRESULT hr;
- if((lpSB = (LPSHELLBROWSER)SendMessageA(lpici->hwnd, CWM_GETISHELLBROWSER, 0,
0)))
- {
+ lpSB = (LPSHELLBROWSER)SendMessageA(lpici->hwnd, CWM_GETISHELLBROWSER, 0, 0);
+ if (lpSB)
lpSB->QueryActiveShellView(&lpSV);
- }
if (LOWORD(lpici->lpVerb) == 0)
{
- DoNewFolder(lpSV);
+ CreateNewFolder(lpSV);
return S_OK;
}
hr = DoShellNewCmd(lpici, lpSV);
if (SUCCEEDED(hr) && lpSV)
- {
lpSV->Refresh();
- }
-
- TRACE("INewItem_IContextMenu_fnInvokeCommand %x\n", hr);
+
+ TRACE("CNewMenu::InvokeCommand %x\n", hr);
return hr;
}
@@ -685,7 +664,7 @@
WINAPI
CNewMenu::GetCommandString(UINT_PTR idCmd,
UINT uType,
- UINT* pwReserved,
+ UINT *pwReserved,
LPSTR pszName,
UINT cchMax)
{
@@ -701,29 +680,13 @@
WPARAM wParam,
LPARAM lParam)
{
- DRAWITEMSTRUCT *lpids = (DRAWITEMSTRUCT*) lParam;
- MEASUREITEMSTRUCT *lpmis = (MEASUREITEMSTRUCT*) lParam;
-
- TRACE("INewItem_IContextMenu_fnHandleMenuMsg (%p)->(msg=%x wp=%lx
lp=%lx)\n", this, uMsg, wParam, lParam);
-
- switch(uMsg)
- {
- case WM_MEASUREITEM:
- return DoMeasureItem((HWND)wParam, lpmis);
- break;
- case WM_DRAWITEM:
- return DoDrawItem((HWND)wParam, lpids);
- break;
- }
+ UNIMPLEMENTED;
return S_OK;
-
- return E_UNEXPECTED;
}
HRESULT WINAPI
CNewMenu::Initialize(LPCITEMIDLIST pidlFolder,
- IDataObject *pdtobj, HKEY hkeyProgID )
-{
-
+ IDataObject *pdtobj, HKEY hkeyProgID)
+{
return S_OK;
}
Modified: trunk/reactos/dll/win32/shell32/newmenu.h
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/shell32/newmenu.…
==============================================================================
--- trunk/reactos/dll/win32/shell32/newmenu.h [iso-8859-1] (original)
+++ trunk/reactos/dll/win32/shell32/newmenu.h [iso-8859-1] Thu Jan 5 23:04:06 2012
@@ -41,29 +41,32 @@
struct SHELLNEW_ITEM
{
- SHELLNEW_TYPE Type;
- LPWSTR szExt;
- LPWSTR szTarget;
- LPWSTR szDesc;
- LPWSTR szIcon;
- SHELLNEW_ITEM *Next;
+ SHELLNEW_TYPE Type;
+ LPWSTR pwszExt;
+ LPWSTR pwszTarget;
+ LPWSTR pwszDesc;
+ LPWSTR pwszIcon;
+ SHELLNEW_ITEM *pNext;
};
- LPWSTR szPath;
- SHELLNEW_ITEM *s_SnHead;
- IUnknown* fSite;
+ LPWSTR m_wszPath;
+ SHELLNEW_ITEM *m_pShellItems;
+ IUnknown *m_pSite;
+ HMENU m_hSubMenu;
+
+ void CleanupMenu();
+ static BOOL GetKeyDescription(LPCWSTR pwszExt, LPWSTR pwszResult);
+ SHELLNEW_ITEM *LoadItem(LPCWSTR pwszExt);
+ void UnloadItem(SHELLNEW_ITEM *pItem);
+ void UnloadShellItems();
+ BOOL LoadShellNewItems();
+ UINT InsertShellNewItems(HMENU hMenu, UINT idFirst, UINT idMenu);
+ HRESULT DoShellNewCmd(LPCMINVOKECOMMANDINFO lpcmi, IShellView *psv);
+ void CreateNewFolder(IShellView *psv);
+
public:
CNewMenu();
~CNewMenu();
- SHELLNEW_ITEM *LoadItem(LPWSTR szKeyName);
- void UnloadItem(SHELLNEW_ITEM *item);
- void UnloadShellItems();
- BOOL LoadShellNewItems();
- UINT InsertShellNewItems(HMENU hMenu, UINT idFirst, UINT idMenu);
- HRESULT DoShellNewCmd(LPCMINVOKECOMMANDINFO lpcmi, IShellView * psv);
- HRESULT DoMeasureItem(HWND hWnd, MEASUREITEMSTRUCT *lpmis);
- HRESULT DoDrawItem(HWND hWnd, DRAWITEMSTRUCT *drawItem);
- void DoNewFolder(IShellView *psv);
// IObjectWithSite
virtual HRESULT STDMETHODCALLTYPE SetSite(IUnknown *pUnkSite);
@@ -72,7 +75,7 @@
// IContextMenu
virtual HRESULT WINAPI QueryContextMenu(HMENU hMenu, UINT indexMenu, UINT idCmdFirst,
UINT idCmdLast, UINT uFlags);
virtual HRESULT WINAPI InvokeCommand(LPCMINVOKECOMMANDINFO lpcmi);
- virtual HRESULT WINAPI GetCommandString(UINT_PTR idCommand,UINT uFlags, UINT
*lpReserved, LPSTR lpszName, UINT uMaxNameLen);
+ virtual HRESULT WINAPI GetCommandString(UINT_PTR idCommand, UINT uFlags, UINT
*lpReserved, LPSTR lpszName, UINT uMaxNameLen);
// IContextMenu2
virtual HRESULT WINAPI HandleMenuMsg(UINT uMsg, WPARAM wParam, LPARAM lParam);