Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

210 lines
4.7 KiB

// menucmd.cpp - Context menu command class
#include "stdafx.h"
#include "menucmd.h"
#include "streamio.h"
#include "qryitem.h"
#include "resource.h"
#include <shellapi.h>
#include <algorithm>
#include <atlgdi.h>
extern DWORD g_dwFileVer; // Current console file version (from compdata.cpp)
// Table of standard menu command parameters
// Gives order for parameter menu and maps ID to resource string
// Zero entry indicates menu separator
const MENU_PARAM_ENTRY MenuParamTable[MENU_PARAM_TABLE_LEN] =
{
{ MENU_PARAM_SCOPE, IDS_QUERY_SCOPE },
{ MENU_PARAM_FILTER, IDS_QUERY_FILTER },
{ MENU_PARAM_ID(0), 0 },
{ MENU_PARAM_NAME, IDS_NAME },
{ MENU_PARAM_TYPE, IDS_TYPE },
};
/////////////////////////////////////////////////////////////////////////////////////////
// CShellMenuCmd
HRESULT
CShellMenuCmd::Save(IStream& stm)
{
stm << m_menuID;
stm << m_dwFlags;
stm << m_strProgPath;
stm << m_strCmdLine;
stm << m_strStartDir;
stm << m_guidNoLocMenu;
return S_OK;
}
HRESULT
CShellMenuCmd::Load(IStream& stm)
{
stm >> m_menuID;
if (g_dwFileVer >= 101)
stm >> m_dwFlags;
stm >> m_strProgPath;
stm >> m_strCmdLine;
stm >> m_strStartDir;
if( g_dwFileVer >= 150 )
{
stm >> m_guidNoLocMenu;
}
return S_OK;
}
HRESULT
CShellMenuCmd::Execute(CParamLookup* pLookup, HANDLE* phProcess)
{
ASSERT(pLookup != NULL && phProcess != NULL);
*phProcess = NULL;
// Substitue parameter values in the command line
tstring strParam = m_strCmdLine;
HRESULT hr = ReplaceParameters(strParam, *pLookup, FALSE);
RETURN_ON_FAILURE(hr);
// Expand any environment variables
tstring strLocProgPath;
hr = ExpandEnvironmentParams(m_strProgPath, strLocProgPath);
RETURN_ON_FAILURE(hr);
tstring strLocStartDir;
hr = ExpandEnvironmentParams(m_strStartDir, strLocStartDir);
RETURN_ON_FAILURE(hr);
tstring strLocParam;
ExpandEnvironmentParams(strParam, strLocParam);
RETURN_ON_FAILURE(hr);
// Execute the command
SHELLEXECUTEINFO info;
info.cbSize = sizeof(info);
info.fMask = SEE_MASK_NOCLOSEPROCESS;
info.hwnd = NULL;
info.lpVerb = NULL;
info.lpFile = strLocProgPath.c_str();
info.lpParameters = strLocParam.c_str();
info.lpDirectory = strLocStartDir.c_str();
info.nShow = SW_SHOWNORMAL;
info. hInstApp = 0;
info.hProcess = 0;
*phProcess = info.hProcess;
BOOL bStat = ShellExecuteEx(&info);
if (!bStat)
return E_FAIL;
*phProcess = info.hProcess;
return S_OK;
}
/////////////////////////////////////////////////////////////////////////////////////////
// CActDirMenuCmd
HRESULT
CActDirMenuCmd::Save(IStream& stm)
{
stm << m_menuID;
stm << m_dwFlags;
stm << m_strADName;
stm << m_guidNoLocMenu;
stm << m_strADNoLocName;
return S_OK;
}
HRESULT
CActDirMenuCmd::Load(IStream& stm)
{
stm >> m_menuID;
if (g_dwFileVer >= 101)
stm >> m_dwFlags;
stm >> m_strADName;
if( g_dwFileVer >= 150 )
{
stm >> m_guidNoLocMenu;
stm >> m_strADNoLocName;
}
return S_OK;
}
//////////////////////////////////////////////////////////////////////
// menu vector stream i/o
IStream& operator<< (IStream& stm, menucmd_vector& vMenus)
{
stm << static_cast<long>(vMenus.size());
menucmd_vector::iterator itMenu;
for (itMenu = vMenus.begin(); itMenu != vMenus.end(); ++itMenu)
{
stm << static_cast<int>((*itMenu)->MenuType());
HRESULT hr = (*itMenu)->Save(stm);
THROW_ON_FAILURE(hr);
}
return stm;
}
IStream& operator>> (IStream& stm, menucmd_vector& vMenus)
{
long nItems;
stm >> nItems;
vMenus.reserve(nItems);
for (long lItem = 0; lItem < nItems; ++lItem)
{
CMenuCmd* pMenu = NULL;
int iType;
stm >> iType;
MENUTYPE type = static_cast<MENUTYPE>(iType);
switch (type)
{
case MENUTYPE_SHELL:
pMenu = new CShellMenuCmd();
ASSERT(pMenu != NULL);
break;
case MENUTYPE_ACTDIR:
pMenu = new CActDirMenuCmd();
ASSERT(pMenu != NULL);
break;
default:
THROW_ON_FAILURE(E_FAIL);
}
if( pMenu )
{
HRESULT hr = pMenu->Load(stm);
THROW_ON_FAILURE(hr);
vMenus.push_back(CMenuCmdPtr(pMenu));
}
}
return stm;
}