我只是想将卷句柄的文件指针从FILE_END
向后移动。不幸的是,无论我传递给它任何输入值,操作都会失败!
我正在使用以下代码:
HANDLE vol_handle = CreateFile ("\\\\.\\C:",
GENERIC_READ | GENERIC_WRITE,
FILE_SHARE_READ | FILE_SHARE_WRITE,
NULL, OPEN_EXISTING, 0, NULL);
if (vol_handle == INVALID_HANDLE_VALUE)
{
printf("Failed to create volume handle!\n");
print_last_error(GetLastError());
return ERROR;
}
printf("Handle acquired for volume %s \n", VOLUME);
long int dist = 512000; // 500 KB forwards
SetLastError(0);
int result = SetFilePointer (vol_handle, dist, NULL, FILE_BEGIN);
if (result == INVALID_SET_FILE_POINTER)
{
printf("SetFilePointer (BEGIN) FAILED!\n");
print_last_error(GetLastError());
}
else
printf("SetFilePointer (BEGIN) SUCCESS!\n");
dist = -5120; // 50 KB backwards
SetLastError(0);
result = SetFilePointer (vol_handle, dist, NULL, FILE_END);
if (result == INVALID_SET_FILE_POINTER)
{
printf("SetFilePointer (END) FAILED!\n");
print_last_error(GetLastError());
}
else
printf("SetFilePointer (END) SUCCESS!\n");
SetLastError(0);
result = SetFilePointer (vol_handle, dist, NULL, FILE_CURRENT);
if (result == INVALID_SET_FILE_POINTER)
{
printf("SetFilePointer (CURRENT) FAILED!\n", offset_low_part);
print_last_error(GetLastError());
}
else
printf("SetFilePointer (CURRENT) SUCCESS!\n");
输出:
Handle acquired for volume \\.\C: SetFilePointer (BEGIN) SUCCESS! SetFilePointer (END) FAILED! Error 0x57: The parameter is incorrect. SetFilePointer (CURRENT) SUCCESS!
As you can see, the seek works fine for FILE_BEGIN
and FILE_CURRENT
, but it always fails for FILE_END
with error code 0x57
(87 in decimal) saying:
The parameter is incorrect
Note that changing dist
to a positive value doesn't change the situation.
What am I missing here?
( NOTE: Testing on Windows-5.1.2600 (XP SP3) in latest Code::Blocks IDE 16.01 with MinGW compiler, and Administrator privileges )
NOTE: This is absolutely not a duplicate of this question, since I am not accessing physical disk (volume access is different from physical disk) and the distance value is a multiple of 512 bytes (the logical sector size). If the distance length was incorrect, then the other seeks (BEGIN and CURRENT) would have failed as well, yet they don't.
Update
Based on Rohans' answer, I performed another check with the following code:
long long int offset_64 = 5120000 // 5000 KB distance;
long int offset_low_part = -(0xffffffff & offset_64);
long int offset_hig_part = offset_64 >> 32;
printf("offset_64 = %lld\n", offset_64);
printf("low_part = %ld\n", offset_low_part);
printf("high_part = %ld\n\n", offset_hig_part);
// Get volume handle using CreateFile(...) exactly as before;
SetLastError(0);
int result = SetFilePointer (vol_handle, offset_low_part, &offset_hig_part, FILE_END);
if (result == INVALID_SET_FILE_POINTER)
{
print_last_error(GetLastError());
printf("Failed to set file pointer!\n");
printf("high_part after SetFilePointer = %ld\n", offset_hig_part);
return ERROR;
}
尽管我相信Rohans的观点很重要,但仍然不能解决问题:
offset_64 = 5120000
low_part = -5120000
high_part = 0
Handle acquired for volume \\.\C:
Error 0x57: The parameter is incorrect.
Failed to set file pointer!
high_part after SetFilePointer = 0
为
low_part
使用正值不会改变这种情况。更新资料
基于下面的David Heffernan的评论,我承认使用
SetFilePointerEx
可以使此代码更短,更容易,但是结果仍然相同,并且该操作无法在卷句柄上从FILE_END
进行查找。 最佳答案
这不足为奇。卷不是文件,因此它没有文件结尾位置。
Windows当然可以将卷长度用作文件位置的末尾,但是没有特殊的理由要求它处理这种特殊情况。
您将必须自己计算偏移量。