S
S
starkdm2015-09-01 19:52:45
Programming
starkdm, 2015-09-01 19:52:45

C++ How can I overwrite the clusters of a file?

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;
}

Searches for clusters for the given file. What are the other parameters of the function for?
Instead of lpFileName, write a linear address or a regular file path?
After receiving the list, what should I do? How to overwrite clusters?

Answer the question

In order to leave comments, you need to log in

1 answer(s)
Z
zed, 2015-09-01
@zedxxx

Well, look at how this code is called and draw the appropriate conclusions:

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;
}

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question