Для начала, мне не даётся использование DeviceIoControl.
Говорит, что hFile неверный, хотя он не NULL. С какими атрибутами открывать?
ANDLE hFile = CreateFile(path,
GENERIC_READ,
0,
NULL,
OPEN_EXISTING,
0,
NULL);
RETRIEVAL_POINTERS_BUFFER rpb;
STARTING_VCN_INPUT_BUFFER startingVcn;
DWORD dwBytesReturned;
OVERLAPPED overlapped;
DWORD dwFragments = 0, dwTotalClusters = 0;
// ...
DeviceIoControl(hFile,
FSCTL_GET_REPARSE_POINT,
&startingVcn, sizeof startingVcn,
&rpb, sizeof rpb,
&dwBytesReturned, &overlapped);
// ... while(dwError == ERROR_MORE_DATA);
Далее алгоритм будет следующий:
Вызвать GetLastError и по коду ошибки определить дальнейшие действия.
Если это первая итерация и ERROR_HANDLE_EOF, значит файл резидентный, если не первая, то выход из цикла.
Если NO_ERROR, файл занимает 1 фрагмент кластеров (т.е. все по-порядку, а не в разброс по диску).
Если ERROR_MORE_DATA, есть ещё на диске фрагменты этого файла.
Таким образом, будем иметь список всех фрагментов файла на диске ввиде списка пар StartLCN-ClustersLength.
Так же, понятия не имею, что делать, если файл резидентный. Как вытащить его положение на диске?
Работать всё это должно под FAT, FAT32 и NTFS (с поддержкой SPARSE, COMPRESSED и ENCRYPTED файлов).
Нужно это положение для программы безопасного удаления данных, т.е. потом я полученные кластеры затру.
Ответ
HANDLE hFile = CreateFile(lpFilePath,
FILE_READ_EA,
FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
NULL,
OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS | FILE_FLAG_OPEN_REPARSE_POINT,
NULL);
if (hFile == INVALID_HANDLE_VALUE)
{
wcout << "Open file error: " << GetLastError() << endl;
system("pause");
return -1;
}
PSTARTING_VCN_INPUT_BUFFER startingVcn = new STARTING_VCN_INPUT_BUFFER();
PRETRIEVAL_POINTERS_BUFFER prpb = new RETRIEVAL_POINTERS_BUFFER();
DWORD dwBytesReturned = 0;
DWORD dwExtentNumber = 0, dwTotalClusters = 0;
DWORD dwError;
do
{
DeviceIoControl(hFile,
FSCTL_GET_RETRIEVAL_POINTERS,
startingVcn, sizeof *startingVcn,
prpb, sizeof *prpb,
&dwBytesReturned,
NULL);
dwError = GetLastError();
switch (dwError)
{
case ERROR_HANDLE_EOF:
if (dwExtentNumber == 0)
cout << "MFT Table..." << endl;
else
wcout << endl <<
"Total clusters: " << dwTotalClusters << endl <<
"Fragments: " << dwExtentNumber << endl;
break;
case NO_ERROR:
wcout << "Fragment 0:" << endl <<
"\tStart LCN: " << prpb->Extents->Lcn.QuadPart << endl <<
"\tClusters: " << prpb->Extents->NextVcn.QuadPart - prpb->StartingVcn.QuadPart << endl << endl;
wcout <<
"Total clusters: " << prpb->Extents->NextVcn.QuadPart - prpb->StartingVcn.QuadPart << endl <<
"Fragments: " << dwExtentNumber;
break;
case ERROR_MORE_DATA:
wcout << "Fragment " << dwExtentNumber << ":" << endl <<
"\tStart LCN: " << prpb->Extents->Lcn.QuadPart << endl <<
"\tClusters: " << prpb->Extents->NextVcn.QuadPart - prpb->StartingVcn.QuadPart << endl << endl;
dwTotalClusters += prpb->Extents->NextVcn.QuadPart - prpb->StartingVcn.QuadPart;
startingVcn->StartingVcn.QuadPart = prpb->Extents->NextVcn.QuadPart;
break;
default:
wcout << "DeviceIoControl error: " << dwError << endl;
system("pause");
return -1;
}
dwExtentNumber++;
} while (dwError == ERROR_MORE_DATA);
CloseHandle(hFile);
system("pause");
return 0;
Комментариев нет:
Отправить комментарий