1 /* 2 vfdshutil.cpp 3 4 Virtual Floppy Drive for Windows 5 Driver control library 6 shell extension utility functions 7 8 Copyright (c) 2003-2005 Ken Kato 9 */ 10 11 #define WIN32_LEAN_AND_MEAN 12 #include <windows.h> 13 #include <objbase.h> 14 #include <stdio.h> 15 16 #include "vfdtypes.h" 17 #include "vfdapi.h" 18 #include "vfdlib.h" 19 #include "vfdshcfact.h" 20 21 //===================================== 22 // Initialize the GUID instance 23 //===================================== 24 25 #ifdef _MSC_VER 26 #pragma data_seg(".text") 27 #endif 28 #define INITGUID 29 #include <initguid.h> 30 #include <shlguid.h> 31 #include "vfdshguid.h" 32 #ifdef _MSC_VER 33 #pragma data_seg() 34 #endif 35 36 // 37 // Registry path to the approved shell extensions key 38 // 39 #define REGKEY_APPROVED \ 40 "Software\\Microsoft\\Windows\\CurrentVersion\\Shell Extensions\\Approved" 41 42 43 //===================================== 44 // Shell extension library requirements 45 //===================================== 46 47 // 48 // Creates a class factory instance 49 // 50 STDAPI DllGetClassObject( 51 REFCLSID rclsid, 52 REFIID riid, 53 LPVOID *ppvOut) 54 { 55 VFDTRACE(0, 56 ("DllGetClassObject\n")); 57 58 *ppvOut = NULL; 59 60 if (IsEqualIID(rclsid, CLSID_VfdShellExt)) { 61 CVfdFactory *pFactory = new CVfdFactory; 62 63 if (!pFactory) { 64 return E_OUTOFMEMORY; 65 } 66 67 return pFactory->QueryInterface(riid, ppvOut); 68 } 69 70 return CLASS_E_CLASSNOTAVAILABLE; 71 } 72 73 // 74 // DllCanUnloadNow 75 // 76 STDAPI DllCanUnloadNow(void) 77 { 78 VFDTRACE(0, 79 ("DllCanUnloadNow - %s\n", (g_cDllRefCnt ? "No" : "Yes"))); 80 81 return (g_cDllRefCnt ? S_FALSE : S_OK); 82 } 83 84 //===================================== 85 // Shell extension register functions 86 //===================================== 87 88 static inline void MakeGuidString(LPTSTR str, const GUID &guid) 89 { 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]); 95 } 96 97 // 98 // Regster this dll as shell extention handlers 99 // 100 DWORD WINAPI VfdRegisterHandlers() 101 { 102 TCHAR buf[MAX_PATH]; 103 TCHAR guid_str[40]; 104 HKEY hKey; 105 DWORD temp; 106 DWORD ret; 107 108 MakeGuidString(guid_str, CLSID_VfdShellExt); 109 110 // 111 // Register the GUID in the CLSID subtree 112 // 113 sprintf(buf, "CLSID\\%s", guid_str); 114 115 VFDTRACE(0, ("HKCR\\%s\n", buf)); 116 117 ret = RegCreateKeyEx( 118 HKEY_CLASSES_ROOT, buf, 0, NULL, 119 0, KEY_ALL_ACCESS, NULL, &hKey, &temp); 120 121 if (ret != ERROR_SUCCESS) { 122 return ret; 123 } 124 125 if (temp == REG_OPENED_EXISTING_KEY) { 126 temp = sizeof(buf); 127 128 ret = RegQueryValueEx( 129 hKey, NULL, NULL, NULL, (PBYTE)buf, &temp); 130 131 if (ret != ERROR_SUCCESS) { 132 RegCloseKey(hKey); 133 return ret; 134 } 135 136 if (_stricmp(buf, VFDEXT_DESCRIPTION)) { 137 RegCloseKey(hKey); 138 return ERROR_FILE_EXISTS; 139 } 140 } 141 else { 142 143 VFDTRACE(0, ("@=" VFDEXT_DESCRIPTION "\n")); 144 145 ret = RegSetValueEx(hKey, NULL, NULL, REG_SZ, 146 (PBYTE)VFDEXT_DESCRIPTION, sizeof(VFDEXT_DESCRIPTION)); 147 148 RegCloseKey(hKey); 149 150 if (ret != ERROR_SUCCESS) { 151 return ret; 152 } 153 } 154 155 // 156 // Register the executable path 157 // 158 sprintf(buf, "CLSID\\%s\\InProcServer32", guid_str); 159 160 VFDTRACE(0, ("HKCR\\%s\n", buf)); 161 162 ret = RegCreateKeyEx( 163 HKEY_CLASSES_ROOT, buf, 0, NULL, 164 0, KEY_ALL_ACCESS, NULL, &hKey, NULL); 165 166 if (ret != ERROR_SUCCESS) { 167 return ret; 168 } 169 170 temp = GetModuleFileName(g_hDllModule, buf, sizeof(buf)); 171 172 VFDTRACE(0, ("@=%s\n", buf)); 173 174 ret = RegSetValueEx( 175 hKey, NULL, NULL, REG_SZ, (PBYTE)buf, temp + 1); 176 177 if (ret != ERROR_SUCCESS) { 178 RegCloseKey(hKey); 179 return ret; 180 } 181 182 VFDTRACE(0, ("ThreadingModel=Apartment\n")); 183 184 ret = RegSetValueEx(hKey, "ThreadingModel", NULL, REG_SZ, 185 (PBYTE)"Apartment", sizeof("Apartment")); 186 187 RegCloseKey(hKey); 188 189 if (ret != ERROR_SUCCESS) { 190 return ret; 191 } 192 193 // 194 // Register context menu handler 195 // 196 VFDTRACE(0, ("HKCR\\" VFDEXT_MENU_REGKEY "\n")); 197 198 ret = RegCreateKeyEx( 199 HKEY_CLASSES_ROOT, VFDEXT_MENU_REGKEY, 0, NULL, 200 0, KEY_ALL_ACCESS, NULL, &hKey, NULL); 201 202 if (ret != ERROR_SUCCESS) { 203 return ret; 204 } 205 206 VFDTRACE(0, ("@=%s\n", guid_str)); 207 208 ret = RegSetValueEx(hKey, NULL, NULL, REG_SZ, 209 (PBYTE)guid_str, strlen(guid_str) + 1); 210 211 RegCloseKey(hKey); 212 213 if (ret != ERROR_SUCCESS) { 214 return ret; 215 } 216 217 // 218 // Register Drag&Drop handler 219 // 220 if (!IS_WINDOWS_NT()) { 221 // 222 // Windows NT does not support Drag&Drop handlers ??? 223 // 224 VFDTRACE(0, ("HKCR\\" VFDEXT_DND_REGKEY "\n")); 225 226 ret = RegCreateKeyEx( 227 HKEY_CLASSES_ROOT, VFDEXT_DND_REGKEY, 0, NULL, 228 0, KEY_ALL_ACCESS, NULL, &hKey, NULL); 229 230 if (ret != ERROR_SUCCESS) { 231 return ret; 232 } 233 234 VFDTRACE(0, ("@=%s\n", guid_str)); 235 236 ret = RegSetValueEx(hKey, NULL, NULL, REG_SZ, 237 (PBYTE)guid_str, strlen(guid_str) + 1); 238 239 RegCloseKey(hKey); 240 241 if (ret != ERROR_SUCCESS) { 242 return ret; 243 } 244 } 245 246 // 247 // Register property sheet handler 248 // 249 VFDTRACE(0, ("HKCR\\" VFDEXT_PROP_REGKEY "\n")); 250 251 ret = RegCreateKeyEx( 252 HKEY_CLASSES_ROOT, VFDEXT_PROP_REGKEY, 0, NULL, 253 0, KEY_ALL_ACCESS, NULL, &hKey, NULL); 254 255 if (ret != ERROR_SUCCESS) { 256 return ret; 257 } 258 259 VFDTRACE(0, ("@=%s\n", guid_str)); 260 261 ret = RegSetValueEx(hKey, NULL, NULL, REG_SZ, 262 (PBYTE)guid_str, strlen(guid_str) + 1); 263 264 RegCloseKey(hKey); 265 266 if (ret != ERROR_SUCCESS) { 267 return ret; 268 } 269 270 // 271 // Register approved extensions entry 272 // 273 VFDTRACE(0, ("HKLM\\" REGKEY_APPROVED "\n")); 274 275 ret = RegCreateKeyEx( 276 HKEY_LOCAL_MACHINE, REGKEY_APPROVED, 277 0, NULL, 0, KEY_ALL_ACCESS, NULL, &hKey, NULL); 278 279 if (ret != ERROR_SUCCESS) { 280 return ret; 281 } 282 283 VFDTRACE(0, 284 ("%s=" VFDEXT_DESCRIPTION "\n", guid_str)); 285 286 ret = RegSetValueEx(hKey, guid_str, NULL, REG_SZ, 287 (PBYTE)VFDEXT_DESCRIPTION, sizeof(VFDEXT_DESCRIPTION)); 288 289 RegCloseKey(hKey); 290 291 return ret; 292 } 293 294 // 295 // Unregister context menu handler 296 // 297 DWORD WINAPI VfdUnregisterHandlers() 298 { 299 TCHAR buf[MAX_PATH]; 300 TCHAR guid_str[40]; 301 HKEY hKey; 302 DWORD temp; 303 DWORD ret; 304 305 MakeGuidString(guid_str, CLSID_VfdShellExt); 306 307 sprintf(buf, "CLSID\\%s", guid_str); 308 309 VFDTRACE(0, ("HKCR\\%s\n", buf)); 310 311 temp = sizeof(buf); 312 313 ret = RegQueryValue(HKEY_CLASSES_ROOT, buf, buf, (PLONG)&temp); 314 315 if (ret != ERROR_SUCCESS) { 316 return ret; 317 } 318 319 if (_stricmp(buf, VFDEXT_DESCRIPTION)) { 320 return ERROR_PATH_NOT_FOUND; 321 } 322 323 sprintf(buf, "CLSID\\%s\\InProcServer32", guid_str); 324 325 VFDTRACE(0, ("HKCR\\%s\n", buf)); 326 327 ret = RegDeleteKey(HKEY_CLASSES_ROOT, buf); 328 329 if (ret != ERROR_SUCCESS) { 330 return ret; 331 } 332 333 sprintf(buf, "CLSID\\%s", guid_str); 334 335 VFDTRACE(0, ("HKCR\\%s\n", buf)); 336 337 ret = RegDeleteKey(HKEY_CLASSES_ROOT, buf); 338 339 if (ret != ERROR_SUCCESS) { 340 return ret; 341 } 342 343 VFDTRACE(0, ("HKCR\\" VFDEXT_MENU_REGKEY "\n")); 344 345 ret = RegDeleteKey(HKEY_CLASSES_ROOT, VFDEXT_MENU_REGKEY); 346 347 if (ret != ERROR_SUCCESS) { 348 return ret; 349 } 350 351 if (!IS_WINDOWS_NT()) { 352 353 // Windows NT doesn't support Drag & Drop handlers ??? 354 355 VFDTRACE(0, ("HKCR\\" VFDEXT_DND_REGKEY "\n")); 356 357 ret = RegDeleteKey(HKEY_CLASSES_ROOT, VFDEXT_DND_REGKEY); 358 359 if (ret != ERROR_SUCCESS) { 360 return ret; 361 } 362 } 363 364 VFDTRACE(0, ("HKCR\\" VFDEXT_PROP_REGKEY "\n")); 365 366 ret = RegDeleteKey(HKEY_CLASSES_ROOT, VFDEXT_PROP_REGKEY); 367 368 if (ret != ERROR_SUCCESS) { 369 return ret; 370 } 371 372 VFDTRACE(0, ("HKLM\\" REGKEY_APPROVED "\n")); 373 374 ret = RegCreateKeyEx( 375 HKEY_LOCAL_MACHINE, 376 REGKEY_APPROVED, 377 0, NULL, 0, KEY_ALL_ACCESS, NULL, &hKey, NULL); 378 379 if (ret != ERROR_SUCCESS) { 380 return ret; 381 } 382 383 ret = RegDeleteValue(hKey, guid_str); 384 385 RegCloseKey(hKey); 386 387 return ret; 388 } 389 390 // 391 // Check if context menu handler is registered 392 // 393 DWORD WINAPI VfdCheckHandlers() 394 { 395 TCHAR buf[MAX_PATH]; 396 TCHAR guid_str[40]; 397 DWORD temp; 398 DWORD ret; 399 400 MakeGuidString(guid_str, CLSID_VfdShellExt); 401 402 sprintf(buf, "CLSID\\%s", guid_str); 403 404 VFDTRACE(0, ("HKCR\\%s\n", buf)); 405 406 temp = sizeof(buf); 407 408 ret = RegQueryValue(HKEY_CLASSES_ROOT, buf, buf, (PLONG)&temp); 409 410 if (ret != ERROR_SUCCESS) { 411 return ret; 412 } 413 414 if (_stricmp(buf, VFDEXT_DESCRIPTION)) { 415 return ERROR_PATH_NOT_FOUND; 416 } 417 418 return ERROR_SUCCESS; 419 } 420