dir.cpp revision 677833bc953b6cb418c701facbdcf4aa18d6c44e
0N/A * InnoTek Portable Runtime - Directory Manipulation. 2362N/A * Copyright (C) 2006 InnoTek Systemberatung GmbH 2362N/A * This file is part of VirtualBox Open Source Edition (OSE), as 0N/A * you can redistribute it and/or modify it under the terms of the GNU 0N/A * General Public License as published by the Free Software Foundation, 0N/A * in version 2 as it comes in the "COPYING" file of the VirtualBox OSE 0N/A * distribution. VirtualBox OSE is distributed in the hope that it will 0N/A * be useful, but WITHOUT ANY WARRANTY of any kind. 0N/A * If you received this file as part of a commercial VirtualBox 0N/A * distribution, then only the terms of your commercial VirtualBox 0N/A * license agreement apply instead of the previous paragraph. 2362N/A/******************************************************************************* 0N/A*******************************************************************************/ 0N/A * Iterate the path components making sure each of the exist. 0N/A /* skip volume name */ 0N/A /* skip the root slash if any */ 0N/A /* iterate over path components. */ /* the next component is NULL, stop iterating */ * ASSUME that RTDirCreate will return VERR_ALREADY_EXISTS and not VERR_ACCESS_DENIED in those cases * where the directory exists but we don't have write access to the parent directory. * Filter a the filename in the against a filter. * @returns true if the name matches the filter. * @returns false if the name doesn't match filter. * @param pDir The directory handle. * @param pszName The path to match to the filter. * Walk the string and compare. * Recursive star matching. * Practically the same as normal star, except that the dos star stops * when hitting the last dot. * @returns true on match. * @returns false on miss. * If there is no dos star, we should work just like the NT star. * Since that's generally faster algorithms, we jump down to there if we can. * Inspect the next filter char(s) until we find something to work on. * The star expression is the last in the pattern. * We're fine if the name ends with a dot. * Simplified by brute force. case '>':
/* dos question mark */ /* backtrack and do the current char. */ * Ok, we've got zero or more characters. * We'll try match starting at each occurence of this character. /* won't ever get here! */ * Recursive star matching. * @returns true on match. * @returns false on miss. * Inspect the next filter char(s) until we find something to work on. * The star expression is the last in the pattern. * Cool, that means we're done! * Just in case (doubt we ever get here), just merge it with the current one. * Skip a fixed number of chars. * Figure out how many by walking the filter ignoring '*'s. * The simple way is to try char by char and match the remaining * expression. If it's trailing we're done. case '>':
/* dos question mark */ /* backtrack and do the current char. */ * This bugger is interesting. * Time for brute force. Iterate the name char by char. * This guy matches a '.' or the end of the name. * It's very simple if the rest of the filter expression also matches eon. * Ok, we've got zero or more characters. * We'll try match starting at each occurence of this character. /* won't ever get here! */ * Filter a the filename in the against a filter. * The rules are as follows: * '?' Matches exactly one char. * '*' Matches zero or more chars. * '<' The dos star, matches zero or more chars except the DOS dot. * '>' The dos question mark, matches one char, but dots and end-of-name eats them. * '"' The dos dot, matches a dot or end-of-name. * @returns true if the name matches the filter. * @returns false if the name doesn't match filter. * @param iDepth The recursion depth. * @param pszName The path to match to the filter. * @param puszFilter The filter string. * Walk the string and match it up char by char. /* One char, but the dos dot and end-of-name eats '>' and '<'. */ else /* the does question mark doesn't match '.'s, so backtrack. */ /* Match a dot or the end-of-name. */ * Filter a the filename in the against a filter. * @returns true if the name matches the filter. * @returns false if the name doesn't match filter. * @param pDir The directory handle. * @param pszName The path to match to the filter. * Initializes a WinNt like wildcard filter. * @returns Pointer to the filter function. * @returns NULL if the filter doesn't filter out anything. * @param pDir The directory handle (not yet opened). * Check for the usual * and <"< (*.* in DOS language) patterns. * Uppercase the expression, also do a little optimizations when possible. /* remove extra stars. */ else if (
uc ==
'?' ||
uc ==
'>' ||
uc ==
'<' ||
uc ==
'"')
* Common worker for opening a directory. * @returns IPRT status code. * @param ppDir Where to store the directory handle. * @param pszPath The specified path. * @param pszFilter Pointer to where the filter start in the path. NULL if no filter. * @param enmFilter The type of filter to apply. * The purpose of this exercise to have the abs path around * for querying extra information about the objects we list. * As a sideeffect we also validate the path here. /* yea, I'm lazy. sue me. */ /* add trailing '/' if missing. */ * Allocate and initialize the directory handle. * Hand it over to the native part. * Take common cause with RTDirOpenFiltered(). * Find the last component, i.e. where the filter criteria starts and the dir name ends. * Call worker common with RTDirOpen which will verify the path, allocate * and initialize the handle, and finally call the backend. LogFlow((
"RTDirOpenFiltered(%p:{%p}, %p:{%s}, %d): return %Rrc\n",