Sunday, August 16, 2009

Marking ActiveX Controls as Safe

What is ActiveX Controls?
A control using ActiveX technologies. An ActiveX control can be automatically downloaded and executed by a Web browser. ActiveX is not a programming language, but rather a set of rules for how applications should share information. Programmers can develop ActiveX controls in a variety of languages, including C, C++, Visual Basic, and Java.

Creating a Simple COM Component
Lets create a simple com component that will extract existing DSN of client system using .NET.
1. Create a File->New->Project->ClassLibrary Project. Name it DSNComComponent.
2. A default class "Class1.vb" is added to your project file. Here in this project we are not using this class so its better to delete.
3. Add a Com Class to your project. Name it DSNComponent. Paste following code


_
Public Class DSNComponent
#Region "COM GUIDs"
' These GUIDs provide the COM identity for this class
' and its COM interfaces. If you change them, existing
' clients will no longer be able to access the class.
Public Const ClassId As String = "5162d4b1-7440-4fa3-b47f-12906475728b"
Public Const InterfaceId As String = "22dd7975-2554-4d49-bc82-b54ef0d2409f"
Public Const EventsId As String = "eb56f021-5c97-4e71-a2de-67d6acd2f703"
#End Region
' A creatable COM class must have a Public Sub New()
' with no parameters, otherwise, the class will not be
' registered in the COM registry and cannot be created
' via CreateObject.
Public Sub New()
MyBase.New()
End Sub
Public Function GetDSNLists() As String
Return OdbcHelper.GetDSNLists()
End Function
End Class


4. Add module to your project. Name it OdbcHelper. Paste following code

#Region "Imports"
Imports System.Text
Imports System
Imports System.Runtime.InteropServices
#End Region
Module OdbcHelper
#Region "Variable Declaration"
Private Const SQL_HANDLE_ENV As Short = 1
Private Const SQL_SUCCESS As Short = 0
Private Const DEFAULT_RESULT_SIZE As Short = 1024
Private Const SQL_FETCH_NEXT As UShort = 1
Private Const SQL_MAX_DSN_LENGTH As Short = 1024
Private Const SQL_ATTR_ODBC_VERSION As Integer = 200
Private Const SQL_OV_ODBC3 As Integer = 3
Private Const SQL_HANDLE_CON As Short = 2
Private Hwnd As IntPtr
#End Region
#Region "API Calls / Declarations"
_
Private Function SQLDataSources( _
ByVal henv As System.IntPtr, ByVal fDirection As UShort, _
ByVal szDSN As StringBuilder, ByVal cbDSNMax As Short, _
ByRef pcbDSN As Short, ByVal szDescription As StringBuilder, _
ByVal cbDescriptionMax As Short, ByRef pcbDescription As Short _
) As Short
End Function
_
Private Function SQLAllocHandle(ByVal hType As Short, ByVal inputHandle As IntPtr, ByRef outputHandle As IntPtr) As Short
End Function
_
Private Function SQLSetEnvAttr(ByVal henv As IntPtr, ByVal attribute As Integer, ByVal valuePtr As IntPtr, ByVal strLength As Integer) As Short
End Function
_
Private Function SQLFreeHandle(ByVal inStringLength As Short, ByVal hconn As IntPtr) As Short
End Function
#End Region
#Region "API Method Invoke"
Friend Function GetDSNLists() As String
Dim nRc = 0
Dim txt As String = String.Empty
Dim henv As IntPtr = IntPtr.Zero
Dim hconn As IntPtr = IntPtr.Zero
Dim nDSNLen As Short
Dim inString As StringBuilder = New StringBuilder(1024)
Dim outString As StringBuilder = New StringBuilder(1024)
Dim lenNeeded As Short
Dim Inc As Integer = 0
Try
If SQL_SUCCESS = SQLAllocHandle(SQL_HANDLE_ENV, henv, henv) Then
If SQL_SUCCESS = SQLSetEnvAttr(henv, SQL_ATTR_ODBC_VERSION, CType(SQL_OV_ODBC3, IntPtr), 0) Then
Do Until nRc <> SQL_SUCCESS
nRc = SQLDataSources(henv, SQL_FETCH_NEXT, inString, SQL_MAX_DSN_LENGTH, nDSNLen, outString, SQL_MAX_DSN_LENGTH, lenNeeded)
If nRc <> SQL_SUCCESS Then
Exit Do
End If
If Inc = 0 Then
txt = inString.ToString()
Else
txt = txt & "," & inString.ToString()
End If
Inc += 1
Loop
End If
End If
Catch ex As Exception
MsgBox(ex.Message)
txt = String.Empty
Finally
If Not (henv = IntPtr.Zero) Then
SQLFreeHandle(SQL_HANDLE_ENV, hconn)
End If
End Try
Return txt
End Function
#End Region
End Module


5. Compile your code. A file DSNComComponent.dll should be created in your bin directory.

Using COM Component on HTML Page
1. Create an empty HTML page. Add following code in your HTML file.


2. Open this html page in browser. You would be receiving an Error: Automation server can't create object.

3. Search Key HKEY_CLASSES_ROOT\CLSID\{5162D4B1-7440-4FA3-B47F-12906475728B} in your registry using regedit. Note that each COM component created in .NET application has different key value. This key value is available in your COM Class DSNComponent.vb.

4. Add two keys within {5162D4B1-7440-4FA3-B47F-12906475728B}
[HKEY_CLASSES_ROOT\CLSID\{5162D4B1-7440-4FA3-B47F-12906475728B}\Implemented Categories\{7DD95801-9882-11CF-9FA9-00AA006C42C4}]
[HKEY_CLASSES_ROOT\CLSID\{5162D4B1-7440-4FA3-B47F-12906475728B}\Implemented Categories\{7DD95802-9882-11CF-9FA9-00AA006C42C4}]
Key 7DD95801-9882-11CF-9FA9-00AA006C42C4 is used to mark controls that are safely scriptable.
Key 7DD95802-9882-11CF-9FA9-00AA006C42C4 is used to mark controls safely initializable from persistent data.



5. Browse your web page. Now DSN list would appear on your window.



Note: Don't use this method unless you have no other choice, and never use this method to mark as safe controls that aren't really safe.

No comments:

Post a Comment