DirectShow Spy: ROT fix and evrprop.dll

A small issue appears to be affecting DirectShow applications with DirectShow Spy installed. As underlying COM base is non-standard, the spy implements a few hacks to run smoothly and to keep reference counting correct in particular. Under certain conditions, DirectShow-enabled ActiveX control hosted by Internet Explorer seems to be unable to put its graph onto Running Object Table (ROT). What happened next is that Spy assumed ROT operation to succeed, and compensated reference counting, which under bad assumption could cause E_UNEXPECTED error while creating a filter graph. This updated fixes the issue.

Another small improvement is that similarly to SDK proppage.dll, Spy registration UI also assists in registering another DLL – evrprop.dll, should it be there near the spy module.

Evrprop.dll registration

Download links

DirectShow Spy: Easier Registration

Because DirectShow Spy is often a troubleshooting tool, one of its use scenarios is its being a drop-in module to quickly install on a system of interest in order to connect to graphs for troubleshooting purposes, such as to check topology and media types.

Its installation requires COM registration, and over time it changed gradually from simple to more and more complex step. Why? In Windows XP one had to open command prompt and regsvr32. With Vista’s UAC one needs a prompt, with privilege elevation, which opens typically in wrong directory, then UAC prompt. A relatively easy step became annoying multi-step operation. Then proxy/stub classes were moved into Windows SDK DLL…

Things are getting back to be easier with DirectShow Spy. It is given a special property sheet right there withing the DLL, to take care of all the important things:

  • checks registration status
  • buttons to Unregister/Register
  • per-user registration (not recommended though due to system wide class hooking)
  • automatically takes care of UAC prompt
  • place Windows SDK proppage.dll into the same directory near spy, and additional property page will help you to register this additional dependency

To invoke registration UI, start:

rundll32 DirectShowSpy.dll,DoRegistrationPropertySheetModal

from command line, or just have a .BAT file ready to do it for you.

Download links

Skype improved support for video devices for richer user experience

A new release of Skype is out there, version

  • Metro look on the main (roster) window – good job!
  • Broken compatibility with software (virtual) video capture devices – good job!
  • Broken compatibility with some of hardware capture devices – good job!

While stripping virtual video devices in favor of true cameras, to avoid issues, might be intentional (though it would still be hard to justify anyway), the update also screwed the operation with a true hardware WDM driver backed PCI video capture board… Nice – with a dozen of cameras around the table I no longer have a single one compatible with Skype.

A little bit of hackery brings virtual DirectShow sources back to life, including those created by IP Video Source, however the issue is clearly Skype’s: I have no intention to work it around, let’s hope Skype guys are given some piece of mind to fix that soon.

Be aware and DO NOT UPGRADE if operation of virtual video source in Skype is is essential!

NOTE: There is an open issue on Skype’s tracker for the virtual camera compatibility.

IP Video Source: Support for HTTPS protocol

This publishes a small update to IP Video Source tool to expose M-JPEG/JPEG video streams as DriectShow video devices. The utility now accepts https:// URL scheme and pulls video over secure connections. Not every camera has support for HTTPS, however many do including those from UDP Technology, Axis etc.

The update also includes other minor fixes including more reasonable memory allocation, and hotfix for D-Link DCS-930L model, which – to mention – is an excellent indication of quality of camera firmware nowadays (it has nothing to do with D-Link, most of vendors do things like this):

#pragma region D-Link DCS-930L Fix
// NOTE: This is just ridiculous, the camera sends boundary with space without quotes AND misuses -- prefix
if(sValue.Compare(L"multipart/x-mixed-replace;boundary=--video boundary--") == 0)
    sValue = L"multipart/x-mixed-replace;boundary=\"video boundary--\"";
#pragma endregion

Download links

Log Process Exceptions: Filters and Email Notification

Moving on with LogProcessExceptions tool which externally monitors (debugs, to be more specific) an application of interest and captures its exceptions writing minidump files for further analysis.

This updates adds two features:

  1. Ability to filter out the exceptions of interest
  2. An email notification on exception, with or without minidump file


A new property page in the wizard provides one with an option to specify filters/rules to identify exceptions of interest. One rule per line, once exception occurred its codes are compared against rules top to bottom. The first matching rule results in decision whether to log the minidump (and issue a notification) or not. If no filter/rule applicable found, or the entire filter is empty, the exception is logged (positive).

The rule syntax is the following:

  • empty lines are ignored
  • anything to the right from // is considered to be a comment
  • meaningful line has one or more items separated by spaces
  • first item on the line is either - or + to indicate whether the rule will result in skipping the exception (minus sign) or logging in (plus sign)
  • second item is exception code, e.g. 0xC0000005 for memory access violation, 0xE06D7363 for native C++ exception (this constant has a dedicated alias “C++”
  • third item applies to C++ exceptions and matches ATL CAtlException codes, and this allows to filter out specific HRESULTs; it is also possible to specify a range of codes as shown on the screenshot above

Email Notification

Why? Some issues are long to wait, so you don’t want to have it in front of you until the issue takes place. This is when a friendly email from the application would be so much appreciated.

The application gets you that by queuing an email once exception of interest takes place. The email settings are basically those of class described on an earlier EmailTools.dll post. The whole SMTP email class is embedded into this application, and it actually deserves a dedicated post on explaining how to embed ATL COM class with persistence based on COM map, which in turn depends on type library expected to be registered, into another application which additionally runs without registration.

There is a default preset tuned for Google Mail, but there are other options as well. Note that both filter and email settings are saved into registry under HKCU to be reused in next runs of the application.

Small minidump files are attached right to the emails. Larger ones (typically those with Full Memory option checked) are only mentioned. There is a threshold setting that defines how many megabytes is OK to attach the most.

Download links:

Automated cell phone balance check, mutliple accounts

Everyone has a cell phone nowadays, a lot of people have 2+ numbers, many have dependents with cell phones. In this country with prepaid services being so popular the number of people who pay for cellular phone services for several numbers perhaps exceeds one million. It looks obvious that there is certain demand for a service to access multiple accounts and consolidate balances at ones fingertips to be able to top them up timely.

The idea itself is not new, there have been various apps to gather the information, however the companies seem to be ignoring this request. I have five numbers with Kyivstar which I want to keep in good standing and the best the company can offer is the website where I can log in and out interactively to query the stats one by one.

It definitely stopped being fun at some point (it was certainly one of those days when important number hit the bottom when it was not expected to) and I had to delegate the checks to an automated script. The challenge is merely simple: there is a website, one need to log in, automated, get the data of interest, and then a few times again. Below are a few steps a power user might do to set up automated balance querying.

  • First of all, there is an inproc COM server that implements the HTTP requests to My Kyivstar website. Pre-built UaMobileTools.dll is available from repository, so does the [partial] source code. The DLL has to be registered with regsvr32 and it is ready to serve. Effectively, it implements two HTTP requests to authenticate, and then obtain and parse web page with current balance and other account statement data (the relevant part of the source code is here).
  • Because the items below are going to involve sending an email to notify of low balance, one needs to similarly install and additional DLL to provide simple SMTP email services to scripting environment. The DLL is EmailTools.dll which also needs to be downloaded and registered. It was mentioned separately a while ago.
  • Next part is setting up automation script that does the querying. The COM server in item 1 above is the implementation of the requests, but it needs to be automated.

I prepared a template of the .JS script that performs the checks.

The script is Check – Template.js and can be basically used as is, with only putting numbers of interest and respective passwords from My Kyivstar service. The part to be updated manually and individually is around line 54:

Do("Ann", "+380961111111", "password at", 10);
Do("Bill", "+380962222222", "password at", 20);
Do("Celine", "+380963333333", "password at", 30);
Do("Diana", "+380964444444", "password at", 40);

Where the items within the brackets are, respectively, friendly name, number, password and balance threshold for notification.

Should any of the numbers have balance below the respective threshold, the script composes and sends an email with all balances on the body. I personally have it routed to both real mailbox, and SMS gate at so I have the notification delivered to both destinations. Email settings are also on the script.

  • Now when checking script is implemented and ready, Windows Task Manager is here to run it on schedule. I have it running twice a day, morning and evening. The data is also being written into log file, and should there be a need for topping up – I have an email, and I have an SMS message. Task Scheduler only needs to run C:\Windows\syswow64\cscript.exe (might be system32 for 32-bit OS) with a full path to .JS script as an argument.

Happy being on top of when to top the thing up.

An excerpt in Russian for those who might want it that way.

Эта инструкция может быть полезна для тех, кто захочет путем
несложных манипуляций настроить проверку баланса счета мобильного
номера Киевстар так, чтобы она выполнялась автоматически, регулярно и
для нескольких счетов. Так, что если хотя бы один из счетов “уходит”
ниже порогового значения, чтобы следовало уведомление об этом письмом
или сообщением.

Для того, чтобы выполнить настройку, необходимо загрузить и
зарегистрировать несколько файлов как это описано выше, а также подправить
небольшой сценарий проверки, указав там номера и пароли к службе “Мой
Киевстар” для этих номеров.

DirectShow Spy: Who Sent EC_ERRORABORT?

persiflage@stackoverflow asks if there is a chance to use DirectShow Spy see who sent an EC_ERRORABORT notification, which filter exactly. Let us see first why there is no way to find this out, and then we will see what we can do.

DirectShow Filter Graph Manager accepts events from filters via its IMediaEventSink interface. The conversation taking place around event notifications is like this:

  • Filter: Hey, Graph Manager! Can I call you IMediaEventSink?
  • Manager: Yes, you can.
  • F: I notify you on EC_ERRORABORT event, here is HRESULT that I have: VFW_E_SOMETHING.
  • M: OK.

Filter graph manager (FGM) does not ask “Who’s taking?”. It does not need to know, it accepts information anonymously. Can a non-filter post an event? Absolutely, FGM does not have to care. This is simple, but when a question raised who posted the event, there is no answer for it – there was no such information in first place.

The good news through is that a developer does not need one hundred percent precision. The source of the event is important to understand which of the filters aborted streaming, and any information is helpful. Spy impersonates the whole FGM and as such it is capable of covering IMediaEventSink interface as well, in order to trace calls to the log file, and, even more helpful, trace call stack of the call which brought specific event in.

With the call stack information at the time of event notification, the filter of interest can be identified pretty precisely. Especially, having debug symbols available, so that Spy could provide symbols for the code locations on stack.

For instance, let us looks at Windows SDK AMCap Sample which previews video and uses video renderer, and hence has EC_VIDEO_SIZE_CHANGED event involved (just an example, spy from now on traces EC_ERRORABORT call stack only). Once this event reaches FGM, the call stack logged is:

FilterGraphSpy.h(850): CSpyT<class CSpy,&struct _GUID const CLSID_FilterGraph>::Notify: nEventCode EC_VIDEO_SIZE_CHANGED (0x0A), nParameter1 0x00F00140, nParameter2 0x00000000
  DirectShowSpy!6a3ba3b4 CSpyT<CSpy,&CLSID_FilterGraph>::Notify (+ 337) [d:\projects\\repository-public\directshowspy\filtergraphspy.h, 859] (+ 13) @6a3a0000
  quartz!6a243188 CBaseFilter::NotifyEvent (+ 46) @6a220000
  quartz!6a3394f6 CBaseControlVideo::OnVideoSizeChange (+ 56) @6a220000
  quartz!6a2a2f9a CRenderer::CompleteConnect (+ 175) @6a220000
  quartz!6a337668 CRendererInputPin::CompleteConnect (+ 25) @6a220000
  quartz!6a23a470 CBasePin::ReceiveConnection (+ 213) @6a220000
  quartz!6a2a3741 CVideoInputPin::ReceiveConnection (+ 92) @6a220000
  ksproxy!65e94dc0 CBasePin::AttemptConnection (+ 84) @65e70000
  ksproxy!65e94e81 CBasePin::TryMediaTypes (+ 104) @65e70000
  ksproxy!65e94f68 CBasePin::AgreeMediaType (+ 115) @65e70000
  ksproxy!65e966a0 CBasePin::Connect (+ 100) @65e70000
  ksproxy!65e7d711 CKsOutputPin::Connect (+ 381) @65e70000
  quartz!6a23252e CFilterGraph::ConnectDirectInternal (+ 233) @6a220000
  quartz!6a23847c CFilterGraph::ConnectRecursively (+ 44) @6a220000
  quartz!6a238d09 CFilterGraph::ConnectInternal (+ 331) @6a220000
  quartz!6a238c22 CFilterGraph::Connect (+ 23) @6a220000
  DirectShowSpy!6a3b8686 CSpyT<CSpy,&CLSID_FilterGraph>::Connect (+ 881) [d:\projects\\repository-public\directshowspy\filtergraphspy.h, 672] (+ 0) @6a3a0000
  quartz!6a2322f0 CEnumMediaTypes::Release (+ 39) @6a220000
  qcap!6a6c7a31 CBuilder2_2::DoesCategoryAndTypeMatch (+ 408) @6a6b0000
  qcap!6a6b3424 _GUID_00000000_0000_0000_0000_000000000000 (+ 4) @6a6b0000
  qcap!6a6cb9cb CBuilder2_2::RenderStream (+ 5294) @6a6b0000
  AMCap!01009723 @01000000
  AMCap!010041be @01000000
  AMCap!01005e27 @01000000
  AMCap!0100611c @01000000
  AMCap!01007600 @01000000
  AMCap!010076ba @01000000
  AMCap!0100a90d @01000000

It does not take a rocket scientist to see that event is posted by video renderer hosted by quartz.dll, which was a part of pin connection handling, where a pin of ksproxy’s filter – which has to be WDM Video Capture Filter – was connected to video renderer input pin.

DirectShow Spy started logging new items:

  • COM interface calls on filter graph IMediaEvent, IMediaEventEx, IMediaEventSink interfaces
  • Call staclk on IMediaEventSink::Notify call, with EC_ERRORABORT code (other codes are logged without call stack to reduce hook overhead and avoid logging stuff for no reason)

Download links: