I was recently working on a C++/MFC application that needed to backup a bunch of files. Copying files is easy enough, but I had to create the target folder if it didn't exist. Creating a folder is also easy: just call CreateDirectory(). However, this function will not create intermediate directories.
That is, if I need to create the directory D:\Documents\Financials, CreateDirectory() will fail if D:\Documents does not already exist. To build this directory, I must first create D:\Documents before I can create D:\Documents\Financials. Clearly, I needed a routine that will ensure a path of any depth exists, and will create any missing folders.
Note that SHCreateDirectory() is documented as doing just this. However, the documentation also states this function "might be altered or unavailable in subsequent versions of Windows." I didn't really care for the sound of that so I decided to write my own routine. Although it required a little thought, the routine I came up with with reasonably simple and quite short.
My EnsurePathExists() Function
Listing one shows my EnsurePathExists() routine. It takes a path string, and will determine whether or not that path exists. If it does not exist, the routine will create it. It returns a Boolean value, which is false if a portion of the directory could not be created. (For example, if there was already a file with the same name.)
Listing 1: EnsurePathExists() function
// Ensures the given path exists, creating it if needed
bool EnsurePathExists(LPCTSTR lpszPath)
// Nothing to do if path already exists
// Ignore trailing backslash
int nLen = _tcslen(lpszPath);
if (lpszPath[nLen - 1] == '\\')
// Skip past drive specifier
int nCurrLen = 0;
if (nLen >= 3 && lpszPath == ':' && lpszPath == '\\')
nCurrLen = 2;
// We can't create root so skip past any root specifier
while (lpszPath[nCurrLen] == '\\')
// Test each component of this path, creating directories as needed
while (nCurrLen < nLen)
// Parse next path compenent
LPCTSTR psz = _tcschr(lpszPath + nCurrLen, '\\');
if (psz != NULL)
nCurrLen = (int)(psz - lpszPath);
nCurrLen = nLen;
// Ensure this path exists
if (!::CreateDirectory(sPath, NULL))
// Skip over current backslash
if (lpszPath[nCurrLen] != '\0')
// Returns true if the specified path exists and is a directory
bool DirectoryExists(LPCTSTR lpszPath)
DWORD dw = ::GetFileAttributes(lpszPath);
return (dw != INVALID_FILE_ATTRIBUTES &&
(dw & FILE_ATTRIBUTE_DIRECTORY) != 0);
The code processes a single component, or level, of the path at a time, either ensuring it exists or creating it if it does not. It uses my helper routine DirectoryExists() to determine if each component exists. If it does not, that component is created using CreateDirectory().
To save time, EnsurePathExists() starts by testing for the existence of the entire path. If it already exists, the function simply returns true.
That's about all there is to it. Most of the details are just in making sure each component is properly parsed and tested. The code skips the root folder because you cannot create a root folder. The code also strips multiple leading backslashes, as might be seen in paths that refer to network locations.
Use of this article and any related source code or other files is governed
by the terms and conditions of