发现isomaster-1.3.7有两个bug
1.在windows用ultraiso编辑过的iso文件用isomaster打开有些文件看不见(在windows中新增的文件)
2.有些non-emulation的可引导iso文件的引导记录无法用另存为保存
原因:
1.windows中编辑时的新增文件的文件属性字节(posixFileMode)为0xffff8124,而linux下的一般为0x8124
2.引导文件存在另外一个链接文件(该文件的posixFileMod为0xa1ff,文件大小为0)
修改方法:
1.修改bk/bk.h文件的79-81行:
原代码:
#define IS_DIR(posix) ((posix & 0770000) == 0040000)
#define IS_REG_FILE(posix) ((posix & 0770000) == 0100000)
#define IS_SYMLINK(posix) ((posix & 0770000) == 0120000)
修改为:
#define IS_DIR(posix) ((posix & 0170000) == 0040000)
#define IS_REG_FILE(posix) ((posix & 0170000) == 0100000)
#define IS_SYMLINK(posix) ((posix & 0170000) == 0120000)
2.修改bk/bkRead.c文件的readFileInfo函数:
原代码:
int readFileInfo(VolInfo* volInfo, BkFile* file, int filenameType,
bool keepPosixPermissions, BkFileBase** specialFile)
{
int rc;
unsigned char recordLength;
unsigned locExtent; /* block num where the file is */
unsigned lenExtent; /* in bytes */
unsigned char lenFileId9660; /* also len joliet fileid (bytes) */
int lenSU; /* calculated as recordLength - 33 - lenFileId9660 */
bk_off_t posBeforeName;
char nameAsOnDisk[UCHAR_MAX + 1];
/* so if anything failes it's still safe to delete file */
file->pathAndName = NULL;
if(volInfo->stopOperation)
return BKERROR_OPER_CANCELED_BY_USER;
maybeUpdateProgress(volInfo);
*specialFile = NULL;
rc = readRead(volInfo, &recordLength, 1);
if(rc != 1)
return BKERROR_READ_GENERIC;
readSeekSet(volInfo, 1, SEEK_CUR);
rc = read733(volInfo, &locExtent);
if(rc != 8)
return BKERROR_READ_GENERIC;
rc = read733(volInfo, &lenExtent);
if(rc != 8)
return BKERROR_READ_GENERIC;
/* The length of isolinux.bin given in the initial/default entry of
* the el torito boot catalog does not match the actual length of the file
* but apparently when executed by the bios that's not a problem.
* However, if i ever want to read that file myself, i need
* the length proper.
* So i'm looking for a file that starts in the same logical sector as the
* boot record from the initial/default entry. */
if(volInfo->bootMediaType == BOOT_MEDIA_NO_EMULATION &&
locExtent == volInfo->bootRecordOffset / NBYTES_LOGICAL_BLOCK)
{
volInfo->bootRecordSize = lenExtent;
volInfo->bootRecordIsVisible = true;
volInfo->bootRecordOnImage = file;
}
readSeekSet(volInfo, 14, SEEK_CUR);
rc = readRead(volInfo, &lenFileId9660, 1);
if(rc != 1)
return BKERROR_READ_GENERIC;
lenSU = recordLength - 33 - lenFileId9660;
if(lenFileId9660 % 2 == 0)
lenSU -= 1;
/* READ 9660 name */
posBeforeName = readSeekTell(volInfo);
rc = readRead(volInfo, nameAsOnDisk, lenFileId9660);
if(rc != lenFileId9660)
return BKERROR_READ_GENERIC;
nameAsOnDisk[lenFileId9660] = '\0';
/* record 9660 name for writing later */
strncpy(BK_BASE_PTR(file)->original9660name, nameAsOnDisk, 14);
BK_BASE_PTR(file)->original9660name[14] = '\0';
removeCrapFromFilename(nameAsOnDisk, lenFileId9660);
strncpy(BK_BASE_PTR(file)->name, nameAsOnDisk, NCHARS_FILE_ID_MAX_STORE - 1);
BK_BASE_PTR(file)->name[NCHARS_FILE_ID_MAX_STORE - 1] = '\0';
/* padding field */
if(lenFileId9660 % 2 == 0)
readSeekSet(volInfo, 1, SEEK_CUR);
if(filenameType != FNTYPE_9660)
readSeekSet(volInfo, posBeforeName, SEEK_SET);
/* END READ 9660 name */
if(filenameType == FNTYPE_JOLIET)
{
char nameAsOnDisk[UCHAR_MAX];
/* in the worst possible case i'll use 129 bytes for this: */
char nameInAscii[UCHAR_MAX];
int ucsCount, byteCount;
if(lenFileId9660 % 2 != 0)
return BKERROR_INVALID_UCS2;
rc = readRead(volInfo, nameAsOnDisk, lenFileId9660);
if(rc != lenFileId9660)
return BKERROR_READ_GENERIC;
for(ucsCount = 1, byteCount = 0; ucsCount < lenFileId9660;
ucsCount += 2, byteCount += 1)
{
nameInAscii[byteCount] = nameAsOnDisk[ucsCount];
}
removeCrapFromFilename(nameInAscii, lenFileId9660 / 2);
if( strlen(nameInAscii) > NCHARS_FILE_ID_MAX_STORE - 1 )
return BKERROR_MAX_NAME_LENGTH_EXCEEDED;
strncpy(BK_BASE_PTR(file)->name, nameInAscii, NCHARS_FILE_ID_MAX_STORE - 1);
BK_BASE_PTR(file)->name[NCHARS_FILE_ID_MAX_STORE - 1] = '\0';
/* padding field */
if(lenFileId9660 % 2 == 0)
readSeekSet(volInfo, 1, SEEK_CUR);
}
else if(filenameType == FNTYPE_ROCKRIDGE)
{
/* skip 9660 filename */
readSeekSet(volInfo, lenFileId9660, SEEK_CUR);
/* skip padding field */
if(lenFileId9660 % 2 == 0)
readSeekSet(volInfo, 1, SEEK_CUR);
rc = readRockridgeFilename(volInfo, BK_BASE_PTR(file)->name, lenSU, 0);
if(rc < 0)
return rc;
}
else if(filenameType != FNTYPE_9660)
return BKERROR_UNKNOWN_FILENAME_TYPE;
if(keepPosixPermissions)
{
rc = readPosixFileMode(volInfo, &(BK_BASE_PTR(file)->posixFileMode), lenSU);
if(rc < 0)
return rc;
}
else
{
BK_BASE_PTR(file)->posixFileMode = volInfo->posixFileDefaults;
}
//~ printf("'%s' %X\n", BK_BASE_PTR(file)->name, BK_BASE_PTR(file)->posixFileMode);
rc = readRockridgeSymlink(volInfo, (BkSymLink**)specialFile, lenSU);
if(rc < 0)
return rc;
if(*specialFile != NULL)
/* the file is actually a symbolic link */
{
strcpy((*specialFile)->name, BK_BASE_PTR(file)->name);
strcpy((*specialFile)->original9660name, BK_BASE_PTR(file)->original9660name);
/* apparently permissions for symbolic links are never used */
(*specialFile)->posixFileMode = 0120777;
}
if(volInfo->scanForDuplicateFiles)
{
BkHardLink* newLink;
rc = findInHardLinkTable(volInfo, locExtent * NBYTES_LOGICAL_BLOCK, NULL,
lenExtent, true, &newLink);
if(rc < 0)
return rc;
if(newLink == NULL)
/* not found */
{
rc = addToHardLinkTable(volInfo, locExtent * NBYTES_LOGICAL_BLOCK,
NULL, lenExtent, true, &newLink);
if(rc < 0)
return rc;
}
file->location = newLink;
}
readSeekSet(volInfo, lenSU, SEEK_CUR);
file->onImage = true;
file->position = ((bk_off_t)locExtent) * ((bk_off_t)NBYTES_LOGICAL_BLOCK);
file->size = lenExtent;
return recordLength;
}
修改为:
int readFileInfo(VolInfo* volInfo, BkFile* file, int filenameType,
bool keepPosixPermissions, BkFileBase** specialFile)
{
int rc;
unsigned char recordLength;
unsigned locExtent; /* block num where the file is */
unsigned lenExtent; /* in bytes */
unsigned char lenFileId9660; /* also len joliet fileid (bytes) */
int lenSU; /* calculated as recordLength - 33 - lenFileId9660 */
bk_off_t posBeforeName;
char nameAsOnDisk[UCHAR_MAX + 1];
/* so if anything failes it's still safe to delete file */
file->pathAndName = NULL;
if(volInfo->stopOperation)
return BKERROR_OPER_CANCELED_BY_USER;
maybeUpdateProgress(volInfo);
*specialFile = NULL;
rc = readRead(volInfo, &recordLength, 1);
if(rc != 1)
return BKERROR_READ_GENERIC;
readSeekSet(volInfo, 1, SEEK_CUR);
rc = read733(volInfo, &locExtent);
if(rc != 8)
return BKERROR_READ_GENERIC;
rc = read733(volInfo, &lenExtent);
if(rc != 8)
return BKERROR_READ_GENERIC;
/* The length of isolinux.bin given in the initial/default entry of
* the el torito boot catalog does not match the actual length of the file
* but apparently when executed by the bios that's not a problem.
* However, if i ever want to read that file myself, i need
* the length proper.
* So i'm looking for a file that starts in the same logical sector as the
* boot record from the initial/default entry. */
readSeekSet(volInfo, 14, SEEK_CUR);
rc = readRead(volInfo, &lenFileId9660, 1);
if(rc != 1)
return BKERROR_READ_GENERIC;
lenSU = recordLength - 33 - lenFileId9660;
if(lenFileId9660 % 2 == 0)
lenSU -= 1;
/* READ 9660 name */
posBeforeName = readSeekTell(volInfo);
rc = readRead(volInfo, nameAsOnDisk, lenFileId9660);
if(rc != lenFileId9660)
return BKERROR_READ_GENERIC;
nameAsOnDisk[lenFileId9660] = '\0';
/* record 9660 name for writing later */
strncpy(BK_BASE_PTR(file)->original9660name, nameAsOnDisk, 14);
BK_BASE_PTR(file)->original9660name[14] = '\0';
removeCrapFromFilename(nameAsOnDisk, lenFileId9660);
strncpy(BK_BASE_PTR(file)->name, nameAsOnDisk, NCHARS_FILE_ID_MAX_STORE - 1);
BK_BASE_PTR(file)->name[NCHARS_FILE_ID_MAX_STORE - 1] = '\0';
/* padding field */
if(lenFileId9660 % 2 == 0)
readSeekSet(volInfo, 1, SEEK_CUR);
if(filenameType != FNTYPE_9660)
readSeekSet(volInfo, posBeforeName, SEEK_SET);
/* END READ 9660 name */
if(filenameType == FNTYPE_JOLIET)
{
char nameAsOnDisk[UCHAR_MAX];
/* in the worst possible case i'll use 129 bytes for this: */
char nameInAscii[UCHAR_MAX];
int ucsCount, byteCount;
if(lenFileId9660 % 2 != 0)
return BKERROR_INVALID_UCS2;
rc = readRead(volInfo, nameAsOnDisk, lenFileId9660);
if(rc != lenFileId9660)
return BKERROR_READ_GENERIC;
for(ucsCount = 1, byteCount = 0; ucsCount < lenFileId9660;
ucsCount += 2, byteCount += 1)
{
nameInAscii[byteCount] = nameAsOnDisk[ucsCount];
}
removeCrapFromFilename(nameInAscii, lenFileId9660 / 2);
if( strlen(nameInAscii) > NCHARS_FILE_ID_MAX_STORE - 1 )
return BKERROR_MAX_NAME_LENGTH_EXCEEDED;
strncpy(BK_BASE_PTR(file)->name, nameInAscii, NCHARS_FILE_ID_MAX_STORE - 1);
BK_BASE_PTR(file)->name[NCHARS_FILE_ID_MAX_STORE - 1] = '\0';
/* padding field */
if(lenFileId9660 % 2 == 0)
readSeekSet(volInfo, 1, SEEK_CUR);
}
else if(filenameType == FNTYPE_ROCKRIDGE)
{
/* skip 9660 filename */
readSeekSet(volInfo, lenFileId9660, SEEK_CUR);
/* skip padding field */
if(lenFileId9660 % 2 == 0)
readSeekSet(volInfo, 1, SEEK_CUR);
rc = readRockridgeFilename(volInfo, BK_BASE_PTR(file)->name, lenSU, 0);
if(rc < 0)
return rc;
}
else if(filenameType != FNTYPE_9660)
return BKERROR_UNKNOWN_FILENAME_TYPE;
if(keepPosixPermissions)
{
rc = readPosixFileMode(volInfo, &(BK_BASE_PTR(file)->posixFileMode), lenSU);
if(rc < 0)
return rc;
}
else
{
BK_BASE_PTR(file)->posixFileMode = volInfo->posixFileDefaults;
}
//~ printf("'%s' %X\n", BK_BASE_PTR(file)->name, BK_BASE_PTR(file)->posixFileMode);
rc = readRockridgeSymlink(volInfo, (BkSymLink**)specialFile, lenSU);
if(rc < 0)
return rc;
if(*specialFile != NULL)
/* the file is actually a symbolic link */
{
strcpy((*specialFile)->name, BK_BASE_PTR(file)->name);
strcpy((*specialFile)->original9660name, BK_BASE_PTR(file)->original9660name);
/* apparently permissions for symbolic links are never used */
(*specialFile)->posixFileMode = 0120777;
}
if(volInfo->scanForDuplicateFiles)
{
BkHardLink* newLink;
rc = findInHardLinkTable(volInfo, locExtent * NBYTES_LOGICAL_BLOCK, NULL,
lenExtent, true, &newLink);
if(rc < 0)
return rc;
if(newLink == NULL)
/* not found */
{
rc = addToHardLinkTable(volInfo, locExtent * NBYTES_LOGICAL_BLOCK,
NULL, lenExtent, true, &newLink);
if(rc < 0)
return rc;
}
file->location = newLink;
}
readSeekSet(volInfo, lenSU, SEEK_CUR);
file->onImage = true;
file->position = ((bk_off_t)locExtent) * ((bk_off_t)NBYTES_LOGICAL_BLOCK);
file->size = lenExtent;
if(volInfo->bootMediaType == BOOT_MEDIA_NO_EMULATION &&
locExtent == volInfo->bootRecordOffset / NBYTES_LOGICAL_BLOCK
&& IS_REG_FILE(BK_BASE_PTR(file)->posixFileMode))
{
volInfo->bootRecordSize = lenExtent;
volInfo->bootRecordIsVisible = true;
volInfo->bootRecordOnImage = file;
}
return recordLength;
}
阅读(1191) | 评论(0) | 转发(0) |