Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

1010 lines
16 KiB

/*++
Copyright (C) Microsoft Corporation, 1998 - 1998
All rights reserved.
Module Name:
splperst.cxx
Abstract:
Implementation of spooler persisting code
IPrnStream & IStream
Author:
Adina Trufinescu (AdinaTru) 4-Nov-1998
Revision History:
Lazar Ivanov (LazarI) Jul-2000 - moved from printui.
--*/
#include "precomp.h"
#pragma hdrstop
#include "prnprst.hxx"
#include <initguid.h>
#include "winprtp.h"
////////////////////////////////////////
// class TPrnPersist
//
class TPrnPersist: public IPrnStream,
public IStream
{
public:
TPrnPersist(
VOID
);
~TPrnPersist(
VOID
);
/***********
IUnknown
***********/
STDMETHODIMP QueryInterface(REFIID riid, void **ppv);
STDMETHODIMP_(ULONG) AddRef();
STDMETHODIMP_(ULONG) Release();
/***********
IPrnStream
***********/
STDMETHODIMP
BindPrinterAndFile(
IN LPCTSTR pszPrinter,
LPCTSTR pszFile
);
STDMETHODIMP
StorePrinterInfo(
IN DWORD Flag
);
STDMETHODIMP
RestorePrinterInfo(
IN DWORD Flag
);
STDMETHODIMP
QueryPrinterInfo(
IN PrinterPersistentQueryFlag Flag,
OUT PersistentInfo *pPrstInfo
);
/***********
IStream
***********/
HRESULT STDMETHODCALLTYPE
Read( // IMPLEMENTED
VOID * pv,
ULONG cb,
ULONG * pcbRead
);
HRESULT STDMETHODCALLTYPE
Write( //IMPLEMENTED
VOID const* pv,
ULONG cb,
ULONG * pcbWritten
);
HRESULT STDMETHODCALLTYPE
Seek( //IMPLEMENTED
LARGE_INTEGER dlibMove,
DWORD dwOrigin,
ULARGE_INTEGER * plibNewPosition
);
HRESULT STDMETHODCALLTYPE
SetSize(
ULARGE_INTEGER nSize
);
HRESULT STDMETHODCALLTYPE
CopyTo( //NOT_IMPLEMENTED
LPSTREAM pStrm,
ULARGE_INTEGER cb,
ULARGE_INTEGER * pcbRead,
ULARGE_INTEGER * pcbWritten
);
HRESULT STDMETHODCALLTYPE
Commit( //NOT_IMPLEMENTED
IN DWORD dwFlags
);
HRESULT STDMETHODCALLTYPE
Revert( //NOT_IMPLEMENTED
VOID
);
HRESULT STDMETHODCALLTYPE
LockRegion( //NOT_IMPLEMENTED
ULARGE_INTEGER cbOffset,
ULARGE_INTEGER cbLength,
DWORD dwFlags
);
HRESULT STDMETHODCALLTYPE
UnlockRegion( //NOT_IMPLEMENTED
ULARGE_INTEGER cbOffset,
ULARGE_INTEGER cbLength,
DWORD dwFlags
);
HRESULT STDMETHODCALLTYPE
Stat( //NOT_IMPLEMENTED
STATSTG * pStatStg,
DWORD dwFlags
);
HRESULT STDMETHODCALLTYPE
Clone( //NOT_IMPLEMENTED
OUT LPSTREAM * ppStrm
);
private:
LONG m_cRef;
TPrinterPersist *_pPrnPersist;
};
TPrnPersist::
TPrnPersist(
VOID
): m_cRef(1),
_pPrnPersist(NULL)
{
}
TPrnPersist::
~TPrnPersist(
VOID
)
{
if( _pPrnPersist )
{
delete _pPrnPersist;
}
}
/***********
IUnknown
***********/
STDMETHODIMP TPrnPersist::QueryInterface(REFIID riid, void **ppv)
{
// standard implementation
if( !ppv )
{
return E_INVALIDARG;
}
*ppv = NULL;
if( IsEqualIID(riid, IID_IUnknown) || IsEqualIID(riid, IID_IPrnStream) )
{
*ppv = static_cast<IPrnStream*>(this);
}
else if( IsEqualIID(riid, IID_IStream) )
{
*ppv = static_cast<IStream*>(this);
}
else
{
return E_NOINTERFACE;
}
reinterpret_cast<IUnknown*>(*ppv)->AddRef();
return S_OK;
}
STDMETHODIMP_(ULONG) TPrnPersist::AddRef()
{
// standard implementation
return InterlockedIncrement(&m_cRef);
}
STDMETHODIMP_(ULONG) TPrnPersist::Release()
{
// standard implementation
ULONG cRefs = InterlockedDecrement(&m_cRef);
if( 0 == cRefs )
{
delete this;
}
return cRefs;
}
/*++
Name:
TPrnPersist::BindPrinterAndFile
Description:
Creates a PrnStream object if it don't exists and bind it to a printer and a file
Arguments:
printer name
file name
Return Value:
S_OK if succeeded
--*/
STDMETHODIMP
TPrnPersist::
BindPrinterAndFile(
IN LPCTSTR pszPrinter,
IN LPCTSTR pszFile
)
{
HRESULT hr = E_FAIL;
//
// Create the PrnStream location object if this is the first call.
//
if (!_pPrnPersist)
{
_pPrnPersist = new TPrinterPersist;
}
//
// Invoke the BindPrinterAndFile method if the printer stream
// object was create successfully.
//
if (_pPrnPersist != NULL)
{
DBGMSG(DBG_TRACE , ("TPrnPersist::BindPrinterAndFile \n"));
hr = _pPrnPersist->BindPrinterAndFile(pszPrinter, pszFile);
}
else
{
hr = E_OUTOFMEMORY;
}
DBGMSG(DBG_TRACE , ("TPrnPersist::BindPrinterAndFile %x \n" , hr));
return hr;
}
/*++
Name:
TPrnPersist::StorePrinterInfo
Description:
Creates a PrnStream object if it don't exists and invoke StorePrinterInfo
Arguments:
flags that specifies what settings to store
Return Value:
S_OK if succeeded
--*/
STDMETHODIMP
TPrnPersist::
StorePrinterInfo(
IN DWORD Flag
)
{
TStatusH hr;
hr DBGNOCHK = E_FAIL;
DWORD StoredFlags;
//
// Create the PrnStream location object if this is the first call.
//
if (!_pPrnPersist)
{
_pPrnPersist = new TPrinterPersist;
}
//
// Invoke the stote info method if the printer stream
// object was create successfully.
//
DBGMSG(DBG_TRACE , ("TPrnPersist::StorePrinterInfo Flag %x \n" , Flag));
if(_pPrnPersist != NULL)
{
if (VALID_PTR(_pPrnPersist))
{
//
// Winlogon calls this function for TS. We need to catch any possbile exception,
// otherwise we may cause BSOD.
//
__try
{
hr DBGCHK = _pPrnPersist->StorePrinterInfo(Flag, StoredFlags);
}
__except(EXCEPTION_EXECUTE_HANDLER)
{
DBGMSG(DBG_WARNING, ("TPrnPersist::StorePrinterInfo exception %x\n", GetExceptionCode()));
hr DBGCHK = E_FAIL;
}
}
else
{
hr DBGCHK = MakePrnPersistHResult(PRN_PERSIST_ERROR_UNBOUND);
}
}
else
{
hr DBGCHK = E_OUTOFMEMORY;
}
return hr;
}
/*++
Name:
TPrnPersist::RestorePrinterInfo
Description:
Creates a PrnStream object if it don't exists and invoke RestorePrinterInfo
Arguments:
flags that specifies what settings to restore
Return Value:
S_OK if succeeded
--*/
STDMETHODIMP
TPrnPersist::
RestorePrinterInfo(
IN DWORD Flag
)
{
TStatusH hr;
//
// Create the Prnstream location object if this is the first call.
//
if (!_pPrnPersist)
{
_pPrnPersist = new TPrinterPersist;
}
//
// Invoke the restore info method if the printer stream
// object was created successfully.
//
if(_pPrnPersist != NULL)
{
if (VALID_PTR(_pPrnPersist))
{
//
// Winlogon calls this function on the machine where TS runs. If the file from which
// we restore the settings is corrupted, we must protect us against AVs that can occur
// while accessing bad data.
//
__try
{
hr DBGCHK = _pPrnPersist->SafeRestorePrinterInfo(Flag);
}
__except(EXCEPTION_EXECUTE_HANDLER)
{
DBGMSG(DBG_WARNING, ("TPrnPersist::SafeRestorePrinterInfo exception %x\n", GetExceptionCode()));
hr DBGCHK = E_FAIL;
}
}
else
{
hr DBGCHK = MakePrnPersistHResult(PRN_PERSIST_ERROR_UNBOUND);
}
}
else
{
hr DBGCHK = E_OUTOFMEMORY;
}
return hr;
}
/*++
Name:
TPrnPersist::QueryPrinterInfo
Description:
Creates a PrnStream object if it don't exists and invoke QueryPrinterInfo
Arguments:
flags that specifies what settings to query
Return Value:
S_OK if succeeded
--*/
STDMETHODIMP
TPrnPersist::
QueryPrinterInfo(
IN PrinterPersistentQueryFlag Flag,
OUT PersistentInfo *pPrstInfo
)
{
TStatusH hr;
hr DBGNOCHK = E_FAIL;
//
// Create the Prnstream location object if this is the first call.
//
if (!_pPrnPersist)
{
_pPrnPersist = new TPrinterPersist;
}
//
// Invoke the query info method if the printer stream
// object was create successfully.
//
if(_pPrnPersist != NULL)
{
if (VALID_PTR(_pPrnPersist))
{
__try
{
hr DBGCHK = _pPrnPersist->QueryPrinterInfo(Flag , pPrstInfo);
}
__except(EXCEPTION_EXECUTE_HANDLER)
{
DBGMSG(DBG_WARNING, ("TPrnPersist::QueryPrinterInfo exception %x\n", GetExceptionCode()));
hr DBGCHK = E_FAIL;
}
}
else
{
hr DBGCHK = MakePrnPersistHResult(PRN_PERSIST_ERROR_UNBOUND);
}
}
else
{
hr DBGCHK = E_OUTOFMEMORY;
}
return hr;
}
/*++
Name:
TPrnPersist::Read
Description:
Creates a PrnStream object if it don't exists and invoke Read
Arguments:
pv - The buffer that the bytes are read into
cb - The offset in the stream to begin reading from.
pcbRead - The number of bytes to read
Return Value:
S_OK if succeeded
--*/
STDMETHODIMP
TPrnPersist::
Read(
VOID * pv,
ULONG cb,
ULONG * pcbRead
)
{
HRESULT hr = E_FAIL;
//
// Create the Prnstream location object if this is the first call.
//
if (!_pPrnPersist)
{
_pPrnPersist = new TPrinterPersist;
}
//
// Invoke the read method if the printer stream
// object was create successfully.
//
if(_pPrnPersist != NULL)
{
if (VALID_PTR(_pPrnPersist))
{
hr = _pPrnPersist->Read(pv, cb, pcbRead);
}
else
{
hr = MakePrnPersistHResult(PRN_PERSIST_ERROR_UNBOUND);
}
}
else
{
hr = E_OUTOFMEMORY;
}
return hr;
}
/*++
Name:
TPrnPersist::Write
Description:
Creates a PrnStream object if it don't exists and invoke Write
Arguments:
pv - The buffer to write from.
cb - The offset in the array to begin writing from
pcbRead - The number of bytes to write
Return Value:
S_OK if succeeded
--*/
STDMETHODIMP
TPrnPersist::
Write(
VOID const* pv,
ULONG cb,
ULONG * pcbWritten
)
{
HRESULT hr = E_FAIL;
//
// Create the Prnstream location object if this is the first call.
//
if (!_pPrnPersist)
{
_pPrnPersist = new TPrinterPersist;
}
//
// Invoke the write method if the printer stream
// object was create successfully.
//
if(_pPrnPersist != NULL)
{
if (VALID_PTR(_pPrnPersist))
{
hr = _pPrnPersist->Write(pv, cb, pcbWritten);
}
else
{
hr = MakePrnPersistHResult(PRN_PERSIST_ERROR_UNBOUND);
}
}
else
{
hr = E_OUTOFMEMORY;
}
return hr;
}
/*++
Name:
TPrnPersist::Seek
Description:
Creates a PrnStream object if it don't exists and invoke Seek
Arguments:
dlibMove - The offset relative to dwOrigin
dwOrigin - The origin of the offset
plibNewPosition - Pointer to value of the new seek pointer from the beginning of the stream
Return Value:
S_OK if succeeded
--*/
STDMETHODIMP
TPrnPersist::
Seek(
LARGE_INTEGER dlibMove,
DWORD dwOrigin,
ULARGE_INTEGER * plibNewPosition
)
{
HRESULT hr = E_FAIL;
//
// Create the Prnstream location object if this is the first call.
//
if (!_pPrnPersist)
{
_pPrnPersist = new TPrinterPersist;
}
//
// Invoke the seek method if the printer stream
// object was create successfully.
//
if(_pPrnPersist != NULL)
{
if (VALID_PTR(_pPrnPersist))
{
hr = _pPrnPersist->Seek(dlibMove, dwOrigin, plibNewPosition);
}
else
{
hr = MakePrnPersistHResult(PRN_PERSIST_ERROR_UNBOUND);
}
}
else
{
hr = E_OUTOFMEMORY;
}
return hr;
}
/*++
Name:
TPrnPersist::SetSize
Description:
Arguments:
Return Value:
E_NOTIMPL
--*/
STDMETHODIMP
TPrnPersist::
SetSize(
ULARGE_INTEGER nSize
)
{
return E_NOTIMPL;
}
/*++
Name:
TPrnPersist::CopyTo
Description:
Arguments:
Return Value:
E_NOTIMPL
--*/
STDMETHODIMP
TPrnPersist::
CopyTo(
LPSTREAM pStrm,
ULARGE_INTEGER cb,
ULARGE_INTEGER * pcbRead,
ULARGE_INTEGER * pcbWritten
)
{
return E_NOTIMPL;
}
/*++
Name:
TPrnPersist::Commit
Description:
Arguments:
Return Value:
E_NOTIMPL
--*/
STDMETHODIMP
TPrnPersist::
Commit(
IN DWORD dwFlags
)
{
return E_NOTIMPL;
}
/*++
Name:
TPrnPersist::Revert
Description:
Arguments:
Return Value:
E_NOTIMPL
--*/
STDMETHODIMP
TPrnPersist::
Revert(
VOID
)
{
return E_NOTIMPL;
}
/*++
Name:
TPrnPersist::LockRegion
Description:
Arguments:
Return Value:
E_NOTIMPL
--*/
STDMETHODIMP
TPrnPersist::
LockRegion(
ULARGE_INTEGER cbOffset,
ULARGE_INTEGER cbLength,
DWORD dwFlags
)
{
return E_NOTIMPL;
}
/*++
Name:
TPrnPersist::UnlockRegion
Description:
Arguments:
Return Value:
E_NOTIMPL
--*/
STDMETHODIMP
TPrnPersist::
UnlockRegion(
ULARGE_INTEGER cbOffset,
ULARGE_INTEGER cbLength,
DWORD dwFlags
)
{
return E_NOTIMPL;
}
/*++
Name:
TPrnPersist::Stat
Description:
Arguments:
Return Value:
E_NOTIMPL
--*/
STDMETHODIMP
TPrnPersist::
Stat(
STATSTG * pStatStg,
DWORD dwFlags
)
{
return E_NOTIMPL;
}
/*++
Name:
TPrnPersist::Clone
Description:
Arguments:
Return Value:
E_NOTIMPL
--*/
STDMETHODIMP
TPrnPersist::
Clone(
LPSTREAM * ppStrm
)
{
return E_NOTIMPL;
}
#ifdef __cplusplus
extern "C" {
#endif
// forward declarations....
HRESULT TPrnPersist_CreateInstance(REFIID riid, void **ppv);
BOOL WebPnpEntry(LPCTSTR lpszCmdLine);
BOOL WebPnpPostEntry(BOOL fConnection, LPCTSTR lpszBinFile, LPCTSTR lpszPortName, LPCTSTR lpszPrtName);
/*++
Name:
TPrnPersist_CreateInstance
Description:
creates an instance of TPrnPersist
Arguments:
Return Value:
S_OK on sucsess or OLE error on failure.
--*/
HRESULT TPrnPersist_CreateInstance(
IN REFIID riid,
OUT void **ppv
)
{
HRESULT hr = E_INVALIDARG;
if( ppv )
{
*ppv = NULL;
TPrnPersist *pObj = new TPrnPersist;
if( pObj )
{
hr = pObj->QueryInterface( riid, ppv );
pObj->Release( );
}
else
{
hr = E_OUTOFMEMORY;
}
}
return hr;
}
/*++
Name:
PrintUIWebPnpEntry
Description:
wrapper around WebPnpEntry
Arguments:
Return Value:
S_OK on sucsess or OLE error on failure.
--*/
HRESULT PrintUIWebPnpEntry(
LPCTSTR lpszCmdLine
)
{
return WebPnpEntry(lpszCmdLine) ? S_OK : E_FAIL;
}
/*++
Name:
PrintUIWebPnpPostEntry
Description:
wrapper around WebPnpPostEntry
Arguments:
Return Value:
S_OK on sucsess or OLE error on failure.
--*/
HRESULT PrintUIWebPnpPostEntry(BOOL fConnection, LPCTSTR lpszBinFile, LPCTSTR lpszPortName, LPCTSTR lpszPrtName)
{
return WebPnpPostEntry(fConnection, lpszBinFile, lpszPortName, lpszPrtName) ? S_OK : E_FAIL;
}
/*++
Name:
PrintUICreateInstance
Description:
wrapper around TPrnPersist_CreateInstance
Arguments:
Return Value:
S_OK on sucsess or OLE error on failure.
--*/
HRESULT PrintUICreateInstance(REFIID riid, void **ppv)
{
return TPrnPersist_CreateInstance(riid, ppv);
}
#ifdef __cplusplus
}
#endif