IObjectSafety

K

Ken

First, Thanks for helping.

I have implemented IObjectSafety as outlined in "Microsoft Knowledge
Base Article - 182598". However, I can not get InfoPath SP1 (rtm) to
load the control.

InfoPath complaines that is is not safe for scripting. I am having to
manually, enter the guids in "implemented categories" --- Messy.

Has anyone else found that IObjectSafety as described in the KB
article mentioned above is flakey?

Thanks,

KenS
 
S

Scott Roberts [MSFT]

Hi Ken,

Using IObjectSafety should work. It's possible that there is an issue with
the article. Can you post your code that implements IObjectSafety so I can
double check that everything is correct? If you are able to post your
control or at least a scaled down version of it, I can try to determine why
this isn't working for you.

Thanks,
Scott
 
K

Ken

Thanks for replying Scott.

I figured I'd get a VB 6 control working first before I experimented
with one in C# using interop.

Below is the IObjectSafety code:

I altered the Iff to if...then and even removed the error return in an
attempt to have it recognize it as safe for initializaiton and
scripting.



============== global constants and declares in a module file
Option Explicit

Public Const IID_IDispatch =
"{00020400-0000-0000-C000-000000000046}"
Public Const IID_IPersistStorage = _
"{0000010A-0000-0000-C000-000000000046}"
Public Const IID_IPersistStream = _
"{00000109-0000-0000-C000-000000000046}"
Public Const IID_IPersistPropertyBag = _
"{37D84F60-42CB-11CE-8135-00AA004BB851}"

Public Const INTERFACESAFE_FOR_UNTRUSTED_CALLER = &H1
Public Const INTERFACESAFE_FOR_UNTRUSTED_DATA = &H2
Public Const E_NOINTERFACE = &H80004002
Public Const E_FAIL = &H80004005
Public Const MAX_GUIDLEN = 40

Public Declare Sub CopyMemory Lib "kernel32" Alias
"RtlMoveMemory" _
(pDest As Any, pSource As Any, ByVal ByteLen As Long)
Public Declare Function StringFromGUID2 Lib "ole32.dll" (rguid
As _
Any, ByVal lpstrClsId As Long, ByVal cbMax As Integer) As
Long

Public Type udtGUID
Data1 As Long
Data2 As Integer
Data3 As Integer
Data4(7) As Byte
End Type

Public m_fSafeForScripting As Boolean
Public m_fSafeForInitializing As Boolean

Sub Main()
m_fSafeForScripting = True
m_fSafeForInitializing = True
End Sub





=================== non - global code =======================

Implements IObjectSafety
..... other code in here

'=============== implement the IObjectSafety interface
Private Sub IObjectSafety_GetInterfaceSafetyOptions(ByVal riid As _
Long, pdwSupportedOptions As Long, pdwEnabledOptions As Long)

Dim Rc As Long
Dim rClsId As udtGUID
Dim IID As String
Dim bIID() As Byte

pdwSupportedOptions = INTERFACESAFE_FOR_UNTRUSTED_CALLER Or _
INTERFACESAFE_FOR_UNTRUSTED_DATA

If (riid <> 0) Then
CopyMemory rClsId, ByVal riid, Len(rClsId)

bIID = String$(MAX_GUIDLEN, 0)
Rc = StringFromGUID2(rClsId, VarPtr(bIID(0)), MAX_GUIDLEN)
Rc = InStr(1, bIID, vbNullChar) - 1
IID = Left$(UCase(bIID), Rc)
' pdwEnabledOptions = INTERFACESAFE_FOR_UNTRUSTED_CALLER Or _
' INTERFACESAFE_FOR_UNTRUSTED_DATA
'Exit Sub
Select Case IID
Case IID_IDispatch
If m_fSafeForScripting = True Then
pdwEnabledOptions =
INTERFACESAFE_FOR_UNTRUSTED_CALLER
Else
pdwEnabledOptions = 0
End If
Exit Sub
Case IID_IPersistStorage, IID_IPersistStream, _
IID_IPersistPropertyBag
If m_fSafeForInitializing = True Then

pdwEnabledOptions = INTERFACESAFE_FOR_UNTRUSTED_DATA
Else
pdwEnabledOptions = 0
End If

Exit Sub
Case Else
' Err.Raise E_NOINTERFACE
Exit Sub
End Select
End If
End Sub

Private Sub IObjectSafety_SetInterfaceSafetyOptions(ByVal riid As _
Long, ByVal dwOptionsSetMask As Long, ByVal dwEnabledOptions As Long)
Dim Rc As Long
Dim rClsId As udtGUID
Dim IID As String
Dim bIID() As Byte

If (riid <> 0) Then
CopyMemory rClsId, ByVal riid, Len(rClsId)

bIID = String$(MAX_GUIDLEN, 0)
Rc = StringFromGUID2(rClsId, VarPtr(bIID(0)), MAX_GUIDLEN)
Rc = InStr(1, bIID, vbNullChar) - 1
IID = Left$(UCase(bIID), Rc)

Select Case IID
Case IID_IDispatch
If ((dwEnabledOptions And dwOptionsSetMask) <> _
INTERFACESAFE_FOR_UNTRUSTED_CALLER) Then
Err.Raise E_FAIL
Exit Sub
Else
If Not m_fSafeForScripting Then
Err.Raise E_FAIL
End If
Exit Sub
End If

Case IID_IPersistStorage, IID_IPersistStream, _
IID_IPersistPropertyBag
If ((dwEnabledOptions And dwOptionsSetMask) <> _
INTERFACESAFE_FOR_UNTRUSTED_DATA) Then
Err.Raise E_FAIL
Exit Sub
Else
If Not m_fSafeForInitializing Then
Err.Raise E_FAIL
End If
Exit Sub
End If

Case Else
'Err.Raise E_NOINTERFACE
Exit Sub
End Select
End If
End Sub
 
S

Scott Roberts [MSFT]

Hi Ken,

I or somebody on my team will take a look at this and get back to you.

- Scott
 
A

Andrew Ma

So there are a bunch of little gotchas that I remember hitting when I wrote
VB controls.

First, make sure you have a modules file which has all the constants and the
Sub Main.
Also, check to make sure you change the project properties so that the
startup object is Sub Main.

Andrew.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top