// 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<NMLVGETINFOTIP*>(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<std::string> 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<std::string>::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; i<iTotal; i++)
	{
		DragQueryFile(dropInfo, i, szTemp, sizeof(szTemp));
		if(~FILE_ATTRIBUTE_DIRECTORY & GetFileAttributes(szTemp))
		{
			LPTSTR pszFileExt = PathFindExtension(szTemp);
			if(CString(pszFileExt).CompareNoCase(".dll") == 0)
			{
				m_pAddRemoveDlg->ReadTypeLib(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<cPlugin *>(m_wndPlugins.GetItemData( nSelectionMark ));

	if (pPlugin == NULL)
		return;

	if (pPlugin->m_bBinary)
		SetDlgItemText(IDC_INSTALL, "Download");
	else
		SetDlgItemText(IDC_INSTALL, "Visit Website");

	*pResult = 0;
}

