unsigned long mts_prepare_set_log (tp_message_t * mm) { ITransactionEnlistmentAsync *mts_enlistment = (ITransactionEnlistmentAsync *) mm->mm_resource; IPrepareInfo *info = 0; unsigned long sz = 0; dbg_printf (("mts_prepare_set_log..")); if (SUCCEEDED (mts_enlistment->QueryInterface (IID_IPrepareInfo, (void **) &info)) && (SUCCEEDED (info->GetPrepareInfoSize (&sz)))) { box_t info_box = dk_alloc_box (sz, DV_BIN); if (SUCCEEDED (info->GetPrepareInfo ((BYTE *) info_box))) { mm->mm_trx->lt_2pc._2pc_log = info_box; dbg_printf ((".. success\n")); } else dk_free_box (info_box); } if (info) info->Release (); return 0; }
HRESULT __stdcall EnlistmentNotifyShim::PrepareRequest( BOOL fRetaining, DWORD grfRM, BOOL fWantMoniker, BOOL fSinglePhase ) { HRESULT hr = S_OK; IPrepareInfo* pPrepareInfo = NULL; BYTE* prepareInfoBuffer = NULL; ULONG prepareInfoLength = 0; ITransactionEnlistmentAsync* pEnlistmentAsync = NULL; #if defined(_X86_) pEnlistmentAsync = (ITransactionEnlistmentAsync*)InterlockedExchange((LONG volatile*)&this->pEnlistmentAsync, NULL); #elif defined(_WIN64) pEnlistmentAsync = (ITransactionEnlistmentAsync*)InterlockedExchange64((LONGLONG volatile*)&this->pEnlistmentAsync, NULL); #endif if( pEnlistmentAsync == NULL ) { return E_UNEXPECTED; } hr = pEnlistmentAsync->QueryInterface( IID_IPrepareInfo, (void**) &pPrepareInfo ); if ( FAILED( hr ) ) { goto ErrorExit; } hr = pPrepareInfo->GetPrepareInfoSize( &prepareInfoLength ); if ( FAILED( hr ) ) { goto ErrorExit; } // This buffer will be freed by Managed code through the CoTaskMemHandle object that is // created when the pointer to this buffer is returned from GetNotification. prepareInfoBuffer = (BYTE*) CoTaskMemAlloc( prepareInfoLength ); hr = pPrepareInfo->GetPrepareInfo( prepareInfoBuffer ); if ( FAILED( hr ) ) { goto ErrorExit; } this->prepareInfoSize = prepareInfoLength; this->pPrepareInfo = prepareInfoBuffer; this->isSinglePhase = fSinglePhase; this->notificationType = PrepareRequestNotify; this->shimFactory->NewNotification( this ); ErrorExit: SafeReleaseInterface( (IUnknown**) &pPrepareInfo ); // We can now release our pEnlistmentAsync reference. We don't need it any longer // and it causes problems if the app responds to SPC with InDoubt. SafeReleaseInterface( (IUnknown**) &pEnlistmentAsync ); // We only delete the prepareinInfoBuffer if we had an error. if ( FAILED( hr ) ) { if ( NULL != prepareInfoBuffer ) { CoTaskMemFree( prepareInfoBuffer ); } } return hr; }