void AFXAPI AfxGetRoot(LPCTSTR lpszPath, CString& strRoot) { ASSERT(lpszPath != NULL); // determine the root name of the volume LPTSTR lpszRoot = strRoot.GetBuffer(_MAX_PATH); memset(lpszRoot, 0, _MAX_PATH); lstrcpyn(lpszRoot, lpszPath, _MAX_PATH); for (LPTSTR lpsz = lpszRoot; *lpsz != '\0'; lpsz = _tcsinc(lpsz)) { // find first double slash and stop if (IsDirSep(lpsz[0]) && IsDirSep(lpsz[1])) break; } if (*lpsz != '\0') { // it is a UNC name, find second slash past '\\' ASSERT(IsDirSep(lpsz[0])); ASSERT(IsDirSep(lpsz[1])); lpsz += 2; while (*lpsz != '\0' && (!IsDirSep(*lpsz))) lpsz = _tcsinc(lpsz); if (*lpsz != '\0') lpsz = _tcsinc(lpsz); while (*lpsz != '\0' && (!IsDirSep(*lpsz))) lpsz = _tcsinc(lpsz); // terminate it just after the UNC root (ie. '\\server\share\') if (*lpsz != '\0') lpsz[1] = '\0'; } else { // not a UNC, look for just the first slash lpsz = lpszRoot; while (*lpsz != '\0' && (!IsDirSep(*lpsz))) lpsz = _tcsinc(lpsz); // terminate it just after root (ie. 'x:\') if (*lpsz != '\0') lpsz[1] = '\0'; } strRoot.ReleaseBuffer(); }
//--------------------------------------------------------------------------- // concatenates two paths - szPathAbs is always absolute (including drive letter), szPathRel can be relative (in which case we'll attempt // to add it to szPathAbs), or absolute (in which case it's the result) //--------------------------------------------------------------------------- BOOL LUtilConcatPaths(LPCTSTR szPathAbs, LPCTSTR szPathRel, CString &strPath) { BOOL fSucceed = TRUE; BOOL fNeedToCompressPath = false; // ASSERT (szPathAbs && szPathRel); strPath.Empty(); if (!szPathRel) { fSucceed = FALSE; } else { // check whether the path is an absolute path if (IsDirSep(szPathRel[0])) { // if not UNC, then prepend drive-letter if (!IsDirSep(szPathRel[1])) { if (!szPathAbs) { return FALSE; } strPath += szPathAbs[0]; strPath += _T(':'); } } else if (!(((szPathRel[0] >= _T('a') && szPathRel[0] <= _T('z')) || (szPathRel[0] >= _T('A') && szPathRel[0] <= _T('Z'))) && szPathRel[1] == _T(':'))) { if (!szPathAbs) { return FALSE; } // got a relative path -> prepend pathAbs strPath += szPathAbs; if (szPathRel[0] != _T('\0')&& strPath.Right(1) != _T('\\')) { strPath += _T('\\'); } } strPath += szPathRel; { // GetFullPathName needs a buffer large enough to do the processing of the path, so we // pass in a buffer that is 2*MAX_PATH and then fail if the final result is longer than MAX_PATH. TCHAR szPath[2 * MAX_PATH + 1], *pch; szPath[0] = _T('\0'); DWORD dwRet = GetFullPathName(strPath, 2 * MAX_PATH, szPath, &pch); if (dwRet == 0 || dwRet > MAX_PATH || szPath[0] == _T('\0')) fSucceed = FALSE; else strPath = szPath; } } return fSucceed; }
// // BUGBUG: Not fully implemented yet. // VOID OsPathNormPathInPlace ( IN CHAR8 *Path ) /*++ Routine Description: This function returns the directory path which contains the particular path. Some examples: "a/b/../c" -> "a/c" "a/b//c" -> "a/b/c" "a/./b" -> "a/b" This function does not check for the existence of the file. Arguments: Path Path name of file to normalize Returns: The string is altered in place. --*/ { CHAR8 *Pos; INTN Offset; BOOLEAN TryAgain; UINTN Length; UINTN Remaining; UINTN SubLength; do { TryAgain = FALSE; Length = strlen (Path); for (Offset = 0; Offset < Length; Offset++) { Remaining = Length - Offset; // // Collapse '//' -> '/' // if ( (Remaining >= 2) && ((Offset > 0) || (Path[0] != '\\')) && IsDirSep (Path[Offset]) && IsDirSep (Path[Offset + 1]) ) { memmove (&Path[Offset], &Path[Offset + 1], Remaining); TryAgain = TRUE; break; } // // Collapse '/./' -> '/' // if ((Remaining >= 3) && IsDirSep (Path[Offset]) && (Path[Offset + 1] == '.') && IsDirSep (Path[Offset + 2]) ) { memmove (&Path[Offset], &Path[Offset + 1], Remaining); TryAgain = TRUE; break; } // // Collapse 'a/../b' -> 'b' // // BUGBUG: Not implemented yet } } while (TryAgain); Return = CloneString (FilePath); if (Return == NULL) { return NULL; } Length = strlen (Return); // // Check for the root directory case // if ( (Length == 3 && isalpha (Return[0]) && (strcmp(Return + 1, ":\\") == 0)) || (strcmp(Return, "/") == 0) ) { free (Return); return NULL; } // // // for (Offset = Length; Offset > 0; Offset--) { if ((Return[Offset] == '/') || (Return[Offset] == '\\')) { Return[Offset] = '\0'; return Return; } } }