This project mainly consists of Vhd2img.cpp Layout.h, C code implementation.
Vhd2img.cpp:
Vhd2img.cpp: Defines the entry point for a console application. by www.frombyte.cn Zhangyu/North Asia Data Recovery Center (www.sjhf.net) Zhang Yu 2012/1/6 published in 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)) & BI
T_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)) Retu
rn-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;
The for (u32 i=0;i<vhd.spb;i++) {if (Test_bit (spb_bitmap,i))//bit is 1, indicating that there is data on the disk, which requires a copy of {
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 ( "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));
return 0;
} Vhd_info VHD;
Open the input VHD if (OPEN_VHD (ARGV[1],VHD)!= 1) return-1; Generate target file 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"), get
LastError ());
return-1;
}//u32 nblksize = vhd.ublksize;
byte* buf = new byte [vhd.ublksize]; U32 nbitmapsize = (VHD.SPB >&Gt
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)//Read error or belong to sparse space 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);
Release delete [] buf;
delete [] bitmap;
CloseHandle (HIn); CloseHandle (HOut);
return 1; }