- add sources.
[platform/framework/web/crosswalk.git] / src / cloud_print / virtual_driver / win / port_monitor / port_monitor_unittest.cc
1 // Copyright (c) 2012 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 "cloud_print/virtual_driver/win/port_monitor/port_monitor.h"
6 #include <winspool.h>
7 #include "base/file_util.h"
8 #include "base/path_service.h"
9 #include "base/strings/string16.h"
10 #include "base/win/registry.h"
11 #include "base/win/scoped_handle.h"
12 #include "cloud_print/virtual_driver/win/port_monitor/spooler_win.h"
13 #include "testing/gtest/include/gtest/gtest.h"
14
15 namespace cloud_print {
16
17 const wchar_t kChromeExePath[] = L"google\\chrome\\application\\chrometest.exe";
18 const wchar_t kChromeExePathRegValue[] = L"PathToChromeTestExe";
19 const wchar_t kChromeProfilePathRegValue[] = L"PathToChromeTestProfile";
20 const bool kIsUnittest = true;
21
22 namespace {
23
24 const wchar_t kAlternateChromeExePath[] =
25     L"google\\chrome\\application\\chrometestalternate.exe";
26
27 const wchar_t kCloudPrintRegKey[] = L"Software\\Google\\CloudPrint";
28
29 }  // namespace
30
31 class PortMonitorTest : public testing::Test  {
32  public:
33   PortMonitorTest() {}
34  protected:
35   // Creates a registry entry pointing at a chrome
36   virtual void SetUpChromeExeRegistry() {
37     // Create a temporary chrome.exe location value.
38     base::win::RegKey key(HKEY_CURRENT_USER,
39                           cloud_print::kCloudPrintRegKey,
40                           KEY_ALL_ACCESS);
41
42     base::FilePath path;
43     PathService::Get(base::DIR_LOCAL_APP_DATA, &path);
44     path = path.Append(kAlternateChromeExePath);
45     ASSERT_EQ(ERROR_SUCCESS,
46               key.WriteValue(cloud_print::kChromeExePathRegValue,
47                              path.value().c_str()));
48     base::FilePath temp;
49     PathService::Get(base::DIR_TEMP, &temp);
50     // Write any dir here.
51     ASSERT_EQ(ERROR_SUCCESS,
52               key.WriteValue(cloud_print::kChromeProfilePathRegValue,
53                              temp.value().c_str()));
54   }
55   // Deletes the registry entry created in SetUpChromeExeRegistry
56   virtual void DeleteChromeExeRegistry() {
57     base::win::RegKey key(HKEY_CURRENT_USER,
58                           cloud_print::kCloudPrintRegKey,
59                           KEY_ALL_ACCESS);
60     key.DeleteValue(cloud_print::kChromeExePathRegValue);
61     key.DeleteValue(cloud_print::kChromeProfilePathRegValue);
62   }
63
64   virtual void CreateTempChromeExeFiles() {
65     base::FilePath path;
66     PathService::Get(base::DIR_LOCAL_APP_DATA, &path);
67     base::FilePath main_path = path.Append(kChromeExePath);
68     ASSERT_TRUE(file_util::CreateDirectory(main_path));
69     base::FilePath alternate_path = path.Append(kAlternateChromeExePath);
70     ASSERT_TRUE(file_util::CreateDirectory(alternate_path));
71   }
72
73   virtual void DeleteTempChromeExeFiles() {
74     base::FilePath path;
75     PathService::Get(base::DIR_LOCAL_APP_DATA, &path);
76     base::FilePath main_path = path.Append(kChromeExePath);
77     ASSERT_TRUE(base::DeleteFile(main_path, true));
78     PathService::Get(base::DIR_LOCAL_APP_DATA, &path);
79     base::FilePath alternate_path = path.Append(kAlternateChromeExePath);
80     ASSERT_TRUE(base::DeleteFile(alternate_path, true));
81   }
82
83  protected:
84   virtual void SetUp() {
85     SetUpChromeExeRegistry();
86   }
87
88   virtual void TearDown() {
89     DeleteChromeExeRegistry();
90   }
91
92  private:
93   DISALLOW_COPY_AND_ASSIGN(PortMonitorTest);
94 };
95
96 TEST_F(PortMonitorTest, GetChromeExePathTest) {
97   CreateTempChromeExeFiles();
98   base::FilePath chrome_path = cloud_print::GetChromeExePath();
99   EXPECT_FALSE(chrome_path.empty());
100   EXPECT_TRUE(
101       chrome_path.value().rfind(kAlternateChromeExePath) != std::string::npos);
102   EXPECT_TRUE(base::PathExists(chrome_path));
103   DeleteChromeExeRegistry();
104   chrome_path = cloud_print::GetChromeExePath();
105   // No Chrome or regular chrome path.
106   EXPECT_TRUE(chrome_path.empty() ||
107               chrome_path.value().rfind(kChromeExePath) == std::string::npos);
108 }
109
110 TEST_F(PortMonitorTest, GetChromeProfilePathTest) {
111   base::FilePath data_path = cloud_print::GetChromeProfilePath();
112   EXPECT_FALSE(data_path.empty());
113   base::FilePath temp;
114   PathService::Get(base::DIR_TEMP, &temp);
115   EXPECT_EQ(data_path, temp);
116   EXPECT_TRUE(base::DirectoryExists(data_path));
117   DeleteChromeExeRegistry();
118   data_path = cloud_print::GetChromeProfilePath();
119   EXPECT_TRUE(data_path.empty());
120 }
121
122 TEST_F(PortMonitorTest, EnumPortsTest) {
123   DWORD needed_bytes = 0;
124   DWORD returned = 0;
125   EXPECT_FALSE(Monitor2EnumPorts(NULL,
126                                  NULL,
127                                  1,
128                                  NULL,
129                                  0,
130                                  &needed_bytes,
131                                  &returned));
132   EXPECT_EQ(ERROR_INSUFFICIENT_BUFFER, GetLastError());
133   EXPECT_NE(0u, needed_bytes);
134   EXPECT_EQ(0u, returned);
135
136   BYTE* buffer = new BYTE[needed_bytes];
137   ASSERT_TRUE(buffer != NULL);
138   EXPECT_TRUE(Monitor2EnumPorts(NULL,
139                                 NULL,
140                                 1,
141                                 buffer,
142                                 needed_bytes,
143                                 &needed_bytes,
144                                 &returned));
145   EXPECT_NE(0u, needed_bytes);
146   EXPECT_EQ(1u, returned);
147   PORT_INFO_1* port_info_1 = reinterpret_cast<PORT_INFO_1*>(buffer);
148   EXPECT_TRUE(port_info_1->pName != NULL);
149   delete[] buffer;
150
151   returned = 0;
152   needed_bytes = 0;
153   EXPECT_FALSE(Monitor2EnumPorts(NULL,
154                                  NULL,
155                                  2,
156                                  NULL,
157                                  0,
158                                  &needed_bytes,
159                                  &returned));
160   EXPECT_EQ(ERROR_INSUFFICIENT_BUFFER, GetLastError());
161   EXPECT_NE(0u, needed_bytes);
162   EXPECT_EQ(0u, returned);
163
164   buffer = new BYTE[needed_bytes];
165   ASSERT_TRUE(buffer != NULL);
166   EXPECT_TRUE(Monitor2EnumPorts(NULL,
167                                 NULL,
168                                 2,
169                                 buffer,
170                                 needed_bytes,
171                                 &needed_bytes,
172                                 &returned));
173   EXPECT_NE(0u, needed_bytes);
174   EXPECT_EQ(1u, returned);
175   PORT_INFO_2* port_info_2 = reinterpret_cast<PORT_INFO_2*>(buffer);
176   EXPECT_TRUE(port_info_2->pPortName != NULL);
177   delete[] buffer;
178 }
179
180 TEST_F(PortMonitorTest, FlowTest) {
181   const wchar_t kXcvDataItem[] = L"MonitorUI";
182   MONITORINIT monitor_init = {0};
183   HANDLE monitor_handle = NULL;
184   HANDLE port_handle = NULL;
185   HANDLE xcv_handle = NULL;
186   DWORD bytes_processed = 0;
187   DWORD bytes_needed = 0;
188   const size_t kBufferSize = 100;
189   BYTE buffer[kBufferSize] = {0};
190
191   // Initialize the print monitor
192   MONITOR2* monitor2 = InitializePrintMonitor2(&monitor_init, &monitor_handle);
193   EXPECT_TRUE(monitor2 != NULL);
194   EXPECT_TRUE(monitor_handle != NULL);
195
196   // Test the XCV functions.  Used for reporting the location of the
197   // UI portion of the port monitor.
198   EXPECT_TRUE(monitor2->pfnXcvOpenPort != NULL);
199   EXPECT_TRUE(monitor2->pfnXcvOpenPort(monitor_handle, NULL, 0, &xcv_handle));
200   EXPECT_TRUE(xcv_handle != NULL);
201   EXPECT_TRUE(monitor2->pfnXcvDataPort != NULL);
202   EXPECT_EQ(ERROR_ACCESS_DENIED,
203             monitor2->pfnXcvDataPort(xcv_handle,
204                                      kXcvDataItem,
205                                      NULL,
206                                      0,
207                                      buffer,
208                                      kBufferSize,
209                                      &bytes_needed));
210   EXPECT_TRUE(monitor2->pfnXcvClosePort != NULL);
211   EXPECT_TRUE(monitor2->pfnXcvClosePort(xcv_handle));
212   EXPECT_TRUE(monitor2->pfnXcvOpenPort(monitor_handle,
213                                        NULL,
214                                        SERVER_ACCESS_ADMINISTER,
215                                        &xcv_handle));
216   EXPECT_TRUE(xcv_handle != NULL);
217   EXPECT_TRUE(monitor2->pfnXcvDataPort != NULL);
218   EXPECT_EQ(ERROR_SUCCESS,
219             monitor2->pfnXcvDataPort(xcv_handle,
220                                      kXcvDataItem,
221                                      NULL,
222                                      0,
223                                      buffer,
224                                      kBufferSize,
225                                      &bytes_needed));
226   EXPECT_TRUE(monitor2->pfnXcvClosePort != NULL);
227   EXPECT_TRUE(monitor2->pfnXcvClosePort(xcv_handle));
228
229   // Test opening the port and running a print job.
230   EXPECT_TRUE(monitor2->pfnOpenPort != NULL);
231   EXPECT_TRUE(monitor2->pfnOpenPort(monitor_handle, NULL, &port_handle));
232   EXPECT_TRUE(port_handle != NULL);
233   EXPECT_TRUE(monitor2->pfnStartDocPort != NULL);
234   EXPECT_TRUE(monitor2->pfnWritePort != NULL);
235   EXPECT_TRUE(monitor2->pfnReadPort != NULL);
236   EXPECT_TRUE(monitor2->pfnEndDocPort != NULL);
237
238   // These functions should fail if we have not impersonated the user.
239   EXPECT_FALSE(monitor2->pfnStartDocPort(port_handle, L"", 0, 0, NULL));
240   EXPECT_FALSE(monitor2->pfnWritePort(port_handle,
241                                      buffer,
242                                      kBufferSize,
243                                      &bytes_processed));
244   EXPECT_EQ(0, bytes_processed);
245   EXPECT_FALSE(monitor2->pfnReadPort(port_handle,
246                                      buffer,
247                                      sizeof(buffer),
248                                      &bytes_processed));
249   EXPECT_EQ(0u, bytes_processed);
250   EXPECT_FALSE(monitor2->pfnEndDocPort(port_handle));
251
252   // Now impersonate so we can test the success case.
253   ASSERT_TRUE(ImpersonateSelf(SecurityImpersonation));
254   EXPECT_TRUE(monitor2->pfnStartDocPort(port_handle, L"", 0, 0, NULL));
255   EXPECT_TRUE(monitor2->pfnWritePort(port_handle,
256                                      buffer,
257                                      kBufferSize,
258                                      &bytes_processed));
259   EXPECT_EQ(kBufferSize, bytes_processed);
260   EXPECT_FALSE(monitor2->pfnReadPort(port_handle,
261                                      buffer,
262                                      sizeof(buffer),
263                                      &bytes_processed));
264   EXPECT_EQ(0u, bytes_processed);
265   EXPECT_TRUE(monitor2->pfnEndDocPort(port_handle));
266   RevertToSelf();
267   EXPECT_TRUE(monitor2->pfnClosePort != NULL);
268   EXPECT_TRUE(monitor2->pfnClosePort(port_handle));
269   // Shutdown the port monitor.
270   Monitor2Shutdown(monitor_handle);
271 }
272
273 }  // namespace cloud_print
274