mirror of
https://github.com/QL-Win/QuickLook.git
synced 2025-09-10 09:19:06 +00:00
Fix #29: stupid DOpus requires a more stupid "dopusrt.exe"... let OllyDbg fxxk it up
This commit is contained in:
141
QuickLook.Native/QuickLook.Native32/DOpus.cpp
Normal file
141
QuickLook.Native/QuickLook.Native32/DOpus.cpp
Normal file
@@ -0,0 +1,141 @@
|
||||
// Copyright <20> 2017 Paddy Xu
|
||||
//
|
||||
// This file is part of QuickLook program.
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
#include "stdafx.h"
|
||||
#include "DOpus.h"
|
||||
#include "rapidxml.hpp"
|
||||
|
||||
#include <iostream>
|
||||
|
||||
#define DOPOUS_IPC_LP_INFO 0x00000015
|
||||
#define DOPOUS_IPC_LP_DATA L"listsel"
|
||||
#define DOPOUS_CLASS L"DOpus.ParentWindow"
|
||||
#define DOPOUS_NAME L"Directory Opus"
|
||||
#define MSGWINDOW_CLASS L"QuickLook.Native.DOpus.MsgWindow"
|
||||
|
||||
HWND hMsgWnd;
|
||||
HANDLE hGetResultEvent;
|
||||
|
||||
PCHAR pXmlBuffer;
|
||||
|
||||
void DOpus::GetSelected(PWCHAR buffer)
|
||||
{
|
||||
/*
|
||||
* CPU Disasm
|
||||
* 6A44B588 |. 68 A839526A PUSH OFFSET 6A5239A8 ; /WindowName = "Directory Opus"
|
||||
* 6A44B58D |. 68 6459526A PUSH OFFSET 6A525964 ; |ClassName = "DOpus.ParentWindow"
|
||||
* 6A44B592 |. 894424 40 MOV DWORD PTR SS:[ESP+40],EAX ; |
|
||||
* 6A44B596 |. C74424 30 140 MOV DWORD PTR SS:[ESP+30],14 ; |
|
||||
* 6A44B59E |. FFD7 CALL EDI ; \USER32.FindWindowW
|
||||
* ...
|
||||
* 00BC2E9B |. 50 PUSH EAX ; /lParam = 12FE80C -> 15 ;
|
||||
* 00BC2E9C |. 57 PUSH EDI ; |wParam ; class = dopusrt.getinfo
|
||||
* 00BC2E9D |. 6A 4A PUSH 4A ; |Msg = WM_COPYDATA
|
||||
* 00BC2E9F |. FF75 FC PUSH DWORD PTR SS:[LOCAL.1] ; |hWnd => [LOCAL.1] ; class = DOpus.ParentWindow, text = Directory Opus
|
||||
* 00BC2EA2 |. FF15 0802C000 CALL DWORD PTR DS:[<&USER32.SendMessageW ; \USER32.SendMessageW
|
||||
*
|
||||
* CPU Stack
|
||||
* 012FE80C |00000015
|
||||
* 012FE810 |00000010
|
||||
* 012FE814 |013A26C0 ; UNICODE "listsel"
|
||||
*/
|
||||
|
||||
if (hMsgWnd == nullptr)
|
||||
PrepareMessageWindow();
|
||||
if (hMsgWnd == nullptr)
|
||||
return;
|
||||
|
||||
PWCHAR data = DOPOUS_IPC_LP_DATA;
|
||||
COPYDATASTRUCT cds;
|
||||
cds.dwData = DOPOUS_IPC_LP_INFO;
|
||||
cds.cbData = (wcslen(data) + 1) * sizeof WCHAR;
|
||||
cds.lpData = data;
|
||||
|
||||
auto ret = SendMessage(FindWindow(DOPOUS_CLASS, DOPOUS_NAME), WM_COPYDATA, (WPARAM)hMsgWnd, (LPARAM)&cds);
|
||||
if (!ret)
|
||||
return;
|
||||
|
||||
WaitForSingleObject(hGetResultEvent, 2000);
|
||||
|
||||
ParseXmlBuffer(buffer);
|
||||
|
||||
delete[] pXmlBuffer;
|
||||
}
|
||||
|
||||
void DOpus::ParseXmlBuffer(PWCHAR buffer)
|
||||
{
|
||||
/*
|
||||
* <?xml version="1.0" encoding="UTF-8"?>
|
||||
* <results command="listsel" result="1">
|
||||
* <items display_path="C:\folder" lister="0x707f6" path="C:\folder" tab="0xb0844">
|
||||
* <item id="11" name="1.jpg" path="C:\folder\1.jpg" type="0" />
|
||||
* <item id="12" name="2.zip" path="C:\folder\2.zip" type="1" />
|
||||
* ...
|
||||
*/
|
||||
|
||||
using namespace rapidxml;
|
||||
|
||||
xml_document<> doc;
|
||||
doc.parse<0>(pXmlBuffer);
|
||||
|
||||
auto results = doc.first_node("results");
|
||||
auto items = results->first_node("items");
|
||||
for (auto item = items->first_node("item"); item; item = item->next_sibling("item"))
|
||||
{
|
||||
auto path = item->first_attribute("path")->value();
|
||||
|
||||
auto size = MultiByteToWideChar(CP_UTF8, MB_ERR_INVALID_CHARS, path, -1, nullptr, 0);
|
||||
auto b = new WCHAR[size];
|
||||
MultiByteToWideChar(CP_UTF8, MB_ERR_INVALID_CHARS, path, -1, b, size);
|
||||
|
||||
wcscpy_s(buffer, MAX_PATH, b);
|
||||
return; // we now cares only the first result
|
||||
}
|
||||
}
|
||||
|
||||
void DOpus::PrepareMessageWindow()
|
||||
{
|
||||
WNDCLASSEX wx = {'\0'};
|
||||
wx.cbSize = sizeof(WNDCLASSEX);
|
||||
wx.lpfnWndProc = msgWindowProc;
|
||||
wx.lpszClassName = MSGWINDOW_CLASS;
|
||||
|
||||
if (RegisterClassEx(&wx))
|
||||
hMsgWnd = CreateWindowEx(0, MSGWINDOW_CLASS, L"", 0, 0, 0, 0, 0, HWND_MESSAGE, nullptr, nullptr, nullptr);
|
||||
|
||||
hGetResultEvent = CreateEvent(nullptr, FALSE, FALSE, nullptr);
|
||||
}
|
||||
|
||||
LRESULT CALLBACK DOpus::msgWindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
|
||||
{
|
||||
switch (uMsg)
|
||||
{
|
||||
case WM_COPYDATA:
|
||||
{
|
||||
auto cds = reinterpret_cast<PCOPYDATASTRUCT>(lParam);
|
||||
auto buf = static_cast<PCHAR>(cds->lpData);
|
||||
|
||||
pXmlBuffer = new CHAR[cds->cbData + 1]{'\0'};
|
||||
memcpy(pXmlBuffer, buf, cds->cbData);
|
||||
|
||||
SetEvent(hGetResultEvent);
|
||||
return 0;
|
||||
}
|
||||
default:
|
||||
return DefWindowProc(hWnd, uMsg, wParam, lParam);
|
||||
}
|
||||
}
|
27
QuickLook.Native/QuickLook.Native32/DOpus.h
Normal file
27
QuickLook.Native/QuickLook.Native32/DOpus.h
Normal file
@@ -0,0 +1,27 @@
|
||||
// Copyright <20> 2017 Paddy Xu
|
||||
//
|
||||
// This file is part of QuickLook program.
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
#pragma once
|
||||
class DOpus
|
||||
{
|
||||
public:
|
||||
static void PrepareMessageWindow();
|
||||
static void GetSelected(PWCHAR buffer);
|
||||
private:
|
||||
static void ParseXmlBuffer(PWCHAR buffer);
|
||||
static LRESULT CALLBACK msgWindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
|
||||
};
|
@@ -49,6 +49,8 @@ void DialogHook::GetSelected(PWCHAR buffer)
|
||||
if (!IsWow64Process(hProc, &isTargetWoW64))
|
||||
return;
|
||||
|
||||
CloseHandle(hProc);
|
||||
|
||||
BOOL isSelfWoW64 = false;
|
||||
if (!IsWow64Process(GetCurrentProcess(), &isSelfWoW64))
|
||||
return;
|
||||
|
@@ -19,12 +19,14 @@
|
||||
|
||||
#include "Shell32.h"
|
||||
#include "WoW64HookHelper.h"
|
||||
#include "DOpus.h"
|
||||
|
||||
#define EXPORT extern "C" __declspec(dllexport)
|
||||
|
||||
EXPORT void LaunchWoW64HookHelper()
|
||||
EXPORT void Init()
|
||||
{
|
||||
WoW64HookHelper::Launch();
|
||||
DOpus::PrepareMessageWindow();
|
||||
}
|
||||
|
||||
EXPORT Shell32::FocusedWindowType GetFocusedWindowType()
|
||||
|
@@ -83,8 +83,10 @@
|
||||
</ItemDefinitionGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="DialogHook.h" />
|
||||
<ClInclude Include="DOpus.h" />
|
||||
<ClInclude Include="Everything.h" />
|
||||
<ClInclude Include="HelperMethods.h" />
|
||||
<ClInclude Include="rapidxml.hpp" />
|
||||
<ClInclude Include="WoW64HookHelper.h" />
|
||||
<ClInclude Include="Shell32.h" />
|
||||
<ClInclude Include="stdafx.h" />
|
||||
@@ -100,6 +102,7 @@
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
<ClCompile Include="DOpus.cpp" />
|
||||
<ClCompile Include="Everything.cpp" />
|
||||
<ClCompile Include="HelperMethods.cpp" />
|
||||
<ClCompile Include="DllExport.cpp" />
|
||||
|
@@ -36,6 +36,12 @@
|
||||
<ClInclude Include="Everything.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="DOpus.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="rapidxml.hpp">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="stdafx.cpp">
|
||||
@@ -62,5 +68,8 @@
|
||||
<ClCompile Include="Everything.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="DOpus.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
</Project>
|
@@ -21,6 +21,7 @@
|
||||
#include "HelperMethods.h"
|
||||
#include "DialogHook.h"
|
||||
#include "Everything.h"
|
||||
#include "DOpus.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
@@ -32,29 +33,33 @@ Shell32::FocusedWindowType Shell32::GetFocusedWindowType()
|
||||
return INVALID;
|
||||
|
||||
WCHAR classBuffer[MAX_PATH] = {'\0'};
|
||||
if (SUCCEEDED(GetClassName(hwndfg, classBuffer, MAX_PATH)))
|
||||
if (FAILED(GetClassName(hwndfg, classBuffer, MAX_PATH)))
|
||||
return INVALID;
|
||||
|
||||
if (wcscmp(classBuffer, L"dopus.lister") == 0)
|
||||
{
|
||||
if (wcscmp(classBuffer, L"EVERYTHING") == 0)
|
||||
return DOPUS;
|
||||
}
|
||||
if (wcscmp(classBuffer, L"EVERYTHING") == 0)
|
||||
{
|
||||
return EVERYTHING;
|
||||
}
|
||||
if (wcscmp(classBuffer, L"WorkerW") == 0 || wcscmp(classBuffer, L"Progman") == 0)
|
||||
{
|
||||
if (FindWindowEx(hwndfg, nullptr, L"SHELLDLL_DefView", nullptr) != nullptr)
|
||||
{
|
||||
return EVERYTHING;
|
||||
return DESKTOP;
|
||||
}
|
||||
if (wcscmp(classBuffer, L"WorkerW") == 0 || wcscmp(classBuffer, L"Progman") == 0)
|
||||
}
|
||||
if (wcscmp(classBuffer, L"ExploreWClass") == 0 || wcscmp(classBuffer, L"CabinetWClass") == 0)
|
||||
{
|
||||
return EXPLORER;
|
||||
}
|
||||
if (wcscmp(classBuffer, L"#32770") == 0)
|
||||
{
|
||||
if (FindWindowEx(hwndfg, nullptr, L"DUIViewWndClassName", nullptr) != nullptr)
|
||||
{
|
||||
if (FindWindowEx(hwndfg, nullptr, L"SHELLDLL_DefView", nullptr) != nullptr)
|
||||
{
|
||||
return DESKTOP;
|
||||
}
|
||||
}
|
||||
if (wcscmp(classBuffer, L"ExploreWClass") == 0 || wcscmp(classBuffer, L"CabinetWClass") == 0)
|
||||
{
|
||||
return EXPLORER;
|
||||
}
|
||||
if (wcscmp(classBuffer, L"#32770") == 0)
|
||||
{
|
||||
if (FindWindowEx(hwndfg, nullptr, L"DUIViewWndClassName", nullptr) != nullptr)
|
||||
{
|
||||
return DIALOG;
|
||||
}
|
||||
return DIALOG;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -77,6 +82,9 @@ void Shell32::GetCurrentSelection(PWCHAR buffer)
|
||||
case EVERYTHING:
|
||||
Everything::GetSelected(buffer);
|
||||
break;
|
||||
case DOPUS:
|
||||
DOpus::GetSelected(buffer);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
@@ -29,6 +29,7 @@ public:
|
||||
EXPLORER,
|
||||
DIALOG,
|
||||
EVERYTHING,
|
||||
DOPUS,
|
||||
};
|
||||
|
||||
static FocusedWindowType GetFocusedWindowType();
|
||||
|
2596
QuickLook.Native/QuickLook.Native32/rapidxml.hpp
Normal file
2596
QuickLook.Native/QuickLook.Native32/rapidxml.hpp
Normal file
File diff suppressed because it is too large
Load Diff
@@ -31,3 +31,4 @@
|
||||
#include<shlguid.h>
|
||||
#include<Shlobj.h>
|
||||
#include<Shellapi.h>
|
||||
#include<Psapi.h>
|
||||
|
@@ -21,6 +21,7 @@
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\QuickLook.Native32\DOpus.cpp" />
|
||||
<ClCompile Include="..\QuickLook.Native32\Everything.cpp" />
|
||||
<ClCompile Include="..\QuickLook.Native32\HelperMethods.cpp" />
|
||||
<ClCompile Include="..\QuickLook.Native32\Shell32.cpp" />
|
||||
|
@@ -9,5 +9,6 @@
|
||||
<ClCompile Include="..\QuickLook.Native32\stdafx.cpp" />
|
||||
<ClCompile Include="..\QuickLook.Native32\WoW64HookHelper.cpp" />
|
||||
<ClCompile Include="..\QuickLook.Native32\Everything.cpp" />
|
||||
<ClCompile Include="..\QuickLook.Native32\DOpus.cpp" />
|
||||
</ItemGroup>
|
||||
</Project>
|
Reference in New Issue
Block a user