4 Virtual Floppy Drive for Windows
6 shell extension utility functions
8 Copyright (c) 2003-2005 Ken Kato
11 #define WIN32_LEAN_AND_MEAN
19 #include "vfdshcfact.h"
21 //=====================================
22 // Initialize the GUID instance
23 //=====================================
26 #pragma data_seg(".text")
31 #include "vfdshguid.h"
37 // Registry path to the approved shell extensions key
39 #define REGKEY_APPROVED \
40 "Software\\Microsoft\\Windows\\CurrentVersion\\Shell Extensions\\Approved"
43 //=====================================
44 // Shell extension library requirements
45 //=====================================
48 // Creates a class factory instance
50 STDAPI
DllGetClassObject(
56 ("DllGetClassObject\n"));
60 if (IsEqualIID(rclsid
, CLSID_VfdShellExt
)) {
61 CVfdFactory
*pFactory
= new CVfdFactory
;
67 return pFactory
->QueryInterface(riid
, ppvOut
);
70 return CLASS_E_CLASSNOTAVAILABLE
;
76 STDAPI
DllCanUnloadNow(void)
79 ("DllCanUnloadNow - %s\n", (g_cDllRefCnt
? "No" : "Yes")));
81 return (g_cDllRefCnt
? S_FALSE
: S_OK
);
84 //=====================================
85 // Shell extension register functions
86 //=====================================
88 static inline void MakeGuidString(LPTSTR str
, const GUID
&guid
)
90 sprintf(str
, "{%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x}",
91 guid
.Data1
, guid
.Data2
, guid
.Data3
,
92 guid
.Data4
[0], guid
.Data4
[1],
93 guid
.Data4
[2], guid
.Data4
[3], guid
.Data4
[4],
94 guid
.Data4
[5], guid
.Data4
[6], guid
.Data4
[7]);
98 // Regster this dll as shell extention handlers
100 DWORD WINAPI
VfdRegisterHandlers()
108 MakeGuidString(guid_str
, CLSID_VfdShellExt
);
111 // Register the GUID in the CLSID subtree
113 sprintf(buf
, "CLSID\\%s", guid_str
);
115 VFDTRACE(0, ("HKCR\\%s\n", buf
));
117 ret
= RegCreateKeyEx(
118 HKEY_CLASSES_ROOT
, buf
, 0, NULL
,
119 0, KEY_ALL_ACCESS
, NULL
, &hKey
, &temp
);
121 if (ret
!= ERROR_SUCCESS
) {
125 if (temp
== REG_OPENED_EXISTING_KEY
) {
128 ret
= RegQueryValueEx(
129 hKey
, NULL
, NULL
, NULL
, (PBYTE
)buf
, &temp
);
131 if (ret
!= ERROR_SUCCESS
) {
136 if (_stricmp(buf
, VFDEXT_DESCRIPTION
)) {
138 return ERROR_FILE_EXISTS
;
143 VFDTRACE(0, ("@=" VFDEXT_DESCRIPTION
"\n"));
145 ret
= RegSetValueEx(hKey
, NULL
, NULL
, REG_SZ
,
146 (PBYTE
)VFDEXT_DESCRIPTION
, sizeof(VFDEXT_DESCRIPTION
));
150 if (ret
!= ERROR_SUCCESS
) {
156 // Register the executable path
158 sprintf(buf
, "CLSID\\%s\\InProcServer32", guid_str
);
160 VFDTRACE(0, ("HKCR\\%s\n", buf
));
162 ret
= RegCreateKeyEx(
163 HKEY_CLASSES_ROOT
, buf
, 0, NULL
,
164 0, KEY_ALL_ACCESS
, NULL
, &hKey
, NULL
);
166 if (ret
!= ERROR_SUCCESS
) {
170 temp
= GetModuleFileName(g_hDllModule
, buf
, sizeof(buf
));
172 VFDTRACE(0, ("@=%s\n", buf
));
175 hKey
, NULL
, NULL
, REG_SZ
, (PBYTE
)buf
, temp
+ 1);
177 if (ret
!= ERROR_SUCCESS
) {
182 VFDTRACE(0, ("ThreadingModel=Apartment\n"));
184 ret
= RegSetValueEx(hKey
, "ThreadingModel", NULL
, REG_SZ
,
185 (PBYTE
)"Apartment", sizeof("Apartment"));
189 if (ret
!= ERROR_SUCCESS
) {
194 // Register context menu handler
196 VFDTRACE(0, ("HKCR\\" VFDEXT_MENU_REGKEY
"\n"));
198 ret
= RegCreateKeyEx(
199 HKEY_CLASSES_ROOT
, VFDEXT_MENU_REGKEY
, 0, NULL
,
200 0, KEY_ALL_ACCESS
, NULL
, &hKey
, NULL
);
202 if (ret
!= ERROR_SUCCESS
) {
206 VFDTRACE(0, ("@=%s\n", guid_str
));
208 ret
= RegSetValueEx(hKey
, NULL
, NULL
, REG_SZ
,
209 (PBYTE
)guid_str
, strlen(guid_str
) + 1);
213 if (ret
!= ERROR_SUCCESS
) {
218 // Register Drag&Drop handler
220 if (!IS_WINDOWS_NT()) {
222 // Windows NT does not support Drag&Drop handlers ???
224 VFDTRACE(0, ("HKCR\\" VFDEXT_DND_REGKEY
"\n"));
226 ret
= RegCreateKeyEx(
227 HKEY_CLASSES_ROOT
, VFDEXT_DND_REGKEY
, 0, NULL
,
228 0, KEY_ALL_ACCESS
, NULL
, &hKey
, NULL
);
230 if (ret
!= ERROR_SUCCESS
) {
234 VFDTRACE(0, ("@=%s\n", guid_str
));
236 ret
= RegSetValueEx(hKey
, NULL
, NULL
, REG_SZ
,
237 (PBYTE
)guid_str
, strlen(guid_str
) + 1);
241 if (ret
!= ERROR_SUCCESS
) {
247 // Register property sheet handler
249 VFDTRACE(0, ("HKCR\\" VFDEXT_PROP_REGKEY
"\n"));
251 ret
= RegCreateKeyEx(
252 HKEY_CLASSES_ROOT
, VFDEXT_PROP_REGKEY
, 0, NULL
,
253 0, KEY_ALL_ACCESS
, NULL
, &hKey
, NULL
);
255 if (ret
!= ERROR_SUCCESS
) {
259 VFDTRACE(0, ("@=%s\n", guid_str
));
261 ret
= RegSetValueEx(hKey
, NULL
, NULL
, REG_SZ
,
262 (PBYTE
)guid_str
, strlen(guid_str
) + 1);
266 if (ret
!= ERROR_SUCCESS
) {
271 // Register approved extensions entry
273 VFDTRACE(0, ("HKLM\\" REGKEY_APPROVED
"\n"));
275 ret
= RegCreateKeyEx(
276 HKEY_LOCAL_MACHINE
, REGKEY_APPROVED
,
277 0, NULL
, 0, KEY_ALL_ACCESS
, NULL
, &hKey
, NULL
);
279 if (ret
!= ERROR_SUCCESS
) {
284 ("%s=" VFDEXT_DESCRIPTION
"\n", guid_str
));
286 ret
= RegSetValueEx(hKey
, guid_str
, NULL
, REG_SZ
,
287 (PBYTE
)VFDEXT_DESCRIPTION
, sizeof(VFDEXT_DESCRIPTION
));
295 // Unregister context menu handler
297 DWORD WINAPI
VfdUnregisterHandlers()
305 MakeGuidString(guid_str
, CLSID_VfdShellExt
);
307 sprintf(buf
, "CLSID\\%s", guid_str
);
309 VFDTRACE(0, ("HKCR\\%s\n", buf
));
313 ret
= RegQueryValue(HKEY_CLASSES_ROOT
, buf
, buf
, (PLONG
)&temp
);
315 if (ret
!= ERROR_SUCCESS
) {
319 if (_stricmp(buf
, VFDEXT_DESCRIPTION
)) {
320 return ERROR_PATH_NOT_FOUND
;
323 sprintf(buf
, "CLSID\\%s\\InProcServer32", guid_str
);
325 VFDTRACE(0, ("HKCR\\%s\n", buf
));
327 ret
= RegDeleteKey(HKEY_CLASSES_ROOT
, buf
);
329 if (ret
!= ERROR_SUCCESS
) {
333 sprintf(buf
, "CLSID\\%s", guid_str
);
335 VFDTRACE(0, ("HKCR\\%s\n", buf
));
337 ret
= RegDeleteKey(HKEY_CLASSES_ROOT
, buf
);
339 if (ret
!= ERROR_SUCCESS
) {
343 VFDTRACE(0, ("HKCR\\" VFDEXT_MENU_REGKEY
"\n"));
345 ret
= RegDeleteKey(HKEY_CLASSES_ROOT
, VFDEXT_MENU_REGKEY
);
347 if (ret
!= ERROR_SUCCESS
) {
351 if (!IS_WINDOWS_NT()) {
353 // Windows NT doesn't support Drag & Drop handlers ???
355 VFDTRACE(0, ("HKCR\\" VFDEXT_DND_REGKEY
"\n"));
357 ret
= RegDeleteKey(HKEY_CLASSES_ROOT
, VFDEXT_DND_REGKEY
);
359 if (ret
!= ERROR_SUCCESS
) {
364 VFDTRACE(0, ("HKCR\\" VFDEXT_PROP_REGKEY
"\n"));
366 ret
= RegDeleteKey(HKEY_CLASSES_ROOT
, VFDEXT_PROP_REGKEY
);
368 if (ret
!= ERROR_SUCCESS
) {
372 VFDTRACE(0, ("HKLM\\" REGKEY_APPROVED
"\n"));
374 ret
= RegCreateKeyEx(
377 0, NULL
, 0, KEY_ALL_ACCESS
, NULL
, &hKey
, NULL
);
379 if (ret
!= ERROR_SUCCESS
) {
383 ret
= RegDeleteValue(hKey
, guid_str
);
391 // Check if context menu handler is registered
393 DWORD WINAPI
VfdCheckHandlers()
400 MakeGuidString(guid_str
, CLSID_VfdShellExt
);
402 sprintf(buf
, "CLSID\\%s", guid_str
);
404 VFDTRACE(0, ("HKCR\\%s\n", buf
));
408 ret
= RegQueryValue(HKEY_CLASSES_ROOT
, buf
, buf
, (PLONG
)&temp
);
410 if (ret
!= ERROR_SUCCESS
) {
414 if (_stricmp(buf
, VFDEXT_DESCRIPTION
)) {
415 return ERROR_PATH_NOT_FOUND
;
418 return ERROR_SUCCESS
;