|
|
/*****************************************************************************\
* MODULE: request.cpp * * PURPOSE: Implementation of COM interface for BidiSpooler * * Copyright (C) 2000 Microsoft Corporation * * History: * * 03/07/00 Weihai Chen (weihaic) Created * \*****************************************************************************/
#include "precomp.h"
#include "priv.h"
//
// Constructor
//
TBidiRequest::TBidiRequest() : m_cRef(1), m_kDataType (BIDI_NULL), m_dwDataSize (0), m_pbData (NULL), m_pSchema (NULL), m_bValid (FALSE) { InterlockedIncrement(&g_cComponents) ;
m_bValid = m_CritSec.bValid () && m_ResponseDataList.bValid ();
DBGMSG(DBG_TRACE,("TBidiRequest Created\n")); }
//
// Destructor
//
TBidiRequest::~TBidiRequest() {
InterlockedDecrement(&g_cComponents) ;
if (m_pSchema) delete [] m_pSchema;
DBGMSG(DBG_TRACE,("TBidiRequest Dstroy self\n")); }
//
// IUnknown implementation
//
STDMETHODIMP TBidiRequest::QueryInterface( REFIID iid, PVOID* ppv) {
HRESULT hr = S_OK;
DBGMSG(DBG_TRACE,("Enter TBidiRequest QI\n"));
if (iid == IID_IUnknown) { *ppv = static_cast<IBidiRequest*>(this) ; } else if (iid == IID_IBidiRequest) {
*ppv = static_cast<IBidiRequest*>(this) ; } else if (iid == IID_IBidiRequestSpl) {
*ppv = static_cast<IBidiRequestSpl*>(this) ; } else { *ppv = NULL ; hr = E_NOINTERFACE ; }
if (*ppv) { reinterpret_cast<IUnknown*>(*ppv)->AddRef() ; }
DBGMSG(DBG_TRACE,("Leave TBidiRequest QI hr=%x\n", hr)); return hr ; }
STDMETHODIMP_ (ULONG) TBidiRequest::AddRef() { DBGMSG(DBG_TRACE,("Enter TBidiRequest::AddRef ref= %d\n", m_cRef)); return InterlockedIncrement(&m_cRef) ; }
STDMETHODIMP_ (ULONG) TBidiRequest::Release() {
DBGMSG(DBG_TRACE,("Enter TBidiRequest::Release ref= %d\n", m_cRef)); if (InterlockedDecrement(&m_cRef) == 0) { delete this ; return 0 ; } return m_cRef ; }
STDMETHODIMP TBidiRequest::SetSchema( LPCWSTR pszSchema) { HRESULT hr (E_FAIL);
DBGMSG(DBG_TRACE,("Enter SetSchema %ws\n", pszSchema));
if (m_bValid) {
TAutoCriticalSection CritSec (m_CritSec);
if (CritSec.bValid ()) {
if (m_pSchema) { delete[] m_pSchema; m_pSchema = NULL; }
if (pszSchema) { DWORD dwLen = lstrlen (pszSchema) + 1; m_pSchema = new WCHAR [dwLen];
if (m_pSchema) { hr = StringCchCopy (m_pSchema, dwLen, pszSchema); } } else SetLastError (ERROR_INVALID_PARAMETER); }
if (FAILED (hr)) {
hr = LastError2HRESULT(); } } else hr = E_HANDLE;
return hr; }
STDMETHODIMP TBidiRequest::SetInputData( IN CONST DWORD dwType, IN CONST BYTE *pData, IN CONST UINT uSize) { HRESULT hr (S_OK);
DBGMSG(DBG_TRACE,("Enter SetInputData dwType=%d\n", dwType));
if (m_bValid) {
// Verify data type and its size
switch (dwType) { case BIDI_NULL: if (uSize) hr = E_INVALIDARG; break; case BIDI_INT: if (uSize != sizeof (ULONG)) { hr = E_INVALIDARG; } break; case BIDI_FLOAT: if (uSize != sizeof (FLOAT)) { hr = E_INVALIDARG; } break; case BIDI_BOOL: if (uSize != sizeof (BOOL)) { hr = E_INVALIDARG; } break; case BIDI_ENUM: case BIDI_STRING: case BIDI_TEXT: if (uSize != sizeof (WCHAR) * (lstrlen (reinterpret_cast<LPCWSTR> (pData)) + 1)) { hr = E_INVALIDARG; } break; case BIDI_BLOB: hr = S_OK; break; default: hr = E_INVALIDARG; }
if (hr == S_OK) {
TAutoCriticalSection CritSec (m_CritSec);
if (CritSec.bValid ()) {
if (m_pbData) { delete [] m_pbData; m_pbData = NULL; }
m_kDataType = (BIDI_TYPE) dwType; m_dwDataSize = uSize;
if (uSize > 0) { m_pbData = new BYTE [uSize];
if (m_pbData) { CopyMemory (m_pbData, pData, uSize); hr = S_OK; } else hr = E_OUTOFMEMORY; } else hr = S_OK;
} else { hr = LastError2HRESULT(); } } } else hr = E_HANDLE;
return hr; }
STDMETHODIMP TBidiRequest::GetResult( HRESULT *phr) { HRESULT hr;
DBGMSG(DBG_TRACE,("Enter GetResult\n"));
if (m_bValid) {
if (phr) { TAutoCriticalSection CritSec (m_CritSec);
if (CritSec.bValid ()) { *phr = m_hr; hr = S_OK; } else hr = LastError2HRESULT();
} else { hr = E_POINTER; } } else hr = E_HANDLE;
return hr; }
STDMETHODIMP TBidiRequest::GetOutputData( DWORD dwIndex, LPWSTR *ppszSchema, PDWORD pdwType, PBYTE *ppData, PULONG puSize) { HRESULT hr (E_FAIL);
DBGMSG(DBG_TRACE,("Enter GetOutputData\n"));
if (m_bValid) {
if (ppszSchema && ppData && pdwType && puSize) {
TAutoCriticalSection CritSec (m_CritSec); PBYTE pData = NULL; LPWSTR pszSchema = NULL; DWORD dwType = 0; DWORD dwSize = 0;
if (CritSec.bValid ()) { TResponseData * pRespData = m_ResponseDataList.GetItemFromIndex (dwIndex);
if (pRespData) {
LPCTSTR pszRespSchema = pRespData->GetSchema ();
if (pszRespSchema) { DWORD dwLen = ( 1 + lstrlen (pszRespSchema)) * sizeof (TCHAR); pszSchema = (LPWSTR) CoTaskMemAlloc (dwLen);
if (pszSchema) { StringCbCopy (pszSchema, dwLen, pszRespSchema); } else goto Cleanup; } else pszSchema = NULL;
dwType = pRespData->GetType (); dwSize = pRespData->GetSize ();
if (dwSize == 0) { hr = S_OK; } else { pData = (PBYTE) CoTaskMemAlloc (dwSize);
if (pData) { CopyMemory (pData, pRespData->GetData (), dwSize); hr = S_OK; } } } else { SetLastError (ERROR_INVALID_DATA); } } Cleanup: if (FAILED (hr)) { hr = LastError2HRESULT ();
if (pszSchema) { CoTaskMemFree (pszSchema); pszSchema = NULL; } if (pData) { CoTaskMemFree (pData); pData = NULL; } } else { *ppszSchema = pszSchema; *ppData = pData; *pdwType = dwType; *puSize = dwSize; }
} else hr = E_POINTER; } else hr = E_HANDLE;
return hr;
}
STDMETHODIMP TBidiRequest::GetEnumCount( OUT PDWORD pdwTotal) { HRESULT hr;
DBGMSG(DBG_TRACE,("Enter GetOutputData\n"));
if (m_bValid) {
if (pdwTotal) { TAutoCriticalSection CritSec (m_CritSec);
if (CritSec.bValid ()) { BOOL bRet;
bRet = m_ResponseDataList.GetTotalNode (pdwTotal);
if (bRet) { hr = S_OK; } else hr = LastError2HRESULT(); } else hr = LastError2HRESULT(); } else { hr = E_POINTER; } } else hr = E_HANDLE;
return hr; }
STDMETHODIMP TBidiRequest::GetSchema ( OUT LPWSTR *ppszSchema) { HRESULT hr; LPWSTR pStr;
DBGMSG(DBG_TRACE,("Enter GetSchema\n"));
if (m_bValid) {
if (ppszSchema) {
TAutoCriticalSection CritSec (m_CritSec);
if (CritSec.bValid ()) {
if (m_pSchema) {
DWORD dwLen = ( 1 + lstrlen (m_pSchema)) * sizeof (WCHAR); pStr = (LPWSTR) CoTaskMemAlloc (dwLen);
if (pStr) {
hr = StringCbCopy (pStr, dwLen, m_pSchema);
if (SUCCEEDED(hr)) *ppszSchema = pStr; else { *ppszSchema = NULL; CoTaskMemFree (pStr); }
} else hr = E_OUTOFMEMORY; } else { *ppszSchema = NULL; hr = S_OK; } } else hr = LastError2HRESULT(); } else { hr = E_POINTER; } } else hr = E_HANDLE;
return hr; }
STDMETHODIMP TBidiRequest::GetInputData ( OUT PDWORD pdwType, OUT PBYTE *ppData, OUT PULONG puSize) { HRESULT hr;
DBGMSG(DBG_TRACE,("Enter GetInputData\n"));
if (m_bValid) {
if (pdwType && ppData && puSize) {
TAutoCriticalSection CritSec (m_CritSec);
if (CritSec.bValid ()) {
*pdwType = m_kDataType;
if (m_pbData) {
*ppData = (PBYTE) CoTaskMemAlloc (m_dwDataSize);
if (*ppData) { CopyMemory (*ppData, m_pbData, m_dwDataSize); *puSize = m_dwDataSize;
hr = S_OK; } else hr = E_OUTOFMEMORY; } else { *ppData = NULL; *puSize = 0; hr = S_OK; } } else hr = LastError2HRESULT(); } else hr = E_POINTER; } else hr = E_HANDLE;
return hr; }
STDMETHODIMP TBidiRequest::SetResult ( IN CONST HRESULT hrReq) { HRESULT hr;
DBGMSG(DBG_TRACE,("Enter SetResult\n"));
if (m_bValid) {
TAutoCriticalSection CritSec (m_CritSec);
if (CritSec.bValid ()) { m_hr = hrReq; hr = S_OK; } else hr = LastError2HRESULT(); } else hr = E_HANDLE;
return hr; }
STDMETHODIMP TBidiRequest::AppendOutputData ( IN CONST LPCWSTR pszSchema, IN CONST DWORD dwType, IN CONST BYTE *pData, IN CONST ULONG uSize) { HRESULT hr (E_FAIL); BOOL bRet;
DBGMSG(DBG_TRACE,("Enter AppendOutputData\n"));
if (m_bValid) {
TResponseData *pRespData = NULL;
pRespData = new TResponseData (pszSchema, dwType, pData, uSize);
bRet = pRespData && pRespData->bValid ();
if (bRet) {
TAutoCriticalSection CritSec (m_CritSec);
if (CritSec.bValid ()) {
bRet = m_ResponseDataList.AppendItem (pRespData);
if (bRet) { hr = S_OK;
} } }
if (FAILED (hr)) { hr = LastError2HRESULT(); if (pRespData) { delete (pRespData); } } } else hr = E_HANDLE;
return hr; }
|