本工程主要由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