I have an Internet Explorer BHO that can execute a script on the current website and then read variables that have been assigned in that script. Unfortunately, as of IE9 (I tested with the RC), reading the JS variable results in a HRESULT 0x80020006.
The script sets assigns the JS variable as follows:
this.<js_var> = <value>
where this is the current Window object. It is executed using
hr = pWindow->execScript( ccom_js, lang, &vEmpty );
and the JS variable is read using
bool get_js_var( CComPtr<IDispatch> pDisp, LPOLESTR name, VARIANT *dest )
{
DISPID id;
HRESULT hr = pDisp->GetIDsOfNames( IID_NULL, &name, 1, LOCALE_SYSTEM_DEFAULT, &id );
if ( SUCCEEDED( hr ) ) {
VariantInit( dest );
VariantClear( dest );
DISPPARAMS dp = { 0, 0, 0, 0 };
hr = pDisp->Invoke( id, IID_NULL, LOCALE_SYSTEM_DEFAULT, DISPATCH_PROPERTYGET, &dp, dest, NULL, NULL );
if ( SUCCEEDED( hr ) ) {
return true;
} else {
LOG( _T( "failed to get var contents, hresult = 0x%lx" ), hr );
}
} else {
LOG( _T( "failed to get id of var name, hresult = 0x%lx" ), hr );
}
return false;
}
where pDisp has been retrieved using document->get_Script( &pDisp );.
This code works fine in previous versions of IE, on Windows XP, Vista and 7. In IE9 the script executes (I can invoke alerts, etc.), but the variable can not be read. What change in IE9 causes this problem?
While IDispatch->GetIDsOfNames() fails to get a Dispatch ID of the variable in IE9, it turns out that using the result from get_Script() as IDispatchEx instead of IDispatch and calling:
HRESULT hr = pDispEx->GetDispID( CComBSTR( name ), fdexNameImplicit, &id );
instead of
RESULT hr = pDisp->GetIDsOfNames( IID_NULL, &name, 1, LOCALE_SYSTEM_DEFAULT, &id );
does result in a valid and usable id to be used with pDispEx->Invoke().
To get an IDispatchEx pointer, I used:
CComPtr<IDispatchEx> pDispEx;
hr = pDisp->QueryInterface(IID_IDispatchEx, (void**)&pDispEx);`
Related
This is from a 2009 Microsoft project, and I'm not sure why I'm getting an error specifically in Windows-8. Here is the link: MSDN MFCopy
This happens when using the '-v' option 'Set Video Format', I get this error:
"Failed to negotiate a format between the source reader and sink writer".
Keep in mind, I am processing the same video files in Win-7 and 8.
Edit: Is this a WinAPI issue? Is there some differences in the calls that need to be made? if so, can that be repaired in the source...
Example Usage is:
MfCopy.exe -t -xa -v WVC1 -r 270 "g:\pd1.mov" "g:\pd3.wmv"
'-t' = Trim Black frames
'-xa' = Video only
'-r' (270) = Rotate 270 degrees
'-v' (WVC1) = (Video options, H264, WMV2, WMV3, WVC1... none work in Win-8)
I also have the sourcecode, and I can debug. Again it runs fine in Win-7. But in Win-8, I get an error specifically at this line:
hr = m_pSinkWriter->SetInputMediaType( streamInfo.dwOutputStreamIndex,
pFullMediaType,
NULL );
The error is: 'The data specified for the media type is invalid, inconsistent, or not supported by this object'.
That is in this code block:
/////////////////////////////////////////////////////////////////
HRESULT CMFCopy::_NegotiateStreamFormat(
__in DWORD dwStreamIndex,
__in REFGUID guidMajorType,
__in DWORD cFormats,
__in_ecount( cFormats ) const GUID **paFormats )
{
HRESULT hr = S_OK;
const StreamInfo& streamInfo = m_paStreamInfo[dwStreamIndex];
IMFMediaType *pPartialMediaType = NULL;
IMFMediaType *pFullMediaType = NULL;
BOOL fConfigured = FALSE;
CHECK_HR( hr = MFCreateMediaType( &pPartialMediaType ) );
CHECK_HR( hr = pPartialMediaType->SetGUID( MF_MT_MAJOR_TYPE, guidMajorType ) );
for( DWORD ii = 0; ii < cFormats; ii++ )
{
SAFE_RELEASE( pFullMediaType );
CHECK_HR( hr = pPartialMediaType->SetGUID( MF_MT_SUBTYPE, *paFormats[ii] ) );
// try to set the partial media type on the source reader
hr = m_pSourceReader->SetCurrentMediaType( dwStreamIndex,
NULL,
pPartialMediaType );
if( S_OK != hr )
{
// format is not supported by the source reader, try the next on the list
hr = S_OK;
continue;
}
// get the full media type from the source reader
CHECK_HR( hr = m_pSourceReader->GetCurrentMediaType( dwStreamIndex,
&pFullMediaType ) );
if (MFMediaType_Video == guidMajorType)
{
_UpdateInputVideoStreamOverscanLineCount(pFullMediaType);
if (RotateNone != m_Options.eRotation)
{
CHECK_HR( hr = GetDefaultStride(pFullMediaType, &m_srcDefaultStride)); // get the default stride for the source
CComPtr<IMFMediaType> spRotatedMediaType;
CHECK_HR(hr = hr = CreateRotatedMediaType(pFullMediaType, spRotatedMediaType, _simpleOverScanLines));
pFullMediaType->Release();
pFullMediaType = spRotatedMediaType.Detach(); // transfer ownership
}
}
// try to set the input media type on the sink writer
hr = m_pSinkWriter->SetInputMediaType( streamInfo.dwOutputStreamIndex,
pFullMediaType,
NULL );
if( S_OK != hr )
{
// format is not supported by the sink writer, try the next on the list
hr = S_OK;
continue;
}
if (MFMediaType_Video == guidMajorType)
{
CHECK_HR( hr = _UpdateRotationInfo(pFullMediaType)); // may need to update info about rotated image
}
fConfigured = TRUE;
break;
}
if( !fConfigured )
{
hr = MF_E_INVALIDMEDIATYPE;
_SetErrorDetails( hr, L"Failed to negotiate a format between the source reader and sink writer" );
goto done;
}
done:
SAFE_RELEASE( pPartialMediaType );
SAFE_RELEASE( pFullMediaType );
return( hr );
}
I'm a newbie in the DirectShow world, and I just studied the simple "playcap" sample provided by Microsoft SDK Samples. With this little program I've been able to have a window with my webcam stream.
How can I take two shots from my webcam and compare them (even without saving them on the hard disk) to find which pixels are different?
I easily did this job using Win32API capture windows, but it was very slow, and I need it to be fast.
Thank you in advance, it is very important for my project.
You'd better search here for answer or look in samples for Sample Grabber Filter.
For more details you can write me directly here.
Add the Sample Grabber filter to the graph.
IBaseFilter *pSG_Filter;
hr = CoCreateInstance(
CLSID_SampleGrabber,
NULL,
CLSCTX_INPROC_SERVER,
IID_IBaseFilter,
(void**)&pSG_Filter
);
hr = pGraph->AddFilter(pSG_Filter, L"SampleGrab");
Add the Null Renderer filter to the graph.
IBaseFilter *pNull;
hr = CoCreateInstance(
CLSID_NullRenderer,
NULL,
CLSCTX_INPROC_SERVER,
IID_IBaseFilter,
(void**)&pNull
);
hr = pGraph->AddFilter(pNull, L"NullRender");
Now you can use the ICaptureGraphBuilder2::RenderStream method to connect all three filters in one method call, going from the still pin to the Sample Grabber, and from the Sample Grabber to the Null Renderer:
hr = pBuild->RenderStream(
&PIN_CATEGORY_STILL, // Connect this pin ...
&MEDIATYPE_Video, // with this media type ...
pCap, // on this filter ...
pSG_Filter, // to the Sample Grabber ...
pNull); // ... and finally to the Null Renderer.
Now use the ISampleGrabber interface to configure the Sample Grabber so that it buffers samples:
ISampleGrabber *pSG = NULL;
hr = pSG_Filter->QueryInterface(IID_ISampleGrabber, (void**)&pSG);
if (SUCCEEDED(hr))
{
hr = pSG->SetOneShot(FALSE);
hr = pSG->SetBufferSamples(TRUE);
...
Now, you should look at method ISampleGrabber::SetOneShot and maybe set TRUE there.
Set the callback interface with a pointer to your callback object:
hr = pSG->SetCallback(&g_StillCapCB, 0); // 0 = Use the SampleCB callback method.
Get the media type that the still pin used to connect with the Sample Grabber:
// Store the media type for later use.
AM_MEDIA_TYPE g_StillMediaType;
hr = pSG->GetConnectedMediaType(&g_StillMediaType);
pSG->Release();
This media type will contain the BITMAPINFOHEADER structure that defines the format of the still image.
What follows is an example of the callback class. Note that the class implements IUnknown, which it inherits through the ISampleGrabber interface, but it does not keep a reference count. This is safe because the application creates the object on the stack, and the object remains in scope throughout the lifetime of the filter graph.
All of the work happens in the BufferCB method, which is called by the Sample Grabber whenever it gets a new sample. In the following example, the method writes the bitmap to a file:
class SampleGrabberCallback : public ISampleGrabberCB
{
public:
// Fake referance counting.
STDMETHODIMP_(ULONG) AddRef() { return 1; }
STDMETHODIMP_(ULONG) Release() { return 2; }
STDMETHODIMP QueryInterface(REFIID riid, void **ppvObject)
{
if (NULL == ppvObject) return E_POINTER;
if (riid == __uuidof(IUnknown))
{
*ppvObject = static_cast<IUnknown*>(this);
return S_OK;
}
if (riid == __uuidof(ISampleGrabberCB))
{
*ppvObject = static_cast<ISampleGrabberCB*>(this);
return S_OK;
}
return E_NOTIMPL;
}
STDMETHODIMP SampleCB(double Time, IMediaSample *pSample)
{
return E_NOTIMPL;
}
STDMETHODIMP BufferCB(double Time, BYTE *pBuffer, long BufferLen)
{
if ((g_StillMediaType.majortype != MEDIATYPE_Video) ||
(g_StillMediaType.formattype != FORMAT_VideoInfo) ||
(g_StillMediaType.cbFormat < sizeof(VIDEOINFOHEADER)) ||
(g_StillMediaType.pbFormat == NULL))
{
return VFW_E_INVALIDMEDIATYPE;
}
HANDLE hf = CreateFile("C:\\Example.bmp", GENERIC_WRITE,
FILE_SHARE_WRITE, NULL, CREATE_ALWAYS, 0, NULL);
if (hf == INVALID_HANDLE_VALUE)
{
return E_FAIL;
}
long cbBitmapInfoSize = g_StillMediaType.cbFormat - SIZE_PREHEADER;
VIDEOINFOHEADER *pVideoHeader =
(VIDEOINFOHEADER*)g_StillMediaType.pbFormat;
BITMAPFILEHEADER bfh;
ZeroMemory(&bfh, sizeof(bfh));
bfh.bfType = 'MB'; // Little-endian for "BM".
bfh.bfSize = sizeof( bfh ) + BufferLen + cbBitmapInfoSize;
bfh.bfOffBits = sizeof( BITMAPFILEHEADER ) + cbBitmapInfoSize;
// Write the file header.
DWORD dwWritten = 0;
WriteFile( hf, &bfh, sizeof( bfh ), &dwWritten, NULL );
WriteFile(hf, HEADER(pVideoHeader), cbBitmapInfoSize, &dwWritten, NULL);
WriteFile( hf, pBuffer, BufferLen, &dwWritten, NULL );
CloseHandle( hf );
return S_OK;
}
};
Free the media type before the application exits:
// On exit, remember to release the media type.
FreeMediaType(g_StillMediaType);
Problem with MSMQ configuration or code i've implemented??
I've written windows service code (win32 C++ ) in which i am sending a log to the local private queue.This code is working fine if I execute that in 32-bit environment (either windows7/8/vista). But that same code if I build for x64 OS and if I execute MQSendMessage() failed with MQ_ERROR_INVALID_PARAMETER (0xC00E0006). What could be the problem.??? Please help me out in this regard.Thanks in advance..
I've tried by changing the NUMBEROFPROPERTIES from 3-7 in x-64 windows 7 system. But still the problem remains same. what to do to avoid this..
Here is my sample code
#define ClientQueue L".\\Private$\\TestQueue"
#define LogMsgLable L"TestLOG"
#define MIN_PRIVATE_QUEUE_NAME_LENGTH 55
DWORD MSMQSendMessage()
{
//Define the required constants and variables.
const int NUMBEROFPROPERTIES = 7; // Number of properties
DWORD cPropId = 0; // Property counter
HRESULT hr = MQ_OK; // Return code
HANDLE hQueue = NULL; // Queue handle
//Define an MQMSGPROPS structure.
MQMSGPROPS msgProps;
MSGPROPID aMsgPropId[NUMBEROFPROPERTIES] = {0};
MQPROPVARIANT aMsgPropVar[NUMBEROFPROPERTIES] = {0};
HRESULT aMsgStatus[NUMBEROFPROPERTIES] = {0};
// Specify the message properties to be sent.
aMsgPropId[cPropId] = PROPID_M_LABEL; // Property ID
aMsgPropVar[cPropId].vt = VT_LPWSTR; // Type indicator
aMsgPropVar[cPropId].pwszVal = L"ADCLOG"; // The message label
cPropId++;
// Specifying the storage of messages in the harddisk
// setting the message properties as recoverable
aMsgPropId[cPropId] = PROPID_M_DELIVERY;
aMsgPropVar[cPropId].vt = VT_UI1;
aMsgPropVar[cPropId].bVal = MQMSG_DELIVERY_RECOVERABLE;
cPropId++;
aMsgPropId[cPropId] = PROPID_M_ACKNOWLEDGE; // Property ID
aMsgPropVar[cPropId].vt = VT_UI1; // Type indicator
aMsgPropVar[cPropId].bVal = MQMSG_ACKNOWLEDGMENT_FULL_RECEIVE;
cPropId++;
// we need to set the size of the message
// if we dont set it, takes 4MB as default message size
// to set the size of it we have ---> PROPID_M_BODY
ULONG ulBufferSize = 15;
char *lLog_msg = NULL;
lLog_msg = ( char*)GlobalAlloc( GPTR, 15);
ZeroMemory( lLog_msg, 15) ;
strcpy(lLog_msg, "HelloWorld");
aMsgPropId[cPropId] = PROPID_M_BODY; // Property ID
aMsgPropVar[cPropId].vt = VT_VECTOR | VT_UI1; // Type indicator
aMsgPropVar[cPropId].caub.pElems = (UCHAR *)lLog_msg; // Body buffer
aMsgPropVar[cPropId].caub.cElems = ulBufferSize; // Buffer size
cPropId++;
//here we should not put VT_NULL in type as defined with VT_UI4.........
aMsgPropId[cPropId] = PROPID_M_BODY_TYPE; // Property ID
aMsgPropVar[cPropId].vt = VT_UI4; // Type indicator
cPropId++;
// Initialize the MQMSGPROPS structure.
msgProps.cProp = cPropId;
msgProps.aPropID = aMsgPropId;
msgProps.aPropVar = aMsgPropVar;
msgProps.aStatus = aMsgStatus;
// Create a direct format name for the queue.
WCHAR *gFormatName = NULL;
DWORD dwBufferLength = 0;
dwBufferLength = MIN_PRIVATE_QUEUE_NAME_LENGTH; //Private queue format name buffer size atleast 54
gFormatName = (WCHAR *)malloc( dwBufferLength*sizeof( WCHAR ));
if (gFormatName == NULL)
{
printf( "malloc", 0, NULL );
return MQ_ERROR_INSUFFICIENT_RESOURCES;
}
SecureZeroMemory( gFormatName, dwBufferLength*sizeof(WCHAR) );
hr = MQPathNameToFormatName( ClientQueue,
gFormatName,
&dwBufferLength );
if (FAILED( hr ))
{
if( hr == MQ_ERROR_FORMATNAME_BUFFER_TOO_SMALL )
{
if (gFormatName != NULL)
{
gFormatName = (WCHAR *)realloc( gFormatName, dwBufferLength*sizeof( WCHAR ));
if (gFormatName == NULL)
{
printf( "realloc failed\n");
return MQ_ERROR_INSUFFICIENT_RESOURCES;
}
}
SecureZeroMemory( gFormatName, dwBufferLength*sizeof( WCHAR ));
hr = MQPathNameToFormatName( ClientQueue,
gFormatName,
&dwBufferLength );
if(FAILED( hr ))
{
printf( L"MQPathNameToFormatName2 failed:%x\n", hr);
return hr;
}
}
else
{
printf("MQPathNameToFormatName failed:%x\n", hr);
return hr;
}
}
// Call MQOpenQueue to open the queue with send access.
hr = MQOpenQueue(
gFormatName, // Format name of the queue
MQ_SEND_ACCESS, // Access mode
MQ_DENY_NONE, // Share mode
&hQueue // OUT: Queue handle
);
if ( FAILED( hr ))
{
printf("MQOpenQueue failed:%x\n", hr);
goto ret;
//goto cleanup;
}
if( gFormatName )
free( gFormatName );
// Call MQSendMessage to send the message to the queue.
hr = MQSendMessage(
hQueue, // Queue handle
&msgProps, // Message property structure
NULL // Not in a transaction
);
if (FAILED(hr))
{
printf( "MQSendMessage failed:%x\n", hr );
MQCloseQueue( hQueue );
goto ret;
}
//Call MQCloseQueue to close the queue.
hr = MQCloseQueue(hQueue);
if(hr != 0)
{
printf("MQCloseQueue failed:%x",hr);
//goto cleanup;
goto ret;
}ret:
if( lLog_msg )
{
GlobalFree( lLog_msg );
lLog_msg = NULL;
}
return hr;
}
Your code works on 32-bit Windows purely by chance. Take a look at this:
ULONG ulBufferSize = sizeof( 15);
char *lLog_msg = NULL;
lLog_msg = ( char*)GlobalAlloc( GPTR, sizeof( 15));
ZeroMemory( lLog_msg, sizeof( 15)) ;
strcpy(lLog_msg, "HelloWorld");
You seem to misunderstand what the sizeof operator does. It is a compile time operator that replaces its argument with the size of that argument. In this case, the compiler replaces sizeof(15) with the number 4. Why? Because a literal constant like 15 occupies 4 bytes on a 64-bit machine. So in the code above you are allocating 4 bytes of memory and then copying 11 bytes into it, thereby corrupting memory.
To fix this, simply remove sizeof. The code above should look like this:
ULONG ulBufferSize = 15;
char *lLog_msg = NULL; // this is pointless since you set it in the next line
lLog_msg = ( char*)GlobalAlloc( GPTR, ulBufferSize);
ZeroMemory( lLog_msg, ulBufferSize) ;
strcpy(lLog_msg, "HelloWorld");
I am using Outlook automation to find items in the Calendar. For that I use IsSearchSynchronous() method to see if I have to wait for the AdvancedSearchComplete event. BTW, is it ever synchronous???
Anyway, if I have Outlook running, I have no problems with this call. But if it doesn't run - the call fails with
HRESULT: 0x80020009 Exception occurred
The EXCEPINFO contains:
Source: "Microsoft Outlook"
Description: "The operation failed."
scode: 0x80004005
Any suggestions?
Here is my test case:
#include <atlstr.h>
int _tmain()
{
IDispatch* pApp;
HRESULT hr;
CoInitialize(NULL);
CLSID clsid;
hr = CLSIDFromProgID(L"Outlook.Application", &clsid);
if(SUCCEEDED(hr))
{
hr = CoCreateInstance(clsid, NULL, CLSCTX_LOCAL_SERVER, IID_IDispatch, (void **)&pApp);
if(SUCCEEDED(hr))
{
// Get DISPID for "IsSearchSynchronous"
OLECHAR Name[] = {L"IsSearchSynchronous"};
LPOLESTR lp = Name;
DISPID dispID;
hr = pApp->GetIDsOfNames(IID_NULL, &lp, 1, LOCALE_USER_DEFAULT, &dispID);
if(SUCCEEDED(hr))
{
// The path name of the folders that the search will search through.
VARIANT path;
path.vt = VT_BSTR;
path.bstrVal = SysAllocString(L"'Calendar'");
// Build DISPPARAMS
DISPPARAMS dp = { NULL, NULL, 0, 0 };
dp.cArgs = 1;
dp.rgvarg = &path;
// get IsSearchSynchronous
VARIANT result;
VariantInit(&result);
EXCEPINFO ei = {0};
hr = pApp->Invoke(dispID, IID_NULL, LOCALE_SYSTEM_DEFAULT, DISPATCH_PROPERTYGET, &dp, &result, &ei, NULL);
VARIANT_BOOL vbIsSearchSynchronous = result.boolVal;
}
}
}
CoUninitialize();
return 0;
}
In case anybody else is interested, this is resolved with a help from Microsoft.
The “scope” parameter to a IsSearchSynchronous() call should be a complete path to the calendar folder, like:
"\\Mailbox - <user_name>\\Calendar"
On Windows XP there is a known way to create a Remote Assistance Ticket.
http://msdn.microsoft.com/en-us/library/ms811079.aspx
But on Vista this does not appear to work. How does one do this on Vista or Windows 7?
There turns out to be two ways. The Microsoft API is called IRASrv and is documented here:
http://msdn.microsoft.com/en-us/library/cc240176(PROT.10).aspx
Another way is to simply call msra.exe. with password and novice params (e.g. msra.exe /saveasfile testfile thepassword). However that does prompt the user with the password dialog.
Here is example code for calling the IRASrv interface and generating a Remote Assistance Connection String.
COSERVERINFO si; ::ZeroMemory( &si, sizeof( si ) );
MULTI_QI qi; ::ZeroMemory( &qi, sizeof( qi ) );
HRESULT hr = S_OK;
BSTR bstrUserName = SysAllocString(L"jon");
BSTR bstrDomainName = SysAllocString(L"");
BSTR bstrPasswordStr = SysAllocString(L"testpass");
// Get the security information entered by the user
_bstr_t bstrUser(bstrUserName);
_bstr_t bstrDomain(bstrDomainName);
_bstr_t bstrPassword(bstrPasswordStr);
// Set AuthIdentity
SEC_WINNT_AUTH_IDENTITY_W AuthIdentity = {
(unsigned short*)bstrUserName,
bstrUser.length(),
(unsigned short*)bstrDomainName,
bstrDomain.length(),
(unsigned short*)bstrPasswordStr,
bstrPassword.length(),
SEC_WINNT_AUTH_IDENTITY_UNICODE
};
COAUTHINFO AuthInfo = {
RPC_C_AUTHN_WINNT,
RPC_C_AUTHZ_DEFAULT,
NULL,
RPC_C_AUTHN_LEVEL_PKT_PRIVACY, // The authentication level used
RPC_C_IMP_LEVEL_IMPERSONATE,
(COAUTHIDENTITY*)&AuthIdentity,
EOAC_NONE
};
si.pAuthInfo = &AuthInfo;
si.pwszName = bstrMachineName;
qi.pIID = &(__uuidof(RAServerLib::IRASrv));
hr = ::CoCreateInstanceEx(
__uuidof(RAServerLib::RASrv), NULL, CLSCTX_REMOTE_SERVER,
&si, 1, &qi );
if (FAILED(hr))
{
return hr;
}
CComPtr<RAServerLib::IRASrv> prasrv;
hr = qi.pItf->QueryInterface(__uuidof(RAServerLib::IRASrv), (void**)&prasrv);
if (FAILED(hr))
{
return hr;
}
LPWSTR pstr=NULL;
hr = prasrv->raw_GetNoviceUserInfo(&pstr);
if (FAILED(hr))
{
return hr;
}
pstr contains the Remote Assistance Connection String (type 2)