2008年(787)
分类:
2008-09-25 16:06:04
安装以后,一扫描到ntfs分区就立马崩溃,报告出现了段错误。我只好对qtparted进行跟踪调试,最后把错误定位到了qp_fswrap.cpp中的QP_FSNtfs::_get_label()。关键代码如下,这个函数的作用是获取ntfs分区的卷标。
do
{
// szData points to the beginning of an attribute
dwAttribType = NTFS_GETU32(cData);
dwAttribLen = NTFS_GETU32(cData+4);
bAttribResident = (NTFS_GETU8(cData+8)==0);
if(dwAttribType == 0x60) // "volume_name"
{
if (bAttribResident == false)
{
//printf("readVolumeLabel(): failed: $volume_name attribute is not residentn");
return QString::null;
}
nAttrSize = NTFS_GETU16(cData+0x10);
cDataResident = cData+NTFS_GETU16(cData+0x14);
for (i=0; i < (DWORD)(nAttrSize/2); i++)
label[i] = cDataResident[2*i];
}
/*if(dwAttribType == 0x70) // "volume_information"
{
int nNtfsVersion = 0;
if (bAttribResident == true)
{
nAttrSize = NTFS_GETU16(cData+0x10);
cDataResident = cData+NTFS_GETU16(cData+0x14);
nNtfsVersion = (((BYTE) cDataResident[8]) << 8) | ((BYTE) cDataResident[9]);
printf("readVolumeLabel(): version is %d.%dn", cDataResident[8], cDataResident[9]);
}
}*/
cData += dwAttribLen;
} while(dwAttribType != (DWORD)-1); // attribute list ends with type -1
跟踪时发现,dwAttribType=-1永远不可能发生,其结果就是cData无限制的增长下去直到发生越界,于是段错误就发生了。
从整个函数看来,只要这段代码中的那个for循环已经执行,卷标即以获得,整个函数可以返回了,因此我添加了那行粗体的代码,这样段错误就不会发生。不知作者为什么没有那么做,但是从那段注释掉的代码看来,也许作者本来是想让这个函数做更多事情的。
不知道为什么在Everest 0.2中没这个问题,也许跟内核有关,也许跟这个版本新引入的ntfs-3g有关,但有一点可以肯定,新版本的Everest对ntfs分区做了某种处理,dwAttribType的取值发生了变化。