|
Hi,
I want to redirect JavaScript functions (such as alert, open etc) calls to be redirected to my code written in C++. I launch IE from my application that implements an event sink to listen to various events by IE.
- I have inherited a class from IDispatch and implemented only Invoke that handles DISPID_VALUE.
- The next thing i did is call Invoke using my class dispatch pointer with DISPID_VALUE.
- After that i get dispid to the function (say alert()) in global scripting object whose call i want to redirect to my class.
- Using this dispid as the parameter, i call Invoke with global scripting object retrieved from get_Script().
- Doing so gives me error DISP_E_BADVARTYPE (bad variable type).
Following is the code:
//==============================
CComObject<cmycomobj> *pObj = NULL;
DISPPARAMS dispparams, dispparamsNoArgs = {NULL, NULL, 0, 0};
VARIANT var;
dispparams.rgvarg=NULL;
dispparams.rgdispidNamedArgs=NULL;
dispparams.cArgs=0;
dispparams.cNamedArgs=0;
//Create my class object.
pObj->CreateInstance(&pObj);
pObj->QueryInterface(IID_IUnknown, (void **) &punkTemp);
hr = punkTemp->QueryInterface(IID_IDispatch, (void **) &pDispMyObj);
//Call invoke to get the required info from parameters passed.
hr = pDispMyObj->Invoke(DISPID_VALUE, IID_NULL, LOCALE_USER_DEFAULT, DISPATCH_PROPERTYGET,
&dispparams, &var, NULL, NULL);
//Get global scripting object DispatchEx pointer
m_spInetExplorer-&get_Document(&pDisp);
pDisp->QueryInterface(IID_IHTMLDocument2, (void **) &pHTMLDocument2);
pHTMLDocument2->get_Script(&pDispSE);
pDispSE->QueryInterface(IID_IDispatchEx, (void **) &DispExSE);
//Set arguments that will be sent with the invoke call below.
DISPID putid = DISPID_PROPERTYPUT;
dispparams.rgvarg = &var;
dispparams.rgdispidNamedArgs = &putid;
dispparams.cArgs = 1;
dispparams.cNamedArgs = 1;
BSTR strOpen = SysAllocString(OLESTR("alert"));
DISPID dispIDAlert;
//Get dispid of the function that is to be hooked in this case alert().
hr = pDispExSE->GetDispID(strOpen, fdexNameEnsure, &dispIDAlert);
//Here it returns the error DISP_E_BADVARTYPE.
//Call invoke with DISPATCH_PROPERTYPUT to install hooks.
hr = pDispExSE->InvokeEx(dispIDAlert, LOCALE_USER_DEFAULT, DISPATCH_PROPERTYPUT, &dispparams,
NULL, NULL, NULL);
//==============================
Please let me know if such a thing is possible. If so then is this the right way to achieve this? What am i doing wrong here?
Thanks for your help.
|
|
|
|
|
I have made some progress in hooking the global scripting engine. When a call to a JS function such as alert, open etc (or which ever function i have hooked) is made then call first lands at my c++ code. Currently there are some stability issues and i am looking into their possible resolutions. I will keep on updating this thread until the issue is resolved (or someone help me resolve it which BTW seems highly unlikely at this forum). This would be helpful for those who want to do a similar thing and dont know where to start.
|
|
|
|
|
Please post the code you already have. I am very interested in this and would be able to test it in my app.
Chris.
|
|
|
|
|
I have a WMI provider, which will be extending the Win32_DiskDrive class. My WMI class name is "TL_PhysicalDisk" in namespace "TLV2", at the time of enumerating the instances I am trying to enumerate the Win32_DiskDrive, for this I am doing following:
a) Creating a CWbemLocator object
b) Connecting to "root\CIMV2" namespace and getting the CWbemServices object
Problem: I am not getting the enumeration of Win32_DiskDrive inside my provider, though I can see the list in WMI Object Browser.
Is there something else which needs to be done for accessing a different namespace than that of WMI Proivder from inside the provider?
|
|
|
|
|
Without looking at relavant portions of your source code, we will be guessing at solutions to your problem. Where does your code fail?
By the way, I just read through your previous post and the suggestions of Stuart Dootson. I've read most of his posts, and he is a much more knowledgable programmer than I am.
...so, I hope he leaps in.
|
|
|
|
|
In my code for WMI Provider, I am trying access a different namespace. My current namespace is "TLV2" and I need to read the disk values from "CIMV2". The method Next() of object IEnumWbemClassObject returns me an WBEM_E_ACCESS_DENIED.
Both the providers hosting model is same "NetworkServiceHost", within my provider source I am initialzing WMI for calls to "CIMV2". I figure this is something to do with the impersonation or security, though the hosting models are same but the windows processes are different. The code for initializing WMI is as follows;
bool CWMI::InitializeWMI(IWbemContext *pCtx)
{
HRESULT hr;
IsConnected = false;
hr = CoCreateInstance(CLSID_WbemLocator, 0, CLSCTX_INPROC_SERVER, IID_IWbemLocator, (LPVOID *) &WbemLocator);
if (FAILED(hr)) {
CoUninitialize();
}
else{
if(SUCCEEDED(hr) && WbemLocator != NULL){
hr = WbemLocator->ConnectServer( BSTR(L"root\\cimv2"), NULL, NULL, 0, NULL, 0,pCtx, &WbemServices);
if (FAILED(hr)){
WbemLocator->Release();
CoUninitialize();
}
else{
if(SUCCEEDED(hr))
{
hr = CoSetProxyBlanket(WbemServices, RPC_C_AUTHN_WINNT, RPC_C_AUTHZ_NONE,NULL, RPC_C_AUTHN_LEVEL_CALL, RPC_C_IMP_LEVEL_IMPERSONATE, NULL, EOAC_NONE);
if (FAILED(hr)) {
WbemServices->Release();
WbemLocator->Release();
CoUninitialize();
}
else{
IsConnected = true;
}
}
}
}
}
return(IsConnected);
}
|
|
|
|
|
You know, I've read through Don Box's section on COM security in "Essential COM" numerous times,...and, I'm embarrassed to admit it, but, it still confuses the hell out of me.
...But, you should probably read this over at MSDN: Impersonating a Client[^], especially the section entitled, Handling Access Denied Messages in a Provider[^].
I noticed you don't call CoInitializeSecurity[^].
What you need to do is query the security settings, and since WMI runs as an out of process server, I'm thinking the appropriate function would be: CoQueryProxyBlanket[^]. There are several COM interfaces available specifically for this purpose (see end of this post). But, honestly, I'm not sure and I don't have Don Box's "Essential COM" with me.
This might be useful. I found an explanation of COM Security in Chapter 18, COM Security[^], "Inside COM+". It explains the COM security model in great detail, especially impersonation levels and how to query COM security settings, both with the Distributed COM Configuration Utility and programatically. All the good stuff is near the end of the chapter.
...And, if you're STILL confused, try: MSDN, Security in COM reference[^].
|
|
|
|
|
Thanks for the pointers, I guess you are right. I am shooting in dark, I will go through the book by Don Box.
Well since I am calling WMI from inside a WMI Provider calling CoInitializeSecurity[^] gives me error. Let me check out the CoQueryProxyBlanket[^].
I couldn't get back since I don't have a internet connection at me residence, it will get up and running this weekend. Hopefully then there won't be such a long gap.
|
|
|
|
|
Thanks for the pointers, I was able to solve the problem. Actually inside the WMI Provider I was not cloaking the call to next call of WMI. I did this and it works perfectly fine:
hr = CoSetProxyBlanket(WbemServices, RPC_C_AUTHN_WINNT, RPC_C_AUTHZ_DEFAULT ,
NULL, RPC_C_AUTHN_LEVEL_DEFAULT,
RPC_C_IMP_LEVEL_IMPERSONATE, NULL, EOAC_DYNAMIC_CLOAKING);
The last parameter I set as EOAC_DYNAMIC_CLOAKING.
|
|
|
|
|
In a programme there is a follwing error message from the system..
message
"The .Net Data OLE DB Provider(System.Oledb.Data) requires Microsoft Data Access Components(MDAC)version 2.6 or later, version 2.10.3711.9 was found currently installed"
This result the database connection not working, pl. any one to help to solve this problem
rajagopal
rajkottayam@rediffmail.com
|
|
|
|
|
I have loaded a Typelib of ("C:\\WINDOWS\\system32\\FM20.DLL")
ITypeLib* m_pTypeLib;
HRESULT hr = ::LoadTypeLib(ws_type_lib_file.c_str(), &m_pTypeLib);
And got the TypeInfo of below Guid
CString strClsid= "{8BD21D40-EC42-11CE-9E0D-00AA006002F3}";
CLSID clsid;
BSTR bstrClassId;
bstrClassId = strClsid.AllocSysString();
VERIFY(NOERROR == CLSIDFromString(bstrClassId, &clsid));
::SysFreeString(bstrClassId);
ITypeInfo* m_pCurITypeInfo;
m_pTypeLib->GetTypeInfoOfGuid(clsid,&m_pCurITypeInfo);
This is an co class. Which has two interface.(Copied form Ole view)
[
uuid(8BD21D40-EC42-11CE-9E0D-00AA006002F3),
helpcontext(0x001e8656),
noncreatable,
control
]
coclass CheckBox {
[default] interface IMdcCheckBox;
[default, source] dispinterface MdcCheckBoxEvents;
};
How can I get the default interface of this coclass.Actually i need need the property and method name of IMdcCheckBox.(But i will not be having the Giud of IMdcCheckBox)
VIBIN
"Fool's run away,where angle's fear to tread"
|
|
|
|
|
Try the __uuidof operator on IMdcCheckBox
«_Superman_»
I love work. It gives me something to do between weekends.
|
|
|
|
|
Auctully i need to get the CoClass default interface,as in C++\CLI:
Interop.Microsoft.TLI.InterfaceInfo DefaultInterface { get; }
(Member of Interop.Microsoft.TLI.CoClassInfo)
VIBIN
"Fool's run away,where angle's fear to tread"
|
|
|
|
|
Hello vibindia,
Try out the following code :
int main()
{
ITypeLib* pITypeLib = NULL;
HRESULT hrRet = S_OK;
hrRet = LoadTypeLibEx
(
(LPCOLESTR)(L"C:\\WINDOWS\\system32\\FM20.DLL"),
(ITypeLib**)&pITypeLib
);
if (pITypeLib)
{
ITypeInfo *pITypeInfo_Coclass = NULL;
CLSID clsid;
CLSIDFromString
(
L"{8BD21D40-EC42-11CE-9E0D-00AA006002F3}",
&clsid
);
pITypeLib -> GetTypeInfoOfGuid(clsid, &pITypeInfo_Coclass);
if (pITypeInfo_Coclass)
{
TYPEATTR* pTYPEATTR = NULL ;
pITypeInfo_Coclass -> GetTypeAttr (&pTYPEATTR);
// For each implemented interface in this coclass, get its name and determine if it is the default interface.
int i ;
for (i = 0 ; i < (pTYPEATTR->cImplTypes); i ++)
{
HREFTYPE hRefType = NULL;
pITypeInfo_Coclass->GetRefTypeOfImplType (i, &hRefType);
if (hRefType)
{
ITypeInfo* pRefTypeInfo = NULL;
BSTR bstrName = NULL;
pITypeInfo_Coclass->GetRefTypeInfo (hRefType, &pRefTypeInfo);
if (pRefTypeInfo)
{
pRefTypeInfo->GetDocumentation(MEMBERID_NIL, &bstrName, NULL, NULL, NULL);
int iImplTypeFlags = 0;
pITypeInfo_Coclass->GetImplTypeFlags
(
i,
&iImplTypeFlags
);
if (iImplTypeFlags & IMPLTYPEFLAG_FDEFAULT)
{
if (iImplTypeFlags & IMPLTYPEFLAG_FSOURCE)
{
printf ("[default, source] interface is [%s].\r\n", (LPCTSTR)_bstr_t(bstrName));
}
else
{
printf ("[default] interface is [%s].\r\n", (LPCTSTR)_bstr_t(bstrName));
}
}
pRefTypeInfo->Release();
pRefTypeInfo = NULL;
}
if (bstrName)
{
::SysFreeString(bstrName);
bstrName = NULL;
}
}
}
pITypeInfo_Coclass->ReleaseTypeAttr(pTYPEATTR);
pTYPEATTR = NULL;
pITypeInfo_Coclass->Release();
pITypeInfo_Coclass = NULL;
}
pITypeLib->Release();
pITypeLib = NULL;
}
return 0;
}
Note that there could be two default interfaces : one being the default incoming interface (i.e. [default]) and the other a default source interface (i.e. [default, source].
The important method to use is ITypeInfo::GetImplTypeFlags(). Call it on the ITypeInfo interface of the coclass that you are interested in e.g. :
pITypeInfo_Coclass->GetImplTypeFlags
(
i,
&iImplTypeFlags
);
This method will return a IMPLTYPEFLAGS. The code to obtain the default interface should be self-explanatory.
The calls to GetRefTypeOfImplType() and GetRefTypeInfo() are so that we can get the ITypeInfo interface on each of the interfaces of the coclass.
Best Regards,
Bio.
modified on Monday, June 8, 2009 12:08 AM
|
|
|
|
|
Hi,
This is manjari.I hv some problem while customise the print dialog.In comdlg32.dll -in dialogs-i hv inserted some controls for customise for username and password in no of copies panel.i want to replace the customised comdlg32.dll in systm32.here i used one patch wfp10 for disabling the windows file protection .then i used inuse for replacing the comdlg and rebooting.but it didnt replace.tell me the process how to do.plz help me as soon as possible.
thanks,
regards,
manjari
How i will design a a form in windows service to print a document.
|
|
|
|
|
Hi,
I happen to create a WMI push provider, when I am creating the instance of it I get the error.
The provider is written in VC++, I was wondering if there is a way of debugging the code when I try to create the instance through WMI Studio.
I had tried by attaching the debugging process in Visual Studio to "wmiprvse.exe", but could not find a solution.
Thanks
Krish
|
|
|
|
|
Same as debugging any in-process (i.e. DLL based) COM server - specify the executable that will be creating instances of it.
So, open the WMI providers project/solution in VC++. In the project properties, set the debug executable to be WMI Studio. Set breakpoints in your DLL's source code. Debug the project - WMI Studio should start, so you can do what you need to instantiate your provider and start debugging!
Java, Basic, who cares - it's all a bunch of tree-hugging hippy cr*p
|
|
|
|
|
I have Visual Studio 2005, in project properties for debugger to launch option I am not able to see option for "WMI Studio". The options which come up are:
a) Local Windows Debugger
b) Remote Windows Debugger
c) Web Services Debugger
d) MPI Cluster Debugger
Do I need to install some debugging add-on?
|
|
|
|
|
Local Windows Debugger, set the Command proprty to be the path to the WMI Studio executable.
Java, Basic, who cares - it's all a bunch of tree-hugging hippy cr*p
|
|
|
|
|
I have WMI Studio which works as a activeX control on IE, instances/query is run from WMI Studio. I tired attaching the IE process and wmiprvse.exe process, when I execute the query on my WMI management class it runs as "LOCAL SERVICE" instead of "SYSTEM".
I tried attaching to both the instances, but could not debug. In visual studio after attaching the process I press F5 to run it.
Either debugger is not getting attached to the process or I am not placing debug pointer at the correct location. Is there a way that automatically it steps into the code, without me figuring out the locations where to place the debug point?
|
|
|
|
|
So...which process is your WMI provider loaded into?! Until you know that, you're going to have trouble debugging it!
Java, Basic, who cares - it's all a bunch of tree-hugging hippy cr*p
|
|
|
|
|
Hey, thanks for the prompt reponse(s).
I am using WMI CIM Studio supplied by MS for viewing instances of the my management class.
Though my management class is for touchscreen, but I am having same problem with the code from GWYN COLE's book "Developing WMI Solution" and compiled and regsitered it. The namespace is "WMIBook" and class is "SampleWINNet_Basket", there is method for enumeration.
I guess when I try to view the instances of Baskets in WMI Studio, I get a "WMI:Provider load failure". In order to figure the error, I am trying to get into debugging.
|
|
|
|
|
So, it sounds like WMI CIM Studio is trying to load your provider (I presume your provider is a DLL?), which means that the process trying to load your provider is Internet Explorer? In that case, you want to specify Internet Explorer as your debug executable and set breakpoints in your provider source code. I would suggest the Initialize method of IWbemProviderInit as a good place to start?
If that method's never reached, then it suggests that the system is having trouble locating your provider, which suggests that the registration of your management class is incorrect.
Java, Basic, who cares - it's all a bunch of tree-hugging hippy cr*p
|
|
|
|
|
My provider is a DLL, I tried attaching it to Internet Explorer but didn't work even after placing breakpoints in the Initialize method of IWbemProviderInit.
I am creating a new WMI Management object with its WMI provider, the class will only do enumeration. Let me check how it goes, I guess it will take me half an hour to try out all the above permutation and combinations. Will definitely get back.
|
|
|
|
|
I just Googled for "debug wmi provider dll". Found a couple of things:
From Wikipedia:
WinMgmt.exe: WinMgmt.exe is not a tool; it is the executable that implements the WMI Core service. Under the Windows NT family of operating systems, WMI runs as a service. On computers running Windows 98, Windows 95 or Windows Me, WMI runs as an application. Under the Windows NT family of operating systems, it is also possible to run this executable as an application, in which case, the executable runs in the current user context. For this, the WMI service must be stopped first. The executable supports some switches that can be useful when starting WMI as a service or as an application. WMI provider developers who may want to debug their providers essentially need to run the WMI service as an application.
From this CodeProject article[^]:
Debugging WMI provider critta 4:39 11 Jan '06
Step 1:
stop the Windows Management Instrumentation Service
(control panel-->administrative tools---> services, or Start-->Run--> services.msc)
Step 2:
In your VS click go to Build/Start Debug / Go, a dialog appears and asks for "Executable for Debug Session" here specify the path to the winmgmt.exe (should be under %systemroot%/system32/wbem.
That's it !
Java, Basic, who cares - it's all a bunch of tree-hugging hippy cr*p
|
|
|
|
|