2015-12-16 09:40:37 -08:00
|
|
|
// Licensed to the Software Freedom Conservancy (SFC) under one
|
|
|
|
|
// or more contributor license agreements. See the NOTICE file
|
|
|
|
|
// distributed with this work for additional information
|
|
|
|
|
// regarding copyright ownership. The SFC licenses this file
|
|
|
|
|
// to you under the Apache License, Version 2.0 (the "License");
|
|
|
|
|
// you may not use this file except in compliance with the License.
|
|
|
|
|
// You may obtain a copy of the License at
|
|
|
|
|
//
|
|
|
|
|
// http://www.apache.org/licenses/LICENSE-2.0
|
|
|
|
|
//
|
|
|
|
|
// Unless required by applicable law or agreed to in writing, software
|
|
|
|
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
|
|
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
|
|
|
// See the License for the specific language governing permissions and
|
|
|
|
|
// limitations under the License.
|
|
|
|
|
|
|
|
|
|
#include "WindowUtilities.h"
|
2017-02-14 09:48:56 -08:00
|
|
|
|
Improving IE driver use with invalid Protected Mode settings
Now, when the user does not set the Protected Mode settings of the
browser and sends the capability to bypass the checks for those
settings, the driver will attempt to predict when a Protected Mode
boundary will be crossed, and set in motion a process to reattach
itself to the newly created browser. This process is far from perfect.
It is subject to really challenging race conditions that are truly
impossible to eliminate entirely, because of the architecture of the
browser itself. Nevertheless, even in its flawed state, this is still
a better outcome than it was previously for users.
Please note that the advice and support policy of the IE driver will
continue to be that the user must set the Protected Mode settings of
the browser properly before using the driver. Any "issues" that arise
by not having the settings set, but that disappear when the settings
are corrected, are not considered by the project to be valid issues.
This will include, but not be limited to, issues like abandoned
browser instances not being closed, use of multiple instances of the
driver where the wrong browser window is connected to and automated,
and issues where the driver appears to hang upon navigation to a new
page. If the problem disappears when the browser is properly
configured, any issue reports will be immediately closed with a note
to properly configure the browser and remove the capability.
The following situations should be at least partially mitigated by the
change:
* Navigation to a new page
* Clicking on a link (specifically an <a> tag) that will lead to a
navigation to a new page
* Clicking a link that opens a new window
Other cases, like navigating backward and forward through the browser
history, clicking an element that submits a form, and so on, may not
be handled. In those cases, issue reports will be summarily closed,
unless a specific pull request fixing the issue is also provided.
Additionally, use of things like proxies to capture traffic between the
browser and web server may miss some traffic because of the race
conditions inherent in the mechanism used to reattach to a newly
created browser. Again, these race conditions are unavoidable, and
issue reports that are based on them will be immediately closed with a
note indicating that the browser must have its settings properly set.
These strict guidelines are not intended to be harsh, and are not put
in place with the intent to avoid investigating and fixing issues;
rather, they must be enforced because the underlying architecture of
the browser makes them unavoidable.
2019-02-17 09:29:01 -08:00
|
|
|
#include <algorithm>
|
2015-12-16 09:40:37 -08:00
|
|
|
#include <ctime>
|
Improving IE driver use with invalid Protected Mode settings
Now, when the user does not set the Protected Mode settings of the
browser and sends the capability to bypass the checks for those
settings, the driver will attempt to predict when a Protected Mode
boundary will be crossed, and set in motion a process to reattach
itself to the newly created browser. This process is far from perfect.
It is subject to really challenging race conditions that are truly
impossible to eliminate entirely, because of the architecture of the
browser itself. Nevertheless, even in its flawed state, this is still
a better outcome than it was previously for users.
Please note that the advice and support policy of the IE driver will
continue to be that the user must set the Protected Mode settings of
the browser properly before using the driver. Any "issues" that arise
by not having the settings set, but that disappear when the settings
are corrected, are not considered by the project to be valid issues.
This will include, but not be limited to, issues like abandoned
browser instances not being closed, use of multiple instances of the
driver where the wrong browser window is connected to and automated,
and issues where the driver appears to hang upon navigation to a new
page. If the problem disappears when the browser is properly
configured, any issue reports will be immediately closed with a note
to properly configure the browser and remove the capability.
The following situations should be at least partially mitigated by the
change:
* Navigation to a new page
* Clicking on a link (specifically an <a> tag) that will lead to a
navigation to a new page
* Clicking a link that opens a new window
Other cases, like navigating backward and forward through the browser
history, clicking an element that submits a form, and so on, may not
be handled. In those cases, issue reports will be summarily closed,
unless a specific pull request fixing the issue is also provided.
Additionally, use of things like proxies to capture traffic between the
browser and web server may miss some traffic because of the race
conditions inherent in the mechanism used to reattach to a newly
created browser. Again, these race conditions are unavoidable, and
issue reports that are based on them will be immediately closed with a
note indicating that the browser must have its settings properly set.
These strict guidelines are not intended to be harsh, and are not put
in place with the intent to avoid investigating and fixing issues;
rather, they must be enforced because the underlying architecture of
the browser makes them unavoidable.
2019-02-17 09:29:01 -08:00
|
|
|
#include <Psapi.h>
|
2015-12-16 09:40:37 -08:00
|
|
|
|
2017-02-14 09:48:56 -08:00
|
|
|
#include "StringUtilities.h"
|
|
|
|
|
|
2015-12-16 09:40:37 -08:00
|
|
|
namespace webdriver {
|
|
|
|
|
|
|
|
|
|
WindowUtilities::WindowUtilities() {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
WindowUtilities::~WindowUtilities() {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void WindowUtilities::Wait(long wait_in_milliseconds) {
|
|
|
|
|
clock_t end = clock() + wait_in_milliseconds;
|
|
|
|
|
do {
|
|
|
|
|
MSG msg;
|
|
|
|
|
if (::PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) {
|
|
|
|
|
::TranslateMessage(&msg);
|
|
|
|
|
::DispatchMessage(&msg);
|
|
|
|
|
}
|
|
|
|
|
::Sleep(0);
|
|
|
|
|
} while (clock() < end);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void WindowUtilities::WaitWithoutMsgPump(long wait_in_milliseconds) {
|
|
|
|
|
::Sleep(wait_in_milliseconds);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
HWND WindowUtilities::GetChildWindow(HWND parent_window_handle,
|
|
|
|
|
std::wstring window_class) {
|
|
|
|
|
std::vector<wchar_t> class_name_buffer(window_class.size() + 1);
|
|
|
|
|
HWND hwndtmp = GetWindow(parent_window_handle, GW_CHILD);
|
|
|
|
|
while (hwndtmp != NULL) {
|
|
|
|
|
::GetClassName(hwndtmp,
|
|
|
|
|
&class_name_buffer[0],
|
|
|
|
|
static_cast<int>(class_name_buffer.size()));
|
|
|
|
|
std::wstring actual_class = &class_name_buffer[0];
|
|
|
|
|
if (window_class == actual_class) {
|
|
|
|
|
return hwndtmp;
|
|
|
|
|
}
|
|
|
|
|
hwndtmp = GetWindow(hwndtmp, GW_HWNDNEXT);
|
|
|
|
|
}
|
|
|
|
|
return NULL;
|
|
|
|
|
}
|
|
|
|
|
|
2016-02-18 11:42:32 -08:00
|
|
|
std::string WindowUtilities::GetWindowCaption(HWND window_handle) {
|
|
|
|
|
std::wstring window_caption = L"";
|
|
|
|
|
std::vector<wchar_t> buffer(256);
|
|
|
|
|
int success = ::GetWindowText(window_handle, &buffer[0], 256);
|
|
|
|
|
if (success > 0) {
|
|
|
|
|
window_caption = &buffer[0];
|
|
|
|
|
}
|
|
|
|
|
return StringUtilities::ToString(window_caption);
|
|
|
|
|
}
|
|
|
|
|
|
2021-11-05 15:48:25 -04:00
|
|
|
std::string WindowUtilities::GetWindowClass(HWND window_handle) {
|
|
|
|
|
std::string window_class = "";
|
|
|
|
|
std::vector<char> buffer(256);
|
|
|
|
|
int success = ::GetClassNameA(window_handle, &buffer[0], buffer.size());
|
|
|
|
|
if (success > 0) {
|
|
|
|
|
window_class = &buffer[0];
|
|
|
|
|
}
|
|
|
|
|
return window_class;
|
|
|
|
|
}
|
|
|
|
|
|
Improving IE driver use with invalid Protected Mode settings
Now, when the user does not set the Protected Mode settings of the
browser and sends the capability to bypass the checks for those
settings, the driver will attempt to predict when a Protected Mode
boundary will be crossed, and set in motion a process to reattach
itself to the newly created browser. This process is far from perfect.
It is subject to really challenging race conditions that are truly
impossible to eliminate entirely, because of the architecture of the
browser itself. Nevertheless, even in its flawed state, this is still
a better outcome than it was previously for users.
Please note that the advice and support policy of the IE driver will
continue to be that the user must set the Protected Mode settings of
the browser properly before using the driver. Any "issues" that arise
by not having the settings set, but that disappear when the settings
are corrected, are not considered by the project to be valid issues.
This will include, but not be limited to, issues like abandoned
browser instances not being closed, use of multiple instances of the
driver where the wrong browser window is connected to and automated,
and issues where the driver appears to hang upon navigation to a new
page. If the problem disappears when the browser is properly
configured, any issue reports will be immediately closed with a note
to properly configure the browser and remove the capability.
The following situations should be at least partially mitigated by the
change:
* Navigation to a new page
* Clicking on a link (specifically an <a> tag) that will lead to a
navigation to a new page
* Clicking a link that opens a new window
Other cases, like navigating backward and forward through the browser
history, clicking an element that submits a form, and so on, may not
be handled. In those cases, issue reports will be summarily closed,
unless a specific pull request fixing the issue is also provided.
Additionally, use of things like proxies to capture traffic between the
browser and web server may miss some traffic because of the race
conditions inherent in the mechanism used to reattach to a newly
created browser. Again, these race conditions are unavoidable, and
issue reports that are based on them will be immediately closed with a
note indicating that the browser must have its settings properly set.
These strict guidelines are not intended to be harsh, and are not put
in place with the intent to avoid investigating and fixing issues;
rather, they must be enforced because the underlying architecture of
the browser makes them unavoidable.
2019-02-17 09:29:01 -08:00
|
|
|
void WindowUtilities::GetProcessesByName(const std::wstring& process_name,
|
|
|
|
|
std::vector<DWORD>* process_ids) {
|
|
|
|
|
int max_process_id_count = 1024;
|
|
|
|
|
std::vector<DWORD> all_process_ids(max_process_id_count);
|
|
|
|
|
DWORD bytes_needed = 0;
|
|
|
|
|
BOOL processes_enumerated = ::EnumProcesses(&all_process_ids[0],
|
|
|
|
|
static_cast<DWORD>(all_process_ids.size()) * sizeof(DWORD),
|
|
|
|
|
&bytes_needed);
|
|
|
|
|
DWORD process_id_count = bytes_needed / sizeof(DWORD);
|
|
|
|
|
while (process_id_count == max_process_id_count) {
|
|
|
|
|
// Retry EnumProcesses with bigger array. This shouldn't happen often.
|
|
|
|
|
max_process_id_count *= 2;
|
|
|
|
|
all_process_ids.resize(max_process_id_count);
|
|
|
|
|
bytes_needed = 0;
|
|
|
|
|
processes_enumerated = ::EnumProcesses(&all_process_ids[0],
|
|
|
|
|
static_cast<DWORD>(all_process_ids.size()) * sizeof(DWORD),
|
|
|
|
|
&bytes_needed);
|
|
|
|
|
process_id_count = bytes_needed / sizeof(DWORD);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
for (size_t index = 0; index < process_id_count; ++index) {
|
|
|
|
|
DWORD process_id = all_process_ids[index];
|
|
|
|
|
HANDLE process_handle = ::OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ,
|
|
|
|
|
FALSE,
|
|
|
|
|
process_id);
|
|
|
|
|
if (process_handle != NULL) {
|
|
|
|
|
std::vector<wchar_t> image_path_buffer(MAX_PATH);
|
|
|
|
|
DWORD chars_copied = ::GetProcessImageFileName(process_handle,
|
|
|
|
|
&image_path_buffer[0],
|
|
|
|
|
MAX_PATH);
|
|
|
|
|
std::wstring image_path(&image_path_buffer[0]);
|
|
|
|
|
std::transform(image_path.begin(),
|
|
|
|
|
image_path.end(),
|
|
|
|
|
image_path.begin(),
|
|
|
|
|
::towlower);
|
|
|
|
|
if (image_path.find(process_name) != std::wstring::npos) {
|
|
|
|
|
process_ids->push_back(process_id);
|
|
|
|
|
}
|
|
|
|
|
::CloseHandle(process_handle);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2015-12-16 09:40:37 -08:00
|
|
|
} // namespace webdriver
|