Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(634)

Unified Diff: third_party/crashpad/crashpad/util/file/file_io_win.cc

Issue 1505213004: Copy Crashpad into the Chrome tree instead of importing it via DEPS (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Address review comments, update README.chromium Created 5 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: third_party/crashpad/crashpad/util/file/file_io_win.cc
diff --git a/third_party/crashpad/crashpad/util/file/file_io_win.cc b/third_party/crashpad/crashpad/util/file/file_io_win.cc
new file mode 100644
index 0000000000000000000000000000000000000000..def2a5a2bf8d5592e3cda1ad5b5cce12c4d09d90
--- /dev/null
+++ b/third_party/crashpad/crashpad/util/file/file_io_win.cc
@@ -0,0 +1,239 @@
+// Copyright 2014 The Crashpad Authors. All rights reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#include "util/file/file_io.h"
+
+#include "base/files/file_path.h"
+#include "base/logging.h"
+#include "base/numerics/safe_conversions.h"
+#include "base/strings/utf_string_conversions.h"
+
+namespace {
+
+bool IsSocketHandle(HANDLE file) {
+ if (GetFileType(file) == FILE_TYPE_PIPE) {
+ // FILE_TYPE_PIPE means that it's a socket, a named pipe, or an anonymous
+ // pipe. If we are unable to retrieve the pipe information, we know it's a
+ // socket.
+ return !GetNamedPipeInfo(file, NULL, NULL, NULL, NULL);
+ }
+ return false;
+}
+
+} // namespace
+
+namespace crashpad {
+
+namespace {
+
+FileHandle OpenFileForOutput(DWORD access,
+ const base::FilePath& path,
+ FileWriteMode mode,
+ FilePermissions permissions) {
+ DCHECK(access & GENERIC_WRITE);
+ DCHECK_EQ(access & ~(GENERIC_READ | GENERIC_WRITE), 0u);
+
+ DWORD disposition = 0;
+ switch (mode) {
+ case FileWriteMode::kReuseOrFail:
+ disposition = OPEN_EXISTING;
+ break;
+ case FileWriteMode::kReuseOrCreate:
+ disposition = OPEN_ALWAYS;
+ break;
+ case FileWriteMode::kTruncateOrCreate:
+ disposition = CREATE_ALWAYS;
+ break;
+ case FileWriteMode::kCreateOrFail:
+ disposition = CREATE_NEW;
+ break;
+ }
+ return CreateFile(path.value().c_str(),
+ access,
+ FILE_SHARE_READ | FILE_SHARE_WRITE,
+ nullptr,
+ disposition,
+ FILE_ATTRIBUTE_NORMAL,
+ nullptr);
+}
+
+} // namespace
+
+// TODO(scottmg): Handle > DWORD sized writes if necessary.
+
+FileOperationResult ReadFile(FileHandle file, void* buffer, size_t size) {
+ DCHECK(!IsSocketHandle(file));
+ DWORD size_dword = base::checked_cast<DWORD>(size);
+ DWORD total_read = 0;
+ char* buffer_c = reinterpret_cast<char*>(buffer);
+ while (size_dword > 0) {
+ DWORD bytes_read;
+ BOOL success = ::ReadFile(file, buffer_c, size_dword, &bytes_read, nullptr);
+ if (!success) {
+ if (GetLastError() == ERROR_BROKEN_PIPE) {
+ // When reading a pipe and the write handle has been closed, ReadFile
+ // fails with ERROR_BROKEN_PIPE, but only once all pending data has been
+ // read.
+ break;
+ } else if (GetLastError() != ERROR_MORE_DATA) {
+ return -1;
+ }
+ } else if (bytes_read == 0 && GetFileType(file) != FILE_TYPE_PIPE) {
+ // Zero bytes read for a file indicates reaching EOF. Zero bytes read from
+ // a pipe indicates only that there was a zero byte WriteFile issued on
+ // the other end, so continue reading.
+ break;
+ }
+
+ buffer_c += bytes_read;
+ size_dword -= bytes_read;
+ total_read += bytes_read;
+ }
+ return total_read;
+}
+
+FileOperationResult WriteFile(FileHandle file,
+ const void* buffer,
+ size_t size) {
+ // TODO(scottmg): This might need to handle the limit for pipes across a
+ // network in the future.
+ DWORD size_dword = base::checked_cast<DWORD>(size);
+ DWORD bytes_written;
+ BOOL rv = ::WriteFile(file, buffer, size_dword, &bytes_written, nullptr);
+ if (!rv)
+ return -1;
+ CHECK_EQ(bytes_written, size_dword);
+ return bytes_written;
+}
+
+FileHandle OpenFileForRead(const base::FilePath& path) {
+ return CreateFile(path.value().c_str(),
+ GENERIC_READ,
+ FILE_SHARE_READ | FILE_SHARE_WRITE,
+ nullptr,
+ OPEN_EXISTING,
+ 0,
+ nullptr);
+}
+
+FileHandle OpenFileForWrite(const base::FilePath& path,
+ FileWriteMode mode,
+ FilePermissions permissions) {
+ return OpenFileForOutput(GENERIC_WRITE, path, mode, permissions);
+}
+
+FileHandle OpenFileForReadAndWrite(const base::FilePath& path,
+ FileWriteMode mode,
+ FilePermissions permissions) {
+ return OpenFileForOutput(
+ GENERIC_READ | GENERIC_WRITE, path, mode, permissions);
+}
+
+FileHandle LoggingOpenFileForRead(const base::FilePath& path) {
+ FileHandle file = OpenFileForRead(path);
+ PLOG_IF(ERROR, file == INVALID_HANDLE_VALUE)
+ << "CreateFile " << base::UTF16ToUTF8(path.value());
+ return file;
+}
+
+FileHandle LoggingOpenFileForWrite(const base::FilePath& path,
+ FileWriteMode mode,
+ FilePermissions permissions) {
+ FileHandle file = OpenFileForWrite(path, mode, permissions);
+ PLOG_IF(ERROR, file == INVALID_HANDLE_VALUE)
+ << "CreateFile " << base::UTF16ToUTF8(path.value());
+ return file;
+}
+
+FileHandle LoggingOpenFileForReadAndWrite(const base::FilePath& path,
+ FileWriteMode mode,
+ FilePermissions permissions) {
+ FileHandle file = OpenFileForReadAndWrite(path, mode, permissions);
+ PLOG_IF(ERROR, file == INVALID_HANDLE_VALUE)
+ << "CreateFile " << base::UTF16ToUTF8(path.value());
+ return file;
+}
+
+bool LoggingLockFile(FileHandle file, FileLocking locking) {
+ DWORD flags =
+ (locking == FileLocking::kExclusive) ? LOCKFILE_EXCLUSIVE_LOCK : 0;
+
+ // Note that the `Offset` fields of overlapped indicate the start location for
+ // locking (beginning of file in this case), and `hEvent` must be also be set
+ // to 0.
+ OVERLAPPED overlapped = {0};
+ if (!LockFileEx(file, flags, 0, MAXDWORD, MAXDWORD, &overlapped)) {
+ PLOG(ERROR) << "LockFileEx";
+ return false;
+ }
+ return true;
+}
+
+bool LoggingUnlockFile(FileHandle file) {
+ // Note that the `Offset` fields of overlapped indicate the start location for
+ // locking (beginning of file in this case), and `hEvent` must be also be set
+ // to 0.
+ OVERLAPPED overlapped = {0};
+ if (!UnlockFileEx(file, 0, MAXDWORD, MAXDWORD, &overlapped)) {
+ PLOG(ERROR) << "UnlockFileEx";
+ return false;
+ }
+ return true;
+}
+
+FileOffset LoggingSeekFile(FileHandle file, FileOffset offset, int whence) {
+ DWORD method = 0;
+ switch (whence) {
+ case SEEK_SET:
+ method = FILE_BEGIN;
+ break;
+ case SEEK_CUR:
+ method = FILE_CURRENT;
+ break;
+ case SEEK_END:
+ method = FILE_END;
+ break;
+ default:
+ NOTREACHED();
+ break;
+ }
+
+ LARGE_INTEGER distance_to_move;
+ distance_to_move.QuadPart = offset;
+ LARGE_INTEGER new_offset;
+ BOOL result = SetFilePointerEx(file, distance_to_move, &new_offset, method);
+ if (!result) {
+ PLOG(ERROR) << "SetFilePointerEx";
+ return -1;
+ }
+ return new_offset.QuadPart;
+}
+
+bool LoggingTruncateFile(FileHandle file) {
+ if (LoggingSeekFile(file, 0, SEEK_SET) != 0)
+ return false;
+ if (!SetEndOfFile(file)) {
+ PLOG(ERROR) << "SetEndOfFile";
+ return false;
+ }
+ return true;
+}
+
+bool LoggingCloseFile(FileHandle file) {
+ BOOL rv = CloseHandle(file);
+ PLOG_IF(ERROR, !rv) << "CloseHandle";
+ return !!rv;
+}
+
+} // namespace crashpad

Powered by Google App Engine
This is Rietveld 408576698