vhd 转换为img源码,由VS 2010 C++编译

本工程主要由vhd2img.cpp layout.h组成,C代码实现。

vhd2img.cpp:

// vhd2img.cpp : 定义控制台应用程序的入口点。
//by www.frombyte.cn zhangyu
//北亚数据恢复中心(www.sjhf.net)张宇 2012/1/6 发表于51cto   

#include "stdafx.h"
#include <windows.h>
#include "layout.h"
#define VHD_OPENED 1
#define VHD_UNOPEN 0
#define BIT_MASK 0x80
static inline int test_bit (byte *addr, u32 nr)
{
    return ((addr[nr >> 3] << (nr & 7)) & BIT_MASK) != 0;
};
static inline void set_bit (byte *addr, u32 nr)
{
    addr[nr >> 3] |= (BIT_MASK >> (nr & 7));
}    

HANDLE hIn,hOut;    

struct vhd_info
{
    u64 uSize;
    u32 *bat;
    byte *batmap;
    u64 uBlkSize;
    u64 uBatNum;
    u32 spb; //secters per block
    u32 log2spb;
    u32 vhd_status;
    bool is_have_batmap;
};    

int open_vhd(TCHAR *name,vhd_info &vhd)
{
    hd_ftr vhd_head;
    hIn = CreateFile(name,GENERIC_READ,FILE_SHARE_READ,NULL,OPEN_EXISTING,0,NULL);
    if(hIn == INVALID_HANDLE_VALUE)
    {
        _tprintf(_T("ERROR%d:source VHD file open error!\n"),GetLastError());
        return -1;
    }
    DWORD bRead;
    ReadFile(hIn,(char*)&vhd_head,sizeof(hd_ftr),&bRead,NULL);
    if(bRead != sizeof(hd_ftr))
        return -2;
    if(strncmp(vhd_head.cookie,HD_COOKIE,8) != 0)
    {
        _tprintf(_T("the source file is not a valid VHD format!\n"));
        return -3;
    }
    if( (LE32(vhd_head.type) != HD_TYPE_DYNAMIC) && (LE32(vhd_head.type) != HD_TYPE_DIFF) )
        return -4;    

    dd_hdr vhd_sparce;
    ReadFile(hIn,(char*)&vhd_sparce,sizeof(dd_hdr),&bRead,NULL);
    if(bRead != sizeof(dd_hdr))
        return -5;
    if(strncmp(vhd_sparce.cookie,DD_COOKIE,8) != 0)
        return -6;
    vhd.uBlkSize = LE32(vhd_sparce.block_size);
    vhd.uBatNum = LE32(vhd_sparce.max_bat_size);
    vhd.bat = new u32 [vhd.uBatNum];
    LARGE_INTEGER liPoi,liNew;
    liPoi.QuadPart = LE64(vhd_sparce.table_offset);
    SetFilePointerEx(hIn,liPoi,&liNew,FILE_BEGIN);
    ReadFile(hIn,vhd.bat,vhd.uBatNum * sizeof(u32),&bRead,NULL);
    if(bRead != vhd.uBatNum * sizeof(u32))
        return -7;    

    dd_batmap_hdr batmap_head;
    ReadFile(hIn,(char*)&batmap_head,sizeof(dd_batmap_hdr),&bRead,NULL);
    if(bRead != sizeof(dd_batmap_hdr))
        return -8;
    if(strncmp(batmap_head.cookie,VHD_BATMAP_COOKIE,8) != 0)
        vhd.is_have_batmap = FALSE;
    else
        vhd.is_have_batmap = TRUE;    

    vhd.spb = vhd.uBlkSize >> VHD_SECTOR_SHIFT;
    vhd.vhd_status = VHD_OPENED;
    return 1;
}
int read_vhd(vhd_info &vhd,byte* buf,u32 blkno)
{
    byte spb_bitmap[VHD_SECTOR_SIZE];
    DWORD bRead;
    if(vhd.bat[blkno] == 0xFFFFFFFF)
        return 2;
    byte *tbuf = new byte [vhd.uBlkSize];
    LARGE_INTEGER liPoi,liNew;
    liPoi.QuadPart = (u64)(LE32(vhd.bat[blkno])) << VHD_SECTOR_SHIFT;
    SetFilePointerEx(hIn,liPoi,&liNew,FILE_BEGIN);
    ReadFile(hIn,spb_bitmap,VHD_SECTOR_SIZE,&bRead,NULL);
    if(bRead != VHD_SECTOR_SIZE)
    {
        delete [] tbuf;
        return -2;
    }
    ReadFile(hIn,tbuf,vhd.uBlkSize,&bRead,NULL);
    if(bRead != vhd.uBlkSize)
    {
        delete [] tbuf;
        return -3;
    }
    for(u32 i=0;i<vhd.spb;i++)
    {
        if(test_bit(spb_bitmap,i)) //位为1,表示磁盘上有数据,需要拷贝
        {
            memcpy(buf + i * VHD_SECTOR_SIZE,tbuf + i*VHD_SECTOR_SIZE,VHD_SECTOR_SIZE);
        }
    }
    delete [] tbuf;
    return 1;
}    

int _tmain(int argc, _TCHAR* argv[])
{
    if(argc != 3)
    {
        _tprintf(_T("vhd2img.exe <input vhd name> <output file/disk name>\n"));
        _tprintf(_T("eg. vhd2img.exe my.vhd d:\\my.img \n"));
        _tprintf(_T("    vhd2img.exe my.vhd \"\\\\.\\physicaldrive1\" (write to hardisk 1)\n"));
        return 0;
    }    

    vhd_info vhd;    

    //打开输入vhd
    if(open_vhd(argv[1],vhd) != 1)
        return -1;    

    //生成目标文件
    HANDLE hOut = CreateFile(argv[2],GENERIC_READ|GENERIC_WRITE,FILE_SHARE_READ|FILE_SHARE_WRITE,NULL,OPEN_EXISTING,0,NULL);
    if(hOut == INVALID_HANDLE_VALUE)
    {
        hOut = CreateFile(argv[2],GENERIC_READ|GENERIC_WRITE,FILE_SHARE_READ|FILE_SHARE_WRITE,NULL,OPEN_ALWAYS,0,NULL);
        if(hOut == INVALID_HANDLE_VALUE)
        {
            _tprintf(_T("ERROR%d:the dest disk/file open error!\n"),GetLastError());
            return -1;
        }
    }
    //u32 nBlkSize = vhd.uBlkSize;
    byte* buf = new byte [vhd.uBlkSize];
    u32 nBitmapSize = (vhd.spb >> 3 );
    byte* bitmap = new byte [nBitmapSize];
    DWORD bWrite;
    LARGE_INTEGER liPos,liNew;    

    for(int i=0;i<vhd.uBatNum;i++)
    {
        memset(buf,0,vhd.uBlkSize);
        memset(bitmap,0,nBitmapSize);
        if(read_vhd(vhd,buf,i) != 1) //读错误或属于稀疏空间
            continue;
        liPos.QuadPart = (u64)i * (u64)vhd.uBlkSize;
        SetFilePointerEx(hOut,liPos,&liNew,FILE_BEGIN);
        WriteFile(hOut,buf,vhd.uBlkSize,&bWrite,NULL);
        if(bWrite != vhd.uBlkSize)
        {
            _tprintf(_T("ERROR%d:#%dblk (2MB) write error!\n\n"),GetLastError(),i);
            return -1;
        }
    }    

    liPos.QuadPart = (u64)vhd.uBatNum * (u64)vhd.uBlkSize;
    SetFilePointerEx(hOut,liPos,&liNew,FILE_BEGIN);
    SetEndOfFile(hOut);    

    //释放
    delete [] buf;
    delete [] bitmap;
    CloseHandle(hIn);
    CloseHandle(hOut);    

    return 1;    

}

以上是小编为您精心准备的的内容,在的博客、问答、公众号、人物、课程等栏目也有的相关内容,欢迎继续使用右上角搜索按钮进行搜索sizeof
, byte
, return
, int64_t
, c++ vs2010
, vs2010keilc51
, 依赖源码编译vs2010
, freeglut编译错误vs2010
, vs2010  CRforVS_13_0
, VHD
strncmp()
img转vhd、img vhd、qemu img vhd、img.gz vhd、vhd转换vmdk,以便于您获取更多的相关知识。

时间: 2024-08-22 14:51:41

vhd 转换为img源码,由VS 2010 C++编译的相关文章

反编译-spring源码增加注释如何重新编译打包?

问题描述 spring源码增加注释如何重新编译打包? spring源码增加注释如何重新编译打包,或者其它反编译获得的源码加注释后重新编译如何打成jar包 解决方案 spring 源码编译

Ubuntu Android源码以及内核下载与编译_Android

本教程是基于Ubuntu下Android6.0.1源码以及内核的下载和编译,记录一下,以后也就不用自己去找资料,一遍一遍的尝试了.可以翻墙的,英语好的,直接去AndroidSource. 系统环境:Ubuntu14.04LTS Android版本:6.0.1 重要网址 清华大学镜像 AndroidSource 下载前的准备 安装OpenJdk sudo add-apt-repository ppa:openjdk-r/ppa sudo apt-get update sudo apt-get in

Android源码浅析(三)——Android AOSP 5.1.1源码的同步sync和编译make,搭建Samba服务器进行更便捷的烧录刷机

Android源码浅析(三)--Android AOSP 5.1.1源码的同步sync和编译make,搭建Samba服务器进行更便捷的烧录刷机 最近比较忙,而且又要维护自己的博客,视频和公众号,也就没仔细的梳理源码的入门逻辑,今天也就来讲一个源码的玩法,各位看官,一起学习学习! 看本篇博客之前,先看下我的前面两篇 Android源码浅析(一)--VMware Workstation Pro和Ubuntu Kylin 16.04 LTS安装配置 Android源码浅析(二)--Ubuntu Roo

Android内核源码 在Ubuntu上下载,编译,安装

从源代码树下载下来的最新Android源代码,是不包括内核代码的,也就是Android源代码工程默认不包含Linux Kernel代码,而是使用预先编译好的内核,也就是prebuilt/android-arm/kernel/kernel-qemu文件.那么,如何才能DIY自己的内核呢?这篇文章一一道来. 一. 首选,参照前一篇在Android源码 在Ubuntu上下载,编译和安装准备好Android源代码目录. 二. 下载Linux Kernel for Android源代码. 1. 使用GIT

在tiny4412源码下编写全系统编译执行脚本

今天心血来潮,想把之前做的开发板环境配置以及编译的东西重新整理一下,毕竟最近在搞开发,所以有必要温故而知新. 以下是我整个Android-5.0的工程目录列表: 其中build_4412_img.sh.copyimage_to_window_system.sh是我自己写的快速编译拷贝脚本. book@book-virtual-machine:/work/android-5.0.2$ ls abi build_4412_img.sh development gen-img.sh Makefile

用C#写了一个SLE4442加密卡充值售电软件,源代码中包含写卡密码,C#源码可用.Net Reflector 反编译的话,那写卡密码岂不是很容易泄露

问题描述 用C#写了一个SLE4442加密卡充值售电软件,源代码中包含写卡密码,C#源码可用.NetReflector反编译的话,那写卡密码岂不是很容易泄露.请问如何解决这个问题.谢谢大家. 解决方案 解决方案二:你的充值售电软件会网上公开吗解决方案三:引用1楼andywangguanxi的回复: 你的充值售电软件会网上公开吗 不在网上公开,但是,如果我们当地的同行业竞争对手搞到我们的软件(那是很容易的),而后反编译,那就可以仿造我们的产品,以低价争抢我们原有的客户资源,那是很危险的.解决方案四

Android源码 在Ubuntu上下载,编译和安装

看完了前面说的几本书之后,对Linux Kernel和Android有一定的认识了,是不是心里蠢蠢欲动,想小试牛刀自己编译一把Android源代码了呢?一直习惯使用Windows系统,而Android源代码是不支持在Windows上编译上,于是决定使用虚拟机安装Ubuntu,然后下载.编译和安装Android源代码. 一. 环境准备. 1. 磁盘空间预留20G左右,内存3G,因为一边要跑主机,一边要跑虚拟机,内存要求还是比较高的,这样才会比较流畅. 2. 安装VMWare 7.1.4.我的操作系

源码方式安装LAMP

一.安装环境: Linux平台:Linux 2.6.18-164.el5 源码安装所需要的编译环境: 开发环境的设置是必须的,不然,在源码编译过程中会出现许多不必要的错误: 将源码安装包导入到Linux系统的/root目录下:

[jjzhu学hadoop]之hadoop2.7.3源码编译eclipse项目

编译环境 必须的安装包 安装jdk 安装mvn 配置本地仓库路径 更换阿里云maven镜像强烈推荐更换 Native libraries ProtocolBuffer 250 可选的安装包 Snappy compression Bzip2 Jansson C Library for JSON Linux FUSE 编译eclipse plugin 切换到root编译hadoop-maven-plugins 生成eclipse项目 ProtocolBuffer版本问题解决办法 先卸载libbpro