Solved

Reading and Writing Registry Key in 64 bit or 32 bit OS to force webbrowser control to IE9

Posted on 2013-11-17
9
3,576 Views
Last Modified: 2013-11-19
Hello,

Google maps recently forced the site to use greater than IE7 standards making the webbrowser control (WB) not work with their website.  The best solution seems to be modifying the registry to force the WB to use IE9 or 10 standards.  I'm trying to modify my code so that the user machine on all profiles will use the IE 9 standard.  I'd like to check if the following registry value is present and add it if it isn't in both 32 bit and 64 bit systems.  I'm having trouble however and the junk code is my attempts so far.

Value to be added to wow64 OR 32 bit registry:

32 bit:


HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Internet Explorer\MAIN\FeatureControl\FEATURE_BROWSER_EMULATION

Value Key: yourapplication.exe
Type: Reg_DWORD
Value: 9999 (decimal)

64 bit:


HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\Internet Explorer\MAIN\FeatureControl\FEATURE_BROWSER_EMULATION

Value Key: yourapplication.exe
Type: Reg_DWORD
Value: 9999 (decimal)

as suggested by this nice person:

http://www.west-wind.com/weblog/posts/2011/May/21/Web-Browser-Control-Specifying-the-IE-Version

Thanks for any help you can give




 Try

            Dim RK As RegistryKey = RegistryKey.openbasekey(RegistryHive.LocalMachine, registryview.registry64)


            Dim key As RegistryKey = Registry.LocalMachine.OpenSubKey("HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\Internet Explorer\MAIN\FeatureControl\FEATURE_BROWSER_EMULATION", True)
            Dim val As String()
            val = key.GetValueNames()
            key.SetValue("MYPROGRAM.EXE", "9999", RegistryValueKind.[String])
            key.Close()


            '  HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\Internet Explorer\MAIN\FeatureControl\FEATURE_BROWSER_EMULATION

            ' [HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_BROWSER_EMULATION]"YOURPROGRAM.EXE"=dword:00002328
            'If Microsoft.Win32.Registry.LocalMachine.OpenSubKey("HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Internet Explorer\MAIN\FeatureControl\FEATURE_BROWSER_EMULATION") Is Nothing Then
            '    ' Key doesn't exist
            '    MsgBox("Key doesn't exist")
            '    Microsoft.Win32.Registry.LocalMachine.CreateSubKey("HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Internet Explorer\MAIN\FeatureControl\FEATURE_BROWSER_EMULATION")
            '    Microsoft.Win32.Registry.LocalMachine.SetValue("HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Internet Explorer\MAIN\FeatureControl\FEATURE_BROWSER_EMULATION", "9999")
            'Else
            '    ' Key existed
            'End If
        Catch ex As Exception

        End Try

Open in new window

0
Comment
Question by:zipnotic
  • 5
  • 2
  • 2
9 Comments
 

Author Comment

by:zipnotic
ID: 39656347
Still trying to figure this out.  Any help would be appreciated.  

If it means anything, VS 2010 is set to compile to x86.  It doesn't give me any other option.


Also tried the simpler

            '  My.Computer.Registry.SetValue("HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Internet Explorer\MAIN\FeatureControl\FEATURE_BROWSER_EMULATION", "TestValue", "This is a test value.")

but it resulted in a null object exception

Having a bit more success with:

            Registry.LocalMachine.SetValue("HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Internet Explorer\MAIN\FeatureControl\FEATURE_BROWSER_EMULATION", "TestValue", RegistryValueKind.String)

 ' RegistryKeyPermissionCheck.ReadWriteSubTree, Security.AccessControl.RegistryRights.WriteKey)

But that gives me permission denied exception (that's the closest I came so far to adding the key I need to).

The following only gives me "nothing" in the instances....




 Try

            Dim instance As RegistryKey = Registry.CurrentUser.OpenSubKey("HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Internet Explorer\MAIN\FeatureControl\FEATURE_BROWSER_EMULATION", RegistryKeyPermissionCheck.ReadWriteSubTree, Security.AccessControl.RegistryRights.WriteKey)
            Dim instance2 As RegistryKey = Registry.CurrentUser.OpenSubKey("HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\Internet Explorer\MAIN\FeatureControl\FEATURE_BROWSER_EMULATION", RegistryKeyPermissionCheck.ReadWriteSubTree, Security.AccessControl.RegistryRights.WriteKey)
            Dim instance3 As RegistryKey = Registry.LocalMachine.CreateSubKey("HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Internet Explorer\MAIN\FeatureControl\FEATURE_BROWSER_EMULATION", RegistryKeyPermissionCheck.ReadWriteSubTree)
            Dim name As String
            Dim value As Object
            Dim valueKind As RegistryValueKind

            name = "NEW TEST SUBKEY.EXE"
            value = "9999"
            valueKind = RegistryValueKind.DWord


            instance.SetValue(name, value, valueKind)

Open in new window

0
 

Author Comment

by:zipnotic
ID: 39656562
I'm reading about permissions in Windows 7, is that the problem when writing to Local Machine?  Something about adding something to the manifest?
0
 
LVL 96

Expert Comment

by:Bob Learned
ID: 39656602
Yes, Windows 7 security limits access by default, unless you elevate privileges to administrator level.

Create and Embed an Application Manifest (UAC)
http://msdn.microsoft.com/en-us/library/bb756929.aspx
0
 

Author Comment

by:zipnotic
ID: 39656622
Looks like I have some reading to do.

Can you advise the best practice code (even just aircode) to ultimately write the following to the registry when the target machine may be

32 or 64
Win 7 or Win XP or Win 8
Users have no admin rights


HKEY_LOCAL_MACHINE (or HKEY_CURRENT_USER)
   SOFTWARE
      Microsoft
         Internet Explorer
            Main
               FeatureControl
                  FEATURE_BROWSER_EMULATION
                     MYAPPLICATIONNAME.exe = (DWORD) 00009000
0
Top 6 Sources for Identifying Threat Actor TTPs

Understanding your enemy is essential. These six sources will help you identify the most popular threat actor tactics, techniques, and procedures (TTPs).

 
LVL 96

Assisted Solution

by:Bob Learned
Bob Learned earned 250 total points
ID: 39657208
If the user doesn't have admin rights, then you can impersonate an admin user.

WindowsIdentity.Impersonate Method
http://msdn.microsoft.com/en-us/library/w070t6ka(v=vs.110).aspx

' This sample demonstrates the use of the WindowsIdentity class to impersonate a user. 
' IMPORTANT NOTES:  
' This sample requests the user to enter a password on the console screen. 
' Because the console window does not support methods allowing the password to be masked, 
' it will be visible to anyone viewing the screen. 
' On Windows Vista and later this sample must be run as an administrator.  

Imports System
Imports System.Runtime.InteropServices
Imports System.Security.Principal
Imports System.Security.Permissions
Imports Microsoft.VisualBasic
Imports Microsoft.Win32.SafeHandles
Imports System.Runtime.ConstrainedExecution
Imports System.Security

Module Module1

    Public Class ImpersonationDemo

        'Private Declare Auto Function LogonUser Lib "advapi32.dll" (ByVal lpszUsername As [String], _ 
        '    ByVal lpszDomain As [String], ByVal lpszPassword As [String], _ 
        '    ByVal dwLogonType As Integer, ByVal dwLogonProvider As Integer, _ 
        '    ByRef phToken As IntPtr) As Boolean 

        Private Declare Auto Function LogonUser Lib "advapi32.dll" (ByVal lpszUsername As [String], _
            ByVal lpszDomain As [String], ByVal lpszPassword As [String], _
            ByVal dwLogonType As Integer, ByVal dwLogonProvider As Integer, _
            <Out()> ByRef phToken As SafeTokenHandle) As Boolean 

        Public Declare Auto Function CloseHandle Lib "kernel32.dll" (ByVal handle As IntPtr) As Boolean 

        ' Test harness. 
        ' If you incorporate this code into a DLL, be sure to demand FullTrust.
        <PermissionSetAttribute(SecurityAction.Demand, Name:="FullTrust")> _
        Public Overloads Shared Sub Main(ByVal args() As String)
            Dim safeTokenHandle As SafeTokenHandle = Nothing 
            Dim tokenHandle As New IntPtr(0)
            Try 


                Dim userName, domainName As String 

                ' Get the user token for the specified user, domain, and password using the  
                ' unmanaged LogonUser method.   
                ' The local machine name can be used for the domain name to impersonate a user on this machine.
                Console.Write("Enter the name of a domain on which to log on: ")
                domainName = Console.ReadLine()

                Console.Write("Enter the login of a user on {0} that you wish to impersonate: ", domainName)
                userName = Console.ReadLine()

                Console.Write("Enter the password for {0}: ", userName)

                Const LOGON32_PROVIDER_DEFAULT As Integer = 0
                'This parameter causes LogonUser to create a primary token. 
                Const LOGON32_LOGON_INTERACTIVE As Integer = 2

                ' Call LogonUser to obtain a handle to an access token. 
                Dim returnValue As Boolean = LogonUser(userName, domainName, Console.ReadLine(), LOGON32_LOGON_INTERACTIVE, LOGON32_PROVIDER_DEFAULT, safeTokenHandle)

                Console.WriteLine("LogonUser called.")

                If False = returnValue Then 
                    Dim ret As Integer = Marshal.GetLastWin32Error()
                    Console.WriteLine("LogonUser failed with error code : {0}", ret)
                    Throw New System.ComponentModel.Win32Exception(ret)

                    Return 
                End If 
                Using safeTokenHandle
                    Dim success As String 
                    If returnValue Then success = "Yes" Else success = "No"
                    Console.WriteLine(("Did LogonUser succeed? " + success))
                    Console.WriteLine(("Value of Windows NT token: " + safeTokenHandle.DangerousGetHandle().ToString()))

                    ' Check the identity.
                    Console.WriteLine(("Before impersonation: " + WindowsIdentity.GetCurrent().Name))

                    ' Use the token handle returned by LogonUser. 
                    Using newId As New WindowsIdentity(safeTokenHandle.DangerousGetHandle())
                        Using impersonatedUser As WindowsImpersonationContext = newId.Impersonate()

                            ' Check the identity.
                            Console.WriteLine(("After impersonation: " + WindowsIdentity.GetCurrent().Name))

                            ' Free the tokens. 
                        End Using 
                    End Using 
                End Using 
            Catch ex As Exception
                Console.WriteLine(("Exception occurred. " + ex.Message))
            End Try 
        End Sub 'Main 
    End Class 'Class1
End Module 

Public NotInheritable Class SafeTokenHandle
    Inherits SafeHandleZeroOrMinusOneIsInvalid

    Private Sub New()
        MyBase.New(True)

    End Sub 'New 

    Private Declare Auto Function LogonUser Lib "advapi32.dll" (ByVal lpszUsername As [String], _
            ByVal lpszDomain As [String], ByVal lpszPassword As [String], _
            ByVal dwLogonType As Integer, ByVal dwLogonProvider As Integer, _
            ByRef phToken As IntPtr) As Boolean
    <DllImport("kernel32.dll"), ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success), SuppressUnmanagedCodeSecurity()> _
    Private Shared Function CloseHandle(ByVal handle As IntPtr) As <MarshalAs(UnmanagedType.Bool)> Boolean 

    End Function 
    Protected Overrides Function ReleaseHandle() As Boolean 
        Return CloseHandle(handle)

    End Function 'ReleaseHandle
End Class 'SafeTokenHandle

Open in new window

0
 
LVL 32

Expert Comment

by:sarabande
ID: 39657248
to add to above comments:

if HKEY_CURRENT_USER would be an alternative, you should do it with that.

alternatively, you may think of a setup for your program that runs in admin mode and writes the entry to the registry.

Sara
0
 

Author Comment

by:zipnotic
ID: 39658061
So far, writing to the CURRENT_USER seems cleaner.  From what I understand the "registry director" will send the following entry to the right node automatically?  I tried it on a win 7 64 bit machine and an XP 32 bit machine and so far so good but will there be any deployment problems I should anticipate?  If not then this 'workaround' solution is a lot easier then I made it out to be...

The SetValue does nothing if the entry is already there, this is good.
The process is seamless to the user, this is good.
The webbrowser behaves, this is good.
The project is compiled for x86 while anyCPU breaks it, this is not so good, but tolerable.

Try
            Dim instance3 As RegistryKey = Registry.CurrentUser.CreateSubKey("SOFTWARE\Microsoft\Internet Explorer\MAIN\FeatureControl\FEATURE_BROWSER_EMULATION", RegistryKeyPermissionCheck.ReadWriteSubTree)
            instance3.SetValue(Application.ExecutablePath.ToString(), 9999, RegistryValueKind.DWord)
            instance3.SetValue("IconicResolution.vshost.exe", 9999, RegistryValueKind.DWord) 'TODO Remove this line
            instance3.Close()
Catch ex as exception
End Try
0
 
LVL 32

Accepted Solution

by:
sarabande earned 250 total points
ID: 39659571
From what I understand the "registry director" will send the following entry to the right node automatically?

yes, the windows operation would translate the Registry.CurrentUser of your 32-bit program always to HKEY_CURRENT_USER of the 32-bit registry.

a 32-bit program cannot access the 64-bit and a 64-bit program would ignore the 32-bit part of registry.

so your programs would write and read to/from the right node.

Sara
0
 

Author Closing Comment

by:zipnotic
ID: 39659803
Thank you both.  Learned's would probably work but Sara's is quicker and direct.
0

Featured Post

Enabling OSINT in Activity Based Intelligence

Activity based intelligence (ABI) requires access to all available sources of data. Recorded Future allows analysts to observe structured data on the open, deep, and dark web.

Join & Write a Comment

Suggested Solutions

Title # Comments Views Activity
How do I get the unique ID after insert? 87 92
Wpf develop 5 35
Get String split 5 33
Birthdays 3 21
Calculating holidays and working days is a function that is often needed yet it is not one found within the Framework. This article presents one approach to building a working-day calculator for use in .NET.
If you need to start windows update installation remotely or as a scheduled task you will find this very helpful.
This video gives you a great overview about bandwidth monitoring with SNMP and WMI with our network monitoring solution PRTG Network Monitor (https://www.paessler.com/prtg). If you're looking for how to monitor bandwidth using netflow or packet s…
In this tutorial you'll learn about bandwidth monitoring with flows and packet sniffing with our network monitoring solution PRTG Network Monitor (https://www.paessler.com/prtg). If you're interested in additional methods for monitoring bandwidt…

762 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

20 Experts available now in Live!

Get 1:1 Help Now