@starkdm

C++ Каким образом я могу выполнить перезапись кластеров файла?

ULONGLONG *GetFileClusters(
	LPCWSTR lpFileName, //путь к файлу
	ULONG ClusterSize, //размер кластера (какое значение сюда передавать?)
	ULONG *ClCount, //???
	ULONG *FileSize //размер файла
	)
{
	HANDLE hFile; //дескриптор файла
	ULONG OutSize; //
	ULONG Bytes, Cls, CnCount, r; //???
	ULONGLONG *Clusters = NULL; //список кластеров
	BOOLEAN Result = FALSE;
	LARGE_INTEGER PrevVCN, Lcn; //???
	STARTING_VCN_INPUT_BUFFER InBuf; //???
	PRETRIEVAL_POINTERS_BUFFER OutBuf; //???
	//получение доступа к диску:
	hFile = CreateFile(lpFileName, FILE_READ_ATTRIBUTES,
		FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
		NULL, OPEN_EXISTING, 0, 0);
	//при успехе доступа:
	if (hFile != INVALID_HANDLE_VALUE)
	{
		//
		*FileSize = GetFileSize(hFile, NULL); //получение размера файла
		OutSize = sizeof(RETRIEVAL_POINTERS_BUFFER) + (*FileSize / ClusterSize) * sizeof(OutBuf->Extents);  //???
		//OutBuf = malloc(OutSize); //выделение памяти
		InBuf.StartingVcn.QuadPart = 0; //???
		if (DeviceIoControl(hFile, FSCTL_GET_RETRIEVAL_POINTERS, &InBuf,
			sizeof(InBuf), OutBuf, OutSize, &Bytes, NULL))
		{
			*ClCount = (*FileSize + ClusterSize - 1) / ClusterSize; //???
			//Clusters = malloc(*ClCount * sizeof(ULONGLONG));
			PrevVCN = OutBuf->StartingVcn; //???
			for (r = 0, Cls = 0; r < OutBuf->ExtentCount; r++)
			{
				Lcn = OutBuf->Extents[r].Lcn; //???
				for (CnCount = OutBuf->Extents[r].NextVcn.QuadPart - PrevVCN.QuadPart;
					CnCount; CnCount--, Cls++, Lcn.QuadPart++) Clusters[Cls] = Lcn.QuadPart;
					PrevVCN = OutBuf->Extents[r].NextVcn; //???
			}
		}
		//
		free(OutBuf); //???
		CloseHandle(hFile);
	}
	//вернуть список кластеров:
	return Clusters;
}

Выполняет поиск кластеров для данного файла. А остальные параметры функции зачем нужны?
Вместо lpFileName писать линейный адрес или обычный путь к файлу?
После получения списка что делать? Каким образом перезаписать кластеры?
  • Вопрос задан
  • 819 просмотров
Пригласить эксперта
Ответы на вопрос 1
@zedxxx
Ну, посмотрите как этот код вызывается и сделайте соответствующие выводы:
void FileCopy(
       PCHAR lpSrcName,
       PCHAR lpDstName
       )
{
   ULONG         ClusterSize, BlockSize;
   ULONGLONG    *Clusters;
   ULONG         ClCount, FileSize, Bytes;
   HANDLE        hDrive, hFile;
   ULONG         SecPerCl, BtPerSec, r;
   PVOID         Buff;
   LARGE_INTEGER Offset;
   CHAR          Name[7];

   Name[0] = lpSrcName[0];
   Name[1] = ":";
   Name[2] = 0;

   GetDiskFreeSpace(Name, &SecPerCl, &BtPerSec, NULL, NULL);

   ClusterSize = SecPerCl * BtPerSec;

   Clusters = GetFileClusters(lpSrcName, ClusterSize, &ClCount, &FileSize);

   if (Clusters)
   {
       Name[0] = "\\";
       Name[1] = "\\";
       Name[2] = ".";
       Name[3] = "\\";
       Name[4] = lpSrcName[0];
       Name[5] = ":";
       Name[6] = 0;

       hDrive = CreateFile(Name, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, 0);

       if (hDrive != INVALID_HANDLE_VALUE)
       {
           hFile = CreateFile(lpDstName, GENERIC_WRITE, 0, NULL, CREATE_NEW, 0, 0);

           if (hFile != INVALID_HANDLE_VALUE)
           {
               Buff = malloc(ClusterSize);

               for (r = 0; r < ClCount; r++, FileSize -= BlockSize)
               {
                   Offset.QuadPart = ClusterSize * Clusters[r];

                   SetFilePointer(hDrive, Offset.LowPart, &Offset.HighPart, FILE_BEGIN);

                   ReadFile(hDrive, Buff, ClusterSize, &Bytes, NULL);

                   BlockSize = FileSize < ClusterSize ? FileSize : ClusterSize;

                   WriteFile(hFile, Buff, BlockSize, &Bytes, NULL);
               }

               free(Buff);

               CloseHandle(hFile);
           }
           CloseHandle(hDrive);
       }
       free(Clusters);
   }
}

int main(int argc, char *argv[])
{
CHAR Name[MAX_PATH];

   GetSystemDirectory(Name, MAX_PATH);

   lstrcat(Name, "\\config\\SAM");

if (argc > 1)
{
 FileCopy(Name, argv[1]);
}
return 0;
}
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы