#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;
Комментариев нет:
Отправить комментарий