575 lines
13 KiB
C++
575 lines
13 KiB
C++
/*****************************************************************************\
|
|
* 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) {
|
|
m_pSchema = new WCHAR [lstrlen (pszSchema) + 1];
|
|
|
|
if (m_pSchema) {
|
|
lstrcpy (m_pSchema, pszSchema);
|
|
hr = S_OK;
|
|
}
|
|
}
|
|
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) {
|
|
pszSchema = (LPWSTR) CoTaskMemAlloc (( 1 + lstrlen (pszRespSchema)) * sizeof (TCHAR));
|
|
|
|
if (pszSchema) {
|
|
lstrcpy (pszSchema, 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) {
|
|
|
|
pStr = (LPWSTR) CoTaskMemAlloc (( 1 + lstrlen (m_pSchema)) * sizeof (WCHAR));
|
|
|
|
if (pStr) {
|
|
|
|
lstrcpy (pStr, m_pSchema);
|
|
|
|
*ppszSchema = pStr;
|
|
|
|
hr = S_OK;
|
|
|
|
}
|
|
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;
|
|
}
|
|
|
|
|