mirror of
https://github.com/ApfelTeeSaft/reactos.git
synced 2026-08-26 19:33:31 +00:00
[SHELL32][SHELL32_APITEST] Handle named registry verbs in CDefaultContextMenu::InvokeCommand (#9340)
CORE-20690
This commit is contained in:
@@ -17,6 +17,19 @@ CCopyMoveToMenu::CCopyMoveToMenu() :
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static BOOL
|
||||||
|
IsValidTarget(CCopyMoveToMenu *pThis, LPCITEMIDLIST pidl)
|
||||||
|
{
|
||||||
|
WCHAR szPath[MAX_PATH];
|
||||||
|
|
||||||
|
if (ILIsEqual(pidl, pThis->m_pidlFolder))
|
||||||
|
return pThis->GetFileOp() == FO_COPY;
|
||||||
|
|
||||||
|
szPath[0] = UNICODE_NULL;
|
||||||
|
SHGetPathFromIDListW(pidl, szPath);
|
||||||
|
return _ILIsDesktop(pidl) || PathFileExistsW(szPath);
|
||||||
|
}
|
||||||
|
|
||||||
static LRESULT CALLBACK
|
static LRESULT CALLBACK
|
||||||
WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
|
WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
|
||||||
{
|
{
|
||||||
@@ -62,20 +75,12 @@ WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
|
|||||||
static INT CALLBACK
|
static INT CALLBACK
|
||||||
BrowseCallbackProc(HWND hwnd, UINT uMsg, LPARAM lParam, LPARAM lpData)
|
BrowseCallbackProc(HWND hwnd, UINT uMsg, LPARAM lParam, LPARAM lpData)
|
||||||
{
|
{
|
||||||
CCopyMoveToMenu *this_ =
|
CCopyMoveToMenu *this_ = reinterpret_cast<CCopyMoveToMenu*>(lpData);
|
||||||
reinterpret_cast<CCopyMoveToMenu *>(GetWindowLongPtr(hwnd, GWLP_USERDATA));
|
|
||||||
|
|
||||||
switch (uMsg)
|
switch (uMsg)
|
||||||
{
|
{
|
||||||
case BFFM_INITIALIZED:
|
case BFFM_INITIALIZED:
|
||||||
{
|
{
|
||||||
SetWindowLongPtr(hwnd, GWLP_USERDATA, lpData);
|
|
||||||
this_ = reinterpret_cast<CCopyMoveToMenu *>(lpData);
|
|
||||||
|
|
||||||
// Select initial directory
|
|
||||||
SendMessageW(hwnd, BFFM_SETSELECTION, FALSE,
|
|
||||||
reinterpret_cast<LPARAM>(static_cast<LPCITEMIDLIST>(this_->m_pidlFolder)));
|
|
||||||
|
|
||||||
// Set caption
|
// Set caption
|
||||||
CString strCaption(MAKEINTRESOURCEW(this_->GetCaptionStringID()));
|
CString strCaption(MAKEINTRESOURCEW(this_->GetCaptionStringID()));
|
||||||
SetWindowTextW(hwnd, strCaption);
|
SetWindowTextW(hwnd, strCaption);
|
||||||
@@ -85,31 +90,30 @@ BrowseCallbackProc(HWND hwnd, UINT uMsg, LPARAM lParam, LPARAM lpData)
|
|||||||
SetDlgItemText(hwnd, IDOK, strCopyOrMove);
|
SetDlgItemText(hwnd, IDOK, strCopyOrMove);
|
||||||
|
|
||||||
// Subclassing
|
// Subclassing
|
||||||
|
// TODO: Replace this with BIF_VALIDATE
|
||||||
|
SetWindowLongPtr(hwnd, GWLP_USERDATA, lpData);
|
||||||
this_->m_fnOldWndProc =
|
this_->m_fnOldWndProc =
|
||||||
reinterpret_cast<WNDPROC>(
|
reinterpret_cast<WNDPROC>(
|
||||||
SetWindowLongPtr(hwnd, GWLP_WNDPROC, reinterpret_cast<LONG_PTR>(WindowProc)));
|
SetWindowLongPtr(hwnd, GWLP_WNDPROC, reinterpret_cast<LONG_PTR>(WindowProc)));
|
||||||
|
|
||||||
// Disable OK
|
// Expand "My Computer"
|
||||||
PostMessageW(hwnd, BFFM_ENABLEOK, 0, FALSE);
|
CComHeapPtr<ITEMIDLIST> drivesPidl(SHCloneSpecialIDList(hwnd, CSIDL_DRIVES, TRUE));
|
||||||
|
if (drivesPidl)
|
||||||
|
SendMessageW(hwnd, BFFM_SETEXPANDED, FALSE, (LPARAM)(LPITEMIDLIST)drivesPidl);
|
||||||
|
|
||||||
|
// Select initial directory
|
||||||
|
// TODO: Remember the last directory used by the user
|
||||||
|
CComHeapPtr<ITEMIDLIST> pidl(SHCloneSpecialIDList(hwnd, CSIDL_PERSONAL, TRUE));
|
||||||
|
if (pidl)
|
||||||
|
SendMessageW(hwnd, BFFM_SETSELECTION, FALSE, (LPARAM)(LPITEMIDLIST)pidl);
|
||||||
|
|
||||||
|
SendMessageW(hwnd, BFFM_ENABLEOK, 0, pidl && IsValidTarget(this_, pidl));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case BFFM_SELCHANGED:
|
case BFFM_SELCHANGED:
|
||||||
{
|
{
|
||||||
if (!this_)
|
|
||||||
break;
|
|
||||||
|
|
||||||
WCHAR szPath[MAX_PATH];
|
|
||||||
LPCITEMIDLIST pidl = reinterpret_cast<LPCITEMIDLIST>(lParam);
|
LPCITEMIDLIST pidl = reinterpret_cast<LPCITEMIDLIST>(lParam);
|
||||||
|
PostMessageW(hwnd, BFFM_ENABLEOK, 0, IsValidTarget(this_, pidl));
|
||||||
szPath[0] = 0;
|
|
||||||
SHGetPathFromIDListW(pidl, szPath);
|
|
||||||
|
|
||||||
if (ILIsEqual(pidl, this_->m_pidlFolder))
|
|
||||||
PostMessageW(hwnd, BFFM_ENABLEOK, 0, this_->GetFileOp() == FO_COPY);
|
|
||||||
else if (PathFileExistsW(szPath) || _ILIsDesktop(pidl))
|
|
||||||
PostMessageW(hwnd, BFFM_ENABLEOK, 0, TRUE);
|
|
||||||
else
|
|
||||||
PostMessageW(hwnd, BFFM_ENABLEOK, 0, FALSE);
|
|
||||||
|
|
||||||
// the text box will be updated later soon, ignore it
|
// the text box will be updated later soon, ignore it
|
||||||
this_->m_bIgnoreTextBoxChange = TRUE;
|
this_->m_bIgnoreTextBoxChange = TRUE;
|
||||||
@@ -123,6 +127,7 @@ BrowseCallbackProc(HWND hwnd, UINT uMsg, LPARAM lParam, LPARAM lpData)
|
|||||||
HRESULT
|
HRESULT
|
||||||
CCopyMoveToMenu::DoRealFileOp(const CIDA *pCIDA, LPCMINVOKECOMMANDINFO lpici, PCUIDLIST_ABSOLUTE pidlDestination)
|
CCopyMoveToMenu::DoRealFileOp(const CIDA *pCIDA, LPCMINVOKECOMMANDINFO lpici, PCUIDLIST_ABSOLUTE pidlDestination)
|
||||||
{
|
{
|
||||||
|
// TODO: Use SH32_SimulateDropWithSite instead
|
||||||
CStringW strFiles;
|
CStringW strFiles;
|
||||||
WCHAR szPath[MAX_PATH];
|
WCHAR szPath[MAX_PATH];
|
||||||
for (UINT n = 0; n < pCIDA->cidl; ++n)
|
for (UINT n = 0; n < pCIDA->cidl; ++n)
|
||||||
@@ -340,15 +345,13 @@ CCopyMoveToMenu::GetCommandString(
|
|||||||
LPSTR pszName,
|
LPSTR pszName,
|
||||||
UINT cchMax)
|
UINT cchMax)
|
||||||
{
|
{
|
||||||
|
#if 1 // Windows does not implement any of these but we will continue to do so as long as we (incorrectly) show them in the context menu
|
||||||
if ((uType | GCS_UNICODE) == GCS_VALIDATEW)
|
if ((uType | GCS_UNICODE) == GCS_VALIDATEW)
|
||||||
return idCmd == IDC_ACTION ? S_OK : S_FALSE;
|
return idCmd == IDC_ACTION ? S_OK : S_FALSE;
|
||||||
|
|
||||||
if (uType == GCS_VERBW && idCmd == IDC_ACTION)
|
if (uType == GCS_VERBW && idCmd == IDC_ACTION)
|
||||||
return SHAnsiToUnicode(GetVerb(), (LPWSTR)pszName, cchMax);
|
return SHAnsiToUnicode(GetVerb(), (LPWSTR)pszName, cchMax);
|
||||||
|
#endif
|
||||||
FIXME("%p %lu %u %p %p %u\n", this,
|
|
||||||
idCmd, uType, pwReserved, pszName, cchMax);
|
|
||||||
|
|
||||||
return E_NOTIMPL;
|
return E_NOTIMPL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -398,3 +401,30 @@ CCopyMoveToMenu::GetSite(REFIID riid, void **ppvSite)
|
|||||||
|
|
||||||
return m_pSite->QueryInterface(riid, ppvSite);
|
return m_pSite->QueryInterface(riid, ppvSite);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
HRESULT
|
||||||
|
CCopyMoveToMenu::DoCopyMoveToFolder(BOOL Copy, HWND hWnd, IUnknown *pSite,
|
||||||
|
IShellFolder *pSF, UINT cidl, PCUITEMID_CHILD_ARRAY pidls)
|
||||||
|
{
|
||||||
|
SFGAOF attr = SFGAO_CANCOPY | SFGAO_CANMOVE;
|
||||||
|
HRESULT hr = pSF->GetAttributesOf(cidl, pidls, &attr);
|
||||||
|
if (FAILED_UNEXPECTEDLY(hr))
|
||||||
|
return hr;
|
||||||
|
if (!(attr & (Copy ? SFGAO_CANCOPY : SFGAO_CANMOVE)))
|
||||||
|
return E_INVALIDARG;
|
||||||
|
|
||||||
|
CComPtr<IDataObject> pDO;
|
||||||
|
hr = pSF->GetUIObjectOf(hWnd, cidl, pidls, IID_NULL_PPV_ARG(IDataObject, &pDO));
|
||||||
|
if (FAILED_UNEXPECTEDLY(hr))
|
||||||
|
return hr;
|
||||||
|
|
||||||
|
REFCLSID clsid = Copy ? CLSID_CopyToMenu : CLSID_MoveToMenu;
|
||||||
|
CComPtr<IContextMenu> pCM;
|
||||||
|
hr = SHELL_InitializeExtension(clsid, NULL, pDO, NULL, IID_PPV_ARG(IContextMenu, &pCM));
|
||||||
|
if (FAILED_UNEXPECTEDLY(hr))
|
||||||
|
return hr;
|
||||||
|
IUnknown_SetSite(pCM, pSite);
|
||||||
|
|
||||||
|
CMINVOKECOMMANDINFO ici = { sizeof(ici), 0, hWnd, MAKEINTRESOURCEA(IDC_ACTION), NULL, NULL, SW_SHOW };
|
||||||
|
return pCM->InvokeCommand(&ici);
|
||||||
|
}
|
||||||
|
|||||||
@@ -46,6 +46,8 @@ public:
|
|||||||
// IObjectWithSite
|
// IObjectWithSite
|
||||||
STDMETHODIMP SetSite(IUnknown *pUnkSite) override;
|
STDMETHODIMP SetSite(IUnknown *pUnkSite) override;
|
||||||
STDMETHODIMP GetSite(REFIID riid, void **ppvSite) override;
|
STDMETHODIMP GetSite(REFIID riid, void **ppvSite) override;
|
||||||
|
|
||||||
|
static HRESULT DoCopyMoveToFolder(BOOL Copy, HWND hWnd, IUnknown *pSite, IShellFolder *pSF, UINT cidl, PCUITEMID_CHILD_ARRAY pidls);
|
||||||
};
|
};
|
||||||
|
|
||||||
class CCopyToMenu
|
class CCopyToMenu
|
||||||
|
|||||||
@@ -2487,25 +2487,9 @@ void CDefView::DoActivate(UINT uState)
|
|||||||
|
|
||||||
void CDefView::_DoCopyToMoveToFolder(BOOL bCopy)
|
void CDefView::_DoCopyToMoveToFolder(BOOL bCopy)
|
||||||
{
|
{
|
||||||
if (!GetSelections())
|
if (GetSelections())
|
||||||
return;
|
CCopyMoveToMenu::DoCopyMoveToFolder(bCopy, m_hWnd, static_cast<IDropTarget*>(this),
|
||||||
|
m_pSFParent, m_cidl, m_apidl);
|
||||||
SFGAOF rfg = SFGAO_CANCOPY | SFGAO_CANMOVE | SFGAO_FILESYSTEM;
|
|
||||||
HRESULT hr = m_pSFParent->GetAttributesOf(m_cidl, m_apidl, &rfg);
|
|
||||||
if (FAILED_UNEXPECTEDLY(hr))
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (!bCopy && !(rfg & SFGAO_CANMOVE))
|
|
||||||
return;
|
|
||||||
if (bCopy && !(rfg & SFGAO_CANCOPY))
|
|
||||||
return;
|
|
||||||
|
|
||||||
CComPtr<IContextMenu> pCM;
|
|
||||||
hr = m_pSFParent->GetUIObjectOf(m_hWnd, m_cidl, m_apidl, IID_IContextMenu, 0, (void **)&pCM);
|
|
||||||
if (FAILED_UNEXPECTEDLY(hr))
|
|
||||||
return;
|
|
||||||
|
|
||||||
InvokeContextMenuCommand(pCM, (bCopy ? "copyto" : "moveto"), NULL);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
LRESULT CDefView::OnActivate(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled)
|
LRESULT CDefView::OnActivate(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled)
|
||||||
|
|||||||
@@ -164,10 +164,7 @@ static const struct _StaticInvokeCommandMap_
|
|||||||
SHORT DfmCmd;
|
SHORT DfmCmd;
|
||||||
} g_StaticInvokeCmdMap[] =
|
} g_StaticInvokeCmdMap[] =
|
||||||
{
|
{
|
||||||
{ "runas", 0 }, // Unimplemented
|
// Note: Verbs from the registry should not be listed here
|
||||||
{ "print", 0 }, // Unimplemented
|
|
||||||
{ "preview", 0 }, // Unimplemented
|
|
||||||
{ "open", FCIDM_SHVIEW_OPEN },
|
|
||||||
{ CMDSTR_NEWFOLDERA, FCIDM_SHVIEW_NEWFOLDER, (SHORT)DFM_CMD_NEWFOLDER },
|
{ CMDSTR_NEWFOLDERA, FCIDM_SHVIEW_NEWFOLDER, (SHORT)DFM_CMD_NEWFOLDER },
|
||||||
{ "cut", FCIDM_SHVIEW_CUT, /* ? */ },
|
{ "cut", FCIDM_SHVIEW_CUT, /* ? */ },
|
||||||
{ "copy", FCIDM_SHVIEW_COPY, (SHORT)DFM_CMD_COPY },
|
{ "copy", FCIDM_SHVIEW_COPY, (SHORT)DFM_CMD_COPY },
|
||||||
@@ -176,8 +173,6 @@ static const struct _StaticInvokeCommandMap_
|
|||||||
{ "delete", FCIDM_SHVIEW_DELETE, (SHORT)DFM_CMD_DELETE },
|
{ "delete", FCIDM_SHVIEW_DELETE, (SHORT)DFM_CMD_DELETE },
|
||||||
{ "properties", FCIDM_SHVIEW_PROPERTIES, (SHORT)DFM_CMD_PROPERTIES },
|
{ "properties", FCIDM_SHVIEW_PROPERTIES, (SHORT)DFM_CMD_PROPERTIES },
|
||||||
{ "rename", FCIDM_SHVIEW_RENAME, (SHORT)DFM_CMD_RENAME },
|
{ "rename", FCIDM_SHVIEW_RENAME, (SHORT)DFM_CMD_RENAME },
|
||||||
{ "copyto", FCIDM_SHVIEW_COPYTO },
|
|
||||||
{ "moveto", FCIDM_SHVIEW_MOVETO },
|
|
||||||
};
|
};
|
||||||
|
|
||||||
PCSTR MapFcidmCmdToVerb(_In_ UINT_PTR CmdId)
|
PCSTR MapFcidmCmdToVerb(_In_ UINT_PTR CmdId)
|
||||||
@@ -328,7 +323,6 @@ class CDefaultContextMenu :
|
|||||||
UINT AddShellExtensionsToMenu(HMENU hMenu, UINT* pIndexMenu, UINT idCmdFirst, UINT idCmdLast, UINT uFlags);
|
UINT AddShellExtensionsToMenu(HMENU hMenu, UINT* pIndexMenu, UINT idCmdFirst, UINT idCmdLast, UINT uFlags);
|
||||||
UINT AddStaticContextMenusToMenu(HMENU hMenu, UINT* IndexMenu, UINT iIdCmdFirst, UINT iIdCmdLast, UINT uFlags);
|
UINT AddStaticContextMenusToMenu(HMENU hMenu, UINT* IndexMenu, UINT iIdCmdFirst, UINT iIdCmdLast, UINT uFlags);
|
||||||
HRESULT DoPaste(LPCMINVOKECOMMANDINFOEX lpcmi, BOOL bLink);
|
HRESULT DoPaste(LPCMINVOKECOMMANDINFOEX lpcmi, BOOL bLink);
|
||||||
HRESULT DoOpenOrExplore(LPCMINVOKECOMMANDINFOEX lpcmi);
|
|
||||||
HRESULT DoCreateLink(LPCMINVOKECOMMANDINFOEX lpcmi);
|
HRESULT DoCreateLink(LPCMINVOKECOMMANDINFOEX lpcmi);
|
||||||
HRESULT DoDelete(LPCMINVOKECOMMANDINFOEX lpcmi);
|
HRESULT DoDelete(LPCMINVOKECOMMANDINFOEX lpcmi);
|
||||||
HRESULT DoCopyOrCut(LPCMINVOKECOMMANDINFOEX lpcmi, BOOL bCopy);
|
HRESULT DoCopyOrCut(LPCMINVOKECOMMANDINFOEX lpcmi, BOOL bCopy);
|
||||||
@@ -336,7 +330,6 @@ class CDefaultContextMenu :
|
|||||||
HRESULT DoProperties(LPCMINVOKECOMMANDINFOEX lpcmi);
|
HRESULT DoProperties(LPCMINVOKECOMMANDINFOEX lpcmi);
|
||||||
HRESULT DoUndo(LPCMINVOKECOMMANDINFOEX lpcmi);
|
HRESULT DoUndo(LPCMINVOKECOMMANDINFOEX lpcmi);
|
||||||
HRESULT DoCreateNewFolder(LPCMINVOKECOMMANDINFOEX lpici);
|
HRESULT DoCreateNewFolder(LPCMINVOKECOMMANDINFOEX lpici);
|
||||||
HRESULT DoCopyToMoveToFolder(LPCMINVOKECOMMANDINFOEX lpici, BOOL bCopy);
|
|
||||||
HRESULT InvokeShellExt(LPCMINVOKECOMMANDINFOEX lpcmi);
|
HRESULT InvokeShellExt(LPCMINVOKECOMMANDINFOEX lpcmi);
|
||||||
HRESULT InvokeRegVerb(LPCMINVOKECOMMANDINFOEX lpcmi);
|
HRESULT InvokeRegVerb(LPCMINVOKECOMMANDINFOEX lpcmi);
|
||||||
DWORD BrowserFlagsFromVerb(LPCMINVOKECOMMANDINFOEX lpcmi, PStaticShellEntry pEntry);
|
DWORD BrowserFlagsFromVerb(LPCMINVOKECOMMANDINFOEX lpcmi, PStaticShellEntry pEntry);
|
||||||
@@ -345,6 +338,11 @@ class CDefaultContextMenu :
|
|||||||
PDynamicShellEntry GetDynamicEntry(UINT idCmd);
|
PDynamicShellEntry GetDynamicEntry(UINT idCmd);
|
||||||
BOOL MapVerbToCmdId(PVOID Verb, PUINT idCmd, BOOL IsUnicode);
|
BOOL MapVerbToCmdId(PVOID Verb, PUINT idCmd, BOOL IsUnicode);
|
||||||
|
|
||||||
|
HRESULT GetNoAssocError()
|
||||||
|
{
|
||||||
|
return LOBYTE(GetVersion()) < 6 ? E_INVALIDARG : HResultFromWin32(ERROR_NO_ASSOCIATION);
|
||||||
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
CDefaultContextMenu();
|
CDefaultContextMenu();
|
||||||
~CDefaultContextMenu();
|
~CDefaultContextMenu();
|
||||||
@@ -1108,13 +1106,6 @@ HRESULT CDefaultContextMenu::DoPaste(LPCMINVOKECOMMANDINFOEX lpcmi, BOOL bLink)
|
|||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
HRESULT
|
|
||||||
CDefaultContextMenu::DoOpenOrExplore(LPCMINVOKECOMMANDINFOEX lpcmi)
|
|
||||||
{
|
|
||||||
UNIMPLEMENTED;
|
|
||||||
return E_FAIL;
|
|
||||||
}
|
|
||||||
|
|
||||||
HRESULT CDefaultContextMenu::DoCreateLink(LPCMINVOKECOMMANDINFOEX lpcmi)
|
HRESULT CDefaultContextMenu::DoCreateLink(LPCMINVOKECOMMANDINFOEX lpcmi)
|
||||||
{
|
{
|
||||||
HRESULT hr = _DoInvokeCommandCallback(lpcmi, DFM_CMD_LINK);
|
HRESULT hr = _DoInvokeCommandCallback(lpcmi, DFM_CMD_LINK);
|
||||||
@@ -1239,43 +1230,6 @@ CDefaultContextMenu::DoUndo(LPCMINVOKECOMMANDINFOEX lpcmi)
|
|||||||
return E_NOTIMPL;
|
return E_NOTIMPL;
|
||||||
}
|
}
|
||||||
|
|
||||||
HRESULT
|
|
||||||
CDefaultContextMenu::DoCopyToMoveToFolder(LPCMINVOKECOMMANDINFOEX lpici, BOOL bCopy)
|
|
||||||
{
|
|
||||||
HRESULT hr = E_FAIL;
|
|
||||||
if (!m_pDataObj)
|
|
||||||
{
|
|
||||||
ERR("m_pDataObj is NULL\n");
|
|
||||||
return hr;
|
|
||||||
}
|
|
||||||
|
|
||||||
CComPtr<IContextMenu> pContextMenu;
|
|
||||||
if (bCopy)
|
|
||||||
hr = SHCoCreateInstance(NULL, &CLSID_CopyToMenu, NULL,
|
|
||||||
IID_PPV_ARG(IContextMenu, &pContextMenu));
|
|
||||||
else
|
|
||||||
hr = SHCoCreateInstance(NULL, &CLSID_MoveToMenu, NULL,
|
|
||||||
IID_PPV_ARG(IContextMenu, &pContextMenu));
|
|
||||||
if (FAILED_UNEXPECTEDLY(hr))
|
|
||||||
return hr;
|
|
||||||
|
|
||||||
CComPtr<IShellExtInit> pInit;
|
|
||||||
hr = pContextMenu->QueryInterface(IID_PPV_ARG(IShellExtInit, &pInit));
|
|
||||||
if (FAILED_UNEXPECTEDLY(hr))
|
|
||||||
return hr;
|
|
||||||
|
|
||||||
hr = pInit->Initialize(m_pidlFolder, m_pDataObj, NULL);
|
|
||||||
if (FAILED_UNEXPECTEDLY(hr))
|
|
||||||
return hr;
|
|
||||||
|
|
||||||
if (bCopy)
|
|
||||||
lpici->lpVerb = "copyto";
|
|
||||||
else
|
|
||||||
lpici->lpVerb = "moveto";
|
|
||||||
|
|
||||||
return pContextMenu->InvokeCommand((LPCMINVOKECOMMANDINFO)lpici);
|
|
||||||
}
|
|
||||||
|
|
||||||
// This code is taken from CNewMenu and should be shared between the 2 classes
|
// This code is taken from CNewMenu and should be shared between the 2 classes
|
||||||
HRESULT
|
HRESULT
|
||||||
CDefaultContextMenu::DoCreateNewFolder(
|
CDefaultContextMenu::DoCreateNewFolder(
|
||||||
@@ -1358,18 +1312,16 @@ BOOL
|
|||||||
CDefaultContextMenu::MapVerbToCmdId(PVOID Verb, PUINT idCmd, BOOL IsUnicode)
|
CDefaultContextMenu::MapVerbToCmdId(PVOID Verb, PUINT idCmd, BOOL IsUnicode)
|
||||||
{
|
{
|
||||||
WCHAR UnicodeStr[MAX_VERB];
|
WCHAR UnicodeStr[MAX_VERB];
|
||||||
|
UINT i;
|
||||||
|
|
||||||
/* Loop through all the static verbs looking for a match */
|
/* Loop through all the static verbs looking for a match */
|
||||||
for (UINT i = 0; i < _countof(g_StaticInvokeCmdMap); i++)
|
for (i = 0; i < _countof(g_StaticInvokeCmdMap); i++)
|
||||||
{
|
{
|
||||||
/* We can match both ANSI and unicode strings */
|
|
||||||
if (IsUnicode)
|
if (IsUnicode)
|
||||||
{
|
{
|
||||||
/* The static verbs are ANSI, get a unicode version before doing the compare */
|
|
||||||
SHAnsiToUnicode(g_StaticInvokeCmdMap[i].szStringVerb, UnicodeStr, MAX_VERB);
|
SHAnsiToUnicode(g_StaticInvokeCmdMap[i].szStringVerb, UnicodeStr, MAX_VERB);
|
||||||
if (!_wcsicmp(UnicodeStr, (LPWSTR)Verb))
|
if (!_wcsicmp(UnicodeStr, (LPWSTR)Verb))
|
||||||
{
|
{
|
||||||
/* Return the Corresponding Id */
|
|
||||||
*idCmd = g_StaticInvokeCmdMap[i].IntVerb;
|
*idCmd = g_StaticInvokeCmdMap[i].IntVerb;
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
@@ -1384,7 +1336,22 @@ CDefaultContextMenu::MapVerbToCmdId(PVOID Verb, PUINT idCmd, BOOL IsUnicode)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (POSITION it = m_DynamicEntries.GetHeadPosition(); it != NULL;)
|
POSITION it;
|
||||||
|
HRESULT hr = S_OK;
|
||||||
|
// Check the registry verbs
|
||||||
|
if (!IsUnicode)
|
||||||
|
hr = StringCchPrintfW(UnicodeStr, _countof(UnicodeStr), L"%hs", Verb);
|
||||||
|
for (i = 0, it = m_StaticEntries.GetHeadPosition(); it && SUCCEEDED(hr); ++i)
|
||||||
|
{
|
||||||
|
StaticShellEntry& entry = m_StaticEntries.GetNext(it);
|
||||||
|
if (!_wcsicmp(entry.Verb, UnicodeStr))
|
||||||
|
{
|
||||||
|
*idCmd = m_iIdSCMFirst + i;
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (it = m_DynamicEntries.GetHeadPosition(); it != NULL;)
|
||||||
{
|
{
|
||||||
DynamicShellEntry& entry = m_DynamicEntries.GetNext(it);
|
DynamicShellEntry& entry = m_DynamicEntries.GetNext(it);
|
||||||
if (!entry.NumIds)
|
if (!entry.NumIds)
|
||||||
@@ -1396,7 +1363,7 @@ CDefaultContextMenu::MapVerbToCmdId(PVOID Verb, PUINT idCmd, BOOL IsUnicode)
|
|||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return FALSE;
|
return FALSE; // Note: Even if the verb is "open", we must fail if we can't find a handler
|
||||||
}
|
}
|
||||||
|
|
||||||
HRESULT
|
HRESULT
|
||||||
@@ -1547,7 +1514,7 @@ CDefaultContextMenu::InvokeRegVerb(
|
|||||||
POSITION it = m_StaticEntries.FindIndex(iCmd);
|
POSITION it = m_StaticEntries.FindIndex(iCmd);
|
||||||
|
|
||||||
if (it == NULL)
|
if (it == NULL)
|
||||||
return E_INVALIDARG;
|
return HResultFromWin32(ERROR_NO_ASSOCIATION);
|
||||||
|
|
||||||
PStaticShellEntry pEntry = &m_StaticEntries.GetAt(it);
|
PStaticShellEntry pEntry = &m_StaticEntries.GetAt(it);
|
||||||
|
|
||||||
@@ -1670,7 +1637,7 @@ CDefaultContextMenu::InvokeCommand(
|
|||||||
if (MapVerbToCmdId((LPVOID)LocalInvokeInfo.lpVerb, &CmdId, FALSE))
|
if (MapVerbToCmdId((LPVOID)LocalInvokeInfo.lpVerb, &CmdId, FALSE))
|
||||||
LocalInvokeInfo.lpVerb = MAKEINTRESOURCEA(CmdId);
|
LocalInvokeInfo.lpVerb = MAKEINTRESOURCEA(CmdId);
|
||||||
else
|
else
|
||||||
return E_INVALIDARG;
|
return GetNoAssocError();
|
||||||
}
|
}
|
||||||
CmdId = LOWORD(LocalInvokeInfo.lpVerb);
|
CmdId = LOWORD(LocalInvokeInfo.lpVerb);
|
||||||
|
|
||||||
@@ -1719,10 +1686,6 @@ CDefaultContextMenu::InvokeCommand(
|
|||||||
case FCIDM_SHVIEW_INSERTLINK:
|
case FCIDM_SHVIEW_INSERTLINK:
|
||||||
Result = DoPaste(&LocalInvokeInfo, TRUE);
|
Result = DoPaste(&LocalInvokeInfo, TRUE);
|
||||||
break;
|
break;
|
||||||
case FCIDM_SHVIEW_OPEN:
|
|
||||||
case FCIDM_SHVIEW_EXPLORE:
|
|
||||||
Result = DoOpenOrExplore(&LocalInvokeInfo);
|
|
||||||
break;
|
|
||||||
case FCIDM_SHVIEW_COPY:
|
case FCIDM_SHVIEW_COPY:
|
||||||
case FCIDM_SHVIEW_CUT:
|
case FCIDM_SHVIEW_CUT:
|
||||||
Result = DoCopyOrCut(&LocalInvokeInfo, CmdId == FCIDM_SHVIEW_COPY);
|
Result = DoCopyOrCut(&LocalInvokeInfo, CmdId == FCIDM_SHVIEW_COPY);
|
||||||
@@ -1742,12 +1705,6 @@ CDefaultContextMenu::InvokeCommand(
|
|||||||
case FCIDM_SHVIEW_NEWFOLDER:
|
case FCIDM_SHVIEW_NEWFOLDER:
|
||||||
Result = DoCreateNewFolder(&LocalInvokeInfo);
|
Result = DoCreateNewFolder(&LocalInvokeInfo);
|
||||||
break;
|
break;
|
||||||
case FCIDM_SHVIEW_COPYTO:
|
|
||||||
Result = DoCopyToMoveToFolder(&LocalInvokeInfo, TRUE);
|
|
||||||
break;
|
|
||||||
case FCIDM_SHVIEW_MOVETO:
|
|
||||||
Result = DoCopyToMoveToFolder(&LocalInvokeInfo, FALSE);
|
|
||||||
break;
|
|
||||||
case FCIDM_SHVIEW_UNDO:
|
case FCIDM_SHVIEW_UNDO:
|
||||||
Result = DoUndo(&LocalInvokeInfo);
|
Result = DoUndo(&LocalInvokeInfo);
|
||||||
break;
|
break;
|
||||||
|
|||||||
@@ -9,7 +9,7 @@
|
|||||||
|
|
||||||
WINE_DEFAULT_DEBUG_CHANNEL(shell);
|
WINE_DEFAULT_DEBUG_CHANNEL(shell);
|
||||||
|
|
||||||
HRESULT
|
EXTERN_C HRESULT
|
||||||
SHELL_GetShellExtensionRegCLSID(HKEY hKey, LPCWSTR KeyName, CLSID *pClsId)
|
SHELL_GetShellExtensionRegCLSID(HKEY hKey, LPCWSTR KeyName, CLSID *pClsId)
|
||||||
{
|
{
|
||||||
// First try the key name
|
// First try the key name
|
||||||
@@ -22,7 +22,7 @@ SHELL_GetShellExtensionRegCLSID(HKEY hKey, LPCWSTR KeyName, CLSID *pClsId)
|
|||||||
return !err ? SHCLSIDFromStringW(buf, pClsId) : HRESULT_FROM_WIN32(err);
|
return !err ? SHCLSIDFromStringW(buf, pClsId) : HRESULT_FROM_WIN32(err);
|
||||||
}
|
}
|
||||||
|
|
||||||
static HRESULT
|
EXTERN_C HRESULT
|
||||||
SHELL_InitializeExtension(REFCLSID clsid, PCIDLIST_ABSOLUTE pidlFolder, IDataObject *pDO, HKEY hkeyProgID, REFIID riid, void **ppv)
|
SHELL_InitializeExtension(REFCLSID clsid, PCIDLIST_ABSOLUTE pidlFolder, IDataObject *pDO, HKEY hkeyProgID, REFIID riid, void **ppv)
|
||||||
{
|
{
|
||||||
*ppv = NULL;
|
*ppv = NULL;
|
||||||
|
|||||||
@@ -1831,7 +1831,6 @@ static HRESULT ShellExecute_ContextMenuVerb(LPSHELLEXECUTEINFOW sei)
|
|||||||
return hr;
|
return hr;
|
||||||
|
|
||||||
CComHeapPtr<char> verb, parameters, dir;
|
CComHeapPtr<char> verb, parameters, dir;
|
||||||
__SHCloneStrWtoA(&verb, sei->lpVerb);
|
|
||||||
__SHCloneStrWtoA(¶meters, sei->lpParameters);
|
__SHCloneStrWtoA(¶meters, sei->lpParameters);
|
||||||
__SHCloneStrWtoA(&dir, sei->lpDirectory);
|
__SHCloneStrWtoA(&dir, sei->lpDirectory);
|
||||||
|
|
||||||
@@ -1841,6 +1840,7 @@ static HRESULT ShellExecute_ContextMenuVerb(LPSHELLEXECUTEINFOW sei)
|
|||||||
ici.nShow = sei->nShow;
|
ici.nShow = sei->nShow;
|
||||||
if (!fDefault)
|
if (!fDefault)
|
||||||
{
|
{
|
||||||
|
__SHCloneStrWtoA(&verb, sei->lpVerb);
|
||||||
ici.lpVerb = verb;
|
ici.lpVerb = verb;
|
||||||
ici.lpVerbW = sei->lpVerb;
|
ici.lpVerbW = sei->lpVerb;
|
||||||
}
|
}
|
||||||
@@ -2185,6 +2185,19 @@ static void do_error_dialog(UINT_PTR retval, HWND hwnd, PCWSTR filename)
|
|||||||
SetLastError(error_code); // Restore
|
SetLastError(error_code); // Restore
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static UINT_PTR ExecuteFailed(UINT_PTR retval, SHELLEXECUTEINFOW &sei, LPCWSTR lpFile, BOOL AllowOpenWith = TRUE)
|
||||||
|
{
|
||||||
|
if (retval <= 32 && !(sei.fMask & SEE_MASK_FLAG_NO_UI))
|
||||||
|
{
|
||||||
|
if (retval == SE_ERR_NOASSOC && !(sei.fMask & SEE_MASK_CLASSALL) && AllowOpenWith)
|
||||||
|
retval = InvokeOpenWith(sei.hwnd, sei);
|
||||||
|
if (retval <= 32)
|
||||||
|
do_error_dialog(retval, sei.hwnd, lpFile);
|
||||||
|
}
|
||||||
|
sei.hInstApp = (HINSTANCE)UlongToHandle(retval > 32 ? 33 : retval);
|
||||||
|
return retval;
|
||||||
|
}
|
||||||
|
|
||||||
static WCHAR *expand_environment( const WCHAR *str )
|
static WCHAR *expand_environment( const WCHAR *str )
|
||||||
{
|
{
|
||||||
CHeapPtr<WCHAR, CLocalAllocator> buf;
|
CHeapPtr<WCHAR, CLocalAllocator> buf;
|
||||||
@@ -2351,8 +2364,7 @@ static BOOL SHELL_execute(LPSHELLEXECUTEINFOW sei, SHELL_ExecuteW32 execfunc)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* process the IDList */
|
/* process the IDList */
|
||||||
if (sei_tmp.fMask & SEE_MASK_IDLIST &&
|
if ((sei_tmp.fMask & SEE_MASK_INVOKEIDLIST) == SEE_MASK_IDLIST)
|
||||||
(sei_tmp.fMask & SEE_MASK_INVOKEIDLIST) != SEE_MASK_INVOKEIDLIST)
|
|
||||||
{
|
{
|
||||||
LPCITEMIDLIST pidl = (LPCITEMIDLIST)sei_tmp.lpIDList;
|
LPCITEMIDLIST pidl = (LPCITEMIDLIST)sei_tmp.lpIDList;
|
||||||
hr = SHGetNameAndFlagsW(pidl, SHGDN_FORPARSING, wszApplicationName, dwApplicationNameLen, NULL);
|
hr = SHGetNameAndFlagsW(pidl, SHGDN_FORPARSING, wszApplicationName, dwApplicationNameLen, NULL);
|
||||||
@@ -2385,6 +2397,9 @@ static BOOL SHELL_execute(LPSHELLEXECUTEINFOW sei, SHELL_ExecuteW32 execfunc)
|
|||||||
sei->hInstApp = (HINSTANCE)42;
|
sei->hInstApp = (HINSTANCE)42;
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
UINT err = HRESULT_FACILITY(hr) == FACILITY_WIN32 ? HRESULT_CODE(hr) : GetLastError();
|
||||||
|
SetLastError(err ? err : ERROR_ACCESS_DENIED);
|
||||||
|
return ExecuteFailed(retval, *sei, NULL, FALSE) > 32;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ERROR_SUCCESS == ShellExecute_FromContextMenuHandlers(&sei_tmp))
|
if (ERROR_SUCCESS == ShellExecute_FromContextMenuHandlers(&sei_tmp))
|
||||||
@@ -2588,16 +2603,10 @@ static BOOL SHELL_execute(LPSHELLEXECUTEINFOW sei, SHELL_ExecuteW32 execfunc)
|
|||||||
|
|
||||||
TRACE("retval %lu\n", retval);
|
TRACE("retval %lu\n", retval);
|
||||||
|
|
||||||
if (retval <= 32 && !(sei_tmp.fMask & SEE_MASK_FLAG_NO_UI))
|
|
||||||
{
|
|
||||||
if (retval == SE_ERR_NOASSOC && !(sei->fMask & SEE_MASK_CLASSALL))
|
|
||||||
retval = InvokeOpenWith(sei_tmp.hwnd, *sei);
|
|
||||||
if (retval <= 32)
|
if (retval <= 32)
|
||||||
do_error_dialog(retval, sei_tmp.hwnd, lpFile);
|
retval = ExecuteFailed(retval, *sei, lpFile);
|
||||||
}
|
|
||||||
|
|
||||||
sei->hInstApp = (HINSTANCE)(retval > 32 ? 33 : retval);
|
sei->hInstApp = (HINSTANCE)(retval > 32 ? 33 : retval);
|
||||||
|
|
||||||
return retval > 32;
|
return retval > 32;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -165,10 +165,11 @@ HGLOBAL RenderSHELLIDLIST (LPITEMIDLIST pidlRoot, LPITEMIDLIST * apidl, UINT cid
|
|||||||
HGLOBAL RenderFILENAMEA (LPITEMIDLIST pidlRoot, LPITEMIDLIST * apidl, UINT cidl) DECLSPEC_HIDDEN;
|
HGLOBAL RenderFILENAMEA (LPITEMIDLIST pidlRoot, LPITEMIDLIST * apidl, UINT cidl) DECLSPEC_HIDDEN;
|
||||||
HGLOBAL RenderFILENAMEW (LPITEMIDLIST pidlRoot, LPITEMIDLIST * apidl, UINT cidl) DECLSPEC_HIDDEN;
|
HGLOBAL RenderFILENAMEW (LPITEMIDLIST pidlRoot, LPITEMIDLIST * apidl, UINT cidl) DECLSPEC_HIDDEN;
|
||||||
|
|
||||||
HRESULT SHELL_GetShellExtensionRegCLSID(
|
EXTERN_C HRESULT
|
||||||
HKEY hKey,
|
SHELL_GetShellExtensionRegCLSID(HKEY hKey, LPCWSTR KeyName, CLSID *pClsId);
|
||||||
LPCWSTR KeyName,
|
EXTERN_C HRESULT
|
||||||
CLSID *pClsId);
|
SHELL_InitializeExtension(REFCLSID clsid, PCIDLIST_ABSOLUTE pidlFolder, IDataObject *pDO,
|
||||||
|
HKEY hkeyProgID, REFIID riid, void **ppv);
|
||||||
|
|
||||||
/* Change Notification */
|
/* Change Notification */
|
||||||
void InitChangeNotifications(void) DECLSPEC_HIDDEN;
|
void InitChangeNotifications(void) DECLSPEC_HIDDEN;
|
||||||
|
|||||||
@@ -46,7 +46,7 @@ list(APPEND SOURCE
|
|||||||
She.cpp
|
She.cpp
|
||||||
#ShellExec_RunDLL.cpp # Broke on Windows
|
#ShellExec_RunDLL.cpp # Broke on Windows
|
||||||
#ShellExecCmdLine.cpp # Broke on Windows
|
#ShellExecCmdLine.cpp # Broke on Windows
|
||||||
#ShellExecuteEx.cpp # Broke on Windows
|
ShellExecuteEx.cpp
|
||||||
#ShellExecuteW.cpp # Broke on Windows
|
#ShellExecuteW.cpp # Broke on Windows
|
||||||
ShellHook.cpp
|
ShellHook.cpp
|
||||||
ShellInfo.cpp
|
ShellInfo.cpp
|
||||||
|
|||||||
@@ -17,6 +17,27 @@
|
|||||||
#include <shellutils.h>
|
#include <shellutils.h>
|
||||||
#include "shell32_apitest_sub.h"
|
#include "shell32_apitest_sub.h"
|
||||||
|
|
||||||
|
static void RunTest(LPTHREAD_START_ROUTINE TestFunc, UINT TimeOut = 1000 * 30)
|
||||||
|
{
|
||||||
|
// These tests have a tendency to hang, kill it if it takes too long
|
||||||
|
HANDLE hThread = CreateThread(NULL, 0, TestFunc, NULL, 0, NULL);
|
||||||
|
if (hThread)
|
||||||
|
{
|
||||||
|
if (WaitForSingleObject(hThread, TimeOut) != WAIT_OBJECT_0)
|
||||||
|
TerminateThread(hThread, ERROR_OPERATION_ABORTED);
|
||||||
|
CloseHandle(hThread);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class T> static T& Reset(T &sei, UINT flags = SEE_MASK_FLAG_NO_UI)
|
||||||
|
{
|
||||||
|
ZeroMemory(&sei, sizeof(T));
|
||||||
|
sei.cbSize = sizeof(T);
|
||||||
|
sei.fMask = flags;
|
||||||
|
sei.nShow = SW_SHOW;
|
||||||
|
return sei;
|
||||||
|
}
|
||||||
|
|
||||||
static WCHAR s_win_dir[MAX_PATH];
|
static WCHAR s_win_dir[MAX_PATH];
|
||||||
static WCHAR s_sys_dir[MAX_PATH];
|
static WCHAR s_sys_dir[MAX_PATH];
|
||||||
static WCHAR s_win_notepad[MAX_PATH];
|
static WCHAR s_win_notepad[MAX_PATH];
|
||||||
@@ -511,8 +532,47 @@ static void test_DoInvalidDir(void)
|
|||||||
CloseHandle(sei.hProcess);
|
CloseHandle(sei.hProcess);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static DWORD CALLBACK Test_InvokeIdList(LPVOID)
|
||||||
|
{
|
||||||
|
CCoInit ComInit;
|
||||||
|
UINT err, ret;
|
||||||
|
WCHAR Path[MAX_PATH * 2];
|
||||||
|
CComHeapPtr<ITEMIDLIST> pidl;
|
||||||
|
SHELLEXECUTEINFOW sei;
|
||||||
|
|
||||||
|
Reset(sei, SEE_MASK_FLAG_NO_UI | SEE_MASK_INVOKEIDLIST).nShow = SW_HIDE;
|
||||||
|
GetSystemDirectoryW(Path, _countof(Path));
|
||||||
|
PathAppendW(Path, L"cmd.exe");
|
||||||
|
sei.lpParameters = L"/C exit 0";
|
||||||
|
sei.lpIDList = LPITEMIDLIST((pidl.Attach(ILCreateFromPathW(Path)), pidl));
|
||||||
|
if (!pidl)
|
||||||
|
{
|
||||||
|
skip("No exe to test\n");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
sei.lpVerb = NULL;
|
||||||
|
ok(ShellExecuteExW(&sei), "Failed with error %lu\n", GetLastError());
|
||||||
|
|
||||||
|
sei.lpVerb = L"open";
|
||||||
|
ok(ShellExecuteExW(&sei), "Failed with error %lu\n", GetLastError());
|
||||||
|
|
||||||
|
sei.lpVerb = L"Shell32_Test_DoesNotExist";
|
||||||
|
ret = ShellExecuteExW(&sei), err = GetLastError();
|
||||||
|
ok(!ret, "Expected failure\n");
|
||||||
|
ok_long(err, IsWindowsVistaOrGreater() ? ERROR_NO_ASSOCIATION : ERROR_INVALID_PARAMETER);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
START_TEST(ShellExecuteEx)
|
START_TEST(ShellExecuteEx)
|
||||||
{
|
{
|
||||||
|
RunTest(Test_InvokeIdList);
|
||||||
|
|
||||||
|
// FIXME: These tests are broken (silent skip for now)
|
||||||
|
if (!lstrcmpiW(L"", L""))
|
||||||
|
return;
|
||||||
|
|
||||||
#ifdef _WIN64
|
#ifdef _WIN64
|
||||||
skip("Win64 is not supported yet\n");
|
skip("Win64 is not supported yet\n");
|
||||||
return;
|
return;
|
||||||
|
|||||||
@@ -106,7 +106,7 @@ const struct test winetest_testlist[] =
|
|||||||
{ "She", func_She },
|
{ "She", func_She },
|
||||||
//{ "ShellExec_RunDLL", func_ShellExec_RunDLL }, Broke on Windows
|
//{ "ShellExec_RunDLL", func_ShellExec_RunDLL }, Broke on Windows
|
||||||
//{ "ShellExecCmdLine", func_ShellExecCmdLine }, Broke on Windows
|
//{ "ShellExecCmdLine", func_ShellExecCmdLine }, Broke on Windows
|
||||||
//{ "ShellExecuteEx", func_ShellExecuteEx }, Broke on Windows
|
{ "ShellExecuteEx", func_ShellExecuteEx }, // Mostly broken on Windows, only simple tests enabled
|
||||||
//{ "ShellExecuteW", func_ShellExecuteW }, Broke on Windows
|
//{ "ShellExecuteW", func_ShellExecuteW }, Broke on Windows
|
||||||
{ "ShellHook", func_ShellHook },
|
{ "ShellHook", func_ShellHook },
|
||||||
{ "ShellState", func_ShellState },
|
{ "ShellState", func_ShellState },
|
||||||
|
|||||||
Reference in New Issue
Block a user