Делал так как пишет мсдн
откуда брать параметры для FSCTL_MOVE_FILE
int GetClusters(const char* name,bool d)
{
MOVE_FILE_DATA MoveParams;
ULONG ClCount;
LARGE_INTEGER FileSize;
HANDLE hFile;
ULONG OutSize;
ULONG Bytes,CnCount;
LARGE_INTEGER PrevVCN, Lcn;
STARTING_VCN_INPUT_BUFFER InBuf;
PRETRIEVAL_POINTERS_BUFFER OutBuf;
int next=1;
MOVE_FILE_DATA md;
hFile = CreateFile(name,FILE_READ_ATTRIBUTES,
FILE_READ_DATA| FILE_WRITE_DATA| FILE_APPEND_DATA,
NULL, OPEN_EXISTING, 0, 0);
char namef[MAX_PATH];
sprintf(namef,"\\\\.\\%c:",name[0]);
HANDLE hDisk = CreateFile(namef,FILE_READ_ATTRIBUTES,
FILE_READ_DATA| FILE_WRITE_DATA| FILE_APPEND_DATA,
NULL, OPEN_EXISTING, 0, 0);
MoveParams.FileHandle = hFile;
if (hFile != INVALID_HANDLE_VALUE)
{
GetFileSizeEx(hFile, &FileSize);
OutSize = (ULONG)sizeof(RETRIEVAL_POINTERS_BUFFER) + (FileSize.QuadPart / ClusterSize) * sizeof(OutBuf->Extents);
OutBuf = (PRETRIEVAL_POINTERS_BUFFER)malloc(OutSize);
InBuf.StartingVcn.QuadPart = 0;
MoveParams.StartingLcn.QuadPart = 0;
if (DeviceIoControl(hFile, FSCTL_GET_RETRIEVAL_POINTERS, &InBuf,sizeof(InBuf), OutBuf, OutSize, &Bytes, NULL))
{
ClCount = (FileSize.QuadPart + ClusterSize - 1) / ClusterSize;
LONGLONG prev_num=0;
MoveParams.ClusterCount = ClCount;
PrevVCN = OutBuf->StartingVcn;
MoveParams.StartingVcn.QuadPart = PrevVCN.QuadPart;
ULONG r = 0, Cls = 0, all;
bool first=0;
for (; r < OutBuf->ExtentCount; r++)
{
Lcn = OutBuf->Extents[r].Lcn ;
for (CnCount=OutBuf->Extents[r].NextVcn.QuadPart - PrevVCN.QuadPart; CnCount; CnCount--, Cls++, Lcn.QuadPart++)
{
if(prev_num+1!=Lcn.QuadPart&&first)
next++;
prev_num=Lcn.QuadPart;
first=1;
DWORD br;
if(d)
{
if(!DeviceIoControl(hDisk,FSCTL_MOVE_FILE,&MoveParams,sizeof(MoveParams),NULL,0,&br,NULL))
printf("error %d\n",GetLastError());
}
}
PrevVCN = OutBuf->Extents[r].NextVcn;
}
}
free(OutBuf);
CloseHandle(hFile);
}
else
printf("Error opening file %s\n",name);
if(next!=1)
{
if(!d)
{
frag_files.push_back(name);
}
}
return next;
}
/////////////////////////////////////////
bool GetBitmap (void)
{
HANDLE Handle = CreateFile("\\\\.\\f:",
MAXIMUM_ALLOWED, // access
FILE_SHARE_READ | FILE_SHARE_WRITE, // share type
NULL, // security descriptor
OPEN_EXISTING, // open type
NULL, // attributes (none)
NULL // template
);
STARTING_LCN_INPUT_BUFFER StartingLCN;
VOLUME_BITMAP_BUFFER *Bitmap = NULL;
int BitmapSize;
DWORD BytesReturned;
BOOL Result;
StartingLCN.StartingLcn.QuadPart = 0;
// Allocate buffer
// Call FSCTL_GET_VOLUME_BITMAP once with a very small buffer
// This will leave the total number of clusters in Bitmap->BitmapSize and we can
// then correctly allocate based off that
// I suppose this won't work if your drive has only 40 clusters on it or so :)
BitmapSize = sizeof (VOLUME_BITMAP_BUFFER) + 4;
Bitmap = (VOLUME_BITMAP_BUFFER *) malloc (BitmapSize);
Result = DeviceIoControl
(
Handle,
FSCTL_GET_VOLUME_BITMAP,
&StartingLCN,
sizeof (StartingLCN),
Bitmap,
BitmapSize,
&BytesReturned,
NULL
);
// Bad result?
if (Result == FALSE && GetLastError () != ERROR_MORE_DATA)
{
//wprintf ("\nDeviceIoControl returned false, GetLastError() was not ERROR_MORE_DATA\n");
free (Bitmap);
return (false);
}
// Otherwise, we're good
BitmapSize = sizeof (VOLUME_BITMAP_BUFFER) + (Bitmap->BitmapSize.QuadPart / 8) + 1;
Bitmap = (VOLUME_BITMAP_BUFFER *) realloc (Bitmap, BitmapSize);
Result = DeviceIoControl
(
Handle,
FSCTL_GET_VOLUME_BITMAP,
&StartingLCN,
sizeof (StartingLCN),
Bitmap,
BitmapSize,
&BytesReturned,
NULL
);
DWORD LastError = GetLastError ();
if (Result == FALSE)
{
wprintf (L"\nCouldn't properly read volume bitmap\n");
free (Bitmap);
return (false);
}
free (Bitmap);
return (true);
}
11.08.12 23:33: Перенесено модератором из 'C/C++' — Кодт