Просмотр исходного кода

[shell_integration] Remove the usage of Win32 APIs not available on XP

Jocelyn Turcotte 11 лет назад
Родитель
Сommit
af0001a149

+ 1 - 0
shell_integration/windows/OCContextMenu/OCContextMenu.vcxproj

@@ -146,6 +146,7 @@
     <ClInclude Include="OCContextMenuFactory.h" />
     <ClInclude Include="OCContextMenuRegHandler.h" />
     <ClInclude Include="OCContextMenu.h" />
+    <ClInclude Include="RegDelnode.h" />
     <ClInclude Include="resource.h" />
     <ClInclude Include="stdafx.h" />
     <ClInclude Include="targetver.h" />

+ 3 - 2
shell_integration/windows/OCContextMenu/OCContextMenuRegHandler.cpp

@@ -15,6 +15,7 @@
 #include "stdafx.h"
 
 #include "OCContextMenuRegHandler.h"
+#include "RegDelnode.h"
 #include <strsafe.h>
 #include <objbase.h>
 
@@ -125,7 +126,7 @@ HRESULT OCContextMenuRegHandler::UnregisterInprocServer(const CLSID& clsid)
 	hr = StringCchPrintf(szSubkey, ARRAYSIZE(szSubkey), L"CLSID\\%s", szCLSID);
 	if (SUCCEEDED(hr))
 	{
-		hr = HRESULT_FROM_WIN32(RegDeleteTree(HKEY_CLASSES_ROOT, szSubkey));
+		hr = HRESULT_FROM_WIN32(RegDelnode(HKEY_CLASSES_ROOT, szSubkey));
 	}
 
 	return hr;
@@ -210,7 +211,7 @@ HRESULT OCContextMenuRegHandler::UnregisterShellExtContextMenuHandler(
 		L"%s\\shellex\\ContextMenuHandlers\\%s", pszFileType, pszFriendlyName);
 	if (SUCCEEDED(hr))
 	{
-		hr = HRESULT_FROM_WIN32(RegDeleteTree(HKEY_CLASSES_ROOT, szSubkey));
+		hr = HRESULT_FROM_WIN32(RegDelnode(HKEY_CLASSES_ROOT, szSubkey));
 	}
 
 	return hr;

+ 114 - 0
shell_integration/windows/OCContextMenu/RegDelnode.h

@@ -0,0 +1,114 @@
+#pragma once
+
+#include <windows.h>
+#include <stdio.h>
+#include <strsafe.h>
+
+// Stolen from the "Deleting a Key with Subkeys" example to replace
+// RegDeleteTree which isn't available on WinXP.
+// https://msdn.microsoft.com/en-us/library/ms724235(VS.85).aspx
+
+//*************************************************************
+//
+//  RegDelnodeRecurse()
+//
+//  Purpose:    Deletes a registry key and all its subkeys / values.
+//
+//  Parameters: hKeyRoot    -   Root key
+//              lpSubKey    -   SubKey to delete
+//
+//  Return:     TRUE if successful.
+//              FALSE if an error occurs.
+//
+//*************************************************************
+
+HRESULT RegDelnodeRecurse(HKEY hKeyRoot, LPTSTR lpSubKey)
+{
+	LPTSTR lpEnd;
+	LONG lResult;
+	DWORD dwSize;
+	TCHAR szName[MAX_PATH];
+	HKEY hKey;
+	FILETIME ftWrite;
+
+	// First, see if we can delete the key without having
+	// to recurse.
+
+	lResult = RegDeleteKey(hKeyRoot, lpSubKey);
+
+	if (lResult == ERROR_SUCCESS)
+		return lResult;
+
+	lResult = RegOpenKeyEx(hKeyRoot, lpSubKey, 0, KEY_READ, &hKey);
+
+	if (lResult != ERROR_SUCCESS)
+		return lResult;
+
+	// Check for an ending slash and add one if it is missing.
+
+	lpEnd = lpSubKey + lstrlen(lpSubKey);
+
+	if (*(lpEnd - 1) != TEXT('\\'))
+	{
+		*lpEnd = TEXT('\\');
+		lpEnd++;
+		*lpEnd = TEXT('\0');
+	}
+
+	// Enumerate the keys
+
+	dwSize = MAX_PATH;
+	lResult = RegEnumKeyEx(hKey, 0, szName, &dwSize, NULL,
+		NULL, NULL, &ftWrite);
+
+	if (lResult == ERROR_SUCCESS)
+	{
+		do {
+
+			StringCchCopy(lpEnd, MAX_PATH * 2, szName);
+
+			if (!RegDelnodeRecurse(hKeyRoot, lpSubKey)) {
+				break;
+			}
+
+			dwSize = MAX_PATH;
+
+			lResult = RegEnumKeyEx(hKey, 0, szName, &dwSize, NULL,
+				NULL, NULL, &ftWrite);
+
+		} while (lResult == ERROR_SUCCESS);
+	}
+
+	lpEnd--;
+	*lpEnd = TEXT('\0');
+
+	RegCloseKey(hKey);
+
+	// Try again to delete the key.
+
+	lResult = RegDeleteKey(hKeyRoot, lpSubKey);
+	return lResult;
+}
+
+//*************************************************************
+//
+//  RegDelnode()
+//
+//  Purpose:    Deletes a registry key and all its subkeys / values.
+//
+//  Parameters: hKeyRoot    -   Root key
+//              lpSubKey    -   SubKey to delete
+//
+//  Return:     TRUE if successful.
+//              FALSE if an error occurs.
+//
+//*************************************************************
+
+HRESULT RegDelnode(HKEY hKeyRoot, LPTSTR lpSubKey)
+{
+	TCHAR szDelKey[MAX_PATH * 2];
+
+	StringCchCopy(szDelKey, MAX_PATH * 2, lpSubKey);
+	return RegDelnodeRecurse(hKeyRoot, szDelKey);
+
+}

+ 2 - 0
shell_integration/windows/OCContextMenu/targetver.h

@@ -5,4 +5,6 @@
 // If you wish to build your application for a previous Windows platform, include WinSDKVer.h and
 // set the _WIN32_WINNT macro to the platform you wish to support before including SDKDDKVer.h.
 
+#define WINVER 0x0501
+#define _WIN32_WINNT 0x0501
 #include <SDKDDKVer.h>

+ 2 - 0
shell_integration/windows/OCOverlays/stdafx.h

@@ -13,6 +13,8 @@
  */
 
 #define WIN32_LEAN_AND_MEAN
+#define WINVER 0x0501
+#define _WIN32_WINNT 0x0501
 
 #include "CommunicationSocket.h"
 #include "RegistryUtil.h"

+ 2 - 0
shell_integration/windows/OCUtil/stdafx.h

@@ -1,5 +1,7 @@
 #pragma once
 
 #define WIN32_LEAN_AND_MEAN
+#define WINVER 0x0501
+#define _WIN32_WINNT 0x0501
 
 #include <windows.h>