Bazel client, Windows: implement GetHomeDir 

Create a method in blaze_util_<platform> to
retrieve the path to the home dir ($HOME on
Linux/macOS, %USERPROFILE% on Windows), where we
look for the user's bazelrc file (".bazelrc").

--
Change-Id: I86be1dbe1f992ad55eb09b496024754099d54912
Reviewed-on: https://cr.bazel.build/9513
PiperOrigin-RevId: 151004759
MOS_MIGRATED_REVID=151004759
diff --git a/src/main/cpp/BUILD b/src/main/cpp/BUILD
index 05a53c5..632fd79 100644
--- a/src/main/cpp/BUILD
+++ b/src/main/cpp/BUILD
@@ -52,6 +52,8 @@
         ],
         "//src:windows_msvc": [
             "-Wl,advapi32.lib",  # GetUserNameW
+            "-Wl,ole32.lib",  # CoTaskMemFree
+            "-Wl,shell32.lib",  # SHGetKnownFolderPath
             "-Wl,ws2_32.lib",  # grpc
         ],
         "//conditions:default": [
diff --git a/src/main/cpp/blaze_util_platform.h b/src/main/cpp/blaze_util_platform.h
index 2f313a4..f158b58 100644
--- a/src/main/cpp/blaze_util_platform.h
+++ b/src/main/cpp/blaze_util_platform.h
@@ -56,6 +56,10 @@
 // Returns the directory Bazel can use to store output.
 std::string GetOutputRoot();
 
+// Returns the current user's home directory, or the empty string if unknown.
+// On Linux/macOS, this is $HOME. On Windows this is %USERPROFILE%.
+std::string GetHomeDir();
+
 // Returns the location of the global bazelrc file if it exists, otherwise "".
 std::string FindSystemWideBlazerc();
 
diff --git a/src/main/cpp/blaze_util_posix.cc b/src/main/cpp/blaze_util_posix.cc
index 99070d4..dab5f0a 100644
--- a/src/main/cpp/blaze_util_posix.cc
+++ b/src/main/cpp/blaze_util_posix.cc
@@ -126,6 +126,8 @@
   return ToString(getpid());
 }
 
+string GetHomeDir() { return GetEnv("HOME"); }
+
 string FindSystemWideBlazerc() {
   string path = "/etc/bazel.bazelrc";
   if (blaze_util::CanReadFile(path)) {
diff --git a/src/main/cpp/blaze_util_windows.cc b/src/main/cpp/blaze_util_windows.cc
index e859da3..dbc5e32 100644
--- a/src/main/cpp/blaze_util_windows.cc
+++ b/src/main/cpp/blaze_util_windows.cc
@@ -24,14 +24,17 @@
 #include <sys/stat.h>
 #include <sys/statfs.h>
 #include <unistd.h>
-#endif  // not COMPILER_MSVC
+#endif  // COMPILER_MSVC
 
-#include <windows.h>
 #include <lmcons.h>  // UNLEN
+#include <windows.h>
 
 #ifdef COMPILER_MSVC
-#include <io.h>  // _open
-#endif  // COMPILER_MSVC
+#include <io.h>            // _open
+#include <knownfolders.h>  // FOLDERID_Profile
+#include <objbase.h>       // CoTaskMemFree
+#include <shlobj.h>        // SHGetKnownFolderPath
+#endif
 
 #include <algorithm>
 #include <cstdio>
@@ -334,9 +337,22 @@
 #endif  // COMPILER_MSVC
 }
 
+string GetHomeDir() {
+#ifdef COMPILER_MSVC
+  PWSTR wpath;
+  if (SUCCEEDED(::SHGetKnownFolderPath(FOLDERID_Profile, KF_FLAG_DEFAULT, NULL,
+                                       &wpath))) {
+    string result = string(blaze_util::WstringToCstring(wpath).get());
+    ::CoTaskMemFree(wpath);
+    return result;
+  }
+#endif
+  return GetEnv("HOME");  // only defined in MSYS/Cygwin
+}
+
 string FindSystemWideBlazerc() {
 #ifdef COMPILER_MSVC
-  // TODO(bazel-team): implement this.
+  // TODO(bazel-team): figure out a good path to return here.
   return "";
 #else   // not COMPILER_MSVC
   string path = "/etc/bazel.bazelrc";
diff --git a/src/main/cpp/option_processor.cc b/src/main/cpp/option_processor.cc
index f025c30..66a09e3 100644
--- a/src/main/cpp/option_processor.cc
+++ b/src/main/cpp/option_processor.cc
@@ -283,7 +283,7 @@
     return blaze_exit_code::SUCCESS;
   }
 
-  string home = blaze::GetEnv("HOME");
+  string home = blaze::GetHomeDir();
   if (home.empty()) {
     *blaze_rc_file = "";
     return blaze_exit_code::SUCCESS;