📄 vdkopen.c
字号:
// Allocate COWD parameter area // cowd_prm = (PVDK_COWD_PARAM)VdkAllocMem( sizeof(VDK_COWD_PARAM)); if (!cowd_prm) { VDKTRACE(VDKOPEN, ("[VDK] Failed to allocate cowd parameter\n")); return VDK_NOMEMORY; } VdkZeroMem(cowd_prm, sizeof(VDK_COWD_PARAM)); FileInfo->prm.cowd = cowd_prm; // // Allocate COWD header area // cowd_hdr = (PCOWD_SECTOR_0)VdkAllocMem( VDK_BYTES_PER_SECTOR); if (!cowd_hdr) { VDKTRACE(VDKOPEN, ("[VDK] Failed to allocate cowd header buffer\n")); status = VDK_NOMEMORY; goto cleanup_exit; } // // Read COWD header // status = VdkReadFileAt( FileInfo->FileHandle, 0, cowd_hdr, VDK_BYTES_PER_SECTOR, NULL); if (!VDKSUCCESS(status)) { goto cleanup_exit; } // // set up COWD parameters // cowd_prm->PrimaryMapSize = (((cowd_hdr->PrimaryMapSize * sizeof(ULONG)) + (VDK_BYTES_PER_SECTOR - 1)) & ~VDK_SECTOR_ALIGNMENT_MASK) / sizeof(ULONG); cowd_prm->SecondaryMapSize = COWD_SECONDARY_MAP_SIZE; cowd_prm->PrimaryGranularity = cowd_hdr->Granularity * cowd_prm->SecondaryMapSize; cowd_prm->SecondaryGranularity = cowd_hdr->Granularity; VDKTRACE(VDKOPEN | VDKINFO, ("[VDK] PrimaryMap size = %lu, granularity = %lu\n", cowd_prm->PrimaryMapSize, cowd_prm->PrimaryGranularity)); VDKTRACE(VDKOPEN | VDKINFO, ("[VDK] Secondary size = %lu, granularity = %lu\n", cowd_prm->SecondaryMapSize, cowd_prm->SecondaryGranularity)); // // Check parameter logical consistency // if (cowd_prm->PrimaryMapSize * cowd_prm->PrimaryGranularity < FileInfo->Capacity) { // // Sector map cannot cover whole sectors in this file // VDKTRACE(VDKOPEN, ("[VDK] map is too small\n")); status = VDK_PARAM; goto cleanup_exit; } if (cowd_hdr->PrimaryMapOffset < 4 || cowd_hdr->PrimaryMapOffset >= FileInfo->EndOfFile) { // // PrimaryMapOffset is too large for this file. // Probably the file is corrupt. // VDKTRACE(VDKOPEN, ("[VDK] Invalid PrimaryMapOffset %u\n", cowd_hdr->PrimaryMapOffset)); status = VDK_PARAM; goto cleanup_exit; } // // Prepare PrimaryMap buffer // cowd_prm->PrimaryMap = (PULONG)VdkAllocMem( cowd_prm->PrimaryMapSize * sizeof(ULONG)); if (!cowd_prm->PrimaryMap) { VDKTRACE(VDKOPEN, ("[VDK] Can't allocate memory for primary map\n")); status = VDK_NOMEMORY; goto cleanup_exit; } // // Read primary map // status = VdkReadFileAt( FileInfo->FileHandle, (INT64)cowd_hdr->PrimaryMapOffset << VDK_BYTE_SHIFT_TO_SECTOR, cowd_prm->PrimaryMap, cowd_prm->PrimaryMapSize * sizeof(ULONG), NULL); if (!VDKSUCCESS(status)) { goto cleanup_exit; } // // Prepare SecondaryMap buffer // cowd_prm->SecondaryMap = (PULONG)VdkAllocMem( cowd_prm->SecondaryMapSize * sizeof(ULONG)); if (!cowd_prm->SecondaryMap) { VDKTRACE(VDKOPEN, ("[VDK] Can't allocate memory for secondary map\n")); status = VDK_NOMEMORY; goto cleanup_exit; } // // Read secondary map // if (cowd_prm->PrimaryMap[0] <= cowd_hdr->PrimaryMapOffset || cowd_prm->PrimaryMap[0] >= FileInfo->EndOfFile) { // // Secondary Map is not allocated or too large for this file. // VDKTRACE(VDKOPEN | VDKWARN, ("[VDK] Invalid SecondaryMapOffset %u\n", cowd_prm->PrimaryMap[0])); VdkZeroMem( cowd_prm->SecondaryMap, cowd_prm->SecondaryMapSize * sizeof(ULONG)); } else { status = VdkReadFileAt( FileInfo->FileHandle, (INT64)cowd_prm->PrimaryMap[0] << VDK_BYTE_SHIFT_TO_SECTOR, cowd_prm->SecondaryMap, cowd_prm->SecondaryMapSize * sizeof(ULONG), NULL); if (!VDKSUCCESS(status)) { goto cleanup_exit; } }cleanup_exit: if (cowd_hdr) { if (VDKSUCCESS(status) && !ReadOnly) { FileInfo->prm.cowd->Sector0 = cowd_hdr; } else { VdkFreeMem(cowd_hdr); } } return status;}//// Prepare extra parameters for VMDK files//VDKSTAT VdkSetVmdkParam( PVDK_FILE_INFO FileInfo, ULONG ReadOnly){ PVDK_VMDK_PARAM vmdk_prm = NULL; PVMDK_HEADER vmdk_hdr = NULL; PVOID read_buf = NULL; ULONG read_len; VDKSTAT status = VDK_OK; // // Allocate VMDK parameter area // vmdk_prm = (PVDK_VMDK_PARAM)VdkAllocMem(sizeof(VDK_VMDK_PARAM)); if (!vmdk_prm) { VDKTRACE(VDKOPEN, ("[VDK] Failed to allocate VMDK parameter\n")); return VDK_NOMEMORY; } VdkZeroMem(vmdk_prm, sizeof(VDK_VMDK_PARAM)); FileInfo->prm.vmdk = vmdk_prm; // // Allocate VMDK header area // vmdk_hdr = (PVMDK_HEADER)VdkAllocMem(VDK_BYTES_PER_SECTOR); if (!vmdk_hdr) { status = VDK_NOMEMORY; VDKTRACE(VDKOPEN, ("[VDK] Failed to allocate VMDK header buffer\n")); goto cleanup_exit; } // // Read VMDK header // status = VdkReadFileAt( FileInfo->FileHandle, 0, vmdk_hdr, VDK_BYTES_PER_SECTOR, NULL); if (!VDKSUCCESS(status)) { goto cleanup_exit; } // // Check parameter logical consistency // if (!vmdk_hdr->CapacityLow || !vmdk_hdr->numGTEsPerGT || !vmdk_hdr->GranularityLow || !vmdk_hdr->rgdOffsetLow || !vmdk_hdr->gdOffsetLow || vmdk_hdr->CapacityHigh || vmdk_hdr->GranularityHigh || vmdk_hdr->rgdOffsetHigh || vmdk_hdr->gdOffsetHigh || vmdk_hdr->rgdOffsetLow >= FileInfo->EndOfFile || vmdk_hdr->gdOffsetLow >= FileInfo->EndOfFile) { // // Directory Offset is too large for this file. // Probably the file is corrupt. // VDKTRACE(VDKOPEN, ("[VDK] Invalid VMDK header param\n")); status = VDK_PARAM; goto cleanup_exit; } if (vmdk_hdr->CapacityLow < FileInfo->Capacity) { // // VMDK file cannot cover specified capacity // VDKTRACE(VDKOPEN, ("[VDK] VMDK capacity mismatch\n")); status = VDK_PARAM; goto cleanup_exit; } // // set up VMDK parameters // vmdk_prm->GrainTableSize = vmdk_hdr->numGTEsPerGT; vmdk_prm->SectorsPerGrain = vmdk_hdr->GranularityLow; vmdk_prm->SectorsPerTable = vmdk_prm->GrainTableSize * vmdk_prm->SectorsPerGrain; vmdk_prm->DirectorySize = (vmdk_hdr->CapacityLow + vmdk_prm->SectorsPerTable - 1) / vmdk_prm->SectorsPerTable; VDKTRACE(VDKOPEN | VDKINFO, ("[VDK] Directory size = %lu\n", vmdk_prm->DirectorySize)); VDKTRACE(VDKOPEN | VDKINFO, ("[VDK] GrainTableSize = %lu\n", vmdk_prm->GrainTableSize)); VDKTRACE(VDKOPEN | VDKINFO, ("[VDK] SectorsPerTable = %lu\n", vmdk_prm->SectorsPerTable)); VDKTRACE(VDKOPEN | VDKINFO, ("[VDK] SectorsPerGrain = %lu\n", vmdk_prm->SectorsPerGrain)); // // Prepare Directory read buffer // read_len = (vmdk_prm->DirectorySize * sizeof(ULONG) + VDK_BYTES_PER_SECTOR - 1) & ~VDK_SECTOR_ALIGNMENT_MASK; read_buf = VdkAllocMem(read_len); if (!read_buf) { VDKTRACE(VDKOPEN, ("[VDK] Can't allocate memory for read buffer\n")); status = VDK_NOMEMORY; goto cleanup_exit; } // // Prepare Primary Directory buffer // vmdk_prm->PrimaryDirectory = (PULONG)VdkAllocMem( vmdk_prm->DirectorySize * sizeof(ULONG)); if (!vmdk_prm->PrimaryDirectory) { VDKTRACE(VDKOPEN, ("[VDK] Can't allocate memory for PrimaryDirectory\n")); status = VDK_NOMEMORY; goto cleanup_exit; } // // Read Primary Directory // VDKTRACE(VDKOPEN | VDKINFO, ("[VDK] Reading Primary Directory at offset 0x%08x\n", vmdk_hdr->rgdOffsetLow)); status = VdkReadFileAt( FileInfo->FileHandle, (INT64)vmdk_hdr->rgdOffsetLow << VDK_BYTE_SHIFT_TO_SECTOR, read_buf, read_len, NULL); if (!VDKSUCCESS(status)) { goto cleanup_exit; } VdkCopyMem(vmdk_prm->PrimaryDirectory, read_buf, vmdk_prm->DirectorySize * sizeof(ULONG)); if (!ReadOnly) { // // Prepare Backup Directory buffer // vmdk_prm->BackupDirectory = (PULONG)VdkAllocMem( vmdk_prm->DirectorySize * sizeof(ULONG)); if (!vmdk_prm->BackupDirectory) { VDKTRACE(VDKOPEN, ("[VDK] Can't allocate memory for BackupDirectory\n")); status = VDK_NOMEMORY; goto cleanup_exit; } // // Read Backup Directory // VDKTRACE(VDKOPEN | VDKINFO, ("[VDK] Reading Backup Directory at offset 0x%08x\n", vmdk_hdr->gdOffsetLow)); status = VdkReadFileAt( FileInfo->FileHandle, (INT64)vmdk_hdr->gdOffsetLow << VDK_BYTE_SHIFT_TO_SECTOR, read_buf, read_len, NULL); if (!VDKSUCCESS(status)) { goto cleanup_exit; } VdkCopyMem(vmdk_prm->BackupDirectory, read_buf, vmdk_prm->DirectorySize * sizeof(ULONG)); } // // Prepare Grain Table buffer // vmdk_prm->GrainTable = (PULONG)VdkAllocMem( vmdk_prm->GrainTableSize * sizeof(ULONG)); if (!vmdk_prm->GrainTable) { VDKTRACE(VDKOPEN, ("[VDK] Can't allocate memory for Grain Table\n")); status = VDK_NOMEMORY; goto cleanup_exit; } // // Read Grain Table // if (vmdk_prm->PrimaryDirectory[0] <= vmdk_hdr->rgdOffsetLow || vmdk_prm->PrimaryDirectory[0] >= FileInfo->EndOfFile) { // // Secondary Map is not allocated or too large for this file. // VDKTRACE(VDKOPEN, ("[VDK] Invalid Grain Table[0] Offset %u\n", vmdk_prm->PrimaryDirectory[0])); VdkZeroMem( vmdk_prm->GrainTable, vmdk_prm->GrainTableSize * sizeof(ULONG)); } else { VDKTRACE(VDKOPEN | VDKINFO, ("[VDK] Reading Grain Table[0] at offset 0x%08x\n", vmdk_prm->PrimaryDirectory[0])); status = VdkReadFileAt( FileInfo->FileHandle, (INT64)vmdk_prm->PrimaryDirectory[0] << VDK_BYTE_SHIFT_TO_SECTOR, vmdk_prm->GrainTable, vmdk_prm->GrainTableSize * sizeof(ULONG), NULL); if (!VDKSUCCESS(status)) { goto cleanup_exit; } }cleanup_exit: if (vmdk_hdr) { VdkFreeMem(vmdk_hdr); } if (read_buf) { VdkFreeMem(read_buf); } return status;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -