Retrieving and Changing File Attributes Program Example
An application can retrieve the file attributes by using the GetFileAttributes() or GetFileAttributesEx() function. The CreateFile() and SetFileAttributes() functions can set many of the attributes. However, applications cannot set all attributes. The following program example uses the CopyFile() function to copy all text files (.txt) in the current directory to a new directory of read-only files. Files in the new directory are changed to read only, if necessary. The application creates the directory specified as a parameter by using the CreateDirectory() function. The directory must not exist already. The application searches the current directory for all text files by using the FindFirstFile() and FindNextFile() functions. Each text file is copied to the \TextRO directory. After a file is copied, the GetFileAttributes() function determines whether or not a file is read only. If the file is not read only, the application changes directories to \TextRO and converts the copied file to read only by using the SetFileAttributes() function. After all text files in the current directory are copied, the application closes the search handle by using the FindClose() function.
Create a new empty Win32 console application project. Give a suitable project name and change the project location if needed.
Then, add the source file and give it a suitable name.
Next, add the following source code.
#include <windows.h>
#include <stdio.h>
#include <strsafe.h>
// A prototype that receives a function name, displaying
// system error code and its respective message
void DisplayErrorBox(LPTSTR lpszFunction);
int wmain(int argc, WCHAR* argv[])
{
WIN32_FIND_DATA FileData;
HANDLE hSearch;
DWORD dwAttrs;
TCHAR szNewPath[MAX_PATH];
BOOL fFinished = FALSE;
if(argc != 2)
{
wprintf(LUsage: %s <new_directory_to_be_created>\n, argv[0]);
wprintf(LExample: %s C:\\NewDirectory\n, argv[0]);
return 1;
}
// Create a new directory
if (!CreateDirectory(argv[1], NULL))
{
DisplayErrorBox(LCreateDirectory());
return 1;
}
else
wprintf(L%s directory was successfully created!\n, argv[1]);
// Start searching for text files in the current directory
hSearch = FindFirstFile(L*.txt, &FileData);
if (hSearch == INVALID_HANDLE_VALUE)
{
DisplayErrorBox(LFindFirstFile());
return 1;
}
else
wprintf(LFindFirstFile() - text file found!\n);
// Copy each .TXT file to the new directory and change it to read only, if not already
wprintf(LCopying all the text files to %s & change them to Read Only & Hidden\n, argv[1]);
while (!fFinished)
{
if(StringCchPrintf(szNewPath, MAX_PATH, L%s\\%s, argv[1], FileData.cFileName) == S_OK)
wprintf(LStringCchPrintf() is OK!\n);
else
DisplayErrorBox(LStringCchPrintf());
if (CopyFile(FileData.cFileName, szNewPath, FALSE))
{
dwAttrs = GetFileAttributes(FileData.cFileName);
if (dwAttrs==INVALID_FILE_ATTRIBUTES)
return 1;
else
wprintf(LGetFileAttributes() looks OK!\n);
if (!(dwAttrs & FILE_ATTRIBUTE_READONLY))
{
if(SetFileAttributes(szNewPath, dwAttrs | FILE_ATTRIBUTE_READONLY | FILE_ATTRIBUTE_HIDDEN) != 0)
wprintf(LSetFileAttributes() to read only & hidden is OK!\n);
else
DisplayErrorBox(LSetFileAttributes());
}
}
else
{
DisplayErrorBox(LCopyFile());
return 1;
}
if (!FindNextFile(hSearch, &FileData))
{
if (GetLastError() == ERROR_NO_MORE_FILES)
{
wprintf(LCopied *.txt to %s\n, argv[1]);
fFinished = TRUE;
}
else
{
DisplayErrorBox(LFindNextFile());
return 1;
}
}
}
// Close the search handle
if(FindClose(hSearch) != 0)
wprintf(LFindClose() is OK...\n);
else
DisplayErrorBox(LFindClose());
return 0;
}
void DisplayErrorBox(LPTSTR lpszFunction)
{
// Retrieve the system error message for the last-error code
LPVOID lpMsgBuf;
LPVOID lpDisplayBuf;
DWORD dw = GetLastError();
FormatMessage(
FORMAT_MESSAGE_ALLOCATE_BUFFER |
FORMAT_MESSAGE_FROM_SYSTEM |
FORMAT_MESSAGE_IGNORE_INSERTS,
NULL,
dw,
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
(LPTSTR) &lpMsgBuf,
0, NULL);
// Display the error message and clean up
lpDisplayBuf = (LPVOID)LocalAlloc(LMEM_ZEROINIT, (lstrlen((LPCTSTR)lpMsgBuf)+lstrlen((LPCTSTR)lpszFunction)+40)*sizeof(WCHAR));
StringCchPrintf((LPTSTR)lpDisplayBuf, LocalSize(lpDisplayBuf) / sizeof(WCHAR), L%s failed with error %d: %s, lpszFunction, dw, lpMsgBuf);
MessageBox(NULL, (LPCTSTR)lpDisplayBuf, LError, MB_OK);
LocalFree(lpMsgBuf);
LocalFree(lpDisplayBuf);
}
Firstly, let create a few text files under the project's Debug folder.

The default files' properties are shown below, at the beginning.

Next, run the program with a folder name as the argument.

Then, verify that the new folder has been created, with all the text files have been moved to the new folder.

Those files' properties are hidden and read only so you may need to enable the Windows explorer to show the hidden files and folders. The steps are shown in the following Figures.


Then, verify the properties one of those files.
