Feng Yuning <fengyuning1984@gmail.com>:

- Fix ntfs reading problem (occurs when trying to load Windows from an NTFS partition, reading always failed).

svn path=/trunk/; revision=28364
This commit is contained in:
Aleksey Bragin 2007-08-15 20:04:50 +00:00
parent 85c976b666
commit 0364357251

View file

@ -195,7 +195,9 @@ static ULONGLONG NtfsReadAttribute(PNTFS_ATTR_CONTEXT Context, ULONGLONG Offset,
* I. Find the corresponding start data run.
*/
if (Context->CacheRunOffset == Offset)
AlreadyRead = 0;
if(Context->CacheRunOffset <= Offset && Offset < Context->CacheRunOffset + Context->CacheRunLength * NtfsClusterSize)
{
DataRun = Context->CacheRun;
LastLCN = Context->CacheRunLastLCN;
@ -232,7 +234,7 @@ static ULONGLONG NtfsReadAttribute(PNTFS_ATTR_CONTEXT Context, ULONGLONG Offset,
if (*DataRun == 0)
{
return 0;
return AlreadyRead;
}
CurrentOffset += DataRunLength * NtfsClusterSize;
@ -243,42 +245,69 @@ static ULONGLONG NtfsReadAttribute(PNTFS_ATTR_CONTEXT Context, ULONGLONG Offset,
* II. Go through the run list and read the data
*/
AlreadyRead = 0;
while (Length > 0)
ReadLength = min(DataRunLength * NtfsClusterSize - (Offset - CurrentOffset), Length);
if (DataRunStartLCN == -1)
RtlZeroMemory(Buffer, ReadLength);
if (NtfsDiskRead(DataRunStartLCN * NtfsClusterSize + Offset - CurrentOffset, ReadLength, Buffer))
{
ReadLength = min(DataRunLength * NtfsClusterSize, Length);
if (DataRunStartLCN == -1)
RtlZeroMemory(Buffer, ReadLength);
else if (!NtfsDiskRead(DataRunStartLCN * NtfsClusterSize + Offset - CurrentOffset, ReadLength, Buffer))
break;
Length -= ReadLength;
Buffer += ReadLength;
AlreadyRead += ReadLength;
Length -= ReadLength;
Buffer += ReadLength;
AlreadyRead += ReadLength;
/* We finished this request, but there still data in this data run. */
if (Length == 0 && ReadLength != DataRunLength * NtfsClusterSize)
break;
/*
* Go to next run in the list.
*/
if (*DataRun == 0)
break;
DataRun = NtfsDecodeRun(DataRun, &DataRunOffset, &DataRunLength);
if (DataRunOffset != -1)
if (ReadLength == DataRunLength * NtfsClusterSize - (Offset - CurrentOffset))
{
/* Normal data run. */
DataRunStartLCN = LastLCN + DataRunOffset;
LastLCN = DataRunStartLCN;
CurrentOffset += DataRunLength * NtfsClusterSize;
DataRun = NtfsDecodeRun(DataRun, &DataRunOffset, &DataRunLength);
if (DataRunLength != -1)
{
DataRunStartLCN = LastLCN + DataRunOffset;
LastLCN = DataRunStartLCN;
}
else
DataRunStartLCN = -1;
if (*DataRun == 0)
return AlreadyRead;
}
else
while (Length > 0)
{
/* Sparse data run. */
DataRunStartLCN = -1;
}
CurrentOffset += DataRunLength * NtfsClusterSize;
}
ReadLength = min(DataRunLength * NtfsClusterSize, Length);
if (DataRunStartLCN == -1)
RtlZeroMemory(Buffer, ReadLength);
else if (!NtfsDiskRead(DataRunStartLCN * NtfsClusterSize, ReadLength, Buffer))
break;
Length -= ReadLength;
Buffer += ReadLength;
AlreadyRead += ReadLength;
/* We finished this request, but there still data in this data run. */
if (Length == 0 && ReadLength != DataRunLength * NtfsClusterSize)
break;
/*
* Go to next run in the list.
*/
if (*DataRun == 0)
break;
CurrentOffset += DataRunLength * NtfsClusterSize;
DataRun = NtfsDecodeRun(DataRun, &DataRunOffset, &DataRunLength);
if (DataRunOffset != -1)
{
/* Normal data run. */
DataRunStartLCN = LastLCN + DataRunOffset;
LastLCN = DataRunStartLCN;
}
else
{
/* Sparse data run. */
DataRunStartLCN = -1;
}
} /* while */
} /* if Disk */
Context->CacheRun = DataRun;
Context->CacheRunOffset = Offset + AlreadyRead;