UPDATERECEIPT.CPP
// Filename: UpdateReceipt.cpp 
// 
// Description: Implementation of CUpdateReceipt 
// 
// This file is provided as part of the Microsoft Transaction Server Samples 
// 
// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT  
// WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED,  
// INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES  
// OF MERCHANTABILITY AND/OR FITNESS FOR A  PARTICULAR  
// PURPOSE. 
// 
// Copyright (C) 1997 Microsoft Corporation, All rights reserved 
 
#include "stdafx.h" 
#include "Account.h" 
#include "UpdateReceipt.h" 
 
#include <mtx.h> 
#include <adoid.h> 
#include <adoint.h> 
 
///////////////////////////////////////////////////////////////////////////// 
// 
 
STDMETHODIMP CUpdateReceipt::InterfaceSupportsErrorInfo(REFIID riid) 
{ 
static const IID* arr[] =  
{ 
&IID_IUpdateReceipt, 
}; 
 
for (int i=0;i<sizeof(arr)/sizeof(arr[0]);i++) 
{ 
if (InlineIsEqualGUID(*arr[i],riid)) 
return S_OK; 
} 
return S_FALSE; 
} 
 
//Update: update the database next receipt number when 100 receipts have been issued by GetReceipt 
// 
//returns: S_OK or E_FAIL 
 
STDMETHODIMP CUpdateReceipt::Update (OUT long* plReceiptNo) { 
 
HRESULT hr = S_OK; 
 
IObjectContext* pObjectContext = NULL; 
 
ADOConnection* adoCoConnection = NULL; 
ADORecordset* adoRsReceipt = NULL; 
ADOFields* pFields = NULL; 
ADOField* pField = NULL; 
 
long lErrFlag = 0; 
TCHAR* pErrMsg = NULL; 
 
*plReceiptNo = 0; 
 
try { 
 
// First of all, get the object context 
THROW_ERR ( GetObjectContext(&pObjectContext), "GetObjectContext" ); 
 
// Create ADOConnection object and initialize the connection 
THROW_ERR ( CoCreateInstance (CLSID_CADOConnection, NULL, CLSCTX_INPROC_SERVER, 
IID_IADOConnection, (LPVOID *) &adoCoConnection), "CoCreateInstance(CLSID_CADOConnection)" ); 
 
BSTR bstrDSN = ::SysAllocString (L"FILEDSN=MTSSamples"); 
hr = adoCoConnection->Open(bstrDSN, NULL, NULL, adCmdUnspecified); 
::SysFreeString (bstrDSN); 
RETHROW_ERR ( hr ); 
 
// Update the next receipt record 
CComVariant vAdoNull; 
TCHAR szBuffer [512]; 
wsprintf (szBuffer, _T("Update Receipt set NextReceipt = NextReceipt + 100")); 
BSTR bstrSQL = TCHAR2BSTR (szBuffer); 
hr = adoCoConnection->Execute(bstrSQL, &vAdoNull, -1, NULL); 
::SysFreeString (bstrSQL); 
RETHROW_ERR ( hr ); 
 
// Obtain the desired recordset with an SQL query 
bstrSQL = ::SysAllocString (L"SELECT NextReceipt FROM Receipt"); 
hr = adoCoConnection->Execute (bstrSQL, &vAdoNull, -1, &adoRsReceipt); 
::SysFreeString (bstrSQL); 
RETHROW_ERR ( hr ); 
 
// Get the appropriate fields 
RETHROW_ERR( adoRsReceipt->get_Fields(&pFields) ); 
 
// Get the appropriate field 
CComVariant vField = L"NextReceipt"; 
RETHROW_ERR ( pFields->get_Item (vField, &pField) ); 
CComVariant vNextReceipt; 
RETHROW_ERR ( pField->get_Value (&vNextReceipt) ); 
 
 
// Cleanup resources 
if (pField) pField->Release(); 
if (pFields) pFields->Release(); 
if (adoRsReceipt) adoRsReceipt->Release(); 
if (adoCoConnection) adoCoConnection->Release(); 
 
// We are finished and happy 
pObjectContext->SetComplete(); 
 
// Prepare return value 
*plReceiptNo = vNextReceipt.lVal; 
hr = S_OK; 
 
} catch (HRESULT hr) { 
 
// 
//ErrorInfo is saved here because the following ADO cleanup code  
//may clear it. 
// 
IErrorInfo * pErrorInfo = NULL; 
GetErrorInfo(NULL, &pErrorInfo); 
 
if (pField)pField->Release(); 
if (pFields) pFields->Release(); 
if (adoRsReceipt) adoRsReceipt->Release(); 
if (adoCoConnection) adoCoConnection->Release(); 
 
// Fill in error information 
switch (lErrFlag) { 
 
// Unknown error occurred in this object 
case (0): 
TCHAR szErr [512]; 
wsprintf (szErr, _T("Error 0x%x from CUpdateReceipt calling %s."), hr, pErrMsg); 
pErrMsg = szErr; 
// Fall through 
 
// An application error occurred in this object 
case (1): 
// 
//we are going to put our own error in TLS, so if there is one there, clear it 
// 
if (pErrorInfo) 
pErrorInfo -> Release(); 
 
AtlReportError( CLSID_CUpdateReceipt, pErrMsg, IID_IUpdateReceipt, hr); 
break; 
 
case (2): // An error occurred in a called object 
// 
//put the error back in TLS 
// 
SetErrorInfo(NULL, pErrorInfo); 
break; 
 
// Will never reach here 
default: 
break; 
} 
 
// Indicate our unhappiness 
if (pObjectContext) 
pObjectContext->SetAbort(); 
} 
 
// Resource cleanup 
if (pObjectContext)pObjectContext->Release(); 
 
return hr; 
}