windows-nt/Source/XPSP1/NT/shell/applets/autorun/dataitem.cpp

154 lines
4 KiB
C++
Raw Normal View History

2020-09-26 03:20:57 -05:00
#include <windows.h>
#include <shlwapi.h>
#include <commctrl.h>
#include "dataitem.h"
#include "resource.h"
#include "stdio.h"
#include "util.h"
#define ARRAYSIZE(x) (sizeof(x)/sizeof(x[0]))
#define EXPLORER_EXE_STRING TEXT("explorer.exe")
CDataItem::CDataItem()
{
m_pszTitle = m_pszCmdLine = m_pszArgs = NULL;
m_dwFlags = 0;
}
CDataItem::~CDataItem()
{
if ( m_pszTitle )
delete [] m_pszTitle;
if ( m_pszCmdLine )
delete [] m_pszCmdLine;
if ( m_pszArgs )
delete [] m_pszArgs;
}
BOOL CDataItem::SetData( LPTSTR szTitle, LPTSTR szCmd, LPTSTR szArgs, DWORD dwFlags, DWORD dwType)
{
TCHAR * psz;
// This function should only be called once or else we will leak like a, like a, a thing that leaks a lot.
ASSERT( NULL==m_pszTitle && NULL==m_pszMenuName && NULL==m_pszDescription && NULL==m_pszCmdLine && NULL==m_pszArgs );
m_pszTitle = new TCHAR[lstrlen(szTitle)+1];
if ( m_pszTitle )
lstrcpy( m_pszTitle, szTitle );
m_pszCmdLine = new TCHAR[lstrlen(szCmd)+1];
if ( m_pszCmdLine )
lstrcpy( m_pszCmdLine, szCmd );
if ( szArgs )
{
// Some commands don't have any args so this can remain NULL. This is only used
// if the executable requires arguments.
m_pszArgs = new TCHAR[lstrlen(szArgs)+1];
if ( m_pszArgs )
lstrcpy( m_pszArgs, szArgs );
}
m_dwType = dwType;
m_dwFlags = dwFlags;
return TRUE;
}
BOOL CDataItem::Invoke(HWND hwnd)
{
TCHAR szBuffer1[1000];
TCHAR szBuffer2[1000];
LPTSTR pszExecutable = NULL;
LPTSTR pszArgs = NULL;
if ( NULL != m_pszCmdLine )
{
ExpandEnvironmentStrings(m_pszCmdLine, szBuffer1, ARRAYSIZE(szBuffer1));
pszExecutable = szBuffer1;
}
if ( NULL != m_pszArgs )
{
ExpandEnvironmentStrings(m_pszArgs, szBuffer2, ARRAYSIZE(szBuffer2));
pszArgs = szBuffer2;
}
BOOL fResult = FALSE;
if (0 == strncmp(pszExecutable, EXPLORER_EXE_STRING, ARRAYSIZE(EXPLORER_EXE_STRING))) // explorer paths must be ShellExecuted
{
fResult = ((INT_PTR)ShellExecute(hwnd, TEXT("open"), pszArgs, NULL, NULL, SW_SHOWNORMAL) > 32);
}
else
{
TCHAR szDirectory[MAX_PATH];
if (GetModuleFileName(NULL, szDirectory, ARRAYSIZE(szDirectory)) &&
_PathRemoveFileSpec(szDirectory))
{
fResult = ((INT_PTR)ShellExecute(hwnd, NULL, pszExecutable, pszArgs, szDirectory, SW_SHOWNORMAL) > 32);
}
}
return fResult;
}
#define CH_WHACK TEXT(FILENAME_SEPARATOR)
// stolen from shlwapi
BOOL CDataItem::_PathRemoveFileSpec(LPTSTR pFile)
{
RIPMSG(pFile && IS_VALID_STRING_PTR(pFile, -1), "PathRemoveFileSpec: caller passed bad pFile");
if (pFile)
{
LPTSTR pT;
LPTSTR pT2 = pFile;
for (pT = pT2; *pT2; pT2 = CharNext(pT2))
{
if (*pT2 == CH_WHACK)
{
pT = pT2; // last "\" found, (we will strip here)
}
else if (*pT2 == TEXT(':')) // skip ":\" so we don't
{
if (pT2[1] ==TEXT('\\')) // strip the "\" from "C:\"
{
pT2++;
}
pT = pT2 + 1;
}
}
if (*pT == 0)
{
// didn't strip anything
return FALSE;
}
else if (((pT == pFile) && (*pT == CH_WHACK)) || // is it the "\foo" case?
((pT == pFile+1) && (*pT == CH_WHACK && *pFile == CH_WHACK))) // or the "\\bar" case?
{
// Is it just a '\'?
if (*(pT+1) != TEXT('\0'))
{
// Nope.
*(pT+1) = TEXT('\0');
return TRUE; // stripped something
}
else
{
// Yep.
return FALSE;
}
}
else
{
*pT = 0;
return TRUE; // stripped something
}
}
return FALSE;
}