247 lines
5.5 KiB
C++
247 lines
5.5 KiB
C++
|
#include "stdafx.h"
|
|||
|
#include "basic_form.h"
|
|||
|
|
|||
|
#include <atlstr.h>
|
|||
|
#include <afxdlgs.h>
|
|||
|
#include <afxwin.h>
|
|||
|
#include <io.h>
|
|||
|
#include <iosfwd>
|
|||
|
#include <iostream>
|
|||
|
#include <ios>
|
|||
|
#include <fstream>
|
|||
|
#include <vector>
|
|||
|
#include <codecvt>
|
|||
|
extern"C" {
|
|||
|
#include "bsdiff.h"
|
|||
|
#include "bspatch.h"
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
const std::wstring BasicForm::kClassName = L"Basic";
|
|||
|
|
|||
|
BasicForm::BasicForm()
|
|||
|
{
|
|||
|
}
|
|||
|
|
|||
|
BasicForm::~BasicForm()
|
|||
|
{
|
|||
|
}
|
|||
|
|
|||
|
std::wstring BasicForm::GetSkinFolder()
|
|||
|
{
|
|||
|
return L"basic";
|
|||
|
}
|
|||
|
|
|||
|
std::wstring BasicForm::GetSkinFile()
|
|||
|
{
|
|||
|
return L"bsdiff.xml";
|
|||
|
}
|
|||
|
|
|||
|
std::wstring BasicForm::GetWindowClassName() const
|
|||
|
{
|
|||
|
return kClassName;
|
|||
|
}
|
|||
|
|
|||
|
static int res_write(struct bsdiff_stream* stream, const void* buffer, int size)
|
|||
|
{
|
|||
|
int bz2err;
|
|||
|
|
|||
|
//BZ2_bzWrite(&bz2err, bz2, (void*)buffer, size);
|
|||
|
//if (bz2err != BZ_STREAM_END && bz2err != BZ_OK)
|
|||
|
// return -1;
|
|||
|
if (stream->size == 0) {
|
|||
|
stream->result = new char[8192000];
|
|||
|
stream->size = 8192000;
|
|||
|
}
|
|||
|
memcpy(&stream->result[stream->len], buffer, size);
|
|||
|
stream->len += size;
|
|||
|
|
|||
|
return 0;
|
|||
|
}
|
|||
|
|
|||
|
LRESULT BasicForm::OnNcHitTest(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
|
|||
|
{
|
|||
|
return WindowImplBase::OnNcHitTest(uMsg, wParam, lParam, bHandled);
|
|||
|
}
|
|||
|
|
|||
|
inline std::string to_byte_string(const std::wstring& input)
|
|||
|
{
|
|||
|
std::wstring_convert<std::codecvt_utf8<wchar_t>> converter;
|
|||
|
return converter.to_bytes(input);
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
static int bz2_read( struct bspatch_stream* stream, void* buffer, int length)
|
|||
|
{
|
|||
|
int n;
|
|||
|
int bz2err;
|
|||
|
char* addr = (char*)stream->opaque;
|
|||
|
memcpy(buffer, &addr[stream->res_len], length);
|
|||
|
stream->res_len += length;
|
|||
|
return 0;
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
std::vector<char>* ReadFile(std::string path) {
|
|||
|
std::vector<char>* ret = nullptr;
|
|||
|
std::ifstream file(path.c_str(), std::ios::in | std::ios::binary);
|
|||
|
if (file)
|
|||
|
{
|
|||
|
// <20><><EFBFBD>ն<EFBFBD><D5B6><EFBFBD><EFBFBD>Ƹ<EFBFBD>ʽ<EFBFBD><CABD>ȡ<EFBFBD><C8A1><EFBFBD><EFBFBD>
|
|||
|
file.seekg(0, std::ios::end);
|
|||
|
long long fileSize = file.tellg();
|
|||
|
printf("size of firm: %lld\n", fileSize);
|
|||
|
|
|||
|
// <20><><EFBFBD><EFBFBD>дλ<D0B4><CEBB><EFBFBD>ƶ<EFBFBD><C6B6><EFBFBD><EFBFBD>ļ<EFBFBD><C4BC><EFBFBD>ͷ<EFBFBD><CDB7><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ڴ棬<DAB4><E6A3AC><EFBFBD>̼<EFBFBD><CCBC><EFBFBD><EFBFBD>ݴ<EFBFBD><DDB4><EFBFBD>buffer
|
|||
|
file.seekg(0, std::ios::beg);
|
|||
|
char* buffer = new char[fileSize];
|
|||
|
file.read(buffer, sizeof(char) * fileSize);
|
|||
|
|
|||
|
ret = new std::vector<char>(buffer, buffer + sizeof(char) * fileSize);
|
|||
|
file.close();
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
std::cout << "Failed to open file." << std::endl;
|
|||
|
}
|
|||
|
return ret;
|
|||
|
}
|
|||
|
|
|||
|
void BasicForm::InitWindow() {
|
|||
|
|
|||
|
ui::Button* btn_open1 = dynamic_cast<ui::Button*>(FindControl(L"btn_do_open1"));
|
|||
|
|
|||
|
ui::Button* btn_open2 = dynamic_cast<ui::Button*>(FindControl(L"btn_do_open2"));
|
|||
|
|
|||
|
ui::Button* btn_open3 = dynamic_cast<ui::Button*>(FindControl(L"btn_do_generate"));
|
|||
|
|
|||
|
mLabel1 = dynamic_cast<ui::RichEdit*>(FindControl(L"file1_dir"));
|
|||
|
mLabel2 = dynamic_cast<ui::RichEdit*>(FindControl(L"file2_dir"));
|
|||
|
|
|||
|
btn_open1->AttachClick([this](ui::EventArgs*) {
|
|||
|
CString strFilter;
|
|||
|
CString str;
|
|||
|
CString m_strTmpFile;
|
|||
|
CStdioFile cfLogFile;
|
|||
|
|
|||
|
//<2F><><EFBFBD><EFBFBD><EFBFBD>˳<EFBFBD>*.txt<78><74>*.dat<61><74><EFBFBD>ļ<EFBFBD>
|
|||
|
strFilter = "dat file (*.*)|*.*";
|
|||
|
CFileDialog TmpDlg(true, 0, 0, OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT, strFilter.GetBuffer(),
|
|||
|
CWnd::FromHandle(this->m_hWnd));
|
|||
|
|
|||
|
if (TmpDlg.DoModal() == IDOK)
|
|||
|
{
|
|||
|
//<2F><>ȡ<EFBFBD>ļ<EFBFBD>·<EFBFBD><C2B7>
|
|||
|
m_strTmpFile = TmpDlg.GetPathName();
|
|||
|
|
|||
|
mLabel1->SetText(std::wstring(m_strTmpFile));
|
|||
|
}
|
|||
|
|
|||
|
return true;
|
|||
|
});
|
|||
|
|
|||
|
btn_open2->AttachClick([this](ui::EventArgs*) {
|
|||
|
CString strFilter;
|
|||
|
CString str;
|
|||
|
CString m_strTmpFile;
|
|||
|
CStdioFile cfLogFile;
|
|||
|
|
|||
|
//<2F><><EFBFBD><EFBFBD><EFBFBD>˳<EFBFBD>*.txt<78><74>*.dat<61><74><EFBFBD>ļ<EFBFBD>
|
|||
|
strFilter = "dat file (*.*)|*.*";
|
|||
|
CFileDialog TmpDlg(true, 0, 0, OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT, strFilter.GetBuffer(),
|
|||
|
CWnd::FromHandle(this->m_hWnd));
|
|||
|
|
|||
|
if (TmpDlg.DoModal() == IDOK)
|
|||
|
{
|
|||
|
//<2F><>ȡ<EFBFBD>ļ<EFBFBD>·<EFBFBD><C2B7>
|
|||
|
m_strTmpFile = TmpDlg.GetPathName();
|
|||
|
|
|||
|
mLabel2->SetText(std::wstring(m_strTmpFile));
|
|||
|
}
|
|||
|
|
|||
|
return true;
|
|||
|
});
|
|||
|
|
|||
|
btn_open3->AttachClick([this](ui::EventArgs*) {
|
|||
|
CString strFilter;
|
|||
|
CString str;
|
|||
|
CString m_strTmpFile;
|
|||
|
CStdioFile cfLogFile;
|
|||
|
|
|||
|
if (mLabel1->GetText() == L"") {
|
|||
|
AfxMessageBox(_T("<EFBFBD><EFBFBD><EFBFBD>ȴ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ļ<EFBFBD>"));
|
|||
|
|
|||
|
return false;
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
if (mLabel2->GetText() == L"") {
|
|||
|
AfxMessageBox(_T("<EFBFBD><EFBFBD><EFBFBD>ȴ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ļ<EFBFBD>"));
|
|||
|
|
|||
|
return false;
|
|||
|
}
|
|||
|
|
|||
|
std::vector<char>* v1 = ReadFile(to_byte_string(mLabel1->GetText()));
|
|||
|
std::vector<char>* v2 = ReadFile(to_byte_string(mLabel2->GetText()));
|
|||
|
|
|||
|
|
|||
|
//<2F><><EFBFBD><EFBFBD><EFBFBD>˳<EFBFBD>*.txt<78><74>*.dat<61><74><EFBFBD>ļ<EFBFBD>
|
|||
|
strFilter = "dat file (*.diff)|*.diff";
|
|||
|
CFileDialog TmpDlg(true, 0, 0, OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT, strFilter.GetBuffer(),
|
|||
|
CWnd::FromHandle(this->m_hWnd));
|
|||
|
|
|||
|
bsdiff_stream stream;
|
|||
|
stream.malloc = &malloc;
|
|||
|
stream.free = &free;
|
|||
|
stream.write = &res_write;
|
|||
|
stream.size = 0;
|
|||
|
stream.len = 0;
|
|||
|
|
|||
|
int ret = bsdiff((uint8_t*)v1->data(), v1->size(),
|
|||
|
(uint8_t*)v2->data(), v2->size(), &stream);
|
|||
|
|
|||
|
if (TmpDlg.DoModal() == IDOK)
|
|||
|
{
|
|||
|
//<2F><>ȡ<EFBFBD>ļ<EFBFBD>·<EFBFBD><C2B7>
|
|||
|
m_strTmpFile = TmpDlg.GetPathName();
|
|||
|
|
|||
|
std::ofstream file(m_strTmpFile, std::ios::out | std::ios::binary);
|
|||
|
file.write(reinterpret_cast<char*>(stream.result), stream.len);
|
|||
|
|
|||
|
file.flush();
|
|||
|
file.close();
|
|||
|
|
|||
|
bspatch_stream rec;
|
|||
|
rec.read = &bz2_read;
|
|||
|
rec.opaque = (uint8_t*)stream.result;
|
|||
|
rec.res_len = 0;
|
|||
|
char *data = new char[v2->size()];
|
|||
|
|
|||
|
// <20><><EFBFBD>ն<EFBFBD><D5B6><EFBFBD><EFBFBD>Ƹ<EFBFBD>ʽ<EFBFBD><CABD>ȡ<EFBFBD><C8A1><EFBFBD><EFBFBD>
|
|||
|
AfxMessageBox(_T("<EFBFBD><EFBFBD><EFBFBD>ɳɹ<EFBFBD>"));
|
|||
|
int err = bspatch((uint8_t*)v1->data(), v1->size(), (uint8_t*)data, v2->size(), &rec);
|
|||
|
if (err < 0) {
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
m_strTmpFile = "recover.hex";
|
|||
|
|
|||
|
std::ofstream file2(m_strTmpFile, std::ios::out | std::ios::binary);
|
|||
|
file2.write(data, v2->size());
|
|||
|
|
|||
|
file2.flush();
|
|||
|
file2.close();
|
|||
|
|
|||
|
|
|||
|
return true;
|
|||
|
}
|
|||
|
}
|
|||
|
);
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
LRESULT BasicForm::OnClose(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
|
|||
|
{
|
|||
|
PostQuitMessage(0L);
|
|||
|
return __super::OnClose(uMsg, wParam, lParam, bHandled);
|
|||
|
}
|