@@ -55,46 +55,152 @@ using namespace std;
5555using namespace WinUtils ;
5656
5757namespace {
58- class D3D10GrabberWorker : public QObject {
59- Q_OBJECT
58+ class D3D10GrabberWorker : public QObject {
59+ Q_OBJECT
60+
61+ public:
62+ D3D10GrabberWorker (QObject *parent, LPSECURITY_ATTRIBUTES lpsa);
63+ bool init ();
64+ ~D3D10GrabberWorker ();
65+ private:
66+ HANDLE m_frameGrabbedEvent;
67+ signals:
68+ void frameGrabbed ();
69+ public slots:
70+ void runLoop ();
71+
72+ public:
73+ bool stop = false ;
74+ private:
75+ LPSECURITY_ATTRIBUTES m_lpsa;
76+ };
77+
78+ const unsigned kBytesPerPixel = 4 ;
79+
80+ D3D10GrabberWorker::D3D10GrabberWorker (QObject *parent, LPSECURITY_ATTRIBUTES lpsa) :
81+ QObject (parent),
82+ m_lpsa (lpsa)
83+ {
84+ }
6085
61- public:
62- D3D10GrabberWorker (QObject *parent, LPSECURITY_ATTRIBUTES lpsa);
63- ~D3D10GrabberWorker ();
64- private:
65- HANDLE m_frameGrabbedEvent;
66- signals:
67- void frameGrabbed ();
68- public slots:
69- void runLoop ();
86+ bool D3D10GrabberWorker::init () {
87+ if (NULL == (m_frameGrabbedEvent = CreateEventW (m_lpsa, false , false , HOOKSGRABBER_FRAMEGRABBED_EVENT_NAME))) {
88+ qCritical () << Q_FUNC_INFO << " unable to create frameGrabbedEvent" ;
89+ return false ;
90+ }
7091
71- public:
72- bool stop = false ;
73- };
92+ return true ;
93+ }
94+
95+ D3D10GrabberWorker::~D3D10GrabberWorker () {
96+ if (m_frameGrabbedEvent)
97+ CloseHandle (m_frameGrabbedEvent);
98+ }
7499
75- const unsigned kBytesPerPixel = 4 ;
100+ void D3D10GrabberWorker::runLoop () {
101+ while (!stop) {
102+ if (WAIT_OBJECT_0 == WaitForSingleObject (m_frameGrabbedEvent, 50 )) {
103+ emit frameGrabbed ();
104+ if (!ResetEvent (m_frameGrabbedEvent)) {
105+ qCritical () << Q_FUNC_INFO << " couldn't reset frameGrabbedEvent" ;
106+ }
107+ }
108+ }
109+ }
110+ } // namespace
76111
77- D3D10GrabberWorker::D3D10GrabberWorker (QObject *parent, LPSECURITY_ATTRIBUTES lpsa) : QObject(parent) {
78- if (NULL == (m_frameGrabbedEvent = CreateEventW (lpsa, false , false , HOOKSGRABBER_FRAMEGRABBED_EVENT_NAME))) {
79- qCritical () << Q_FUNC_INFO << " unable to create frameGrabbedEvent" ;
112+ namespace {
113+ class D3D10GrabberInjector : public QObject {
114+ Q_OBJECT
115+
116+ public:
117+ D3D10GrabberInjector (QObject *parent, bool injectD3D9);
118+ bool init ();
119+ ~D3D10GrabberInjector ();
120+ public slots:
121+ void infectCleanDxProcesses ();
122+ public:
123+ void sanitizeProcesses ();
124+ private:
125+ QList<DWORD> m_lastSeenDxProcesses;
126+ ILibraryInjector * m_libraryInjector;
127+ WCHAR m_hooksLibPath[300 ];
128+ WCHAR m_unhookLibPath[300 ];
129+ WCHAR m_systemrootPath[300 ];
130+ bool m_injectD3D9;
131+ };
132+
133+ D3D10GrabberInjector::D3D10GrabberInjector (QObject *parent, bool injectD3D9) : QObject(parent),
134+ m_libraryInjector (NULL ),
135+ m_injectD3D9(injectD3D9)
136+ {
80137 }
81- }
82138
83- D3D10GrabberWorker::~D3D10GrabberWorker () {
84- if (m_frameGrabbedEvent)
85- CloseHandle (m_frameGrabbedEvent);
86- }
139+ bool D3D10GrabberInjector::init () {
140+ AcquirePrivileges ();
141+
142+ GetModuleFileName (NULL , m_hooksLibPath, SIZEOF_ARRAY (m_hooksLibPath));
143+ PathRemoveFileSpec (m_hooksLibPath);
144+ wcscat (m_hooksLibPath, L" \\ " );
145+ wcscat (m_hooksLibPath, lightpackHooksDllName);
87146
88- void D3D10GrabberWorker::runLoop () {
89- while (!stop) {
90- if (WAIT_OBJECT_0 == WaitForSingleObject (m_frameGrabbedEvent, 50 )) {
91- emit frameGrabbed ();
92- if (!ResetEvent (m_frameGrabbedEvent)) {
93- qCritical () << Q_FUNC_INFO << " couldn't reset frameGrabbedEvent" ;
147+ GetModuleFileName (NULL , m_unhookLibPath, SIZEOF_ARRAY (m_hooksLibPath));
148+ PathRemoveFileSpec (m_unhookLibPath);
149+ wcscat (m_unhookLibPath, L" \\ " );
150+ wcscat (m_unhookLibPath, lightpackUnhookDllName);
151+
152+ GetWindowsDirectoryW (m_systemrootPath, SIZEOF_ARRAY (m_systemrootPath));
153+
154+ HRESULT hr = CoInitialize (0 );
155+ // hr = InitComSecurity();
156+ // hr = CoCreateInstanceAsAdmin(NULL, CLSID_ILibraryInjector, IID_ILibraryInjector, reinterpret_cast<void **>(&m_libraryInjector));
157+ hr = CoCreateInstance (CLSID_ILibraryInjector, NULL , CLSCTX_INPROC_SERVER, IID_ILibraryInjector, reinterpret_cast <void **>(&m_libraryInjector));
158+ if (FAILED (hr)) {
159+ qCritical () << Q_FUNC_INFO << " Can't create libraryinjector. D3D10Grabber wasn't initialised. Please try to register server: regsvr32 libraryinjector.dll" ;
160+ CoUninitialize ();
161+ return false ;
162+ }
163+
164+ // Remove any injections from previous runs
165+ sanitizeProcesses ();
166+
167+ return true ;
168+ }
169+
170+ D3D10GrabberInjector::~D3D10GrabberInjector () {
171+ if (m_libraryInjector) {
172+ m_libraryInjector->Release ();
173+ CoUninitialize ();
174+ }
175+ }
176+
177+ void D3D10GrabberInjector::infectCleanDxProcesses () {
178+ QList<DWORD> processes = QList<DWORD>();
179+ if (m_injectD3D9)
180+ getDxProcessesIDs (&processes, m_systemrootPath);
181+ else
182+ getDxgiProcessesIDs (&processes, m_systemrootPath);
183+ foreach (DWORD procId, processes) {
184+ // Require the process to have run for at least one full timer tick,
185+ // hoping when injection happens their swapchain is already setup
186+ if (m_lastSeenDxProcesses.contains (procId)) {
187+ DEBUG_LOW_LEVEL << Q_FUNC_INFO << " Infecting DX process " << procId;
188+ m_libraryInjector->Inject (procId, m_hooksLibPath);
94189 }
95190 }
191+ m_lastSeenDxProcesses.clear ();
192+ m_lastSeenDxProcesses.append (processes);
96193 }
97- }
194+
195+ void D3D10GrabberInjector::sanitizeProcesses () {
196+ QList<DWORD> processes = QList<DWORD>();
197+ getHookedProcessesIDs (&processes, m_systemrootPath);
198+ foreach (DWORD procId, processes) {
199+ DEBUG_LOW_LEVEL << Q_FUNC_INFO << " Sanitizing process " << procId;
200+ m_libraryInjector->Inject (procId, m_unhookLibPath);
201+ }
202+ }
203+
98204} // namespace
99205
100206class D3D10GrabberImpl : public QObject
@@ -109,7 +215,6 @@ class D3D10GrabberImpl: public QObject
109215 m_memMap(NULL ),
110216 m_lastFrameId(0 ),
111217 m_isInited(false ),
112- m_libraryInjector(NULL ),
113218 m_isFrameGrabbedDuringLastSecond(false ),
114219 m_context(context),
115220 m_getHwndCb(getHwndCb),
@@ -164,32 +269,6 @@ class D3D10GrabberImpl: public QObject
164269 if (m_isInited)
165270 return true ;
166271
167- AcquirePrivileges ();
168-
169- GetModuleFileName (NULL , m_hooksLibPath, SIZEOF_ARRAY (m_hooksLibPath));
170- PathRemoveFileSpec (m_hooksLibPath);
171- wcscat (m_hooksLibPath, L" \\ " );
172- wcscat (m_hooksLibPath, lightpackHooksDllName);
173-
174- GetModuleFileName (NULL , m_unhookLibPath, SIZEOF_ARRAY (m_hooksLibPath));
175- PathRemoveFileSpec (m_unhookLibPath);
176- wcscat (m_unhookLibPath, L" \\ " );
177- wcscat (m_unhookLibPath, lightpackUnhookDllName);
178-
179- GetWindowsDirectoryW (m_systemrootPath, SIZEOF_ARRAY (m_systemrootPath));
180-
181- HRESULT hr = CoInitialize (0 );
182- // hr = InitComSecurity();
183- // hr = CoCreateInstanceAsAdmin(NULL, CLSID_ILibraryInjector, IID_ILibraryInjector, reinterpret_cast<void **>(&m_libraryInjector));
184- hr = CoCreateInstance (CLSID_ILibraryInjector, NULL , CLSCTX_INPROC_SERVER, IID_ILibraryInjector, reinterpret_cast <void **>(&m_libraryInjector));
185- if (FAILED (hr)) {
186- qCritical () << Q_FUNC_INFO << " Can't create libraryinjector. D3D10Grabber wasn't initialised. Please try to register server: regsvr32 libraryinjector.dll" ;
187- return false ;
188- }
189-
190- // Remove any injections from previous runs
191- sanitizeProcesses ();
192-
193272#if 0
194273 // TODO: Remove this code or use |sa| in initIPC()
195274 SECURITY_ATTRIBUTES sa;
@@ -262,23 +341,40 @@ class D3D10GrabberImpl: public QObject
262341
263342#endif
264343
265- m_thread.reset (new QThread ());
266- m_thread->start ();
267- this ->moveToThread (m_thread.data ());
268-
269- m_processesScanAndInfectTimer.reset (new QTimer (this ));
270- m_processesScanAndInfectTimer->setInterval (5000 );
271- m_processesScanAndInfectTimer->setSingleShot (false );
272- connect (m_processesScanAndInfectTimer.data (), SIGNAL (timeout ()), this , SLOT (infectCleanDxProcesses ()) );
273- m_processesScanAndInfectTimer->start ();
344+ m_injectorThread.reset (new QThread ());
345+ m_injector.reset (new D3D10GrabberInjector (NULL , m_injectD3D9));
346+ if (!m_injector->init ()) {
347+ qCritical (Q_FUNC_INFO " Init D3D10GrabberInjector failed. D3D10Grabber wasn't initialised." );
348+ m_injector.reset ();
349+ return false ;
350+ }
351+ m_injector->moveToThread (m_injectorThread.data ());
352+ m_injectorThread->start ();
353+ // TODO:
354+ // connect(m_worker.data(), SIGNAL(frameGrabbed()), this, SIGNAL(frameGrabbed()), Qt::QueuedConnection);
274355
275356 m_workerThread.reset (new QThread ());
276357 m_worker.reset (new D3D10GrabberWorker (NULL , NULL ));
358+ if (!m_worker->init ()) {
359+ qCritical (Q_FUNC_INFO " Init D3D10GrabberWorker failed. D3D10Grabber wasn't initialised." );
360+ m_worker.reset ();
361+ m_injector.reset ();
362+ m_injectorThread->quit ();
363+ m_injectorThread->wait ();
364+ m_injectorThread.reset ();
365+ return false ;
366+ }
277367 m_worker->moveToThread (m_workerThread.data ());
278368 m_workerThread->start ();
279369 connect (m_worker.data (), SIGNAL (frameGrabbed ()), this , SIGNAL (frameGrabbed ()), Qt::QueuedConnection);
280370 QMetaObject::invokeMethod (m_worker.data (), " runLoop" , Qt::QueuedConnection);
281371
372+ m_processesScanAndInfectTimer.reset (new QTimer (this ));
373+ m_processesScanAndInfectTimer->setInterval (5000 );
374+ m_processesScanAndInfectTimer->setSingleShot (false );
375+ connect (m_processesScanAndInfectTimer.data (), SIGNAL (timeout ()), m_injector.data (), SLOT (infectCleanDxProcesses ()));
376+ m_processesScanAndInfectTimer->start ();
377+
282378 m_checkIfFrameGrabbedTimer.reset (new QTimer ());
283379 m_checkIfFrameGrabbedTimer->setSingleShot (false );
284380 m_checkIfFrameGrabbedTimer->setInterval (1000 );
@@ -391,26 +487,6 @@ class D3D10GrabberImpl: public QObject
391487 void frameGrabbed ();
392488
393489private slots:
394- void infectCleanDxProcesses (void ) {
395- if (m_isInited && m_libraryInjector) {
396- QList<DWORD> processes = QList<DWORD>();
397- if (m_injectD3D9)
398- getDxProcessesIDs (&processes, m_systemrootPath);
399- else
400- getDxgiProcessesIDs (&processes, m_systemrootPath);
401- foreach (DWORD procId, processes) {
402- // Require the process to have run for at least one full timer tick,
403- // hoping when injection happens their swapchain is already setup
404- if (m_lastSeenDxProcesses.contains (procId)) {
405- qDebug () << Q_FUNC_INFO << " Infecting DX process " << procId;
406- m_libraryInjector->Inject (procId, m_hooksLibPath);
407- }
408- }
409- m_lastSeenDxProcesses.clear ();
410- m_lastSeenDxProcesses.append (processes);
411- }
412- }
413-
414490 void handleIfFrameGrabbed () {
415491 if (!m_isFrameGrabbedDuringLastSecond) {
416492 if (m_isStarted) {
@@ -422,14 +498,6 @@ private slots:
422498 }
423499
424500private:
425- void sanitizeProcesses () {
426- QList<DWORD> processes = QList<DWORD>();
427- getHookedProcessesIDs (&processes, m_systemrootPath);
428- foreach (DWORD procId, processes) {
429- qDebug () << Q_FUNC_INFO << " Sanitizing process " << procId;
430- m_libraryInjector->Inject (procId, m_unhookLibPath);
431- }
432- }
433501
434502 QRgb getColor (const QRect &widgetRect)
435503 {
@@ -597,16 +665,15 @@ private slots:
597665 disconnect (m_worker.data ());
598666 m_worker->stop = true ;
599667
600- m_thread->quit ();
668+ m_injector->sanitizeProcesses ();
669+
601670 m_workerThread->quit ();
602- m_thread-> wait ();
671+ m_injectorThread-> quit ();
603672 m_workerThread->wait ();
673+ m_injectorThread->wait ();
604674
605- sanitizeProcesses ();
606675
607676 disconnect (this , SLOT (handleIfFrameGrabbed ()));
608- if (m_libraryInjector)
609- m_libraryInjector->Release ();
610677 freeIPC ();
611678 CoUninitialize ();
612679 m_isInited = false ;
@@ -619,20 +686,16 @@ private slots:
619686 UINT m_lastFrameId;
620687 MONITORINFO m_monitorInfo;
621688 QScopedPointer<QTimer> m_processesScanAndInfectTimer;
622- QList<DWORD> m_lastSeenDxProcesses;
623689 bool m_isInited;
624- ILibraryInjector * m_libraryInjector;
625- WCHAR m_hooksLibPath[300 ];
626- WCHAR m_unhookLibPath[300 ];
627- WCHAR m_systemrootPath[300 ];
628690 bool m_isFrameGrabbedDuringLastSecond;
629691 GrabberContext *m_context;
630692 GetHwndCallback_t m_getHwndCb;
631693
632694 QScopedPointer<QTimer> m_checkIfFrameGrabbedTimer;
633695 QScopedPointer<D3D10GrabberWorker> m_worker;
634696 QScopedPointer<QThread> m_workerThread;
635- QScopedPointer<QThread> m_thread;
697+ QScopedPointer<D3D10GrabberInjector> m_injector;
698+ QScopedPointer<QThread> m_injectorThread;
636699 HOOKSGRABBER_SHARED_MEM_DESC m_memDesc;
637700 D3D10Grabber &m_owner;
638701 bool m_injectD3D9;
0 commit comments