dir.cpp revision 0b2adb807a57929f6b2f07bc5439250906ff7918
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync * IPRT - Directory Manipulation.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync * Copyright (C) 2006-2010 Oracle Corporation
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync * This file is part of VirtualBox Open Source Edition (OSE), as
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync * available from http://www.virtualbox.org. This file is free software;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync * you can redistribute it and/or modify it under the terms of the GNU
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync * General Public License (GPL) as published by the Free Software
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync * Foundation, in version 2 as it comes in the "COPYING" file of the
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync * The contents of this file may alternatively be used under the terms
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync * of the Common Development and Distribution License Version 1.0
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync * VirtualBox OSE distribution, in which case the provisions of the
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync * CDDL are applicable instead of those of the GPL.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync * You may elect to license modified versions of this file under the
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync * terms and conditions of either the GPL or the CDDL or both.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync/*******************************************************************************
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync* Header Files *
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync*******************************************************************************/
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync#ifdef RT_OS_WINDOWS /* PORTME: Assumes everyone else is using dir-posix.cpp */
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncstatic DECLCALLBACK(bool) rtDirFilterWinNtMatch(PRTDIR pDir, const char *pszName);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncstatic DECLCALLBACK(bool) rtDirFilterWinNtMatchNoWildcards(PRTDIR pDir, const char *pszName);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncDECLINLINE(bool) rtDirFilterWinNtMatchEon(PCRTUNICP puszFilter);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncstatic bool rtDirFilterWinNtMatchDosStar(unsigned iDepth, RTUNICP uc, const char *pszNext, PCRTUNICP puszFilter);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncstatic bool rtDirFilterWinNtMatchStar(unsigned iDepth, RTUNICP uc, const char *pszNext, PCRTUNICP puszFilter);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncstatic bool rtDirFilterWinNtMatchBase(unsigned iDepth, const char *pszName, PCRTUNICP puszFilter);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncRTDECL(int) RTDirCreateFullPath(const char *pszPath, RTFMODE fMode)
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync * Resolve the path.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync int rc = RTPathAbs(pszPath, szAbsPath, sizeof(szAbsPath));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync * Iterate the path components making sure each of them exists.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync /* skip volume name */
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync char *psz = &szAbsPath[rtPathVolumeSpecLen(szAbsPath)];
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync /* skip the root slash if any */
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync /* iterate over path components. */
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync /* the next component is NULL, stop iterating */
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync * ASSUME that RTDirCreate will return VERR_ALREADY_EXISTS and not VERR_ACCESS_DENIED in those cases
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync * where the directory exists but we don't have write access to the parent directory.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync * Filter a the filename in the against a filter.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync * @returns true if the name matches the filter.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync * @returns false if the name doesn't match filter.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync * @param pDir The directory handle.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync * @param pszName The path to match to the filter.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncstatic DECLCALLBACK(bool) rtDirFilterWinNtMatchNoWildcards(PRTDIR pDir, const char *pszName)
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync * Walk the string and compare.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return false;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return true;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync * Matches end of name.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncDECLINLINE(bool) rtDirFilterWinNtMatchEon(PCRTUNICP puszFilter)
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync * Recursive star matching.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync * Practically the same as normal star, except that the dos star stops
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync * when hitting the last dot.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync * @returns true on match.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync * @returns false on miss.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncstatic bool rtDirFilterWinNtMatchDosStar(unsigned iDepth, RTUNICP uc, const char *pszNext, PCRTUNICP puszFilter)
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync * If there is no dos star, we should work just like the NT star.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync * Since that's generally faster algorithms, we jump down to there if we can.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return rtDirFilterWinNtMatchStar(iDepth, uc, pszNext, puszFilter);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync * Inspect the next filter char(s) until we find something to work on.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync * The star expression is the last in the pattern.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync * We're fine if the name ends with a dot.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync * Simplified by brute force.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (rtDirFilterWinNtMatchBase(iDepth, pszNext, puszFilter))
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return true;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync int rc = RTStrGetCpEx(&pszNext, &uc); AssertRCReturn(rc, false);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync } while ((intptr_t)pszDosDot - (intptr_t)pszNext >= -1);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync /* backtrack and do the current char. */
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pszNext = RTStrPrevCp(NULL, pszStart); AssertReturn(pszNext, false);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return rtDirFilterWinNtMatchBase(iDepth, pszNext, puszFilter);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync * Ok, we've got zero or more characters.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync * We'll try match starting at each occurence of this character.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync && rtDirFilterWinNtMatchBase(iDepth, pszNext, puszFilter))
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return true;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync int rc = RTStrGetCpEx(&pszNext, &uc); AssertRCReturn(rc, false);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync && rtDirFilterWinNtMatchBase(iDepth, pszNext, puszFilter))
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return true;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync } while ((intptr_t)pszDosDot - (intptr_t)pszNext >= -1);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return false;
static bool rtDirFilterWinNtMatchStar(unsigned iDepth, RTUNICP uc, const char *pszNext, PCRTUNICP puszFilter)
switch (ucFilter)
puszFilter++;
if (!uc)
} while (--cQms > 0);
if (!ucFilter)
} while (uc);
} while (uc);
} while (uc);
switch (ucFilter)
if (!uc)
if (!uc)
puszFilter++;
++puszFilter;
if (uc)
} while (uc);
return NULL;
bool fHaveWildcards = false;
unsigned iRead = 0;
unsigned iWrite = 0;
fHaveWildcards = true;
iRead++;
fHaveWildcards = true;
return fHaveWildcards
static int rtDirOpenCommon(PRTDIR *ppDir, const char *pszPath, const char *pszFilter, RTDIRFILTER enmFilter)
int rc;
if (!pszFilter)
if (!pszTmp)
return VERR_NO_MEMORY;
return rc;
#ifndef RT_OS_WINDOWS
# ifdef NAME_MAX
# ifdef _XOPEN_NAME_MAX
+ cbFilter
if (!pDir)
return VERR_NO_MEMORY;
if (cbFilter)
switch (enmFilter)
case RTDIRFILTER_NONE:
case RTDIRFILTER_WINNT:
case RTDIRFILTER_UNIX:
case RTDIRFILTER_UNIX_UPCASED:
#ifndef RT_OS_WINDOWS
return rc;
return rc;
switch (enmFilter)
case RTDIRFILTER_UNIX:
case RTDIRFILTER_UNIX_UPCASED:
return VERR_NOT_IMPLEMENTED;
case RTDIRFILTER_NONE:
case RTDIRFILTER_WINNT:
const char *pszFilter;
return rc;
static int rtDirRemoveRecursiveSub(char *pszBuf, size_t cchDir, PRTDIRENTRY pDirEntry, PRTFSOBJINFO pObjInfo)
return rc;
case RTDIRENTRYTYPE_FILE:
case RTDIRENTRYTYPE_DIRECTORY:
return rc;
return rc;
return VERR_ACCESS_DENIED;
return VERR_FILENAME_TOO_LONG;
return VINF_SUCCESS;
return rc;
return VERR_NOT_A_DIRECTORY;
return rc;
return rc;