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)
|
||
{
|
||
// 按照二进制格式读取数据
|
||
file.seekg(0, std::ios::end);
|
||
long long fileSize = file.tellg();
|
||
printf("size of firm: %lld\n", fileSize);
|
||
|
||
// 将读写位置移动到文件开头,申请内存,将固件内容存入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;
|
||
|
||
//会过滤出*.txt和*.dat的文件
|
||
strFilter = "dat file (*.*)|*.*";
|
||
CFileDialog TmpDlg(true, 0, 0, OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT, strFilter.GetBuffer(),
|
||
CWnd::FromHandle(this->m_hWnd));
|
||
|
||
if (TmpDlg.DoModal() == IDOK)
|
||
{
|
||
//获取文件路径
|
||
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;
|
||
|
||
//会过滤出*.txt和*.dat的文件
|
||
strFilter = "dat file (*.*)|*.*";
|
||
CFileDialog TmpDlg(true, 0, 0, OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT, strFilter.GetBuffer(),
|
||
CWnd::FromHandle(this->m_hWnd));
|
||
|
||
if (TmpDlg.DoModal() == IDOK)
|
||
{
|
||
//获取文件路径
|
||
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("请先打开文件"));
|
||
|
||
return false;
|
||
}
|
||
|
||
|
||
if (mLabel2->GetText() == L"") {
|
||
AfxMessageBox(_T("请先打开文件"));
|
||
|
||
return false;
|
||
}
|
||
|
||
std::vector<char>* v1 = ReadFile(to_byte_string(mLabel1->GetText()));
|
||
std::vector<char>* v2 = ReadFile(to_byte_string(mLabel2->GetText()));
|
||
|
||
|
||
//会过滤出*.txt和*.dat的文件
|
||
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)
|
||
{
|
||
//获取文件路径
|
||
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()];
|
||
|
||
// 按照二进制格式读取数据
|
||
AfxMessageBox(_T("生成成功"));
|
||
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);
|
||
} |