Solved

initialize and script activex control marked as unsafe

Posted on 2003-10-27
11
1,368 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
Industry Leaders: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 
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

Free Tool: Port Scanner

Check which ports are open to the outside world. Helps make sure that your firewall rules are working as intended.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

Question has a verified solution.

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

Suggested Solutions

Title # Comments Views Activity
Quicksort a dynamic deque 33 79
Would like to move button in a function 3 83
Dynamically allocate memory 9 70
Need some help with Microsoft Visual Studio C++ 2003 5 71
What is C++ STL?: STL stands for Standard Template Library and is a part of standard C++ libraries. It contains many useful data structures (containers) and algorithms, which can spare you a lot of the time. Today we will look at the STL Vector. …
  Included as part of the C++ Standard Template Library (STL) is a collection of generic containers. Each of these containers serves a different purpose and has different pros and cons. It is often difficult to decide which container to use and …
The viewer will learn how to pass data into a function in C++. This is one step further in using functions. Instead of only printing text onto the console, the function will be able to perform calculations with argumentents given by the user.
The viewer will learn how to clear a vector as well as how to detect empty vectors in C++.

685 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