Windows 8 fix for installing visual studio 6 / vb6

All the random crap I spend all day long figuring out.
Post Reply
User avatar
syntax
Site Admin
Posts: 54
Joined: Tue Jan 06, 2009 9:25 pm

Windows 8 fix for installing visual studio 6 / vb6

Post by syntax » Wed Jun 12, 2013 7:30 pm

from: http://www.vbforums.com/showthread.php? ... ws-8/page2
I found what I consider a cleaner way to resolve the issue w/ the VB6 installer on Win8. Using process monitor, you can see that the VB6 installer loops indefinitely while trying to open these keys in the registry:

HKEY_CLASSES_ROOT\RDSServer.DataFactory
HKEY_CLASSES_ROOT\RDSServer.DataFactory\Clsid

By granting the local Administrators group Ownership, and then Full Control over these two keys, the VB6 installer is able to complete without issue on Win8.
powershell script

Code: Select all

#///////////////////////////////////////////////////////////////////////////////
# Name: FixWin8RegistryACLs.ps1
# Author: Leif Maxfield
# Purpose: Fix some registry ACLs on Win8 that prevent VB6 from installing
#   cleanly. The installer loops indefinitely trying to access the keys below
#   R/W, but is only granted read. Setting Full Control for local Administrators
#   on the reg keys in $arrPaths allows the installer to finish cleanly.
#
#   As far as I can see the ACLs on these paths are the same on Win8 as they are
#   on Win7, so it's not clear to me why this has to be done at all, or why
#   it works.
# Changelog:
# * 2/12/2013 LEM: Created.
#///////////////////////////////////////////////////////////////////////////////

# <Block taken from http://shrekpoint.blogspot.com/2012/08/taking-ownership-of-dcom-registry.html>
function Enable-ProcessPrivilege {  
param(  
[ValidateSet(  
"SeAssignPrimaryTokenPrivilege", "SeAuditPrivilege", "SeBackupPrivilege",  
"SeChangeNotifyPrivilege", "SeCreateGlobalPrivilege", "SeCreatePagefilePrivilege",  
"SeCreatePermanentPrivilege", "SeCreateSymbolicLinkPrivilege",  
"SeCreateTokenPrivilege", "SeDebugPrivilege", "SeEnableDelegationPrivilege",  
"SeImpersonatePrivilege", "SeIncreaseBasePriorityPrivilege",  
"SeIncreaseQuotaPrivilege", "SeIncreaseWorkingSetPrivilege", "SeLoadDriverPrivilege",  
"SeLockMemoryPrivilege", "SeMachineAccountPrivilege", "SeManageVolumePrivilege",  
"SeProfileSingleProcessPrivilege", "SeRelabelPrivilege", "SeRemoteShutdownPrivilege",  
"SeRestorePrivilege", "SeSecurityPrivilege", "SeShutdownPrivilege",  
"SeSyncAgentPrivilege", "SeSystemEnvironmentPrivilege", "SeSystemProfilePrivilege",  
"SeSystemtimePrivilege", "SeTakeOwnershipPrivilege", "SeTcbPrivilege",  
"SeTimeZonePrivilege", "SeTrustedCredManAccessPrivilege", "SeUndockPrivilege",  
"SeUnsolicitedInputPrivilege")]  
$Privilege,  
$ProcessId = $pid,  
[Switch] $Disable  
)  
  
$definition = @'  
using System;  
using System.Runtime.InteropServices;  
  
public class AdjPriv  
{  
[DllImport("advapi32.dll", ExactSpelling = true, SetLastError = true)]  
internal static extern bool AdjustTokenPrivileges(IntPtr htok, bool disall,ref  
TokPriv1Luid newst, int len, IntPtr prev, IntPtr relen);  
[DllImport("advapi32.dll", ExactSpelling = true, SetLastError = true)]  
internal static extern bool OpenProcessToken(IntPtr h, int acc, ref IntPtr phtok);  
[DllImport("advapi32.dll", SetLastError = true)]  
internal static extern bool LookupPrivilegeValue(string host, string name, ref long  
pluid);  
[StructLayout(LayoutKind.Sequential, Pack = 1)]  
internal struct TokPriv1Luid  
{  
public int Count;  
public long Luid;  
public int Attr;  
}  
internal const int SE_PRIVILEGE_ENABLED = 0x00000002;  
internal const int SE_PRIVILEGE_DISABLED = 0x00000000;  
internal const int TOKEN_QUERY = 0x00000008;  
internal const int TOKEN_ADJUST_PRIVILEGES = 0x00000020;  
public static bool EnablePrivilege(long processHandle, string privilege, bool disable)  
{  
bool retVal;  
TokPriv1Luid tp;  
IntPtr hproc = new IntPtr(processHandle);  
IntPtr htok = IntPtr.Zero;  
retVal = OpenProcessToken(hproc, TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, ref htok);  
tp.Count = 1;  
tp.Luid = 0;  
if(disable)  
{  
tp.Attr = SE_PRIVILEGE_DISABLED;  
}  
else  
{  
tp.Attr = SE_PRIVILEGE_ENABLED;  
}  
retVal = LookupPrivilegeValue(null, privilege, ref tp.Luid);  
retVal = AdjustTokenPrivileges(htok, false, ref tp, 0, IntPtr.Zero, IntPtr.Zero);  
return retVal;  
}  
}  
'@  
  
$processHandle = (Get-Process -id $ProcessId).Handle  
$type = Add-Type $definition -PassThru  
$type[0]::EnablePrivilege($processHandle, $Privilege, $Disable)  
}

# This is necessary, else taking ownership of the key fails with access denied.
Enable-ProcessPrivilege -Privilege SeTakeOwnershipPrivilege
# </End block taken from http://shrekpoint.blogspot.com/2012/08/taking-ownership-of-dcom-registry.html>

New-PSDrive -Name HKCR -PSProvider Registry -Root HKEY_CLASSES_ROOT

# These paths cannot be accessed by the VB6 installer on Win8. Granting the
# local Administrators group ownership & Full Control on these paths allows
# VB6 to install cleanly.
$arrPaths = @(
  "HKCR:\RDSServer.DataFactory",
  "HKCR:\RDSServer.DataFactory\Clsid"
)

# We will take ownership & set Full Control for the local Administrators group.
$acct = [System.Security.Principal.NTAccount]"Administrators"

$arrPaths | % {
  # Note that we are explicitly processing HKCR keys here. Keys under other
  # base paths would need to be processed differently!
  $subKeyPath = $_ -replace ('HKCR:\\', '')
  $key = [Microsoft.Win32.Registry]::ClassesRoot.OpenSubKey($subKeyPath,
    [Microsoft.Win32.RegistryKeyPermissionCheck]::ReadWriteSubTree,
    [System.Security.AccessControl.RegistryRights]::TakeOwnership)
  $acl = $key.GetAccessControl([System.Security.AccessControl.AccessControlSections]::None)
  $acl.SetOwner($acct)
  $key.SetAccessControl($acl)
  $key.Close()
  
  # Grant $acct Full Control on the path.
  $subKeyPath = $_ -replace ('HKCR:\\', '')
  $key = [Microsoft.Win32.Registry]::ClassesRoot.OpenSubKey($subKeyPath,
    [Microsoft.Win32.RegistryKeyPermissionCheck]::ReadWriteSubTree,
    [System.Security.AccessControl.RegistryRights]::ChangePermissions)    
  $acl = $key.GetAccessControl([System.Security.AccessControl.AccessControlSections]::None)
  $rights = [System.Security.AccessControl.RegistryRights]"FullControl"
  $inheritance = [System.Security.AccessControl.InheritanceFlags]"None"
  $propagation = [System.Security.AccessControl.PropagationFlags]"None"
  $type = [System.Security.AccessControl.AccessControlType]"Allow"
  $rule = New-Object System.Security.AccessControl.RegistryAccessRule("$acct","$rights","$inheritance","$propagation","$type")
  $acl.SetAccessRule($rule)
  $key.SetAccessControl($acl)
  $key.Close()
}
Attachments
powershell_script.zip
(2.72 KiB) Downloaded 530 times

Post Reply