diff options
author | dotnet-bot <dotnet-bot@microsoft.com> | 2015-01-30 14:14:42 -0800 |
---|---|---|
committer | dotnet-bot <dotnet-bot@microsoft.com> | 2015-01-30 14:14:42 -0800 |
commit | ef1e2ab328087c61a6878c1e84f4fc5d710aebce (patch) | |
tree | dee1bbb89e9d722e16b0d1485e3cdd1b6c8e2cfa /src/inc/clr/fs | |
download | coreclr-ef1e2ab328087c61a6878c1e84f4fc5d710aebce.tar.gz coreclr-ef1e2ab328087c61a6878c1e84f4fc5d710aebce.tar.bz2 coreclr-ef1e2ab328087c61a6878c1e84f4fc5d710aebce.zip |
Initial commit to populate CoreCLR repo
[tfs-changeset: 1407945]
Diffstat (limited to 'src/inc/clr/fs')
-rw-r--r-- | src/inc/clr/fs/dir.h | 134 | ||||
-rw-r--r-- | src/inc/clr/fs/file.h | 41 | ||||
-rw-r--r-- | src/inc/clr/fs/path.h | 137 |
3 files changed, 312 insertions, 0 deletions
diff --git a/src/inc/clr/fs/dir.h b/src/inc/clr/fs/dir.h new file mode 100644 index 0000000000..7c604085fc --- /dev/null +++ b/src/inc/clr/fs/dir.h @@ -0,0 +1,134 @@ +// +// Copyright (c) Microsoft. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. +// +// + +// +// This header provides general directory-related file system services. + +#ifndef _clr_fs_Dir_h_ +#define _clr_fs_Dir_h_ + +#include "clrtypes.h" +#include "clr/str.h" +#include "strsafe.h" + +#ifndef countof + #define countof(x) (sizeof(x) / sizeof(x[0])) +#endif // !countof + +namespace clr +{ + namespace fs + { + class Dir + { + public: + static inline bool Exists( + LPCWSTR wzDirPath) + { + DWORD attrs = WszGetFileAttributes(wzDirPath); + return (attrs != INVALID_FILE_ATTRIBUTES) && (attrs & FILE_ATTRIBUTE_DIRECTORY); + } + + //----------------------------------------------------------------------------------------- + // Creates new directory indicated by wzDirPath. + // + // Returns: + // S_OK - on success directory creation + // S_FALSE - when directory previously existed + // HR(ERROR_PATH_NOT_FOUND) - when creation of dir fails. + static inline HRESULT Create( + LPCWSTR wzDirPath) + { + HRESULT hr = S_OK; + + if (!WszCreateDirectory(wzDirPath, nullptr)) + { + hr = HRESULT_FROM_GetLastError(); + if (hr == HRESULT_FROM_WIN32(ERROR_ALREADY_EXISTS)) + { + hr = S_FALSE; + } + } + return hr; + } + + //----------------------------------------------------------------------------------------- + // Creates the specified directory and all required subdirectories. wzDirPath will be + // temporarily modified in the process. + // + // Returns: + // S_OK - on success directory creation + // S_FALSE - when directory previously existed + // HR(ERROR_PATH_NOT_FOUND) - when creation of any dir fails. + static inline HRESULT CreateRecursively( + __inout_z LPWSTR wzDirPath, + size_t cchDirPath = 0) + { + HRESULT hr = S_OK; + + if (wzDirPath == nullptr) + { + return E_POINTER; + } + + if (cchDirPath == 0) + { + IfFailRet(StringCchLength(wzDirPath, _MAX_PATH, &cchDirPath)); + } + + if (cchDirPath >= _MAX_PATH) + { + return E_INVALIDARG; + } + + // Try to create the path. If it fails, assume that's because the parent folder does + // not exist. Try to create the parent then re-attempt. + hr = Create(wzDirPath); + if (hr == HRESULT_FROM_WIN32(ERROR_PATH_NOT_FOUND)) + { + for (WCHAR* pCurCh = wzDirPath + cchDirPath - 1; pCurCh != wzDirPath; --pCurCh) + { + if (*pCurCh == W('\\') || *pCurCh == W('\0')) + { + WCHAR chOrig = *pCurCh; + *pCurCh = W('\0'); + IfFailRet(CreateRecursively(wzDirPath, pCurCh - wzDirPath)); + *pCurCh = chOrig; + break; + } + } + IfFailRet(Create(wzDirPath)); + } + + return hr; + } + + //----------------------------------------------------------------------------------------- + // Creates the specified directory and all required subdirectories. + static inline HRESULT CreateRecursively( + LPCWSTR wzDirPath) + { + HRESULT hr = S_OK; + + if (wzDirPath == nullptr) + { + return E_POINTER; + } + + // Make a writable copy of wzDirPath + WCHAR wzBuffer[_MAX_PATH]; + WCHAR * pPathEnd; + IfFailRet(StringCchCopyEx(wzBuffer, countof(wzBuffer), wzDirPath, + &pPathEnd, nullptr, STRSAFE_NULL_ON_FAILURE)); + IfFailRet(CreateRecursively(wzBuffer, pPathEnd - wzBuffer)); + + return hr; + } + }; + } +} + +#endif // _clr_fs_Dir_h_ diff --git a/src/inc/clr/fs/file.h b/src/inc/clr/fs/file.h new file mode 100644 index 0000000000..21f54d6558 --- /dev/null +++ b/src/inc/clr/fs/file.h @@ -0,0 +1,41 @@ +// +// Copyright (c) Microsoft. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. +// +// + +// +// This header provides general filename-related file system services. + +#ifndef _clr_fs_File_h_ +#define _clr_fs_File_h_ + +#include "clrtypes.h" +#include "cor.h" // SELECTANY + +namespace clr +{ + namespace fs + { + // This list taken from ndp/clr/src/bcl/system/io/path.cs + SELECTANY WCHAR const g_rgInvalidFileNameChars[] = + { W('"'), W('<'), W('>'), W('|'), W('\0'), (WCHAR)1, (WCHAR)2, (WCHAR)3, (WCHAR)4, (WCHAR)5, (WCHAR)6, + (WCHAR)7, (WCHAR)8, (WCHAR)9, (WCHAR)10, (WCHAR)11, (WCHAR)12, (WCHAR)13, (WCHAR)14, + (WCHAR)15, (WCHAR)16, (WCHAR)17, (WCHAR)18, (WCHAR)19, (WCHAR)20, (WCHAR)21, (WCHAR)22, + (WCHAR)23, (WCHAR)24, (WCHAR)25, (WCHAR)26, (WCHAR)27, (WCHAR)28, (WCHAR)29, (WCHAR)30, + (WCHAR)31, W(':'), W('*'), W('?'), W('\\'), W('/') }; + + class File + { + public: + static inline bool Exists( + LPCWSTR wzFilePath) + { + DWORD attrs = WszGetFileAttributes(wzFilePath); + return (attrs != INVALID_FILE_ATTRIBUTES) && !(attrs & FILE_ATTRIBUTE_DIRECTORY); + } + }; + } +} + +#endif // _clr_fs_File_h_ diff --git a/src/inc/clr/fs/path.h b/src/inc/clr/fs/path.h new file mode 100644 index 0000000000..29a70f7260 --- /dev/null +++ b/src/inc/clr/fs/path.h @@ -0,0 +1,137 @@ +// +// Copyright (c) Microsoft. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. +// +// + +// +// This header provides general path-related file system services. + +#ifndef _clr_fs_Path_h_ +#define _clr_fs_Path_h_ + +#include "clrtypes.h" +#include "cor.h" // SELECTANY + +#include "strsafe.h" + +#include "clr/str.h" + +#ifndef LONG_FORMAT_PATH_PREFIX + #define LONG_FORMAT_PATH_PREFIX W("\\\\?\\") +#endif + +namespace clr +{ + namespace fs + { + // This list taken from ndp/clr/src/bcl/system/io/path.cs + SELECTANY WCHAR const g_rgInvalidPathChars[] = + { W('"'), W('<'), W('>'), W('|'), W('\0'), (WCHAR)1, (WCHAR)2, (WCHAR)3, (WCHAR)4, (WCHAR)5, (WCHAR)6, + (WCHAR)7, (WCHAR)8, (WCHAR)9, (WCHAR)10, (WCHAR)11, (WCHAR)12, (WCHAR)13, (WCHAR)14, + (WCHAR)15, (WCHAR)16, (WCHAR)17, (WCHAR)18, (WCHAR)19, (WCHAR)20, (WCHAR)21, (WCHAR)22, + (WCHAR)23, (WCHAR)24, (WCHAR)25, (WCHAR)26, (WCHAR)27, (WCHAR)28, (WCHAR)29, (WCHAR)30, + (WCHAR)31 }; + + class Path + { + public: + //----------------------------------------------------------------------------------------- + static inline bool + Exists( + LPCWSTR wzPath) + { + DWORD attrs = WszGetFileAttributes(wzPath); + return (attrs != INVALID_FILE_ATTRIBUTES); + } + + //----------------------------------------------------------------------------------------- + // Returns true if wzPath represents a long format path (i.e., prefixed with '\\?\'). + static inline bool + HasLongFormatPrefix(LPCWSTR wzPath) + { + _ASSERTE(!clr::str::IsNullOrEmpty(wzPath)); // Must check this first. + return wcscmp(wzPath, LONG_FORMAT_PATH_PREFIX) == 0; + } + + //----------------------------------------------------------------------------------------- + static inline bool + HasUncPrefix(LPCWSTR wzPath) + { + _ASSERTE(!clr::str::IsNullOrEmpty(wzPath)); // Must check this first. + return wzPath[0] != W('\0') && wzPath[0] == W('\\') + && wzPath[1] != W('\0') && wzPath[1] == W('\\') + && wzPath[2] != W('\0') && wzPath[2] != W('?'); + } + + //----------------------------------------------------------------------------------------- + static inline bool + HasDrivePrefix(LPCWSTR wzPath) + { + _ASSERTE(!clr::str::IsNullOrEmpty(wzPath)); // Must check this first. + return wzPath[0] != W('\0') + && wzPath[1] != W('\0') && wzPath[1] == W(':') + && ((wzPath[0] >= W('a') && wzPath[0] <= W('z')) || + (wzPath[0] >= W('A') && wzPath[0] <= W('Z'))); + } + + //----------------------------------------------------------------------------------------- + // Returns true if wzPath represents a relative path. + static inline bool + IsRelative(LPCWSTR wzPath) + { + _ASSERTE(!clr::str::IsNullOrEmpty(wzPath)); // Must check this first. + return !HasLongFormatPrefix(wzPath) + && !HasUncPrefix(wzPath) + && (!HasDrivePrefix(wzPath) || wzPath[2] != W('\\')); + } + + //----------------------------------------------------------------------------------------- + // Combines two path parts. wzPathLeft must be a directory path and may be either absolute + // or relative. wzPathRight may be a directory or file path and must be relative. The + // result is placed in wzBuffer and the number of chars written is placed in pcchBuffer on + // success; otherwise an error HRESULT is returned. + static HRESULT + Combine(LPCWSTR wzPathLeft, LPCWSTR wzPathRight, __out DWORD *pcchBuffer, __out_ecount(*pcchBuffer) LPWSTR wzBuffer) + { + STATIC_CONTRACT_NOTHROW; + + HRESULT hr = S_OK; + + if (clr::str::IsNullOrEmpty(wzPathLeft) || clr::str::IsNullOrEmpty(wzPathRight) || pcchBuffer == nullptr) + return E_INVALIDARG; + + LPWSTR wzBuf = wzBuffer; + size_t cchBuf = *pcchBuffer; + + IfFailRet(StringCchCopyExW(wzBuf, cchBuf, wzPathLeft, &wzBuf, &cchBuf, STRSAFE_NULL_ON_FAILURE)); + IfFailRet(StringCchCatExW(wzBuf, cchBuf, wzBuf[-1] == W('\\') ? W("") : W("\\"), &wzBuf, &cchBuf, STRSAFE_NULL_ON_FAILURE)); + IfFailRet(StringCchCatExW(wzBuf, cchBuf, wzPathRight, &wzBuf, &cchBuf, STRSAFE_NULL_ON_FAILURE)); + + return S_OK; + } + + //----------------------------------------------------------------------------------------- + // Checks if the path provided is valid within the specified constraints. + // ***NOTE: does not yet check for invalid path characters. + static bool + IsValid(LPCWSTR wzPath, DWORD cchPath, bool fAllowLongFormat) + { + if (clr::str::IsNullOrEmpty(wzPath)) + return false; + + bool fIsLongFormat = HasLongFormatPrefix(wzPath); + + if (fIsLongFormat && !fAllowLongFormat) + return false; + + if (!fIsLongFormat && cchPath > _MAX_PATH) + return false; + + return true; + } + }; + } +} + +#endif // _clr_fs_Path_h_ |