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

Side by Side Diff: ipc/attachment_broker_privileged_win_unittest.cc

Issue 2473993003: Delete IPC::ChannelPosix, IPC::ChannelWin and IPC::AttachmentBroker. (Closed)
Patch Set: Created 4 years, 1 month 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 unified diff | Download patch
« no previous file with comments | « ipc/attachment_broker_privileged_win.cc ('k') | ipc/attachment_broker_unprivileged.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 // Copyright 2015 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "build/build_config.h"
6
7 #include <windows.h>
8
9 #include <memory>
10 #include <tuple>
11
12 #include "base/files/file_path.h"
13 #include "base/files/file_util.h"
14 #include "base/files/scoped_temp_dir.h"
15 #include "base/memory/shared_memory.h"
16 #include "base/memory/shared_memory_handle.h"
17 #include "base/run_loop.h"
18 #include "base/win/scoped_handle.h"
19 #include "ipc/attachment_broker_privileged_win.h"
20 #include "ipc/attachment_broker_unprivileged_win.h"
21 #include "ipc/handle_attachment_win.h"
22 #include "ipc/handle_win.h"
23 #include "ipc/ipc_listener.h"
24 #include "ipc/ipc_message.h"
25 #include "ipc/ipc_test_base.h"
26 #include "ipc/ipc_test_messages.h"
27
28 namespace {
29
30 using base::win::ScopedHandle;
31
32 const char kDataBuffer[] = "This is some test data to write to the file.";
33 const size_t kSharedMemorySize = 20000;
34
35 // Returns the contents of the file represented by |h| as a std::string.
36 std::string ReadFromFile(HANDLE h) {
37 SetFilePointer(h, 0, nullptr, FILE_BEGIN);
38 char buffer[100];
39 DWORD bytes_read;
40 BOOL success = ::ReadFile(h, buffer, static_cast<DWORD>(strlen(kDataBuffer)),
41 &bytes_read, nullptr);
42 return success ? std::string(buffer, bytes_read) : std::string();
43 }
44
45 ScopedHandle GetHandleFromBrokeredAttachment(
46 const scoped_refptr<IPC::BrokerableAttachment>& attachment) {
47 if (attachment->GetType() !=
48 IPC::BrokerableAttachment::TYPE_BROKERABLE_ATTACHMENT) {
49 LOG(INFO) << "Attachment type not TYPE_BROKERABLE_ATTACHMENT.";
50 return ScopedHandle(nullptr);
51 }
52
53 if (attachment->GetBrokerableType() !=
54 IPC::BrokerableAttachment::WIN_HANDLE) {
55 LOG(INFO) << "Brokerable type not WIN_HANDLE.";
56 return ScopedHandle(nullptr);
57 }
58
59 IPC::internal::HandleAttachmentWin* received_handle_attachment =
60 static_cast<IPC::internal::HandleAttachmentWin*>(attachment.get());
61 ScopedHandle h(received_handle_attachment->get_handle());
62 received_handle_attachment->reset_handle_ownership();
63 return h;
64 }
65
66 // |message| must be deserializable as a TestHandleWinMsg. Returns the HANDLE,
67 // or nullptr if deserialization failed.
68 ScopedHandle GetHandleFromTestHandleWinMsg(const IPC::Message& message) {
69 // Expect a message with a brokered attachment.
70 if (!message.HasBrokerableAttachments()) {
71 LOG(INFO) << "Message missing brokerable attachment.";
72 return ScopedHandle(nullptr);
73 }
74
75 TestHandleWinMsg::Schema::Param p;
76 bool success = TestHandleWinMsg::Read(&message, &p);
77 if (!success) {
78 LOG(INFO) << "Failed to deserialize message.";
79 return ScopedHandle(nullptr);
80 }
81
82 IPC::HandleWin handle_win = std::get<1>(p);
83 return ScopedHandle(handle_win.get_handle());
84 }
85
86 // Returns a mapped, shared memory region based on the handle in |message|.
87 std::unique_ptr<base::SharedMemory> GetSharedMemoryFromSharedMemoryHandleMsg1(
88 const IPC::Message& message,
89 size_t size) {
90 // Expect a message with a brokered attachment.
91 if (!message.HasBrokerableAttachments()) {
92 LOG(INFO) << "Message missing brokerable attachment.";
93 return nullptr;
94 }
95
96 TestSharedMemoryHandleMsg1::Schema::Param p;
97 bool success = TestSharedMemoryHandleMsg1::Read(&message, &p);
98 if (!success) {
99 LOG(INFO) << "Failed to deserialize message.";
100 return nullptr;
101 }
102
103 base::SharedMemoryHandle handle = std::get<0>(p);
104 std::unique_ptr<base::SharedMemory> shared_memory(
105 new base::SharedMemory(handle, false));
106
107 shared_memory->Map(size);
108 return shared_memory;
109 }
110
111 // |message| must be deserializable as a TestTwoHandleWinMsg. Returns the
112 // HANDLE, or nullptr if deserialization failed.
113 bool GetHandleFromTestTwoHandleWinMsg(const IPC::Message& message,
114 HANDLE* h1,
115 HANDLE* h2) {
116 // Expect a message with a brokered attachment.
117 if (!message.HasBrokerableAttachments()) {
118 LOG(INFO) << "Message missing brokerable attachment.";
119 return false;
120 }
121
122 TestTwoHandleWinMsg::Schema::Param p;
123 bool success = TestTwoHandleWinMsg::Read(&message, &p);
124 if (!success) {
125 LOG(INFO) << "Failed to deserialize message.";
126 return false;
127 }
128
129 IPC::HandleWin handle_win = std::get<0>(p);
130 *h1 = handle_win.get_handle();
131 handle_win = std::get<1>(p);
132 *h2 = handle_win.get_handle();
133 return true;
134 }
135
136 // |message| must be deserializable as a TestHandleWinMsg. Returns true if the
137 // attached file HANDLE has contents |kDataBuffer|.
138 bool CheckContentsOfTestMessage(const IPC::Message& message) {
139 ScopedHandle h(GetHandleFromTestHandleWinMsg(message));
140 if (h.Get() == nullptr) {
141 LOG(INFO) << "Failed to get handle from TestHandleWinMsg.";
142 return false;
143 }
144
145 std::string contents = ReadFromFile(h.Get());
146 bool success = (contents == std::string(kDataBuffer));
147 if (!success) {
148 LOG(INFO) << "Expected contents: " << std::string(kDataBuffer);
149 LOG(INFO) << "Read contents: " << contents;
150 }
151 return success;
152 }
153
154 // Returns 0 on error.
155 DWORD GetCurrentProcessHandleCount() {
156 DWORD handle_count = 0;
157 BOOL success = ::GetProcessHandleCount(::GetCurrentProcess(), &handle_count);
158 return success ? handle_count : 0;
159 }
160
161 enum TestResult {
162 RESULT_UNKNOWN,
163 RESULT_SUCCESS,
164 RESULT_FAILURE,
165 };
166
167 // Once the test is finished, send a control message to the parent process with
168 // the result. The message may require the runloop to be run before its
169 // dispatched.
170 void SendControlMessage(IPC::Sender* sender, bool success) {
171 IPC::Message* message = new IPC::Message(0, 2, IPC::Message::PRIORITY_NORMAL);
172 TestResult result = success ? RESULT_SUCCESS : RESULT_FAILURE;
173 message->WriteInt(result);
174 sender->Send(message);
175 }
176
177 class MockObserver : public IPC::AttachmentBroker::Observer {
178 public:
179 void ReceivedBrokerableAttachmentWithId(
180 const IPC::BrokerableAttachment::AttachmentId& id) override {
181 id_ = id;
182 }
183 IPC::BrokerableAttachment::AttachmentId* get_id() { return &id_; }
184
185 private:
186 IPC::BrokerableAttachment::AttachmentId id_;
187 };
188
189 // Forwards all messages to |listener_|. Quits the message loop after a
190 // message is received, or the channel has an error.
191 class ProxyListener : public IPC::Listener {
192 public:
193 ProxyListener() : listener_(nullptr), reason_(MESSAGE_RECEIVED) {}
194 ~ProxyListener() override {}
195
196 // The reason for exiting the message loop.
197 enum Reason { MESSAGE_RECEIVED, CHANNEL_ERROR };
198
199 bool OnMessageReceived(const IPC::Message& message) override {
200 bool result = false;
201 if (listener_)
202 result = listener_->OnMessageReceived(message);
203 reason_ = MESSAGE_RECEIVED;
204 messages_.push_back(message);
205 base::MessageLoop::current()->QuitNow();
206 return result;
207 }
208
209 void OnChannelError() override {
210 reason_ = CHANNEL_ERROR;
211 base::MessageLoop::current()->QuitNow();
212 }
213
214 void set_listener(IPC::Listener* listener) { listener_ = listener; }
215 Reason get_reason() { return reason_; }
216 IPC::Message get_first_message() { return messages_[0]; }
217 void pop_first_message() { messages_.erase(messages_.begin()); }
218 bool has_message() { return !messages_.empty(); }
219
220 private:
221 IPC::Listener* listener_;
222 Reason reason_;
223 std::vector<IPC::Message> messages_;
224 };
225
226 // Waits for a result to be sent over the channel. Quits the message loop
227 // after a message is received, or the channel has an error.
228 class ResultListener : public IPC::Listener {
229 public:
230 ResultListener() : result_(RESULT_UNKNOWN) {}
231 ~ResultListener() override {}
232
233 bool OnMessageReceived(const IPC::Message& message) override {
234 base::PickleIterator iter(message);
235
236 int result;
237 EXPECT_TRUE(iter.ReadInt(&result));
238 result_ = static_cast<TestResult>(result);
239 return true;
240 }
241
242 TestResult get_result() { return result_; }
243
244 private:
245 TestResult result_;
246 };
247
248 // The parent process acts as an unprivileged process. The forked process acts
249 // as the privileged process.
250 class IPCAttachmentBrokerPrivilegedWinTest : public IPCTestBase {
251 public:
252 IPCAttachmentBrokerPrivilegedWinTest() {}
253 ~IPCAttachmentBrokerPrivilegedWinTest() override {}
254
255 void SetUp() override {
256 IPCTestBase::SetUp();
257 ASSERT_TRUE(temp_dir_.CreateUniqueTempDir());
258 ASSERT_TRUE(
259 base::CreateTemporaryFileInDir(temp_dir_.GetPath(), &temp_path_));
260 }
261
262 void TearDown() override { IPCTestBase::TearDown(); }
263
264 // Takes ownership of |broker|. Has no effect if called after CommonSetUp().
265 void set_broker(IPC::AttachmentBrokerUnprivilegedWin* broker) {
266 broker_.reset(broker);
267 }
268
269 void CommonSetUp() {
270 PreConnectSetUp();
271 PostConnectSetUp();
272 }
273
274 // All of setup before the channel is connected.
275 void PreConnectSetUp() {
276 if (!broker_.get())
277 set_broker(new IPC::AttachmentBrokerUnprivilegedWin);
278 broker_->AddObserver(&observer_, task_runner());
279 CreateChannel(&proxy_listener_);
280 broker_->RegisterBrokerCommunicationChannel(channel());
281 }
282
283 // All of setup including the connection and everything after.
284 void PostConnectSetUp() {
285 ASSERT_TRUE(ConnectChannel());
286 ASSERT_TRUE(StartClient());
287
288 handle_count_ = GetCurrentProcessHandleCount();
289 EXPECT_NE(handle_count_, 0u);
290 }
291
292 void CommonTearDown() {
293 EXPECT_EQ(handle_count_, handle_count_);
294
295 // Close the channel so the client's OnChannelError() gets fired.
296 channel()->Close();
297
298 EXPECT_TRUE(WaitForClientShutdown());
299 DestroyChannel();
300 broker_.reset();
301 }
302
303 HANDLE CreateTempFile() {
304 EXPECT_NE(-1, WriteFile(temp_path_, kDataBuffer,
305 static_cast<int>(strlen(kDataBuffer))));
306
307 HANDLE h =
308 CreateFile(temp_path_.value().c_str(), GENERIC_READ | GENERIC_WRITE, 0,
309 nullptr, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, nullptr);
310 EXPECT_NE(h, INVALID_HANDLE_VALUE);
311 return h;
312 }
313
314 void SendMessageWithAttachment(HANDLE h) {
315 IPC::HandleWin handle_win(h, IPC::HandleWin::FILE_READ_WRITE);
316 IPC::Message* message = new TestHandleWinMsg(100, handle_win, 200);
317 sender()->Send(message);
318 }
319
320 ProxyListener* get_proxy_listener() { return &proxy_listener_; }
321 IPC::AttachmentBrokerUnprivilegedWin* get_broker() { return broker_.get(); }
322 MockObserver* get_observer() { return &observer_; }
323
324 private:
325 base::ScopedTempDir temp_dir_;
326 base::FilePath temp_path_;
327 ProxyListener proxy_listener_;
328 std::unique_ptr<IPC::AttachmentBrokerUnprivilegedWin> broker_;
329 MockObserver observer_;
330 DWORD handle_count_;
331 };
332
333 // A broker which always sets the current process as the destination process
334 // for attachments.
335 class MockBroker : public IPC::AttachmentBrokerUnprivilegedWin {
336 public:
337 MockBroker() {}
338 ~MockBroker() override {}
339 bool SendAttachmentToProcess(
340 const scoped_refptr<IPC::BrokerableAttachment>& attachment,
341 base::ProcessId destination_process) override {
342 return IPC::AttachmentBrokerUnprivilegedWin::SendAttachmentToProcess(
343 attachment, base::Process::Current().Pid());
344 }
345 };
346
347 // An unprivileged process makes a file HANDLE, and writes a string to it. The
348 // file HANDLE is sent to the privileged process using the attachment broker.
349 // The privileged process dups the HANDLE into its own HANDLE table. This test
350 // checks that the file has the same contents in the privileged process.
351 TEST_F(IPCAttachmentBrokerPrivilegedWinTest, SendHandle) {
352 Init("SendHandle");
353
354 CommonSetUp();
355 ResultListener result_listener;
356 get_proxy_listener()->set_listener(&result_listener);
357
358 HANDLE h = CreateTempFile();
359 SendMessageWithAttachment(h);
360 base::RunLoop().Run();
361
362 // Check the result.
363 ASSERT_EQ(ProxyListener::MESSAGE_RECEIVED,
364 get_proxy_listener()->get_reason());
365 ASSERT_EQ(result_listener.get_result(), RESULT_SUCCESS);
366
367 CommonTearDown();
368 }
369
370 // Similar to SendHandle, except the file HANDLE attached to the message has
371 // neither read nor write permissions.
372 TEST_F(IPCAttachmentBrokerPrivilegedWinTest,
373 SendHandleWithoutPermissions) {
374 Init("SendHandleWithoutPermissions");
375
376 CommonSetUp();
377 ResultListener result_listener;
378 get_proxy_listener()->set_listener(&result_listener);
379
380 HANDLE h = CreateTempFile();
381 HANDLE h2;
382 BOOL result = ::DuplicateHandle(GetCurrentProcess(), h, GetCurrentProcess(),
383 &h2, 0, FALSE, DUPLICATE_CLOSE_SOURCE);
384 ASSERT_TRUE(result);
385 IPC::HandleWin handle_win(h2, IPC::HandleWin::DUPLICATE);
386 IPC::Message* message = new TestHandleWinMsg(100, handle_win, 200);
387 sender()->Send(message);
388 base::RunLoop().Run();
389
390 // Check the result.
391 ASSERT_EQ(ProxyListener::MESSAGE_RECEIVED,
392 get_proxy_listener()->get_reason());
393 ASSERT_EQ(result_listener.get_result(), RESULT_SUCCESS);
394
395 CommonTearDown();
396 }
397
398 // Similar to SendHandle, except the attachment's destination process is this
399 // process. This is an unrealistic scenario, but simulates an unprivileged
400 // process sending an attachment to another unprivileged process.
401 TEST_F(IPCAttachmentBrokerPrivilegedWinTest, SendHandleToSelf) {
402 Init("SendHandleToSelf");
403
404 set_broker(new MockBroker);
405
406 PreConnectSetUp();
407 // Technically, the channel is an endpoint, but we need the proxy listener to
408 // receive the messages so that it can quit the message loop.
409 channel()->SetAttachmentBrokerEndpoint(false);
410 PostConnectSetUp();
411 get_proxy_listener()->set_listener(get_broker());
412
413 HANDLE h = CreateTempFile();
414 SendMessageWithAttachment(h);
415 base::RunLoop().Run();
416
417 // Get the received attachment.
418 IPC::BrokerableAttachment::AttachmentId* id = get_observer()->get_id();
419 scoped_refptr<IPC::BrokerableAttachment> received_attachment;
420 get_broker()->GetAttachmentWithId(*id, &received_attachment);
421 ASSERT_NE(received_attachment.get(), nullptr);
422
423 // Check that it's a different entry in the HANDLE table.
424 ScopedHandle h2(GetHandleFromBrokeredAttachment(received_attachment));
425 EXPECT_NE(h2.Get(), h);
426
427 // But still points to the same file.
428 std::string contents = ReadFromFile(h2.Get());
429 EXPECT_EQ(contents, std::string(kDataBuffer));
430
431 CommonTearDown();
432 }
433
434 // Similar to SendHandle, but sends a message with two instances of the same
435 // handle.
436 TEST_F(IPCAttachmentBrokerPrivilegedWinTest, SendTwoHandles) {
437 Init("SendTwoHandles");
438
439 CommonSetUp();
440 ResultListener result_listener;
441 get_proxy_listener()->set_listener(&result_listener);
442
443 HANDLE h = CreateTempFile();
444 HANDLE h2;
445 BOOL result = ::DuplicateHandle(GetCurrentProcess(), h, GetCurrentProcess(),
446 &h2, 0, FALSE, DUPLICATE_SAME_ACCESS);
447 ASSERT_TRUE(result);
448 IPC::HandleWin handle_win1(h, IPC::HandleWin::FILE_READ_WRITE);
449 IPC::HandleWin handle_win2(h2, IPC::HandleWin::FILE_READ_WRITE);
450 IPC::Message* message = new TestTwoHandleWinMsg(handle_win1, handle_win2);
451 sender()->Send(message);
452 base::RunLoop().Run();
453
454 // Check the result.
455 ASSERT_EQ(ProxyListener::MESSAGE_RECEIVED,
456 get_proxy_listener()->get_reason());
457 ASSERT_EQ(result_listener.get_result(), RESULT_SUCCESS);
458
459 CommonTearDown();
460 }
461
462 // Similar to SendHandle, but sends the same message twice.
463 TEST_F(IPCAttachmentBrokerPrivilegedWinTest, SendHandleTwice) {
464 Init("SendHandleTwice");
465
466 CommonSetUp();
467 ResultListener result_listener;
468 get_proxy_listener()->set_listener(&result_listener);
469
470 HANDLE h = CreateTempFile();
471 HANDLE h2;
472 BOOL result = ::DuplicateHandle(GetCurrentProcess(), h, GetCurrentProcess(),
473 &h2, 0, FALSE, DUPLICATE_SAME_ACCESS);
474 ASSERT_TRUE(result);
475 SendMessageWithAttachment(h);
476 SendMessageWithAttachment(h2);
477 base::RunLoop().Run();
478
479 // Check the result.
480 ASSERT_EQ(ProxyListener::MESSAGE_RECEIVED,
481 get_proxy_listener()->get_reason());
482 ASSERT_EQ(result_listener.get_result(), RESULT_SUCCESS);
483
484 CommonTearDown();
485 }
486
487 // An unprivileged process makes a shared memory region and sends it to the
488 // privileged process.
489 TEST_F(IPCAttachmentBrokerPrivilegedWinTest, SendSharedMemoryHandle) {
490 Init("SendSharedMemoryHandle");
491
492 CommonSetUp();
493 ResultListener result_listener;
494 get_proxy_listener()->set_listener(&result_listener);
495
496 std::unique_ptr<base::SharedMemory> shared_memory(new base::SharedMemory);
497 shared_memory->CreateAndMapAnonymous(kSharedMemorySize);
498 memcpy(shared_memory->memory(), kDataBuffer, strlen(kDataBuffer));
499 sender()->Send(new TestSharedMemoryHandleMsg1(shared_memory->handle()));
500 base::RunLoop().Run();
501
502 // Check the result.
503 ASSERT_EQ(ProxyListener::MESSAGE_RECEIVED,
504 get_proxy_listener()->get_reason());
505 ASSERT_EQ(result_listener.get_result(), RESULT_SUCCESS);
506
507 CommonTearDown();
508 }
509
510 using OnMessageReceivedCallback = void (*)(IPC::Sender* sender,
511 const IPC::Message& message);
512
513 int CommonPrivilegedProcessMain(OnMessageReceivedCallback callback,
514 const char* channel_name) {
515 LOG(INFO) << "Privileged process start.";
516 base::MessageLoopForIO main_message_loop;
517 ProxyListener listener;
518
519 // Set up IPC channel.
520 IPC::AttachmentBrokerPrivilegedWin broker;
521 std::unique_ptr<IPC::Channel> channel(IPC::Channel::CreateClient(
522 IPCTestBase::GetChannelName(channel_name), &listener));
523 broker.RegisterCommunicationChannel(channel.get(), nullptr);
524 CHECK(channel->Connect());
525
526 while (true) {
527 LOG(INFO) << "Privileged process spinning run loop.";
528 base::RunLoop().Run();
529 ProxyListener::Reason reason = listener.get_reason();
530 if (reason == ProxyListener::CHANNEL_ERROR)
531 break;
532
533 while (listener.has_message()) {
534 LOG(INFO) << "Privileged process running callback.";
535 callback(channel.get(), listener.get_first_message());
536 LOG(INFO) << "Privileged process finishing callback.";
537 listener.pop_first_message();
538 }
539 }
540
541 LOG(INFO) << "Privileged process end.";
542 return 0;
543 }
544
545 void SendHandleCallback(IPC::Sender* sender, const IPC::Message& message) {
546 bool success = CheckContentsOfTestMessage(message);
547 SendControlMessage(sender, success);
548 }
549
550 MULTIPROCESS_IPC_TEST_CLIENT_MAIN(SendHandle) {
551 return CommonPrivilegedProcessMain(&SendHandleCallback, "SendHandle");
552 }
553
554 void SendHandleWithoutPermissionsCallback(IPC::Sender* sender,
555 const IPC::Message& message) {
556 ScopedHandle h(GetHandleFromTestHandleWinMsg(message));
557 if (h.Get() != nullptr) {
558 SetFilePointer(h.Get(), 0, nullptr, FILE_BEGIN);
559
560 char buffer[100];
561 DWORD bytes_read;
562 BOOL success =
563 ::ReadFile(h.Get(), buffer, static_cast<DWORD>(strlen(kDataBuffer)),
564 &bytes_read, nullptr);
565 if (!success && GetLastError() == ERROR_ACCESS_DENIED) {
566 SendControlMessage(sender, true);
567 return;
568 }
569 }
570
571 SendControlMessage(sender, false);
572 }
573
574 MULTIPROCESS_IPC_TEST_CLIENT_MAIN(SendHandleWithoutPermissions) {
575 return CommonPrivilegedProcessMain(&SendHandleWithoutPermissionsCallback,
576 "SendHandleWithoutPermissions");
577 }
578
579 void SendHandleToSelfCallback(IPC::Sender* sender, const IPC::Message&) {
580 // Do nothing special. The default behavior already runs the
581 // AttachmentBrokerPrivilegedWin.
582 }
583
584 MULTIPROCESS_IPC_TEST_CLIENT_MAIN(SendHandleToSelf) {
585 return CommonPrivilegedProcessMain(&SendHandleToSelfCallback,
586 "SendHandleToSelf");
587 }
588
589 void SendTwoHandlesCallback(IPC::Sender* sender, const IPC::Message& message) {
590 // Check for two handles.
591 HANDLE h1, h2;
592 EXPECT_TRUE(GetHandleFromTestTwoHandleWinMsg(message, &h1, &h2));
593 if (h1 == nullptr || h2 == nullptr) {
594 SendControlMessage(sender, false);
595 return;
596 }
597
598 // Check that their contents are correct.
599 std::string contents1 = ReadFromFile(h1);
600 std::string contents2 = ReadFromFile(h2);
601 if (contents1 != std::string(kDataBuffer) ||
602 contents2 != std::string(kDataBuffer)) {
603 SendControlMessage(sender, false);
604 return;
605 }
606
607 // Check that the handles point to the same file.
608 const char text[] = "katy perry";
609 DWORD bytes_written = 0;
610 SetFilePointer(h1, 0, nullptr, FILE_BEGIN);
611 BOOL success = ::WriteFile(h1, text, static_cast<DWORD>(strlen(text)),
612 &bytes_written, nullptr);
613 if (!success) {
614 SendControlMessage(sender, false);
615 return;
616 }
617
618 SetFilePointer(h2, 0, nullptr, FILE_BEGIN);
619 char buffer[100];
620 DWORD bytes_read;
621 success = ::ReadFile(h2, buffer, static_cast<DWORD>(strlen(text)),
622 &bytes_read, nullptr);
623 if (!success) {
624 SendControlMessage(sender, false);
625 return;
626 }
627 success = std::string(buffer, bytes_read) == std::string(text);
628 SendControlMessage(sender, success);
629 }
630
631 MULTIPROCESS_IPC_TEST_CLIENT_MAIN(SendTwoHandles) {
632 return CommonPrivilegedProcessMain(&SendTwoHandlesCallback, "SendTwoHandles");
633 }
634
635 void SendHandleTwiceCallback(IPC::Sender* sender, const IPC::Message& message) {
636 // We expect the same message twice.
637 static int i = 0;
638 static bool success = true;
639 success &= CheckContentsOfTestMessage(message);
640 if (i == 0) {
641 LOG(INFO) << "Received first message.";
642 ++i;
643 } else {
644 LOG(INFO) << "Received second message.";
645 SendControlMessage(sender, success);
646 }
647 }
648
649 MULTIPROCESS_IPC_TEST_CLIENT_MAIN(SendHandleTwice) {
650 return CommonPrivilegedProcessMain(&SendHandleTwiceCallback,
651 "SendHandleTwice");
652 }
653
654 void SendSharedMemoryHandleCallback(IPC::Sender* sender,
655 const IPC::Message& message) {
656 std::unique_ptr<base::SharedMemory> shared_memory =
657 GetSharedMemoryFromSharedMemoryHandleMsg1(message, kSharedMemorySize);
658 bool success =
659 memcmp(shared_memory->memory(), kDataBuffer, strlen(kDataBuffer)) == 0;
660 SendControlMessage(sender, success);
661 }
662
663 MULTIPROCESS_IPC_TEST_CLIENT_MAIN(SendSharedMemoryHandle) {
664 return CommonPrivilegedProcessMain(&SendSharedMemoryHandleCallback,
665 "SendSharedMemoryHandle");
666 }
667
668 } // namespace
OLDNEW
« no previous file with comments | « ipc/attachment_broker_privileged_win.cc ('k') | ipc/attachment_broker_unprivileged.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698