Welcome

首页 / 软件开发 / C++ / vhd 转换为img源码,由VS 2010 C++编译

vhd 转换为img源码,由VS 2010 C++编译2013-04-20 51cto 张宇的BLOG本工程主要由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 0x80static 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 blocku32 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!
"),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!
"));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;elsevhd.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>
"));_tprintf(_T("eg. vhd2img.exe my.vhd d:\my.img 
"));_tprintf(_T("vhd2img.exe my.vhd "\\.\physicaldrive1" (write to hardisk 1)
"));return 0;}vhd_info vhd;//打开输入vhdif(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!
"),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!

"),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;}