Windows Directory Management 7





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 code 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 \the_new_created_directory 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 \the_new_created_directory 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.


Retrieving and Changing File Attributes Program Example: Creating new Win32 C++ console application project in Visual C++ .NET


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;  

   WCHAR szNewPath[MAX_PATH];

   // WCHAR Buffer[BUFSIZE];



   BOOL fFinished = FALSE;


   if(argc != 2)


         wprintf(LCopying text files in the current directory to a new directory\n);

         wprintf(LUsage: %s <new dir>\n, argv[0]);

         wprintf(LExample: %s C:\\testdir\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)


      wprintf(LNo text files found.\n);

      return 1;



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

   while (!fFinished)


      StringCchPrintf(szNewPath, MAX_PATH, L%s\\%s, argv[1], FileData.cFileName);


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


         dwAttrs = GetFileAttributes(FileData.cFileName);

         if (dwAttrs==INVALID_FILE_ATTRIBUTES)

                   return 1;


         if (!(dwAttrs & FILE_ATTRIBUTE_READONLY))


            SetFileAttributes(szNewPath, dwAttrs | FILE_ATTRIBUTE_READONLY);





         wprintf(LCould not copy file.\n);

         return 1;



      if (!FindNextFile(hSearch, &FileData))


         if (GetLastError() == ERROR_NO_MORE_FILES)


            wprintf(LCopied *.txt to %s directory\n, argv[1]);

            fFinished = TRUE;




                   wprintf(LCould not find next file.\n);

                   return 1;





   // Close the search handle



   /*  Optional extra codes

   // Change to the new created directory




      return 1;


   wprintf(LSet current directory to %s\n, argv[1]);


    dwRet = GetCurrentDirectory(BUFSIZE, Buffer);


   if( dwRet == 0 )



      return 1;



   if(dwRet > BUFSIZE)


      wprintf(LBuffer too small; need %d characters\n, dwRet);

      return 1;



   wprintf(LCurrent directory is %s\n, Buffer);


   // =========  Need another loop, find first, find next =======

   // Removing the read only attribute of those files

   //  TODO: Change all the read only file attribute to write

   //       so that all those file can be deleted


   // Deleting all the files

   if(DeleteFile(L*.txt) == 0)


   // =========  End loop, find first, find next =======


   // Then, when the directory is empty we can remove it

   if(RemoveDirectory(argv[1]) == 0)



            wprintf(L%s failed to be removed!\n, argv[1]);



   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, LError, MB_OK);






Build the project and to test this program you need to create a few text files under the project's Debug folder. Then, run the project. The following screenshots are sample outputs.


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


The following screenshot shows a sample output when the new directory already existed.


Retrieving and Changing File Attributes Program Example: A sample console program output in action 2, with error


The following sample output generated when there is no text file found.


Retrieving and Changing File Attributes Program Example: A sample console program output in action 3, no file found




< Windows Directory 6 | Win32 Programming | Win32 Directory Index | Windows Directory 8 >