📄 vdiskvmdk.cpp
字号:
p++; } if (!VdkCmpNoCaseN(p, "twoGbMaxExtentSparse", 20)) { type = VDISK_VMDK_SPLIT_SPARSE; } else if (!VdkCmpNoCaseN(p, "monolithicSparse", 16)) { type = VDISK_VMDK_MONO_SPARSE; } else if (!VdkCmpNoCaseN(p, "twoGbMaxExtentFlat", 18)) { type = VDISK_VMDK_SPLIT_FLAT; } else if (!VdkCmpNoCaseN(p, "monolithicFlat", 14)) { type = VDISK_VMDK_MONO_FLAT; } else { type = VDiskCallBack( VDISK_CB_DESC_DISKTYPE, cbparams); SetFlag(VDISK_FLAG_DIRTY); } switch (type) { case VDISK_VMDK_SPLIT_FLAT: ClrFlag(VDISK_FLAG_SINGLE); ClrFlag(VDISK_FLAG_CHILD); ClrFlag(VDISK_FLAG_SPARSE); break; case VDISK_VMDK_MONO_FLAT: SetFlag(VDISK_FLAG_SINGLE); ClrFlag(VDISK_FLAG_CHILD); ClrFlag(VDISK_FLAG_SPARSE); break; case VDISK_VMDK_SPLIT_SPARSE: ClrFlag(VDISK_FLAG_SINGLE); SetFlag(VDISK_FLAG_SPARSE); break; case VDISK_VMDK_MONO_SPARSE: SetFlag(VDISK_FLAG_SINGLE); SetFlag(VDISK_FLAG_SPARSE); break; default: return VDK_DATA; } } else if (!VdkCmpNoCaseN(current, "version", 7)) {/* PCHAR p = current + 7; while (*p == ' ' || *p == '=' || *p == '\"') { p++; } m_nVmdkVersion = atol(p);*/ } else if (!VdkCmpNoCaseN(current, "parentFileNameHint", 18)) { PCHAR top = current + 18; PCHAR tail; while (*top == ' ' || *top == '=' || *top == '\"') { top++; } tail = top; while (*tail && *tail != '\"') { tail++; } *tail = '\0'; ret = StoreParentPath(top); if (ret != VDK_OK) { return ret; } SetFlag(VDISK_FLAG_CHILD); } else if (!VdkCmpNoCaseN(current, "ddb.toolsVersion", 16)) { PCHAR p = current + 16; while (*p == ' ' || *p == '=' || *p == '\"') { p++; } m_nToolsFlag = atol(p); } else if (*current && *current != '#') { if (!VDiskCallBack(VDISK_CB_DESC_BADENTRY, cbparams)) { return VDK_CANCEL; } SetFlag(VDISK_FLAG_DIRTY); } } if (ret == VDK_EOF) { return Check(); } else { return ret; }}//// create VMDK descriptor file and extent files//VDKSTAT VDiskVmdk::Create(ULONG flags){ ULONG idx; VDKSTAT ret; if (!m_nExtents || !m_ppExtents || !m_ppExtents[0]) { return VDK_FUNCTION; } if (m_nFlags & VDISK_FLAG_SINGLE) { flags |= VDISK_CREATE_SINGLE; } // // create each extent file // for (idx = 0; idx < m_nExtents; idx++) { ret = m_ppExtents[idx]->Create(flags); if (ret != VDK_OK) { return ret; } } // // create the description file (or write description into monolithic file) // ret = WriteDescriptor(TRUE, (flags & VDISK_CREATE_FORCE)); return ret;}//// write VMDK descriptor file//VDKSTAT VDiskVmdk::WriteDescriptor(BOOL create, BOOL force){ CHAR buf[MAX_PATH + 30]; ULONG idx; ULONG path_len; HANDLE hFile; VDKSTAT ret = VDK_OK; // // create/open the description file // sprintf(buf, "%s" PATH_SEPARATOR_STR "%s.%s", m_pPath, m_pBody, m_pExtension); if (create) { ret = VdkCreateFile(&hFile, buf, force); } else { ret = VdkOpenFile(&hFile, buf, strlen(buf), FALSE); } if (ret != VDK_OK) { return ret; } if ((m_nFlags & VDISK_FLAG_SINGLE) && (m_nFlags & VDISK_FLAG_SPARSE)) { // // adjust descriptor offset for monolithic sparse file // ret = VdkSeekFile(hFile, ((VDiskExtVmdk *)m_ppExtents[0])->GetHeader()->DescOffsetLow); if (ret != VDK_OK) { goto cleanup; } } // // create header entries // sprintf(buf, "# Disk DescriptorFile\n" "version=1\n" "CID=%08lx\n" "parentCID=%08lx\n" "createType=\"%s%s\"\n", m_nTimeStamp, m_nParentTS, (m_nFlags & VDISK_FLAG_SINGLE) ? "monolithic" : "twoGbMaxExtent", (m_nFlags & VDISK_FLAG_SPARSE) ? "Sparse" : "Flat"); ret = VdkWriteFileAt(hFile, -1, buf, strlen(buf), NULL); if (ret != VDK_OK) { goto cleanup; } if (m_nFlags & VDISK_FLAG_CHILD) { sprintf(buf, "parentFileNameHint=\"%s\"\n", m_pParentPath); ret = VdkWriteFileAt(hFile, -1, buf, strlen(buf), NULL); if (ret != VDK_OK) { goto cleanup; } } // // create each extent entry // strcpy(buf, "\n# Extent description\n"); ret = VdkWriteFileAt(hFile, -1, buf, strlen(buf), NULL); if (ret != VDK_OK) { goto cleanup; } path_len = strlen(m_pPath); for (idx = 0; idx < m_nExtents; idx++) { VDiskExt *ext = *(m_ppExtents + idx); PCHAR path; path = ext->GetFullPath(); if (!(m_nFlags & VDISK_FLAG_ABSPATH) && !VdkCmpNoCaseN(m_pPath, path, path_len)) { path = ext->GetFileName(); } if (ext->GetFileType() == VDK_FILETYPE_VMDK) { sprintf(buf, "RW %lu SPARSE \"%s\"\n", ext->GetCapacity(), path); } else { sprintf(buf, "RW %lu FLAT \"%s\" %lu\n", ext->GetCapacity(), path, ((VDiskExtRaw *)ext)->GetBackOffset()); } ret = VdkWriteFileAt(hFile, -1, buf, strlen(buf), NULL); if (ret != VDK_OK) { goto cleanup; } } // // create trailing entries // strcpy(buf, "\n# The Disk Data Base \n" "#DDB\n\n"); ret = VdkWriteFileAt(hFile, -1, buf, strlen(buf), NULL); if (ret != VDK_OK) { goto cleanup; } if (!(m_nFlags & VDISK_FLAG_CHILD)) { sprintf(buf, "ddb.virtualHWVersion = \"%lu\"\n" "ddb.geometry.cylinders = \"%lu\"\n" "ddb.geometry.heads = \"%lu\"\n" "ddb.geometry.sectors = \"%lu\"\n" "ddb.adapterType = \"%s\"\n", m_nHardwareVer, m_nCylinders, m_nTracks, m_nSectors, (m_nController == VDISK_CONTROLLER_IDE) ? "ide" : "buslogic"); ret = VdkWriteFileAt(hFile, -1, buf, strlen(buf), NULL); if (ret != VDK_OK) { goto cleanup; } }cleanup: if (hFile != INVALID_HANDLE_VALUE) { VdkCloseFile(hFile); } return ret;}//// Create a new extent object for this disk instance//VDiskExt *VDiskVmdk::NewExtent(){ if (m_nFlags & VDISK_FLAG_SPARSE) { return new VDiskExtVmdk; } else { return new VDiskExtRaw; }}//// Get path for each extent files//void VDiskVmdk::GetExtentPath( PCHAR pPath, ULONG nSeq){ if (m_nFlags & VDISK_FLAG_SPARSE) { if (m_nFlags & VDISK_FLAG_SINGLE) { sprintf(pPath, "%s" PATH_SEPARATOR_STR "%s.%s", m_pPath, m_pBody, m_pExtension); } else { sprintf(pPath, "%s" PATH_SEPARATOR_STR "%s-s%03lu.%s", m_pPath, m_pBody, nSeq + 1, m_pExtension); } } else { if (m_nFlags & VDISK_FLAG_SINGLE) { sprintf(pPath, "%s" PATH_SEPARATOR_STR "%s-flat.%s", m_pPath, m_pBody, m_pExtension); } else { sprintf(pPath, "%s" PATH_SEPARATOR_STR "%s-f%03lu.%s", m_pPath, m_pBody, nSeq + 1, m_pExtension); } }}//// Set default geometry values//void VDiskVmdk::SetGeometry(){ if (m_nController == VDISK_CONTROLLER_IDE) { m_nTracks = VMDK_TRACKS_IDE; m_nSectors = VMDK_SECTORS_IDE; } else { if (m_nCapacity <= VMDK_SECTORS_SCSI_1023M * VMDK_TRACKS_SCSI_1023M * 1023) { m_nSectors = VMDK_SECTORS_SCSI_1023M; m_nTracks = VMDK_TRACKS_SCSI_1023M; } else if (m_nCapacity <= VMDK_SECTORS_SCSI_2046M * VMDK_TRACKS_SCSI_2046M * 1023) { m_nSectors = VMDK_SECTORS_SCSI_2046M; m_nTracks = VMDK_TRACKS_SCSI_2046M; } else { m_nSectors = VMDK_SECTORS_SCSI_LARGE; m_nTracks = VMDK_TRACKS_SCSI_LARGE; } } m_nCylinders = m_nCapacity / (m_nSectors * m_nTracks);}//// Set default Timestamp values;//void VDiskVmdk::SetDefaultTS(){ m_nParentTS = (ULONG)-1; m_nTimeStamp = (ULONG)-2;}//// Get default extent size//ULONG VDiskVmdk::DefaultExtSize(){ ULONG ext_size; if (m_nFlags & VDISK_FLAG_SINGLE) { ext_size = m_nCapacity; } else { if (m_nFlags & VDISK_FLAG_SPARSE) { ext_size = VMDK_MAX_EXTENT_SPARSE; } else { ext_size = VMDK_MAX_EXTENT_SOLID; } if (ext_size > m_nCapacity) { ext_size = m_nCapacity; } } return ext_size;}//// Check VMDK sparse disk//VDKSTAT VDiskVmdk::Check(){ PVOID cbparams[3]; CHAR path[MAX_PATH]; ULONG idx; VDKSTAT ret; FullPath(path); cbparams[0] = path; // // At least one extent must be present // if (!m_nExtents) { VDiskCallBack(VDISK_CB_EMPTY_IMAGE, cbparams); return VDK_DATA; } // // Sum up extent capacity // m_nCapacity = 0; for (idx = 0; idx < m_nExtents; idx++) { if ((ret = m_ppExtents[idx]->Check()) != VDK_OK) { return ret; } if (m_ppExtents[idx]->IsModified()) { SetFlag(VDISK_FLAG_DIRTY); } m_nCapacity += m_ppExtents[idx]->GetCapacity(); } // // Check total capacity // /* if (total_size != m_nCapacity) { cbparams[1] = (PVOID)m_nCapacity; cbparams[2] = (PVOID)total_size; if (!VDiskCallBack(VDISK_CB_EXT_CAPACITY, cbparams)) { return VDK_DATA; } m_nCapacity = total_size; SetGeometry(); SetFlag(VDISK_FLAG_DIRTY); for (idx = 0; idx < m_nExtents; idx++) { if (total_size < m_ppExtents[idx]->GetCapacity()) { m_ppExtents[idx]->SetCapacity(total_size); total_size = 0; } else { total_size -= m_ppExtents[idx]->GetCapacity(); } } } */ // // Any bad parameter? // if (m_nFlags & VDISK_FLAG_DIRTY) { if (VDiskCallBack(VDISK_CB_CONFIRM_FIX, cbparams)) { ret = WriteDescriptor(FALSE, FALSE); if (ret != VDK_OK) { return ret; } for (idx = 0; idx < m_nExtents; idx++) { ret = m_ppExtents[idx]->Update(); if (ret != VDK_OK) { return ret; } } } ClrFlag(VDISK_FLAG_DIRTY); } return VDK_OK;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -