Delete read-only files on Windows, too

Fixes main complaint of #1886.
diff --git a/src/disk_interface.cc b/src/disk_interface.cc
index 49af001..8d4cc7f 100644
--- a/src/disk_interface.cc
+++ b/src/disk_interface.cc
@@ -265,6 +265,23 @@
 }
 
 int RealDiskInterface::RemoveFile(const string& path) {
+#ifdef _WIN32
+  DWORD attributes = GetFileAttributes(path.c_str());
+  if (attributes == INVALID_FILE_ATTRIBUTES &&
+      GetLastError() == ERROR_FILE_NOT_FOUND) {
+    return 1;
+  }
+  if (attributes & FILE_ATTRIBUTE_READONLY) {
+    // On non-Windows systems remove will happily delete read-only files. On
+    // Windows Ninja should behave the same. See
+    // https://github.com/ninja-build/ninja/issues/1886
+    SetFileAttributes(path.c_str(), attributes & ~FILE_ATTRIBUTE_READONLY);
+  }
+  if (!DeleteFile(path.c_str())) {
+    Error("remove(%s): %s", path.c_str(), GetLastErrorString().c_str());
+    return -1;
+  }
+#else
   if (remove(path.c_str()) < 0) {
     switch (errno) {
       case ENOENT:
@@ -273,9 +290,9 @@
         Error("remove(%s): %s", path.c_str(), strerror(errno));
         return -1;
     }
-  } else {
-    return 0;
   }
+#endif
+  return 0;
 }
 
 void RealDiskInterface::AllowStatCache(bool allow) {
diff --git a/src/disk_interface_test.cc b/src/disk_interface_test.cc
index 066c770..b424243 100644
--- a/src/disk_interface_test.cc
+++ b/src/disk_interface_test.cc
@@ -211,6 +211,12 @@
   EXPECT_EQ(0, disk_.RemoveFile(kFileName));
   EXPECT_EQ(1, disk_.RemoveFile(kFileName));
   EXPECT_EQ(1, disk_.RemoveFile("does not exist"));
+#ifdef _WIN32
+  ASSERT_TRUE(Touch(kFileName));
+  EXPECT_EQ(0, system((std::string("attrib +R ") + kFileName).c_str()));
+  EXPECT_EQ(0, disk_.RemoveFile(kFileName));
+  EXPECT_EQ(1, disk_.RemoveFile(kFileName));
+#endif
 }
 
 struct StatTest : public StateTestWithBuiltinRules,