Initial commit: Complete open-source Decal rebuild
All 5 phases of the open-source Decal rebuild: Phase 1: 14 decompiled .NET projects (Interop.*, Adapter, FileService, DecalUtil) Phase 2: 10 native DLLs rewritten as C# COM servers with matching GUIDs - DecalDat, DHS, SpellFilter, DecalInput, DecalNet, DecalFilters - Decal.Core, DecalControls, DecalRender, D3DService Phase 3: C++ shims for Inject.DLL (D3D9 hooking) and LauncherHook.DLL Phase 4: DenAgent WinForms tray application Phase 5: WiX installer and build script 25 C# projects building with 0 errors. Native C++ projects require VS 2022 + Windows SDK (x86). Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
commit
d1442e3747
1382 changed files with 170725 additions and 0 deletions
844
Native/DenAgent/DenAgentDlg.cpp
Normal file
844
Native/DenAgent/DenAgentDlg.cpp
Normal file
|
|
@ -0,0 +1,844 @@
|
|||
// DenAgentDlg.cpp : implementation file
|
||||
//
|
||||
|
||||
#include "stdafx.h"
|
||||
#include "DenAgent.h"
|
||||
#include "DenAgentDlg.h"
|
||||
#include "DownloaderDlg.h"
|
||||
#include "OptionsDlg.h"
|
||||
#include "ExportDlg.h"
|
||||
#include "TrayWnd.h"
|
||||
#include "AutoUpdate.h"
|
||||
|
||||
#include "..\Inject\InjectApi.h"
|
||||
|
||||
#include "AddRemoveDlg.h"
|
||||
#include ".\denagentdlg.h"
|
||||
|
||||
#ifdef _DEBUG
|
||||
#define new DEBUG_NEW
|
||||
#undef THIS_FILE
|
||||
static char THIS_FILE[] = __FILE__;
|
||||
#endif
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// CDenAgentDlg dialog
|
||||
|
||||
CDenAgentDlg::CDenAgentDlg(CWnd* pParent /*=NULL*/)
|
||||
: CDialog(CDenAgentDlg::IDD, pParent),
|
||||
m_pCurrentDrag ( NULL ), m_bDoingUpdate( false ), m_bDoUpdate( false )
|
||||
{
|
||||
//{{AFX_DATA_INIT(CDenAgentDlg)
|
||||
//}}AFX_DATA_INIT
|
||||
|
||||
// Load the icon, unload will be done automagically
|
||||
m_hIcon = AfxGetApp()->LoadIcon(IDR_TRAYICON);
|
||||
}
|
||||
|
||||
void CDenAgentDlg::DoDataExchange(CDataExchange* pDX)
|
||||
{
|
||||
CDialog::DoDataExchange(pDX);
|
||||
//{{AFX_DATA_MAP(CDenAgentDlg)
|
||||
DDX_Control(pDX, IDC_PLUGINS, m_wndPlugins);
|
||||
//}}AFX_DATA_MAP
|
||||
}
|
||||
|
||||
BEGIN_MESSAGE_MAP(CDenAgentDlg, CDialog)
|
||||
//{{AFX_MSG_MAP(CDenAgentDlg)
|
||||
ON_BN_CLICKED(IDC_REFRESH, OnRefresh)
|
||||
ON_BN_CLICKED(IDC_ADDREMOVE, OnAddremove)
|
||||
ON_BN_CLICKED(IDC_UPDATE, OnUpdate)
|
||||
ON_BN_CLICKED(IDC_OPTIONS, OnOptions)
|
||||
ON_NOTIFY(LVN_DELETEITEM, IDC_PLUGINS, OnDeleteitemPlugins)
|
||||
ON_NOTIFY(NM_CLICK, IDC_PLUGINS, OnClickPlugins)
|
||||
ON_NOTIFY(LVN_BEGINDRAG, IDC_PLUGINS, OnBegindragPlugins)
|
||||
ON_WM_MOUSEMOVE()
|
||||
ON_WM_LBUTTONUP()
|
||||
//}}AFX_MSG_MAP
|
||||
ON_BN_CLICKED(IDC_DELETE, OnBnClickedDelete)
|
||||
ON_BN_CLICKED(IDC_EXPORT, OnBnClickedExport)
|
||||
END_MESSAGE_MAP()
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// CDenAgentDlg message handlers
|
||||
|
||||
BOOL CDenAgentDlg::OnInitDialog()
|
||||
{
|
||||
CDialog::OnInitDialog();
|
||||
|
||||
SetForegroundWindow();
|
||||
BringWindowToTop();
|
||||
|
||||
// Create the decal object
|
||||
HRESULT hRes = ::CoCreateInstance ( __uuidof ( Decal ), NULL, CLSCTX_INPROC_SERVER, __uuidof ( IDecal ),
|
||||
reinterpret_cast< LPVOID * > ( &m_pDecal ) );
|
||||
|
||||
// Set up the list control and image list
|
||||
m_groups.Create ( IDB_GROUPS, 16, 0, RGB(255,0,255));
|
||||
m_wndPlugins.SetImageList ( &m_groups, LVSIL_SMALL );
|
||||
|
||||
// Prepare the column list
|
||||
CRect rcListClient;
|
||||
m_wndPlugins.GetClientRect ( rcListClient );
|
||||
|
||||
CClientDC dcList ( &m_wndPlugins );
|
||||
dcList.SelectObject ( m_wndPlugins.GetFont () );
|
||||
|
||||
int nVersionWidth = dcList.GetTextExtent ( CString ( _T( "100.00.00.00001" ) ) ).cx;
|
||||
|
||||
m_wndPlugins.InsertColumn ( 0, _T( "Component" ), LVCFMT_LEFT, rcListClient.Width () - nVersionWidth - 16, 0 );
|
||||
m_wndPlugins.InsertColumn ( 1, _T( "Version" ), LVCFMT_RIGHT, nVersionWidth, 1 );
|
||||
|
||||
m_wndPlugins.SetExtendedStyle ( LVS_EX_FULLROWSELECT | LVS_EX_INFOTIP );
|
||||
|
||||
if ( FAILED ( hRes ) )
|
||||
{
|
||||
AfxMessageBox ( _T( "Failed to create Decal Object." ) );
|
||||
EndDialog ( IDCANCEL );
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
loadPluginList ();
|
||||
|
||||
// Set the icon into the window for runtime
|
||||
SetIcon(m_hIcon, TRUE); // Set big icon
|
||||
SetIcon(m_hIcon, FALSE); // Set small icon
|
||||
|
||||
TCHAR szModule[ MAX_PATH ];
|
||||
::GetModuleFileName ( NULL, szModule, MAX_PATH );
|
||||
|
||||
CString strVersion;
|
||||
CDenAgentApp::getVersionString ( szModule, strVersion );
|
||||
CDenAgentApp::getVersionInfo ( szModule, iReleaseMajor, iReleaseMinor, iBuildMajor, iBuildMinor );
|
||||
|
||||
SetWindowText( CString("Decal Agent ") + strVersion );
|
||||
|
||||
updateFileInfo();
|
||||
|
||||
return TRUE; // return TRUE unless you set the focus to a control
|
||||
}
|
||||
|
||||
void CDenAgentDlg::OnRefresh()
|
||||
{
|
||||
loadPluginList ();
|
||||
}
|
||||
|
||||
void CDenAgentDlg::OnAddremove()
|
||||
{
|
||||
CFile cf;
|
||||
CFileStatus cfs;
|
||||
|
||||
RegKey key;
|
||||
CString strDecalPlugins("decalplugins.xml");
|
||||
|
||||
if( key.Create( HKEY_LOCAL_MACHINE, _T( "SOFTWARE\\Decal\\Agent" )) == ERROR_SUCCESS )
|
||||
{
|
||||
TCHAR szDecalDirectory[ MAX_PATH + 1];
|
||||
DWORD dwSize = MAX_PATH;
|
||||
|
||||
if(key.QueryStringValue( _T( "AgentPath" ), szDecalDirectory, &dwSize )==ERROR_SUCCESS)
|
||||
{
|
||||
strDecalPlugins = CString(szDecalDirectory) + "\\decalplugins.xml";
|
||||
}
|
||||
}
|
||||
|
||||
if(!cf.GetStatus(strDecalPlugins, cfs))
|
||||
{
|
||||
if(MessageBox("Your list of Decal Components is missing.\n\nWould like to Download them?", NULL, MB_YESNO)==IDYES)
|
||||
OnUpdate();
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
CTime modification_time = cfs.m_mtime;
|
||||
CTime now = CTime::GetCurrentTime ();
|
||||
|
||||
if((modification_time.GetDay() < now.GetDay()) && (modification_time.GetMonth() <= now.GetMonth()) && (modification_time.GetYear() <= now.GetYear()))
|
||||
if(MessageBox("Your list of Decal Components are outdated.\n\nWould you like to Update?", NULL, MB_YESNO)==IDYES)
|
||||
{
|
||||
m_bDoingUpdate = true;
|
||||
OnUpdate();
|
||||
}
|
||||
}
|
||||
|
||||
cAddRemoveDlg dlg( this );
|
||||
dlg.m_pDecal = m_pDecal;
|
||||
dlg.DoModal ();
|
||||
|
||||
loadPluginList ();
|
||||
}
|
||||
|
||||
int CDenAgentDlg::getDragInsertBefore ( CPoint &ptClient )
|
||||
{
|
||||
_ASSERTE ( m_pCurrentDrag != NULL );
|
||||
|
||||
CRect rc;
|
||||
m_wndPlugins.GetWindowRect ( rc );
|
||||
ScreenToClient ( rc );
|
||||
|
||||
ptClient.x = ptClient.x - rc.left;
|
||||
ptClient.y = ptClient.y - rc.top;
|
||||
|
||||
int nItemHit = m_wndPlugins.HitTest ( ptClient );
|
||||
|
||||
if ( nItemHit != -1 )
|
||||
{
|
||||
cPlugin *pPlugin = reinterpret_cast< cPlugin * > ( m_wndPlugins.GetItemData ( nItemHit ) );
|
||||
if ( pPlugin != NULL && pPlugin->m_dragimage == m_pCurrentDrag->m_dragimage )
|
||||
return nItemHit;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// Tries to update the local copy of decal
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void CDenAgentDlg::updateDecal(_variant_t vCodeBase) {
|
||||
USES_CONVERSION;
|
||||
|
||||
if (MessageBox("A New Version of Decal exists.\n\nWould you like to Update?",NULL, MB_ICONQUESTION | MB_YESNO) == IDYES) {
|
||||
ShellExecute(m_hWnd,"open",OLE2A(vCodeBase.bstrVal),0,0,0);
|
||||
EndDialog(0);
|
||||
GetParent()->DestroyWindow();
|
||||
PostQuitMessage(0);
|
||||
}
|
||||
}
|
||||
|
||||
struct cPluginGroup
|
||||
{
|
||||
LPCTSTR m_groupName,
|
||||
m_groupKey;
|
||||
int m_iconIndex;
|
||||
};
|
||||
|
||||
void CDenAgentDlg::loadPluginList ()
|
||||
{
|
||||
m_wndPlugins.SetRedraw ( FALSE );
|
||||
|
||||
int nTop = m_wndPlugins.GetTopIndex ();
|
||||
|
||||
// Save the original selection
|
||||
GUID idSelected = GUID_NULL;
|
||||
{
|
||||
POSITION pos = m_wndPlugins.GetFirstSelectedItemPosition ();
|
||||
if ( pos != NULL )
|
||||
{
|
||||
int nSelected = m_wndPlugins.GetNextSelectedItem ( pos );
|
||||
cPlugin *pPlugin = reinterpret_cast< cPlugin * > ( m_wndPlugins.GetItemData ( nSelected ) );
|
||||
if ( pPlugin != NULL )
|
||||
idSelected = pPlugin->m_id;
|
||||
}
|
||||
}
|
||||
|
||||
// Erase the contents of the list and collection
|
||||
m_wndPlugins.DeleteAllItems ();
|
||||
CDenAgentApp::importV1Plugins ();
|
||||
|
||||
USES_CONVERSION;
|
||||
|
||||
static cPluginGroup _groups[] = {
|
||||
{ _T( "Plugins" ), _T( "Plugins" ), 4 },
|
||||
{ _T( "Network Filters" ), _T( "NetworkFilters" ), 1 },
|
||||
{ _T( "File Filters" ), _T( "FileFilters" ), 1 },
|
||||
{ _T( "Services" ), _T( "Services" ), 0 },
|
||||
{ _T( "Surrogates" ), _T( "Surrogates" ), 3 },
|
||||
{ _T( "Input Actions" ), _T( "InputActions" ), 2 } },
|
||||
*_end_groups = _groups + sizeof ( _groups ) / sizeof ( cPluginGroup );
|
||||
|
||||
int nCount = 0;
|
||||
for ( cPluginGroup *i = _groups; i != _end_groups; ++ i )
|
||||
{
|
||||
int nGroup = m_wndPlugins.InsertItem ( LVIF_IMAGE | LVIF_TEXT, nCount ++, i->m_groupName, 0,
|
||||
0, i->m_iconIndex, 0 );
|
||||
|
||||
CComPtr<IDecalEnum> pEnum;
|
||||
HRESULT hRes = m_pDecal->get_Configuration ( _bstr_t ( i->m_groupKey ), GUID_NULL, &pEnum );
|
||||
_ASSERTE( SUCCEEDED ( hRes ) );
|
||||
|
||||
while ( pEnum->Next () == S_OK )
|
||||
{
|
||||
CLSID clsid;
|
||||
hRes = pEnum->get_ComClass ( &clsid );
|
||||
_ASSERTE ( SUCCEEDED ( hRes ) );
|
||||
|
||||
VARIANT_BOOL bEnabled;
|
||||
hRes = pEnum->get_Enabled ( &bEnabled );
|
||||
_ASSERTE ( SUCCEEDED ( hRes ) );
|
||||
|
||||
int nState = ( clsid == idSelected ) ? LVIS_SELECTED | LVIS_FOCUSED : 0;
|
||||
|
||||
LVITEM lvi = { LVIF_STATE | LVIF_IMAGE | LVIF_INDENT | LVIF_PARAM | LVIF_TEXT, nCount ++, 0,
|
||||
nState, nState, NULL, -1, ( bEnabled ) ? 6 : 5, reinterpret_cast< LPARAM > ( new cPlugin ( clsid, i->m_groupKey, !!bEnabled, i->m_iconIndex ) ), 1 };
|
||||
|
||||
CComBSTR strName;
|
||||
if ( SUCCEEDED ( pEnum->get_FriendlyName( &strName ) ) )
|
||||
lvi.pszText = OLE2T ( strName );
|
||||
else
|
||||
{
|
||||
LPOLESTR szProgID;
|
||||
if ( FAILED ( ::ProgIDFromCLSID ( clsid, &szProgID ) ) )
|
||||
{
|
||||
hRes = ::StringFromCLSID ( clsid, &szProgID );
|
||||
_ASSERTE ( SUCCEEDED ( hRes ) );
|
||||
}
|
||||
|
||||
// This *must* succeed
|
||||
lvi.pszText = OLE2T ( szProgID );
|
||||
::CoTaskMemFree ( szProgID );
|
||||
}
|
||||
|
||||
lvi.cchTextMax = ::_tcslen ( lvi.pszText );
|
||||
int nItem = m_wndPlugins.InsertItem ( &lvi );
|
||||
|
||||
// Load the version info
|
||||
CString strDLL;
|
||||
if ( !CDenAgentApp::getCOMObjectDLL ( clsid, strDLL ) )
|
||||
{
|
||||
m_wndPlugins.SetItemText ( nItem, 1, _T( "<No DLL>" ) );
|
||||
continue;
|
||||
}
|
||||
|
||||
CString strDLLVersion;
|
||||
if ( !CDenAgentApp::getVersionString ( strDLL, strDLLVersion ) )
|
||||
m_wndPlugins.SetItemText ( nItem, 1, _T( "<No Version>" ) );
|
||||
else
|
||||
m_wndPlugins.SetItemText ( nItem, 1, strDLLVersion );
|
||||
}
|
||||
}
|
||||
|
||||
m_wndPlugins.SetRedraw ( TRUE );
|
||||
m_wndPlugins.Invalidate ();
|
||||
|
||||
// Scroll back to the top index of before
|
||||
RECT rc;
|
||||
m_wndPlugins.GetItemRect ( 0, &rc, LVIR_BOUNDS );
|
||||
m_wndPlugins.Scroll ( CSize ( 0, ( rc.bottom - rc.top ) * nTop ) );
|
||||
}
|
||||
|
||||
void CDenAgentDlg::OnUpdate()
|
||||
{
|
||||
USES_CONVERSION;
|
||||
// Release Decal object so it can be updated.
|
||||
m_pDecal.Release();
|
||||
m_pDecal = NULL;
|
||||
CoFreeUnusedLibraries();
|
||||
RegKey key;
|
||||
|
||||
cDownloaderDlg dlg;
|
||||
bool bUpdates = false;
|
||||
|
||||
if (key.Create( HKEY_LOCAL_MACHINE, _T( "SOFTWARE\\Decal\\Agent" )) != ERROR_SUCCESS)
|
||||
return;
|
||||
|
||||
TCHAR szURLDirectory[1024];
|
||||
TCHAR szDecalDirectory[MAX_PATH + 1];
|
||||
DWORD dwSize = 1024;
|
||||
|
||||
if (key.QueryStringValue( _T( "DecalDirectory" ), szURLDirectory, &dwSize ) != ERROR_SUCCESS)
|
||||
{
|
||||
::_tcscpy(szURLDirectory, "http://decal.acdev.org");
|
||||
key.SetStringValue("DecalDirectory", "http://decal.acdev.org");
|
||||
}
|
||||
|
||||
dwSize = MAX_PATH;
|
||||
|
||||
if (key.QueryStringValue( _T( "AgentPath" ), szDecalDirectory, &dwSize ) == ERROR_SUCCESS) {
|
||||
// Gouru: szDecalDirectory may have trailing slash in registry, all following
|
||||
// code assumes it does not, and adds another one. Since this could potentially
|
||||
// cause path problems, the extra slash (if extant) is removed here
|
||||
if ( szDecalDirectory[strlen(szDecalDirectory)-1] == '/'
|
||||
|| szDecalDirectory[strlen(szDecalDirectory)-1] == '\\'
|
||||
){
|
||||
szDecalDirectory[strlen(szDecalDirectory)-1] = 0 ;
|
||||
}
|
||||
|
||||
AutoUpdate aUpdate(szDecalDirectory);
|
||||
|
||||
aUpdate.initialiseFromXML(std::string(szURLDirectory));
|
||||
|
||||
if (!aUpdate.performUpdate())
|
||||
MessageBox("Decal component update failed!");
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
|
||||
MSXML::IXMLDOMDocumentPtr pDPDoc;
|
||||
|
||||
pDPDoc.CreateInstance( __uuidof( MSXML::DOMDocument ) );
|
||||
pDPDoc->async = false;
|
||||
|
||||
VARIANT_BOOL bSuccess = pDPDoc->load( "decalplugins.xml" );
|
||||
|
||||
if(bSuccess)
|
||||
{
|
||||
MSXML::IXMLDOMElementPtr pNode = pDPDoc->selectSingleNode( _T("decal") );
|
||||
_variant_t vVersion = pNode->getAttribute( _T( "version" ) ), vCodeBase = pNode->getAttribute( _T( "codebase" ) );
|
||||
|
||||
char *sVersion = OLE2A(vVersion.bstrVal);
|
||||
|
||||
int iRemoteReleaseMajor, iRemoteReleaseMinor;
|
||||
int iRemoteBuildMajor, iRemoteBuildMinor;
|
||||
|
||||
sscanf(sVersion, "%d.%d.%d.%d", &iRemoteReleaseMajor, &iRemoteReleaseMinor, &iRemoteBuildMajor, &iRemoteBuildMinor);
|
||||
|
||||
if (iReleaseMajor == iRemoteReleaseMajor)
|
||||
{
|
||||
if (iReleaseMinor == iRemoteReleaseMinor)
|
||||
{
|
||||
if (iBuildMajor == iRemoteBuildMajor)
|
||||
{
|
||||
if (iBuildMinor < iRemoteBuildMinor)
|
||||
updateDecal(vCodeBase);
|
||||
}
|
||||
else if (iBuildMajor < iRemoteBuildMajor)
|
||||
updateDecal(vCodeBase);
|
||||
}
|
||||
else if (iReleaseMinor < iRemoteReleaseMinor)
|
||||
updateDecal(vCodeBase);
|
||||
}
|
||||
else if (iReleaseMajor < iRemoteReleaseMajor)
|
||||
updateDecal(vCodeBase);
|
||||
|
||||
|
||||
MSXML::IXMLDOMNodeListPtr pPlugins = pDPDoc->selectNodes( _T( "/decal/plugin" ) );
|
||||
for( MSXML::IXMLDOMElementPtr pPlugin = pPlugins->nextNode(); pPlugin.GetInterfacePtr() != NULL; pPlugin = pPlugins->nextNode() )
|
||||
{
|
||||
_variant_t vClsid = pPlugin->getAttribute( _T( "clsid" ) ),
|
||||
vCodebase = pPlugin->getAttribute( _T( "codebase" ) ),
|
||||
vVersion = pPlugin->getAttribute( _T( "version" ) ),
|
||||
vName = pPlugin->getAttribute( _T( "name" ) );
|
||||
|
||||
DWORD dwMajor;
|
||||
DWORD dwMinor;
|
||||
|
||||
convertVersion( OLE2T( vVersion.bstrVal ), dwMajor, dwMinor );
|
||||
|
||||
RegKey keyPlugin;
|
||||
|
||||
if( keyPlugin.Open( HKEY_LOCAL_MACHINE, _T( "SOFTWARE\\Decal\\Plugins\\" ), KEY_READ ) == ERROR_SUCCESS )
|
||||
{
|
||||
keyPlugin.Close();
|
||||
|
||||
if( keyPlugin.Open( HKEY_CLASSES_ROOT, CString(_T("\\CLSID\\")) + OLE2T(vClsid.bstrVal) + _T("\\InprocServer32"), KEY_READ ) != ERROR_SUCCESS ) continue;
|
||||
|
||||
DWORD dwSize = MAX_PATH;
|
||||
TCHAR szDllName[MAX_PATH];
|
||||
|
||||
if(keyPlugin.QueryStringValue("", szDllName, &dwSize) != ERROR_SUCCESS) continue;
|
||||
|
||||
keyPlugin.Close();
|
||||
|
||||
DWORD dwHandle;
|
||||
DWORD dwVerInfoSize = GetFileVersionInfoSize(szDllName,&dwHandle);
|
||||
if(!dwVerInfoSize) continue;
|
||||
|
||||
LPBYTE pVersionData = NULL;
|
||||
|
||||
pVersionData = new BYTE[dwVerInfoSize];
|
||||
|
||||
if(!GetFileVersionInfo(szDllName, dwHandle, dwVerInfoSize, pVersionData))
|
||||
{
|
||||
delete [] pVersionData;
|
||||
continue;
|
||||
}
|
||||
|
||||
VS_FIXEDFILEINFO* pFixedFileInfo;
|
||||
|
||||
UINT uFixedInfoSize;
|
||||
if(!VerQueryValue(pVersionData, "\\", (void**) &pFixedFileInfo, &uFixedInfoSize))
|
||||
{
|
||||
delete [] pVersionData;
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
if (HIWORD(pFixedFileInfo->dwFileVersionMS) == HIWORD(dwMajor))
|
||||
{
|
||||
if (LOWORD(pFixedFileInfo->dwFileVersionMS) == LOWORD(dwMajor))
|
||||
{
|
||||
if (HIWORD(pFixedFileInfo->dwFileVersionLS) == HIWORD(dwMinor))
|
||||
{
|
||||
if (LOWORD(pFixedFileInfo->dwFileVersionLS) < LOWORD(dwMinor))
|
||||
bUpdates = true;
|
||||
}
|
||||
else if (HIWORD(pFixedFileInfo->dwFileVersionLS) < HIWORD(dwMinor))
|
||||
bUpdates = true;
|
||||
}
|
||||
else if (LOWORD(pFixedFileInfo->dwFileVersionMS) < LOWORD(dwMajor))
|
||||
bUpdates = true;
|
||||
}
|
||||
else if (HIWORD(pFixedFileInfo->dwFileVersionMS) < HIWORD(dwMajor))
|
||||
bUpdates = true;
|
||||
|
||||
delete [] pVersionData;
|
||||
}
|
||||
}
|
||||
|
||||
if((bUpdates) && (!m_bDoingUpdate))
|
||||
{
|
||||
if (MessageBox("Decal has detected that one or more of your plugins are out of date.\n\nWould you like to view the plugin list?",NULL, MB_ICONQUESTION | MB_YESNO) == IDYES)
|
||||
{
|
||||
HRESULT hRes = ::CoCreateInstance ( __uuidof ( Decal ), NULL, CLSCTX_INPROC_SERVER, __uuidof ( IDecal ),
|
||||
reinterpret_cast< LPVOID * > ( &m_pDecal ) );
|
||||
|
||||
cAddRemoveDlg ardlg( this );
|
||||
ardlg.m_pDecal = m_pDecal;
|
||||
ardlg.DoModal();
|
||||
loadPluginList();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
m_bDoingUpdate = false;
|
||||
|
||||
updateFileInfo ();
|
||||
|
||||
HRESULT hRes = ::CoCreateInstance ( __uuidof ( Decal ), NULL, CLSCTX_INPROC_SERVER, __uuidof ( IDecal ),
|
||||
reinterpret_cast< LPVOID * > ( &m_pDecal ) );
|
||||
}
|
||||
|
||||
void CDenAgentDlg::OnOptions()
|
||||
{
|
||||
cOptionsDlg dlg;
|
||||
dlg.DoModal();
|
||||
}
|
||||
|
||||
void CDenAgentDlg::convertVersion( LPTSTR szVersion, DWORD &dwVersionMajor, DWORD &dwVersionMinor )
|
||||
{
|
||||
int wVersionParts[ 4 ],
|
||||
*i_ver = wVersionParts;
|
||||
|
||||
for( TCHAR *szVersionPart = ::_tcstok( szVersion, _T( "." ) ); szVersionPart != NULL; szVersionPart = ::_tcstok( NULL, _T( "." ) ), ++ i_ver )
|
||||
::_stscanf( szVersionPart, _T( "%i" ), i_ver );
|
||||
|
||||
dwVersionMajor = MAKELONG( wVersionParts[ 1 ], wVersionParts[ 0 ] );
|
||||
dwVersionMinor = MAKELONG( wVersionParts[ 3 ], wVersionParts[ 2 ] );
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void CDenAgentDlg::updateFileInfo(void)
|
||||
{
|
||||
struct cFiles
|
||||
{
|
||||
LPCTSTR szFilename;
|
||||
LPCTSTR szRootElement;
|
||||
LPCTSTR szVElement;
|
||||
UINT nDlgID;
|
||||
};
|
||||
|
||||
static cFiles files[] = {
|
||||
{ _T( "messages.xml" ), _T("schema"), _T("revision"), IDC_MESSAGES_TEXT },
|
||||
{ _T( "memlocs.xml" ), _T(""), _T("locations"), IDC_MEMLOCS_TEXT },
|
||||
{ _T( "decalplugins.xml" ), _T(""), _T(""), IDC_DECALPLUGINS_TEXT } },
|
||||
*end_files = files + sizeof ( files ) / sizeof ( cFiles );
|
||||
|
||||
for ( cFiles *i = files; i != end_files; ++ i )
|
||||
{
|
||||
CString strFileInfo;
|
||||
GetFileInfoBase ( i->szFilename, i->szRootElement, i->szVElement, strFileInfo );
|
||||
SetDlgItemText ( i->nDlgID, strFileInfo );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void CDenAgentDlg::GetFileInfoBase(LPCTSTR pszFilename, LPCTSTR pszRootElement, LPCTSTR pszVElement, CString &szFileInfo)
|
||||
{
|
||||
USES_CONVERSION;
|
||||
|
||||
RegKey key;
|
||||
TCHAR szVal[MAX_PATH+1];
|
||||
DWORD dwSize = MAX_PATH;
|
||||
static BOOL bAlreadyBuggedUser = false;
|
||||
|
||||
szFileInfo = _T("file not found");
|
||||
|
||||
// Open the registry key
|
||||
if(key.Open(HKEY_LOCAL_MACHINE, _T("SOFTWARE\\Decal\\Agent")) == ERROR_SUCCESS)
|
||||
{
|
||||
// Determine the agent path
|
||||
if (key.QueryStringValue(_T("AgentPath"), szVal, &dwSize) == ERROR_SUCCESS)
|
||||
{
|
||||
CString szFilename, szAgentPath(szVal);
|
||||
|
||||
// Create the filename
|
||||
szFilename.Format(_T("%s%s%s"),
|
||||
szAgentPath,
|
||||
(szAgentPath.Right(1) != _T("\\")) ? _T("\\") : _T(""),
|
||||
pszFilename);
|
||||
|
||||
// Look for the data file
|
||||
CFileStatus FileStatus;
|
||||
if (CFile::GetStatus((LPCTSTR)szFilename, FileStatus))
|
||||
{
|
||||
if (strlen(pszVElement)) {
|
||||
MSXML::IXMLDOMDocumentPtr m_pDoc;
|
||||
MSXML::IXMLDOMElementPtr pVersionElement;
|
||||
|
||||
m_pDoc.CreateInstance( __uuidof( MSXML::DOMDocument ) );
|
||||
m_pDoc->async = false;
|
||||
|
||||
BOOL bSuccess = m_pDoc->load( _bstr_t(szFilename) );
|
||||
if( !bSuccess )
|
||||
{
|
||||
std::string szXML;
|
||||
CDenAgentApp::DecryptXML( static_cast< LPCSTR >( szFilename ), szXML );
|
||||
|
||||
if( szXML != "" )
|
||||
bSuccess = m_pDoc->loadXML( _bstr_t( szXML.c_str() ) );
|
||||
|
||||
szXML = " ";
|
||||
for( int i = 0; i < 2500; ++i )
|
||||
szXML += "DIRL";
|
||||
}
|
||||
|
||||
if( !bSuccess )
|
||||
return;
|
||||
|
||||
if (strlen(pszRootElement)) {
|
||||
MSXML::IXMLDOMElementPtr pRootElement = m_pDoc->selectSingleNode(_T(pszRootElement));
|
||||
pVersionElement = pRootElement->selectSingleNode(_T(pszVElement));
|
||||
} else {
|
||||
pVersionElement = m_pDoc->selectSingleNode(_T(pszVElement));
|
||||
}
|
||||
|
||||
if (pVersionElement) {
|
||||
_variant_t vVersion = pVersionElement->getAttribute(_T("version"));
|
||||
|
||||
szFileInfo.Format(_T("%d bytes, Version %s"), (DWORD) FileStatus.m_size, OLE2T(vVersion.bstrVal));
|
||||
} else {
|
||||
CString szDateTime = FileStatus.m_mtime.Format(_T("%#m/%#d/%Y %#I:%M %p"));
|
||||
szFileInfo.Format(_T("%d bytes, %s"), (DWORD) FileStatus.m_size, szDateTime);
|
||||
}
|
||||
} else {
|
||||
CString szDateTime = FileStatus.m_mtime.Format(_T("%#m/%#d/%Y %#I:%M %p"));
|
||||
szFileInfo.Format(_T("%d bytes, %s"), (DWORD) FileStatus.m_size, szDateTime);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// This is mainly to protect me from myself :) Yes, I did almost post a bug report
|
||||
// because I didn't have XML files in and AC was crashing. --elph
|
||||
if( m_bDoUpdate )
|
||||
{
|
||||
m_bDoUpdate = false;
|
||||
OnUpdate( );
|
||||
}
|
||||
else if (szFileInfo == _T("file not found") && !bAlreadyBuggedUser) {
|
||||
::MessageBox(NULL, "One or more of your XML files were not found!\nPlease click the Update button to ensure that Decal works correctly!", "Decal", MB_OK|MB_ICONERROR);
|
||||
bAlreadyBuggedUser = true;
|
||||
}
|
||||
}
|
||||
|
||||
void CDenAgentDlg::OnDeleteitemPlugins(NMHDR* pNMHDR, LRESULT* pResult)
|
||||
{
|
||||
NM_LISTVIEW* pNMListView = (NM_LISTVIEW*)pNMHDR;
|
||||
|
||||
// Clear the plugin
|
||||
delete reinterpret_cast< cPlugin * > ( pNMListView->lParam );
|
||||
|
||||
*pResult = 0;
|
||||
}
|
||||
|
||||
void CDenAgentDlg::OnClickPlugins(NMHDR* pNMHDR, LRESULT* pResult)
|
||||
{
|
||||
*pResult = 0;
|
||||
LPNMITEMACTIVATE pItemActivate = reinterpret_cast< LPNMITEMACTIVATE > ( pNMHDR );
|
||||
|
||||
if ( pItemActivate->iItem == -1 || pItemActivate->lParam == 0 )
|
||||
// A plugin item was not hit
|
||||
return;
|
||||
|
||||
// Hit test to see if the icon was hit (checkbox)
|
||||
if ( pItemActivate->ptAction.x < 16 || pItemActivate->ptAction.x > 32 )
|
||||
return;
|
||||
|
||||
// Invert the check
|
||||
cPlugin *pPlugin = reinterpret_cast< cPlugin * > ( m_wndPlugins.GetItemData ( pItemActivate->iItem ) );
|
||||
CComPtr< IDecalEnum > pEnum;
|
||||
|
||||
if (pPlugin && SUCCEEDED ( m_pDecal->get_Configuration ( _bstr_t ( pPlugin->m_group ), pPlugin->m_id, &pEnum ) ) )
|
||||
{
|
||||
pPlugin->m_bEnabled = !pPlugin->m_bEnabled;
|
||||
|
||||
// Write the registry and the icons
|
||||
pEnum->put_Enabled ( ( pPlugin->m_bEnabled ) ? VARIANT_TRUE : VARIANT_FALSE );
|
||||
|
||||
LVITEM lvi = { LVIF_IMAGE, pItemActivate->iItem, 0, 0, 0, NULL, 0,
|
||||
( pPlugin->m_bEnabled ) ? 6 : 5, };
|
||||
m_wndPlugins.SetItem ( &lvi );
|
||||
}
|
||||
else
|
||||
// Bad data in the list - refresh
|
||||
loadPluginList ();
|
||||
}
|
||||
|
||||
void CDenAgentDlg::OnBegindragPlugins(NMHDR* pNMHDR, LRESULT* pResult)
|
||||
{
|
||||
*pResult = 0;
|
||||
NM_LISTVIEW* pNMListView = (NM_LISTVIEW*)pNMHDR;
|
||||
|
||||
// Check if this item is valid for dragging
|
||||
if ( pNMListView->iItem == -1 )
|
||||
return;
|
||||
|
||||
cPlugin *pPlugin = reinterpret_cast< cPlugin * > ( m_wndPlugins.GetItemData ( pNMListView->iItem ) );
|
||||
if ( pPlugin == NULL )
|
||||
return;
|
||||
|
||||
m_wndPlugins.SetItemState ( pNMListView->iItem, LVIS_SELECTED, LVIS_SELECTED );
|
||||
m_hDragImage = ListView_CreateDragImage ( m_wndPlugins.m_hWnd, pNMListView->iItem, &CPoint ( 0, 0 ) );
|
||||
|
||||
CRect rcItem;
|
||||
m_wndPlugins.GetItemRect ( pNMListView->iItem, rcItem, LVIR_BOUNDS );
|
||||
|
||||
ImageList_BeginDrag ( m_hDragImage, 0, pNMListView->ptAction.x - rcItem.left, pNMListView->ptAction.y - rcItem.top );
|
||||
ImageList_DragEnter ( m_wndPlugins.m_hWnd, pNMListView->ptAction.x, pNMListView->ptAction.y );
|
||||
|
||||
m_pCurrentDrag = pPlugin;
|
||||
|
||||
SetCapture ();
|
||||
}
|
||||
|
||||
void CDenAgentDlg::OnMouseMove(UINT nFlags, CPoint point)
|
||||
{
|
||||
if ( m_pCurrentDrag != NULL )
|
||||
{
|
||||
SetCursor ( ::LoadCursor ( NULL, ( getDragInsertBefore ( point ) == -1 ) ? IDC_NO : IDC_ARROW ) );
|
||||
ImageList_DragMove ( point.x, point.y );
|
||||
}
|
||||
|
||||
CDialog::OnMouseMove(nFlags, point);
|
||||
}
|
||||
|
||||
void CDenAgentDlg::OnLButtonUp(UINT nFlags, CPoint point)
|
||||
{
|
||||
if ( m_pCurrentDrag != NULL )
|
||||
{
|
||||
ImageList_DragLeave ( m_wndPlugins.m_hWnd );
|
||||
ImageList_EndDrag ();
|
||||
ImageList_Destroy ( m_hDragImage );
|
||||
|
||||
ReleaseCapture ();
|
||||
|
||||
int nInsertBefore = getDragInsertBefore ( point );
|
||||
if ( nInsertBefore != -1 )
|
||||
{
|
||||
{
|
||||
CComPtr< IDecalEnum > pEnum;
|
||||
if ( SUCCEEDED ( m_pDecal->get_Configuration ( _bstr_t ( m_pCurrentDrag->m_group ), GUID_NULL, &pEnum ) ) )
|
||||
{
|
||||
if ( SUCCEEDED ( pEnum->Skip ( m_pCurrentDrag->m_id ) ) )
|
||||
pEnum->MoveBefore ( reinterpret_cast< cPlugin * > ( m_wndPlugins.GetItemData ( nInsertBefore ) )->m_id );
|
||||
}
|
||||
}
|
||||
|
||||
loadPluginList ();
|
||||
}
|
||||
|
||||
m_pCurrentDrag = NULL;
|
||||
}
|
||||
|
||||
CDialog::OnLButtonUp(nFlags, point);
|
||||
}
|
||||
|
||||
void CDenAgentDlg::OnBnClickedDelete()
|
||||
{
|
||||
/*
|
||||
HOW TO USE THIS FEATURE
|
||||
create a string value under your plugin key called "Uninstaller"
|
||||
the value of this key should be the name of your uninstaller program,
|
||||
as listed under HKLM\Software\Microsoft\Windows\CurrentVersion\Uninstall\
|
||||
for MSI installers the name will be a GUID, for others it may be a GUID or plain text
|
||||
|
||||
that's it
|
||||
-para
|
||||
*/
|
||||
|
||||
USES_CONVERSION;
|
||||
|
||||
int nSelMark = m_wndPlugins.GetSelectionMark();
|
||||
if ( nSelMark == -1 )
|
||||
return;
|
||||
|
||||
cPlugin *pPlugin = reinterpret_cast< cPlugin * >(m_wndPlugins.GetItemData( nSelMark ));
|
||||
if ( pPlugin == NULL )
|
||||
return;
|
||||
|
||||
//ask permission MB_OKCANCEL | MB_ICONEXCLAMATION = IDOK
|
||||
//_snprintf(szMsg, 512, "You are about to remove %s\nPress OK to continue", stuff)
|
||||
if ( ::MessageBox(NULL, _T("You are about to remove this plugin.\nPress OK to continue"), _T("Remove Plugin"), MB_OKCANCEL | MB_ICONEXCLAMATION) != IDOK )
|
||||
return;
|
||||
|
||||
//load up the decal registry and remove this entry
|
||||
RegKey keyPlugin;
|
||||
CString decalPluginKey;
|
||||
BSTR sClsid;
|
||||
|
||||
StringFromCLSID(pPlugin->m_id, &sClsid);
|
||||
if ((stricmp(pPlugin->m_group, "plugins") == 0) || (stricmp(pPlugin->m_group, "networkfilters") == 0))
|
||||
{
|
||||
decalPluginKey.Format("SOFTWARE\\Decal\\%s", pPlugin->m_group);
|
||||
|
||||
if (keyPlugin.Open(HKEY_LOCAL_MACHINE, _T(decalPluginKey), KEY_ALL_ACCESS) == ERROR_SUCCESS)
|
||||
{
|
||||
RegKey keySub;
|
||||
if (keySub.Open(keyPlugin.m_hKey, OLE2T(sClsid), KEY_READ) == ERROR_SUCCESS)
|
||||
{
|
||||
//read the uninstaller string and fire it off
|
||||
TCHAR sUninstall[512];
|
||||
DWORD dwSize = 512;
|
||||
|
||||
if (keySub.QueryStringValue(_T("Uninstaller"), sUninstall, &dwSize) == ERROR_SUCCESS)
|
||||
{
|
||||
RegKey keyUninstall;
|
||||
CString sUninstallKey;
|
||||
|
||||
sUninstallKey.Format("SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\%s", sUninstall);
|
||||
if (keyUninstall.Open(HKEY_LOCAL_MACHINE, _T(sUninstallKey), KEY_READ) == ERROR_SUCCESS)
|
||||
{
|
||||
TCHAR sUninstallPath[512];
|
||||
dwSize = 512;
|
||||
|
||||
keyUninstall.QueryStringValue(_T("UninstallString"), sUninstallPath, &dwSize);
|
||||
keyUninstall.Close();
|
||||
|
||||
//execute!
|
||||
STARTUPINFO si;
|
||||
PROCESS_INFORMATION pi;
|
||||
|
||||
memset(&si, 0, sizeof(si));
|
||||
memset(&pi, 0, sizeof(pi));
|
||||
si.cb = sizeof(si);
|
||||
|
||||
CreateProcess(NULL, sUninstallPath, NULL, NULL, false, CREATE_DEFAULT_ERROR_MODE, NULL, NULL, &si, &pi);
|
||||
}
|
||||
} else {
|
||||
::MessageBox(NULL, _T("There was no uninstaller key defined for this object\nYou will have to uninstall it manually"), _T("Decal Error"), MB_ICONEXCLAMATION);
|
||||
}
|
||||
keySub.Close();
|
||||
}
|
||||
|
||||
keyPlugin.DeleteSubKey(OLE2T(sClsid));
|
||||
keyPlugin.Close();
|
||||
}
|
||||
else
|
||||
::MessageBox(NULL, _T("Unable to open registry"), _T("Decal Error"), MB_ICONEXCLAMATION);
|
||||
|
||||
//refresh
|
||||
loadPluginList();
|
||||
}
|
||||
}
|
||||
void CDenAgentDlg::OnBnClickedExport()
|
||||
{
|
||||
cExportDlg dlg;
|
||||
dlg.SetDecal(m_pDecal);
|
||||
dlg.DoModal();
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue