mirror of
https://github.com/QL-Win/QuickLook.git
synced 2025-12-25 02:00:12 +08:00
Use 32bit helper to interact between 32bit processes
This commit is contained in:
131
QuickLook.Native/QuickLook.Native32/DialogHook.cpp
Normal file
131
QuickLook.Native/QuickLook.Native32/DialogHook.cpp
Normal file
@@ -0,0 +1,131 @@
|
||||
#include "stdafx.h"
|
||||
#include "DialogHook.h"
|
||||
#include "WoW64HookHelper.h"
|
||||
#include "HelperMethods.h"
|
||||
|
||||
|
||||
#pragma comment(linker, "/SECTION:.shared,RWS")
|
||||
#pragma data_seg(".shared")
|
||||
|
||||
static HHOOK ghHook = nullptr; // Hook handle
|
||||
static UINT WM_HOOK_NOTIFY = 0;
|
||||
static WCHAR filePathBuffer[MAX_PATH] = {'\0'};
|
||||
|
||||
#pragma data_seg()
|
||||
|
||||
#define SHARED_MEM_NAME L"QUICKLOOK_WOW64HOOKHELPER_MEM"
|
||||
|
||||
void DialogHook::GetSelectedFromCommonDialog(PWCHAR buffer)
|
||||
{
|
||||
auto hwndfg = GetForegroundWindow();
|
||||
DWORD pid = 0;
|
||||
auto tid = GetWindowThreadProcessId(hwndfg, &pid);
|
||||
|
||||
auto hProc = OpenProcess(PROCESS_QUERY_INFORMATION, false, pid);
|
||||
if (hProc == nullptr)
|
||||
return;
|
||||
|
||||
if (WM_HOOK_NOTIFY == 0)
|
||||
WM_HOOK_NOTIFY = RegisterWindowMessage(L"WM_QUICKLOOK_HOOK_NOTIFY_MSG");
|
||||
|
||||
BOOL isTargetWoW64 = false;
|
||||
if (GetProcAddress(GetModuleHandle(L"kernel32.dll"), "IsWow64Process") && !IsWow64Process(hProc, &isTargetWoW64))
|
||||
return;
|
||||
|
||||
BOOL isSelfWoW64 = false;
|
||||
if (GetProcAddress(GetModuleHandle(L"kernel32.dll"), "IsWow64Process") && !IsWow64Process(GetCurrentProcess(), &isSelfWoW64))
|
||||
return;
|
||||
|
||||
if (isTargetWoW64 && !isSelfWoW64)
|
||||
{
|
||||
// if self is 64bit and target is 32bit, do this
|
||||
GetSelectedFromWoW64HookHelper(buffer);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (ghHook != nullptr)
|
||||
UnhookWindowsHookEx(ghHook);
|
||||
ghHook = SetWindowsHookEx(WH_CALLWNDPROC, static_cast<HOOKPROC>(MsgHookProc), ModuleFromAddress(MsgHookProc), tid);
|
||||
if (ghHook == nullptr)
|
||||
return;
|
||||
|
||||
SendMessage(hwndfg, WM_HOOK_NOTIFY, 0, 0);
|
||||
wcscpy_s(buffer, wcslen(buffer) - 1, filePathBuffer);
|
||||
}
|
||||
}
|
||||
|
||||
void DialogHook::getSelectedInternal(CComPtr<IShellBrowser> psb, PWCHAR buffer)
|
||||
{
|
||||
CComPtr<IShellView> psv;
|
||||
if (FAILED(psb->QueryActiveShellView(&psv)))
|
||||
return;
|
||||
|
||||
CComPtr<IDataObject> dao;
|
||||
if (FAILED(psv->GetItemObject(SVGIO_SELECTION, IID_IDataObject, reinterpret_cast<void**>(&dao))))
|
||||
return;
|
||||
|
||||
return HelperMethods::ObtainFirstItem(dao, buffer);
|
||||
}
|
||||
|
||||
void DialogHook::GetSelectedFromWoW64HookHelper(PWCHAR buffer)
|
||||
{
|
||||
if (!WoW64HookHelper::CheckStatus())
|
||||
if (!WoW64HookHelper::Launch())
|
||||
return;
|
||||
|
||||
auto hHelperWnd = FindWindowEx(HWND_MESSAGE, nullptr, WoW64HookHelper::GetMsgWindowClassName(), nullptr);
|
||||
if (hHelperWnd == nullptr)
|
||||
return;
|
||||
|
||||
auto hMapFile = CreateFileMapping(INVALID_HANDLE_VALUE, nullptr, PAGE_READWRITE, 0, MAX_PATH * sizeof WCHAR, SHARED_MEM_NAME);
|
||||
if (hMapFile == nullptr)
|
||||
return;
|
||||
|
||||
auto sharedBuffer = static_cast<PWCHAR>(MapViewOfFile(hMapFile, FILE_MAP_ALL_ACCESS, 0, 0, MAX_PATH * sizeof WCHAR));
|
||||
if (sharedBuffer == nullptr)
|
||||
{
|
||||
CloseHandle(hMapFile);
|
||||
return;
|
||||
}
|
||||
|
||||
SendMessage(hHelperWnd, WM_HOOK_NOTIFY, 0, 0);
|
||||
|
||||
// the sharedBuffer should now ready
|
||||
wcscpy_s(buffer, MAX_PATH, sharedBuffer);
|
||||
|
||||
UnmapViewOfFile(sharedBuffer);
|
||||
CloseHandle(hMapFile);
|
||||
}
|
||||
|
||||
HMODULE DialogHook::ModuleFromAddress(PVOID pv)
|
||||
{
|
||||
MEMORY_BASIC_INFORMATION mbi;
|
||||
return VirtualQuery(pv, &mbi, sizeof mbi) != 0 ? static_cast<HMODULE>(mbi.AllocationBase) : nullptr;
|
||||
}
|
||||
|
||||
LRESULT DialogHook::MsgHookProc(int nCode, WPARAM wParam, LPARAM lParam)
|
||||
{
|
||||
if (nCode < 0)
|
||||
goto CONTINUE;
|
||||
|
||||
auto pMSG = reinterpret_cast<CWPSTRUCT*>(lParam);
|
||||
|
||||
// only response to WM_HOOK_NOTIFY
|
||||
if (pMSG->message != WM_HOOK_NOTIFY)
|
||||
goto CONTINUE;
|
||||
|
||||
UnhookWindowsHookEx(ghHook);
|
||||
ghHook = nullptr;
|
||||
|
||||
// get current selected item
|
||||
auto psb = reinterpret_cast<IShellBrowser*>(SendMessage(GetForegroundWindow(), WM_USER + 7, 0, 0));
|
||||
if (psb == nullptr)
|
||||
goto CONTINUE;
|
||||
|
||||
getSelectedInternal(psb, filePathBuffer);
|
||||
|
||||
return 0;
|
||||
|
||||
CONTINUE:
|
||||
return CallNextHookEx(ghHook, nCode, wParam, lParam);
|
||||
}
|
||||
12
QuickLook.Native/QuickLook.Native32/DialogHook.h
Normal file
12
QuickLook.Native/QuickLook.Native32/DialogHook.h
Normal file
@@ -0,0 +1,12 @@
|
||||
#pragma once
|
||||
class DialogHook
|
||||
{
|
||||
public:
|
||||
static void GetSelectedFromCommonDialog(PWCHAR buffer);
|
||||
|
||||
private:
|
||||
static void getSelectedInternal(CComPtr<IShellBrowser> psb, PWCHAR buffer);
|
||||
static void GetSelectedFromWoW64HookHelper(PWCHAR buffer);
|
||||
static HMODULE ModuleFromAddress(PVOID pv);
|
||||
static LRESULT CALLBACK MsgHookProc(int nCode, WPARAM wParam, LPARAM lParam);
|
||||
};
|
||||
@@ -1,9 +1,15 @@
|
||||
#include "stdafx.h"
|
||||
|
||||
#include "Shell32.h"
|
||||
#include "WoW64HookHelper.h"
|
||||
|
||||
#define EXPORT extern "C" __declspec(dllexport)
|
||||
|
||||
EXPORT void LaunchWoW64HookHelper()
|
||||
{
|
||||
WoW64HookHelper::Launch();
|
||||
}
|
||||
|
||||
EXPORT Shell32::FocusedWindowType GetFocusedWindowType()
|
||||
{
|
||||
return Shell32::GetFocusedWindowType();
|
||||
56
QuickLook.Native/QuickLook.Native32/HelperMethods.cpp
Normal file
56
QuickLook.Native/QuickLook.Native32/HelperMethods.cpp
Normal file
@@ -0,0 +1,56 @@
|
||||
#include "stdafx.h"
|
||||
#include "HelperMethods.h"
|
||||
|
||||
void HelperMethods::GetSelectedInternal(CComQIPtr<IWebBrowserApp> pwba, PWCHAR buffer)
|
||||
{
|
||||
CComQIPtr<IServiceProvider> psp;
|
||||
if (FAILED(pwba->QueryInterface(IID_IServiceProvider, reinterpret_cast<void**>(&psp))))
|
||||
return;
|
||||
|
||||
CComPtr<IShellBrowser> psb;
|
||||
if (FAILED(psp->QueryService(SID_STopLevelBrowser, IID_IShellBrowser, reinterpret_cast<LPVOID*>(&psb))))
|
||||
return;
|
||||
|
||||
CComPtr<IShellView> psv;
|
||||
if (FAILED(psb->QueryActiveShellView(&psv)))
|
||||
return;
|
||||
|
||||
CComPtr<IDataObject> dao;
|
||||
if (FAILED(psv->GetItemObject(SVGIO_SELECTION, IID_IDataObject, reinterpret_cast<void**>(&dao))))
|
||||
return;
|
||||
|
||||
return ObtainFirstItem(dao, buffer);
|
||||
}
|
||||
|
||||
void HelperMethods::ObtainFirstItem(CComPtr<IDataObject> dao, PWCHAR buffer)
|
||||
{
|
||||
FORMATETC formatetc;
|
||||
STGMEDIUM medium;
|
||||
|
||||
formatetc.cfFormat = CF_HDROP;
|
||||
formatetc.ptd = nullptr;
|
||||
formatetc.dwAspect = DVASPECT_CONTENT;
|
||||
formatetc.lindex = -1;
|
||||
formatetc.tymed = TYMED_HGLOBAL;
|
||||
|
||||
medium.tymed = TYMED_HGLOBAL;
|
||||
|
||||
if (FAILED(dao->GetData(&formatetc, &medium)))
|
||||
return;
|
||||
|
||||
int n = DragQueryFile(HDROP(medium.hGlobal), 0xFFFFFFFF, nullptr, 0);
|
||||
|
||||
if (n < 1)
|
||||
return;
|
||||
|
||||
DragQueryFile(HDROP(medium.hGlobal), 0, buffer, MAX_PATH - 1);
|
||||
}
|
||||
|
||||
bool HelperMethods::IsCursorActivated(HWND hwnd)
|
||||
{
|
||||
auto tId = GetWindowThreadProcessId(hwnd, nullptr);
|
||||
|
||||
GUITHREADINFO gui = {sizeof gui};
|
||||
GetGUIThreadInfo(tId, &gui);
|
||||
return gui.flags || gui.hwndCaret;
|
||||
}
|
||||
8
QuickLook.Native/QuickLook.Native32/HelperMethods.h
Normal file
8
QuickLook.Native/QuickLook.Native32/HelperMethods.h
Normal file
@@ -0,0 +1,8 @@
|
||||
#pragma once
|
||||
class HelperMethods
|
||||
{
|
||||
public:
|
||||
static void GetSelectedInternal(CComQIPtr<IWebBrowserApp> pWebBrowserApp, PWCHAR buffer);
|
||||
static void ObtainFirstItem(CComPtr<IDataObject> dao, PWCHAR buffer);
|
||||
static bool IsCursorActivated(HWND hwndfg);
|
||||
};
|
||||
@@ -82,11 +82,15 @@
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="DialogHook.h" />
|
||||
<ClInclude Include="HelperMethods.h" />
|
||||
<ClInclude Include="WoW64HookHelper.h" />
|
||||
<ClInclude Include="Shell32.h" />
|
||||
<ClInclude Include="stdafx.h" />
|
||||
<ClInclude Include="targetver.h" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="DialogHook.cpp" />
|
||||
<ClCompile Include="dllmain.cpp">
|
||||
<CompileAsManaged Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">false</CompileAsManaged>
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
@@ -95,12 +99,14 @@
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
<ClCompile Include="QuickLook.Native32.cpp" />
|
||||
<ClCompile Include="HelperMethods.cpp" />
|
||||
<ClCompile Include="DllExport.cpp" />
|
||||
<ClCompile Include="Shell32.cpp" />
|
||||
<ClCompile Include="stdafx.cpp">
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Create</PrecompiledHeader>
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Create</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
<ClCompile Include="WoW64HookHelper.cpp" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
|
||||
@@ -24,6 +24,15 @@
|
||||
<ClInclude Include="Shell32.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="WoW64HookHelper.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="DialogHook.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="HelperMethods.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="stdafx.cpp">
|
||||
@@ -35,7 +44,16 @@
|
||||
<ClCompile Include="Shell32.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="QuickLook.Native32.cpp">
|
||||
<ClCompile Include="WoW64HookHelper.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="DialogHook.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="HelperMethods.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="DllExport.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
#include "stdafx.h"
|
||||
|
||||
#include "Shell32.h"
|
||||
#include "HelperMethods.h"
|
||||
#include "DialogHook.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
@@ -10,10 +12,10 @@ Shell32::FocusedWindowType Shell32::GetFocusedWindowType()
|
||||
|
||||
auto hwndfg = GetForegroundWindow();
|
||||
|
||||
if (isCursorActivated(hwndfg))
|
||||
if (HelperMethods::IsCursorActivated(hwndfg))
|
||||
return INVALID;
|
||||
|
||||
auto classBuffer = new WCHAR[MAX_PATH];
|
||||
WCHAR classBuffer[MAX_PATH] = {'\0'};
|
||||
if (SUCCEEDED(GetClassName(hwndfg, classBuffer, MAX_PATH)))
|
||||
{
|
||||
if (wcscmp(classBuffer, L"WorkerW") == 0 || wcscmp(classBuffer, L"Progman") == 0)
|
||||
@@ -35,7 +37,6 @@ Shell32::FocusedWindowType Shell32::GetFocusedWindowType()
|
||||
}
|
||||
}
|
||||
}
|
||||
delete[] classBuffer;
|
||||
|
||||
return type;
|
||||
}
|
||||
@@ -51,7 +52,7 @@ void Shell32::GetCurrentSelection(PWCHAR buffer)
|
||||
getSelectedFromExplorer(buffer);
|
||||
break;
|
||||
case DIALOG:
|
||||
getSelectedFromCommonDialog(buffer);
|
||||
DialogHook::GetSelectedFromCommonDialog(buffer);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
@@ -90,10 +91,10 @@ void Shell32::getSelectedFromExplorer(PWCHAR buffer)
|
||||
if (FAILED(pwba->get_HWND(reinterpret_cast<LONG_PTR*>(&hwndwba))))
|
||||
continue;
|
||||
|
||||
if (hwndwba != hwndfg || isCursorActivated(hwndwba))
|
||||
if (hwndwba != hwndfg || HelperMethods::IsCursorActivated(hwndwba))
|
||||
continue;
|
||||
|
||||
getSelectedInternal(pwba, buffer);
|
||||
HelperMethods::GetSelectedInternal(pwba, buffer);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -112,138 +113,8 @@ void Shell32::getSelectedFromDesktop(PWCHAR buffer)
|
||||
if (FAILED(psw->FindWindowSW(&pvarLoc, &pvarLoc, SWC_DESKTOP, &phwnd, SWFO_NEEDDISPATCH, reinterpret_cast<IDispatch**>(&pwba))))
|
||||
return;
|
||||
|
||||
if (isCursorActivated(reinterpret_cast<HWND>(LongToHandle(phwnd))))
|
||||
if (HelperMethods::IsCursorActivated(reinterpret_cast<HWND>(LongToHandle(phwnd))))
|
||||
return;
|
||||
|
||||
getSelectedInternal(pwba, buffer);
|
||||
HelperMethods::GetSelectedInternal(pwba, buffer);
|
||||
}
|
||||
|
||||
void Shell32::getSelectedInternal(CComQIPtr<IWebBrowserApp> pwba, PWCHAR buffer)
|
||||
{
|
||||
CComQIPtr<IServiceProvider> psp;
|
||||
if (FAILED(pwba->QueryInterface(IID_IServiceProvider, reinterpret_cast<void**>(&psp))))
|
||||
return;
|
||||
|
||||
CComPtr<IShellBrowser> psb;
|
||||
if (FAILED(psp->QueryService(SID_STopLevelBrowser, IID_IShellBrowser, reinterpret_cast<LPVOID*>(&psb))))
|
||||
return;
|
||||
|
||||
CComPtr<IShellView> psv;
|
||||
if (FAILED(psb->QueryActiveShellView(&psv)))
|
||||
return;
|
||||
|
||||
CComPtr<IDataObject> dao;
|
||||
if (FAILED(psv->GetItemObject(SVGIO_SELECTION, IID_IDataObject, reinterpret_cast<void**>(&dao))))
|
||||
return;
|
||||
|
||||
return obtainFirstItem(dao, buffer);
|
||||
}
|
||||
|
||||
void Shell32::obtainFirstItem(CComPtr<IDataObject> dao, PWCHAR buffer)
|
||||
{
|
||||
FORMATETC formatetc;
|
||||
STGMEDIUM medium;
|
||||
|
||||
formatetc.cfFormat = CF_HDROP;
|
||||
formatetc.ptd = nullptr;
|
||||
formatetc.dwAspect = DVASPECT_CONTENT;
|
||||
formatetc.lindex = -1;
|
||||
formatetc.tymed = TYMED_HGLOBAL;
|
||||
|
||||
medium.tymed = TYMED_HGLOBAL;
|
||||
|
||||
if (FAILED(dao->GetData(&formatetc, &medium)))
|
||||
return;
|
||||
|
||||
int n = DragQueryFile(HDROP(medium.hGlobal), 0xFFFFFFFF, nullptr, 0);
|
||||
|
||||
if (n < 1)
|
||||
return;
|
||||
|
||||
DragQueryFile(HDROP(medium.hGlobal), 0, buffer, MAX_PATH - 1);
|
||||
}
|
||||
|
||||
bool Shell32::isCursorActivated(HWND hwnd)
|
||||
{
|
||||
auto tId = GetWindowThreadProcessId(hwnd, nullptr);
|
||||
|
||||
GUITHREADINFO gui = {sizeof gui};
|
||||
GetGUIThreadInfo(tId, &gui);
|
||||
return gui.flags || gui.hwndCaret;
|
||||
}
|
||||
|
||||
#pragma region DialogHook
|
||||
|
||||
#pragma comment(linker, "/SECTION:.shared,RWS")
|
||||
#pragma data_seg(".shared")
|
||||
HWND ghMsgWindow = nullptr; // Window handle
|
||||
HHOOK ghHook = nullptr; // Hook handle
|
||||
UINT WM_HOOK_NOTIFY = 0;
|
||||
WCHAR filePathBuffer[MAX_PATH] = {'\0'};
|
||||
#pragma data_seg()
|
||||
|
||||
void Shell32::getSelectedFromCommonDialog(PWCHAR buffer)
|
||||
{
|
||||
auto hwndfg = GetForegroundWindow();
|
||||
auto tid = GetWindowThreadProcessId(hwndfg, nullptr);
|
||||
|
||||
if (WM_HOOK_NOTIFY == 0)
|
||||
WM_HOOK_NOTIFY = RegisterWindowMessage(L"WM_QUICKLOOK_HOOK_NOTIFY_MSG");
|
||||
|
||||
if (ghHook != nullptr)
|
||||
UnhookWindowsHookEx(ghHook);
|
||||
ghHook = SetWindowsHookEx(WH_CALLWNDPROC, static_cast<HOOKPROC>(MsgHookProc), ModuleFromAddress(MsgHookProc), tid);
|
||||
if (ghHook == nullptr)
|
||||
return;
|
||||
|
||||
SendMessage(hwndfg, WM_HOOK_NOTIFY, 0, 0);
|
||||
wcscpy_s(buffer, wcslen(buffer) - 1, filePathBuffer);
|
||||
}
|
||||
|
||||
HMODULE Shell32::ModuleFromAddress(PVOID pv)
|
||||
{
|
||||
MEMORY_BASIC_INFORMATION mbi;
|
||||
return VirtualQuery(pv, &mbi, sizeof mbi) != 0 ? static_cast<HMODULE>(mbi.AllocationBase) : nullptr;
|
||||
}
|
||||
|
||||
LRESULT Shell32::MsgHookProc(int nCode, WPARAM wParam, LPARAM lParam)
|
||||
{
|
||||
if (nCode < 0)
|
||||
goto CONTINUE;
|
||||
|
||||
auto pMSG = reinterpret_cast<CWPSTRUCT*>(lParam);
|
||||
|
||||
// only response to WM_HOOK_NOTIFY
|
||||
if (pMSG->message != WM_HOOK_NOTIFY)
|
||||
goto CONTINUE;
|
||||
|
||||
UnhookWindowsHookEx(ghHook);
|
||||
ghHook = nullptr;
|
||||
|
||||
// get current selected item
|
||||
auto psb = reinterpret_cast<IShellBrowser*>(SendMessage(GetForegroundWindow(), WM_USER + 7, 0, 0));
|
||||
if (psb == nullptr)
|
||||
goto CONTINUE;
|
||||
|
||||
getSelectedInternal2(psb, filePathBuffer);
|
||||
|
||||
return 0;
|
||||
|
||||
CONTINUE:
|
||||
return CallNextHookEx(ghHook, nCode, wParam, lParam);
|
||||
}
|
||||
|
||||
void Shell32::getSelectedInternal2(CComPtr<IShellBrowser> psb, PWCHAR buffer)
|
||||
{
|
||||
CComPtr<IShellView> psv;
|
||||
if (FAILED(psb->QueryActiveShellView(&psv)))
|
||||
return;
|
||||
|
||||
CComPtr<IDataObject> dao;
|
||||
if (FAILED(psv->GetItemObject(SVGIO_SELECTION, IID_IDataObject, reinterpret_cast<void**>(&dao))))
|
||||
return;
|
||||
|
||||
return obtainFirstItem(dao, buffer);
|
||||
}
|
||||
|
||||
#pragma endregion DialogHook
|
||||
|
||||
@@ -15,20 +15,8 @@ public:
|
||||
|
||||
static FocusedWindowType GetFocusedWindowType();
|
||||
static void GetCurrentSelection(PWCHAR buffer);
|
||||
static LRESULT __stdcall WindowProcedure(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
|
||||
|
||||
private:
|
||||
static void getSelectedFromDesktop(PWCHAR buffer);
|
||||
static void getSelectedFromExplorer(PWCHAR buffer);
|
||||
|
||||
static void getSelectedInternal(CComQIPtr<IWebBrowserApp> pWebBrowserApp, PWCHAR buffer);
|
||||
static void obtainFirstItem(CComPtr<IDataObject> dao, PWCHAR buffer);
|
||||
static bool isCursorActivated(HWND hwndfg);
|
||||
|
||||
#pragma region DialogHook
|
||||
static void getSelectedFromCommonDialog(PWCHAR buffer);
|
||||
static HMODULE ModuleFromAddress(PVOID pv);
|
||||
static LRESULT CALLBACK MsgHookProc(int nCode, WPARAM wParam, LPARAM lParam);
|
||||
static void getSelectedInternal2(CComPtr<IShellBrowser> psb, PWCHAR buffer);
|
||||
#pragma endregion DialogHook
|
||||
};
|
||||
|
||||
54
QuickLook.Native/QuickLook.Native32/WoW64HookHelper.cpp
Normal file
54
QuickLook.Native/QuickLook.Native32/WoW64HookHelper.cpp
Normal file
@@ -0,0 +1,54 @@
|
||||
#include "stdafx.h"
|
||||
#include "WoW64HookHelper.h"
|
||||
|
||||
#define HELPER_FILE L"\\QuickLook.WoW64HookHelper.exe"
|
||||
#define RUN_ARG L"033A853A-E4B2-4552-9A91-E88789761C48"
|
||||
|
||||
HANDLE hHelper = nullptr;
|
||||
HANDLE hJob = nullptr;
|
||||
|
||||
bool WoW64HookHelper::CheckStatus()
|
||||
{
|
||||
DWORD running = -1;
|
||||
GetExitCodeProcess(hHelper, &running);
|
||||
return running == STILL_ACTIVE;
|
||||
}
|
||||
|
||||
bool WoW64HookHelper::Launch()
|
||||
{
|
||||
if (CheckStatus())
|
||||
return true;
|
||||
|
||||
createJob();
|
||||
|
||||
WCHAR fullPath[MAX_PATH] = {'\0'};
|
||||
GetModuleFileName(nullptr, fullPath, MAX_PATH - 1);
|
||||
auto p = wcsrchr(fullPath, L'\\');
|
||||
memcpy(p, HELPER_FILE, wcslen(HELPER_FILE) * sizeof WCHAR);
|
||||
|
||||
STARTUPINFO si = {'\0'};
|
||||
PROCESS_INFORMATION pi = {nullptr};
|
||||
si.cb = sizeof si;
|
||||
|
||||
CreateProcess(fullPath, RUN_ARG, nullptr, nullptr, false, 0, nullptr, nullptr, &si, &pi);
|
||||
hHelper = pi.hProcess;
|
||||
|
||||
AssignProcessToJobObject(hJob, hHelper);
|
||||
|
||||
return CheckStatus();
|
||||
}
|
||||
|
||||
void WoW64HookHelper::createJob()
|
||||
{
|
||||
if (hJob != nullptr)
|
||||
return;
|
||||
|
||||
hJob = CreateJobObject(nullptr, nullptr);
|
||||
|
||||
JOBOBJECT_BASIC_LIMIT_INFORMATION BasicLimitInformation = {'\0'};
|
||||
BasicLimitInformation.LimitFlags = JOB_OBJECT_LIMIT_KILL_ON_JOB_CLOSE;
|
||||
JOBOBJECT_EXTENDED_LIMIT_INFORMATION lpJobObjectInfo = {'\0'};
|
||||
lpJobObjectInfo.BasicLimitInformation = BasicLimitInformation;
|
||||
|
||||
SetInformationJobObject(hJob, JobObjectExtendedLimitInformation, &lpJobObjectInfo, sizeof JOBOBJECT_EXTENDED_LIMIT_INFORMATION);
|
||||
}
|
||||
18
QuickLook.Native/QuickLook.Native32/WoW64HookHelper.h
Normal file
18
QuickLook.Native/QuickLook.Native32/WoW64HookHelper.h
Normal file
@@ -0,0 +1,18 @@
|
||||
#pragma once
|
||||
|
||||
#include "stdafx.h"
|
||||
|
||||
class WoW64HookHelper
|
||||
{
|
||||
public:
|
||||
static PWCHAR GetMsgWindowClassName()
|
||||
{
|
||||
return L"QUICKLOOK_WOW64HOOKHELPER_MSG_CLASS";
|
||||
}
|
||||
|
||||
static bool CheckStatus();
|
||||
static bool Launch();
|
||||
|
||||
private:
|
||||
static void createJob();
|
||||
};
|
||||
Reference in New Issue
Block a user