home *** CD-ROM | disk | FTP | other *** search
- // Filename: MoveMoney.cpp
- //
- // Description: Implementation of CMoveMoney
- //
- // This file is provided as part of the Microsoft Transaction Server
- // Software Development Kit
- //
- // 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 "MoveMoney.h"
- #include "Account.h"
- #include "GetReceipt.h"
-
- #include <mtx.h>
- #include <comdef.h>
-
- /////////////////////////////////////////////////////////////////////////////
- //
-
- STDMETHODIMP CMoveMoney::InterfaceSupportsErrorInfo(REFIID riid)
- {
- static const IID* arr[] =
- {
- &IID_IMoveMoney,
- };
-
- for (int i=0;i<sizeof(arr)/sizeof(arr[0]);i++)
- {
- if (InlineIsEqualGUID(*arr[i],riid))
- return S_OK;
- }
- return S_FALSE;
- }
-
- // Perform: modifies the specified account by the specified amount
- //
- // pvResult: a BSTR giving information. NOTE: this is set to NULL when an error occurs
- //
- // returns: S_OK or E_FAIL
-
- STDMETHODIMP CMoveMoney::Perform (IN long lPrimeAccount, IN long lSecondAccount, IN long lAmount,
- IN long lTranType, OUT BSTR* pbstrResult) {
- USES_CONVERSION;
-
- HRESULT hr = S_OK;
-
- IObjectContext* pObjectContext = NULL;
-
- IAccount* pObjAccount = NULL;
- IGetReceipt* pObjGetReceipt = NULL;
-
- long lErrFlag = 0;
- TCHAR* pErrMsg = NULL;
-
- BSTR bstrResult2 = NULL;
- BSTR bstrCall1 = NULL;
- BSTR bstrCall2 = NULL;
-
- *pbstrResult = NULL;
-
- try {
-
- // Get the object context
- THROW_ERR ( GetObjectContext (&pObjectContext), "GetObjectContext" );
-
- // Check security for large transfers
- if (lAmount > 500 || lAmount < -500) {
-
- BOOL bInRole;
- BSTR bstrRole = ::SysAllocString (L"Managers");
- hr = pObjectContext->IsCallerInRole (bstrRole, &bInRole);
- ::SysFreeString(bstrRole);
-
- if (!SUCCEEDED ( hr )) {
-
- THROW_STR ( _T("IsCallerInRole() call failed! Please add the 'Managers' Roll to the package."));
- }
-
- if (!bInRole) {
- THROW_STR ( _T("Need 'Managers' role for amounts over $500") );
- }
- }
-
- // Create the account object using our context
- THROW_ERR ( pObjectContext->CreateInstance(CLSID_CAccount, IID_IAccount, (void**)&pObjAccount),
- "CreateInstance(CLSID_CAccount)" );
-
- // Call the post function based on the transaction type
- switch ( lTranType )
- {
- case (1): // debit
- RETHROW_ERR ( pObjAccount->Post (lPrimeAccount, 0 - lAmount, &bstrResult2) );
- break;
-
- case (2): // credit
- RETHROW_ERR ( pObjAccount->Post (lPrimeAccount, lAmount, &bstrResult2) );
- break;
-
- case (3): // transfer
- // Do the credit
- RETHROW_ERR ( pObjAccount->Post (lSecondAccount, lAmount, &bstrCall1) );
-
- // Then do the debit
- RETHROW_ERR ( pObjAccount->Post (lPrimeAccount, 0 - lAmount, &bstrCall2) );
-
- // Prepare return string
- TCHAR szBuf [512];
- _tcscpy (szBuf, W2T( bstrCall1 ));
- _tcscat (szBuf, _T("; "));
- _tcscat (szBuf, W2T( bstrCall2 ));
- bstrResult2 = TCHAR2BSTR (szBuf);
- break;
-
- default:
- THROW_STR ( _T("Invalid Transaction Type") );
- }
-
- // Get Receipt Number for the transaction
- THROW_ERR ( pObjectContext->CreateInstance (CLSID_CGetReceipt, IID_IGetReceipt, (void**)&pObjGetReceipt),
- "CreateInstance(CLSID_CGetReceipt)" );
- long lngReceiptNo;
- RETHROW_ERR ( pObjGetReceipt->GetNextReceipt(&lngReceiptNo) );
-
- // Tag receipt information onto return string
-
- TCHAR szBuffer [512];
- wsprintf (szBuffer, _T("; Receipt No: %li"), lngReceiptNo);
- BSTR bstrTemp = TCHAR2BSTR (szBuffer);
-
- TCHAR szBuffer2 [512];
- _tcscpy (szBuffer2, W2T ( bstrResult2 ));
- _tcscat (szBuffer2, W2T ( bstrTemp ));
- ::SysFreeString (bstrTemp);
-
- *pbstrResult = TCHAR2BSTR (szBuffer2);
-
- // We are finished and happy
- pObjectContext->SetComplete();
- hr = S_OK;
-
- } catch (HRESULT hr) {
-
- //
- // store error info locally
- //
-
- IErrorInfo * pErrorInfo = NULL;
- GetErrorInfo(NULL, &pErrorInfo);
-
- // Fill in error information
- switch (lErrFlag) {
-
- // Unknown error occurred in this object
- case (0):
- TCHAR szErr [512];
- wsprintf (szErr, _T("Error 0x%x from CMoveMoney 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_CMoveMoney, pErrMsg, IID_IMoveMoney, 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();
- }
-
-
- // Release resources
- if (pObjAccount)
- pObjAccount->Release();
-
- if (pObjectContext)
- pObjectContext->Release();
-
- if (pObjGetReceipt)
- pObjGetReceipt->Release();
-
- if (bstrResult2)
- ::SysFreeString (bstrResult2);
-
- if (bstrCall1)
- ::SysFreeString (bstrCall1);
-
- if (bstrCall2)
- ::SysFreeString (bstrCall2);
-
- return hr;
- }