#cpp #winapi #файловая_система
Для начала, мне не даётся использование 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 файлов).
Нужно это положение для программы безопасного удаления данных, т.е. потом я полученные
кластеры затру.
Ответы
Ответ 1
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;
Комментариев нет:
Отправить комментарий