FFDShow is getting more annoying

Surprisingly fast I got new problems having ffdshow installed as a part of K-Lite Codec Pack. No wonder though because let us take a look at registration information:

Display Name: @device:sw:{083863F1-70DE-11D0-BD40-00A0C911CE86}\{0F40E1E5-4F79-4988-B1A9-CC98794E6B55}
CLSID: {0F40E1E5-4F79-4988-B1A9-CC98794E6B55}
Friendly Name: ffdshow Audio Decoder
Path: C:\Program Files\K-Lite Codec Pack\ffdshow\ffdshow.ax
Merit: 0x3fffffff

Nice merit, ain’t it? What is merit anyway? Let us check at MSDN:

MERIT_PREFERRED = 0x800000,
MERIT_NORMAL = 0x600000,

MERIT_HW_COMPRESSOR = 0x100050

The highest defined value is 0x00800000, while ffdshow is registered with 0x3FFFFFFF, that is on top of everything. No doubt the developers read Guidelines for Registering Filters and decided to get rid of the rest of installed software as unnecessary crap.

Anyway back to the problem: I had an A-law wave file (WAVE_FORMAT_ALAW) to play and make sure its data is valid and quite unexpectedly there was a silence while playing. A quick check confirmed that the sustem has CCITT A-law codec installed, however GraphEdit shown ffdshow Audio Decoder intercepting decoding. Obviously it spoiled the thing!

Finally I decided it was a right time to take an advantage of IAMGraphBuilderCallback interface to detect and reject the bastard.

Continue reading →

ATL’s CenterWindow

It appears that ATL does not center window correctly on multi-monitor systems. ATL code checks screen work area coordinates in CWindow::CenterWindow to ensure new position is within visible area, however since SystemParametersInfo/SPI_GETWORKAREA is used target rectangle is always on a primary monitor.

This hotfix works the problem around:

Continue reading →

Default Struct Member Alignment surprise with Visual C++.NET 2005

I am compiling C++ project which is using IJG JPEG library using Visual Studio .NET 2005 (yes, 2008 is yet to come) and it came as a surprise that I stumbled upon struct data alignment issue. I am pretty sure this was not a problem with Visual Studio .NET 2003.

The project includes my C++ files and C source from the library. C++ code includes:

extern "C"
{

#undef FAR
#define XMD_H // Otherwise INT32 is redefined

// NOTE: See jmorecfg.h for condition compilation options
#include "cdjpeg.h"
#include "jversion.h"

};

Running this, I receive an error from the library (thanks for pointing this out early anyway!):

JPEG parameter struct mismatch: library thinks size is 360, caller expects 347.

How comes? Project settings are default and set to use default alignment /Zp. It seems as if compiler uses default value of 1 for my C++ code and uses default value of 8 for C code… with a result of break on runtime.

The workaround is in referencing C code with alignment override using #pragma pack:

extern "C"
{

#undef FAR
#define XMD_H // Otherwise INT32 is redefined

//#pragma pack(show)
#pragma pack(push, 8 )

// NOTE: See jmorecfg.h for condition compilation options
#include "cdjpeg.h"
#include "jversion.h"

#pragma pack(pop)

};

Crap around the world: Importing IMAPI2.DLL type library (Part 2)

IMAPI version 2 is well designed – no arguments – file systems, recorders, data streams, notifications, dispatch interfaces to be compatible with scripting, higher level development environments and interoperation layer. Still I am armed with C++ at the very moment and back to type library imports using #import.

I want to know why the hell it is required to sort out mess even between the two API modules: IMAPI2.DLL and IMAPI2FS.dll:

#pragma warning(disable: 4192)
#import “libid:2735412F-7F64-5B0F-8F00-5D77AFBE261E” no_namespace raw_interfaces_only raw_dispinterfaces // IMAPI2
#import “libid:2C941FD0-975B-59BE-A960-9A2A262853A5” no_namespace raw_interfaces_only raw_dispinterfaces exclude(“_IMAPI_MEDIA_PHYSICAL_TYPE”, “IDiscRecorder2”) // IMAPI2FS
#pragma warning(default: 4192)

In order to import into C++ project, it is required to exclude two items which are duplicate between the modules. OMFG.

Still it is not the end. Since I am subscribing to events using ATL’s IDispEventImpl and SINK_ENTRY_EX, I need DISPID values for the Update methods of DDiscFormat2DataEvents and DFileSystemImageEvents. How do I find them? Type library as usual? No, my dear friend, type library does not mention this useless value… For further reference:

  • DFileSystemImageEvents::Update – DISPID is 256
  • DDiscFormat2DataEvents::Update – DISPID is 512

Crap around the world: Importing IMAPI2.DLL type library

Trying to import IMAPI2.DLL type library to be able to use IMAPI version 2 in application:

//#pragma warning(disable: 4192)
#import “libid:2735412F-7F64-5B0F-8F00-5D77AFBE261E” no_namespace raw_interfaces_only raw_dispinterfaces // IMAPI2
//#pragma warning(default: 4192)

Compiler output I see:

warning C4192: automatically excluding ‘IConnectionPointContainer’ while importing type library ‘2735412F-7F64-5B0F-8F00-5D77AFBE261E’
warning C4192: automatically excluding ‘IEnumConnectionPoints’ while importing type library ‘2735412F-7F64-5B0F-8F00-5D77AFBE261E’
warning C4192: automatically excluding ‘IConnectionPoint’ while importing type library ‘2735412F-7F64-5B0F-8F00-5D77AFBE261E’
warning C4192: automatically excluding ‘IEnumConnections’ while importing type library ‘2735412F-7F64-5B0F-8F00-5D77AFBE261E’
warning C4192: automatically excluding ‘tagCONNECTDATA’ while importing type library ‘2735412F-7F64-5B0F-8F00-5D77AFBE261E’
warning C4192: automatically excluding ‘IStream’ while importing type library ‘2735412F-7F64-5B0F-8F00-5D77AFBE261E’
warning C4192: automatically excluding ‘ISequentialStream’ while importing type library ‘2735412F-7F64-5B0F-8F00-5D77AFBE261E’
warning C4192: automatically excluding ‘_LARGE_INTEGER’ while importing type library ‘2735412F-7F64-5B0F-8F00-5D77AFBE261E’
warning C4192: automatically excluding ‘_ULARGE_INTEGER’ while importing type library ‘2735412F-7F64-5B0F-8F00-5D77AFBE261E’
warning C4192: automatically excluding ‘tagSTATSTG’ while importing type library ‘2735412F-7F64-5B0F-8F00-5D77AFBE261E’
warning C4192: automatically excluding ‘_FILETIME’ while importing type library ‘2735412F-7F64-5B0F-8F00-5D77AFBE261E’

I was of an opinion that Microsoft people is quite familiar about hiding identifiers from automatic embedding into type library (they are probably using ATL and attributed code) and avoiding duplicating well known identifiers like IConnectionPointContainer.

Windows Image Mastering IMAPI

In continuation of Nero API

Windows IMAPI is much more convenient to use, it is built on COM, it is “more Windows” etc, however there was an issue even there.

Normally IEnumXXX::Next enumerator method accepts third parameter NULL since if we are getting items one by one, we are fine processing return code S_OK/S_FALSE and we don’t need extra parameter pceltFetched to get us number of fetched items. It is ok to pass NULL in most cases, not with IMAPI enumerators however – they require a valid pointer.

Nero API

I have recently been working on CD/DVD burning feature and I was using Ahead Nero API as an option. Frankly, I was of a better opinion of this API. It is more or less well documented and C++ definitions looks fine, however…

The first problem was it failed to operate on a worker thread. My lord! I have to have burning task running on the application GUI STA thread using crappy poll-style abort callbacks. Anyway it did not work on a worker thread stumbling on a number of memory access violations. It was ludicrous that I already made everything look almost like in their sample application but API kept throwing exceptions. Until I realized it makes difference if it was running on a worker thread or not.

Anyway it keeps throwing int exceptions, and when under debugger and you stop on the exception, then chances are high that there will be anyway access violations later after burn is complete.

First-chance exception at 0x7c81eb33 in DVRRunDll.exe: Microsoft C++ exception: dummy_exception @ 0x0013a688.
First-chance exception at 0x7c81eb33 in DVRRunDll.exe: Microsoft C++ exception: int @ 0x00139594.
First-chance exception at 0x7c81eb33 in DVRRunDll.exe: Microsoft C++ exception: int @ 0x00139594.
First-chance exception at 0x7c81eb33 in DVRRunDll.exe: Microsoft C++ exception: int @ 0x00139594.
First-chance exception at 0x7c81eb33 in DVRRunDll.exe: Microsoft C++ exception: int @ 0x00139594.
First-chance exception at 0x7c81eb33 in DVRRunDll.exe: Microsoft C++ exception: int @ 0x00139594.
First-chance exception at 0x7c81eb33 in DVRRunDll.exe: Microsoft C++ exception: int @ 0x00139594.
First-chance exception at 0x7c81eb33 in DVRRunDll.exe: Microsoft C++ exception: int @ 0x00139594.
First-chance exception at 0x7c81eb33 in DVRRunDll.exe: Microsoft C++ exception: int @ 0x00139594.
First-chance exception at 0x7c81eb33 in DVRRunDll.exe: Microsoft C++ exception: int @ 0x00139594.
First-chance exception at 0x7c81eb33 in DVRRunDll.exe: Microsoft C++ exception: int @ 0x00139594.