Add new improved interface and multi-threaded goodness

This commit is contained in:
locka%iol.ie 1998-10-26 22:15:33 +00:00
Родитель a286330c8b
Коммит 2c75727053
14 изменённых файлов: 934 добавлений и 237 удалений

Просмотреть файл

@ -3,7 +3,6 @@
#include "stdafx.h"
#include "IEPatcher.h"
#include "IEPatcherDlg.h"
#ifdef _DEBUG
#define new DEBUG_NEW
@ -27,8 +26,7 @@ END_MESSAGE_MAP()
CIEPatcherApp::CIEPatcherApp()
{
// TODO: add construction code here,
// Place all significant initialization in InitInstance
m_pIEPatcherDlg = NULL;
}
/////////////////////////////////////////////////////////////////////////////
@ -73,9 +71,10 @@ BOOL CIEPatcherApp::InitInstance()
COleObjectFactory::UpdateRegistryAll();
}
CIEPatcherDlg dlg;
m_pMainWnd = &dlg;
int nResponse = dlg.DoModal();
// Now the scanner window
m_pIEPatcherDlg = new CIEPatcherDlg;
m_pMainWnd = m_pIEPatcherDlg;
int nResponse = m_pIEPatcherDlg->DoModal();
if (nResponse == IDOK)
{
// TODO: Place code here to handle when the dialog is
@ -86,6 +85,7 @@ BOOL CIEPatcherApp::InitInstance()
// TODO: Place code here to handle when the dialog is
// dismissed with Cancel
}
delete m_pIEPatcherDlg;
// Since the dialog has been closed, return FALSE so that we exit the
// application, rather than start the application's message pump.

Просмотреть файл

@ -102,6 +102,13 @@ SOURCE=.\IEPatcher.odl
# Begin Source File
SOURCE=.\IEPatcher.rc
!IF "$(CFG)" == "IEPatcher - Win32 Release"
!ELSEIF "$(CFG)" == "IEPatcher - Win32 Debug"
!ENDIF
# End Source File
# Begin Source File
@ -109,6 +116,18 @@ SOURCE=.\IEPatcherDlg.cpp
# End Source File
# Begin Source File
SOURCE=.\ScanForFilesDlg.cpp
# End Source File
# Begin Source File
SOURCE=.\ScannerThread.cpp
# End Source File
# Begin Source File
SOURCE=.\ScannerWnd.cpp
# End Source File
# Begin Source File
SOURCE=.\StdAfx.cpp
# ADD CPP /Yc"stdafx.h"
# End Source File
@ -134,6 +153,18 @@ SOURCE=.\Resource.h
# End Source File
# Begin Source File
SOURCE=.\ScanForFilesDlg.h
# End Source File
# Begin Source File
SOURCE=.\ScannerThread.h
# End Source File
# Begin Source File
SOURCE=.\ScannerWnd.h
# End Source File
# Begin Source File
SOURCE=.\StdAfx.h
# End Source File
# End Group
@ -142,12 +173,28 @@ SOURCE=.\StdAfx.h
# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;cnt;rtf;gif;jpg;jpeg;jpe"
# Begin Source File
SOURCE=.\res\containsie.ico
# End Source File
# Begin Source File
SOURCE=.\res\containsmozilla.ico
# End Source File
# Begin Source File
SOURCE=.\res\doesntcontainie.ico
# End Source File
# Begin Source File
SOURCE=.\res\IEPatcher.ico
# End Source File
# Begin Source File
SOURCE=.\res\IEPatcher.rc2
# End Source File
# Begin Source File
SOURCE=.\res\unknownstatus.ico
# End Source File
# End Group
# Begin Source File

Просмотреть файл

@ -14,6 +14,8 @@
#include "resource.h" // main symbols
#include "IEPatcherDlg.h"
/////////////////////////////////////////////////////////////////////////////
// CIEPatcherApp:
// See IEPatcher.cpp for the implementation of this class
@ -24,6 +26,8 @@ class CIEPatcherApp : public CWinApp
public:
CIEPatcherApp();
CIEPatcherDlg *m_pIEPatcherDlg;
// Overrides
// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(CIEPatcherApp)

Просмотреть файл

@ -26,25 +26,34 @@ LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
// Dialog
//
IDD_IEPATCHER_DIALOG DIALOGEX 0, 0, 277, 202
IDD_IEPATCHER_DIALOG DIALOGEX 0, 0, 323, 202
STYLE DS_MODALFRAME | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU
EXSTYLE WS_EX_APPWINDOW
CAPTION "IE to Mozilla Patcher"
FONT 8, "MS Sans Serif"
BEGIN
LTEXT "Source filename:",IDC_STATIC,16,7,54,8
EDITTEXT IDC_FILENAME,16,18,230,15,ES_AUTOHSCROLL
PUSHBUTTON "...",IDC_PICKSOURCE,250,18,15,15
GROUPBOX "",IDC_STATIC,7,40,263,51
CONTROL "&Patch file",IDC_PATCHFILE,"Button",BS_AUTOCHECKBOX |
WS_TABSTOP,15,40,47,10
LTEXT "Destination filename:",IDC_STATIC,16,54,119,8
EDITTEXT IDC_DESTINATION_FILENAME,16,65,230,15,ES_AUTOHSCROLL |
WS_DISABLED
PUSHBUTTON "...",IDC_PICKDESTINATION,250,65,15,15,WS_DISABLED
PUSHBUTTON "&Scan",IDC_SCAN,7,98,50,14
LISTBOX IDC_PROGRESS,7,119,263,76,LBS_NOINTEGRALHEIGHT |
LBS_NOSEL | WS_VSCROLL | WS_HSCROLL | WS_TABSTOP
PUSHBUTTON "&Scan...",IDC_SCAN,266,6,50,14
CONTROL "List1",IDC_FILELIST,"SysListView32",LVS_REPORT |
LVS_SHOWSELALWAYS | LVS_SORTASCENDING | WS_BORDER |
WS_TABSTOP,7,59,309,136
PUSHBUTTON "&Patch",IDC_PATCH,266,26,50,14
LTEXT "Add files to the source list by selecting ""Scan"". Files containing references to Internet Explorer or Mozilla will be highlighted.",
IDC_STATIC,7,6,257,18
LTEXT "Choose ""Patch"" to apply the Mozilla patch to any selected files. The patching process does not overwrite the original file but creates a new file prepended with ""moz_"" which you may test at your leisure.",
IDC_STATIC,7,30,257,26
END
IDD_SCANFORFILES DIALOG DISCARDABLE 0, 0, 227, 46
STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
CAPTION "Scan for files"
FONT 8, "MS Sans Serif"
BEGIN
LTEXT "Type a wildcard pattern or filename.",IDC_STATIC,7,7,
155,12
EDITTEXT IDC_FILEPATTERN,7,20,145,13,ES_AUTOHSCROLL
PUSHBUTTON "...",IDC_SELECTFILE,150,20,12,13
DEFPUSHBUTTON "OK",IDOK,170,5,50,14
PUSHBUTTON "Cancel",IDCANCEL,170,25,50,14
END
@ -102,14 +111,34 @@ BEGIN
IDD_IEPATCHER_DIALOG, DIALOG
BEGIN
LEFTMARGIN, 7
RIGHTMARGIN, 270
TOPMARGIN, 7
RIGHTMARGIN, 316
TOPMARGIN, 6
BOTTOMMARGIN, 195
END
IDD_SCANFORFILES, DIALOG
BEGIN
LEFTMARGIN, 7
RIGHTMARGIN, 220
TOPMARGIN, 7
BOTTOMMARGIN, 39
END
END
#endif // APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// Icon
//
// Icon with lowest ID value placed first to ensure application icon
// remains consistent on all systems.
IDI_CONTAINSIE ICON DISCARDABLE "res\\containsie.ico"
IDI_DOESNTCONTAINIE ICON DISCARDABLE "res\\doesntcontainie.ico"
IDI_CONTAINSMOZILLA ICON DISCARDABLE "res\\containsmozilla.ico"
IDI_UNKNOWNSTATUS ICON DISCARDABLE "res\\unknownstatus.ico"
/////////////////////////////////////////////////////////////////////////////
//
// String Table

Просмотреть файл

@ -4,6 +4,8 @@
#include "stdafx.h"
#include "IEPatcher.h"
#include "IEPatcherDlg.h"
#include "ScanForFilesDlg.h"
#include "ScannerThread.h"
#include "DlgProxy.h"
#include <sys/types.h>
@ -23,6 +25,14 @@ const IID IID_IWebBrowser = { 0xEAB22AC1, 0x30C1, 0x11CF, { 0xA7, 0xEB, 0x00, 0x
const IID IID_IWebBrowser2 = { 0xD30C1661, 0xCDAF, 0x11d0, { 0x8A, 0x3E, 0x00, 0xC0, 0x4F, 0xC9, 0xE2, 0x6E } };
const IID IID_IWebBrowserApp = { 0x0002DF05, 0x0000, 0x0000, { 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46 } };
#define ITEM_PATCHSTATUS 1
#define IMG_DOESNTCONTAINIE 0
#define IMG_CONTAINSIE 1
#define IMG_CONTAINSMOZILLA 2
#define IMG_UNKNOWNSTATUS 3
/////////////////////////////////////////////////////////////////////////////
// CIEPatcherDlg dialog
@ -32,15 +42,13 @@ CIEPatcherDlg::CIEPatcherDlg(CWnd* pParent /*=NULL*/)
: CDialog(CIEPatcherDlg::IDD, pParent)
{
//{{AFX_DATA_INIT(CIEPatcherDlg)
m_sFile = _T("");
m_sDestinationFile = _T("");
m_bPatchFile = FALSE;
//}}AFX_DATA_INIT
// Note that LoadIcon does not require a subsequent DestroyIcon in Win32
m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
m_pAutoProxy = NULL;
}
CIEPatcherDlg::~CIEPatcherDlg()
{
// If there is an automation proxy for this dialog, set
@ -50,32 +58,30 @@ CIEPatcherDlg::~CIEPatcherDlg()
m_pAutoProxy->m_pDialog = NULL;
}
void CIEPatcherDlg::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
//{{AFX_DATA_MAP(CIEPatcherDlg)
DDX_Control(pDX, IDC_PICKDESTINATION, m_btnPickDestination);
DDX_Control(pDX, IDC_SCAN, m_btnScan);
DDX_Control(pDX, IDC_DESTINATION_FILENAME, m_edtDestinationFile);
DDX_Control(pDX, IDC_PROGRESS, m_lstProgress);
DDX_Text(pDX, IDC_FILENAME, m_sFile);
DDX_Text(pDX, IDC_DESTINATION_FILENAME, m_sDestinationFile);
DDX_Check(pDX, IDC_PATCHFILE, m_bPatchFile);
DDX_Control(pDX, IDC_PATCH, m_btnPatch);
DDX_Control(pDX, IDC_FILELIST, m_cFileList);
//}}AFX_DATA_MAP
}
BEGIN_MESSAGE_MAP(CIEPatcherDlg, CDialog)
//{{AFX_MSG_MAP(CIEPatcherDlg)
ON_WM_PAINT()
ON_WM_QUERYDRAGICON()
ON_WM_CLOSE()
ON_BN_CLICKED(IDC_SCAN, OnScan)
ON_BN_CLICKED(IDC_PATCHFILE, OnPatchFile)
ON_BN_CLICKED(IDC_PICKSOURCE, OnPicksource)
ON_BN_CLICKED(IDC_PICKDESTINATION, OnPickdestination)
ON_NOTIFY(NM_CLICK, IDC_FILELIST, OnClickFilelist)
ON_BN_CLICKED(IDC_PATCH, OnPatch)
//}}AFX_MSG_MAP
ON_MESSAGE(WM_UPDATEFILESTATUS, OnUpdateFileStatus)
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CIEPatcherDlg message handlers
@ -83,16 +89,73 @@ BOOL CIEPatcherDlg::OnInitDialog()
{
CDialog::OnInitDialog();
// Start the scanner thread
AfxBeginThread(RUNTIME_CLASS(CScannerThread), 0);
// Set the icon for this dialog. The framework does this automatically
// when the application's main window is not a dialog
SetIcon(m_hIcon, TRUE); // Set big icon
SetIcon(m_hIcon, FALSE); // Set small icon
// Add icons to image list
m_cImageList.Create(16, 16, ILC_MASK, 0, 5);
m_cImageList.Add(AfxGetApp()->LoadIcon(IDI_DOESNTCONTAINIE));
m_cImageList.Add(AfxGetApp()->LoadIcon(IDI_CONTAINSIE));
m_cImageList.Add(AfxGetApp()->LoadIcon(IDI_CONTAINSMOZILLA));
m_cImageList.Add(AfxGetApp()->LoadIcon(IDI_UNKNOWNSTATUS));
// Associate image list with file list
m_cFileList.SetImageList(&m_cImageList, LVSIL_SMALL);
struct ColumnData
{
TCHAR *sColumnTitle;
int nPercentageWidth;
int nFormat;
};
ColumnData aColData[] =
{
{ _T("File"), 70, LVCFMT_LEFT },
{ _T("Patch Status"), 30, LVCFMT_LEFT }
};
// Get the size of the file list control and neatly
// divide it into columns
CRect rcFileList;
m_cFileList.GetClientRect(&rcFileList);
int nColTotal = sizeof(aColData) / sizeof(aColData[0]);
int nWidthRemaining = rcFileList.Width();
// TODO: Add extra initialization here
for (int nCol = 0; nCol < nColTotal; nCol++)
{
ColumnData *pData = &aColData[nCol];
int nColWidth = (rcFileList.Width() * pData->nPercentageWidth) / 100;
if (nCol == nColTotal - 1)
{
nColWidth = nWidthRemaining;
}
else if (nColWidth > nWidthRemaining)
{
nColWidth = nWidthRemaining;
}
m_cFileList.InsertColumn(nCol, pData->sColumnTitle, pData->nFormat, nColWidth);
nWidthRemaining -= nColWidth;
if (nColWidth <= 0)
{
break;
}
}
return TRUE; // return TRUE unless you set the focus to a control
}
// If you add a minimize button to your dialog, you will need the code below
// to draw the icon. For MFC applications using the document/view model,
// this is automatically done for you by the framework.
@ -122,6 +185,7 @@ void CIEPatcherDlg::OnPaint()
}
}
// The system calls this to obtain the cursor to display while the user drags
// the minimized window.
HCURSOR CIEPatcherDlg::OnQueryDragIcon()
@ -129,6 +193,7 @@ HCURSOR CIEPatcherDlg::OnQueryDragIcon()
return (HCURSOR) m_hIcon;
}
// Automation servers should not exit when a user closes the UI
// if a controller still holds on to one of its objects. These
// message handlers make sure that if the proxy is still in use,
@ -141,18 +206,65 @@ void CIEPatcherDlg::OnClose()
CDialog::OnClose();
}
void CIEPatcherDlg::OnOK()
LONG CIEPatcherDlg::OnUpdateFileStatus(WPARAM wParam, LPARAM lParam)
{
if (CanExit())
CDialog::OnOK();
PatchStatus ps = (PatchStatus) wParam;
TCHAR *pszFile = (TCHAR *) lParam;
UpdateFileStatus(pszFile, ps);
return 0;
}
void CIEPatcherDlg::OnCancel()
void CIEPatcherDlg::OnScan()
{
if (CanExit())
CDialog::OnCancel();
CScanForFilesDlg dlg;
if (dlg.DoModal() == IDOK)
{
CWaitCursor wc;
CFileFind op;
if (op.FindFile(dlg.m_sFilePattern))
{
op.FindNextFile();
do {
if (!op.IsDirectory())
{
AddFileToList(op.GetFilePath());
}
} while (op.FindNextFile());
op.Close();
}
}
}
void CIEPatcherDlg::OnPatch()
{
int nItem = -1;
do {
nItem = m_cFileList.GetNextItem(nItem, LVNI_ALL | LVNI_SELECTED);
if (nItem != -1)
{
m_cQueuedFileDataList[nItem]->ps = psPatchPending;
UpdateFileStatus(nItem, m_cQueuedFileDataList[nItem]->sFileName, m_cQueuedFileDataList[nItem]->ps);
}
} while (nItem != -1);
}
void CIEPatcherDlg::OnClickFilelist(NMHDR* pNMHDR, LRESULT* pResult)
{
// Check if files are selected
*pResult = 0;
}
///////////////////////////////////////////////////////////////////////////////
BOOL CIEPatcherDlg::CanExit()
{
// If the proxy object is still around, then the automation
@ -167,219 +279,343 @@ BOOL CIEPatcherDlg::CanExit()
return TRUE;
}
void CIEPatcherDlg::OnScan()
PatchStatus CIEPatcherDlg::ScanFile(const CString &sFileName)
{
UpdateData();
m_lstProgress.ResetContent();
// Search file for files matching the file name
// in case it is a pattern
CStringList sFileList;
CFileFind cFileFind;
if (cFileFind.FindFile(m_sFile))
char *pszBuffer = NULL;
long nBufferSize = 0;
if (!ReadFileToBuffer(sFileName, &pszBuffer, &nBufferSize))
{
while (cFileFind.FindNextFile())
{
sFileList.AddTail(cFileFind.GetFilePath());
}
cFileFind.Close();
return psFileError;
}
if (sFileList.IsEmpty())
{
m_lstProgress.AddString("No matching files were found");
return;
}
else if (sFileList.GetCount() > 1)
{
m_lstProgress.AddString("More than 1 matching file was found");
POSITION pos = sFileList.GetHeadPosition();
while (pos)
{
CString sFile = sFileList.GetNext(pos);
PatchFile(sFile);
}
}
else
{
CString sFile = sFileList.GetAt(0);
if (!m_bPatchFile || m_sDestinationFile.IsEmpty())
{
PatchFile(m_sFile);
}
else
{
PatchFile(m_sFile, m_sDestinationFile);
}
}
m_lstProgress.AddString("Processing completed");
PatchStatus ps = ScanBuffer(pszBuffer, nBufferSize, FALSE);
delete []pszBuffer;
return ps;
}
BOOL CIEPatcherDlg::PatchFile(const CString & sFileFrom, const CString & sFileTo)
BOOL CIEPatcherDlg::WriteBufferToFile(const CString &sFileName, char *pszBuffer, long nBufferSize)
{
// Turn on patching if possible
BOOL bPatchOnly = TRUE;
if (!sFileTo.IsEmpty())
CString sMessage;
sMessage.Format("Saving patched file \"%s\"", sFileName);
TraceProgress(sMessage);
FILE *fDest = fopen(sFileName, "wb");
if (fDest == NULL)
{
if (sFileTo == sFileFrom)
{
m_lstProgress.AddString("Warning: Patching disabled for safety reasons, source and destination names must differ");
}
else
{
bPatchOnly = FALSE;
}
TraceProgress("Error: Could not open destination file");
return FALSE;
}
fwrite(pszBuffer, 1, nBufferSize, fDest);
fclose(fDest);
TraceProgress("File saved");
return TRUE;
}
BOOL CIEPatcherDlg::ReadFileToBuffer(const CString &sFileName, char **ppszBuffer, long *pnBufferSize)
{
CString sProcessing;
sProcessing.Format("Processing file \"%s\"", sFileFrom);
m_lstProgress.AddString(sProcessing);
sProcessing.Format("Processing file \"%s\"", sFileName);
TraceProgress(sProcessing);
// Allocate a memory buffer to slurp up the whole file
struct _stat srcStat;
_stat(sFileFrom, &srcStat);
_stat(sFileName, &srcStat);
char *pszFile = new char[srcStat.st_size / sizeof(char)];
if (pszFile == NULL)
char *pszBuffer = new char[srcStat.st_size / sizeof(char)];
if (pszBuffer == NULL)
{
m_lstProgress.AddString("Error: Could not allocate buffer for file");
TraceProgress("Error: Could not allocate buffer for file");
return FALSE;
}
FILE *fSrc = fopen(sFileName, "rb");
if (fSrc == NULL)
{
TraceProgress("Error: Could not open file");
delete []pszBuffer;
return FALSE;
}
size_t sizeSrc = srcStat.st_size;
size_t sizeRead = 0;
// Dumb but effective
sizeRead = fread(pszBuffer, 1, sizeSrc, fSrc);
fclose(fSrc);
if (sizeRead != sizeSrc)
{
TraceProgress("Error: Could not read all of file");
delete []pszBuffer;
return FALSE;
}
*ppszBuffer = pszBuffer;
*pnBufferSize = sizeRead;
return TRUE;
}
PatchStatus CIEPatcherDlg::ScanBuffer(char *pszBuffer, long nBufferSize, BOOL bApplyPatch)
{
if (nBufferSize < sizeof(CLSID))
{
return psNotPatchable;
}
TraceProgress("Scanning for IE...");
BOOL bPatchApplied = FALSE;
PatchStatus ps = psUnknownStatus;
// Scan through buffer, one byte at a time doing a memcmp
for (size_t i = 0; i < nBufferSize - sizeof(CLSID); i++)
{
if (memcmp(&pszBuffer[i], &CLSID_MozillaBrowser, sizeof(CLSID)) == 0)
{
TraceProgress("Found CLSID_MozillaBrowser");
if (ps == psUnknownStatus)
{
ps = psAlreadyPatched;
}
}
else if (memcmp(&pszBuffer[i], &CLSID_WebBrowser_V1, sizeof(CLSID)) == 0)
{
TraceProgress("Found CLSID_WebBrowser_V1");
if (ps == psUnknownStatus)
{
ps = psPatchable;
}
if (bApplyPatch)
{
TraceProgress("Patching with CLSID_MozillaBrowser");
memcpy(&pszBuffer[i], &CLSID_MozillaBrowser, sizeof(CLSID));
bPatchApplied = TRUE;
}
}
else if (memcmp(&pszBuffer[i], &CLSID_WebBrowser, sizeof(CLSID)) == 0)
{
TraceProgress("Found CLSID_WebBrowser");
if (ps == psUnknownStatus)
{
ps = psPatchable;
}
if (bApplyPatch)
{
TraceProgress("Patching with CLSID_MozillaBrowser");
memcpy(&pszBuffer[i], &CLSID_MozillaBrowser, sizeof(CLSID));
TraceProgress("Patching with CLSID_MozillaBrowser");
}
}
else if (memcmp(&pszBuffer[i], &IID_IWebBrowser, sizeof(CLSID)) == 0)
{
TraceProgress("Found IID_IWebBrowser");
if (ps == psUnknownStatus)
{
ps = psPatchable;
}
}
else if (memcmp(&pszBuffer[i], &CLSID_InternetExplorer, sizeof(CLSID)) == 0)
{
TraceProgress("Warning: Found CLSID_InternetExplorer, patching might not work");
if (ps == psUnknownStatus)
{
ps = psMayBePatchable;
}
}
else if (memcmp(&pszBuffer[i], &IID_IWebBrowser2, sizeof(CLSID)) == 0)
{
TraceProgress("Found IID_IWebBrowser2");
if (ps == psUnknownStatus)
{
ps = psPatchable;
}
}
else if (memcmp(&pszBuffer[i], &IID_IWebBrowserApp, sizeof(CLSID)) == 0)
{
TraceProgress("Found IID_IWebBrowserApp");
if (ps == psUnknownStatus)
{
ps = psPatchable;
}
}
}
if (ps == psUnknownStatus)
{
ps = psNotPatchable;
}
if (bApplyPatch)
{
ps = (bPatchApplied) ? psAlreadyPatched : psNotPatchable;
}
TraceProgress("Scan completed");
return ps;
}
BOOL CIEPatcherDlg::PatchFile(const CString & sFileFrom, const CString & sFileTo, PatchStatus *pPatchStatus)
{
if (sFileTo.IsEmpty())
{
return FALSE;
}
if (sFileTo == sFileFrom)
{
TraceProgress("Warning: Patching disabled for safety reasons, source and destination names must differ");
return FALSE;
}
char *pszBuffer = NULL;
long nBufferSize = 0;
if (!ReadFileToBuffer(sFileFrom, &pszBuffer, &nBufferSize))
{
return FALSE;
}
// Scan and patch the buffer
*pPatchStatus = ScanBuffer(pszBuffer, nBufferSize, TRUE);
if (*pPatchStatus == psNotPatchable)
{
TraceProgress("Error: Nothing was found to patch");
}
else
{
FILE *fSrc = fopen(sFileFrom, "rb");
if (fSrc == NULL)
{
m_lstProgress.AddString("Error: Could not open file");
}
else
{
size_t sizeSrc = srcStat.st_size;
size_t sizeRead = 0;
// Dumb but effective
sizeRead = fread(pszFile, 1, sizeSrc, fSrc);
fclose(fSrc);
if (sizeRead != sizeSrc)
{
m_lstProgress.AddString("Error: Could not read all of file");
}
else
{
BOOL bPatchApplied = FALSE;
m_lstProgress.AddString("Scanning for IE...");
// Scan through buffer, one byte at a time doing a memcmp
for (size_t i = 0; i < sizeSrc - sizeof(CLSID); i++)
{
if (memcmp(&pszFile[i], &CLSID_WebBrowser_V1, sizeof(CLSID)) == 0)
{
m_lstProgress.AddString("Found CLSID_WebBrowser_V1");
if (!bPatchOnly)
{
m_lstProgress.AddString("Patching with CLSID_MozillaBrowser");
memcpy(&pszFile[i], &CLSID_MozillaBrowser, sizeof(CLSID));
bPatchApplied = TRUE;
}
}
else if (memcmp(&pszFile[i], &CLSID_WebBrowser, sizeof(CLSID)) == 0)
{
m_lstProgress.AddString("Found CLSID_WebBrowser");
if (!bPatchOnly)
{
m_lstProgress.AddString("Patching with CLSID_MozillaBrowser");
memcpy(&pszFile[i], &CLSID_MozillaBrowser, sizeof(CLSID));
m_lstProgress.AddString("Patching with CLSID_MozillaBrowser");
}
}
else if (memcmp(&pszFile[i], &IID_IWebBrowser, sizeof(CLSID)) == 0)
{
m_lstProgress.AddString("Found IID_IWebBrowser");
}
else if (memcmp(&pszFile[i], &CLSID_InternetExplorer, sizeof(CLSID)) == 0)
{
m_lstProgress.AddString("Warning: Found CLSID_InternetExplorer, patching might not work");
}
else if (memcmp(&pszFile[i], &IID_IWebBrowser2, sizeof(CLSID)) == 0)
{
m_lstProgress.AddString("Warning: Found IID_IWebBrowser2, patching might not work");
}
else if (memcmp(&pszFile[i], &IID_IWebBrowserApp, sizeof(CLSID)) == 0)
{
m_lstProgress.AddString("Warning: Found IID_IWebBrowserApp, patching might not work");
}
}
m_lstProgress.AddString("Scan completed");
// Write out the patch file
if (!bPatchOnly)
{
if (!bPatchApplied)
{
m_lstProgress.AddString("Error: Nothing was found to patch");
}
else
{
CString sMessage;
sMessage.Format("Saving patched file \"%s\"", sFileTo);
m_lstProgress.AddString(sMessage);
FILE *fDest = fopen(sFileTo, "wb");
if (fDest == NULL)
{
m_lstProgress.AddString("Error: Could not open destination file");
}
else
{
fwrite(pszFile, 1, sizeSrc, fDest);
fclose(fDest);
m_lstProgress.AddString("File saved");
}
}
}
}
}
delete []pszFile;
// Write out the patch file
WriteBufferToFile(sFileTo, pszBuffer, nBufferSize);
}
delete []pszBuffer;
return FALSE;
}
void CIEPatcherDlg::OnPatchFile()
void CIEPatcherDlg::TraceProgress(const CString &sProgress)
{
UpdateData();
m_edtDestinationFile.EnableWindow(m_bPatchFile);
m_btnPickDestination.EnableWindow(m_bPatchFile);
m_btnScan.SetWindowText(m_bPatchFile ? "&Patch" : "&Scan");
// TODO
}
void CIEPatcherDlg::OnPicksource()
{
CFileDialog dlgChooser(TRUE, NULL, NULL, OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT, _T("Application Files (*.exe;*.dll)|*.exe; *.dll|All Files (*.*)|*.*||"));
if (dlgChooser.DoModal() == IDOK)
void CIEPatcherDlg::AddFileToList(const CString & sFile)
{
CSingleLock sl(&m_csQueuedFileDataList, TRUE);
int nIndex = m_cFileList.GetItemCount();
m_cFileList.InsertItem(nIndex, sFile, IMG_UNKNOWNSTATUS);
QueuedFileData *pData = new QueuedFileData;
pData->ps = psUnknownStatus;
pData->sFileName = sFile;
pData->sPatchedFileName = sFile;
m_cQueuedFileDataList.Add(pData);
UpdateFileStatus(nIndex, pData->ps);
}
void CIEPatcherDlg::UpdateFileStatus(int nFileIndex, const CString &sFile, PatchStatus ps)
{
CString sStatus;
int nIconStatus = -1;
switch (ps)
{
m_sFile = dlgChooser.GetPathName();
UpdateData(FALSE);
case psFileError:
sStatus = _T("File error");
break;
case psNotPatchable:
sStatus = _T("Nothing to patch");
nIconStatus = IMG_DOESNTCONTAINIE;
break;
case psPatchable:
sStatus = _T("Patchable");
nIconStatus = IMG_CONTAINSIE;
break;
case psMayBePatchable:
sStatus = _T("Maybe patchable");
nIconStatus = IMG_CONTAINSIE;
break;
case psAlreadyPatched:
sStatus = _T("Already patched");
nIconStatus = IMG_CONTAINSMOZILLA;
break;
case psUnknownStatus:
sStatus = _T("Status pending");
nIconStatus = IMG_UNKNOWNSTATUS;
break;
case psPatchPending:
sStatus = _T("Patch pending");
break;
default:
sStatus = _T("*** ERROR ***");
break;
}
if (nIconStatus != -1)
{
m_cFileList.SetItem(nFileIndex, -1, LVIF_IMAGE, NULL, nIconStatus, 0, 0, 0);
}
m_cFileList.SetItemText(nFileIndex, ITEM_PATCHSTATUS, sStatus);
}
void CIEPatcherDlg::UpdateFileStatus(const CString &sFile, PatchStatus ps)
{
CSingleLock sl(&m_csQueuedFileDataList, TRUE);
for (int n = 0; n < m_cQueuedFileDataList.GetSize(); n++)
{
if (m_cQueuedFileDataList[n]->sFileName == sFile)
{
UpdateFileStatus(n, sFile, ps);
m_cQueuedFileDataList[n]->ps = ps;
return;
}
}
}
void CIEPatcherDlg::OnPickdestination()
{
CFileDialog dlgChooser(FALSE, NULL, NULL, OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT, _T("Application Files (*.exe;*.dll)|*.exe; *.dll|All Files (*.*)|*.*||"));
if (dlgChooser.DoModal() == IDOK)
BOOL CIEPatcherDlg::GetPendingFileToScan(CString & sFileToScan)
{
CSingleLock sl(&m_csQueuedFileDataList, TRUE);
for (int n = 0; n < m_cQueuedFileDataList.GetSize(); n++)
{
m_sDestinationFile = dlgChooser.GetPathName();
UpdateData(FALSE);
if (m_cQueuedFileDataList[n]->ps == psUnknownStatus)
{
sFileToScan = m_cQueuedFileDataList[n]->sFileName;
return TRUE;
}
}
return FALSE;
}
BOOL CIEPatcherDlg::GetPendingFileToPatch(CString & sFileToPatch)
{
CSingleLock sl(&m_csQueuedFileDataList, TRUE);
for (int n = 0; n < m_cQueuedFileDataList.GetSize(); n++)
{
if (m_cQueuedFileDataList[n]->ps == psPatchPending)
{
sFileToPatch = m_cQueuedFileDataList[n]->sFileName;
return TRUE;
}
}
return FALSE;
}

Просмотреть файл

@ -10,6 +10,26 @@
class CIEPatcherDlgAutoProxy;
enum PatchStatus
{
psFileError,
psUnknownStatus,
psPatchPending,
psNotPatchable,
psPatchable,
psMayBePatchable,
psAlreadyPatched
};
struct QueuedFileData
{
CString sFileName;
CString sPatchedFileName;
PatchStatus ps;
};
#define WM_UPDATEFILESTATUS WM_USER+1
/////////////////////////////////////////////////////////////////////////////
// CIEPatcherDlg dialog
@ -20,20 +40,35 @@ class CIEPatcherDlg : public CDialog
// Construction
public:
BOOL PatchFile(const CString &sFileFrom, const CString &sFileTo = "");
void AddFileToList(const CString &sFile);
BOOL GetPendingFileToScan(CString &sFileToScan);
BOOL GetPendingFileToPatch(CString &sFileToPatch);
static PatchStatus ScanFile(const CString &sFileName);
static PatchStatus ScanBuffer(char *pszBuffer, long nBufferSize, BOOL bApplyPatches);
static BOOL PatchFile(const CString & sFileFrom, const CString & sFileTo, PatchStatus *pPatchStatus);
static BOOL WriteBufferToFile(const CString &sFileName, char *pszBuffer, long nBufferSize);
static BOOL ReadFileToBuffer(const CString &sFileName, char **ppszBuffer, long *pnBufferSize);
static void TraceProgress(const CString &sProgress);
void UpdateFileStatus(const CString &sFile, PatchStatus ps);
void UpdateFileStatus(int nFileIndex, const CString &sFile, PatchStatus ps);
CIEPatcherDlg(CWnd* pParent = NULL); // standard constructor
virtual ~CIEPatcherDlg();
CImageList m_cImageList;
CArray<QueuedFileData *, QueuedFileData *> m_cQueuedFileDataList;
CCriticalSection m_csQueuedFileDataList;
// Dialog Data
//{{AFX_DATA(CIEPatcherDlg)
enum { IDD = IDD_IEPATCHER_DIALOG };
CButton m_btnPickDestination;
CButton m_btnScan;
CEdit m_edtDestinationFile;
CListBox m_lstProgress;
CString m_sFile;
CString m_sDestinationFile;
BOOL m_bPatchFile;
CButton m_btnPatch;
CListCtrl m_cFileList;
//}}AFX_DATA
// ClassWizard generated virtual function overrides
@ -55,13 +90,11 @@ protected:
afx_msg void OnPaint();
afx_msg HCURSOR OnQueryDragIcon();
afx_msg void OnClose();
virtual void OnOK();
virtual void OnCancel();
afx_msg void OnScan();
afx_msg void OnPatchFile();
afx_msg void OnPicksource();
afx_msg void OnPickdestination();
afx_msg void OnClickFilelist(NMHDR* pNMHDR, LRESULT* pResult);
afx_msg void OnPatch();
//}}AFX_MSG
afx_msg LONG OnUpdateFileStatus(WPARAM, LPARAM);
DECLARE_MESSAGE_MAP()
};
@ -69,3 +102,4 @@ protected:
// Microsoft Developer Studio will insert additional declarations immediately before the previous line.
#endif // !defined(AFX_IEPATCHERDLG_H__A603167C_3B36_11D2_B44D_00600819607E__INCLUDED_)

Просмотреть файл

@ -0,0 +1,60 @@
// ScanForFilesDlg.cpp : implementation file
//
#include "stdafx.h"
#include "IEPatcher.h"
#include "ScanForFilesDlg.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
/////////////////////////////////////////////////////////////////////////////
// CScanForFilesDlg dialog
CScanForFilesDlg::CScanForFilesDlg(CWnd* pParent /*=NULL*/)
: CDialog(CScanForFilesDlg::IDD, pParent)
{
//{{AFX_DATA_INIT(CScanForFilesDlg)
m_sFilePattern = _T("");
//}}AFX_DATA_INIT
}
void CScanForFilesDlg::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
//{{AFX_DATA_MAP(CScanForFilesDlg)
DDX_Text(pDX, IDC_FILEPATTERN, m_sFilePattern);
//}}AFX_DATA_MAP
}
BEGIN_MESSAGE_MAP(CScanForFilesDlg, CDialog)
//{{AFX_MSG_MAP(CScanForFilesDlg)
ON_BN_CLICKED(IDC_SELECTFILE, OnSelectFile)
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CScanForFilesDlg message handlers
void CScanForFilesDlg::OnOK()
{
UpdateData();
CDialog::OnOK();
}
void CScanForFilesDlg::OnSelectFile()
{
CFileDialog dlg(TRUE, NULL, _T("*.*"));
if (dlg.DoModal() == IDOK)
{
m_sFilePattern = dlg.GetPathName();
UpdateData(FALSE);
}
}

Просмотреть файл

@ -0,0 +1,47 @@
#if !defined(AFX_SCANFORFILESDLG_H__2CAAFC02_6C47_11D2_A1F5_000000000000__INCLUDED_)
#define AFX_SCANFORFILESDLG_H__2CAAFC02_6C47_11D2_A1F5_000000000000__INCLUDED_
#if _MSC_VER >= 1000
#pragma once
#endif // _MSC_VER >= 1000
// ScanForFilesDlg.h : header file
//
/////////////////////////////////////////////////////////////////////////////
// CScanForFilesDlg dialog
class CScanForFilesDlg : public CDialog
{
// Construction
public:
CScanForFilesDlg(CWnd* pParent = NULL); // standard constructor
// Dialog Data
//{{AFX_DATA(CScanForFilesDlg)
enum { IDD = IDD_SCANFORFILES };
CString m_sFilePattern;
//}}AFX_DATA
// Overrides
// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(CScanForFilesDlg)
protected:
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
//}}AFX_VIRTUAL
// Implementation
protected:
// Generated message map functions
//{{AFX_MSG(CScanForFilesDlg)
virtual void OnOK();
afx_msg void OnSelectFile();
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
};
//{{AFX_INSERT_LOCATION}}
// Microsoft Developer Studio will insert additional declarations immediately before the previous line.
#endif // !defined(AFX_SCANFORFILESDLG_H__2CAAFC02_6C47_11D2_A1F5_000000000000__INCLUDED_)

Просмотреть файл

@ -0,0 +1,46 @@
// ScannerThread.cpp : implementation file
//
#include "stdafx.h"
#include "iepatcher.h"
#include "ScannerThread.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
/////////////////////////////////////////////////////////////////////////////
// CScannerThread
IMPLEMENT_DYNCREATE(CScannerThread, CWinThread)
CScannerThread::CScannerThread()
{
}
CScannerThread::~CScannerThread()
{
}
BOOL CScannerThread::InitInstance()
{
m_cScannerWnd.Create(AfxRegisterWndClass(0), _T("Scanner"), 0L, CRect(0, 0, 0, 0), AfxGetMainWnd(), 1);
return TRUE;
}
int CScannerThread::ExitInstance()
{
// TODO: perform any per-thread cleanup here
return CWinThread::ExitInstance();
}
BEGIN_MESSAGE_MAP(CScannerThread, CWinThread)
//{{AFX_MSG_MAP(CScannerThread)
// NOTE - the ClassWizard will add and remove mapping macros here.
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CScannerThread message handlers

Просмотреть файл

@ -0,0 +1,54 @@
#if !defined(AFX_SCANNERTHREAD_H__2CAAFC04_6C47_11D2_A1F5_000000000000__INCLUDED_)
#define AFX_SCANNERTHREAD_H__2CAAFC04_6C47_11D2_A1F5_000000000000__INCLUDED_
#if _MSC_VER >= 1000
#pragma once
#endif // _MSC_VER >= 1000
// ScannerThread.h : header file
//
#include "ScannerWnd.h"
/////////////////////////////////////////////////////////////////////////////
// CScannerThread thread
class CScannerThread : public CWinThread
{
DECLARE_DYNCREATE(CScannerThread)
protected:
CScannerThread(); // protected constructor used by dynamic creation
// Attributes
public:
CScannerWnd m_cScannerWnd;
// Operations
public:
// Overrides
// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(CScannerThread)
public:
virtual BOOL InitInstance();
virtual int ExitInstance();
//}}AFX_VIRTUAL
// Implementation
protected:
virtual ~CScannerThread();
// Generated message map functions
//{{AFX_MSG(CScannerThread)
// NOTE - the ClassWizard will add and remove member functions here.
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
};
/////////////////////////////////////////////////////////////////////////////
//{{AFX_INSERT_LOCATION}}
// Microsoft Developer Studio will insert additional declarations immediately before the previous line.
#endif // !defined(AFX_SCANNERTHREAD_H__2CAAFC04_6C47_11D2_A1F5_000000000000__INCLUDED_)

Просмотреть файл

@ -0,0 +1,82 @@
// ScannerWnd.cpp : implementation file
//
#include "stdafx.h"
#include "iepatcher.h"
#include "ScannerWnd.h"
#include "IEPatcherDlg.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
/////////////////////////////////////////////////////////////////////////////
// CScannerWnd
CScannerWnd::CScannerWnd()
{
}
CScannerWnd::~CScannerWnd()
{
}
BEGIN_MESSAGE_MAP(CScannerWnd, CWnd)
//{{AFX_MSG_MAP(CScannerWnd)
ON_WM_TIMER()
ON_WM_CREATE()
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CScannerWnd message handlers
int CScannerWnd::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
if (CWnd::OnCreate(lpCreateStruct) == -1)
return -1;
SetTimer(1, 500, NULL);
return 0;
}
void CScannerWnd::OnTimer(UINT nIDEvent)
{
CIEPatcherDlg * pDlg = ((CIEPatcherApp *) AfxGetApp())->m_pIEPatcherDlg;
if (pDlg)
{
CString sFileToProcess;
if (pDlg->GetPendingFileToScan(sFileToProcess))
{
PatchStatus ps = CIEPatcherDlg::ScanFile(sFileToProcess);
AfxGetMainWnd()->SendMessage(WM_UPDATEFILESTATUS, (WPARAM) ps, (LPARAM) (const TCHAR *) sFileToProcess);
}
else if (pDlg->GetPendingFileToPatch(sFileToProcess))
{
TCHAR szDrive[_MAX_DRIVE];
TCHAR szDir[_MAX_DIR];
TCHAR szFile[_MAX_FNAME];
TCHAR szExt[_MAX_EXT];
_tsplitpath(sFileToProcess, szDrive, szDir, szFile, szExt);
CString sFileOut;
TCHAR szPath[_MAX_PATH];
sFileOut.Format(_T("moz_%s"), szFile);
_tmakepath(szPath, szDrive, szDir, sFileOut, szExt);
PatchStatus ps;
CIEPatcherDlg::PatchFile(sFileToProcess, szPath, &ps);
AfxGetMainWnd()->SendMessage(WM_UPDATEFILESTATUS, (WPARAM) ps, (LPARAM) (const TCHAR *) sFileToProcess);
}
}
CWnd::OnTimer(nIDEvent);
}

Просмотреть файл

@ -0,0 +1,48 @@
#if !defined(AFX_SCANNERWND_H__2CAAFC05_6C47_11D2_A1F5_000000000000__INCLUDED_)
#define AFX_SCANNERWND_H__2CAAFC05_6C47_11D2_A1F5_000000000000__INCLUDED_
#if _MSC_VER >= 1000
#pragma once
#endif // _MSC_VER >= 1000
// ScannerWnd.h : header file
//
/////////////////////////////////////////////////////////////////////////////
// CScannerWnd window
class CScannerWnd : public CWnd
{
// Construction
public:
CScannerWnd();
// Attributes
public:
// Operations
public:
// Overrides
// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(CScannerWnd)
//}}AFX_VIRTUAL
// Implementation
public:
virtual ~CScannerWnd();
// Generated message map functions
protected:
//{{AFX_MSG(CScannerWnd)
afx_msg void OnTimer(UINT nIDEvent);
afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct);
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
};
/////////////////////////////////////////////////////////////////////////////
//{{AFX_INSERT_LOCATION}}
// Microsoft Developer Studio will insert additional declarations immediately before the previous line.
#endif // !defined(AFX_SCANNERWND_H__2CAAFC05_6C47_11D2_A1F5_000000000000__INCLUDED_)

Просмотреть файл

@ -18,7 +18,8 @@
#ifndef _AFX_NO_AFXCMN_SUPPORT
#include <afxcmn.h> // MFC support for Windows Common Controls
#endif // _AFX_NO_AFXCMN_SUPPORT
#include <afxtempl.h>
#include <afxmt.h>
// This macro is the same as IMPLEMENT_OLECREATE, except it passes TRUE
// for the bMultiInstance parameter to the COleObjectFactory constructor.

Просмотреть файл

@ -5,6 +5,11 @@
#define IDP_OLE_INIT_FAILED 100
#define IDD_IEPATCHER_DIALOG 102
#define IDR_MAINFRAME 128
#define IDI_CONTAINSIE 129
#define IDI_DOESNTCONTAINIE 130
#define IDI_CONTAINSMOZILLA 131
#define IDD_SCANFORFILES 132
#define IDI_UNKNOWNSTATUS 133
#define IDC_FILENAME 1000
#define IDC_SCAN 1001
#define IDC_PROGRESS 1002
@ -12,14 +17,18 @@
#define IDC_DESTINATION_FILENAME 1004
#define IDC_PICKSOURCE 1005
#define IDC_PICKDESTINATION 1006
#define IDC_FILELIST 1007
#define IDC_PATCH 1008
#define IDC_FILEPATTERN 1009
#define IDC_SELECTFILE 1011
// Next default values for new objects
//
#ifdef APSTUDIO_INVOKED
#ifndef APSTUDIO_READONLY_SYMBOLS
#define _APS_NEXT_RESOURCE_VALUE 129
#define _APS_NEXT_RESOURCE_VALUE 134
#define _APS_NEXT_COMMAND_VALUE 32771
#define _APS_NEXT_CONTROL_VALUE 1006
#define _APS_NEXT_CONTROL_VALUE 1012
#define _APS_NEXT_SYMED_VALUE 101
#endif
#endif