xpcom/tests/windows/TestNtPathToDosPath.cpp

Sat, 03 Jan 2015 20:18:00 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Sat, 03 Jan 2015 20:18:00 +0100
branch
TOR_BUG_3246
changeset 7
129ffea94266
permissions
-rw-r--r--

Conditionally enable double key logic according to:
private browsing mode or privacy.thirdparty.isolate preference and
implement in GetCookieStringCommon and FindCookie where it counts...
With some reservations of how to convince FindCookie users to test
condition and pass a nullptr when disabling double key logic.

     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 #include "TestHarness.h"
     9 #include <windows.h>
    10 #include <winnetwk.h>
    12 #include "mozilla/FileUtilsWin.h"
    13 #include "mozilla/DebugOnly.h"
    14 #include "nsCRTGlue.h"
    16 class DriveMapping
    17 {
    18 public:
    19   DriveMapping(const nsAString& aRemoteUNCPath);
    20   ~DriveMapping();
    22   bool
    23   Init();
    24   bool
    25   ChangeDriveLetter();
    26   wchar_t
    27   GetDriveLetter() { return mDriveLetter; }
    29 private:
    30   bool
    31   DoMapping();
    32   void
    33   Disconnect(wchar_t aDriveLetter);
    35   wchar_t   mDriveLetter;
    36   nsString  mRemoteUNCPath;
    37 };
    39 DriveMapping::DriveMapping(const nsAString& aRemoteUNCPath)
    40   : mDriveLetter(0)
    41   , mRemoteUNCPath(aRemoteUNCPath)
    42 {
    43 }
    45 bool
    46 DriveMapping::Init()
    47 {
    48   if (mDriveLetter) {
    49     return false;
    50   }
    51   return DoMapping();
    52 }
    54 bool
    55 DriveMapping::DoMapping()
    56 {
    57   wchar_t drvTemplate[] = L" :";
    58   NETRESOURCEW netRes = {0};
    59   netRes.dwType = RESOURCETYPE_DISK;
    60   netRes.lpLocalName = drvTemplate;
    61   netRes.lpRemoteName = reinterpret_cast<wchar_t*>(mRemoteUNCPath.BeginWriting());
    62   wchar_t driveLetter = L'D';
    63   DWORD result = NO_ERROR;
    64   do {
    65     drvTemplate[0] = driveLetter;
    66     result = WNetAddConnection2W(&netRes, nullptr, nullptr, CONNECT_TEMPORARY);
    67   } while (result == ERROR_ALREADY_ASSIGNED && ++driveLetter <= L'Z');
    68   if (result != NO_ERROR) {
    69     return false;
    70   }
    71   mDriveLetter = driveLetter;
    72   return true;
    73 }
    75 bool
    76 DriveMapping::ChangeDriveLetter()
    77 {
    78   wchar_t prevDriveLetter = mDriveLetter;
    79   bool result = DoMapping();
    80   MOZ_ASSERT(mDriveLetter != prevDriveLetter);
    81   if (result && prevDriveLetter) {
    82     Disconnect(prevDriveLetter);
    83   }
    84   return result;
    85 }
    87 void
    88 DriveMapping::Disconnect(wchar_t aDriveLetter)
    89 {
    90   wchar_t drvTemplate[] = {aDriveLetter, L':', L'\0'};
    91   mozilla::DebugOnly<DWORD> result = WNetCancelConnection2W(drvTemplate, 0, TRUE);
    92   MOZ_ASSERT(result == NO_ERROR);
    93 }
    95 DriveMapping::~DriveMapping()
    96 {
    97   if (mDriveLetter) {
    98     Disconnect(mDriveLetter);
    99   }
   100 }
   102 bool
   103 DriveToNtPath(const wchar_t aDriveLetter, nsAString& aNtPath)
   104 {
   105   const wchar_t drvTpl[] = {aDriveLetter, L':', L'\0'};
   106   aNtPath.SetLength(MAX_PATH);
   107   DWORD pathLen;
   108   while (true) {
   109     pathLen = QueryDosDeviceW(drvTpl, reinterpret_cast<wchar_t*>(aNtPath.BeginWriting()), aNtPath.Length());
   110     if (pathLen || GetLastError() != ERROR_INSUFFICIENT_BUFFER) {
   111       break;
   112     }
   113     aNtPath.SetLength(aNtPath.Length() * 2);
   114   }
   115   if (!pathLen) {
   116     return false;
   117   }
   118   // aNtPath contains embedded NULLs, so we need to figure out the real length
   119   // via wcslen.
   120   aNtPath.SetLength(NS_strlen(aNtPath.BeginReading()));
   121   return true;
   122 }
   124 bool
   125 TestNtPathToDosPath(const wchar_t* aNtPath,
   126                     const wchar_t* aExpectedDosPath)
   127 {
   128   nsAutoString output;
   129   bool result = mozilla::NtPathToDosPath(nsDependentString(aNtPath), output);
   130   return result && output == aExpectedDosPath;
   131 }
   133 int main(int argc, char* argv[])
   134 {
   135   ScopedXPCOM xpcom("NtPathToDosPath");
   136   if (xpcom.failed()) {
   137     fail("XPCOM Startup");
   138     return 1;
   139   }
   140   nsAutoString cDrive;
   141   if (!DriveToNtPath(L'C', cDrive)) {
   142     fail("Querying for this machine's C:");
   143     return 1;
   144   }
   146   int result = 0;
   148   // empty string
   149   if (!TestNtPathToDosPath(L"", L"")) {
   150     fail("Empty string");
   151     result = 1;
   152   }
   153   // non-existent device, must fail
   154   if (TestNtPathToDosPath(L"\\Device\\ThisDeviceDoesNotExist\\Foo", nullptr)) {
   155     fail("Non-existent device");
   156     result = 1;
   157   }
   158   // base case
   159   nsAutoString testPath(cDrive);
   160   testPath.Append(L"\\Foo");
   161   if (!TestNtPathToDosPath(testPath.get(), L"C:\\Foo")) {
   162     fail("Base case");
   163     result = 1;
   164   }
   165   // drive letters as symbolic links (NtCreateFile uses these)
   166   if (!TestNtPathToDosPath(L"\\??\\C:\\Foo", L"C:\\Foo")) {
   167     fail("Path specified as symbolic link");
   168     result = 1;
   169   }
   170   // other symbolic links (should fail)
   171   if (TestNtPathToDosPath(L"\\??\\MountPointManager", nullptr)) {
   172     fail("Other symbolic link");
   173     result = 1;
   174   }
   175   // socket (should fail)
   176   if (TestNtPathToDosPath(L"\\Device\\Afd\\Endpoint", nullptr)) {
   177     fail("Socket");
   178     result = 1;
   179   }
   180   // currently UNC paths that are not mapped to drive letters are unsupported,
   181   // so this should fail
   182   if (TestNtPathToDosPath(L"\\Device\\Mup\\127.0.0.1\\C$", nullptr)) {
   183     fail("Unmapped UNC path");
   184     result = 1;
   185   }
   186   DriveMapping drvMapping(NS_LITERAL_STRING("\\\\127.0.0.1\\C$"));
   187   // Only run these tests if we were able to map; some machines don't have perms
   188   if (drvMapping.Init()) {
   189     wchar_t expected[] = L" :\\";
   190     expected[0] = drvMapping.GetDriveLetter();
   191     nsAutoString networkPath;
   192     if (!DriveToNtPath(drvMapping.GetDriveLetter(), networkPath)) {
   193       fail("Querying network drive");
   194       return 1;
   195     }
   196     networkPath += MOZ_UTF16("\\");
   197     if (!TestNtPathToDosPath(networkPath.get(), expected)) {
   198       fail("Mapped UNC path");
   199       result = 1;
   200     }
   201     // NtPathToDosPath must correctly handle paths whose drive letter mapping has
   202     // changed. We need to test this because the APIs called by NtPathToDosPath
   203     // return different info if this has happened.
   204     if (!drvMapping.ChangeDriveLetter()) {
   205       fail("Change drive letter");
   206       return 1;
   207     }
   208     expected[0] = drvMapping.GetDriveLetter();
   209     if (!DriveToNtPath(drvMapping.GetDriveLetter(), networkPath)) {
   210       fail("Querying second network drive");
   211       return 1;
   212     }
   213     networkPath += MOZ_UTF16("\\");
   214     if (!TestNtPathToDosPath(networkPath.get(), expected)) {
   215       fail("Re-mapped UNC path");
   216       result = 1;
   217     }
   218   }
   220   return result;
   221 }

mercurial