2
2
* Process Hacker Network Tools -
3
3
* GeoIP database updater
4
4
*
5
- * Copyright (C) 2016 dmex
5
+ * Copyright (C) 2016-2019 dmex
6
6
*
7
7
* This file is part of Process Hacker.
8
8
*
29
29
HWND UpdateDialogHandle = NULL ;
30
30
HANDLE UpdateDialogThreadHandle = NULL ;
31
31
PH_EVENT InitializedEvent = PH_EVENT_INIT ;
32
+ PPH_OBJECT_TYPE UpdateContextType = NULL ;
33
+ PH_INITONCE UpdateContextTypeInitOnce = PH_INITONCE_INIT ;
32
34
33
- VOID FreeUpdateContext (
34
- _In_ _Post_invalid_ PPH_UPDATER_CONTEXT Context
35
+ VOID UpdateContextDeleteProcedure (
36
+ _In_ PVOID Object ,
37
+ _In_ ULONG Flags
35
38
)
36
39
{
37
- if (Context -> FileDownloadUrl )
38
- PhDereferenceObject (Context -> FileDownloadUrl );
40
+ PPH_UPDATER_CONTEXT context = Object ;
39
41
40
- if (Context -> RevVersion )
41
- PhDereferenceObject (Context -> RevVersion );
42
+ if (context -> FileDownloadUrl )
43
+ PhDereferenceObject (context -> FileDownloadUrl );
44
+ }
45
+
46
+ PPH_UPDATER_CONTEXT CreateUpdateContext (
47
+ VOID
48
+ )
49
+ {
50
+ PPH_UPDATER_CONTEXT context ;
51
+
52
+ if (PhBeginInitOnce (& UpdateContextTypeInitOnce ))
53
+ {
54
+ UpdateContextType = PhCreateObjectType (L"GeoIpContextObjectType" , 0 , UpdateContextDeleteProcedure );
55
+ PhEndInitOnce (& UpdateContextTypeInitOnce );
56
+ }
42
57
43
- if ( Context -> Size )
44
- PhDereferenceObject ( Context -> Size );
58
+ context = PhCreateObject ( sizeof ( PH_UPDATER_CONTEXT ), UpdateContextType );
59
+ memset ( context , 0 , sizeof ( PH_UPDATER_CONTEXT ) );
45
60
46
- PhDereferenceObject ( Context ) ;
61
+ return context ;
47
62
}
48
63
49
64
VOID TaskDialogCreateIcons (
@@ -484,18 +499,68 @@ NTSTATUS GeoIPUpdateThread(
484
499
{
485
500
if (success )
486
501
{
487
- ShowDbInstallRestartDialog (context );
502
+ PostMessage (context -> DialogHandle , PH_SHOWINSTALL , 0 , 0 );
488
503
}
489
504
else
490
505
{
491
- ShowDbUpdateFailedDialog (context );
506
+ PostMessage (context -> DialogHandle , PH_SHOWERROR , 0 , 0 );
492
507
}
493
508
}
494
509
495
510
PhDereferenceObject (context );
496
511
return STATUS_SUCCESS ;
497
512
}
498
513
514
+ LRESULT CALLBACK TaskDialogSubclassProc (
515
+ _In_ HWND hwndDlg ,
516
+ _In_ UINT uMsg ,
517
+ _In_ WPARAM wParam ,
518
+ _In_ LPARAM lParam
519
+ )
520
+ {
521
+ PPH_UPDATER_CONTEXT context ;
522
+ WNDPROC oldWndProc ;
523
+
524
+ if (!(context = PhGetWindowContext (hwndDlg , UCHAR_MAX )))
525
+ return 0 ;
526
+
527
+ oldWndProc = context -> DefaultWindowProc ;
528
+
529
+ switch (uMsg )
530
+ {
531
+ case WM_DESTROY :
532
+ {
533
+ SetWindowLongPtr (hwndDlg , GWLP_WNDPROC , (LONG_PTR )oldWndProc );
534
+ PhRemoveWindowContext (hwndDlg , UCHAR_MAX );
535
+
536
+ PhUnregisterWindowCallback (hwndDlg );
537
+ }
538
+ break ;
539
+ case PH_SHOWDIALOG :
540
+ {
541
+ if (IsMinimized (hwndDlg ))
542
+ ShowWindow (hwndDlg , SW_RESTORE );
543
+ else
544
+ ShowWindow (hwndDlg , SW_SHOW );
545
+
546
+ SetForegroundWindow (hwndDlg );
547
+ }
548
+ break ;
549
+ case PH_SHOWINSTALL :
550
+ {
551
+ ShowDbInstallRestartDialog (context );
552
+ }
553
+ break ;
554
+ case PH_SHOWERROR :
555
+ {
556
+ ShowDbUpdateFailedDialog (context );
557
+ }
558
+ break ;
559
+ }
560
+
561
+ return CallWindowProc (oldWndProc , hwndDlg , uMsg , wParam , lParam );
562
+ }
563
+
499
564
HRESULT CALLBACK TaskDialogBootstrapCallback (
500
565
_In_ HWND hwndDlg ,
501
566
_In_ UINT uMsg ,
@@ -518,6 +583,13 @@ HRESULT CALLBACK TaskDialogBootstrapCallback(
518
583
// Create the Taskdialog icons
519
584
TaskDialogCreateIcons (context );
520
585
586
+ PhRegisterWindowCallback (hwndDlg , PH_PLUGIN_WINDOW_EVENT_TYPE_TOPMOST , NULL );
587
+
588
+ // Subclass the Taskdialog.
589
+ context -> DefaultWindowProc = (WNDPROC )GetWindowLongPtr (hwndDlg , GWLP_WNDPROC );
590
+ PhSetWindowContext (hwndDlg , UCHAR_MAX , context );
591
+ SetWindowLongPtr (hwndDlg , GWLP_WNDPROC , (LONG_PTR )TaskDialogSubclassProc );
592
+
521
593
ShowDbCheckForUpdatesDialog (context );
522
594
}
523
595
break ;
@@ -532,23 +604,21 @@ NTSTATUS GeoIPUpdateDialogThread(
532
604
{
533
605
PH_AUTO_POOL autoPool ;
534
606
PPH_UPDATER_CONTEXT context ;
535
- INT result = 0 ;
536
607
TASKDIALOGCONFIG config = { sizeof (TASKDIALOGCONFIG ) };
537
608
538
609
PhInitializeAutoPool (& autoPool );
539
610
540
- context = (PPH_UPDATER_CONTEXT )PhCreateAlloc (sizeof (PH_UPDATER_CONTEXT ));
541
- memset (context , 0 , sizeof (PH_UPDATER_CONTEXT ));
611
+ context = CreateUpdateContext ();
542
612
543
613
config .dwFlags = TDF_ALLOW_DIALOG_CANCELLATION | TDF_CAN_BE_MINIMIZED ;
544
614
config .pszContent = L"Initializing..." ;
545
615
config .lpCallbackData = (LONG_PTR )context ;
546
616
config .pfCallback = TaskDialogBootstrapCallback ;
547
617
config .hwndParent = Parameter ;
548
618
549
- TaskDialogIndirect (& config , & result , NULL , NULL );
619
+ TaskDialogIndirect (& config , NULL , NULL , NULL );
550
620
551
- FreeUpdateContext (context );
621
+ PhDereferenceObject (context );
552
622
PhDeleteAutoPool (& autoPool );
553
623
554
624
return STATUS_SUCCESS ;
@@ -601,5 +671,16 @@ VOID ShowGeoIPUpdateDialog(
601
671
_In_opt_ HWND Parent
602
672
)
603
673
{
604
- PhCreateThread2 (GeoIPUpdateDialogThread , Parent );
674
+ if (!UpdateDialogThreadHandle )
675
+ {
676
+ if (!(UpdateDialogThreadHandle = PhCreateThread (0 , GeoIPUpdateDialogThread , NULL )))
677
+ {
678
+ PhShowStatus (PhMainWndHandle , L"Unable to create the updater window." , 0 , GetLastError ());
679
+ return ;
680
+ }
681
+
682
+ PhWaitForEvent (& InitializedEvent , NULL );
683
+ }
684
+
685
+ PostMessage (UpdateDialogHandle , PH_SHOWDIALOG , 0 , 0 );
605
686
}
0 commit comments