Christian Weyer asks why Services Without Components is broken on Windows XP. I don't know the exact details of it, but I do know a few things I found out after lurking a while.

Keep in mind that last time I took a look at this was a few months ago, so it might have changed, but I highly doubt it.

Transaction support for SWC is configured through the IServiceTransactionConfig interface. Now, the original interface, with an IID of {772b3fbe-6ffd-42fb-b5f8-8f9b260f3810} is indeed supported on WinXP, and it sort of works. Or at least, it looks like it. [1]

However, it turns out, if I may say so myself, that someone made a bad versioning decision for .NET server, and went against all the COM versioning practices used before. In .NET Server, IServiceTransactionConfig supports 1 other method: ConfigureBYOT().

The problem is, it's not that they redefined the interface. Worse, they renamed it. So, in previous PSDK headers we had the following definition for IServiceTransactionConfig:


MIDL_INTERFACE("772b3fbe-6ffd-42fb-b5f8-8f9b260f3810")
IServiceTransactionConfig : public IUnknown
{
public:
virtual HRESULT STDMETHODCALLTYPE ConfigureTransaction(
/* [in] */ CSC_TransactionConfig transactionConfig) = 0;
virtual HRESULT STDMETHODCALLTYPE IsolationLevel(
/* [in] */ COMAdminTxIsolationLevelOptions option) = 0;
virtual HRESULT STDMETHODCALLTYPE TransactionTimeout(
/* [in] */ ULONG ulTimeoutSec) = 0;
virtual HRESULT STDMETHODCALLTYPE BringYourOwnTransaction(
/* [string][in] */ LPCWSTR szTipURL) = 0;
virtual HRESULT STDMETHODCALLTYPE NewTransactionDescription(
/* [string][in] */ LPCWSTR szTxDesc) = 0;
};

Notice, however, there's no ConfigureBYOT() method, even though the PSDK docs mentioned it was there.
What we have now are two interfaces: IServiceTransactionConfigBase, and IServiceTransactionConfig, which inherits from the first one.

There's the rub. What is now named IServiceTransactionConfigBase is exactly what used to be called IServiceTransactionConfig, and has the same GUID; they just renamed it, and created a new interface with the same name as the old one with a new GUID which is only supported in .NET Server. The definitions for these new interfaces are:


MIDL_INTERFACE("772b3fbe-6ffd-42fb-b5f8-8f9b260f3810")
IServiceTransactionConfigBase : public IUnknown
{
public:
virtual HRESULT STDMETHODCALLTYPE ConfigureTransaction(
/* [in] */ CSC_TransactionConfig transactionConfig) = 0;
virtual HRESULT STDMETHODCALLTYPE IsolationLevel(
/* [in] */ COMAdminTxIsolationLevelOptions option) = 0;
virtual HRESULT STDMETHODCALLTYPE TransactionTimeout(
/* [in] */ ULONG ulTimeoutSec) = 0;
virtual HRESULT STDMETHODCALLTYPE BringYourOwnTransaction(
/* [string][in] */ LPCWSTR szTipURL) = 0;
virtual HRESULT STDMETHODCALLTYPE NewTransactionDescription(
/* [string][in] */ LPCWSTR szTxDesc) = 0;
};
MIDL_INTERFACE("59f4c2a3-d3d7-4a31-b6e4-6ab3177c50b9")
IServiceTransactionConfig : public IServiceTransactionConfigBase
{
public:
virtual HRESULT STDMETHODCALLTYPE ConfigureBYOT(
/* [in] */ ITransaction *pITxByot) = 0;
};

The reason this is terrible is because it breaks source code, even if it doesn't break binary code. If you compile your application agains the old headers, everything will [sort of] work fine on XP, even if you can't use ConfigureBYOT(), since it doesn't exist. (which is fine by me, btw). However, if you recompile it against the new headers, suddently it doesn't work on XP, because it picks up the GUID for the new definition of IServiceTransactionConfig, only existing on .NET Server (so QueryInterface() now fails). [2]

What they should have done, was leave IServiceTransactionConfig alone, and define a new interface with a new name, called IServiceTransactionConfigEx or IServiceTransactionConfig2 or whatever, which is what the common COM versioning rules of thumb are.

Up to a couple of months ago, this wasn't documented anywhere, and the PSDK docs still said that IServiceTransactionConfig, even with the new ConfigureBYOT() method, was supported on XP (which was now a lie, thanks to the GUID change). Not only that, but IServiceTransactionConfigBase is not documented anyway, either.

I just looked at the docs for the February 2003 Platform SDK documentations, and it seems this has been corrected. CoEnterServiceDomain() and friends are now documented as being supported on Windows Server 2003 only. And, in fact, the SWC support in the .NET Framework 1.1 will only work in WS 2003.... the ServiceDomain class won't even instantiate in XP. I was told in very certain terms that the public message from now on would be that SWC was NOT supported on XP.

[1] I have a feeling far more is broken below... I had a few issues with aborting transactions explicitly within a service domain last I fooled around with this...
[2] I haven't installed yet the latest PSDK, so I don't know if this blunder has been fixed...



Tomas Restrepo

Software developer located in Colombia. Sr. PFE at Microsoft.