15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/bind.h"
62a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/files/file_path.h"
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/memory/ref_counted.h"
82a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/scoped_native_library.h"
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "remoting/base/auto_thread.h"
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "testing/gtest/include/gtest/gtest.h"
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#if defined(OS_WIN)
132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include <objbase.h>
142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/win/windows_version.h"
152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#endif
162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace {
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char kThreadName[] = "Test thread";
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void SetFlagTask(bool* success) {
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  *success = true;
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void PostSetFlagTask(
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    scoped_refptr<base::TaskRunner> task_runner,
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    bool* success) {
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  task_runner->PostTask(FROM_HERE, base::Bind(&SetFlagTask, success));
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#if defined(OS_WIN)
322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void CheckComAptTypeTask(APTTYPE* apt_type_out, HRESULT* hresult) {
332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  typedef HRESULT (WINAPI * CoGetApartmentTypeFunc)
342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      (APTTYPE*, APTTYPEQUALIFIER*);
352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // CoGetApartmentType requires Windows 7 or above.
372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (base::win::GetVersion() < base::win::VERSION_WIN7) {
382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    *hresult = E_NOTIMPL;
392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return;
402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Dynamic link to the API so the same test binary can run on older systems.
432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::ScopedNativeLibrary com_library(base::FilePath(L"ole32.dll"));
442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ASSERT_TRUE(com_library.is_valid());
452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  CoGetApartmentTypeFunc co_get_apartment_type =
46116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      reinterpret_cast<CoGetApartmentTypeFunc>(
472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          com_library.GetFunctionPointer("CoGetApartmentType"));
482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ASSERT_TRUE(co_get_apartment_type != NULL);
492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  APTTYPEQUALIFIER apt_type_qualifier;
512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  *hresult = (*co_get_apartment_type)(apt_type_out, &apt_type_qualifier);
522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#endif
542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace remoting {
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class AutoThreadTest : public testing::Test {
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  AutoThreadTest() : message_loop_quit_correctly_(false) {
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void RunMessageLoop() {
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Release |main_task_runner_|, then run |message_loop_| until other
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // references created in tests are gone.  We also post a delayed quit
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // task to |message_loop_| so the test will not hang on failure.
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    main_task_runner_ = NULL;
69c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    message_loop_.PostDelayedTask(FROM_HERE,
70c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                  base::MessageLoop::QuitClosure(),
71c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                  base::TimeDelta::FromSeconds(5));
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    message_loop_.Run();
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void SetUp() OVERRIDE {
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    main_task_runner_ = new AutoThreadTaskRunner(
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        message_loop_.message_loop_proxy(),
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        base::Bind(&AutoThreadTest::QuitMainMessageLoop,
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                   base::Unretained(this)));
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void TearDown() OVERRIDE {
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Verify that |message_loop_| was quit by the AutoThreadTaskRunner.
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_TRUE(message_loop_quit_correctly_);
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) protected:
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void QuitMainMessageLoop() {
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    message_loop_quit_correctly_ = true;
90c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    message_loop_.PostTask(FROM_HERE, base::MessageLoop::QuitClosure());
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
93c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  base::MessageLoop message_loop_;
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool message_loop_quit_correctly_;
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_refptr<AutoThreadTaskRunner> main_task_runner_;
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(AutoThreadTest, StartAndStop) {
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Create an AutoThread joined by our MessageLoop.
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_refptr<base::TaskRunner> task_runner =
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      AutoThread::Create(kThreadName, main_task_runner_);
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(task_runner.get());
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  task_runner = NULL;
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RunMessageLoop();
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(AutoThreadTest, ProcessTask) {
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Create an AutoThread joined by our MessageLoop.
1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_refptr<base::TaskRunner> task_runner =
1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      AutoThread::Create(kThreadName, main_task_runner_);
1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(task_runner.get());
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Post a task to it.
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool success = false;
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  task_runner->PostTask(FROM_HERE, base::Bind(&SetFlagTask, &success));
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  task_runner = NULL;
1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RunMessageLoop();
1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(success);
1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(AutoThreadTest, ThreadDependency) {
1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Create two AutoThreads joined by our MessageLoop.
1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_refptr<base::TaskRunner> task_runner1 =
1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      AutoThread::Create(kThreadName, main_task_runner_);
1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(task_runner1.get());
1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_refptr<base::TaskRunner> task_runner2 =
1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      AutoThread::Create(kThreadName, main_task_runner_);
1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(task_runner2.get());
1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Post a task to thread 1 that will post a task to thread 2.
1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool success = false;
1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  task_runner1->PostTask(FROM_HERE,
1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      base::Bind(&PostSetFlagTask, task_runner2, &success));
1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  task_runner1 = NULL;
1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  task_runner2 = NULL;
1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RunMessageLoop();
1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(success);
1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#if defined(OS_WIN)
1462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(AutoThreadTest, ThreadWithComMta) {
1472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_refptr<base::TaskRunner> task_runner =
148c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      AutoThread::CreateWithLoopAndComInitTypes(kThreadName,
149c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                                main_task_runner_,
150c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                                base::MessageLoop::TYPE_DEFAULT,
151c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                                AutoThread::COM_INIT_MTA);
1522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(task_runner.get());
1532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Post a task to query the COM apartment type.
1552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  HRESULT hresult = E_FAIL;
1562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  APTTYPE apt_type = APTTYPE_NA;
1572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  task_runner->PostTask(FROM_HERE,
1582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                        base::Bind(&CheckComAptTypeTask, &apt_type, &hresult));
1592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  task_runner = NULL;
1612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  RunMessageLoop();
1622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // CoGetApartmentType requires Windows 7 or above.
1642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (base::win::GetVersion() >= base::win::VERSION_WIN7) {
1652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_EQ(S_OK, hresult);
1662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_EQ(APTTYPE_MTA, apt_type);
1672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  } else {
1682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_EQ(E_NOTIMPL, hresult);
1692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
1702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(AutoThreadTest, ThreadWithComSta) {
1732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_refptr<base::TaskRunner> task_runner =
174c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      AutoThread::CreateWithLoopAndComInitTypes(kThreadName,
175c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                                main_task_runner_,
176c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                                base::MessageLoop::TYPE_UI,
177c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                                AutoThread::COM_INIT_STA);
1782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(task_runner.get());
1792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Post a task to query the COM apartment type.
1812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  HRESULT hresult = E_FAIL;
1822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  APTTYPE apt_type = APTTYPE_NA;
1832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  task_runner->PostTask(FROM_HERE,
1842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                        base::Bind(&CheckComAptTypeTask, &apt_type, &hresult));
1852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  task_runner = NULL;
1872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  RunMessageLoop();
1882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // CoGetApartmentType requires Windows 7 or above.
1902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (base::win::GetVersion() >= base::win::VERSION_WIN7) {
1912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_EQ(S_OK, hresult);
1922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // Whether the thread is the "main" STA apartment depends upon previous
1932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // COM activity in this test process, so allow both types here.
1942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_TRUE(apt_type == APTTYPE_MAINSTA || apt_type == APTTYPE_STA);
1952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  } else {
1962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_EQ(E_NOTIMPL, hresult);
1972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
1982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#endif // defined(OS_WIN)
2002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace remoting
202