#include "stdafx.h" #include "basic_form.h" #include #include #include #include #include #include #include #include #include #include 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> 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* ReadFile(std::string path) { std::vector* 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(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(FindControl(L"btn_do_open1")); ui::Button* btn_open2 = dynamic_cast(FindControl(L"btn_do_open2")); ui::Button* btn_open3 = dynamic_cast(FindControl(L"btn_do_generate")); mLabel1 = dynamic_cast(FindControl(L"file1_dir")); mLabel2 = dynamic_cast(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* v1 = ReadFile(to_byte_string(mLabel1->GetText())); std::vector* 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(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); }