forked from coddec/Classic-Shell
-
Notifications
You must be signed in to change notification settings - Fork 452
/
Copy pathClassicExplorerSettings.cpp
146 lines (129 loc) · 4.37 KB
/
ClassicExplorerSettings.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
// Classic Shell (c) 2009-2017, Ivo Beltchev
// Open-Shell (c) 2017-2018, The Open-Shell Team
// Confidential information of Ivo Beltchev. Not for disclosure or distribution without prior written consent from the author
#include <windows.h>
#include <commctrl.h>
#include <shlwapi.h>
#include <Psapi.h>
#include "StringUtils.h"
// Find and activate the Settings window
static BOOL CALLBACK FindSettingsEnum( HWND hwnd, LPARAM lParam )
{
wchar_t className[256];
if (!GetClassName(hwnd,className,_countof(className)) || _wcsicmp(className,L"#32770")!=0)
return TRUE;
DWORD process=0;
GetWindowThreadProcessId(hwnd,&process);
HANDLE hProcess=OpenProcess(PROCESS_QUERY_INFORMATION|PROCESS_VM_READ,FALSE,process);
bool bFound=false;
if (hProcess!=INVALID_HANDLE_VALUE)
{
wchar_t path[_MAX_PATH];
if (GetModuleFileNameEx(hProcess,NULL,path,_countof(path)))
{
if (_wcsicmp(PathFindFileName(path),L"ClassicExplorerSettings.exe")==0)
{
SetForegroundWindow(hwnd);
bFound=true;
}
}
CloseHandle(hProcess);
}
return !bFound;
}
HMODULE LoadClassicExplorerDll( void )
{
wchar_t path[_MAX_PATH];
GetModuleFileName(NULL, path, _countof(path));
*PathFindFileName(path) = 0;
// Load the proper module depending on architecture rather than hardcoding the x86 one
#ifdef _WIN64
PathAppend(path, L"ClassicExplorer64.dll");
#else
PathAppend(path, L"ClassicExplorer32.dll");
#endif
return LoadLibrary(path);
}
// A simple program that loads ClassicExplorer32.dll and calls the ShowExplorerSettings function
// Why not use rundll32 instead? Because it doesn't include the correct manifest for comctl32.dll
int WINAPI wWinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpstrCmdLine, int nCmdShow )
{
INITCOMMONCONTROLSEX init={sizeof(init),ICC_STANDARD_CLASSES};
InitCommonControlsEx(&init);
{
const wchar_t *pXml=wcsstr(lpstrCmdLine,L"-xml ");
if (pXml)
{
wchar_t xml[_MAX_PATH];
GetToken(pXml+5,xml,_countof(xml),L" ");
HMODULE dll=LoadClassicExplorerDll();
if (!dll) return 1;
typedef bool (*tImportSettingsXml)( const wchar_t *fname );
tImportSettingsXml DllImportSettingsXml=(tImportSettingsXml)GetProcAddress(dll,"DllImportSettingsXml");
if (!DllImportSettingsXml)
return 1;
CoInitialize(NULL);
bool res=DllImportSettingsXml(xml);
CoUninitialize();
return res?0:1;
}
}
{
const wchar_t *pBackup=wcsstr(lpstrCmdLine,L"-backup ");
if (pBackup)
{
wchar_t xml[_MAX_PATH];
GetToken(pBackup+8,xml,_countof(xml),L" ");
HMODULE dll=LoadClassicExplorerDll();
if (!dll) return 1;
typedef bool (*tExportSettingsXml)( const wchar_t *fname );
tExportSettingsXml DllExportSettingsXml=(tExportSettingsXml)GetProcAddress(dll,"DllExportSettingsXml");
if (!DllExportSettingsXml)
return 1;
CoInitialize(NULL);
bool res=DllExportSettingsXml(xml);
CoUninitialize();
return res?0:1;
}
}
#ifndef _WIN64
const wchar_t *pSaveAdmx=wcsstr(lpstrCmdLine,L"-saveadmx ");
if (pSaveAdmx)
{
wchar_t language[100];
GetToken(pSaveAdmx+10,language,_countof(language),L" ");
HMODULE dll=LoadClassicExplorerDll();
if (!dll) return 1;
typedef bool (*tSaveAdmx)( const char *admxFile, const char *admlFile, const char *docFile, const wchar_t *language );
tSaveAdmx SaveAdmx=(tSaveAdmx)GetProcAddress(dll,"DllSaveAdmx");
if (!SaveAdmx || !SaveAdmx("ClassicExplorer.admx","ClassicExplorer.adml","ClassicExplorerADMX.txt",language))
return 1;
return 0;
}
#endif
// prevent multiple instances from running on the same desktop
// the assumption is that multiple desktops for the same user will have different name (but may repeat across users)
wchar_t userName[256];
DWORD len=_countof(userName);
GetUserName(userName,&len);
len=0;
HANDLE desktop=GetThreadDesktop(GetCurrentThreadId());
GetUserObjectInformation(desktop,UOI_NAME,NULL,0,&len);
wchar_t *deskName=(wchar_t*)malloc(len);
GetUserObjectInformation(desktop,UOI_NAME,deskName,len,&len);
wchar_t mutexName[1024];
Sprintf(mutexName,_countof(mutexName),L"ClassicExplorerSettings.Mutex.%s.%s",userName,deskName);
free(deskName);
HANDLE hMutex=CreateMutex(NULL,TRUE,mutexName);
if (GetLastError()==ERROR_ALREADY_EXISTS || GetLastError()==ERROR_ACCESS_DENIED)
{
EnumWindows(FindSettingsEnum,0);
return 0;
}
HMODULE dll=LoadClassicExplorerDll();
if (!dll) return 1;
FARPROC proc=GetProcAddress(dll,"ShowExplorerSettings");
if (!proc) return 2;
proc();
return 0;
}