annotate kdiff3/diff_ext_for_kdiff3/server.cpp @ 113:7bca1f1340f6 tip

Build fixes for Xcode 10 / Qt 5.12
author Chris Cannam
date Mon, 17 Dec 2018 11:13:01 +0000
parents b2f22ae5f810
children
rev   line source
joachim99@75 1 /*
joachim99@75 2 * Copyright (c) 2003-2005, Sergey Zorin. All rights reserved.
joachim99@75 3 *
joachim99@75 4 * This software is distributable under the BSD license. See the terms
joachim99@75 5 * of the BSD license in the LICENSE file provided with this software.
joachim99@75 6 *
joachim99@75 7 */
joachim99@75 8
joachim99@75 9 #define _CRT_NON_CONFORMING_SWPRINTFS
joachim99@75 10 #define _CRT_SECURE_NO_DEPRECATE
joachim99@75 11
joachim99@75 12 #include <stdio.h>
joachim99@75 13
joachim99@75 14 #include <windows.h>
joachim99@75 15 #include <tchar.h>
joachim99@75 16
joachim99@75 17 #include <shlguid.h>
joachim99@75 18 #include <olectl.h>
joachim99@75 19 #include <objidl.h>
joachim99@75 20
joachim99@75 21 #include <objbase.h>
joachim99@75 22 #include <initguid.h>
joachim99@75 23
joachim99@75 24 //#include <log/log.h>
joachim99@75 25 //#include <log/log_message.h>
joachim99@75 26 //#include <log/file_sink.h>
joachim99@75 27 //#include <debug/trace.h>
joachim99@75 28
joachim99@75 29 #include "server.h"
joachim99@75 30 #include "class_factory.h"
joachim99@75 31
joachim99@75 32 #define DllExport __declspec( dllexport )
joachim99@75 33
joachim99@75 34 // registry key util struct
joachim99@75 35 struct REGSTRUCT {
joachim99@94 36 LPCTSTR subkey;
joachim99@94 37 LPCTSTR name;
joachim99@94 38 LPCTSTR value;
joachim99@75 39 };
joachim99@75 40
joachim99@75 41 SERVER* SERVER::_instance = 0;
joachim99@75 42 static HINSTANCE server_instance; // Handle to this DLL itself.
joachim99@75 43
joachim99@75 44 //DEFINE_GUID(CLSID_DIFF_EXT, 0xA0482097, 0xC69D, 0x4DEC, 0x8A, 0xB6, 0xD3, 0xA2, 0x59, 0xAC, 0xC1, 0x51);
joachim99@75 45 // New class id for DIFF_EXT for KDiff3
joachim99@94 46 #ifdef _WIN64
joachim99@94 47 // {34471FFB-4002-438b-8952-E4588D0C0FE9}
joachim99@94 48 DEFINE_GUID( CLSID_DIFF_EXT, 0x34471FFB, 0x4002, 0x438b, 0x89, 0x52, 0xE4, 0x58, 0x8D, 0x0C, 0x0F, 0xE9 );
joachim99@94 49 #else
joachim99@75 50 DEFINE_GUID( CLSID_DIFF_EXT, 0x9f8528e4, 0xab20, 0x456e, 0x84, 0xe5, 0x3c, 0xe6, 0x9d, 0x87, 0x20, 0xf3 );
joachim99@94 51 #endif
joachim99@75 52
joachim99@75 53 tstring SERVER::getRegistryKeyString( const tstring& subKey, const tstring& value )
joachim99@75 54 {
joachim99@75 55 tstring keyName = m_registryBaseName;
joachim99@75 56 if (!subKey.empty())
joachim99@75 57 keyName += TEXT("\\")+subKey;
joachim99@75 58
joachim99@75 59 HKEY key;
joachim99@75 60 HKEY baseKey = HKEY_CURRENT_USER;
joachim99@75 61 tstring result;
joachim99@75 62 for(;;)
joachim99@75 63 {
joachim99@75 64 if( RegOpenKeyEx( baseKey, keyName.c_str(), 0, KEY_READ, &key ) == ERROR_SUCCESS )
joachim99@75 65 {
joachim99@75 66 DWORD neededSizeInBytes = 0;
joachim99@75 67 if (RegQueryValueEx(key, value.c_str(), 0, 0, 0, &neededSizeInBytes) == ERROR_SUCCESS)
joachim99@75 68 {
joachim99@75 69 DWORD length = neededSizeInBytes / sizeof( TCHAR );
joachim99@75 70 result.resize( length );
joachim99@75 71 if ( RegQueryValueEx( key, value.c_str(), 0, 0, (LPBYTE)&result[0], &neededSizeInBytes ) == ERROR_SUCCESS)
joachim99@75 72 {
joachim99@75 73 //Everything is ok, but we want to cut off the terminating 0-character
joachim99@75 74 result.resize( length - 1 );
joachim99@75 75 RegCloseKey(key);
joachim99@75 76 return result;
joachim99@75 77 }
joachim99@75 78 else
joachim99@75 79 {
joachim99@75 80 result.resize(0);
joachim99@75 81 }
joachim99@75 82 }
joachim99@75 83
joachim99@75 84 RegCloseKey(key);
joachim99@75 85 }
joachim99@75 86 if (baseKey==HKEY_LOCAL_MACHINE)
joachim99@75 87 break;
joachim99@75 88 baseKey = HKEY_LOCAL_MACHINE;
joachim99@75 89 }
joachim99@75 90
joachim99@75 91 // Error
joachim99@75 92 {
joachim99@75 93 LPTSTR message;
joachim99@75 94 FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM, 0,
joachim99@75 95 GetLastError(), MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPTSTR) &message, 0, 0);
joachim99@75 96 ERRORLOG( (tstring(TEXT("RegOpenKeyEx: ")+keyName+TEXT("->")+value) + TEXT(": ")) + message ); \
joachim99@75 97 LocalFree(message);
joachim99@75 98 }
joachim99@75 99 return result;
joachim99@75 100 }
joachim99@75 101
joachim99@75 102
joachim99@75 103 STDAPI
joachim99@75 104 DllCanUnloadNow(void) {
joachim99@75 105 HRESULT ret = S_FALSE;
joachim99@75 106
joachim99@75 107 if(SERVER::instance()->reference_count() == 0) {
joachim99@75 108 ret = S_OK;
joachim99@75 109 }
joachim99@75 110
joachim99@75 111 return ret;
joachim99@75 112 }
joachim99@75 113
joachim99@75 114 extern "C" int APIENTRY
joachim99@75 115 DllMain(HINSTANCE instance, DWORD reason, LPVOID /* reserved */) {
joachim99@75 116 // char str[1024];
joachim99@75 117 // char* reason_string[] = {"DLL_PROCESS_DETACH", "DLL_PROCESS_ATTACH", "DLL_THREAD_ATTACH", "DLL_THREAD_DETACH"};
joachim99@75 118 // sprintf(str, "instance: %x; reason: '%s'", instance, reason_string[reason]);
joachim99@75 119 // MessageBox(0, str, TEXT("Info"), MB_OK);
joachim99@75 120 switch (reason) {
joachim99@75 121 case DLL_PROCESS_ATTACH:
joachim99@75 122 server_instance = instance;
joachim99@75 123 SERVER::instance()->save_history();
joachim99@75 124 MESSAGELOG(TEXT("DLL_PROCESS_ATTACH"));
joachim99@75 125 break;
joachim99@75 126
joachim99@75 127 case DLL_PROCESS_DETACH:
joachim99@75 128 MESSAGELOG(TEXT("DLL_PROCESS_DETACH"));
joachim99@75 129 SERVER::instance()->save_history();
joachim99@75 130 break;
joachim99@75 131 }
joachim99@75 132
joachim99@75 133 return 1;
joachim99@75 134 }
joachim99@75 135
joachim99@75 136 STDAPI
joachim99@75 137 DllGetClassObject(REFCLSID rclsid, REFIID riid, void** class_object) {
joachim99@75 138 HRESULT ret = CLASS_E_CLASSNOTAVAILABLE;
joachim99@75 139 *class_object = 0;
joachim99@75 140
joachim99@75 141 if (IsEqualIID(rclsid, CLSID_DIFF_EXT)) {
joachim99@75 142 CLASS_FACTORY* pcf = new CLASS_FACTORY();
joachim99@75 143
joachim99@75 144 ret = pcf->QueryInterface(riid, class_object);
joachim99@75 145 }
joachim99@75 146
joachim99@75 147 return ret;
joachim99@75 148 }
joachim99@75 149
joachim99@75 150 /*extern "C" HRESULT STDAPICALLTYPE*/ STDAPI
joachim99@75 151 DllRegisterServer() {
joachim99@75 152 return SERVER::instance()->do_register();
joachim99@75 153 }
joachim99@75 154
joachim99@75 155 STDAPI
joachim99@75 156 DllUnregisterServer() {
joachim99@75 157 return SERVER::instance()->do_unregister();
joachim99@75 158 }
joachim99@75 159
joachim99@75 160 SERVER* SERVER::instance()
joachim99@75 161 {
joachim99@75 162 if(_instance == 0)
joachim99@75 163 {
joachim99@75 164 _instance = new SERVER();
joachim99@75 165 _instance->initLogging();
joachim99@75 166 MESSAGELOG(TEXT("New Server instance"));
joachim99@75 167 }
joachim99@75 168
joachim99@75 169 return _instance;
joachim99@75 170 }
joachim99@75 171
joachim99@75 172 SERVER::SERVER() : _reference_count(0)
joachim99@75 173 {
joachim99@75 174 m_registryBaseName = TEXT("Software\\KDiff3\\diff-ext");
joachim99@75 175 m_pRecentFiles = 0;
joachim99@75 176 m_pLogFile = 0;
joachim99@75 177 }
joachim99@75 178
joachim99@75 179 void SERVER::initLogging()
joachim99@75 180 {
joachim99@75 181 tstring logFileName = getRegistryKeyString( TEXT(""), TEXT("LogFile") );
joachim99@75 182 if ( !logFileName.empty() )
joachim99@75 183 {
joachim99@75 184 m_pLogFile = _tfopen( logFileName.c_str(), TEXT("a+, ccs=UTF-8") );
joachim99@75 185 if (m_pLogFile)
joachim99@75 186 {
joachim99@75 187 _ftprintf( m_pLogFile, TEXT("\nSERVER::SERVER()\n") );
joachim99@75 188 }
joachim99@75 189 }
joachim99@75 190 }
joachim99@75 191
joachim99@75 192 SERVER::~SERVER()
joachim99@75 193 {
joachim99@75 194 if ( m_pLogFile )
joachim99@75 195 {
joachim99@75 196 _ftprintf( m_pLogFile, TEXT("SERVER::~SERVER()\n\n") );
joachim99@75 197 fclose( m_pLogFile );
joachim99@75 198 }
joachim99@75 199
joachim99@75 200 delete m_pRecentFiles;
joachim99@75 201 }
joachim99@75 202
joachim99@75 203 HINSTANCE
joachim99@75 204 SERVER::handle() const
joachim99@75 205 {
joachim99@75 206 return server_instance;
joachim99@75 207 }
joachim99@75 208
joachim99@75 209 void
joachim99@75 210 SERVER::lock() {
joachim99@75 211 InterlockedIncrement(&_reference_count);
joachim99@75 212 }
joachim99@75 213
joachim99@75 214 void
joachim99@75 215 SERVER::release() {
joachim99@75 216 InterlockedDecrement(&_reference_count);
joachim99@75 217
joachim99@75 218 //if(InterlockedDecrement((LPLONG)&_reference_count) == 0)
joachim99@75 219 // delete this;
joachim99@75 220 }
joachim99@75 221
joachim99@75 222 void SERVER::logMessage( const char* function, const char* file, int line, const tstring& msg )
joachim99@75 223 {
joachim99@75 224 SERVER* pServer = SERVER::instance();
joachim99@75 225 if ( pServer && pServer->m_pLogFile )
joachim99@75 226 {
joachim99@75 227 SYSTEMTIME st;
joachim99@75 228 GetSystemTime( &st );
joachim99@75 229 _ftprintf( pServer->m_pLogFile, TEXT("%04d/%02d/%02d %02d:%02d:%02d ")
joachim99@75 230 #ifdef UNICODE
joachim99@75 231 TEXT("%S (%S:%d) %s\n"), // integrate char-string into wchar_t string
joachim99@75 232 #else
joachim99@75 233 TEXT("%s (%s:%d) %s\n"),
joachim99@75 234 #endif
joachim99@75 235 st.wYear, st.wMonth, st.wDay, st.wHour, st.wMinute, st.wSecond, function, file, line, msg.c_str() );
joachim99@75 236 fflush(pServer->m_pLogFile);
joachim99@75 237 }
joachim99@75 238 }
joachim99@75 239
joachim99@75 240 std::list<tstring>&
joachim99@75 241 SERVER::recent_files()
joachim99@75 242 {
joachim99@75 243 LOG();
joachim99@75 244 if ( m_pRecentFiles==0 )
joachim99@75 245 {
joachim99@75 246 MESSAGELOG(TEXT("Reading history from registry..."));
joachim99@75 247 m_pRecentFiles = new std::list<tstring>;
joachim99@75 248 for( int i=0; i<32; ++i ) // Max history size
joachim99@75 249 {
joachim99@75 250 TCHAR numAsString[10];
joachim99@75 251 _sntprintf( numAsString, 10, TEXT("%d"), i );
joachim99@75 252 tstring historyItem = getRegistryKeyString( TEXT("history"), numAsString );
joachim99@75 253 if ( ! historyItem.empty() )
joachim99@75 254 m_pRecentFiles->push_back( historyItem );
joachim99@75 255 }
joachim99@75 256 }
joachim99@75 257 return *m_pRecentFiles;
joachim99@75 258 }
joachim99@75 259
joachim99@75 260 void
joachim99@75 261 SERVER::save_history() const
joachim99@75 262 {
joachim99@75 263 if( m_pRecentFiles && !m_pRecentFiles->empty() )
joachim99@75 264 {
joachim99@75 265 HKEY key;
joachim99@75 266 if( RegCreateKeyEx(HKEY_CURRENT_USER, (m_registryBaseName + TEXT("\\history")).c_str(), 0, 0,
joachim99@75 267 REG_OPTION_NON_VOLATILE, KEY_WRITE, 0, &key, 0) == ERROR_SUCCESS )
joachim99@75 268 {
joachim99@75 269 LOG();
joachim99@75 270 //DWORD len = MAX_PATH;
joachim99@75 271 int n = 0;
joachim99@75 272
joachim99@75 273 std::list<tstring>::const_iterator i;
joachim99@75 274
joachim99@75 275 for(i = m_pRecentFiles->begin(); i!=m_pRecentFiles->end(); ++i, ++n )
joachim99@75 276 {
joachim99@75 277 tstring str = *i;
joachim99@75 278 TCHAR numAsString[10];
joachim99@75 279 _sntprintf( numAsString, 10, TEXT("%d"), n );
joachim99@75 280 if(RegSetValueEx(key, numAsString, 0, REG_SZ, (const BYTE*)str.c_str(), (DWORD)(str.size()+1)*sizeof(TCHAR) ) != ERROR_SUCCESS)
joachim99@75 281 {
joachim99@75 282 LPTSTR message;
joachim99@75 283 FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM, 0,
joachim99@75 284 GetLastError(), MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
joachim99@75 285 (LPTSTR) &message, 0, 0);
joachim99@75 286 MessageBox(0, message, TEXT("Save history failed"), MB_OK | MB_ICONINFORMATION);
joachim99@75 287 LocalFree(message);
joachim99@75 288 }
joachim99@75 289 }
joachim99@75 290
joachim99@75 291 RegCloseKey(key);
joachim99@75 292 }
joachim99@75 293 else
joachim99@75 294 {
joachim99@75 295 SYSERRORLOG(TEXT("RegOpenKeyEx"));
joachim99@75 296 }
joachim99@75 297 }
joachim99@75 298 }
joachim99@75 299
joachim99@75 300 HRESULT
joachim99@75 301 SERVER::do_register() {
joachim99@75 302 LOG();
joachim99@75 303 TCHAR class_id[MAX_PATH];
joachim99@75 304 LPWSTR tmp_guid;
joachim99@75 305 HRESULT ret = SELFREG_E_CLASS;
joachim99@75 306
joachim99@75 307 if (StringFromIID(CLSID_DIFF_EXT, &tmp_guid) == S_OK) {
joachim99@75 308 #ifdef UNICODE
joachim99@75 309 _tcsncpy(class_id, tmp_guid, MAX_PATH);
joachim99@75 310 #else
joachim99@75 311 wcstombs(class_id, tmp_guid, MAX_PATH);
joachim99@75 312 #endif
joachim99@75 313 CoTaskMemFree((void*)tmp_guid);
joachim99@75 314
joachim99@75 315 TCHAR subkey[MAX_PATH];
joachim99@75 316 TCHAR server_path[MAX_PATH];
joachim99@75 317 HKEY key;
joachim99@75 318 LRESULT result = NOERROR;
joachim99@75 319 DWORD dwDisp;
joachim99@75 320
joachim99@75 321 GetModuleFileName(SERVER::instance()->handle(), server_path, MAX_PATH);
joachim99@75 322
joachim99@75 323 REGSTRUCT entry[] = {
joachim99@75 324 {TEXT("Software\\Classes\\CLSID\\%s"), 0, TEXT("diff-ext-for-kdiff3")},
joachim99@75 325 {TEXT("Software\\Classes\\CLSID\\%s\\InProcServer32"), 0, TEXT("%s")},
joachim99@75 326 {TEXT("Software\\Classes\\CLSID\\%s\\InProcServer32"), TEXT("ThreadingModel"), TEXT("Apartment")}
joachim99@75 327 };
joachim99@75 328
joachim99@75 329 for(unsigned int i = 0; (i < sizeof(entry)/sizeof(entry[0])) && (result == NOERROR); i++) {
joachim99@75 330 _sntprintf(subkey, MAX_PATH, entry[i].subkey, class_id);
joachim99@75 331 result = RegCreateKeyEx(HKEY_CURRENT_USER, subkey, 0, 0, REG_OPTION_NON_VOLATILE, KEY_WRITE, 0, &key, &dwDisp);
joachim99@75 332
joachim99@75 333 if(result == NOERROR) {
joachim99@75 334 TCHAR szData[MAX_PATH];
joachim99@75 335
joachim99@75 336 _sntprintf(szData, MAX_PATH, entry[i].value, server_path);
joachim99@75 337 szData[MAX_PATH-1]=0;
joachim99@75 338
joachim99@75 339 result = RegSetValueEx(key, entry[i].name, 0, REG_SZ, (LPBYTE)szData, DWORD(_tcslen(szData)*sizeof(TCHAR)));
joachim99@75 340 }
joachim99@75 341
joachim99@75 342 RegCloseKey(key);
joachim99@75 343 }
joachim99@75 344
joachim99@75 345 if(result == NOERROR) {
joachim99@75 346 result = RegCreateKeyEx(HKEY_CURRENT_USER, TEXT("Software\\Classes\\*\\shellex\\ContextMenuHandlers\\diff-ext-for-kdiff3"), 0, 0, REG_OPTION_NON_VOLATILE, KEY_WRITE, 0, &key, &dwDisp);
joachim99@75 347
joachim99@75 348 if(result == NOERROR) {
joachim99@75 349
joachim99@75 350 result = RegSetValueEx(key, 0, 0, REG_SZ, (LPBYTE)class_id, DWORD(_tcslen(class_id)*sizeof(TCHAR)));
joachim99@75 351
joachim99@75 352 RegCloseKey(key);
joachim99@75 353
joachim99@75 354 //If running on NT, register the extension as approved.
joachim99@75 355 OSVERSIONINFO osvi;
joachim99@75 356
joachim99@75 357 osvi.dwOSVersionInfoSize = sizeof(osvi);
joachim99@75 358 GetVersionEx(&osvi);
joachim99@75 359
joachim99@75 360 // NT needs to have shell extensions "approved".
joachim99@75 361 if (osvi.dwPlatformId == VER_PLATFORM_WIN32_NT) {
joachim99@75 362 result = RegCreateKeyEx(HKEY_CURRENT_USER,
joachim99@75 363 TEXT("Software\\Microsoft\\Windows\\CurrentVersion\\Shell Extensions\\Approved"),
joachim99@75 364 0, 0, REG_OPTION_NON_VOLATILE, KEY_WRITE, 0, &key, &dwDisp);
joachim99@75 365
joachim99@75 366 if(result == NOERROR) {
joachim99@75 367 TCHAR szData[MAX_PATH];
joachim99@75 368
joachim99@75 369 lstrcpy(szData, TEXT("diff-ext"));
joachim99@75 370
joachim99@75 371 result = RegSetValueEx(key, class_id, 0, REG_SZ, (LPBYTE)szData, DWORD(_tcslen(szData)*sizeof(TCHAR)));
joachim99@75 372
joachim99@75 373 RegCloseKey(key);
joachim99@75 374
joachim99@75 375 ret = S_OK;
joachim99@75 376 } else if (result == ERROR_ACCESS_DENIED) {
joachim99@75 377 TCHAR msg[] = TEXT("Warning! You have unsufficient rights to write to a specific registry key.\n")
joachim99@75 378 TEXT("The application may work anyway, but it is advised to register this module ")
joachim99@75 379 TEXT("again while having administrator rights.");
joachim99@75 380
joachim99@75 381 MessageBox(0, msg, TEXT("Warning"), MB_ICONEXCLAMATION);
joachim99@75 382
joachim99@75 383 ret = S_OK;
joachim99@75 384 }
joachim99@75 385 }
joachim99@75 386 else {
joachim99@75 387 ret = S_OK;
joachim99@75 388 }
joachim99@75 389 }
joachim99@75 390 }
joachim99@75 391 }
joachim99@75 392
joachim99@75 393 return ret;
joachim99@75 394 }
joachim99@75 395
joachim99@75 396 HRESULT
joachim99@75 397 SERVER::do_unregister() {
joachim99@75 398 LOG();
joachim99@75 399 TCHAR class_id[MAX_PATH];
joachim99@75 400 LPWSTR tmp_guid;
joachim99@75 401 HRESULT ret = SELFREG_E_CLASS;
joachim99@75 402
joachim99@75 403 if (StringFromIID(CLSID_DIFF_EXT, &tmp_guid) == S_OK) {
joachim99@75 404 #ifdef UNICODE
joachim99@75 405 _tcsncpy(class_id, tmp_guid, MAX_PATH);
joachim99@75 406 #else
joachim99@75 407 wcstombs(class_id, tmp_guid, MAX_PATH);
joachim99@75 408 #endif
joachim99@75 409 CoTaskMemFree((void*)tmp_guid);
joachim99@75 410
joachim99@75 411 LRESULT result = NOERROR;
joachim99@75 412 TCHAR subkey[MAX_PATH];
joachim99@75 413
joachim99@75 414 REGSTRUCT entry[] = {
joachim99@75 415 {TEXT("Software\\Classes\\CLSID\\%s\\InProcServer32"), 0, 0},
joachim99@75 416 {TEXT("Software\\Classes\\CLSID\\%s"), 0, 0}
joachim99@75 417 };
joachim99@75 418
joachim99@75 419 for(unsigned int i = 0; (i < sizeof(entry)/sizeof(entry[0])) && (result == NOERROR); i++) {
joachim99@75 420 _stprintf(subkey, entry[i].subkey, class_id);
joachim99@75 421 result = RegDeleteKey(HKEY_CURRENT_USER, subkey);
joachim99@75 422 }
joachim99@75 423
joachim99@75 424 if(result == NOERROR) {
joachim99@75 425 result = RegDeleteKey(HKEY_CURRENT_USER, TEXT("Software\\Classes\\*\\shellex\\ContextMenuHandlers\\diff-ext-for-kdiff3"));
joachim99@75 426
joachim99@75 427 if(result == NOERROR) {
joachim99@75 428 //If running on NT, register the extension as approved.
joachim99@75 429 OSVERSIONINFO osvi;
joachim99@75 430
joachim99@75 431 osvi.dwOSVersionInfoSize = sizeof(osvi);
joachim99@75 432 GetVersionEx(&osvi);
joachim99@75 433
joachim99@75 434 // NT needs to have shell extensions "approved".
joachim99@75 435 if(osvi.dwPlatformId == VER_PLATFORM_WIN32_NT) {
joachim99@75 436 HKEY key;
joachim99@75 437
joachim99@75 438 RegOpenKeyEx(HKEY_CURRENT_USER, TEXT("SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Shell Extensions\\Approved"), 0, KEY_ALL_ACCESS, &key);
joachim99@75 439
joachim99@75 440 result = RegDeleteValue(key, class_id);
joachim99@75 441
joachim99@75 442 RegCloseKey(key);
joachim99@75 443
joachim99@75 444 if(result == ERROR_SUCCESS) {
joachim99@75 445 ret = S_OK;
joachim99@75 446 }
joachim99@75 447 }
joachim99@75 448 else {
joachim99@75 449 ret = S_OK;
joachim99@75 450 }
joachim99@75 451 }
joachim99@75 452 }
joachim99@75 453 }
joachim99@75 454
joachim99@75 455 return ret;
joachim99@75 456 }