Skip to content

Commit 04616ce

Browse files
committed
Fixes for shell extension
* Properly implemented cleanup routines when injected into applications other than Explorer * Never EVER forget to specify a ThreadingModel for a COM object in registry. That was the cause the DLL was making Microsoft Teams crash on startup * Do not free memory when the DLL is unloaded (DLL_PROCESS_DETACH) and lpvReserved is non-NULL. It means the DLL is unloaded as the process terminates, in which case all threads are dead, so it is not safe to call freeing routines - let the operating system reclaim the memory on process exit
1 parent e2af83e commit 04616ce

File tree

5 files changed

+293
-154
lines changed

5 files changed

+293
-154
lines changed

CHANGELOG.md

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

33
This document includes the same release notes as in the [Releases](https://github.com/valinet/ExplorerPatcher/releases) section on GitHub.
44

5+
## 22000.318.36
6+
7+
Tested on build 22000.318.
8+
9+
#### Fixes
10+
11+
* Lots of bug and issue fixes for shell extension failing to work under certain circumstances; fixed #259
12+
513
## 22000.318.35
614

715
Tested on build 22000.318.

ExplorerPatcher/ExplorerPatcher.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 22000,318,35,0
55-
PRODUCTVERSION 22000,318,35,0
54+
FILEVERSION 22000,318,36,0
55+
PRODUCTVERSION 22000,318,36,0
5656
FILEFLAGSMASK 0x3fL
5757
#ifdef _DEBUG
5858
FILEFLAGS 0x1L
@@ -69,12 +69,12 @@ BEGIN
6969
BEGIN
7070
VALUE "CompanyName", "VALINET Solutions SRL"
7171
VALUE "FileDescription", "ExplorerPatcher"
72-
VALUE "FileVersion", "22000.318.35.0"
72+
VALUE "FileVersion", "22000.318.36.0"
7373
VALUE "InternalName", "ExplorerPatcher.dll"
7474
VALUE "LegalCopyright", "Copyright (C) 2006-2021 VALINET Solutions SRL. All rights reserved."
7575
VALUE "OriginalFilename", "ExplorerPatcher.dll"
7676
VALUE "ProductName", "ExplorerPatcher"
77-
VALUE "ProductVersion", "22000.318.35.0"
77+
VALUE "ProductVersion", "22000.318.36.0"
7878
END
7979
END
8080
BLOCK "VarFileInfo"

ExplorerPatcher/SettingsMonitor.c

Lines changed: 91 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -3,83 +3,113 @@
33
DWORD WINAPI MonitorSettings(SettingsChangeParameters* params)
44
{
55
BOOL bShouldExit = FALSE;
6+
HANDLE* handles = NULL;
7+
printf("[SettingsMonitor] Started %p\n", params->settings[0].hEvent);
68

79
while (TRUE)
810
{
9-
HANDLE* handles = malloc(sizeof(HANDLE) * (params->size + 1));
10-
if (!handles)
11+
handles = calloc(sizeof(HANDLE), params->size);
12+
if (handles)
1113
{
12-
return 0;
13-
}
14-
for (unsigned int i = 0; i < params->size; ++i)
15-
{
16-
params->settings[i].hEvent = CreateEventW(NULL, FALSE, FALSE, NULL);
17-
if (!params->settings[i].hEvent)
18-
{
19-
return 0;
20-
}
21-
handles[i] = params->settings[i].hEvent;
22-
if (RegCreateKeyExW(
23-
params->settings[i].origin,
24-
params->settings[i].name,
25-
0,
26-
NULL,
27-
REG_OPTION_NON_VOLATILE,
28-
KEY_READ,
29-
NULL,
30-
&(params->settings[i].hKey),
31-
NULL
32-
) != ERROR_SUCCESS)
14+
for (unsigned int i = 0; i < params->size; ++i)
3315
{
34-
return 0;
16+
if (i == 0)
17+
{
18+
if (params->settings[i].hEvent)
19+
{
20+
handles[i] = params->settings[i].hEvent;
21+
continue;
22+
}
23+
else
24+
{
25+
InterlockedExchange(&(params->size), NULL);
26+
return 0;
27+
}
28+
}
29+
params->settings[i].hEvent = CreateEventW(NULL, FALSE, FALSE, NULL);
30+
if (!params->settings[i].hEvent)
31+
{
32+
InterlockedExchange(&(params->size), 0);
33+
return 0;
34+
}
35+
handles[i] = params->settings[i].hEvent;
36+
if (RegCreateKeyExW(
37+
params->settings[i].origin,
38+
params->settings[i].name,
39+
0,
40+
NULL,
41+
REG_OPTION_NON_VOLATILE,
42+
KEY_READ,
43+
NULL,
44+
&(params->settings[i].hKey),
45+
NULL
46+
) != ERROR_SUCCESS)
47+
{
48+
InterlockedExchange(&(params->size), 0);
49+
return 0;
50+
}
51+
if (RegNotifyChangeKeyValue(
52+
params->settings[i].hKey,
53+
FALSE,
54+
REG_NOTIFY_CHANGE_LAST_SET,
55+
params->settings[i].hEvent,
56+
TRUE
57+
) != ERROR_SUCCESS)
58+
{
59+
InterlockedExchange(&(params->size), 0);
60+
return 0;
61+
}
3562
}
36-
if (RegNotifyChangeKeyValue(
37-
params->settings[i].hKey,
63+
DWORD dwRes = WaitForMultipleObjects(
64+
params->size,
65+
handles,
3866
FALSE,
39-
REG_NOTIFY_CHANGE_LAST_SET,
40-
params->settings[i].hEvent,
41-
TRUE
42-
) != ERROR_SUCCESS)
43-
{
44-
return 0;
45-
}
46-
}
47-
handles[params->size] = params->hExitEvent;
48-
DWORD dwRes = WaitForMultipleObjects(
49-
params->size + (params->hExitEvent ? 1 : 0),
50-
handles,
51-
FALSE,
52-
INFINITE
53-
);
54-
if (dwRes != WAIT_FAILED)
55-
{
56-
unsigned int i = dwRes - WAIT_OBJECT_0;
57-
if (i >= 0 && i < params->size)
58-
{
59-
params->settings[i].callback(params->settings[i].data);
60-
}
61-
else if (i == params->size && params->hExitEvent)
67+
INFINITE
68+
);
69+
if (dwRes != WAIT_FAILED)
6270
{
63-
bShouldExit = TRUE;
71+
unsigned int i = dwRes - WAIT_OBJECT_0;
72+
if (i >= 1 && i < params->size)
73+
{
74+
params->settings[i].callback(params->settings[i].data);
75+
}
76+
else if (i == 0)
77+
{
78+
bShouldExit = TRUE;
79+
}
80+
for (unsigned int j = 1; j < params->size; ++j)
81+
{
82+
if (WaitForSingleObject(handles[j], 0) == WAIT_OBJECT_0)
83+
{
84+
params->settings[j].callback(params->settings[j].data);
85+
}
86+
}
6487
}
65-
for (unsigned int j = 0; j < params->size; ++j)
88+
free(handles);
89+
for (unsigned int i = 1; i < params->size; ++i)
6690
{
67-
if (WaitForSingleObject(handles[j], 0) == WAIT_OBJECT_0)
91+
if (params->settings[i].hEvent)
92+
{
93+
CloseHandle(params->settings[i].hEvent);
94+
}
95+
if (params->settings[i].hKey)
6896
{
69-
params->settings[j].callback(params->settings[j].data);
97+
RegCloseKey(params->settings[i].hKey);
7098
}
7199
}
100+
if (bShouldExit)
101+
{
102+
break;
103+
}
72104
}
73-
free(handles);
74-
for (unsigned int i = 0; i < params->size; ++i)
75-
{
76-
CloseHandle(params->settings[i].hEvent);
77-
RegCloseKey(params->settings[i].hKey);
78-
}
79-
if (bShouldExit)
105+
else
80106
{
81-
break;
107+
InterlockedExchange(&(params->size), 0);
108+
return 0;
82109
}
83110
}
111+
printf("[SettingsMonitor] Ended %p\n", params->settings[0].hEvent);
112+
InterlockedExchange(&(params->size), 0);
113+
return 0;
84114
}
85115

ExplorerPatcher/SettingsMonitor.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
#include <Windows.h>
44
#include <Shlwapi.h>
55
#pragma comment(lib, "Shlwapi.lib")
6+
#include <stdio.h>
67

78
typedef struct _Setting
89
{
@@ -17,7 +18,7 @@ typedef struct _SettingsChangeParameters
1718
{
1819
Setting* settings;
1920
DWORD size;
20-
HANDLE hExitEvent;
21+
HANDLE hThread;
2122
} SettingsChangeParameters;
2223
DWORD WINAPI MonitorSettings(SettingsChangeParameters*);
2324
#endif

0 commit comments

Comments
 (0)