diff --git a/bin/FixedVHDWriter.exe b/bin/FixedVHDWriter.exe
new file mode 100644
index 0000000..4b88a3e
Binary files /dev/null and b/bin/FixedVHDWriter.exe differ
diff --git a/bin/fvw.exe b/bin/fvw.exe
new file mode 100644
index 0000000..72180c7
Binary files /dev/null and b/bin/fvw.exe differ
diff --git a/win32/.vs/FixedVHDWriter/v16/.suo b/win32/.vs/FixedVHDWriter/v16/.suo
new file mode 100644
index 0000000..bc60696
Binary files /dev/null and b/win32/.vs/FixedVHDWriter/v16/.suo differ
diff --git a/win32/FixedVHDWriter.sln b/win32/FixedVHDWriter.sln
new file mode 100644
index 0000000..7b03d1e
--- /dev/null
+++ b/win32/FixedVHDWriter.sln
@@ -0,0 +1,31 @@
+
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio Version 16
+VisualStudioVersion = 16.0.31112.23
+MinimumVisualStudioVersion = 10.0.40219.1
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "FixedVHDWriter", "FixedVHDWriter\FixedVHDWriter.vcxproj", "{C57D90B7-440C-4F15-B41B-E8017B642BE8}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|x64 = Debug|x64
+ Debug|x86 = Debug|x86
+ Release|x64 = Release|x64
+ Release|x86 = Release|x86
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {C57D90B7-440C-4F15-B41B-E8017B642BE8}.Debug|x64.ActiveCfg = Debug|x64
+ {C57D90B7-440C-4F15-B41B-E8017B642BE8}.Debug|x64.Build.0 = Debug|x64
+ {C57D90B7-440C-4F15-B41B-E8017B642BE8}.Debug|x86.ActiveCfg = Debug|Win32
+ {C57D90B7-440C-4F15-B41B-E8017B642BE8}.Debug|x86.Build.0 = Debug|Win32
+ {C57D90B7-440C-4F15-B41B-E8017B642BE8}.Release|x64.ActiveCfg = Release|x64
+ {C57D90B7-440C-4F15-B41B-E8017B642BE8}.Release|x64.Build.0 = Release|x64
+ {C57D90B7-440C-4F15-B41B-E8017B642BE8}.Release|x86.ActiveCfg = Release|Win32
+ {C57D90B7-440C-4F15-B41B-E8017B642BE8}.Release|x86.Build.0 = Release|Win32
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+ GlobalSection(ExtensibilityGlobals) = postSolution
+ SolutionGuid = {D9CA1BA1-AFD3-470E-AECB-BA9FBA817CE0}
+ EndGlobalSection
+EndGlobal
diff --git a/win32/FixedVHDWriter/FixedVHDWriter.aps b/win32/FixedVHDWriter/FixedVHDWriter.aps
new file mode 100644
index 0000000..56427c6
Binary files /dev/null and b/win32/FixedVHDWriter/FixedVHDWriter.aps differ
diff --git a/win32/FixedVHDWriter/FixedVHDWriter.cpp b/win32/FixedVHDWriter/FixedVHDWriter.cpp
new file mode 100644
index 0000000..9427308
--- /dev/null
+++ b/win32/FixedVHDWriter/FixedVHDWriter.cpp
@@ -0,0 +1,105 @@
+// FixedVHDWriter.cpp: 定义应用程序的类行为。
+//
+
+#include "framework.h"
+#include "FixedVHDWriter.h"
+#include "FixedVHDWriterDlg.h"
+
+#ifdef _DEBUG
+#define new DEBUG_NEW
+#endif
+
+
+// CFixedVHDWriterApp
+
+BEGIN_MESSAGE_MAP(CFixedVHDWriterApp, CWinApp)
+ ON_COMMAND(ID_HELP, &CWinApp::OnHelp)
+END_MESSAGE_MAP()
+
+
+// CFixedVHDWriterApp 构造
+
+CFixedVHDWriterApp::CFixedVHDWriterApp()
+{
+ // 支持重新启动管理器
+ m_dwRestartManagerSupportFlags = AFX_RESTART_MANAGER_SUPPORT_RESTART;
+
+ // TODO: 在此处添加构造代码,
+ // 将所有重要的初始化放置在 InitInstance 中
+}
+
+
+// 唯一的 CFixedVHDWriterApp 对象
+
+CFixedVHDWriterApp theApp;
+
+
+// CFixedVHDWriterApp 初始化
+
+BOOL CFixedVHDWriterApp::InitInstance()
+{
+ // 如果一个运行在 Windows XP 上的应用程序清单指定要
+ // 使用 ComCtl32.dll 版本 6 或更高版本来启用可视化方式,
+ //则需要 InitCommonControlsEx()。 否则,将无法创建窗口。
+ INITCOMMONCONTROLSEX InitCtrls;
+ InitCtrls.dwSize = sizeof(InitCtrls);
+ // 将它设置为包括所有要在应用程序中使用的
+ // 公共控件类。
+ InitCtrls.dwICC = ICC_WIN95_CLASSES;
+ InitCommonControlsEx(&InitCtrls);
+
+ CWinApp::InitInstance();
+
+
+ AfxEnableControlContainer();
+
+ // 创建 shell 管理器,以防对话框包含
+ // 任何 shell 树视图控件或 shell 列表视图控件。
+ CShellManager *pShellManager = new CShellManager;
+
+ // 激活“Windows Native”视觉管理器,以便在 MFC 控件中启用主题
+ CMFCVisualManager::SetDefaultManager(RUNTIME_CLASS(CMFCVisualManagerWindows));
+
+ // 标准初始化
+ // 如果未使用这些功能并希望减小
+ // 最终可执行文件的大小,则应移除下列
+ // 不需要的特定初始化例程
+ // 更改用于存储设置的注册表项
+ // TODO: 应适当修改该字符串,
+ // 例如修改为公司或组织名
+ SetRegistryKey(_T("应用程序向导生成的本地应用程序"));
+
+ CFixedVHDWriterDlg dlg;
+ m_pMainWnd = &dlg;
+ INT_PTR nResponse = dlg.DoModal();
+ if (nResponse == IDOK)
+ {
+ // TODO: 在此放置处理何时用
+ // “确定”来关闭对话框的代码
+ }
+ else if (nResponse == IDCANCEL)
+ {
+ // TODO: 在此放置处理何时用
+ // “取消”来关闭对话框的代码
+ }
+ else if (nResponse == -1)
+ {
+ TRACE(traceAppMsg, 0, "警告: 对话框创建失败,应用程序将意外终止。\n");
+ TRACE(traceAppMsg, 0, "警告: 如果您在对话框上使用 MFC 控件,则无法 #define _AFX_NO_MFC_CONTROLS_IN_DIALOGS。\n");
+ }
+
+ // 删除上面创建的 shell 管理器。
+ if (pShellManager != nullptr)
+ {
+ delete pShellManager;
+ }
+
+#if !defined(_AFXDLL) && !defined(_AFX_NO_MFC_CONTROLS_IN_DIALOGS)
+ ControlBarCleanUp();
+#endif
+
+ // 由于对话框已关闭,所以将返回 FALSE 以便退出应用程序,
+ // 而不是启动应用程序的消息泵。
+ return FALSE;
+}
+
diff --git a/win32/FixedVHDWriter/FixedVHDWriter.h b/win32/FixedVHDWriter/FixedVHDWriter.h
new file mode 100644
index 0000000..1b2a268
--- /dev/null
+++ b/win32/FixedVHDWriter/FixedVHDWriter.h
@@ -0,0 +1,30 @@
+// FixedVHDWriter.h: PROJECT_NAME 应用程序的主头文件
+//
+
+#pragma once
+
+#ifndef __AFXWIN_H__
+ #error "在包含此文件之前包含 'pch.h' 以生成 PCH"
+#endif
+
+#include "resource.h" // 主符号
+
+// CFixedVHDWriterApp:
+// 有关此类的实现,请参阅 FixedVHDWriter.cpp
+//
+
+class CFixedVHDWriterApp : public CWinApp
+{
+public:
+ CFixedVHDWriterApp();
+
+// 重写
+public:
+ virtual BOOL InitInstance();
+
+// 实现
+
+ DECLARE_MESSAGE_MAP()
+};
+
+extern CFixedVHDWriterApp theApp;
diff --git a/win32/FixedVHDWriter/FixedVHDWriter.rc b/win32/FixedVHDWriter/FixedVHDWriter.rc
new file mode 100644
index 0000000..ef980e3
Binary files /dev/null and b/win32/FixedVHDWriter/FixedVHDWriter.rc differ
diff --git a/win32/FixedVHDWriter/FixedVHDWriter.vcxproj b/win32/FixedVHDWriter/FixedVHDWriter.vcxproj
new file mode 100644
index 0000000..7da966a
--- /dev/null
+++ b/win32/FixedVHDWriter/FixedVHDWriter.vcxproj
@@ -0,0 +1,214 @@
+
+
+
+
+ Debug
+ Win32
+
+
+ Release
+ Win32
+
+
+ Debug
+ x64
+
+
+ Release
+ x64
+
+
+
+ 16.0
+ {C57D90B7-440C-4F15-B41B-E8017B642BE8}
+ MFCProj
+ FixedVHDWriter
+ 7.0
+
+
+
+ Application
+ true
+ v141_xp
+ Unicode
+ Static
+
+
+ Application
+ false
+ v141_xp
+ true
+ MultiByte
+ Static
+
+
+ Application
+ true
+ v142
+ MultiByte
+ Static
+
+
+ Application
+ false
+ v142
+ true
+ Unicode
+ Static
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ true
+
+
+ true
+
+
+ false
+
+
+ false
+
+
+
+ Use
+ Level3
+ true
+ WIN32;_WINDOWS;_DEBUG;%(PreprocessorDefinitions)
+ pch.h
+
+
+ Windows
+
+
+ false
+ true
+ _DEBUG;%(PreprocessorDefinitions)
+
+
+ 0x0804
+ _DEBUG;%(PreprocessorDefinitions)
+ $(IntDir);%(AdditionalIncludeDirectories)
+
+
+
+
+ NotUsing
+ Level3
+ true
+ _WINDOWS;_DEBUG;%(PreprocessorDefinitions)
+
+
+
+
+ Windows
+ Enabled
+
+
+ false
+ true
+ _DEBUG;%(PreprocessorDefinitions)
+
+
+ 0x0804
+ _DEBUG;%(PreprocessorDefinitions)
+ $(IntDir);%(AdditionalIncludeDirectories)
+
+
+
+
+ NotUsing
+ Level3
+ true
+ true
+ true
+ WIN32;_WINDOWS;NDEBUG;%(PreprocessorDefinitions)
+
+
+
+
+ Windows
+ true
+ true
+ MultiplyDefinedSymbolOnly
+
+
+ false
+ true
+ NDEBUG;%(PreprocessorDefinitions)
+
+
+ 0x0804
+ NDEBUG;%(PreprocessorDefinitions)
+ $(IntDir);%(AdditionalIncludeDirectories)
+
+
+
+
+ Use
+ Level3
+ true
+ true
+ true
+ _WINDOWS;NDEBUG;%(PreprocessorDefinitions)
+ pch.h
+
+
+ Windows
+ true
+ true
+
+
+ false
+ true
+ NDEBUG;%(PreprocessorDefinitions)
+
+
+ 0x0804
+ NDEBUG;%(PreprocessorDefinitions)
+ $(IntDir);%(AdditionalIncludeDirectories)
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/win32/FixedVHDWriter/FixedVHDWriter.vcxproj.filters b/win32/FixedVHDWriter/FixedVHDWriter.vcxproj.filters
new file mode 100644
index 0000000..2288f6e
--- /dev/null
+++ b/win32/FixedVHDWriter/FixedVHDWriter.vcxproj.filters
@@ -0,0 +1,63 @@
+
+
+
+
+ {4FC737F1-C7A5-4376-A066-2A32D752A2FF}
+ cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx
+
+
+ {93995380-89BD-4b04-88EB-625FBE52EBFB}
+ h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd
+
+
+ {67DA6AB6-F800-4c08-8B7A-83BB121AAD01}
+ rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms
+
+
+
+
+ 头文件
+
+
+ 头文件
+
+
+ 头文件
+
+
+ 头文件
+
+
+ 头文件
+
+
+ 头文件
+
+
+
+
+ 源文件
+
+
+ 源文件
+
+
+ 源文件
+
+
+
+
+ 资源文件
+
+
+
+
+ 资源文件
+
+
+
+
+ 资源文件
+
+
+
\ No newline at end of file
diff --git a/win32/FixedVHDWriter/FixedVHDWriter.vcxproj.user b/win32/FixedVHDWriter/FixedVHDWriter.vcxproj.user
new file mode 100644
index 0000000..3078416
--- /dev/null
+++ b/win32/FixedVHDWriter/FixedVHDWriter.vcxproj.user
@@ -0,0 +1,6 @@
+
+
+
+ FixedVHDWriter.rc
+
+
\ No newline at end of file
diff --git a/win32/FixedVHDWriter/FixedVHDWriterDlg.cpp b/win32/FixedVHDWriter/FixedVHDWriterDlg.cpp
new file mode 100644
index 0000000..3cb83e3
--- /dev/null
+++ b/win32/FixedVHDWriter/FixedVHDWriterDlg.cpp
@@ -0,0 +1,187 @@
+
+// FixedVHDWriterDlg.cpp: 实现文件
+//
+
+#include "framework.h"
+#include "FixedVHDWriter.h"
+#include "FixedVHDWriterDlg.h"
+#include "afxdialogex.h"
+
+#include "..\..\writer.h"
+
+#ifdef _DEBUG
+#define new DEBUG_NEW
+#endif
+
+
+// CFixedVHDWriterDlg 对话框
+
+
+
+CFixedVHDWriterDlg::CFixedVHDWriterDlg(CWnd* pParent /*=nullptr*/)
+ : CDialogEx(IDD_FIXEDVHDWRITER_DIALOG, pParent)
+{
+ m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
+}
+
+void CFixedVHDWriterDlg::DoDataExchange(CDataExchange* pDX)
+{
+ CDialogEx::DoDataExchange(pDX);
+}
+
+BEGIN_MESSAGE_MAP(CFixedVHDWriterDlg, CDialogEx)
+ ON_WM_PAINT()
+ ON_WM_QUERYDRAGICON()
+ ON_BN_CLICKED(IDC_BUTTON_OPENSRC, &CFixedVHDWriterDlg::OnBnClickedButtonOpensrc)
+ ON_BN_CLICKED(IDC_BUTTON_OPENDST, &CFixedVHDWriterDlg::OnBnClickedButtonOpendst)
+ ON_BN_CLICKED(IDC_BUTTON_WRITE, &CFixedVHDWriterDlg::OnBnClickedButtonWrite)
+END_MESSAGE_MAP()
+
+
+// CFixedVHDWriterDlg 消息处理程序
+
+BOOL CFixedVHDWriterDlg::OnInitDialog()
+{
+ CDialogEx::OnInitDialog();
+
+ // 设置此对话框的图标。 当应用程序主窗口不是对话框时,框架将自动
+ // 执行此操作
+ SetIcon(m_hIcon, TRUE); // 设置大图标
+ SetIcon(m_hIcon, FALSE); // 设置小图标
+
+ ShowWindow(SW_SHOW);
+
+ // TODO: 在此添加额外的初始化代码
+ SetDlgItemText(IDC_EDIT_BEGSEC, TEXT("0"));
+
+ return TRUE; // 除非将焦点设置到控件,否则返回 TRUE
+}
+
+// 如果向对话框添加最小化按钮,则需要下面的代码
+// 来绘制该图标。 对于使用文档/视图模型的 MFC 应用程序,
+// 这将由框架自动完成。
+
+void CFixedVHDWriterDlg::OnPaint()
+{
+ if (IsIconic())
+ {
+ CPaintDC dc(this); // 用于绘制的设备上下文
+
+ SendMessage(WM_ICONERASEBKGND, reinterpret_cast(dc.GetSafeHdc()), 0);
+
+ // 使图标在工作区矩形中居中
+ int cxIcon = GetSystemMetrics(SM_CXICON);
+ int cyIcon = GetSystemMetrics(SM_CYICON);
+ CRect rect;
+ GetClientRect(&rect);
+ int x = (rect.Width() - cxIcon + 1) / 2;
+ int y = (rect.Height() - cyIcon + 1) / 2;
+
+ // 绘制图标
+ dc.DrawIcon(x, y, m_hIcon);
+ }
+ else
+ {
+ CDialogEx::OnPaint();
+ }
+}
+
+//当用户拖动最小化窗口时系统调用此函数取得光标
+//显示。
+HCURSOR CFixedVHDWriterDlg::OnQueryDragIcon()
+{
+ return static_cast(m_hIcon);
+}
+
+
+
+void CFixedVHDWriterDlg::OnBnClickedButtonOpensrc() {
+ CFileDialog cfd(
+ true, nullptr, nullptr, OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT,
+ "All Files (*.*)|*.*||");
+
+ if (cfd.DoModal() == IDOK) {
+ SetDlgItemText(IDC_EDIT_FILESRC, cfd.GetPathName());
+ }
+}
+
+
+void CFixedVHDWriterDlg::OnBnClickedButtonOpendst() {
+ CFileDialog cfd(
+ true, nullptr, nullptr, OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT,
+ "Fixed VHD File (*.vhd)|*.vhd|All Files (*.*)|*.*||");
+
+ if (cfd.DoModal() == IDOK) {
+ SetDlgItemText(IDC_EDIT_FILEDST, cfd.GetPathName());
+ }
+}
+
+void CFixedVHDWriterDlg::OnBnClickedButtonWrite() {
+ // TODO: 在此添加控件通知处理程序代码
+ CString csSrcPath, csDstPath, csBeginSector;
+ int nBeginSector;
+ int result = MessageBox("您确认要执行写入吗?", "写入文件", MB_OKCANCEL | MB_ICONQUESTION);
+ if (result == IDOK) {
+
+ GetDlgItemText(IDC_EDIT_FILESRC, csSrcPath);
+ GetDlgItemText(IDC_EDIT_FILEDST, csDstPath);
+ GetDlgItemText(IDC_EDIT_BEGSEC, csBeginSector);
+ long nBeginSector = _tcstol(csBeginSector.GetString(), nullptr, 10);
+
+ struct writer_object wo;
+ int64_t data_file_size;
+
+ init_writer_object(&wo, csDstPath.GetString());
+ if (get_last_error(&wo) == OPEN_FILE_ERROR) {
+ MessageBox("Open VHD image file error", nullptr, MB_ICONERROR);
+ return;
+ }
+
+ if (!vaild_vhd(&wo)) {
+ MessageBox("Invaild or broken VHD image file", nullptr, MB_ICONERROR);
+ release_writer_object(&wo);
+ return;
+ }
+
+ if (!fixed_vhd(&wo)) {
+ MessageBox("The VHD image is not fixed which is still not support", nullptr, MB_ICONERROR);
+ release_writer_object(&wo);
+ return;
+ }
+
+ size_vhd(&wo);
+
+ /* read data from the data file, then write it to VHD image file */
+ data_file_size = get_file_size_by_name(csSrcPath.GetString());
+ if (data_file_size == 0) {
+ MessageBox("Data file is invaild", nullptr, MB_ICONERROR);
+ release_writer_object(&wo);
+ return;
+ }
+
+ int64_t total_written_bytes = write_hvd_sector_from_data_file(&wo, nBeginSector, csSrcPath.GetString());
+ enum writer_error err = get_last_error(&wo);
+ if (err == LBA_OUT_OF_RANGE) {
+ CString s; s.Format("LBA is out of range (0 - %l)", wo.size / 512 - 1);
+ MessageBox(s.GetString(), nullptr, MB_ICONERROR);
+ release_writer_object(&wo);
+ return;
+ } else if (err == OPEN_FILE_ERROR) {
+ MessageBox("Open data file error", nullptr, MB_ICONERROR);
+ release_writer_object(&wo);
+ return;
+ }
+
+ CString s;
+ s.Format("Data: %s\nVHD: %s (offset LBA: %l)\nTotal bytes to write: %lld\nTotal sectors to write: %lld\nTotal bytes written: %lld\nTotal sectors written: %lld\n",
+ csSrcPath.GetString(), csDstPath.GetString(), nBeginSector,
+ data_file_size, data_file_size / 512 + (data_file_size % 512 != 0), total_written_bytes, total_written_bytes / 512 + (total_written_bytes % 512 != 0));
+ MessageBox(s.GetString(), "Info", MB_ICONINFORMATION);
+
+ if (total_written_bytes < data_file_size) {
+ MessageBox("\n!!! Detected the tail of VHD image file, the writing data has been truncated!\n", "Info", MB_ICONINFORMATION);
+ }
+
+ release_writer_object(&wo);
+ }
+}
diff --git a/win32/FixedVHDWriter/FixedVHDWriterDlg.h b/win32/FixedVHDWriter/FixedVHDWriterDlg.h
new file mode 100644
index 0000000..61b1f81
--- /dev/null
+++ b/win32/FixedVHDWriter/FixedVHDWriterDlg.h
@@ -0,0 +1,38 @@
+
+// FixedVHDWriterDlg.h: 头文件
+//
+
+#pragma once
+
+extern int main(int argc, char ** argv);
+
+// CFixedVHDWriterDlg 对话框
+class CFixedVHDWriterDlg : public CDialogEx
+{
+// 构造
+public:
+ CFixedVHDWriterDlg(CWnd* pParent = nullptr); // 标准构造函数
+
+// 对话框数据
+#ifdef AFX_DESIGN_TIME
+ enum { IDD = IDD_FIXEDVHDWRITER_DIALOG };
+#endif
+
+ protected:
+ virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV 支持
+
+
+// 实现
+protected:
+ HICON m_hIcon;
+
+ // 生成的消息映射函数
+ virtual BOOL OnInitDialog();
+ afx_msg void OnPaint();
+ afx_msg HCURSOR OnQueryDragIcon();
+ DECLARE_MESSAGE_MAP()
+public:
+ afx_msg void OnBnClickedButtonOpensrc();
+ afx_msg void OnBnClickedButtonOpendst();
+ afx_msg void OnBnClickedButtonWrite();
+};
diff --git a/win32/FixedVHDWriter/framework.h b/win32/FixedVHDWriter/framework.h
new file mode 100644
index 0000000..5672fb5
--- /dev/null
+++ b/win32/FixedVHDWriter/framework.h
@@ -0,0 +1,49 @@
+#pragma once
+
+#ifndef VC_EXTRALEAN
+#define VC_EXTRALEAN // 从 Windows 头中排除极少使用的资料
+#endif
+
+#include "targetver.h"
+
+#define _ATL_CSTRING_EXPLICIT_CONSTRUCTORS // 某些 CString 构造函数将是显式的
+
+// 关闭 MFC 的一些常见且经常可放心忽略的隐藏警告消息
+#define _AFX_ALL_WARNINGS
+
+#include // MFC 核心组件和标准组件
+#include // MFC 扩展
+
+
+#include // MFC 自动化类
+
+
+
+#ifndef _AFX_NO_OLE_SUPPORT
+#include // MFC 对 Internet Explorer 4 公共控件的支持
+#endif
+#ifndef _AFX_NO_AFXCMN_SUPPORT
+#include // MFC 对 Windows 公共控件的支持
+#endif // _AFX_NO_AFXCMN_SUPPORT
+
+#include // MFC 支持功能区和控制条
+
+
+
+
+
+
+
+
+
+#ifdef _UNICODE
+#if defined _M_IX86
+#pragma comment(linker,"/manifestdependency:\"type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='x86' publicKeyToken='6595b64144ccf1df' language='*'\"")
+#elif defined _M_X64
+#pragma comment(linker,"/manifestdependency:\"type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='amd64' publicKeyToken='6595b64144ccf1df' language='*'\"")
+#else
+#pragma comment(linker,"/manifestdependency:\"type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='*' publicKeyToken='6595b64144ccf1df' language='*'\"")
+#endif
+#endif
+
+
diff --git a/win32/FixedVHDWriter/res/FixedVHDWriter.ico b/win32/FixedVHDWriter/res/FixedVHDWriter.ico
new file mode 100644
index 0000000..d56fbcd
Binary files /dev/null and b/win32/FixedVHDWriter/res/FixedVHDWriter.ico differ
diff --git a/win32/FixedVHDWriter/res/FixedVHDWriter.rc2 b/win32/FixedVHDWriter/res/FixedVHDWriter.rc2
new file mode 100644
index 0000000..1bb585c
Binary files /dev/null and b/win32/FixedVHDWriter/res/FixedVHDWriter.rc2 differ
diff --git a/win32/FixedVHDWriter/resource.h b/win32/FixedVHDWriter/resource.h
new file mode 100644
index 0000000..4364d11
--- /dev/null
+++ b/win32/FixedVHDWriter/resource.h
@@ -0,0 +1,23 @@
+//{{NO_DEPENDENCIES}}
+// Microsoft Visual C++ 生成的包含文件。
+// 供 FixedVHDWriter.rc 使用
+//
+#define IDD_FIXEDVHDWRITER_DIALOG 102
+#define IDR_MAINFRAME 128
+#define IDC_EDIT_FILESRC 1000
+#define IDC_BUTTON_OPENSRC 1001
+#define IDC_EDIT_FILEDST 1002
+#define IDC_BUTTON_OPENDST 1003
+#define IDC_EDIT_BEGSEC 1004
+#define IDC_BUTTON_WRITE 1005
+
+// Next default values for new objects
+//
+#ifdef APSTUDIO_INVOKED
+#ifndef APSTUDIO_READONLY_SYMBOLS
+#define _APS_NEXT_RESOURCE_VALUE 130
+#define _APS_NEXT_COMMAND_VALUE 32771
+#define _APS_NEXT_CONTROL_VALUE 1008
+#define _APS_NEXT_SYMED_VALUE 101
+#endif
+#endif
diff --git a/win32/FixedVHDWriter/targetver.h b/win32/FixedVHDWriter/targetver.h
new file mode 100644
index 0000000..91042b9
--- /dev/null
+++ b/win32/FixedVHDWriter/targetver.h
@@ -0,0 +1,8 @@
+#pragma once
+
+// 包括 SDKDDKVer.h 将定义可用的最高版本的 Windows 平台。
+
+// 如果要为以前的 Windows 平台生成应用程序,请包括 WinSDKVer.h,并将
+// 将 _WIN32_WINNT 宏设置为要支持的平台,然后再包括 SDKDDKVer.h。
+
+#include
diff --git a/writer.c b/writer.c
index f457775..a9d835c 100644
--- a/writer.c
+++ b/writer.c
@@ -4,11 +4,7 @@
#include "stdarg.h"
#include "writer.h"
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-int init_writer_object(writer_object * const wo_p, const char * const name) {
+int init_writer_object(struct writer_object * wo_p, const char * name) {
FILE *fp = fopen(name, "rb+");
if (fp == NULL) {
set_last_error(wo_p, OPEN_FILE_ERROR);
@@ -18,15 +14,15 @@ int init_writer_object(writer_object * const wo_p, const char * const name) {
wo_p->fixed = 0;
wo_p->vaild = 0;
wo_p->size = 0;
- wo_p->last_error = NO_ERROR;
+ wo_p->last_error = NOERR;
return 1;
}
-void release_writer_object(writer_object * const wo_p) {
+void release_writer_object(struct writer_object * wo_p) {
fclose(wo_p->vhd_fp);
}
-int vaild_vhd(writer_object * const wo_p) {
+int vaild_vhd(struct writer_object * wo_p) {
char vhd_cookie[9] = { 0 };
/* the beginning of last sector means VHD cookie */
fseek(wo_p->vhd_fp, -512, SEEK_END);
@@ -34,7 +30,7 @@ int vaild_vhd(writer_object * const wo_p) {
return strcmp(vhd_cookie, VHD_COOKIE_STRING) == 0 && (wo_p->vaild = 1);
}
-int fixed_vhd(writer_object * const wo_p) {
+int fixed_vhd(struct writer_object * wo_p) {
int vhd_type;
/* the last sector with offset 0x3C means VHD type */
fseek(wo_p->vhd_fp, -512 + 0x3C, SEEK_END);
@@ -42,7 +38,7 @@ int fixed_vhd(writer_object * const wo_p) {
return vhd_type == 0x02000000 && (wo_p->fixed = 1);
}
-int64_t size_vhd(writer_object * const wo_p) {
+int64_t size_vhd(struct writer_object * wo_p) {
int64_t size;
/* the last sector with offset 0x28 means original size */
fseek(wo_p->vhd_fp, -512 + 0x28, SEEK_END);
@@ -58,12 +54,12 @@ int64_t size_vhd(writer_object * const wo_p) {
return wo_p->size = size;
}
-int write_a_vhd_sector(writer_object * const wo_p, const int64_t lba, const vhd_sector * const sector_p) {
+int write_a_vhd_sector(struct writer_object * wo_p, const int64_t lba, const struct vhd_sector * sector_p) {
fseek(wo_p->vhd_fp, lba * 512, SEEK_SET);
return fwrite(sector_p->raw, 1, sector_p->vaild_bytes, wo_p->vhd_fp);
}
-int64_t write_hvd_sector_from_data_file(writer_object * const wo_p, const int64_t lba, const char * const name) {
+int64_t write_hvd_sector_from_data_file(struct writer_object * wo_p, int64_t lba, const char * name) {
int vaild_bytes, written_bytes;
int64_t total_written_bytes = 0, lba_index = lba, lba_max = wo_p->size / 512;
if (lba_index < 0 || lba_index >= lba_max) {
@@ -72,7 +68,7 @@ int64_t write_hvd_sector_from_data_file(writer_object * const wo_p, const int64_
}
FILE *fp = fopen(name, "rb");
- vhd_sector sector;
+ struct vhd_sector sector;
if (fp == NULL) {
set_last_error(wo_p, OPEN_FILE_ERROR);
@@ -90,16 +86,16 @@ int64_t write_hvd_sector_from_data_file(writer_object * const wo_p, const int64_
return total_written_bytes;
}
-writer_error get_last_error(const writer_object * const wo_p) {
+enum writer_error get_last_error(const struct writer_object * wo_p) {
return wo_p->last_error;
}
-void set_last_error(writer_object * const wo_p, const writer_error last_error) {
+void set_last_error(struct writer_object * wo_p, enum writer_error last_error) {
wo_p->last_error = last_error;
}
-void _err_msg(const char * const fmt, ...) {
+void _err_msg(const char * fmt, ...) {
va_list vl;
va_start(vl, fmt);
vfprintf(stderr, fmt, vl);
@@ -107,7 +103,7 @@ void _err_msg(const char * const fmt, ...) {
va_end(vl);
}
-int64_t get_file_size_by_name(const char * const name) {
+int64_t get_file_size_by_name(const char * name) {
fpos_t fpos_begin, fpos_end;
int res = 0;
FILE *fp = fopen(name, "rb");
@@ -122,13 +118,13 @@ int64_t get_file_size_by_name(const char * const name) {
int main(int argc, char **argv) {
#define __err(s, ...) _err_msg(s, ##__VA_ARGS__);
- writer_object wo;
+ struct writer_object wo;
int i, j, states = 0;
char cc, nc;
char *vhd_file_name = NULL, *data_file_name = NULL;
int64_t lba;
- option_flag last_option_flag = 0; /* 3 options must be set up */
+ enum option_flag last_option_flag = 0; /* 3 options must be set up */
if (argc <= 1) {
__err("Fixed VHD Writer\n[-h] usage help\n[-r] specify data file name (read)\n[-w] specify VHD file name (write)\n[-a] specify LBA to writing data\n");
@@ -222,7 +218,7 @@ int main(int argc, char **argv) {
}
int64_t total_written_bytes = write_hvd_sector_from_data_file(&wo, lba, data_file_name);
- writer_error err = get_last_error(&wo);
+ enum writer_error err = get_last_error(&wo);
if (err == LBA_OUT_OF_RANGE) {
__err("LBA is out of range (0 - %d)", wo.size / 512 - 1);
release_writer_object(&wo);
@@ -244,7 +240,3 @@ int main(int argc, char **argv) {
release_writer_object(&wo);
return 0;
}
-
-#ifdef __cplusplus
-}
-#endif
diff --git a/writer.h b/writer.h
index 4e6649b..18569a9 100644
--- a/writer.h
+++ b/writer.h
@@ -6,46 +6,74 @@
#define VHD_COOKIE_STRING "conectix"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
typedef int BOOL;
-typedef struct _vhd_sector {
+#ifdef __cplusplus
+struct vhd_sector {
int vaild_bytes; /* 0 ~ 512 */
uint8_t raw[512];
-}vhd_sector;
+};
-typedef enum _writer_error {
- NO_ERROR,
+enum writer_error {
+ NOERR,
LBA_OUT_OF_RANGE,
OPEN_FILE_ERROR
-}writer_error;
+};
-typedef struct _writer_object {
+struct writer_object {
FILE *vhd_fp; /* file pointer */
BOOL vaild;
BOOL fixed; /* fixed VHD flag */
int64_t size;
- writer_error last_error;
-}writer_object;
+ enum writer_error last_error;
+};
+
+enum option_flag {
+ FLAG_SET_VHD = 1,
+ FLAG_SET_DATA_FILE = 2,
+ FLAG_SET_LBA = 4
+};
+#else
+struct vhd_sector {
+ int vaild_bytes; /* 0 ~ 512 */
+ uint8_t raw[512];
+};
+
+enum writer_error {
+ NOERR,
+ LBA_OUT_OF_RANGE,
+ OPEN_FILE_ERROR
+};
+
+struct writer_object {
+ FILE * vhd_fp; /* file pointer */
+ BOOL vaild;
+ BOOL fixed; /* fixed VHD flag */
+ int64_t size;
+ enum writer_error last_error;
+};
-typedef enum _option_flag {
+enum option_flag {
FLAG_SET_VHD = 1,
FLAG_SET_DATA_FILE = 2,
FLAG_SET_LBA = 4
-}option_flag;
-
-int init_writer_object(writer_object * const wo_p, const char * const name);
-void release_writer_object(writer_object * const wo_p);
-int vaild_vhd(writer_object * const wo_p);
-int fixed_vhd(writer_object * const wo_p);
-int write_a_vhd_sector(writer_object * const wo_p, const int64_t lba, const vhd_sector * const sector_p);
-int64_t write_hvd_sector_from_data_file(writer_object * const wo_p, const int64_t lba, const char * const name);
-writer_error get_last_error(const writer_object * const wo_p);
-void set_last_error(writer_object * const wo_p, const writer_error last_error);
+};
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+ int init_writer_object(struct writer_object * wo_p, const char * name);
+ void release_writer_object(struct writer_object * wo_p);
+ int vaild_vhd(struct writer_object * wo_p);
+ int fixed_vhd(struct writer_object * wo_p);
+ int64_t size_vhd(struct writer_object * wo_p);
+ int write_a_vhd_sector(struct writer_object * wo_p, int64_t lba, const struct vhd_sector * sector_p);
+ int64_t write_hvd_sector_from_data_file(struct writer_object * wo_p, const int64_t lba, const char * name);
+ enum writer_error get_last_error(const struct writer_object * wo_p);
+ void set_last_error(struct writer_object * wo_p, enum writer_error last_error);
+ int64_t get_file_size_by_name(const char * const name);
#ifdef __cplusplus
}