1012 lines
22 KiB
C++
1012 lines
22 KiB
C++
/*++
|
|
|
|
Copyright (c) 1995 Microsoft Corporation
|
|
|
|
Module Name:
|
|
|
|
cenumjob.cxx
|
|
|
|
Abstract:
|
|
|
|
Contains methods for implementing the Enumeration of print jobs on a
|
|
printer. Has methods for the CWinNTPrintJobsCollection object
|
|
as well as the CWinNTJobsEnumVar object.
|
|
|
|
Author:
|
|
|
|
Ram Viswanathan (ramv) 11-28-95
|
|
|
|
Revision History:
|
|
|
|
--*/
|
|
|
|
#include "winnt.hxx"
|
|
#pragma hdrstop
|
|
|
|
CWinNTPrintJobsCollection::CWinNTPrintJobsCollection()
|
|
{
|
|
_pDispMgr = NULL;
|
|
_pCJobsEnumVar = NULL;
|
|
ENLIST_TRACKING(CWinNTPrintJobsCollection);
|
|
}
|
|
|
|
CWinNTPrintJobsCollection::~CWinNTPrintJobsCollection()
|
|
{
|
|
DWORD fStatus;
|
|
|
|
//
|
|
// close the printer and destroy sub objects
|
|
//
|
|
if(_pszADsPrinterPath){
|
|
FreeADsStr(_pszADsPrinterPath);
|
|
}
|
|
|
|
if(_pszPrinterName){
|
|
FreeADsStr(_pszPrinterName);
|
|
}
|
|
|
|
if (_hPrinter){
|
|
fStatus = ClosePrinter(_hPrinter);
|
|
}
|
|
|
|
delete _pDispMgr;
|
|
|
|
}
|
|
|
|
HRESULT
|
|
CWinNTPrintJobsCollection::Create(LPWSTR pszADsPrinterPath,
|
|
CWinNTCredentials& Credentials,
|
|
CWinNTPrintJobsCollection
|
|
** ppCWinNTPrintJobsCollection )
|
|
{
|
|
|
|
BOOL fStatus = FALSE, LastError;
|
|
HANDLE hPrinter = NULL;
|
|
PRINTER_DEFAULTS PrinterDefaults = {0, 0, PRINTER_ACCESS_USE| READ_CONTROL};
|
|
HRESULT hr;
|
|
CWinNTPrintJobsCollection *pCWinNTJobsCollection = NULL;
|
|
POBJECTINFO pObjectInfo = NULL;
|
|
TCHAR szUncPrinterName[MAX_PATH];
|
|
|
|
//
|
|
// create the jobs collection object
|
|
//
|
|
|
|
pCWinNTJobsCollection = new CWinNTPrintJobsCollection();
|
|
if(pCWinNTJobsCollection == NULL) {
|
|
hr = E_OUTOFMEMORY;
|
|
goto error;
|
|
}
|
|
|
|
hr = BuildObjectInfo(pszADsPrinterPath,
|
|
&pObjectInfo
|
|
);
|
|
|
|
BAIL_ON_FAILURE(hr);
|
|
|
|
pCWinNTJobsCollection->_Credentials = Credentials;
|
|
hr = pCWinNTJobsCollection->_Credentials.RefServer(
|
|
pObjectInfo->ComponentArray[1]);
|
|
BAIL_ON_FAILURE(hr);
|
|
|
|
|
|
hr = PrinterNameFromObjectInfo(pObjectInfo,
|
|
szUncPrinterName
|
|
);
|
|
|
|
BAIL_ON_FAILURE(hr);
|
|
|
|
|
|
|
|
pCWinNTJobsCollection->_pszPrinterName =
|
|
AllocADsStr(szUncPrinterName);
|
|
|
|
if(!(pCWinNTJobsCollection->_pszPrinterName)){
|
|
hr = E_OUTOFMEMORY;
|
|
goto error;
|
|
}
|
|
|
|
|
|
pCWinNTJobsCollection->_pszADsPrinterPath =
|
|
AllocADsStr(pszADsPrinterPath);
|
|
|
|
if(!(pCWinNTJobsCollection->_pszADsPrinterPath)){
|
|
hr = E_OUTOFMEMORY;
|
|
goto error;
|
|
}
|
|
|
|
//
|
|
// open printer and set the handle to the appropriate value
|
|
//
|
|
|
|
fStatus = OpenPrinter(szUncPrinterName,
|
|
&hPrinter,
|
|
&PrinterDefaults
|
|
);
|
|
|
|
if (!fStatus) {
|
|
LastError = GetLastError();
|
|
|
|
switch (LastError) {
|
|
case ERROR_ACCESS_DENIED:
|
|
{
|
|
PRINTER_DEFAULTS PrinterDefaults = {0, 0, PRINTER_ACCESS_USE};
|
|
fStatus = OpenPrinter(szUncPrinterName,
|
|
&hPrinter,
|
|
&PrinterDefaults
|
|
);
|
|
if (!fStatus) {
|
|
hr = HRESULT_FROM_WIN32(GetLastError());
|
|
}
|
|
break;
|
|
}
|
|
default:
|
|
hr = HRESULT_FROM_WIN32(GetLastError());
|
|
break;
|
|
|
|
}
|
|
}
|
|
|
|
BAIL_ON_FAILURE(hr);
|
|
|
|
pCWinNTJobsCollection->_hPrinter = hPrinter;
|
|
|
|
pCWinNTJobsCollection->_pDispMgr = new CAggregatorDispMgr;
|
|
if (pCWinNTJobsCollection->_pDispMgr == NULL){
|
|
hr = E_OUTOFMEMORY;
|
|
goto error;
|
|
}
|
|
|
|
|
|
hr = LoadTypeInfoEntry(pCWinNTJobsCollection->_pDispMgr,
|
|
LIBID_ADs,
|
|
IID_IADsCollection,
|
|
(IADsCollection *)pCWinNTJobsCollection,
|
|
DISPID_NEWENUM
|
|
);
|
|
|
|
BAIL_ON_FAILURE(hr);
|
|
|
|
*ppCWinNTPrintJobsCollection =pCWinNTJobsCollection;
|
|
|
|
if(pObjectInfo){
|
|
FreeObjectInfo(pObjectInfo);
|
|
}
|
|
|
|
RRETURN(hr);
|
|
|
|
error:
|
|
delete pCWinNTJobsCollection;
|
|
|
|
if(pObjectInfo){
|
|
FreeObjectInfo(pObjectInfo);
|
|
}
|
|
|
|
RRETURN_EXP_IF_ERR(hr);
|
|
|
|
}
|
|
|
|
/* IUnknown methods for jobs collection object */
|
|
|
|
STDMETHODIMP
|
|
CWinNTPrintJobsCollection::QueryInterface(REFIID riid, LPVOID FAR* ppvObj)
|
|
{
|
|
if(!ppvObj)
|
|
{
|
|
RRETURN(E_POINTER);
|
|
}
|
|
|
|
if (IsEqualIID(riid, IID_IUnknown))
|
|
{
|
|
*ppvObj = this;
|
|
}
|
|
|
|
else if (IsEqualIID(riid, IID_IDispatch))
|
|
{
|
|
*ppvObj = (IDispatch *)this;
|
|
}
|
|
|
|
else if (IsEqualIID(riid, IID_ISupportErrorInfo))
|
|
{
|
|
*ppvObj = (ISupportErrorInfo FAR *) this;
|
|
}
|
|
|
|
else if (IsEqualIID(riid, IID_IADsCollection))
|
|
{
|
|
*ppvObj = (IADsCollection FAR *)this;
|
|
}
|
|
else
|
|
{
|
|
*ppvObj = NULL;
|
|
return E_NOINTERFACE;
|
|
}
|
|
((LPUNKNOWN)*ppvObj)->AddRef();
|
|
RRETURN(S_OK);
|
|
}
|
|
|
|
|
|
/* ISupportErrorInfo method */
|
|
STDMETHODIMP
|
|
CWinNTPrintJobsCollection::InterfaceSupportsErrorInfo(
|
|
THIS_ REFIID riid
|
|
)
|
|
{
|
|
if (IsEqualIID(riid, IID_IADsCollection)) {
|
|
RRETURN(S_OK);
|
|
} else {
|
|
RRETURN(S_FALSE);
|
|
}
|
|
}
|
|
|
|
DEFINE_IDispatch_Implementation(CWinNTPrintJobsCollection);
|
|
|
|
|
|
/* IADsCollection methods */
|
|
|
|
|
|
STDMETHODIMP
|
|
CWinNTPrintJobsCollection::get__NewEnum(THIS_ IUnknown * FAR* retval)
|
|
{
|
|
HRESULT hr;
|
|
CWinNTJobsEnumVar *pCJobsEnumVar = NULL;
|
|
|
|
if(!retval){
|
|
RRETURN_EXP_IF_ERR(E_POINTER);
|
|
}
|
|
*retval = NULL;
|
|
|
|
hr = CWinNTJobsEnumVar::Create(_hPrinter,
|
|
_pszADsPrinterPath,
|
|
_Credentials,
|
|
&pCJobsEnumVar);
|
|
|
|
if (FAILED(hr)) {
|
|
goto error;
|
|
}
|
|
|
|
ADsAssert(pCJobsEnumVar);
|
|
|
|
_pCJobsEnumVar = pCJobsEnumVar;
|
|
|
|
hr = _pCJobsEnumVar->QueryInterface(IID_IUnknown,
|
|
(void **)retval
|
|
);
|
|
|
|
BAIL_ON_FAILURE(hr);
|
|
|
|
_pCJobsEnumVar->Release();
|
|
|
|
RRETURN(S_OK);
|
|
|
|
error:
|
|
delete pCJobsEnumVar;
|
|
RRETURN_EXP_IF_ERR(hr);
|
|
}
|
|
|
|
STDMETHODIMP
|
|
CWinNTPrintJobsCollection::GetObject(THIS_ BSTR bstrJobName,
|
|
VARIANT *pvar)
|
|
{
|
|
HRESULT hr;
|
|
DWORD dwJobId;
|
|
IDispatch *pDispatch = NULL;
|
|
|
|
|
|
if(!bstrJobName || !pvar){
|
|
RRETURN_EXP_IF_ERR(E_ADS_BAD_PARAMETER);
|
|
}
|
|
|
|
dwJobId = (DWORD)_wtol(bstrJobName);
|
|
|
|
hr = CWinNTPrintJob::CreatePrintJob(_pszADsPrinterPath,
|
|
dwJobId,
|
|
ADS_OBJECT_BOUND,
|
|
IID_IDispatch,
|
|
_Credentials,
|
|
(void **)&pDispatch);
|
|
|
|
BAIL_IF_ERROR(hr);
|
|
|
|
//
|
|
// stick this IDispatch pointer into caller provided variant
|
|
//
|
|
|
|
VariantInit(pvar);
|
|
V_VT(pvar) = VT_DISPATCH;
|
|
V_DISPATCH(pvar) = pDispatch;
|
|
|
|
cleanup:
|
|
RRETURN_EXP_IF_ERR(hr);
|
|
}
|
|
|
|
STDMETHODIMP
|
|
CWinNTPrintJobsCollection::Add(THIS_ BSTR bstrName, VARIANT varNewItem)
|
|
{
|
|
RRETURN_EXP_IF_ERR(E_NOTIMPL);
|
|
}
|
|
|
|
STDMETHODIMP
|
|
CWinNTPrintJobsCollection::Remove(THIS_ BSTR bstrJobName)
|
|
{
|
|
DWORD dwJobId;
|
|
HRESULT hr = S_OK;
|
|
HANDLE hPrinter = NULL;
|
|
BOOL fStatus = FALSE;
|
|
PRINTER_DEFAULTS PrinterDefaults = {0, 0, PRINTER_ACCESS_USE};
|
|
|
|
if(! bstrJobName){
|
|
RRETURN_EXP_IF_ERR(E_ADS_BAD_PARAMETER);
|
|
}
|
|
|
|
//
|
|
// convert the job name into a jobid
|
|
//
|
|
|
|
dwJobId = (DWORD)_wtol(bstrJobName);
|
|
|
|
fStatus = OpenPrinter((LPTSTR)_pszPrinterName,
|
|
&hPrinter,
|
|
&PrinterDefaults
|
|
);
|
|
|
|
if (!fStatus) {
|
|
hr = HRESULT_FROM_WIN32(GetLastError());
|
|
goto cleanup;
|
|
}
|
|
|
|
|
|
//
|
|
// use JOB_CONTROL_DELETE instead of JOB_CONTROL_CANCEL as DELETE works
|
|
// even when a print job has been restarted while CANCEL won't
|
|
//
|
|
|
|
fStatus = SetJob (hPrinter,
|
|
dwJobId,
|
|
0,
|
|
NULL,
|
|
JOB_CONTROL_DELETE
|
|
);
|
|
|
|
if (!fStatus) {
|
|
hr = HRESULT_FROM_WIN32(GetLastError());
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
cleanup:
|
|
|
|
if (hPrinter) {
|
|
ClosePrinter(hPrinter);
|
|
}
|
|
|
|
RRETURN (hr);
|
|
}
|
|
|
|
|
|
|
|
|
|
//
|
|
// CWinNTJobsEnumVar methods follow
|
|
//
|
|
|
|
//+---------------------------------------------------------------------------
|
|
//
|
|
// Function: CWinNTJobsEnumVar::CWinNTJobsEnumVar
|
|
//
|
|
// Synopsis:
|
|
//
|
|
//
|
|
// Arguments:
|
|
//
|
|
//
|
|
// Returns:
|
|
//
|
|
// Modifies:
|
|
//
|
|
// History: 11-22-95 RamV Created.
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
|
|
CWinNTJobsEnumVar::CWinNTJobsEnumVar()
|
|
{
|
|
_pszADsPrinterPath = NULL;
|
|
_pSafeArray = NULL;
|
|
_cElements = 0;
|
|
_lLBound = 0;
|
|
_lCurrentPosition = _lLBound;
|
|
ENLIST_TRACKING(CWinNTJobsEnumVar);
|
|
|
|
}
|
|
|
|
//+---------------------------------------------------------------------------
|
|
//
|
|
// Function: CWinNTJobsEnumVar::~CWinNTJobsEnumVar
|
|
//
|
|
// Synopsis:
|
|
//
|
|
//
|
|
// Arguments:
|
|
//
|
|
// Returns:
|
|
//
|
|
// Modifies:
|
|
//
|
|
// History: 11-22-95 RamV Created.
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
CWinNTJobsEnumVar::~CWinNTJobsEnumVar()
|
|
{
|
|
if (_pSafeArray != NULL)
|
|
SafeArrayDestroy(_pSafeArray);
|
|
|
|
_pSafeArray = NULL;
|
|
if(_pszADsPrinterPath){
|
|
FreeADsStr(_pszADsPrinterPath);
|
|
}
|
|
}
|
|
|
|
|
|
HRESULT CWinNTJobsEnumVar::Create(HANDLE hPrinter,
|
|
LPTSTR szADsPrinterPath,
|
|
CWinNTCredentials& Credentials,
|
|
CWinNTJobsEnumVar ** ppCJobsEnumVar)
|
|
{
|
|
|
|
//
|
|
// This function uses the handle to the printer to query for the
|
|
// number of jobs(cJobs) on the printer, It uses the returned value
|
|
// to create a safearray of cJobs number of Job Objects.
|
|
//
|
|
|
|
HRESULT hr;
|
|
BOOL fStatus = FALSE;
|
|
PRINTER_DEFAULTS PrinterDefaults = {0, 0, PRINTER_ACCESS_USE| READ_CONTROL};
|
|
|
|
OBJECTINFO ObjectInfo;
|
|
CLexer Lexer(szADsPrinterPath);
|
|
|
|
CWinNTJobsEnumVar FAR* pCJobsEnumVar = NULL;
|
|
|
|
*ppCJobsEnumVar = NULL;
|
|
|
|
memset((void*)&ObjectInfo, 0, sizeof(OBJECTINFO));
|
|
|
|
pCJobsEnumVar = new CWinNTJobsEnumVar();
|
|
|
|
if (pCJobsEnumVar == NULL){
|
|
hr = E_OUTOFMEMORY;
|
|
goto error;
|
|
}
|
|
|
|
pCJobsEnumVar->_pszADsPrinterPath = AllocADsStr(szADsPrinterPath);
|
|
|
|
if (!(pCJobsEnumVar->_pszADsPrinterPath)){
|
|
hr = E_OUTOFMEMORY;
|
|
goto error;
|
|
}
|
|
|
|
hr = Object(&Lexer, &ObjectInfo);
|
|
BAIL_ON_FAILURE(hr);
|
|
|
|
pCJobsEnumVar->_Credentials = Credentials;
|
|
// We want the next-to-last element in the array.
|
|
ADsAssert(ObjectInfo.NumComponents >= 2);
|
|
hr = pCJobsEnumVar->_Credentials.RefServer(
|
|
ObjectInfo.ComponentArray[(ObjectInfo.NumComponents - 1) - 1]);
|
|
BAIL_ON_FAILURE(hr);
|
|
|
|
//
|
|
// Fill in the safearray with relevant information here
|
|
//
|
|
|
|
hr = FillSafeArray(hPrinter, szADsPrinterPath, pCJobsEnumVar->_Credentials,
|
|
pCJobsEnumVar);
|
|
|
|
BAIL_ON_FAILURE(hr);
|
|
|
|
*ppCJobsEnumVar = pCJobsEnumVar;
|
|
|
|
//
|
|
// Free the objectInfo data
|
|
//
|
|
FreeObjectInfo( &ObjectInfo, TRUE );
|
|
RRETURN(S_OK);
|
|
|
|
error:
|
|
|
|
//
|
|
// Free the objectInfo data
|
|
//
|
|
FreeObjectInfo( &ObjectInfo, TRUE );
|
|
delete pCJobsEnumVar;
|
|
RRETURN_EXP_IF_ERR(hr);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
//+------------------------------------------------------------------------
|
|
//
|
|
// Function: CWinNTJobsEnumVar::QueryInterface
|
|
//
|
|
// Synopsis:
|
|
//
|
|
// Arguments: [iid]
|
|
// [ppv]
|
|
//
|
|
// Returns: HRESULT
|
|
//
|
|
// Modifies:
|
|
//
|
|
// History: 11-22-95 RamV Created.
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
|
|
STDMETHODIMP
|
|
CWinNTJobsEnumVar::QueryInterface(REFIID iid, void FAR* FAR* ppv)
|
|
{
|
|
if(!ppv){
|
|
RRETURN(E_POINTER);
|
|
}
|
|
*ppv = NULL;
|
|
|
|
if (iid == IID_IUnknown )
|
|
{
|
|
*ppv = this;
|
|
}
|
|
else if(iid == IID_IEnumVARIANT)
|
|
{
|
|
*ppv = (IEnumVARIANT *)this;
|
|
}
|
|
|
|
else
|
|
{
|
|
return E_NOINTERFACE;
|
|
}
|
|
|
|
AddRef();
|
|
RRETURN(S_OK);
|
|
}
|
|
|
|
|
|
//+---------------------------------------------------------------------------
|
|
//
|
|
// Function: CWinNTJobsEnumVar::Next
|
|
//
|
|
// Synopsis: Returns cElements number of requested Job objects in the
|
|
// array supplied in pvar.
|
|
//
|
|
// Arguments: [cElements] -- The number of elements requested by client
|
|
// [pvar] -- ptr to array of VARIANTs to for return objects
|
|
// [pcElementFetched] -- if non-NULL, then number of elements
|
|
// -- actually returned is placed here
|
|
//
|
|
// Returns: HRESULT -- S_OK if number of elements requested are returned
|
|
// -- S_FALSE if number of elements is < requested
|
|
//
|
|
// Modifies:
|
|
//
|
|
// History: 11-27-95 RamV Created.
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
|
|
STDMETHODIMP
|
|
CWinNTJobsEnumVar::Next(ULONG ulNumElementsRequested,
|
|
VARIANT FAR* pvar,
|
|
ULONG FAR* pulNumFetched)
|
|
{
|
|
|
|
HRESULT hresult;
|
|
ULONG l;
|
|
LONG lNewCurrent;
|
|
ULONG lNumFetched;
|
|
|
|
|
|
if (pulNumFetched != NULL)
|
|
*pulNumFetched = 0;
|
|
|
|
//
|
|
// Initialize the elements to be returned
|
|
//
|
|
|
|
for (l=0; l<ulNumElementsRequested; l++)
|
|
VariantInit(&pvar[l]);
|
|
|
|
//
|
|
// Get each element and place it into the return array
|
|
// Don't request more than we have
|
|
//
|
|
|
|
for (lNewCurrent=_lCurrentPosition, lNumFetched=0;
|
|
lNewCurrent<(LONG)(_lLBound+_cElements) &&
|
|
lNumFetched < ulNumElementsRequested;
|
|
lNewCurrent++, lNumFetched++){
|
|
|
|
hresult = SafeArrayGetElement(_pSafeArray, &lNewCurrent,
|
|
&pvar[lNumFetched]);
|
|
//
|
|
// Something went wrong!!!
|
|
//
|
|
|
|
if (FAILED(hresult)){
|
|
for (l=0; l<ulNumElementsRequested; l++)
|
|
VariantClear(&pvar[l]);
|
|
|
|
ADsAssert(hresult == S_FALSE);
|
|
return(S_FALSE);
|
|
|
|
} // End of If Failed
|
|
}
|
|
|
|
//
|
|
// Tell the caller how many we got (which may be less than the number
|
|
// requested), and save the current position
|
|
//
|
|
|
|
if (pulNumFetched != NULL)
|
|
*pulNumFetched = lNumFetched;
|
|
|
|
_lCurrentPosition = lNewCurrent;
|
|
|
|
//
|
|
// If we're returning less than they asked for return S_FALSE, but
|
|
// they still have the data (S_FALSE is a success code)
|
|
//
|
|
|
|
return (lNumFetched < ulNumElementsRequested) ?
|
|
S_FALSE
|
|
: S_OK;
|
|
}
|
|
|
|
//+---------------------------------------------------------------------------
|
|
//
|
|
// Function: CWinNTJobsEnumVar::Skip
|
|
//
|
|
// Synopsis:
|
|
//
|
|
// Arguments: [cElements]
|
|
//
|
|
// Returns: HRESULT
|
|
//
|
|
// Modifies:
|
|
//
|
|
// History: 11-22-95 RamV Created.
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
STDMETHODIMP
|
|
CWinNTJobsEnumVar::Skip(ULONG cElements)
|
|
{
|
|
//
|
|
// Skip the number of elements requested
|
|
//
|
|
|
|
_lCurrentPosition += cElements;
|
|
|
|
//
|
|
// if we went outside of the boundaries unskip
|
|
//
|
|
|
|
if (_lCurrentPosition > (LONG)(_lLBound +_cElements)){
|
|
_lCurrentPosition = _lLBound +_cElements;
|
|
return (S_FALSE);
|
|
}
|
|
else
|
|
RRETURN(S_OK);
|
|
|
|
}
|
|
|
|
//+---------------------------------------------------------------------------
|
|
//
|
|
// Function: CWinNTJobsEnumVar::Reset
|
|
//
|
|
// Synopsis:
|
|
//
|
|
// Arguments: []
|
|
//
|
|
// Returns: HRESULT
|
|
//
|
|
// Modifies:
|
|
//
|
|
// History:
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
STDMETHODIMP
|
|
CWinNTJobsEnumVar::Reset()
|
|
{
|
|
//
|
|
//Just move the CurrentPosition to the lower array boundary
|
|
//
|
|
|
|
_lCurrentPosition = _lLBound;
|
|
|
|
RRETURN(S_OK);
|
|
}
|
|
|
|
|
|
//+---------------------------------------------------------------------------
|
|
//
|
|
// Function: CWinNTJobsEnumVar::Clone
|
|
//
|
|
// Synopsis:
|
|
//
|
|
// Arguments: [pCollection]
|
|
// [ppEnumVariant]
|
|
//
|
|
// Returns: HRESULT
|
|
//
|
|
// Modifies:
|
|
//
|
|
// History: 11-22-95 RamV Created.
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
STDMETHODIMP
|
|
CWinNTJobsEnumVar::Clone(IEnumVARIANT FAR* FAR* ppenum)
|
|
{
|
|
RRETURN_EXP_IF_ERR(E_ADS_PROPERTY_NOT_SUPPORTED);
|
|
}
|
|
|
|
|
|
HRESULT FillSafeArray(HANDLE hPrinter,
|
|
LPTSTR szPrinterPath,
|
|
CWinNTCredentials& Credentials,
|
|
CWinNTJobsEnumVar *pJobsEnumVar )
|
|
{
|
|
BOOL fStatus = FALSE;
|
|
DWORD dwPassed =0, dwNeeded = 0;
|
|
DWORD dwcJobs; // Number of jobs in print queue
|
|
LPPRINTER_INFO_2 pPrinterInfo2;
|
|
DWORD dwError = 0, LastError =0;
|
|
LPBYTE pMem = NULL;
|
|
LPBYTE lpbJobs = NULL;
|
|
DWORD cbBuf =0;
|
|
DWORD dwReturned =0;
|
|
CWinNTPrintJob *pCWinNTPrintJob = NULL;
|
|
SAFEARRAYBOUND sabound[1];
|
|
IDispatch *pDispatch;
|
|
VARIANT v;
|
|
LONG l;
|
|
HRESULT hr = S_OK;
|
|
LPJOB_INFO_1 lpJobInfo1 = NULL;
|
|
|
|
if(hPrinter == NULL){
|
|
RRETURN_EXP_IF_ERR(HRESULT_FROM_WIN32(ERROR_INVALID_HANDLE));
|
|
}
|
|
|
|
VariantInit(&v);
|
|
|
|
//
|
|
// First Get info from printer to determine the number of jobs.
|
|
// AjayR: 10-01-99. We always expect this call to fail but tell
|
|
// us how much memory is needed !!!
|
|
//
|
|
|
|
fStatus = GetPrinter(hPrinter,
|
|
2,
|
|
(LPBYTE)pMem,
|
|
dwPassed,
|
|
&dwNeeded
|
|
);
|
|
|
|
if (!fStatus) {
|
|
LastError = GetLastError();
|
|
switch (LastError) {
|
|
case ERROR_INSUFFICIENT_BUFFER:
|
|
if (pMem){
|
|
FreeADsMem(pMem);
|
|
}
|
|
dwPassed = dwNeeded;
|
|
pMem = (LPBYTE)AllocADsMem(dwPassed);
|
|
|
|
if (!pMem) {
|
|
|
|
hr = E_OUTOFMEMORY;
|
|
break;
|
|
}
|
|
|
|
fStatus = GetPrinter(hPrinter,
|
|
2,
|
|
(LPBYTE)pMem,
|
|
dwPassed,
|
|
&dwNeeded
|
|
);
|
|
if (!fStatus) {
|
|
hr = HRESULT_FROM_WIN32(GetLastError());
|
|
}
|
|
break;
|
|
|
|
default:
|
|
hr = HRESULT_FROM_WIN32(GetLastError());;
|
|
break;
|
|
|
|
}
|
|
}
|
|
|
|
if(FAILED(hr))
|
|
goto error;
|
|
|
|
pPrinterInfo2 =(LPPRINTER_INFO_2)pMem;
|
|
dwcJobs = pPrinterInfo2->cJobs;
|
|
|
|
fStatus = MyEnumJobs(hPrinter,
|
|
0, // First job you want
|
|
dwcJobs,
|
|
1, //Job Info level
|
|
&lpbJobs,
|
|
&cbBuf,
|
|
&dwReturned
|
|
);
|
|
|
|
if(!fStatus){
|
|
hr =HRESULT_FROM_WIN32(GetLastError());
|
|
goto error;
|
|
}
|
|
|
|
//
|
|
// Use the array bound as the number of jobs returned, not
|
|
// the number of jobs you requested, this may have changed!
|
|
//
|
|
|
|
sabound[0].cElements = dwReturned;
|
|
sabound[0].lLbound = 0;
|
|
|
|
//
|
|
// Create a one dimensional SafeArray
|
|
//
|
|
|
|
pJobsEnumVar->_pSafeArray = SafeArrayCreate(VT_VARIANT, 1, sabound);
|
|
|
|
if (pJobsEnumVar->_pSafeArray == NULL){
|
|
hr = E_OUTOFMEMORY;
|
|
goto error;
|
|
}
|
|
|
|
|
|
//
|
|
// for each of the Jobs retrieved create the appropriate structure
|
|
//
|
|
|
|
for(l=0; l<(LONG)dwReturned; l++){
|
|
|
|
lpJobInfo1 = (LPJOB_INFO_1)(lpbJobs +l*sizeof(JOB_INFO_1));
|
|
|
|
hr = CWinNTPrintJob::CreatePrintJob(
|
|
szPrinterPath,
|
|
lpJobInfo1->JobId,
|
|
ADS_OBJECT_BOUND,
|
|
IID_IDispatch,
|
|
Credentials,
|
|
(void **)&pDispatch
|
|
);
|
|
|
|
if(FAILED(hr)){
|
|
break;
|
|
}
|
|
|
|
VariantInit(&v);
|
|
V_VT(&v) = VT_DISPATCH;
|
|
V_DISPATCH(&v) = pDispatch;
|
|
|
|
//
|
|
// Stick the caller provided data into the end of the SafeArray
|
|
//
|
|
|
|
hr = SafeArrayPutElement(pJobsEnumVar->_pSafeArray, &l, &v);
|
|
VariantClear(&v);
|
|
|
|
if (FAILED(hr)){
|
|
break;
|
|
}
|
|
pJobsEnumVar->_cElements++;
|
|
|
|
}
|
|
|
|
BAIL_ON_FAILURE(hr);
|
|
|
|
|
|
if (pMem) {
|
|
FreeADsMem(pMem);
|
|
}
|
|
|
|
if(lpbJobs){
|
|
FreeADsMem(lpbJobs);
|
|
}
|
|
|
|
RRETURN(S_OK);
|
|
|
|
|
|
error:
|
|
if (pMem) {
|
|
FreeADsMem(pMem);
|
|
}
|
|
|
|
//
|
|
// Free the buffer you just allocated
|
|
//
|
|
|
|
if (lpbJobs){
|
|
FreeADsMem(lpbJobs);
|
|
}
|
|
|
|
//
|
|
// Destroy the safearray
|
|
//
|
|
|
|
if(pJobsEnumVar->_pSafeArray != NULL)
|
|
SafeArrayDestroy(pJobsEnumVar->_pSafeArray);
|
|
|
|
VariantClear(&v);
|
|
RRETURN_EXP_IF_ERR(hr);
|
|
}
|
|
|
|
|
|
|
|
BOOL
|
|
MyEnumJobs(HANDLE hPrinter,
|
|
DWORD dwFirstJob,
|
|
DWORD dwNoJobs,
|
|
DWORD dwLevel,
|
|
LPBYTE *lplpbJobs,
|
|
DWORD *pcbBuf,
|
|
LPDWORD lpdwReturned
|
|
)
|
|
{
|
|
|
|
BOOL fStatus = FALSE;
|
|
DWORD dwNeeded = 0;
|
|
DWORD dwError = 0;
|
|
|
|
|
|
fStatus = EnumJobs(hPrinter,
|
|
dwFirstJob,
|
|
dwNoJobs,
|
|
dwLevel,
|
|
*lplpbJobs,
|
|
*pcbBuf,
|
|
&dwNeeded,
|
|
lpdwReturned
|
|
);
|
|
|
|
|
|
if (!fStatus) {
|
|
if ((dwError = GetLastError()) == ERROR_INSUFFICIENT_BUFFER) {
|
|
|
|
if (*lplpbJobs) {
|
|
FreeADsMem( *lplpbJobs );
|
|
}
|
|
|
|
*lplpbJobs = (LPBYTE)AllocADsMem(dwNeeded);
|
|
|
|
if (!*lplpbJobs) {
|
|
*pcbBuf = 0;
|
|
return(FALSE);
|
|
}
|
|
|
|
*pcbBuf = dwNeeded;
|
|
|
|
|
|
fStatus = EnumJobs(hPrinter,
|
|
dwFirstJob,
|
|
dwNoJobs,
|
|
dwLevel,
|
|
*lplpbJobs,
|
|
*pcbBuf,
|
|
&dwNeeded,
|
|
lpdwReturned
|
|
);
|
|
|
|
if (!fStatus) {
|
|
return(FALSE);
|
|
|
|
}else {
|
|
return(TRUE);
|
|
}
|
|
}else {
|
|
return(FALSE);
|
|
}
|
|
}else {
|
|
return(TRUE);
|
|
}
|
|
|
|
}
|