Bumping manifests a=b2g-bump
[gecko.git] / xpcom / io / FileUtilsWin.h
blobc0b008b13daee8d46eb166bdee951b95b09d0258
1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
3 /* This Source Code Form is subject to the terms of the Mozilla Public
4 * License, v. 2.0. If a copy of the MPL was not distributed with this
5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
7 #ifndef mozilla_FileUtilsWin_h
8 #define mozilla_FileUtilsWin_h
10 #include <windows.h>
12 #include "mozilla/Scoped.h"
13 #include "nsStringGlue.h"
15 namespace mozilla {
17 inline bool
18 NtPathToDosPath(const nsAString& aNtPath, nsAString& aDosPath)
20 aDosPath.Truncate();
21 if (aNtPath.IsEmpty()) {
22 return true;
24 NS_NAMED_LITERAL_STRING(symLinkPrefix, "\\??\\");
25 uint32_t ntPathLen = aNtPath.Length();
26 uint32_t symLinkPrefixLen = symLinkPrefix.Length();
27 if (ntPathLen >= 6 && aNtPath.CharAt(5) == L':' &&
28 ntPathLen >= symLinkPrefixLen &&
29 Substring(aNtPath, 0, symLinkPrefixLen).Equals(symLinkPrefix)) {
30 // Symbolic link for DOS device. Just strip off the prefix.
31 aDosPath = aNtPath;
32 aDosPath.Cut(0, 4);
33 return true;
35 nsAutoString logicalDrives;
36 DWORD len = 0;
37 while (true) {
38 len = GetLogicalDriveStringsW(
39 len, reinterpret_cast<wchar_t*>(logicalDrives.BeginWriting()));
40 if (!len) {
41 return false;
42 } else if (len > logicalDrives.Length()) {
43 logicalDrives.SetLength(len);
44 } else {
45 break;
48 const char16_t* cur = logicalDrives.BeginReading();
49 const char16_t* end = logicalDrives.EndReading();
50 nsString targetPath;
51 targetPath.SetLength(MAX_PATH);
52 wchar_t driveTemplate[] = L" :";
53 do {
54 // Unfortunately QueryDosDevice doesn't support the idiom for querying the
55 // output buffer size, so it may require retries.
56 driveTemplate[0] = *cur;
57 DWORD targetPathLen = 0;
58 SetLastError(ERROR_SUCCESS);
59 while (true) {
60 targetPathLen = QueryDosDeviceW(driveTemplate,
61 reinterpret_cast<wchar_t*>(targetPath.BeginWriting()),
62 targetPath.Length());
63 if (targetPathLen || GetLastError() != ERROR_INSUFFICIENT_BUFFER) {
64 break;
66 targetPath.SetLength(targetPath.Length() * 2);
68 if (targetPathLen) {
69 // Need to use wcslen here because targetPath contains embedded NULL chars
70 size_t firstTargetPathLen = wcslen(targetPath.get());
71 const char16_t* pathComponent = aNtPath.BeginReading() +
72 firstTargetPathLen;
73 bool found = _wcsnicmp(char16ptr_t(aNtPath.BeginReading()), targetPath.get(),
74 firstTargetPathLen) == 0 &&
75 *pathComponent == L'\\';
76 if (found) {
77 aDosPath = driveTemplate;
78 aDosPath += pathComponent;
79 return true;
82 // Advance to the next NUL character in logicalDrives
83 while (*cur++);
84 } while (cur != end);
85 // Try to handle UNC paths. NB: This must happen after we've checked drive
86 // mappings in case a UNC path is mapped to a drive!
87 NS_NAMED_LITERAL_STRING(uncPrefix, "\\\\");
88 NS_NAMED_LITERAL_STRING(deviceMupPrefix, "\\Device\\Mup\\");
89 if (StringBeginsWith(aNtPath, deviceMupPrefix)) {
90 aDosPath = uncPrefix;
91 aDosPath += Substring(aNtPath, deviceMupPrefix.Length());
92 return true;
94 NS_NAMED_LITERAL_STRING(deviceLanmanRedirectorPrefix,
95 "\\Device\\LanmanRedirector\\");
96 if (StringBeginsWith(aNtPath, deviceLanmanRedirectorPrefix)) {
97 aDosPath = uncPrefix;
98 aDosPath += Substring(aNtPath, deviceLanmanRedirectorPrefix.Length());
99 return true;
101 return false;
104 bool
105 HandleToFilename(HANDLE aHandle, const LARGE_INTEGER& aOffset,
106 nsAString& aFilename);
108 } // namespace mozilla
110 #endif // mozilla_FileUtilsWin_h