Windows Programming/File Management
This chapter will discuss some of the details of file and directory management. Some topics discussed will include moving and deleting files and directories, enumerating files, locking files, encrypting files, and accessing the Recycle Bin.
File attributes can be used to write-protect, hide, and un-hide files, or as behind-the-scenes file maintenance. This information can be accessible using the GetFileAttributes function. The attributes are called Read Only, Hidden, Archive, and System, and are described below:
Read Only: A file that is marked Read Only cannot be altered. It can be read, but it cannot be changed or deleted.
Hidden: By default, hidden files do not appear in a directory listing.
Archive: The Archive attribute can be used to selectively back up or copy files; it is most helpful in DOS.
System: System files are files flagged for use by the operating system and are not usually displayed in a directory listing.
Copying, Moving and Renaming Files
To copy files or directory there are two functions: CopyFile and the extended CopyFileEx.
BOOL CopyFile( LPCTSTR lpExistingFileName, // ptr to the name of the file/directory to copy LPCTSTR lpNewFileName, // ptr to filename to copy to BOOL bFailIfExists // flag for operation if file exists );
lpExistingFileName: is a pointer to a string that contains the file/directory to copy
lpNewFileName: is a pointer to a string with the new file/directory path
bFailIfExists: if this parameter is TRUE and the new file already exists, the function fail; if it is FALSE it will overwrite the existing file/directory.
If the function fail, the return value is zero, otherwise nonzero.
CopyFileEx is a bit more complicated. You can also specify a callback routine that is called each time a portion of the file has been copied. You can also cancel the copy operation, and if you want restart it later.
BOOL CopyFileEx( LPCWSTR lpExistingFileName, // pointer to name of an existing file LPCWSTR lpNewFileName, //pointer to filename to copy to LPPROGRESS_ROUTINE lpProgressRoutine, // pointer to the callback function LPVOID lpData, //data to be passed to the callback function LPBOOL pbCancel, //flag that can be used to cancel the operation DWORD dwCopyFlags //flags that specify how the file is copied );
lpProgressRoutine: You can set a callback function, so that it is called every time a portion of the file has been copied (it must be in the PROGRESS_ROUTINE form, see below).
lpData: Data to pass to the callback function (can be NULL).
pbCancel: if this flag is set to TRUE during the copy operation, the operation is cancelled.
dwCopyFlags: Specifies how the file is copied. Can be a combination of the following values
COPY_FILE_FAIL_IF_EXISTS The copy operation fail if lpNewFileName already exists
COPY_FILE_RESTARTABLE The copy progress is tracked in the file. You can restart the copy process later using the same values for lpExistingFileName and lpNewFileName
The definition of the copy progress routine:
DWORD WINAPI CopyProgressRoutine( LARGE_INTEGER TotalFileSize, // total file size of the file, in bytes LARGE_INTEGER TotalBytesTransferred, // total number of bytes transferred since operation started LARGE_INTEGER StreamSize, // size of current stream, in bytes LARGE_INTEGER StreamBytesTransferred, // total number of bytes transferred for this stream DWORD dwStreamNumber, // the current stream DWORD dwCallbackReason, // reason for callback HANDLE hSourceFile, // handle to the source file HANDLE hDestinationFile, // handle to the destination file LPVOID lpData // data passed by CopyFileEx );
You can use the first four parameters to display an indicator showing the percentage completed of the process.
dwCallbackReason: can have the following values
CALLBACK_CHUNK_FINISHED Another part of the data was copied.
CALLBACK_STREAM_SWITCH A stream was created and it is about to be copied. This is the reason when the Copy Routine Callback is called for the first time.
This function must return one of the following values:
PROGRESS_CONTINUE Continue with the copy
PROGRESS_CANCEL Cancel the copy operation and delete the target file
PROGRESS_STOP Stop the operation (it can be restarted later)
PROGRESS_QUIET Continue the copy operation, but don't call the Copy Progress Routine Again
Now, let's see how to move and rename files. The function we need are MoveFile and MoveFileEx. These function are used to both move or rename a file. When you call one of these function the system simply copy the file to the new location (with a different name if you also rename it) and deletes the old file.
BOOL MoveFileEx( LPCTSTR lpExistingFileName, // address of name of the existing file LPCTSTR lpNewFileName, // address of new name for the file DWORD dwFlags // flag to determine how to move file );
The API function used to delete files is DeleteFile . The file to delete must be closed, or the function will fail. If the function fails, the return value is 0, if it succeeds it's nonzero.
BOOL DeleteFile( LPCTSTR lpFileName // pointer to name of file to delete );
To delete a directory you can use the RemoveDirectory function, but first you have to delete all it's files and subdirectoryes (it must be empty).
BOOL RemoveDirectory( LPCTSTR lpPathName // address of directory to remove );
ReadDirectoryChangesW can be used to watch a directory (or volume). It can pass notifications when some file action is done in the target directory.