Solved

initialize and script activex control marked as unsafe

Posted on 2003-10-27
11
1,366 Views
Last Modified: 2013-11-18
Hi I have aproblem in signing the active component using registry entry method.

Here is the code

#include "stdafx.h"
#include "resource.h"
#include <initguid.h>
#include "SysInfo.h"
#include "helpers.h"
#include "ObjSafe.H"
#include <string>
//#include <ole2.h>
//#include <windows.h>


#include "SysInfo_i.c"
#include "SysData.h"


CComModule _Module;

BEGIN_OBJECT_MAP(ObjectMap)
OBJECT_ENTRY(CLSID_SysData, CSysData)
END_OBJECT_MAP()

/////////////////////////////////////////////////////////////////////////////
// DLL Entry Point

extern "C"
BOOL WINAPI DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID /*lpReserved*/)
{
    if (dwReason == DLL_PROCESS_ATTACH)
    {
        _Module.Init(ObjectMap, hInstance, &LIBID_SYSINFOLib);
        DisableThreadLibraryCalls(hInstance);
    }
    else if (dwReason == DLL_PROCESS_DETACH)
        _Module.Term();
    return TRUE;    // ok
}

/////////////////////////////////////////////////////////////////////////////
// Used to determine whether the DLL can be unloaded by OLE

STDAPI DllCanUnloadNow(void)
{
    return (_Module.GetLockCount()==0) ? S_OK : S_FALSE;
}

/////////////////////////////////////////////////////////////////////////////
// Returns a class factory to create an object of the requested type

STDAPI DllGetClassObject(REFCLSID rclsid, REFIID riid, LPVOID* ppv)
{
    return _Module.GetClassObject(rclsid, riid, ppv);
}

/////////////////////////////////////////////////////////////////////////////
// DllRegisterServer - Adds entries to the system registry

STDAPI DllRegisterServer(void)
{
   
      UUID result;
      
      
      LPOLESTR lpsz=(LPOLESTR)("{49232000-16E4-426C-A231-62846947304B}");

         CLSIDFromString(lpsz, &result);



      HRESULT hr = CreateComponentCategory(CATID_SafeForScripting,
         L"Controls that are safely scriptable");

      if (SUCCEEDED(hr))
         // Only register if category exists.
         RegisterCLSIDInCategory(result, CATID_SafeForScripting);
         // Don't care if this call fails.

      // Mark as safe for data initialization.
      hr = CreateComponentCategory(CATID_SafeForInitializing,
         L"Controls safely initializable from persistent data");

      if (SUCCEEDED(hr))
         // Only register if category exists.
         RegisterCLSIDInCategory(result, CATID_SafeForInitializing);
         // Don't care if this call fails.

    return _Module.RegisterServer(TRUE);

      


      
}

/////////////////////////////////////////////////////////////////////////////
// DllUnregisterServer - Removes entries from the system registry

STDAPI DllUnregisterServer(void)
{
    return _Module.UnregisterServer(TRUE);
}


///////

//helpers.cpp

#include "stdafx.h"

#include "helpers.h"

/////////////////////////////////////////////////////////////////////////////
// CreateComponentCategory - Ensures component category exists in registry
// (Copied from ActiveX SDK docs)

HRESULT CreateComponentCategory(CATID catid, WCHAR* catDescription)
{

    ICatRegister* pcr = NULL ;      // interface pointer
    HRESULT hr = S_OK ;

    hr = CoCreateInstance(CLSID_StdComponentCategoriesMgr,
                  NULL, CLSCTX_INPROC_SERVER, IID_ICatRegister, (void**)&pcr);
      if (FAILED(hr))
            return hr;

    // Make sure the HKCR\Component Categories\{..catid...}
    // key is registered
    CATEGORYINFO catinfo;
    catinfo.catid = catid;
    catinfo.lcid = 0x0409 ; // english

      // Make sure the provided description is not too long.
      // Only copy the first 127 characters if it is
      int len = wcslen(catDescription);
      if (len>127)
            len = 127;
    wcsncpy(catinfo.szDescription, catDescription, len);
      // Make sure the description is null terminated
      catinfo.szDescription[len] = '\0';

    hr = pcr->RegisterCategories(1, &catinfo);
      pcr->Release();

      return hr;
}



/////////////////////////////////////////////////////////////////////////////
// RegisterCLSIDInCategory - Registers class clsid as implementing category catid
// (Copied from ActiveX SDK docs)

HRESULT RegisterCLSIDInCategory(REFCLSID clsid, CATID catid)
{
// Register your component categories information.
    ICatRegister* pcr = NULL ;
    HRESULT hr = S_OK ;
    hr = CoCreateInstance(CLSID_StdComponentCategoriesMgr,
                  NULL, CLSCTX_INPROC_SERVER, IID_ICatRegister, (void**)&pcr);
    if (SUCCEEDED(hr))
    {
       // Register this category as being "implemented" by
       // the class.
       CATID rgcatid[1] ;
       rgcatid[0] = catid;
       hr = pcr->RegisterClassImplCategories(clsid, 1, rgcatid);
    }

    if (pcr != NULL)
        pcr->Release();
 
      return hr;
}

//helpers.h

#include "comcat.h"

HRESULT CreateComponentCategory(CATID catid, WCHAR* catDescription);
HRESULT RegisterCLSIDInCategory(REFCLSID clsid, CATID catid);

I am using the the article publishe in msdn site

The url is

http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnaxctrl/html/msdn_signmark.asp

But I could not made it to work with out browser security setting. I understand I donot have to make browser setting (initialize and script activex control marked as unsafe) to run the active x component. Can anybody pl help me.

Thanks
Abinash

0
Comment
Question by:aparida123
11 Comments
 
LVL 9

Expert Comment

by:_ys_
ID: 9632299
My thought is that this could be failing
>> LPOLESTR lpsz=(LPOLESTR)("{49232000-16E4-426C-A231-62846947304B}");
>> CLSIDFromString(lpsz, &result);

Just use the CLSID you already have, rather than synthesising your own
RegisterCLSIDInCategory(CLSID_SysData, CATID_SafeForScripting);

>> // Don't care if this call fails
You obviously do, and it's causing grief.

Always check the HRESULTs returned. When something fails they make a good starting point for diagnosis

Note that marking it as safe this way, does not include the initial download. That's still unsafe.
0
 

Author Comment

by:aparida123
ID: 9632568
Sorry I could not get you, U mean to say aftre applying registry setting in this code, still I have to do the browser setting for the initialize and script activex control marked as unsafe to run the dll from IE?
0
 

Author Comment

by:aparida123
ID: 9632670
it does not work , to run the dll I have to make the browser setting. Also I tried with

IObjectSafetyImpl'

But it is giving me compiler error

error C2504: 'IObjectSafetyImpl' : base class undefined

My Code is

// SysData.h : Declaration of the CSysData

#ifndef __SYSDATA_H_
#define __SYSDATA_H_

#include "resource.h"       // main symbols
//#include "BrowserInfo.h"
//#include <Atlbase.h>

/////////////////////////////////////////////////////////////////////////////
// CSysData
class ATL_NO_VTABLE CSysData :
      public IObjectSafetyImpl<CSysData, INTERFACESAFE_FOR_UNTRUSTED_CALLER |INTERFACESAFE_FOR_UNTRUSTED_DATA >,
      public CComObjectRootEx<CComSingleThreadModel>,
      public CComCoClass<CSysData, &CLSID_SysData>,
      public IDispatchImpl<ISysData, &IID_ISysData, &LIBID_SYSINFOLib>
      

{
public:
      CSysData()
      {
      }

DECLARE_REGISTRY_RESOURCEID(IDR_SYSDATA)

DECLARE_PROTECT_FINAL_CONSTRUCT()

BEGIN_COM_MAP(CSysData)
      COM_INTERFACE_ENTRY(IObjectSafety)
      COM_INTERFACE_ENTRY(ISysData)
      COM_INTERFACE_ENTRY(IDispatch)
      
END_COM_MAP()

// ISysData

STDMETHOD(GetInterfaceSafetyOptions)(REFIID riid,
                                  DWORD *pdwSupportedOptions,
                                  DWORD *pdwEnabledOptions)
{
ATLTRACE(_T("CObjectSafetyImpl::GetInterfaceSafetyOptions\n"));
if (!pdwSupportedOptions || !pdwEnabledOptions)
   return E_FAIL;
LPUNKNOWN pUnk;
if (_InternalQueryInterface (riid, (void**)&pUnk) == E_NOINTERFACE) {
   // Our object doesn't even support this interface.
   return E_NOINTERFACE;
}else{
   // Cleanup after ourselves.
   pUnk->Release();
   pUnk = NULL;
}
if (riid == IID_IDispatch) {
   // IDispatch is an interface used for scripting. If your
   // control supports other IDispatch or Dual interfaces, you
   // may decide to add them here as well. Client wants to know
   // if object is safe for scripting. Only indicate safe for
   // scripting when the interface is safe.
   *pdwSupportedOptions = INTERFACESAFE_FOR_UNTRUSTED_CALLER;
   *pdwEnabledOptions = m_dwCurrentSafety &
                        INTERFACESAFE_FOR_UNTRUSTED_CALLER;
   return S_OK;
}else if ((riid == IID_IPersistStreamInit) ||
          (riid == IID_IPersistStorage)) {
   // IID_IPersistStreamInit and IID_IPersistStorage are
   // interfaces used for Initialization. If your control
   // supports other Persistence interfaces, you may decide to
   // add them here as well. Client wants to know if object is
   // safe for initializing. Only indicate safe for initializing
   // when the interface is safe.
   *pdwSupportedOptions = INTERFACESAFE_FOR_UNTRUSTED_DATA;
   *pdwEnabledOptions = m_dwCurrentSafety &
                        INTERFACESAFE_FOR_UNTRUSTED_DATA;
   return S_OK;
}else{
   // We are saying that no other interfaces in this control are
   // safe for initializing or scripting.
   *pdwSupportedOptions = 0;
   *pdwEnabledOptions = 0;
   return E_FAIL;
}
}



STDMETHOD(SetInterfaceSafetyOptions)(REFIID riid,
                                  DWORD dwOptionSetMask,
                                  DWORD dwEnabledOptions)
{
ATLTRACE(_T("CObjectSafetyImpl::SetInterfaceSafetyOptions\n"));
if (!dwOptionSetMask && !dwEnabledOptions) return E_FAIL;
LPUNKNOWN pUnk;
if (_InternalQueryInterface (riid, (void**)&pUnk) == E_NOINTERFACE) {
   // Our object doesn't even support this interface.
   return E_NOINTERFACE;
}else{
   // Cleanup after ourselves.
   pUnk->Release();
   pUnk = NULL;
}
// Store our current safety level to return in
// GetInterfaceSafetyOptions
m_dwCurrentSafety |= dwEnabledOptions & dwOptionSetMask;
if ((riid == IID_IDispatch) &&
    (m_dwCurrentSafety & INTERFACESAFE_FOR_UNTRUSTED_CALLER)) {
   // Client wants us to disable any functionality that would
   // make the control unsafe for scripting. The same applies to
   // any other IDispatch or Dual interfaces your control may
   // support. Because our control is safe for scripting by
   // default we just return S_OK.
   return S_OK;
}else if (((riid == IID_IPersistStreamInit) ||
           (riid == IID_IPersistStorage)) &&
          (m_dwCurrentSafety & INTERFACESAFE_FOR_UNTRUSTED_DATA)) {
   // Client wants us to make the control safe for initializing
   // from persistent data. For these interfaces, this control
   // is safe so we return S_OK. For Any interfaces that are not
   // safe, we would return E_FAIL.
   return S_OK;
}else{
   // This control doesn't allow Initialization or Scripting
   // from any other interfaces so return E_FAIL.
   return E_FAIL;
}
}




public:
      STDMETHOD(GetData)(/*[out]*/ BSTR* ReturnVal);
};

#endif //__SYSDATA_H_
0
Live: Real-Time Solutions, Start Here

Receive instant 1:1 support from technology experts, using our real-time conversation and whiteboard interface. Your first 5 minutes are always free.

 
LVL 9

Expert Comment

by:_ys_
ID: 9632679
>> still I have to do the browser setting ...
Nope.

When the user first connect to the page, the control wil have to be downloaded and installed on the local system. This part will still prompt the user - but once only. After downloaded and installed they'll not see any more messages, reagrdless of the browser settings.

Unless you're willing to digitally sign your control, this cannot be avoided - without reverting to altering the browser settings.
0
 

Author Comment

by:aparida123
ID: 9632736
I solved the error in IObjectSafetyImpl and no I ma trying with it.
You mean to say my browser setting for the initialize and script activex control marked as unsafe should always be kept as enable for the first time even if I implement the registry methor or IObjectSafetyImpl interface?
0
 

Author Comment

by:aparida123
ID: 9632744
I am signing the control, But I donot want user to change their default setting for the IE to run the Activex dll.
0
 
LVL 9

Expert Comment

by:_ys_
ID: 9632817
The default 'medium' setting will allow what you want top do - it will still prompt the user to accept the download though (but this is once only - the initial download).

After download and installation, all things will work as expected.
0
 

Author Comment

by:aparida123
ID: 9632821
I think I solved the problem by implemeting IObjectsafety.
0
 
LVL 9

Expert Comment

by:_ys_
ID: 9632911
It's generally either registry entry or IObjectSafety method. Never seen a situation where one succeeds whilst the other fails.
0
 
LVL 9

Expert Comment

by:tinchos
ID: 10546224
No comment has been added lately, so it's time to clean up this question.
I will leave the following recommendation for this question in the Cleanup topic area:

PAQ with points refunded

Please leave any comments here within the next four days.
PLEASE DO NOT ACCEPT THIS COMMENT AS AN ANSWER!

Tinchos
EE Cleanup Volunteer
0
 

Accepted Solution

by:
ee_ai_construct earned 0 total points
ID: 10586135
PAQed, with points refunded (500)

ee_ai_construct
Community Support Moderator
0

Featured Post

Gigs: Get Your Project Delivered by an Expert

Select from freelancers specializing in everything from database administration to programming, who have proven themselves as experts in their field. Hire the best, collaborate easily, pay securely and get projects done right.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Article by: SunnyDark
This article's goal is to present you with an easy to use XML wrapper for C++ and also present some interesting techniques that you might use with MS C++. The reason I built this class is to ease the pain of using XML files with C++, since there is…
C++ Properties One feature missing from standard C++ that you will find in many other Object Oriented Programming languages is something called a Property (http://www.experts-exchange.com/Programming/Languages/CPP/A_3912-Object-Properties-in-C.ht…
The purpose of this video is to demonstrate how to set up the WordPress backend so that each page automatically generates a Mailchimp signup form in the sidebar. This will be demonstrated using a Windows 8 PC. Tools Used are Photoshop, Awesome…
The goal of the tutorial is to teach the user how to use functions in C++. The video will cover how to define functions, how to call functions and how to create functions prototypes. Microsoft Visual C++ 2010 Express will be used as a text editor an…

776 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