#define UNICODE
#define _UNICODE
#define WINVER 0x0501
#define _ATL_XP_TARGETING
#define _ATL_NO_AUTOMATIC_NAMESPACE
#define _WTL_NO_AUTOMATIC_NAMESPACE
#include <cstdlib>
#include <windows.h>
#include <shobjidl.h>
#include <atlbase.h>
#include <atltypes.h>
#include <atlwin.h>
#include <atlapp.h>
#include <atlcrack.h>
// boostを使いたくないなら、#include <vector>に変更する。
#include <boost/container/static_vector.hpp>
class Module : public ATL::CAtlExeModuleT<Module>
{
};
Module module;
class ATL_NO_VTABLE UntrustedSecurityManager :
public ATL::CComObjectRootEx<ATL::CComSingleThreadModel>,
public IInternetSecurityManagerEx2
{
public:
BEGIN_COM_MAP(UntrustedSecurityManager)
COM_INTERFACE_ENTRY(IInternetSecurityManager)
COM_INTERFACE_ENTRY(IInternetSecurityManagerEx)
COM_INTERFACE_ENTRY(IInternetSecurityManagerEx2)
END_COM_MAP()
IFACEMETHOD(SetSecuritySite)(
_In_opt_ IInternetSecurityMgrSite* /*pSite*/) override
{
return INET_E_DEFAULT_ACTION;
}
IFACEMETHOD(GetSecuritySite)(
_Out_ IInternetSecurityMgrSite** /*ppSite*/) override
{
return INET_E_DEFAULT_ACTION;
}
IFACEMETHOD(MapUrlToZone)(
_In_ LPCWSTR /*pwszUrl*/,
_Out_ DWORD* pdwZone,
DWORD /*dwFlags*/) override
{
*pdwZone = URLZONE_UNTRUSTED;
return S_OK;
}
IFACEMETHOD(GetSecurityId)(
_In_ LPCWSTR /*pwszUrl*/,
_Out_writes_bytes_to_(MAX_SIZE_SECURITY_ID, *pcbSecurityId) BYTE* /*pbSecurityId*/,
_Inout_ _At_(*pcbSecurityId, _In_range_(>= , MAX_SIZE_SECURITY_ID) _Out_range_(0, MAX_SIZE_SECURITY_ID)) DWORD* /*pcbSecurityId*/,
_In_ DWORD_PTR /*dwReserved*/) override
{
return INET_E_DEFAULT_ACTION;
}
IFACEMETHOD(ProcessUrlAction)(
_In_ LPCWSTR pwszUrl,
DWORD dwAction,
_Out_writes_(cbPolicy) BYTE* pPolicy,
DWORD cbPolicy,
_In_opt_ BYTE* pContext,
DWORD cbContext,
DWORD dwFlags,
DWORD dwReserved) override
{
DWORD flags;
return ProcessUrlActionEx(pwszUrl, dwAction, pPolicy, cbPolicy, pContext, cbContext, dwFlags, dwReserved, &flags);
}
IFACEMETHOD(QueryCustomPolicy)(
_In_ LPCWSTR /*pwszUrl*/,
_In_ REFGUID /*guidKey*/,
/*__RPC__deref_out_ecount_full_opt(*pcbPolicy)*/ BYTE** /*ppPolicy*/,
_Out_ DWORD* /*pcbPolicy*/,
_In_ BYTE* /*pContext*/,
DWORD /*cbContext*/,
DWORD /*dwReserved*/) override
{
return INET_E_DEFAULT_ACTION;
}
IFACEMETHOD(SetZoneMapping)(
DWORD /*dwZone*/,
_In_ LPCWSTR /*lpszPattern*/,
DWORD /*dwFlags*/) override
{
return INET_E_DEFAULT_ACTION;
}
IFACEMETHOD(GetZoneMappings)(
DWORD /*dwZone*/,
__RPC__deref_out_opt IEnumString** /*ppenumString*/,
DWORD /*dwFlags*/) override
{
return INET_E_DEFAULT_ACTION;
}
IFACEMETHOD(ProcessUrlActionEx)(
_In_ LPCWSTR /*pwszUrl*/,
DWORD /*dwAction*/,
__RPC__out_ecount_full(cbPolicy) BYTE* pPolicy,
DWORD cbPolicy,
_In_ BYTE* /*pContext*/,
DWORD /*cbContext*/,
DWORD /*dwFlags*/,
DWORD /*dwReserved*/,
_Out_ DWORD* pdwOutFlags) override
{
if (pdwOutFlags != nullptr)
{
*pdwOutFlags = PUAFOUT_DEFAULT;
}
if (cbPolicy == sizeof(DWORD))
{
*reinterpret_cast<DWORD*>(pPolicy) = URLPOLICY_DISALLOW;
return S_FALSE;
}
return INET_E_DEFAULT_ACTION;
}
IFACEMETHOD(MapUrlToZoneEx2)(
_In_ IUri* /*pUri*/,
_Out_ DWORD* pdwZone,
DWORD /*dwFlags*/,
_Outptr_opt_ LPWSTR* ppwszMappedUrl,
_Out_opt_ DWORD* pdwOutFlags) override
{
if (ppwszMappedUrl != nullptr)
{
*ppwszMappedUrl = nullptr;
}
if (pdwOutFlags != nullptr)
{
*pdwOutFlags = 0;
}
if (pdwZone != nullptr)
{
*pdwZone = URLZONE_UNTRUSTED;
}
return S_OK;
}
IFACEMETHOD(ProcessUrlActionEx2)(
_In_ IUri* /*pUri*/,
DWORD dwAction,
__RPC__out_ecount_full(cbPolicy) BYTE* pPolicy,
DWORD cbPolicy,
_In_opt_ BYTE* pContext,
DWORD cbContext,
DWORD dwFlags,
DWORD_PTR dwReserved,
_Out_ DWORD* pdwOutFlags) override
{
return ProcessUrlActionEx(L"", dwAction, pPolicy, cbPolicy, pContext, cbContext, dwFlags, dwReserved, pdwOutFlags);
}
IFACEMETHOD(GetSecurityIdEx2)(
_In_ IUri* /*pUri*/,
/*_Out_writes_bytes_to_(MAX_SIZE_SECURITY_ID, *pcbSecurityId)*/ BYTE* /*pbSecurityId*/,
/*_Inout_ _At_(*pcbSecurityId, _In_range_(>= , MAX_SIZE_SECURITY_ID) _Out_range_(0, MAX_SIZE_SECURITY_ID))*/ DWORD* /*pcbSecurityId*/,
_In_ DWORD_PTR /*dwReserved*/) override
{
return INET_E_DEFAULT_ACTION;
}
IFACEMETHOD(QueryCustomPolicyEx2)(
_In_ IUri* /*pUri*/,
_In_ REFGUID /*guidKey*/,
__RPC__deref_out_ecount_full_opt(*pcbPolicy) BYTE** /*ppPolicy*/,
_Out_ DWORD* /*pcbPolicy*/,
_In_ BYTE* /*pContext*/,
DWORD /*cbContext*/,
DWORD_PTR /*dwReserved*/) override
{
return INET_E_DEFAULT_ACTION;
}
};
class ATL_NO_VTABLE WebBrowserServiceProvider :
public ATL::CComObjectRootEx<ATL::CComSingleThreadModel>,
public IServiceProvider
{
public:
BEGIN_COM_MAP(WebBrowserServiceProvider)
COM_INTERFACE_ENTRY(IServiceProvider)
END_COM_MAP()
public:
IFACEMETHOD(QueryService)(
_In_ REFGUID guidService,
_In_ REFIID riid,
_COM_Outptr_ void** ppv) override
{
if (guidService == SID_SInternetSecurityManager
|| guidService == SID_SInternetSecurityManagerEx
|| guidService == SID_SInternetSecurityManagerEx2)
{
return m_untrustedSecurityManager.QueryInterface(riid, ppv);
}
return E_NOINTERFACE;
}
private:
ATL::CComObjectStackEx<UntrustedSecurityManager> m_untrustedSecurityManager;
};
ATL::CComObjectStackEx<WebBrowserServiceProvider> g_webBrowserServiceProvider;
class TestWindow :
public ATL::CWindowImpl<TestWindow>,
public WTL::CMessageFilter
{
public:
int Run(int cmdShow, _Inout_ WTL::CMessageLoop& msgLoop)
{
if (!Create(nullptr, ATL::CWindow::rcDefault,
TEXT("Hello, world"), WS_OVERLAPPEDWINDOW))
{
return -1;
}
ShowWindow(cmdShow);
UpdateWindow();
msgLoop.AddMessageFilter(this);
return msgLoop.Run();
}
BOOL PreTranslateMessage(_In_ MSG* pmsg) override
{
if (m_webBrowser.IsWindow()
&& m_webBrowser.SendMessage(
WM_FORWARDMSG, 0, reinterpret_cast<LPARAM>(pmsg)))
{
return TRUE;
}
return IsDialogMessage(pmsg);
}
DECLARE_WND_CLASS(TEXT("Test Window Class"));
BEGIN_MSG_MAP(TestWindow)
MSG_WM_SIZE(OnSize)
MSG_WM_SETFOCUS(OnSetFocus)
MSG_WM_CREATE(OnCreate)
MSG_WM_DESTROY(OnDestroy)
END_MSG_MAP()
private:
void OnSize(UINT, SIZE size)
{
m_webBrowser.ResizeClient(size.cx, size.cy);
}
void OnSetFocus(HWND)
{
m_webBrowser.SetFocus();
}
LRESULT OnCreate(const CREATESTRUCT*)
{
constexpr DWORD IDC_WEBBROWSER_CONTROL = 1;
RECT empty{};
m_webBrowser.Create(m_hWnd, empty,
L"{8856F961-340A-11D0-A96B-00C04FD705A2}",
WS_CHILD | WS_VISIBLE | WS_BORDER | WS_TABSTOP | WS_GROUP, 0,
IDC_WEBBROWSER_CONTROL);
ATL::CComPtr<IServiceProvider> sp;
if (SUCCEEDED(m_webBrowser.QueryControl(&sp)))
{
ATL::CComPtr<IProfferService> ps;
if (SUCCEEDED(sp->QueryService(SID_SProfferService, &ps)))
{
DWORD cookie;
ATLENSURE_RETURN_VAL(
SUCCEEDED(ps->ProfferService(
SID_SInternetSecurityManagerEx2,
&g_webBrowserServiceProvider,
&cookie)),
-1);
m_webBrowserServiceCookie.push_back(cookie);
ATLENSURE_RETURN_VAL(
SUCCEEDED(ps->ProfferService(
SID_SInternetSecurityManagerEx,
&g_webBrowserServiceProvider,
&cookie)),
-1);
m_webBrowserServiceCookie.push_back(cookie);
ATLENSURE_RETURN_VAL(
SUCCEEDED(ps->ProfferService(
SID_SInternetSecurityManager,
&g_webBrowserServiceProvider,
&cookie)),
-1);
m_webBrowserServiceCookie.push_back(cookie);
}
}
ATL::CComQIPtr<IWebBrowser2> wb = sp;
ATL::CComVariant url(L"http://enable-javascript.com/ja/");
wb->Navigate2(&url, nullptr, nullptr, nullptr, nullptr);
return 0;
}
void OnDestroy()
{
ATL::CComPtr<IServiceProvider> sp;
if (SUCCEEDED(m_webBrowser.QueryControl(&sp)))
{
ATL::CComPtr<IProfferService> ps;
if (SUCCEEDED(sp->QueryService(SID_SProfferService, &ps)))
{
for (auto cookie : m_webBrowserServiceCookie)
{
ps->RevokeService(cookie);
}
}
}
PostQuitMessage(0);
}
ATL::CAxWindow m_webBrowser;
// boostを使いたくないなら、std::vector<DWORD>に変更する。
boost::container::static_vector<DWORD, 3> m_webBrowserServiceCookie;
};
int WINAPI WinMain(HINSTANCE, HINSTANCE, LPSTR, int cmdShow)
{
if (FAILED(OleInitialize(nullptr)))
{
std::quick_exit(-1);
}
WTL::CMessageLoop msgLoop;
TestWindow wnd;
std::quick_exit(wnd.Run(cmdShow, msgLoop));
} |