[Win] Properly parse all valid Win32 file urls.

We now make sure we properly parse all file:// urls properly for the
windows platform.

Includes a unit test to validate parsing.

This is a manual cherry-pick of aosp/1483306.

Change-Id: I80d16ee1ed77db3c6024635f16ddc6ae12106020
diff --git a/base/SharedMemory_posix.cpp b/base/SharedMemory_posix.cpp
index 5198a6d..7bb91c8 100644
--- a/base/SharedMemory_posix.cpp
+++ b/base/SharedMemory_posix.cpp
@@ -91,6 +91,11 @@
         mFd = shm_open(mName.c_str(), oflag, mode);
     } else {
         mFd = ::open(mName.c_str(), oflag, mode);
+        // Make sure the file can hold at least mSize bytes..
+        struct stat stat;
+        if (!fstat(mFd, &stat) && stat.st_size < mSize) {
+            ftruncate(mFd, mSize);
+        }
     }
     if (mFd == -1) {
         err = -errno;
diff --git a/base/SharedMemory_unittest.cpp b/base/SharedMemory_unittest.cpp
index 23bc50e..a1c29fd 100644
--- a/base/SharedMemory_unittest.cpp
+++ b/base/SharedMemory_unittest.cpp
@@ -58,8 +58,8 @@
 //             ts.getTempRoot()->path(), "shāred.mem");
 //     const mode_t user_read_only = 0600;
 //     std::string message = "Hello World!";
-//     base::SharedMemory mWriter("file://" + unique_name, message.size());
-//     base::SharedMemory mReader("file://" + unique_name, message.size());
+//     base::SharedMemory mWriter("file:///" + unique_name, message.size());
+//     base::SharedMemory mReader("file:///" + unique_name, message.size());
 // 
 //     ASSERT_FALSE(mWriter.isOpen());
 //     ASSERT_FALSE(mReader.isOpen());
diff --git a/base/SharedMemory_win32.cpp b/base/SharedMemory_win32.cpp
index 6b253f1..b6214dd 100644
--- a/base/SharedMemory_win32.cpp
+++ b/base/SharedMemory_win32.cpp
@@ -13,6 +13,7 @@
 // limitations under the License.
 #include "base/SharedMemory.h"
 
+#include <shlwapi.h>
 #include <cassert>
 #include <string>
 
@@ -25,9 +26,15 @@
 SharedMemory::SharedMemory(const std::string& name, size_t size) : mSize(size) {
     const std::string kFileUri = "file://";
     if (name.find(kFileUri, 0) == 0) {
+        // Convert URI to path using win32 api.
+        const Win32UnicodeString srcUri(name);
+        WCHAR path[MAX_PATH];
+        DWORD cPath = MAX_PATH;
+        auto HR = PathCreateFromUrlW(srcUri.c_str(), path, &cPath, NULL);
+        assert(HR == S_OK);
+        const Win32UnicodeString destPath(path);
+        mName = PathUtils::recompose(PathUtils::decompose(destPath.toString()));
         mShareType = ShareType::FILE_BACKED;
-        auto path = name.substr(kFileUri.size());
-        mName = PathUtils::recompose(PathUtils::decompose(path));
     } else {
         mShareType = ShareType::SHARED_MEMORY;
         mName = "SHM_" + name;