1 // Licensed to the .NET Foundation under one or more agreements.
2 // The .NET Foundation licenses this file to you under the MIT license.
3 // See the LICENSE file in the project root for more information.
4 // ============================================================
11 // Implements a bunch of binder auxilary functions
13 // ============================================================
15 #define DISABLE_BINDER_DEBUG_LOGGING
21 #include "strongname.h"
24 namespace BINDER_SPACE
28 inline BOOL IsPathSeparator(WCHAR wcChar)
30 // Invariant: Valid only for MutateUrlToPath treated pathes
31 return (wcChar == W('\\'));
34 inline const WCHAR *GetPlatformPathSeparator()
40 #endif // PLATFORM_UNIX
43 inline WCHAR ToPlatformPathSepator(WCHAR wcChar)
46 if (IsPathSeparator(wcChar))
50 #endif // PLATFORM_UNIX
55 inline BOOL IsDoublePathSeparator(SString::CIterator &cur)
57 return (IsPathSeparator(cur[0]) && IsPathSeparator(cur[1]));
60 bool NeedToRemoveDoubleAndNormalizePathSeparators(SString const &path)
65 SString::CIterator begin = path.Begin();
66 SString::CIterator end = path.End();
67 SString::CIterator cur = path.Begin();
71 if ((cur != begin) && ((cur + 2) < end) && IsDoublePathSeparator(cur))
83 void RemoveDoubleAndNormalizePathSeparators(SString &path)
85 BINDER_LOG_ENTER(W("Utils::RemoveDoubleAndNormalizePathSeparators"));
87 SString::Iterator begin = path.Begin();
88 SString::Iterator end = path.End();
89 SString::Iterator cur = path.Begin();
90 PathString resultPath;
92 BINDER_LOG_STRING(W("path"), path);
96 if ((cur != begin) && ((cur + 2) < end) && IsDoublePathSeparator(cur))
102 resultPath.Append(ToPlatformPathSepator(cur[0]));
106 BINDER_LOG_STRING(W("resultPath"), resultPath);
108 path.Set(resultPath);
110 BINDER_LOG_LEAVE(W("Utils::RemoveDoubleAndNormalizePathSeparators"));
114 HRESULT FileOrDirectoryExists(PathString &path)
116 HRESULT hr = S_FALSE;
118 DWORD dwFileAttributes = WszGetFileAttributes(path.GetUnicode());
119 if (dwFileAttributes == INVALID_FILE_ATTRIBUTES)
121 hr = HRESULT_FROM_GetLastError();
123 if ((hr == HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND)) ||
124 (hr == HRESULT_FROM_WIN32(ERROR_PATH_NOT_FOUND)))
137 HRESULT FileOrDirectoryExistsLog(PathString &path)
139 HRESULT hr = S_FALSE;
140 BINDER_LOG_ENTER(W("Utils::FileOrDirectoryExistsLog"));
141 BINDER_LOG_STRING(W("path"), path);
143 hr = FileOrDirectoryExists(path);
145 BINDER_LOG_LEAVE_HR(W("Utils::FileOrDirectoryExistsLog"), hr);
149 BOOL IsURL(SString &urlOrPath)
151 // This is also in defined rotor pal
152 return PathIsURLW(urlOrPath);
155 void MutateUrlToPath(SString &urlOrPath)
157 BINDER_LOG_ENTER(W("Utils::MutateUrlToPath"));
158 const SString fileUrlPrefix(SString::Literal, W("file://"));
159 SString::Iterator i = urlOrPath.Begin();
161 BINDER_LOG_STRING(W("URL"), urlOrPath);
163 if (urlOrPath.MatchCaseInsensitive(i, fileUrlPrefix))
165 urlOrPath.Delete(i, fileUrlPrefix.GetCount());
167 i = urlOrPath.Begin() + 1;
170 // CLR erroneously passes in file:// prepended to file paths,
171 // so we can't tell the difference between UNC and local file.
175 i = urlOrPath.Begin();
176 #if !defined(PLATFORM_UNIX)
179 // Disk path file:///
180 urlOrPath.Delete(i, 1);
182 else if (i[0] != W('\\'))
184 // UNC Path, re-insert "//" if not the wrong file://\\...
185 urlOrPath.Insert(i, W("//"));
188 // Unix doesn't have a distinction between local and network path
189 _ASSERTE(i[0] == W('\\') || i[0] == W('/'));
194 while (urlOrPath.Find(i, W('/')))
196 urlOrPath.Replace(i, W('\\'));
199 BINDER_LOG_STRING(W("Path"), urlOrPath);
200 BINDER_LOG_LEAVE(W("Utils::MutateUrlToPath"));
203 void MutatePathToUrl(SString &pathOrUrl)
205 BINDER_LOG_ENTER(W("Utils::MutatePathToUrl"));
206 SString::Iterator i = pathOrUrl.Begin();
208 BINDER_LOG_STRING(W("Path"), pathOrUrl);
210 #if !defined(PLATFORM_UNIX)
211 // Network path \\server --> file://server
212 // Disk path c:\dir --> file:///c:/dir
215 const SString networkUrlPrefix(SString::Literal, W("file:"));
218 pathOrUrl.Insert(i, networkUrlPrefix);
219 pathOrUrl.Skip(i, networkUrlPrefix);
223 const SString diskPathUrlPrefix(SString::Literal, W("file:///"));
226 pathOrUrl.Insert(i, diskPathUrlPrefix);
227 pathOrUrl.Skip(i, diskPathUrlPrefix);
230 // Unix doesn't have a distinction between a network or a local path
231 _ASSERTE(i[0] == W('\\') || i[0] == W('/'));
232 const SString fileUrlPrefix(SString::Literal, W("file://"));
234 pathOrUrl.Insert(i, fileUrlPrefix);
235 pathOrUrl.Skip(i, fileUrlPrefix);
238 while (pathOrUrl.Find(i, W('\\')))
240 pathOrUrl.Replace(i, W('/'));
243 BINDER_LOG_STRING(W("URL"), pathOrUrl);
244 BINDER_LOG_LEAVE(W("Utils::MutatePathToUrl"));
247 void PlatformPath(SString &path)
249 BINDER_LOG_ENTER(W("Utils::PlatformPath"));
250 BINDER_LOG_STRING(W("input path"), path);
252 // Create platform representation
253 MutateUrlToPath(path);
254 if (NeedToRemoveDoubleAndNormalizePathSeparators(path))
255 RemoveDoubleAndNormalizePathSeparators(path);
257 BINDER_LOG_STRING(W("platform path"), path);
259 BINDER_LOG_LEAVE(W("Utils::PlatformPath"));
262 void CombinePath(SString &pathA,
264 SString &combinedPath)
266 BINDER_LOG_ENTER(W("Utils::CombinePath"));
268 BINDER_LOG_STRING(W("path A"), pathA);
269 BINDER_LOG_STRING(W("path B"), pathB);
271 SString platformPathSeparator(SString::Literal, GetPlatformPathSeparator());
272 combinedPath.Set(pathA);
274 if (!combinedPath.EndsWith(platformPathSeparator))
276 combinedPath.Append(platformPathSeparator);
279 combinedPath.Append(pathB);
281 BINDER_LOG_LEAVE(W("Utils::CombinePath"));
284 HRESULT GetTokenFromPublicKey(SBuffer &publicKeyBLOB,
285 SBuffer &publicKeyTokenBLOB)
288 BINDER_LOG_ENTER(W("GetTokenFromPublicKey"));
290 const BYTE *pByteKey = publicKeyBLOB;
291 DWORD dwKeyLen = publicKeyBLOB.GetSize();
292 BYTE *pByteToken = NULL;
293 DWORD dwTokenLen = 0;
295 if (!StrongNameTokenFromPublicKey(const_cast<BYTE *>(pByteKey),
300 BINDER_LOG(W("StrongNameTokenFromPublicKey failed!"));
301 IF_FAIL_GO(StrongNameErrorInfo());
305 _ASSERTE(pByteToken != NULL);
306 publicKeyTokenBLOB.Set(pByteToken, dwTokenLen);
307 StrongNameFreeBuffer(pByteToken);
311 BINDER_LOG_LEAVE_HR(W("GetTokenFromPublicKey"), hr);
315 BOOL IsFileNotFound(HRESULT hr)
317 return RuntimeFileNotFound(hr);