// AddRemoveDlg.cpp : implementation file // #include "stdafx.h" #include "DenAgent.h" #include "AddRemoveDlg.h" #include "DownloadDlg.h" #include "..\Inject\Inject.h" #include "..\Inject\Inject_i.c" #ifdef _DEBUG #define new DEBUG_NEW #undef THIS_FILE static char THIS_FILE[] = __FILE__; #endif ///////////////////////////////////////////////////////////////////////////// // cAddRemoveDlg dialog cAddRemoveDlg::cAddRemoveDlg(CWnd* pParent /*=NULL*/) : CDialog(cAddRemoveDlg::IDD, pParent) { //{{AFX_DATA_INIT(cAddRemoveDlg) //}}AFX_DATA_INIT } void cAddRemoveDlg::DoDataExchange(CDataExchange* pDX) { CDialog::DoDataExchange(pDX); //{{AFX_DATA_MAP(cAddRemoveDlg) DDX_Control(pDX, IDC_PLUGINS, m_wndPlugins); //}}AFX_DATA_MAP } void cAddRemoveDlg::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 cAddRemoveDlg::loadListing() { USES_CONVERSION; // Clear old data m_wndPlugins.SetRedraw( FALSE ); m_wndPlugins.DeleteAllItems(); m_plugins.clear(); if (m_pDoc->load("decalplugins.xml") == VARIANT_FALSE) return; MSXML::IXMLDOMNodeListPtr pPlugins = m_pDoc->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" ) ); cPlugin p; ::CLSIDFromString( vClsid.bstrVal, &p.m_clsid ); convertVersion( OLE2T( vVersion.bstrVal ), p.m_dwMajor, p.m_dwMinor ); ::wcscpy( p.m_szURL, OLE2W( vCodebase.bstrVal ) ); CString csurl(p.m_szURL); if((-1!=csurl.Find(".exe", 0)) || (-1!=csurl.Find(".msi", 0)) || (-1!=csurl.Find(".dll", 0)) || (-1!=csurl.Find(".zip", 0)) || (-1!=csurl.Find(".js", 0)) || (-1!=csurl.Find(".vbs", 0))) p.m_bBinary = TRUE; else p.m_bBinary = FALSE; // Now get matching info from the registry - if available RegKey keyPlugin; CString csVersion; CString decalPluginKey; // See if this plugin is installed in the Decal plugin list decalPluginKey.Format("SOFTWARE\\Decal\\Plugins\\%s", OLE2T(vClsid.bstrVal)); if (keyPlugin.Open(HKEY_LOCAL_MACHINE, _T(decalPluginKey), KEY_READ) == ERROR_SUCCESS) { CString szDllName; keyPlugin.Close(); // It is! Get the DLL for the CLSID if (!CDenAgentApp::getCOMObjectDLL(p.m_clsid, szDllName)) goto NotInstalled; int iMajor, iMinor, iBuildMajor, iBuildMinor; // Now get the version from the DLL if (!CDenAgentApp::getVersionInfo(szDllName, iMajor, iMinor, iBuildMajor, iBuildMinor)) goto NotInstalled; // Setup the installed data by shifting the majors into the HIWORDs, minors into the LOWORDs p.m_dwInstalledMajor = (iMajor << 16) | iMinor; p.m_dwInstalledMinor = (iBuildMajor << 16) | iBuildMinor; // Format a version string csVersion.Format("%d.%d.%d.%d", iMajor, iMinor, iBuildMajor, iBuildMinor); p.m_bInstalled = true; } else { NotInstalled: p.m_bInstalled = false; p.m_dwInstalledMajor = 0; p.m_dwInstalledMinor = 0; } m_plugins.push_back( p ); // Next, load this data into the listbox int nIndex = m_wndPlugins.InsertItem( m_wndPlugins.GetItemCount(), OLE2T( vName.bstrVal ) ); m_wndPlugins.SetItemData( nIndex, reinterpret_cast< DWORD >( &m_plugins.back() ) ); m_wndPlugins.SetItemText( nIndex, 1, OLE2T( vVersion.bstrVal ) ); if( p.m_bInstalled ) m_wndPlugins.SetItemText( nIndex, 2, csVersion ); else m_wndPlugins.SetItemText( nIndex, 2, _T( "Not Installed" ) ); // Set the proper image indicator int nImage = 0; if (p.m_bInstalled) { CString szInstalled, szKnown; // Write them out, padded with lots of zeroes szInstalled.Format(_T("%.10d.%.10d.%.10d.%.10d"), HIWORD(p.m_dwInstalledMajor), LOWORD(p.m_dwInstalledMajor), HIWORD(p.m_dwInstalledMinor), LOWORD(p.m_dwInstalledMinor)); szKnown.Format(_T("%.10d.%.10d.%.10d.%.10d"), HIWORD(p.m_dwMajor), LOWORD(p.m_dwMajor), HIWORD(p.m_dwMinor), LOWORD(p.m_dwMinor)); // Determine the image if (szInstalled == szKnown) { nImage = 2; } else if (szInstalled > szKnown) { nImage = 3; } else if (szInstalled < szKnown) { nImage = 1; } } m_wndPlugins.SetItem(nIndex, 0, LVIF_IMAGE, 0, nImage, 0, 0, 0); } if(!m_SortInfo.pListControl) { m_SortInfo.nAscendingSortOrder = TRUE; m_SortInfo.nColumnNo = 2; m_SortInfo.pListControl = &m_wndPlugins; } m_wndPlugins.SortItems(ComparePlugins, (DWORD)&m_SortInfo); m_wndPlugins.SetRedraw( TRUE ); } BEGIN_MESSAGE_MAP(cAddRemoveDlg, CDialog) //{{AFX_MSG_MAP(cAddRemoveDlg) ON_BN_CLICKED(IDC_CHANGE_DIR, OnChangeDir) ON_BN_CLICKED(IDC_INSTALL, OnInstall) ON_NOTIFY(NM_DBLCLK, IDC_PLUGINS, OnDblclkPlugins) ON_BN_CLICKED(IDC_UPGRADE, OnUpgrade) ON_NOTIFY(LVN_COLUMNCLICK, IDC_PLUGINS, OnColumnclickPlugins) ON_NOTIFY(LVN_GETINFOTIP, IDC_PLUGINS, OnInfoTip) ON_BN_CLICKED(IDC_BROWSE, OnBrowse) ON_BN_CLICKED(IDC_REFRESH, OnRefresh) ON_NOTIFY(LVN_ITEMCHANGED, IDC_PLUGINS, OnSelChanged) ON_NOTIFY(NM_CLICK, IDC_PLUGINS, OnSelChanged) //}}AFX_MSG_MAP END_MESSAGE_MAP() ///////////////////////////////////////////////////////////////////////////// // cAddRemoveDlg message handlers void cAddRemoveDlg::OnChangeDir() { // TODO: Add your control notification handler code here } void cAddRemoveDlg::OnInstall() { // cDownloadDlg dlg( this ); // TODO: Get the currently selected item cPlugin *pPlugin = reinterpret_cast< cPlugin * >( m_wndPlugins.GetItemData( m_wndPlugins.GetSelectionMark() ) ); if(pPlugin==NULL) return; /* dlg.m_clsid = pPlugin->m_clsid; dlg.m_dwMajor = pPlugin->m_dwMajor; dlg.m_dwMinor = pPlugin->m_dwMinor; dlg.m_strURL = pPlugin->m_szURL; dlg.m_bDownloadPlugin = true; if( dlg.DoModal() != IDOK ) return; // The download was successful - try and create an instance CComPtr< IPlugin > pPluginObj; HRESULT hRes = dlg.m_pFactory->CreateInstance( NULL, __uuidof( IPlugin ), reinterpret_cast< void ** >( &pPluginObj ) ); if( FAILED( hRes ) ) // Something isn't right AfxMessageBox( _T( "The newly downloaded plugin dosen't appear to work." ), MB_ICONERROR | MB_OK, 0 ); dlg.m_pFactory->LockServer( FALSE ); // Refresh the view loadListing(); */ CString url(pPlugin->m_szURL); ShellExecute(m_hWnd,"open",url,0,0,0); } void cAddRemoveDlg::OnDblclkPlugins(NMHDR* pNMHDR, LRESULT* pResult) { // TODO: Add your control notification handler code here *pResult = 0; } void cAddRemoveDlg::OnUpgrade() { OnInstall(); } BOOL cAddRemoveDlg::OnInitDialog() { CDialog::OnInitDialog(); // Load the string RegKey keyAgent; if( keyAgent.Open( HKEY_LOCAL_MACHINE, _T( "SOFTWARE\\Decal\\Agent" )) != ERROR_SUCCESS ) { ::AfxMessageBox( _T( "Critical registry keys are missing, this installation is broken.\r\nRepair the installation." ), MB_ICONERROR | MB_OK, 0 ); EndDialog( IDCANCEL ); return FALSE; } // Make it look nicer m_wndPlugins.SetExtendedStyle( m_wndPlugins.GetExtendedStyle() | LVS_EX_HEADERDRAGDROP | LVS_EX_FULLROWSELECT | LVS_EX_GRIDLINES | LVS_EX_INFOTIP); // Create and assign the image list //m_ImageList.Create(IDR_VERSION_STATES, 21, 0, RGB(255, 255, 255)); m_ImageList.Create(IDB_IMAGES, 16, 0, RGB(255,0,255)); m_wndPlugins.SetImageList(&m_ImageList, LVSIL_SMALL); // Setup the columns in the list control m_wndPlugins.InsertColumn( 0, _T( "Plugin Name" ), LVCFMT_LEFT, 175 ); m_wndPlugins.InsertColumn( 1, _T( "Version" ), LVCFMT_LEFT, 75, 1 ); m_wndPlugins.InsertColumn( 2, _T( "Installed" ), LVCFMT_LEFT, 75, 2 ); m_wndPlugins.m_pAddRemoveDlg = this; m_pDoc.CreateInstance( __uuidof( MSXML::DOMDocument ) ); m_pDoc->async = false; m_SortInfo.pListControl = NULL; loadListing(); return TRUE; // return TRUE unless you set the focus to a control // EXCEPTION: OCX Property Pages should return FALSE } void cAddRemoveDlg::OnColumnclickPlugins(NMHDR* pNMHDR, LRESULT* pResult) { NM_LISTVIEW* pNMListView = (NM_LISTVIEW*)pNMHDR; if (pNMListView->iSubItem == m_SortInfo.nColumnNo) m_SortInfo.nAscendingSortOrder = !m_SortInfo.nAscendingSortOrder; else m_SortInfo.nAscendingSortOrder = TRUE; m_SortInfo.nColumnNo = pNMListView->iSubItem; m_SortInfo.pListControl = &m_wndPlugins; m_wndPlugins.SortItems( ComparePlugins, (DWORD)&m_SortInfo ); *pResult = 0; } int CALLBACK cAddRemoveDlg::ComparePlugins(LPARAM lParam1, LPARAM lParam2, LPARAM lParamSort) { SortInfo *pSortInfo = (SortInfo *) lParamSort; CListCtrl *pListControl = pSortInfo->pListControl; int lFirstData = -1, lSecondData = -1; LV_FINDINFO FindInfo; FindInfo.flags = LVFI_PARAM | LVFI_WRAP; FindInfo.lParam = lParam1; lFirstData = pListControl->FindItem(&FindInfo); FindInfo.lParam = lParam2; lSecondData = pListControl->FindItem(&FindInfo,lFirstData); ASSERT(lFirstData != -1); ASSERT(lSecondData != -1); CString FirstText = pListControl->GetItemText(lFirstData,pSortInfo->nColumnNo); CString SecondText = pListControl->GetItemText(lSecondData,pSortInfo->nColumnNo); return FirstText.CompareNoCase(SecondText) * ((pSortInfo->nAscendingSortOrder)?1:-1); } void cAddRemoveDlg::OnInfoTip( NMHDR *pNMHDR, LRESULT *pResult ) { NMLVGETINFOTIP *pInfoTip = reinterpret_cast(pNMHDR); cPlugin *pPlugin = reinterpret_cast< cPlugin * >( m_wndPlugins.GetItemData( pInfoTip->iItem ) ); if(pPlugin==NULL) return; CString strTipText(pPlugin->m_szURL); lstrcpy(pInfoTip->pszText, strTipText); *pResult = 0; } void cAddRemoveDlg::DisplayError(HRESULT hr) { LPVOID lpMsgBuf; FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER|FORMAT_MESSAGE_FROM_SYSTEM|FORMAT_MESSAGE_IGNORE_INSERTS,NULL,hr, MAKELANGID(LANG_NEUTRAL,SUBLANG_DEFAULT),(LPTSTR)&lpMsgBuf, 0, NULL ); char szTemp[100]; wsprintf(szTemp, "%s\n", lpMsgBuf); MessageBox(szTemp, "Decal Plugin Registration" , MB_ICONEXCLAMATION); } bool cAddRemoveDlg::ReadTypeLib(CString cstrDll, bool bMultipleFiles) { USES_CONVERSION; bool bRegedDLL = false; HINSTANCE hDLL = LoadLibrary(cstrDll); if(hDLL) { DLLREG DllReg = (DLLREG)GetProcAddress(hDLL, "DllRegisterServer"); if(DllReg!=NULL) { DllReg(); bRegedDLL = true; } FreeLibrary(hDLL); } ITypeLib *pTypeLib = NULL; ITypeInfo *pTypeInfo = NULL; TYPEATTR *pTypeAttr = NULL; bool bSuccess = false; HRESULT hr; WCHAR* pwszClassID = NULL; int i; UINT iCount; hr = LoadTypeLib(A2OLE(cstrDll),&pTypeLib); if ( FAILED(hr)) { goto _cleanup; DisplayError(hr); } iCount = pTypeLib->GetTypeInfoCount(); for (i=0; i < iCount ; i++) { if (FAILED(hr = (pTypeLib->GetTypeInfo(i, &pTypeInfo)))) { DisplayError(hr); goto _cleanup; } if (FAILED(hr = (pTypeInfo->GetTypeAttr(&pTypeAttr)))) { DisplayError(hr); goto _cleanup; } if (TKIND_COCLASS == pTypeAttr->typekind) { HREFTYPE hRefType; ITypeInfo *pTInfoImpl; TYPEATTR *pTAttr = NULL; CComBSTR bstrName; for( int j = 0 ; j < pTypeAttr->cImplTypes ; ++j ) { hr = pTypeInfo->GetRefTypeOfImplType( j, &hRefType ); if( SUCCEEDED( hr ) ) { hr = pTypeInfo->GetRefTypeInfo( hRefType, &pTInfoImpl ); if( SUCCEEDED( hr ) ) { hr = pTInfoImpl->GetDocumentation( -1, &bstrName, NULL, NULL, NULL ); hr = pTInfoImpl->GetTypeAttr(&pTAttr); if( SUCCEEDED( hr ) ) { if((pTAttr->guid==IID_IPlugin) && (bstrName == CComBSTR("IPlugin"))) { StringFromCLSID(pTypeAttr->guid, &pwszClassID); RegKey key; if( key.Create( HKEY_LOCAL_MACHINE, _T( "SOFTWARE\\Decal\\Plugins" )) == ERROR_SUCCESS ) if(key.SetDWORDValue(OLE2A(pwszClassID), (DWORD)0x1) == ERROR_SUCCESS) bSuccess = true; CoTaskMemFree(pwszClassID); } pTInfoImpl->ReleaseTypeAttr(pTAttr); } bstrName.Empty(); pTInfoImpl->Release(); } } } } pTypeInfo->ReleaseTypeAttr(pTypeAttr); pTypeInfo->Release(); } _cleanup: if (pTypeAttr) pTypeInfo->ReleaseTypeAttr(pTypeAttr); if (pTypeInfo) pTypeInfo->Release(); if(pTypeLib) pTypeLib->Release(); if(bSuccess) { MessageBox(CString("Decal Plugin: ") + cstrDll + " was sucessfully registered.", "Decal Plugin Registration", MB_ICONINFORMATION ); return true; } else if(bRegedDLL) { MessageBox(CString("File: ") + cstrDll + " was sucessfully registered.\n\nHowever, Decal was unable to determine if the DLL was a Decal Plugin.\n\nIf it was, it should appear in the Plugin List, otherwise it wasn't.", "Decal Plugin Registration", MB_ICONINFORMATION ); return true; } else if(!bMultipleFiles) MessageBox("Registration failed. Dll might not be a Decal Plugin.", "Decal Plugin Registration", MB_ICONEXCLAMATION); return false; } struct cFileType { CString m_strExt; CComPtr< IDecalFileSurrogate > m_pFile; }; typedef std::list< cFileType > cFileTypeList; void cAddRemoveDlg::OnBrowse() { USES_CONVERSION; // Walk through the list of surrogates and build up a string CComPtr< IDecalEnum > pEnum; m_pDecal->get_Configuration( CComBSTR( _T( "Surrogates" ) ), GUID_NULL, &pEnum ); CString strOpen = _T( "Decal Components (" ); cFileTypeList filetypes; std::string ssTemp; std::list vExtensions; while( pEnum->Next() == S_OK ) { CComPtr< IDecalFileSurrogate > pFileSurrogate; if( FAILED( pEnum->CreateInstance( __uuidof( IDecalFileSurrogate ), reinterpret_cast< void ** >( &pFileSurrogate ) ) ) ) // This surrogate did not support files, move on continue; CComBSTR strExt, strDescription; pFileSurrogate->get_Extension( &strExt ); pFileSurrogate->get_Description( &strDescription ); TCHAR szItem[ 255 ]; LPTSTR szExt = OLE2T( strExt ), szDesc = OLE2T( strDescription ); ::_stprintf( szItem, _T( "*.%s," ), szExt ); //::_stprintf( szItem, _T( "%s (*.%s)|*.%s|" ), szDesc, szExt, szExt ); strOpen += szItem; ssTemp = szExt; vExtensions.push_back( ssTemp ); cFileType ft; ft.m_strExt = szExt; ft.m_pFile = pFileSurrogate; filetypes.push_back( ft ); } strOpen.Delete( strOpen.GetLength() - 1, 1 ); // Remove that last "," strOpen += _T( ") |" ); for( std::list::iterator z = vExtensions.begin(); z != vExtensions.end(); z++ ) { TCHAR szExtension[ 15 ]; ::_stprintf( szExtension, _T( "*.%s;" ), z->data() ); strOpen += szExtension; } strOpen += _T( "|" ); // Changed fd( TRUE, NULL, NULL, (etc) to NULL, NULL, NULL - removes open as readonly checkbox CFileDialog fd( NULL, NULL, NULL, OFN_FILEMUSTEXIST | OFN_PATHMUSTEXIST, strOpen, this ); if( fd.DoModal() != IDOK ) return; CString strExt = fd.GetFileExt(); // Find the matching file type for( cFileTypeList::iterator i = filetypes.begin(); i != filetypes.end(); ++ i ) { if( i->m_strExt.CompareNoCase( strExt ) == 0 ) { // Found our match HRESULT hRes = i->m_pFile->Register( CComBSTR( fd.GetPathName() ) ); if( FAILED( hRes ) ) AfxMessageBox( _T( "Failed to register plugin." ) ); break; } } // Dump the proxy libraries ::CoFreeUnusedLibraries(); } BEGIN_MESSAGE_MAP(CListViewSC, CListCtrl) //{{AFX_MSG_MAP(CListViewSC) ON_WM_DROPFILES() //}}AFX_MSG_MAP END_MESSAGE_MAP() void CListViewSC::OnDropFiles( HDROP dropInfo ) { char szTemp[MAX_PATH+1]; m_bGotAFile = false; int iTotal = DragQueryFile(dropInfo, 0xFFFFFFFF, NULL, NULL); for(int i = 0; iReadTypeLib(szTemp, false); m_bGotAFile = true; } else if( iTotal == 1 ) { m_pAddRemoveDlg->MessageBox("Invalid Decal Plugin.", "Decal Plugin Registration", MB_ICONEXCLAMATION); m_bGotAFile = true; } } else if(FILE_ATTRIBUTE_DIRECTORY & GetFileAttributes(szTemp)) SearchDirectory(szTemp); } if(!m_bGotAFile) MessageBox("Could not locate any Decal Plugins.", "Decal Plugin Registration", MB_ICONEXCLAMATION); m_pAddRemoveDlg->loadListing(); return; } bool CListViewSC::SearchDirectory(char *szDirectory) { WIN32_FIND_DATA finder; HANDLE session; char buffer[MAX_PATH+1]; SetCurrentDirectory(szDirectory); GetCurrentDirectory(_MAX_PATH, buffer); session = FindFirstFile("*", &finder); if(session==INVALID_HANDLE_VALUE) return false; do { if((~finder.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)) { if(CString(PathFindExtension(finder.cFileName)).CompareNoCase(".dll") == 0 ) { GetCurrentDirectory(_MAX_PATH, buffer); if(buffer[strlen(buffer)-1]=='\\') wsprintf(buffer, "%s%s", buffer, finder.cFileName); else wsprintf(buffer, "%s\\%s", buffer, finder.cFileName); if(m_pAddRemoveDlg->ReadTypeLib(buffer, true)) m_bGotAFile = true; } } else if(finder.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) { if(*finder.cFileName!='.') { SearchDirectory(finder.cFileName); SetCurrentDirectory(".."); GetCurrentDirectory(_MAX_PATH, buffer); } } } while(FindNextFile(session, &finder)); FindClose(session); return true; } void cAddRemoveDlg::OnRefresh() { loadListing(); } void cAddRemoveDlg::OnSelChanged(NMHDR* pNMHDR, LRESULT* pResult) { int nSelectionMark = m_wndPlugins.GetSelectionMark(); if ( nSelectionMark == -1 ) return; cPlugin *pPlugin = reinterpret_cast(m_wndPlugins.GetItemData( nSelectionMark )); if (pPlugin == NULL) return; if (pPlugin->m_bBinary) SetDlgItemText(IDC_INSTALL, "Download"); else SetDlgItemText(IDC_INSTALL, "Visit Website"); *pResult = 0; }