FSCTL_MOVE_FILE control code

Relocates one or more virtual clusters of a file from one logical cluster to another within the same volume. This operation is used during defragmentation.

To perform this operation, call the DeviceIoControl function with the following parameters.

DeviceIoControl( (HANDLE)       hDevice,         // handle to volume
                 (DWORD)        FSCTL_MOVE_FILE, // dwIoControlCode
                 (LPVOID)       lpInBuffer,      // MOVE_FILE_DATA structure
                 (DWORD)        nInBufferSize,   // size of input buffer
                 (LPVOID)       NULL,            // lpOutBuffer
                 (DWORD)        0,               // nOutBufferSize
                 (LPDWORD)      lpBytesReturned, // number of bytes returned
                 (LPOVERLAPPED) lpOverlapped );  // OVERLAPPED structure



A handle to the volume that contains the file or directory whose clusters are to be moved. To retrieve a device handle, call the CreateFile function. Only administrators can open volume handles.

Encrypted files must be opened with the FILE_READ_DATA, FILE_WRITE_DATA, FILE_APPEND_DATA, or FILE_EXECUTE access right. Other files need only be opened with the FILE_READ_ATTRIBUTES access right. For more information, see File Security and Access Rights.

Note  NTFS does not require that hDevice be a handle to the volume, only that it be a handle to a file or directory on the volume.

The control code for the operation. Use FSCTL_MOVE_FILE for this operation.


A pointer to the input buffer, a MOVE_FILE_DATA structure.


The size of the input buffer, in bytes.


Not used with this operation; set to NULL.


Not used with this operation; set to zero (0).


A pointer to a variable that receives the size of the data stored in the output buffer, in bytes.

If lpOverlapped is NULL, lpBytesReturned cannot be NULL. Even when an operation returns no output data and lpOutBuffer is NULL, DeviceIoControl makes use of lpBytesReturned. After such an operation, the value of lpBytesReturned is meaningless.

If lpOverlapped is not NULL, lpBytesReturned can be NULL. If this parameter is not NULL and the operation returns data, lpBytesReturned is meaningless until the overlapped operation has completed. To retrieve the number of bytes returned, call GetOverlappedResult. If hDevice is associated with an I/O completion port, you can retrieve the number of bytes returned by calling GetQueuedCompletionStatus.


A pointer to an OVERLAPPED structure.

If hDevice was opened without specifying FILE_FLAG_OVERLAPPED, lpOverlapped is ignored.

If hDevice was opened with the FILE_FLAG_OVERLAPPED flag, the operation is performed as an overlapped (asynchronous) operation. In this case, lpOverlapped must point to a valid OVERLAPPED structure that contains a handle to an event object. Otherwise, the function fails in unpredictable ways.

For overlapped operations, DeviceIoControl returns immediately, and the event object is signaled when the operation has been completed. Otherwise, the function does not return until the operation has been completed or an error occurs.

Return value

If the operation completes successfully, DeviceIoControl returns a nonzero value.

If the operation fails or is pending, DeviceIoControl returns zero. To get extended error information, call GetLastError. The possible return values for GetLastError include the following values.

Return codeDescription

One or more of the following:

  • One or more of the logical clusters to which the file's virtual clusters are to be moved is an allocated cluster.
  • The handle used for the IOCTL is not a DASD (volume) handle.
  • The FileHandle member passed in the MOVE_FILE_DATA structure is not on the same volume as the volume handle specified in hDevice.
  • The FileHandle member of the MOVE_FILE_DATA structure was for a paging file, change journal, or a file type other than a file, directory, or view index.
  • The StartingVcn, StartingLcn, or ClusterCount member of the MOVE_FILE_DATA structure contains an invalid value.
  • The FileHandle member is to an encrypted file, but the handle does not have FILE_READ_DATA, FILE_WRITE_DATA, FILE_APPEND_DATA, or FILE_EXECUTE. This means that there is no security context for moving the data between cache and disk, so the operation cannot be completed.

One or more of the logical clusters to which the file's virtual clusters are to be moved is an allocated cluster.

Note  As previously stated, some file systems may return ERROR_INVALID_PARAMETER when this error condition occurs.

This is an NTFS file system volume and the input buffer was smaller than sizeof(MOVE_FILE_DATA).


The volume is an NTFS file system volume and is unmounted.


Typically, this means that on the NTFS file system, another compress or FSCTL_MOVE_FILE operation is happening at the same time on the file specified by the FileHandle member.


When a move operation returns with a failure, some of the clusters may have been moved. To determine if this is the case, you have to acquire a new bitmap or retrieve new pointers.


The FSCTL_MOVE_FILE control code relocates one or more virtual clusters of a file from one logical cluster to another within the same volume. If the file to be moved is a sparse or compressed file, the granularity of the move is 16 clusters; otherwise, the granularity is one cluster.

To mark an open file so that it is not defragmented, call the DeviceIoControl function with the FSCTL_MARK_HANDLE control code with MARK_HANDLE_PROTECT_CLUSTERS in the HandleInfo member of the MARK_HANDLE_INFO structure passed in the lpInBuffer parameter.

Note that the bitmap returned by the DeviceIoControl function with the FSCTL_GET_VOLUME_BITMAP control code represents a point in time, and can be incorrect as soon as it has been read if the volume has write activity. Thus, it is possible to attempt to move a cluster onto an allocated cluster in spite of a recent bitmap indicating that the cluster is unallocated. Programs using FSCTL_MOVE_FILE must be prepared for this possibility.

For the implications of overlapped I/O on this operation, see the Remarks section of the DeviceIoControl topic.

For a list of files, streams, and stream types supported by the FSCTL_MOVE_FILE control code, see the Files, streams, and stream types supported for defragmentation section of the Defragmenting Files topic.

In Windows 8 and Windows Server 2012, this code is supported by the following technologies.


Server Message Block (SMB) 3.0 protocol


SMB 3.0 Transparent Failover (TFO)


SMB 3.0 with Scale-out File Shares (SO)


Cluster Shared Volume File System (CsvFS)




Minimum supported client

Windows XP [desktop apps only]

Minimum supported server

Windows Server 2003 [desktop apps only]


WinIoCtl.h (include Windows.h)

See also

Defragmenting Files
Disk Management Control Codes