Skip to content

Commit

Permalink
Updating the adapter to:
Browse files Browse the repository at this point in the history
- Implement a --help option that prints the help text then exits
- Serve protcol.json at /protocol.json
- Rename the TS namespace from IE to Edge
  • Loading branch information
andysterland committed Apr 20, 2016
1 parent 0beea60 commit 7d27819
Show file tree
Hide file tree
Showing 22 changed files with 241 additions and 106 deletions.
5 changes: 5 additions & 0 deletions EdgeDiagnosticsAdapter.sln
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,11 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "EdgeDiagnosticsAdapter", "E
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "EdgeWebkitImpl", "EdgeWebkitImpl\EdgeWebkitImpl.csproj", "{1405EE7F-BDA9-4692-B689-200CA8DC1FBF}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{E1DC8AAC-B98E-42F5-AC7B-AF6E0F52B22B}"
ProjectSection(SolutionItems) = preProject
protocol.json = protocol.json
EndProjectSection
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Win32 = Debug|Win32
Expand Down
9 changes: 8 additions & 1 deletion EdgeDiagnosticsAdapter/EdgeDiagnosticsAdapter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,15 @@
#include <Psapi.h>

const CStringA EdgeDiagnosticsAdapter::s_Protocol_Version = CStringA("1.1");
const string EdgeDiagnosticsAdapter::s_Default_Port = "9222";


EdgeDiagnosticsAdapter::EdgeDiagnosticsAdapter(_In_ LPCWSTR rootPath)
{
EdgeDiagnosticsAdapter(rootPath, EdgeDiagnosticsAdapter::s_Default_Port);
}

EdgeDiagnosticsAdapter::EdgeDiagnosticsAdapter(_In_ LPCWSTR rootPath, _In_ string port)
{
try
{
Expand All @@ -25,7 +32,7 @@ EdgeDiagnosticsAdapter::EdgeDiagnosticsAdapter(_In_ LPCWSTR rootPath)
::ChangeWindowMessageFilterEx(m_hWnd, Get_WM_SET_CONNECTION_HWND(), MSGFLT_ALLOW, 0);

// Create websocket thread
m_webSocketHander = ::make_shared<WebSocketHandler>(rootPath, m_hWnd);
m_webSocketHander = ::make_shared<WebSocketHandler>(rootPath, m_hWnd, port);
boost::thread serverThread(&WebSocketHandler::RunServer, m_webSocketHander);
this->IsServerRunning = m_webSocketHander->IsServerListening;
}
Expand Down
18 changes: 10 additions & 8 deletions EdgeDiagnosticsAdapter/EdgeDiagnosticsAdapter.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,24 +12,26 @@
#include <websocketpp/server.hpp>

class EdgeDiagnosticsAdapter :
public CWindowImpl < EdgeDiagnosticsAdapter >
public CWindowImpl < EdgeDiagnosticsAdapter >
{
public:
EdgeDiagnosticsAdapter(_In_ LPCWSTR rootPath);
~EdgeDiagnosticsAdapter();
EdgeDiagnosticsAdapter(_In_ LPCWSTR rootPath);
EdgeDiagnosticsAdapter(_In_ LPCWSTR rootPath, _In_ string port);
~EdgeDiagnosticsAdapter();
bool IsServerRunning;

static const CStringA s_Protocol_Version;
static const CStringA s_Protocol_Version;
static const string s_Default_Port;

BEGIN_MSG_MAP(WebSocketClient)
MESSAGE_HANDLER(WM_COPYDATA, OnCopyData);
BEGIN_MSG_MAP(WebSocketClient)
MESSAGE_HANDLER(WM_COPYDATA, OnCopyData);
MESSAGE_HANDLER(WM_PROCESSCOPYDATA, OnMessageFromIE)
MESSAGE_HANDLER(WM_TEST_TIMEOUT, OnTestTimeout)
MESSAGE_HANDLER(WM_TEST_START, OnTestStart)
END_MSG_MAP()
END_MSG_MAP()

// Window Messages
LRESULT OnCopyData(UINT nMsg, WPARAM wParam, LPARAM lParam, _Inout_ BOOL& /*bHandled*/);
LRESULT OnCopyData(UINT nMsg, WPARAM wParam, LPARAM lParam, _Inout_ BOOL& /*bHandled*/);
LRESULT OnMessageFromIE(UINT nMsg, WPARAM wParam, LPARAM lParam, _Inout_ BOOL& /*bHandled*/);
LRESULT OnTestTimeout(UINT nMsg, WPARAM wParam, LPARAM lParam, _Inout_ BOOL& /*bHandled*/);
LRESULT OnTestStart(UINT nMsg, WPARAM wParam, LPARAM lParam, _Inout_ BOOL& /*bHandled*/);
Expand Down
10 changes: 5 additions & 5 deletions EdgeDiagnosticsAdapter/EdgeDiagnosticsAdapter.vcxproj
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,7 @@
<IntrinsicFunctions>true</IntrinsicFunctions>
<PreprocessorDefinitions>NDEBUG;_CONSOLE;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<SDLCheck>true</SDLCheck>
<AdditionalIncludeDirectories>$(SolutionDir)External\boost_1_60_0\boost;$(SolutionDir)External\;..\Output\Published\$(Configuration)\$(Platform);..\external\websocketpp-0.5.0\;..\external\boost_1_57_0\;;C:\src\EdgeDiagnosticsAdapter\External;..\Common;$(SolutionDir)External\;..\Common\</AdditionalIncludeDirectories>
<AdditionalIncludeDirectories>$(SolutionDir)External\boost_1_60_0\boost;$(SolutionDir)External\;..\Output\Published\$(Configuration)\$(Platform)\;..\external\websocketpp-0.5.0\;..\external\boost_1_60_0\;C:\src\EdgeDiagnosticsAdapter\External;..\Common;$(SolutionDir)External\;..\Common\</AdditionalIncludeDirectories>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
</ClCompile>
<Link>
Expand All @@ -137,7 +137,7 @@
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<AdditionalDependencies>wininet.lib;version.lib;urlmon.lib;Common.lib;Rpcrt4.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalLibraryDirectories>..\Output\Published\$(Configuration)\;..\external\boost_1_57_0\x86\lib;..\Output\Published\$(Configuration)\</AdditionalLibraryDirectories>
<AdditionalLibraryDirectories>..\Output\Published\$(Configuration)\;..\External\boost_1_60_0\lib32-msvc-14.0\;..\Output\Published\$(Configuration)\</AdditionalLibraryDirectories>
<IgnoreSpecificDefaultLibraries>
</IgnoreSpecificDefaultLibraries>
</Link>
Expand All @@ -155,16 +155,16 @@
<IntrinsicFunctions>true</IntrinsicFunctions>
<PreprocessorDefinitions>NDEBUG;_CONSOLE;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<SDLCheck>true</SDLCheck>
<AdditionalIncludeDirectories>$(SolutionDir)External\boost_1_60_0\boost;$(SolutionDir)External;..\Common\;..\Output\Published\$(Configuration)\$(Platform);..\external\websocketpp-0.5.0\;..\external\boost_1_57_0\;;$(SolutionDir)External\;..\Common\</AdditionalIncludeDirectories>
<AdditionalIncludeDirectories>$(SolutionDir)External\boost_1_60_0\boost;$(SolutionDir)External\;..\Output\Published\$(Configuration)\$(Platform)\;..\external\websocketpp-0.5.0\;..\external\boost_1_60_0\;C:\src\EdgeDiagnosticsAdapter\External;..\Common;$(SolutionDir)External\;..\Common\</AdditionalIncludeDirectories>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<AdditionalDependencies>Common.lib;Rpcrt4.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalLibraryDirectories>..\Output\Published\$(Configuration)\;..\Output\Published\$(Configuration)\;..\external\boost_1_57_0\x64\lib;..\Output\Published\$(Configuration)\</AdditionalLibraryDirectories>
<AdditionalDependencies>Common.lib;Rpcrt4.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;version.lib;urlmon.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalLibraryDirectories>..\Output\Published\$(Configuration)\;C:\Program Files (x86)\Windows Kits\10\Lib\10.0.10586.0\um\x64;..\Output\Published\$(Configuration)\;..\External\boost_1_60_0\lib64-msvc-14.0;..\Output\Published\$(Configuration)\</AdditionalLibraryDirectories>
</Link>
<ProjectReference>
<LinkLibraryDependencies>false</LinkLibraryDependencies>
Expand Down
Binary file modified EdgeDiagnosticsAdapter/Resource.rc
Binary file not shown.
29 changes: 22 additions & 7 deletions EdgeDiagnosticsAdapter/WebSocketHandler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
#include <Psapi.h>
#include <Wininet.h>

WebSocketHandler::WebSocketHandler(_In_ LPCWSTR rootPath, _In_ HWND adapterhWnd) :
WebSocketHandler::WebSocketHandler(_In_ LPCWSTR rootPath, _In_ HWND adapterhWnd, _In_ string port) :
m_rootPath(rootPath),
m_AdapterhWnd(adapterhWnd),
m_port(9222),
Expand All @@ -30,10 +30,8 @@ WebSocketHandler::WebSocketHandler(_In_ LPCWSTR rootPath, _In_ HWND adapterhWnd)
m_server.set_message_handler(std::bind(&WebSocketHandler::OnMessage, this, std::placeholders::_1, std::placeholders::_2));
m_server.set_close_handler(std::bind(&WebSocketHandler::OnClose, this, std::placeholders::_1));

std::stringstream port;
port << m_port;
m_server.init_asio();
m_server.listen("0.0.0.0", port.str());
m_server.listen("0.0.0.0", port);
m_server.start_accept();

CString AdaptorLogging_EnvironmentVariable;
Expand Down Expand Up @@ -78,6 +76,17 @@ void WebSocketHandler::OnHttp(websocketpp::connection_hdl hdl)
ss << page;
}
}
else if (requestedResource == "/protocol.json")
{
// Load and return the protocol.json file
CString protocolJsonFile;
HRESULT hr = Helpers::ReadFileFromModule(MAKEINTRESOURCE(IDR_PROTOCOLJSON), protocolJsonFile);
if (hr == S_OK)
{
CStringA page(protocolJsonFile);
ss << page;
}
}
else if (requestedResource == "/json" || requestedResource == "/json/list")
{
// Enumerate the running IE instances
Expand Down Expand Up @@ -135,12 +144,14 @@ void WebSocketHandler::OnHttp(websocketpp::connection_hdl hdl)
}
else if (requestedResource == "/json/version")
{
// To do: This will need to change to support Edge
CStringA edgeVersion = Helpers::GetFileVersion(L"C:\\Windows\\System32\\edgehtml.dll");
// Todo: This is currently broken as the edgehtml version number is set at 11
//CStringA edgeVersion = Helpers::GetFileVersion(L"C:\\Windows\\System32\\edgehtml.dll");
CStringA edgeVersion = "13";
CStringA browser = "Microsoft Edge " + edgeVersion;
browser = Helpers::EscapeJsonString(CString(browser));


/*
Todo: Currently Edge does not store it's UA string and there is no way to fetch the UA without loading Edge.
DWORD dwUASize = 0;
UrlMkGetSessionOption(URLMON_OPTION_USERAGENT, nullptr, 0, &dwUASize, 0);
Expand All @@ -154,6 +165,10 @@ void WebSocketHandler::OnHttp(websocketpp::connection_hdl hdl)
CStringA userAgent = Helpers::EscapeJsonString(CString(pszUserAgent));
*/

CStringA userAgent = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/46.0.2486.0 Safari/537.36 Edge/13.10586";

ss << "{" << endl;
ss << " \"Browser\" : \"" << browser << "\"" << "," << endl;
ss << " \"Protocol-Version\" : \"" << EdgeDiagnosticsAdapter::s_Protocol_Version << "\"" << "," << endl;
Expand Down
2 changes: 1 addition & 1 deletion EdgeDiagnosticsAdapter/WebSocketHandler.h
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ struct IEInstance
class WebSocketHandler
{
public:
WebSocketHandler(_In_ LPCWSTR rootPath, _In_ HWND m_hWnd);
WebSocketHandler(_In_ LPCWSTR rootPath, _In_ HWND m_hWnd, _In_ string port);
void RunServer();
bool IsServerListening;

Expand Down
167 changes: 99 additions & 68 deletions EdgeDiagnosticsAdapter/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,17 +23,95 @@ BOOL WINAPI OnClose(DWORD reason)
return TRUE;
}

CString getPathToCurrentExeContainer()
{
// Get the current path that we are running from
CString fullPath;
DWORD count = ::GetModuleFileName(nullptr, fullPath.GetBuffer(MAX_PATH), MAX_PATH);
fullPath.ReleaseBufferSetLength(count);

LPWSTR buffer = fullPath.GetBuffer();
LPWSTR newPath = ::PathFindFileName(buffer);
if (newPath && newPath != buffer)
{
fullPath.ReleaseBufferSetLength((newPath - buffer));
}
else
{
fullPath.ReleaseBuffer();
}

return fullPath;
}

void setSecurityACLs()
{
CString fullPath = getPathToCurrentExeContainer();
// Check to make sure that the dll has the ACLs to load in an appcontainer
// We're doing this here as the adapter has no setup script and should be xcopy deployable/removeable

PACL pOldDACL = NULL, pNewDACL = NULL;
PSECURITY_DESCRIPTOR pSD = NULL;
EXPLICIT_ACCESS ea;
SECURITY_INFORMATION si = DACL_SECURITY_INFORMATION;

// The check is done on the folder and should be inherited to all objects
DWORD dwRes = GetNamedSecurityInfo(fullPath, SE_FILE_OBJECT, DACL_SECURITY_INFORMATION, NULL, NULL, &pOldDACL, NULL, &pSD);

// Initialize an EXPLICIT_ACCESS structure for the new ACE.
ZeroMemory(&ea, sizeof(EXPLICIT_ACCESS));
ea.grfAccessPermissions = GENERIC_READ | GENERIC_EXECUTE;
ea.grfAccessMode = SET_ACCESS;
ea.grfInheritance = SUB_CONTAINERS_AND_OBJECTS_INHERIT;
ea.Trustee.TrusteeForm = TRUSTEE_IS_NAME;
ea.Trustee.TrusteeType = TRUSTEE_IS_WELL_KNOWN_GROUP;
ea.Trustee.ptstrName = L"ALL APPLICATION PACKAGES";

// Create a new ACL that merges the new ACE into the existing DACL.
dwRes = SetEntriesInAcl(1, &ea, pOldDACL, &pNewDACL);
if (dwRes == ERROR_SUCCESS)
{
dwRes = SetNamedSecurityInfo(fullPath.GetBuffer(), SE_FILE_OBJECT, si, NULL, NULL, pNewDACL, NULL);
if (dwRes == ERROR_SUCCESS)
{

}
}

if (dwRes != ERROR_SUCCESS)
{
// The ACL was not set, this isn't fatal as it only impacts IE in EPM and Edge and the user can set it manually
wcout << L"Could not set ACL to allow access to IE EPM or Edge.";
wcout << L"\n";
wcout << Helpers::GetLastErrorMessage().GetBuffer();
wcout << L"\n";
wcout << L"You can set the ACL manually by adding Read & Execute permissions for 'All APPLICATION PACAKGES' to each dll.";
wcout << L"\n";
}

if (pSD != NULL)
{
LocalFree((HLOCAL)pSD);
}
if (pNewDACL != NULL)
{
LocalFree((HLOCAL)pNewDACL);
}
}

int wmain(int argc, wchar_t* argv[])
{
// Initialize COM and deinitialize when we go out of scope
HRESULT hrCoInit = ::CoInitializeEx(nullptr, COINIT_APARTMENTTHREADED | COINIT_DISABLE_OLE1DDE);
//::MessageBox(NULL, L"Stop here", L"STOP!", MB_ICONWARNING | MB_CANCELTRYCONTINUE | MB_DEFBUTTON3);

std:cout << "Edge Diagnostics Adapter" << std::endl;

po::options_description desc("Allowed options");
desc.add_options()
("help,h", "Prints this help text.")
("launch,l", po::value<string>(), "Launches Edge. Optionally at the URL specified in the value")
("killall,k", "Kills all running Edge processes.")
("chrome,c", "Launches Crhome in the background to serve the Chrome Developer Tools frontend.")
;
("port,p", po::value<string>(), "The port number to listen on. Default is 9222.");

po::variables_map vm;
try
Expand All @@ -47,6 +125,16 @@ int wmain(int argc, wchar_t* argv[])
return E_FAIL;
}

if (vm.count("help"))
{
std::cout << desc << std::endl;
return S_OK;
}


// Initialize COM and deinitialize when we go out of scope
HRESULT hrCoInit = ::CoInitializeEx(nullptr, COINIT_APARTMENTTHREADED | COINIT_DISABLE_OLE1DDE);

shared_ptr<HRESULT> spCoInit(&hrCoInit, [](const HRESULT* hrCom) -> void { if (SUCCEEDED(*hrCom)) { ::CoUninitialize(); } });
{
// Set a close handler to shutdown the chrome instance we launch
Expand Down Expand Up @@ -150,75 +238,16 @@ int wmain(int argc, wchar_t* argv[])
}
}

// Get the current path that we are running from
CString fullPath;
DWORD count = ::GetModuleFileName(nullptr, fullPath.GetBuffer(MAX_PATH), MAX_PATH);
fullPath.ReleaseBufferSetLength(count);

LPWSTR buffer = fullPath.GetBuffer();
LPWSTR newPath = ::PathFindFileName(buffer);
if (newPath && newPath != buffer)
{
fullPath.ReleaseBufferSetLength((newPath - buffer));
}
else
{
fullPath.ReleaseBuffer();
}

// Check to make sure that the dll has the ACLs to load in an appcontainer
// We're doing this here as the adapter has no setup script and should be xcopy deployable/removeable

PACL pOldDACL = NULL, pNewDACL = NULL;
PSECURITY_DESCRIPTOR pSD = NULL;
EXPLICIT_ACCESS ea;
SECURITY_INFORMATION si = DACL_SECURITY_INFORMATION;

// The check is done on the folder and should be inherited to all objects
DWORD dwRes = GetNamedSecurityInfo(fullPath, SE_FILE_OBJECT, DACL_SECURITY_INFORMATION, NULL, NULL, &pOldDACL, NULL, &pSD);

// Initialize an EXPLICIT_ACCESS structure for the new ACE.
ZeroMemory(&ea, sizeof(EXPLICIT_ACCESS));
ea.grfAccessPermissions = GENERIC_READ | GENERIC_EXECUTE;
ea.grfAccessMode = SET_ACCESS;
ea.grfInheritance = SUB_CONTAINERS_AND_OBJECTS_INHERIT;
ea.Trustee.TrusteeForm = TRUSTEE_IS_NAME;
ea.Trustee.TrusteeType = TRUSTEE_IS_WELL_KNOWN_GROUP;
ea.Trustee.ptstrName = L"ALL APPLICATION PACKAGES";

// Create a new ACL that merges the new ACE into the existing DACL.
dwRes = SetEntriesInAcl(1, &ea, pOldDACL, &pNewDACL);
if (dwRes == ERROR_SUCCESS)
{
dwRes = SetNamedSecurityInfo(fullPath.GetBuffer(), SE_FILE_OBJECT, si, NULL, NULL, pNewDACL, NULL);
if (dwRes == ERROR_SUCCESS)
{

}
}

if (dwRes != ERROR_SUCCESS)
string port = EdgeDiagnosticsAdapter::s_Default_Port;
if (vm.count("port"))
{
// The ACL was not set, this isn't fatal as it only impacts IE in EPM and Edge and the user can set it manually
wcout << L"Could not set ACL to allow access to IE EPM or Edge.";
wcout << L"\n";
wcout << Helpers::GetLastErrorMessage().GetBuffer();
wcout << L"\n";
wcout << L"You can set the ACL manually by adding Read & Execute permissions for 'All APPLICATION PACAKGES' to each dll.";
wcout << L"\n";
port = vm["port"].as<string>();
}

if (pSD != NULL)
{
LocalFree((HLOCAL)pSD);
}
if (pNewDACL != NULL)
{
LocalFree((HLOCAL)pNewDACL);
}
setSecurityACLs();

// Load the proxy server
EdgeDiagnosticsAdapter proxy(fullPath);
EdgeDiagnosticsAdapter proxy(getPathToCurrentExeContainer(), port);

if (proxy.IsServerRunning)
{
Expand Down Expand Up @@ -250,4 +279,6 @@ int wmain(int argc, wchar_t* argv[])
}

return S_OK;
}
}


1 change: 1 addition & 0 deletions EdgeDiagnosticsAdapter/resource.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,3 +12,4 @@
#define IDR_ASSERT_SCRIPT 108
#define IDR_CSSPARSER_SCRIPT 109
#define IDR_BROWSERTOOL_SCRIPT 110
#define IDR_PROTOCOLJSON 111
Loading

0 comments on commit 7d27819

Please sign in to comment.