Index: util/file/file_io_win.cc |
diff --git a/minidump/minidump_writer_util.cc b/util/file/file_io_win.cc |
similarity index 29% |
copy from minidump/minidump_writer_util.cc |
copy to util/file/file_io_win.cc |
index fcaa40420e3a4ac0d406d27fef243f7303d5468f..b1640dd0424759be13168bef86f7beb1627d9747 100644 |
--- a/minidump/minidump_writer_util.cc |
+++ b/util/file/file_io_win.cc |
@@ -12,50 +12,70 @@ |
// See the License for the specific language governing permissions and |
// limitations under the License. |
-#include "minidump/minidump_writer_util.h" |
+#include "util/file/file_io.h" |
#include "base/logging.h" |
#include "base/numerics/safe_conversions.h" |
-#include "base/strings/utf_string_conversions.h" |
-#include "util/stdlib/strlcpy.h" |
-namespace crashpad { |
-namespace internal { |
+namespace { |
-// static |
-void MinidumpWriterUtil::AssignTimeT(uint32_t* destination, time_t source) { |
- if (!base::IsValueInRangeForNumericType<uint32_t>(source)) { |
- LOG(WARNING) << "timestamp " << source << " out of range"; |
+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); |
} |
- |
- *destination = source; |
+ return false; |
} |
-// static |
-base::string16 MinidumpWriterUtil::ConvertUTF8ToUTF16(const std::string& utf8) { |
- base::string16 utf16; |
- if (!base::UTF8ToUTF16(utf8.data(), utf8.length(), &utf16)) { |
- LOG(WARNING) << "string " << utf8 |
- << " cannot be converted to UTF-16 losslessly"; |
+} // namespace |
+ |
+namespace crashpad { |
+ |
+// TODO(scottmg): Handle > DWORD sized writes if necessary. |
+ |
+ssize_t 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 && GetLastError() != ERROR_MORE_DATA) { |
+ return -1; |
+ } else if (success && 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 utf16; |
+ return total_read; |
} |
-// static |
-void MinidumpWriterUtil::AssignUTF8ToUTF16(base::char16* destination, |
- size_t destination_size, |
- const std::string& source) { |
- base::string16 source_utf16 = ConvertUTF8ToUTF16(source); |
- if (source_utf16.size() > destination_size - 1) { |
- LOG(WARNING) << "string " << source << " UTF-16 length " |
- << source_utf16.size() |
- << " will be truncated to UTF-16 length " |
- << destination_size - 1; |
- } |
+ssize_t 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; |
+} |
- source_utf16.resize(destination_size - 1); |
- c16lcpy(destination, source_utf16.c_str(), destination_size); |
+bool LoggingCloseFile(FileHandle file) { |
+ BOOL rv = CloseHandle(file); |
+ PLOG_IF(ERROR, !rv) << "CloseHandle"; |
+ return rv; |
} |
-} // namespace internal |
} // namespace crashpad |