【发布时间】:2021-04-29 16:58:45
【问题描述】:
我正在尝试学习本教程:Defragmenting Files。
我在C: 卷的句柄上使用FSCTL_GET_VOLUME_BITMAP 调用DeviceIoControl(),我得到了正确的响应。
然后我成功打开另一个文件的句柄(我尝试了从 10KB 到几 MB 的文件),然后我用 FSCTL_GET_RETRIEVAL_POINTERS 调用 DeviceIoControl(),它成功了,没有最后一个错误或失败结果,但是 @987654327 @ 未填写。
我也尝试在C: 卷句柄上调用它,但即使尝试将OVERLAPPED 偏移量设置为0,并将带有SetFilePointer() 的文件指针设置为相对于文件的开头。
BOOL dic(HANDLE dev, DWORD code, LPVOID in, DWORD ins, LPVOID out, LPDWORD outs)
{
HANDLE h = GetProcessHeap();
DWORD s = 1000;
DWORD r = 0;
out = HeapAlloc(h,HEAP_ZERO_MEMORY,s);
while (!DeviceIoControl(dev, code, in, ins, out, s, &r, 0))
{
if (ERROR_INSUFFICIENT_BUFFER == GetLastError() || ERROR_MORE_DATA == GetLastError())
{
s *= 10;
LPVOID t = HeapReAlloc(h, HEAP_ZERO_MEMORY, out, s);
if(!t){
HeapFree(h, 0, out);
return 0;
}
out = t;
}
else
{
HeapFree(h, 0, out);
printf("dic unk: %d\n", GetLastError());
return 0;
}
}
*outs = s;
return 1;
}
BOOL getvolptr(HANDLE volh, PRETRIEVAL_POINTERS_BUFFER rpb, LPDWORD rpbs)
{
STARTING_VCN_INPUT_BUFFER vcn = { 0 };
return dic(volh, FSCTL_GET_RETRIEVAL_POINTERS, &vcn, sizeof(vcn), rpb, rpbs);
}
RETRIEVAL_POINTERS_BUFFER rpb = { 0 };
DWORD rpbs = 0;
ULONGLONG cluster_cnt=0;
HANDLE fi = openfile("C:\\Windows\\System32\\Kernel32.dll");
if (INVALID_HANDLE_VALUE == fi)
{
printf("failed to open file! (%d)\n", GetLastError());
getchar();
}
r = getvolptr(fi, &rpb, &rpbs);
if (!r)
{
printf("failed to get vol ptrs! (%d)\n", GetLastError());
getchar();
}
for (int i = 0; i < rpb.ExtentCount; ++i)
{
cluster_cnt = (ULONGLONG)(rpb.Extents[i].NextVcn.QuadPart) - (ULONGLONG)(rpb.StartingVcn.QuadPart);
printf("%d) size: %llu clusters (0x%016X)\n", i, cluster_cnt, rpb.Extents[i].Lcn.QuadPart);
}
【问题讨论】:
标签: c windows winapi filesystems fragmentation