// 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 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( "" ) ); continue; } CString strDLLVersion; if ( !CDenAgentApp::getVersionString ( strDLL, strDLLVersion ) ) m_wndPlugins.SetItemText ( nItem, 1, _T( "" ) ); 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(); }