www.pudn.com > vdksrc.zip > VDiskCB.cpp
/*
VDiskCB.cpp
VDiskInitialize() callback function (text mode)
Copyright (C) 2003 Ken Kato
*/
#include "vdkbase.h"
#include "vdkutil.h"
#include "vdkmsg.h"
#include "cowdisk.h"
#include "vmdisk.h"
#include "VDiskUtil.h"
ULONG VDiskCallback(ULONG reason, PVOID *params)
{
ULONG ret = 0;
#ifdef _WIN32
// Windows FormatMessage does not expand 64bit argument
// correctly so convert to a string argument
#define I64PRM(v) _i64toa(*(PINT64)(v), i64buf, 10)
CHAR i64buf[24];
#else
#define I64PRM(v) (*(PINT64)(v))
#endif // _WIN32
switch (reason) {
// Cannot open specified file
// params[0]: PCHAR path,
// params[1]: VDKSTAT error
// return: TRUE retry with new path stored into params[0]
// FALSE fail
case VDISK_CB_FILE_OPEN:
PrintMessage(MSG_CB_FILE_OPEN,
(PCHAR)params[0], VdkStatusStr((ULONG)params[1]));
if ((ULONG)params[1] == VDK_NOFILE ||
(ULONG)params[1] == VDK_NOPATH) {
//
// file not found -- prompt user for a correct path
//
PrintMessage(MSG_PROMPT_PATH);
fflush(stdout);
if (fgets((PCHAR)params[0], MAX_PATH, stdin) &&
*(PCHAR)params[0] != '\n' &&
*(PCHAR)params[0] != '\0') {
PCHAR p = (PCHAR)params[0];
while (*p && *p != '\n') {
p++;
}
*p = '\0';
ret = TRUE;
}
}
break;
// Confirms the user if the file is raw sector image file
// params[0] PCHAR path
// return TRUE the file is a raw sector image file
// FALSE abort
case VDISK_CB_FILE_TYPE:
PrintMessage(MSG_CB_FILE_TYPE, (PCHAR)params[0]);
ret = (InputChar(MSG_PROMPT_YESNO, "yn") == 'y');
break;
// Confirmation for applying fixes to actual file
// params[0] PCHAR path
// return TRUE update the actual file
// FALSE do not update the actual file
case VDISK_CB_CONFIRM_FIX:
break;
// Descriptor file does not contain any extent entry (FATAL)
// params[0] PCHAR path
// return NONE
case VDISK_CB_EMPTY_IMAGE:
PrintMessage(MSG_CB_EMPTY_IMAGE, (PCHAR)params[0]);
break;
// Extent file size is not proper multiple of sector size
// params[0]: PCHAR path
// params[1]: PINT64 size
// return: TRUE ignore / correct
// FALSE abort
case VDISK_CB_SIZE_BOUNDARY:
PrintMessage(MSG_CB_SIZE_BOUNDARY,
(PCHAR)params[0], I64PRM(params[1]),
(ULONG)*(PINT64)params[1] & VDK_SECTOR_ALIGNMENT_MASK);
ret = (InputChar(MSG_PROMPT_ABORTIGNORE, "ai") == 'i');
break;
// Invalid signature
// params[0]: PCHAR path
// params[1]: ULONG bad signature
// return: TRUE ignore / correct
// FALSE abort
case VDISK_CB_SIGNATURE:
PrintMessage(MSG_CB_SIGNATURE,
(PCHAR)params[0], (ULONG)params[1]);
ret = (InputChar(MSG_PROMPT_ABORTIGNORE, "ai") == 'i');
break;
// Unknown controller type in virtual disk file
// params[0]: PCHAR path
// params[1]: PCHAR invalid entry
// return: correct value
// 0: abort
case VDISK_CB_CONTROLLER:
PrintMessage(MSG_CB_CONTROLLER,
(PCHAR)params[0], (PCHAR)params[1]);
switch (InputChar(MSG_PROMPT_CONTROLLER, "isc")) {
case 'i':
ret = VDISK_CONTROLLER_IDE;
break;
case 's':
ret = VDISK_CONTROLLER_SCSI;
break;
default:
ret = 0;
break;
}
break;
// bad hardware version in virtual disk file
// params[0]: PCHAR path
// params[1]: PCHAR invalid entry
// return: correct value
// 0: abort
case VDISK_CB_HARDWAREVER:
PrintMessage(MSG_CB_HARDWAREVER,
(PCHAR)params[0], (PCHAR)params[1]);
/*
switch (InputChar("Input VMware version (2, 3, 4) or A) abort : ", "a234")) {
case '2':
ret = COWD_HARDWARE_VMWARE2;
break;
case '3':
ret = COWD_HARDWARE_VMWARE3;
break;
case '4':
ret = COWD_HARDWARE_VMWARE4;
break;
default:
ret = 0;
break;
}
*/
ret = (InputChar(MSG_PROMPT_ABORTIGNORE, "ai") == 'i')
? COWD_HARDWARE_VMWARE3 : 0;
break;
// Unrecognizable entry in description file
// params[0]: PCHAR path
// params[1]: PCHAR invalid entry
// return: TRUE ignore
// FALSE abort
case VDISK_CB_DESC_BADENTRY:
PrintMessage(MSG_CB_DESC_BADENTRY,
(PCHAR)params[0], (PCHAR)params[1]);
ret = (InputChar(MSG_PROMPT_ABORTIGNORE, "ai") == 'i');
break;
// bad offset value in description file
// params[0]: PCHAR path
// params[1]: PCHAR invalid entry
// return: correct offset value
// -1: abort
case VDISK_CB_DESC_OFFSET:
PrintMessage(MSG_CB_DESC_OFFSET,
(PCHAR)params[0], (PCHAR)params[1]);
/*
ret = InputVal("Correct offset : ", (ULONG)-1);
*/
ret = (ULONG)-1;
break;
// bad capacity value in description file
// params[0]: PCHAR path
// params[1]: PCHAR invalid entry
// return: correct capacity value
// 0: abort
case VDISK_CB_DESC_CAPACITY:
PrintMessage(MSG_CB_DESC_CAPACITY,
(PCHAR)params[0], (PCHAR)params[1]);
/*
ret = InputVal("Correct capacity : ", 0);
*/
break;
// invalid geometry values in description file
// params[0]: PCHAR path
// params[1]: PCHAR invalid entry
// return: correct value
// 0: abort
case VDISK_CB_DESC_GEOMETRY:
PrintMessage(MSG_CB_DESC_GEOMETRY,
(PCHAR)params[0], (PCHAR)params[1]);
/*
ret = InputVal("Correct value : ", 0);
*/
break;
// Unknown extent type in virtual disk file
// params[0]: PCHAR path
// params[1]: PCHAR invalid entry
// return: VDK_FILETYPE value
case VDISK_CB_DESC_FILETYPE:
PrintMessage(MSG_CB_DESC_FILETYPE,
(PCHAR)params[0], (PCHAR)params[1]);
/*
ret = (InputChar("S) Sparse (compact) or F) Flat (preallocate) ? ", "sf") == 's');
*/
break;
// bad timestamp value in virtual disk file
// params[0]: PCHAR path
// params[1]: PCHAR invalid entry
// return: correct value
// 0: abort
case VDISK_CB_DESC_TIMESTAMP:
PrintMessage(MSG_CB_DESC_TIMESTAMP,
(PCHAR)params[0], (PCHAR)params[1]);
/*
ret = InputHexVal("Correct value : ", 0);
*/
ret = (InputChar(MSG_PROMPT_ABORTIGNORE, "ai") == 'i');
break;
// Unknown disk type in virtual disk file
// params[0]: PCHAR path
// params[1]: PCHAR invalid entry
// return: correct value
// 0: abort
case VDISK_CB_DESC_DISKTYPE:
PrintMessage(MSG_CB_DESC_DISKTYPE,
(PCHAR)params[0], (PCHAR)params[1]);
/*
ret = InputChar(
"1) flat/split\n"
"2) flat/single\n"
"3) sparse/split\n"
"4) sparse/single\n"
"0) cancel\n"
"? ", "01234") - '0';
*/
break;
// described offset does not match actual offset
// params[0]: PCHAR path
// params[1]: ULONG described offset
// params[2]: ULONG calculated offset
// return TRUE use correct value
// FALSE abort
case VDISK_CB_EXT_OFFSET:
PrintMessage(MSG_CB_EXT_OFFSET,
(PCHAR)params[0], (ULONG)params[1], (ULONG)params[2]);
ret = (InputChar(MSG_PROMPT_YESNO, "yn") == 'y');
break;
// described capacity does not match actual file size
// params[0]: PCHAR path
// params[1]: ULONG described size
// params[2]: ULONG actual size
// return: correct capacity
// 0 abort
case VDISK_CB_EXT_FILESIZE:
PrintMessage(MSG_CB_EXT_FILESIZE,
(PCHAR)params[0], (ULONG)params[1], (ULONG)params[2]);
ret = ((InputChar(MSG_PROMPT_YESNO, "yn") == 'y') ? (ULONG)params[2] : 0);
break;
// described disk capacity does not match the total of extents
// params[0]: PCHAR path
// params[1]: ULONG described capacity
// params[2]: ULONG calculated capacity
// return: TRUE corrected or ignore
// FALSE abort
case VDISK_CB_EXT_CAPACITY:
PrintMessage(MSG_CB_EXT_CAPACITY,
(PCHAR)params[0], (ULONG)params[1], (ULONG)params[2]);
break;
// Ordinal stored in an extent file does not match the actual order
// params[0]: PCHAR path
// params[1]: ULONG ordinal in the header
// params[2]: ULONG correct ordinal
// return: TRUE corrected or ignore
// FALSE abort
case VDISK_CB_COWD_ORDINAL:
PrintMessage(MSG_CB_COWD_ORDINAL,
(PCHAR)params[0], (ULONG)params[1], (ULONG)params[2]);
ret = (InputChar(MSG_PROMPT_YESNO, "yn") == 'y');
break;
// Parameter conflict between extents
// params[0]: PCHAR path1
// params[1]: value1
// params[1]: PCHAR path2
// params[3]: value2
// return: TRUE corrected or ignore
// FALSE abort
case VDISK_CB_CONF_FILEVER:
PrintMessage(MSG_CB_CONF_FILEVER,
(PCHAR)params[0], (ULONG)params[1],
(PCHAR)params[2], (ULONG)params[3]);
break;
case VDISK_CB_CONF_FLAGS:
PrintMessage(MSG_CB_CONF_FLAGS,
(PCHAR)params[0], (ULONG)params[1],
(PCHAR)params[2], (ULONG)params[3]);
break;
case VDISK_CB_CONF_PARENTTS:
PrintMessage(MSG_CB_CONF_PARENTTS,
(PCHAR)params[0], (ULONG)params[1],
(PCHAR)params[2], (ULONG)params[3]);
break;
case VDISK_CB_CONF_TIMESTAMP:
PrintMessage(MSG_CB_CONF_TIMESTAMP,
(PCHAR)params[0], (ULONG)params[1],
(PCHAR)params[2], (ULONG)params[3]);
break;
case VDISK_CB_CONF_CONTROLLER:
PrintMessage(MSG_CB_CONF_CONTROLLER,
(PCHAR)params[0], (PCHAR)params[1],
(PCHAR)params[2], (PCHAR)params[3]);
break;
case VDISK_CB_CONF_EXTENTS:
PrintMessage(MSG_CB_CONF_EXTENTS,
(PCHAR)params[0], (ULONG)params[1],
(PCHAR)params[2], (ULONG)params[3]);
break;
case VDISK_CB_CONF_CYLINDERS:
PrintMessage(MSG_CB_CONF_CYLINDERS,
(PCHAR)params[0], (ULONG)params[1],
(PCHAR)params[2], (ULONG)params[3]);
break;
case VDISK_CB_CONF_TRACKS:
PrintMessage(MSG_CB_CONF_TRACKS,
(PCHAR)params[0], (ULONG)params[1],
(PCHAR)params[2], (ULONG)params[3]);
break;
case VDISK_CB_CONF_SECTORS:
PrintMessage(MSG_CB_CONF_SECTORS,
(PCHAR)params[0], (ULONG)params[1],
(PCHAR)params[2], (ULONG)params[3]);
break;
case VDISK_CB_CONF_CAPACITY:
PrintMessage(MSG_CB_CONF_CAPACITY,
(PCHAR)params[0], (ULONG)params[1],
(PCHAR)params[2], (ULONG)params[3]);
break;
case VDISK_CB_CONF_HARDWARE:
PrintMessage(MSG_CB_CONF_HARDWARE,
(PCHAR)params[0], (ULONG)params[1],
(PCHAR)params[2], (ULONG)params[3]);
break;
case VDISK_CB_CONF_TOOLSFLAG:
PrintMessage(MSG_CB_CONF_TOOLSFLAG,
(PCHAR)params[0], (ULONG)params[1],
(PCHAR)params[2], (ULONG)params[3]);
break;
case VDISK_CB_CONF_SEQNUM:
PrintMessage(MSG_CB_CONF_SEQNUM,
(PCHAR)params[0], (ULONG)params[1],
(PCHAR)params[2], (ULONG)params[3]);
break;
case VDISK_CB_CONF_PARENTPATH:
PrintMessage(MSG_CB_CONF_PARENTPATH,
(PCHAR)params[0], (PCHAR)params[1],
(PCHAR)params[2], (PCHAR)params[3]);
break;
// prompts to ignore non-fatal conflicts
// return: TRUE yes
// FALSE no
case VDISK_CB_CONFLICT_IGNORE:
ret = (InputChar(MSG_PROMPT_ABORTIGNORE, "ai") == 'i');
break;
// disk capacity stored in the header does not match the total of extents
// params[0]: PCHAR path
// params[1]: ULONG stored capacity
// params[2]: ULONG total capacity
// return: TRUE corrected or ignore
// FALSE abort
case VDISK_CB_COWD_CAPACITY:
PrintMessage(MSG_CB_COWD_CAPACITY,
(PCHAR)params[0], (ULONG)params[1], (ULONG)params[2]);
break;
// Invalid cowd version
// params[0]: PCHAR path
// params[1]: ULONG bad version
// return: correct version
case VDISK_CB_COWD_FILEVER:
PrintMessage(MSG_CB_COWD_FILEVER,
(PCHAR)params[0], (ULONG)params[1]);
ret = (InputChar(MSG_PROMPT_ABORTIGNORE, "ai") == 'i')
? COWD_FILEVER_VMWARE3 : 0;
break;
// File geometry values inconsistent or capacity = 0
// params[0]: PCHAR path
// params[1]: PCOWD_SECTOR_0 sec0
// return: NONE
case VDIDK_CB_COWD_FILEGEOM:
PrintMessage(MSG_CB_COWD_GEOMETRY,
(PCHAR)params[0],
((PCOWD_SECTOR_0)params[1])->u.Geometry.Cylinders,
((PCOWD_SECTOR_0)params[1])->u.Geometry.Tracks,
((PCOWD_SECTOR_0)params[1])->u.Geometry.Sectors,
((PCOWD_SECTOR_0)params[1])->Capacity);
break;
// Disk geometry values inconsistent or capacity = 0
// params[0]: PCHAR path
// params[1]: PCOWD_SECTOR_3 sec3
// return: NONE
case VDISK_CB_COWD_DISKGEOM:
PrintMessage(MSG_CB_COWD_GEOMETRY,
(PCHAR)params[0],
((PCOWD_SECTOR_3)params[1])->Cylinders,
((PCOWD_SECTOR_3)params[1])->Tracks,
((PCOWD_SECTOR_3)params[1])->Sectors,
((PCOWD_SECTOR_3)params[1])->DiskCapacity);
break;
// parent path length
// params[0]: PCHAR path
// params[1]: PCHAR parent_path
// return: TRUE correct
// FALSE abort
case VDISK_CB_COWD_PARENT:
PrintMessage(MSG_CB_COWD_PARENT,
(PCHAR)params[0], (PCHAR)params[1]);
break;
// Mapsize values in COWD header is inconsistent with capacity
// params[0]: PCHAR path
// params[2]: ULONG wrong value
// params[1]: ULONG correct value
// return: corrected map size
case VDISK_CB_COWD_MAPSIZE:
PrintMessage(MSG_CB_COWD_MAPSIZE,
(PCHAR)params[0], (ULONG)params[1], (ULONG)params[2]);
/*
if (InputChar(MSG_PROMPT_ABORTIGNORE, "ai") == 'i') {
ret = (ULONG)params[1];
}
*/
break;
// EndOfFile value does not match actual file size
// params[0]: PCHAR path
// params[2]: ULONG wrong value
// params[1]: ULONG correct value
// return: TRUE ignore
// FALSE fail
case VDISK_CB_COWD_ENDOFFILE:
PrintMessage(MSG_CB_COWD_ENDOFFILE,
(PCHAR)params[0], (ULONG)params[1], (ULONG)params[2]);
ret = TRUE;;
break;
// cowd_sec2->TimeStamp != cowd_sec3->TimeStamp
// params[0]: PCHAR path
// params[1]: ULONG timestamp1
// params[2]: ULONG timestamp2
// return: TRUE ignore
// FALSE fail
case VDISK_CB_COWD_TIMESTAMP:
PrintMessage(MSG_CB_COWD_TIMESTAMP,
(PCHAR)params[0], (ULONG)params[1], (ULONG)params[2]);
ret = (InputChar(MSG_PROMPT_ABORTIGNORE, "ai") == 'i');
break;
// VMDK descriptor is not found in the file
// params[0]: PCHAR path
// return: NONE
case VDISK_CB_VMDK_NODESC:
PrintMessage(MSG_CB_VMDK_NODESC, (PCHAR)params[0]);
break;
// Invalid vmdk version
// params[0]: PCHAR path
// params[1]: ULONG bad version
// return: correct version
case VDISK_CB_VMDK_FILEVER:
PrintMessage(MSG_CB_VMDK_FILEVER,
(PCHAR)params[0], (ULONG)params[1]);
ret = (InputChar(MSG_PROMPT_ABORTIGNORE, "ai") == 'i')
? VMDK_FILEVER_VMWARE4 : 0;
break;
// Invalid vmdk capacity
// params[0]: PCHAR path
// params[1]: PINT64 bad value
// return: TRUE ignore / corrected
// FALSE abort
case VDISK_CB_VMDK_FILECAP:
PrintMessage(MSG_CB_VMDK_FILECAP,
(PCHAR)params[0], I64PRM(params[1]));
break;
// Invalid vmdk granularity
// params[0]: PCHAR path
// params[1]: PINT64 bad value
// return: TRUE ignore / corrected
// FALSE abort
case VDISK_CB_VMDK_GRANULARITY:
PrintMessage(MSG_CB_VMDK_GRANULARITY,
(PCHAR)params[0], I64PRM(params[1]));
break;
// Invalid vmdk descriptor offset
// params[0]: PCHAR path
// params[1]: PINT64 bad value
// return: TRUE ignore / corrected
// FALSE abort
case VDISK_CB_VMDK_DESCOFFSET:
PrintMessage(MSG_CB_VMDK_DESCOFFSET,
(PCHAR)params[0], I64PRM(params[1]));
break;
// Invalid vmdk descriptor size
// params[0]: PCHAR path
// params[1]: PINT64 bad value
// return: TRUE ignore / corrected
// FALSE abort
case VDISK_CB_VMDK_DESCSIZE:
PrintMessage(MSG_CB_VMDK_DESCSIZE,
(PCHAR)params[0], I64PRM(params[1]));
break;
// Invalid vmdk GTEsPerGT value
// params[0]: PCHAR path
// params[1]: ULONG bad value
// return: TRUE ignore / corrected
// FALSE abort
case VDISK_CB_VMDK_GTESPERGT:
PrintMessage(MSG_CB_VMDK_GTESPERGT,
(PCHAR)params[0], (ULONG)params[1]);
break;
// Invalid vmdk grain dictionary offset
// params[0]: PCHAR path
// params[1]: PINT64 bad value
// return: TRUE ignore / corrected
// FALSE abort
case VDISK_CB_VMDK_GDOFFSET:
PrintMessage(MSG_CB_VMDK_GDOFFSET,
(PCHAR)params[0], I64PRM(params[1]));
break;
// Invalid vmdk grain offset
// params[0]: PCHAR path
// params[1]: PINT64 bad value
// return: TRUE ignore / corrected
// FALSE abort
case VDISK_CB_VMDK_GRAINOFFSET:
PrintMessage(MSG_CB_VMDK_GRAINOFFSET,
(PCHAR)params[0], I64PRM(params[1]));
break;
// Invalid vmdk check bytes
// params[0]: PCHAR path
// return: TRUE ignore / corrected
// FALSE abort
case VDISK_CB_VMDK_CHECKBYTES:
PrintMessage(MSG_CB_VMDK_CHECKBYTES, (PCHAR)params[0]);
ret = (InputChar(MSG_PROMPT_ABORTIGNORE, "ai") == 'i');
break;
// VMDK capacity in the header and descriptor mismatch
// params[0]: PCHAR path
// params[1]: ULONG size in the header
// params[2]: ULONG size in the descriptor
// return: TRUE ignore / corrected
// FALSE abort
case VDISK_CB_VMDK_SIZEMISMATCH:
PrintMessage(MSG_CB_VMDK_SIZEMISMATCH,
(PCHAR)params[0], (ULONG)params[1], (ULONG)params[2]);
ret = (InputChar(MSG_PROMPT_YESNO, "yn") == 'y');
break;
// Capacity of the child and the parent do not match
// params[0]: PCHAR child path
// params[1]: ULONG child capacity
// params[2]: PCHAR parent path
// params[3]: ULONG parent capacity
// return: NONE this is fatal
case VDISK_CB_PARENT_CAPACITY:
PrintMessage(MSG_CB_PARENT_CAPACITY,
(PCHAR)params[0], (ULONG)params[1],
(PCHAR)params[2], (ULONG)params[3]);
break;
// Controller type of the child and the parent do not match
// params[0]: PCHAR child path
// params[1]: ULONG child controller
// params[2]: PCHAR parent path
// params[3]: ULONG parent controller
// return: TRUE ignore / corrected
// FALSE abort
case VDISK_CB_PARENT_CONTROLLER:
PrintMessage(MSG_CB_PARENT_CONTROLLER,
(PCHAR)params[0], (ULONG)params[1] == VDISK_CONTROLLER_SCSI ? "SCSI" : "IDE",
(PCHAR)params[2], (ULONG)params[3] == VDISK_CONTROLLER_SCSI ? "SCSI" : "IDE");
ret = (InputChar(MSG_PROMPT_ABORTIGNORE, "ai") == 'i');
break;
// Child's ParentTS and Parent's Timestamp do not match
// params[0]: PCHAR child path
// params[1]: ULONG child ParentTS
// params[2]: PCHAR parent path
// params[3]: ULONG parent Timestamp
// return: TRUE ignore / corrected
// FALSE abort
case VDISK_CB_PARENT_TIMESTAMP:
PrintMessage(MSG_CB_PARENT_TIMESTAMP,
(PCHAR)params[0], (ULONG)params[1],
(PCHAR)params[2], (ULONG)params[3]);
ret = (InputChar(MSG_PROMPT_ABORTIGNORE, "ai") == 'i');
break;
default:
fprintf(stderr, "Unknown Callback reason %lu\n", reason);
break;
}
return ret;
}