The Windows File Management 24






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(L"Usage: %s <new_directory_to_be_created>\n", argv[0]);

      wprintf(L"Example: %s C:\\NewDirectory\n", argv[0]);

      return 1;



   // Create a new directory

   if (!CreateDirectory(argv[1], NULL))



      return 1;



         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)



      return 1;



         wprintf(L"FindFirstFile() - text file found!\n");


   // Copy each .TXT file to the new directory and change it to read only, if not already

   wprintf(L"Copying 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(L"StringCchPrintf() is OK!\n");




      if (CopyFile(FileData.cFileName, szNewPath, FALSE))


         dwAttrs = GetFileAttributes(FileData.cFileName);

         if (dwAttrs==INVALID_FILE_ATTRIBUTES)

                   return 1;


                   wprintf(L"GetFileAttributes() looks OK!\n");


         if (!(dwAttrs & FILE_ATTRIBUTE_READONLY))


            if(SetFileAttributes(szNewPath, dwAttrs | FILE_ATTRIBUTE_READONLY | FILE_ATTRIBUTE_HIDDEN) != 0)

                        wprintf(L"SetFileAttributes() to read only & hidden is OK!\n");








         return 1;



      if (!FindNextFile(hSearch, &FileData))


         if (GetLastError() == ERROR_NO_MORE_FILES)


            wprintf(L"Copied *.txt to %s\n", argv[1]);

            fFinished = TRUE;





            return 1;





   // Close the search handle

   if(FindClose(hSearch) != 0)

         wprintf(L"FindClose() is OK...\n");




   return 0;



void DisplayErrorBox(LPTSTR lpszFunction)


    // Retrieve the system error message for the last-error code

    LPVOID lpMsgBuf;

    LPVOID lpDisplayBuf;

    DWORD dw = GetLastError();









        (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, L"Error", MB_OK);






Firstly, let create a few text files under the project's Debug folder.


Retrieving and Changing File Attributes: Creating some test files for testing


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


Retrieving and Changing File Attributes: The default file properties


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


Retrieving and Changing File Attributes: A sample console program output in action


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


Retrieving and Changing File Attributes: All the files' properties are hidden and read only


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.


Enabling the hidden file view



Enabling the Show hidden files and folders


Then, verify the properties one of those files.


The file attributes have been changed





< Windows Files 23 | Win32 Programming | Win32 File Index | Windows Files 25 >