| Index: base/sync_socket_win.cc
|
| ===================================================================
|
| --- base/sync_socket_win.cc (revision 0)
|
| +++ base/sync_socket_win.cc (revision 0)
|
| @@ -0,0 +1,144 @@
|
| +// Copyright (c) 2009 The Chromium Authors. All rights reserved.
|
| +// Use of this source code is governed by a BSD-style license that can be
|
| +// found in the LICENSE file.
|
| +
|
| +#include "base/sync_socket.h"
|
| +#include <limits.h>
|
| +#include <stdio.h>
|
| +#include <windows.h>
|
| +#include <sys/types.h>
|
| +#include "base/atomicops.h"
|
| +#include "base/logging.h"
|
| +
|
| +
|
| +namespace base {
|
| +
|
| +namespace {
|
| +// This prefix used to be appended to pipe names for pipes
|
| +// created in CreatePair.
|
| +const wchar_t kPipePrefix[] = L"\\\\.\\pipe\\chrome.sync.";
|
| +const size_t kPipePrefixSize = arraysize(kPipePrefix);
|
| +const size_t kPathMax = 28; // print length of process id + pair count.
|
| +const size_t kPipePathMax = kPipePrefixSize + kPathMax + 1;
|
| +
|
| +// To avoid users sending negative message lengths to Send/Receive
|
| +// we clamp message lengths, which are size_t, to no more than INT_MAX.
|
| +const size_t kMaxMessageLength = static_cast<size_t>(INT_MAX);
|
| +
|
| +const int kOutBufferSize = 4096;
|
| +const int kInBufferSize = 4096;
|
| +const int kDefaultTimeoutMilliSeconds = 1000;
|
| +
|
| +static const SyncSocket::Handle kInvalidHandle = INVALID_HANDLE_VALUE;
|
| +
|
| +} // namespace
|
| +
|
| +bool SyncSocket::CreatePair(SyncSocket* pair[2]) {
|
| + Handle handles[2];
|
| + SyncSocket* tmp_sockets[2];
|
| +
|
| + // Create the two SyncSocket objects first to avoid ugly cleanup issues.
|
| + tmp_sockets[0] = new SyncSocket(kInvalidHandle);
|
| + if (tmp_sockets[0] == NULL) {
|
| + return false;
|
| + }
|
| + tmp_sockets[1] = new SyncSocket(kInvalidHandle);
|
| + if (tmp_sockets[1] == NULL) {
|
| + delete tmp_sockets[0];
|
| + return false;
|
| + }
|
| +
|
| + wchar_t name[kPipePathMax];
|
| + do {
|
| + unsigned int rnd_name;
|
| + if (rand_s(&rnd_name) != 0)
|
| + return false;
|
| + swprintf(name, kPipePathMax, L"%s%u.%lu",
|
| + kPipePrefix, GetCurrentProcessId(),
|
| + rnd_name);
|
| + handles[0] = CreateNamedPipeW(
|
| + name,
|
| + PIPE_ACCESS_DUPLEX | FILE_FLAG_FIRST_PIPE_INSTANCE,
|
| + PIPE_TYPE_BYTE | PIPE_READMODE_BYTE,
|
| + 1,
|
| + kOutBufferSize,
|
| + kInBufferSize,
|
| + kDefaultTimeoutMilliSeconds,
|
| + NULL);
|
| + if (handles[0] == INVALID_HANDLE_VALUE &&
|
| + GetLastError() != ERROR_ACCESS_DENIED &&
|
| + GetLastError() != ERROR_PIPE_BUSY) {
|
| + return false;
|
| + }
|
| + } while (handles[0] == INVALID_HANDLE_VALUE);
|
| + handles[1] = CreateFileW(name,
|
| + GENERIC_READ | GENERIC_WRITE,
|
| + 0, // no sharing.
|
| + NULL, // default security attributes.
|
| + OPEN_EXISTING, // opens existing pipe.
|
| + SECURITY_SQOS_PRESENT | SECURITY_ANONYMOUS,
|
| + // no impersonation.
|
| + NULL); // no template file.
|
| + if (handles[1] == INVALID_HANDLE_VALUE) {
|
| + CloseHandle(handles[0]);
|
| + return false;
|
| + }
|
| + if (ConnectNamedPipe(handles[0], NULL) == FALSE) {
|
| + DWORD error = GetLastError();
|
| + if (error != ERROR_PIPE_CONNECTED) {
|
| + CloseHandle(handles[0]);
|
| + CloseHandle(handles[1]);
|
| + return false;
|
| + }
|
| + }
|
| + // Copy the handles out for successful return.
|
| + tmp_sockets[0]->handle_ = handles[0];
|
| + pair[0] = tmp_sockets[0];
|
| + tmp_sockets[1]->handle_ = handles[1];
|
| + pair[1] = tmp_sockets[1];
|
| + return true;
|
| +}
|
| +
|
| +bool SyncSocket::Close() {
|
| + if (handle_ == kInvalidHandle) {
|
| + return false;
|
| + }
|
| + BOOL retval = CloseHandle(handle_);
|
| + handle_ = kInvalidHandle;
|
| + return retval ? true : false;
|
| +}
|
| +
|
| +size_t SyncSocket::Send(const void* buffer, size_t length) {
|
| + DCHECK(length <= kMaxMessageLength);
|
| + size_t count = 0;
|
| + while (count < length) {
|
| + DWORD len;
|
| + // The following statement is for 64 bit portability.
|
| + DWORD chunk = static_cast<DWORD>(
|
| + ((length - count) <= UINT_MAX) ? (length - count) : UINT_MAX);
|
| + if (WriteFile(handle_, static_cast<const char*>(buffer) + count,
|
| + chunk, &len, NULL) == FALSE) {
|
| + return (0 < count) ? count : 0;
|
| + }
|
| + count += len;
|
| + }
|
| + return count;
|
| +}
|
| +
|
| +size_t SyncSocket::Receive(void* buffer, size_t length) {
|
| + DCHECK(length <= kMaxMessageLength);
|
| + size_t count = 0;
|
| + while (count < length) {
|
| + DWORD len;
|
| + DWORD chunk = static_cast<DWORD>(
|
| + ((length - count) <= UINT_MAX) ? (length - count) : UINT_MAX);
|
| + if (ReadFile(handle_, static_cast<char*>(buffer) + count,
|
| + chunk, &len, NULL) == FALSE) {
|
| + return (0 < count) ? count : 0;
|
| + }
|
| + count += len;
|
| + }
|
| + return count;
|
| +}
|
| +
|
| +} // namespace base
|
|
|
| Property changes on: base\sync_socket_win.cc
|
| ___________________________________________________________________
|
| Added: svn:eol-style
|
| + LF
|
|
|
|
|