Skip to content

Commit 809056e

Browse files
Bailey Brownbailey27
authored andcommitted
re-create system tray icon if explorer restarts
1 parent 0746e86 commit 809056e

File tree

11 files changed

+178
-21
lines changed

11 files changed

+178
-21
lines changed

INSTALL.md

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -102,9 +102,7 @@ set PATH=%LOCALAPPDATA%\bin\NASM;%PATH%
102102
Then run the batch file that comes with Visual Studio that sets up the environment variables for compiling from the command line.
103103

104104
```
105-
106105
"C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Auxiliary\Build\vcvarsall.bat" amd64
107-
108106
```
109107

110108
Use "x86" in place of "amd64" if you are doing a 32-bit build.

changelog.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,9 @@
22

33
Changelog
44
------------
5+
v1.4.4.5 11 Nov 2024
6+
* Re-create system tray icon if explorer is restarted.
7+
58
v1.4.4.4 31 Aug 2024
69
* Use Dokany 2.2 (2.2.0.1000)
710

cppcryptfs/cppcryptfs.cpp

Lines changed: 17 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@ THE SOFTWARE.
4747
#include "dokan/cryptdokan.h"
4848
#include "util/getopt.h"
4949
#include "util/LockZeroBuffer.h"
50+
#include "../libcommonutil/commonutil.h"
5051
#include "util/util.h"
5152
#include "crypt/crypt.h"
5253
#include "ui/uiutil.h"
@@ -70,14 +71,14 @@ END_MESSAGE_MAP()
7071

7172
CcppcryptfsApp::CcppcryptfsApp()
7273
{
74+
m_bIsRunningAsAdministrator = ::IsRunningAsAdministrator(&m_bIsReallyAdministrator);
75+
7376
// support Restart Manager
7477
m_dwRestartManagerSupportFlags = AFX_RESTART_MANAGER_SUPPORT_RESTART;
7578

7679
// TODO: add construction code here,
7780
// Place all significant initialization in InitInstance
7881

79-
m_mountedLetters = 0;
80-
8182
// get a shared ptr to an OpenSSL EVP context to force detection of AES-NI instructions
8283
// so we can use AES-NI even if EVP is never used
8384

@@ -277,13 +278,16 @@ BOOL CcppcryptfsApp::InitInstance()
277278

278279
m_pMainWnd = &dlg;
279280

280-
HICON hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
281+
m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
281282

282-
CMenuTrayIcon TI(L"cppcryptfs", hIcon, IDR_PopUps, ID_IDR_SHOWCPPCRYPTFS);
283+
RecreateSystemTrayIcon();
283284

284285
crypt_at_start();
285286

286287
INT_PTR nResponse = dlg.DoModal();
288+
289+
m_system_tray_icon = nullptr;
290+
287291
if (nResponse == IDOK)
288292
{
289293
// TODO: Place code here to handle when the dialog is
@@ -321,6 +325,15 @@ BOOL CcppcryptfsApp::InitInstance()
321325
return FALSE;
322326
}
323327

328+
void CcppcryptfsApp::RecreateSystemTrayIcon()
329+
{
330+
// Destroy it first in case there's any singleton behavior with the CMenuTrayIcon class or anything that
331+
// replaces it in the future.
332+
m_system_tray_icon.reset();
333+
334+
m_system_tray_icon = make_shared<CMenuTrayIcon>(L"cppcryptfs", m_hIcon, IDR_PopUps, ID_IDR_SHOWCPPCRYPTFS);
335+
}
336+
324337
BOOL CcppcryptfsApp::WriteProfileInt(LPCWSTR section, LPCWSTR entry, INT val)
325338
{
326339
if (lstrcmpi(section, CryptSettingsRegValName) && NeverSaveHistory()) {

cppcryptfs/cppcryptfs.h

Lines changed: 16 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,8 @@ THE SOFTWARE.
3131

3232
#pragma once
3333

34+
#include "stdafx.h"
35+
3436
#ifndef __AFXWIN_H__
3537
#error "include 'stdafx.h' before including this file for PCH"
3638
#endif
@@ -39,6 +41,7 @@ THE SOFTWARE.
3941

4042
#include <unordered_map>
4143
#include <string>
44+
#include <memory>
4245
#include "crypt/cryptdefs.h"
4346

4447
using namespace std;
@@ -63,25 +66,32 @@ typedef struct struct_CopyDataCmdLine {
6366
// See cppcryptfs.cpp for the implementation of this class
6467
//
6568

69+
class CMenuTrayIcon;
70+
6671
class CcppcryptfsApp : public CWinApp
6772
{
73+
private:
74+
bool m_bIsRunningAsAdministrator = false;
75+
bool m_bIsReallyAdministrator = false;
6876
public:
6977
void SendCmdArgsToSelf(HANDLE hPipe);
7078
public:
7179
CcppcryptfsApp();
72-
#if 0
73-
unordered_map<wstring, wstring> m_mountedMountPoints; // used for tracking all mounted mountpoints (dirs and drive letters)
74-
// drive letters are stored with colon e.g drive M as L"M:"
75-
#endif
76-
DWORD m_mountedLetters; // used for tracking mounted (by cpppcryptfs) drive letters
77-
// Overrides
80+
HICON m_hIcon = NULL;
81+
DWORD m_mountedLetters = 0; // used for tracking mounted (by cpppcryptfs) drive letters
82+
std::shared_ptr<CMenuTrayIcon> m_system_tray_icon;
83+
// Overrides
7884
public:
7985
virtual BOOL InitInstance() override;
8086

8187
virtual BOOL WriteProfileInt(LPCWSTR section, LPCWSTR entry, INT val) override;
8288
virtual BOOL WriteProfileString(LPCWSTR section, LPCWSTR entry, LPCWSTR val) override;
8389
virtual BOOL WriteProfileBinary(LPCWSTR section, LPCWSTR entry, LPBYTE pData, UINT nBytes) override;
8490

91+
void RecreateSystemTrayIcon();
92+
93+
bool IsRunningAsAdministrator() { return m_bIsRunningAsAdministrator; }
94+
bool IsReallyAdministrator() { return m_bIsReallyAdministrator; }
8595
// Implementation
8696

8797
DECLARE_MESSAGE_MAP()

cppcryptfs/cppcryptfs.rc

0 Bytes
Binary file not shown.

cppcryptfs/ui/CryptAboutPropertyPage.cpp

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -651,10 +651,13 @@ BOOL CCryptAboutPropertyPage::OnInitDialog()
651651

652652
SetDlgItemText(IDC_LINKAGES, L"linked with " + openssl_ver + dokany_version);
653653

654+
bool is_admin = theApp.IsRunningAsAdministrator();
655+
654656
CString prod_ver = prod.c_str();
655-
prod_ver += L", Version ";
656-
prod_ver += &ver[0];
657+
prod_ver += L" ";
658+
prod_ver += ver.c_str();
657659
prod_ver += sizeof(void*) == 8 ? L" 64-bit" : L" 32-bit";
660+
prod_ver += (is_admin ? L" (admin)" : L"");
658661

659662
SetDlgItemText(IDC_PROD_VERSION, prod_ver + CString(aes_ni.c_str()));
660663
SetDlgItemText(IDC_COPYRIGHT, copyright.c_str());

cppcryptfs/ui/CryptPropertySheet.cpp

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ THE SOFTWARE.
3939
#include "dokan/cryptdokan.h"
4040
#include "util/LockZeroBuffer.h"
4141
#include "util/util.h"
42+
#include "../libcommonutil/commonutil.h"
4243
#include "dokan/MountPointManager.h"
4344
#include "ui/uiutil.h"
4445
#include "ui/CryptSettings.h"
@@ -48,6 +49,9 @@ THE SOFTWARE.
4849

4950
// CryptPropertySheet
5051

52+
static const int kSysTrayiTimerId = 1;
53+
static const int kSysTrayTimerInterval = 2000; // milliseconds
54+
5155
IMPLEMENT_DYNAMIC(CCryptPropertySheet, CPropertySheet)
5256

5357
CCryptPropertySheet::CCryptPropertySheet(UINT nIDCaption, CWnd* pParentWnd, UINT iSelectPage)
@@ -106,6 +110,7 @@ BOOL CCryptPropertySheet::CanClose()
106110
}
107111
}
108112

113+
UINT CCryptPropertySheet::WM_TASKBARCREATED = ::RegisterWindowMessage(_T("TaskbarCreated"));
109114

110115
BEGIN_MESSAGE_MAP(CCryptPropertySheet, CPropertySheet)
111116
ON_WM_NCCREATE()
@@ -119,12 +124,22 @@ BEGIN_MESSAGE_MAP(CCryptPropertySheet, CPropertySheet)
119124
// ON_WM_QUERYENDSESSION()
120125
ON_WM_ENDSESSION()
121126
ON_WM_POWERBROADCAST()
127+
// custom messages
128+
ON_REGISTERED_MESSAGE(WM_TASKBARCREATED, OnTaskbarCreated)
129+
ON_WM_TIMER()
130+
ON_WM_DESTROY()
122131
END_MESSAGE_MAP()
123132

124133

125134
// CryptPropertySheet message handlers
126135

127136

137+
LRESULT CCryptPropertySheet::OnTaskbarCreated(WPARAM wParam, LPARAM lParam)
138+
{
139+
theApp.RecreateSystemTrayIcon();
140+
return 0;
141+
}
142+
128143
BOOL CCryptPropertySheet::OnInitDialog()
129144
{
130145

@@ -144,6 +159,14 @@ BOOL CCryptPropertySheet::OnInitDialog()
144159
if (pWnd)
145160
pWnd->ShowWindow(SW_HIDE);
146161

162+
if (theApp.IsRunningAsAdministrator()) {
163+
164+
// We want to know if explorer gets restarted so we can re-create our system tray icon.
165+
// However, if we're running as administrator, we never get any TaskbarCreated messages,
166+
// so we need to poll using a timer.
167+
168+
SetTimer(kSysTrayiTimerId, kSysTrayTimerInterval, nullptr);
169+
}
147170

148171
return bResult;
149172
}
@@ -401,3 +424,43 @@ BOOL CCryptPropertySheet::PreTranslateMessage(MSG* pMsg)
401424

402425
return CPropertySheet::PreTranslateMessage(pMsg);
403426
}
427+
428+
429+
void CCryptPropertySheet::OnTimer(UINT_PTR nIDEvent)
430+
{
431+
// TODO: Add your message handler code here and/or call default
432+
433+
if (nIDEvent == kSysTrayiTimerId) {
434+
const HWND hWnd = ::FindWindow(L"Shell_TrayWnd", NULL);
435+
436+
if (hWnd)
437+
{
438+
if (m_bDoRecreateSysTrayIcon)
439+
{
440+
m_bDoRecreateSysTrayIcon = false;
441+
theApp.RecreateSystemTrayIcon();
442+
}
443+
else if (hWnd != m_hSysTrayWnd)
444+
{
445+
m_hSysTrayWnd = hWnd;
446+
// We seem to need some sort of delay before recreating it.
447+
m_bDoRecreateSysTrayIcon = true;
448+
}
449+
}
450+
}
451+
452+
CPropertySheet::OnTimer(nIDEvent);
453+
}
454+
455+
456+
void CCryptPropertySheet::OnDestroy()
457+
{
458+
CPropertySheet::OnDestroy();
459+
460+
// TODO: Add your message handler code here
461+
462+
if (theApp.IsRunningAsAdministrator())
463+
{
464+
KillTimer(kSysTrayiTimerId);
465+
}
466+
}

cppcryptfs/ui/CryptPropertySheet.h

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,8 +36,7 @@ class CCryptPropertySheet : public CPropertySheet
3636
{
3737
DECLARE_DYNAMIC(CCryptPropertySheet)
3838

39-
public:
40-
39+
public:
4140
// disallow copying
4241
CCryptPropertySheet(CCryptPropertySheet const&) = delete;
4342
void operator=(CCryptPropertySheet const&) = delete;
@@ -52,8 +51,15 @@ class CCryptPropertySheet : public CPropertySheet
5251

5352
int m_nMountPageIndex;
5453

54+
HWND m_hSysTrayWnd = NULL;
55+
56+
bool m_bDoRecreateSysTrayIcon = false;
57+
5558
protected:
5659
DECLARE_MESSAGE_MAP()
60+
61+
static UINT WM_TASKBARCREATED;
62+
afx_msg LRESULT OnTaskbarCreated(WPARAM wParam, LPARAM lParam);
5763
public:
5864
virtual BOOL OnInitDialog();
5965
virtual BOOL OnCommand(WPARAM wParam, LPARAM lParam);
@@ -68,6 +74,8 @@ class CCryptPropertySheet : public CPropertySheet
6874
afx_msg void OnEndSession(BOOL bEnding);
6975
afx_msg UINT OnPowerBroadcast(UINT nPowerEvent, LPARAM nEventData);
7076
virtual BOOL PreTranslateMessage(MSG* pMsg);
77+
afx_msg void OnTimer(UINT_PTR nIDEvent);
78+
afx_msg void OnDestroy();
7179
};
7280

7381

cppcryptfsctl/cppcryptfsctl.rc

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -51,8 +51,8 @@ END
5151
//
5252

5353
VS_VERSION_INFO VERSIONINFO
54-
FILEVERSION 1,4,4,4
55-
PRODUCTVERSION 1,4,4,4
54+
FILEVERSION 1,4,4,5
55+
PRODUCTVERSION 1,4,4,5
5656
FILEFLAGSMASK 0x3fL
5757
#ifdef _DEBUG
5858
FILEFLAGS 0x1L
@@ -69,12 +69,12 @@ BEGIN
6969
BEGIN
7070
VALUE "CompanyName", "Bailey Brown"
7171
VALUE "FileDescription", "cppcryptfsctl"
72-
VALUE "FileVersion", "1.4.4.4"
72+
VALUE "FileVersion", "1.4.4.5"
7373
VALUE "InternalName", "cppcryptfsctl.exe"
7474
VALUE "LegalCopyright", "Copyright (C) 2020-2024 Bailey Brown. All rights reserved."
7575
VALUE "OriginalFilename", "cppcryptfsctl.exe"
7676
VALUE "ProductName", "cppcryptfsctl"
77-
VALUE "ProductVersion", "1.4.4.4"
77+
VALUE "ProductVersion", "1.4.4.5"
7878
END
7979
END
8080
BLOCK "VarFileInfo"

libcommonutil/commonutil.cpp

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -168,3 +168,60 @@ wstring GetWindowsErrorString(DWORD dwLastErr)
168168
return mes;
169169
}
170170

171+
static bool IsProcessElevated()
172+
{
173+
HANDLE hToken = NULL;
174+
TOKEN_ELEVATION elevation;
175+
DWORD size;
176+
177+
if (OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &hToken))
178+
{
179+
if (GetTokenInformation(hToken, TokenElevation, &elevation, sizeof(elevation), &size))
180+
{
181+
CloseHandle(hToken);
182+
return elevation.TokenIsElevated != 0;
183+
}
184+
CloseHandle(hToken);
185+
}
186+
return false;
187+
}
188+
189+
bool IsRunningAsAdministrator(bool *pIsReallyAdmin)
190+
{
191+
BOOL isAdmin = FALSE;
192+
HANDLE hToken = NULL;
193+
194+
if (pIsReallyAdmin)
195+
*pIsReallyAdmin = false;
196+
197+
// Open the process token
198+
if (OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &hToken))
199+
{
200+
// Create a SID for the Administrators group
201+
PSID administratorsGroup = NULL;
202+
SID_IDENTIFIER_AUTHORITY ntAuthority = SECURITY_NT_AUTHORITY;
203+
if (AllocateAndInitializeSid(&ntAuthority, 2,
204+
SECURITY_BUILTIN_DOMAIN_RID,
205+
DOMAIN_ALIAS_RID_ADMINS,
206+
0, 0, 0, 0, 0, 0,
207+
&administratorsGroup))
208+
{
209+
// Check if the token has the Administrators group SID
210+
CheckTokenMembership(hToken, administratorsGroup, &isAdmin);
211+
FreeSid(administratorsGroup);
212+
}
213+
CloseHandle(hToken);
214+
}
215+
216+
if (isAdmin)
217+
{
218+
if (pIsReallyAdmin)
219+
*pIsReallyAdmin = true;
220+
221+
return true;
222+
}
223+
else
224+
{
225+
return IsProcessElevated();
226+
}
227+
}

libcommonutil/commonutil.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,8 @@ bool GetProductVersionInfo(wstring& strProductName, wstring& strProductVersion,
4141

4242
wstring GetWindowsErrorString(DWORD dwLastErr);
4343

44+
bool IsRunningAsAdministrator(bool *pIsReallyAdmin = nullptr);
45+
4446
namespace cppcryptfs
4547
{
4648
/*
@@ -137,5 +139,5 @@ namespace cppcryptfs
137139
std::forward<Deleter>(deleter),
138140
std::forward<Function>(function),
139141
std::forward<Arguments>(args)...);
140-
}
142+
}
141143
}

0 commit comments

Comments
 (0)