482 lines
16 KiB
C++
482 lines
16 KiB
C++
/******************************************************************
|
|
PrintSys.CPP -- WMI provider class implementation
|
|
|
|
Generated by Microsoft WMI Code Generation Engine
|
|
|
|
TO DO: - See individual function headers
|
|
- When linking, make sure you link to framedyd.lib &
|
|
msvcrtd.lib (debug) or framedyn.lib & msvcrt.lib (retail).
|
|
|
|
Description:
|
|
|
|
|
|
|
|
******************************************************************/
|
|
|
|
#include "pchealth.h"
|
|
#include "PrintSys.h"
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// tracing stuff
|
|
|
|
#ifdef THIS_FILE
|
|
#undef THIS_FILE
|
|
#endif
|
|
static char __szTraceSourceFile[] = __FILE__;
|
|
#define THIS_FILE __szTraceSourceFile
|
|
#define TRACE_ID DCID_PRINTERDRIVER
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// initialization
|
|
|
|
CPrintSys MyPrintSysSet (PROVIDER_NAME_PRINTSYS, PCH_NAMESPACE) ;
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// Property names
|
|
|
|
const static WCHAR *c_wszGenDrv = L"GenDrv";
|
|
const static WCHAR *c_wszName = L"Name";
|
|
const static WCHAR *c_wszPath = L"Path";
|
|
const static WCHAR *c_wszUniDrv = L"UniDrv";
|
|
const static WCHAR *c_wszUsePrintMgrSpooling = L"UsePrintMgrSpooling";
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
// construction / destruction
|
|
|
|
// ***************************************************************************
|
|
CPrintSys::CPrintSys (LPCWSTR lpwszName, LPCWSTR lpwszNameSpace ) :
|
|
Provider(lpwszName, lpwszNameSpace)
|
|
{
|
|
m_pParamOut = NULL;
|
|
m_pCurrent = NULL;
|
|
m_pParamIn = NULL;
|
|
m_lFlags = 0;
|
|
}
|
|
|
|
// ***************************************************************************
|
|
CPrintSys::~CPrintSys()
|
|
{
|
|
}
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
// exposed methods
|
|
|
|
// *****************************************************************************
|
|
HRESULT CPrintSys::EnumerateInstances(MethodContext *pMethodContext, long lFlags)
|
|
{
|
|
TraceFunctEnter("CPrintSys::EnumerateInstances");
|
|
|
|
HRESULT hr = WBEM_S_NO_ERROR;
|
|
|
|
// Create a new instance of PCH_Printer Class based on the passed-in MethodContext
|
|
CInstancePtr pPrintSysInst(CreateNewInstance(pMethodContext), false);
|
|
|
|
hr = this->GetObject(pPrintSysInst, 0);
|
|
|
|
TraceFunctLeave();
|
|
return hr;
|
|
}
|
|
|
|
// *****************************************************************************
|
|
HRESULT CPrintSys::ExecMethod (const CInstance& Instance,
|
|
const BSTR bstrMethodName,
|
|
CInstance *pInParams, CInstance *pOutParams,
|
|
long lFlags)
|
|
{
|
|
return WBEM_E_PROVIDER_NOT_CAPABLE;
|
|
}
|
|
|
|
// *****************************************************************************
|
|
HRESULT CPrintSys::GetObject(CInstance* pInstance, long lFlags)
|
|
{
|
|
TraceFunctEnter("CPrintSys::GetObject");
|
|
|
|
HRESULT hr = WBEM_S_NO_ERROR;
|
|
|
|
// Objects
|
|
IWbemClassObjectPtr pFileObj = NULL;
|
|
|
|
// Variants
|
|
CComVariant varValue;
|
|
CComVariant varNotAvail = L"Not Available";
|
|
|
|
// Strings
|
|
CComBSTR bstrDriverWithPath;
|
|
CComBSTR bstrDetails;
|
|
CComBSTR bstrVersion = L"Version";
|
|
CComBSTR bstrFileSize = L"FileSize";
|
|
CComBSTR bstrModifiedDate = L"LastModified";
|
|
|
|
LPCTSTR lpctstrUniDriver = _T("unidrv.dll");
|
|
LPCTSTR lpctstrGenDriver = _T("gendrv.dll");
|
|
LPCTSTR lpctstrWindows = _T("Windows");
|
|
LPCTSTR lpctstrDevice = _T("Device");
|
|
LPCTSTR lpctstrNoUniDrv = _T("(unidrv.dll) = NotInstalled");
|
|
LPCTSTR lpctstrNoGenDrv = _T("(gendrv.dll) = NotInstalled");
|
|
LPCTSTR lpctstrPrintersHive = _T("System\\CurrentControlSet\\Control\\Print\\Printers");
|
|
LPCTSTR lpctstrYes = _T("yes");
|
|
LPCTSTR lpctstrAttributes = _T("Attributes");
|
|
LPCTSTR lpctstrSpooler = _T("Spooler");
|
|
|
|
TCHAR tchBuffer[MAX_PATH + 1];
|
|
TCHAR tchPrinterKeyName[MAX_PATH + 1];
|
|
TCHAR *ptchToken;
|
|
|
|
// Booleans
|
|
BOOL fDriverFound = FALSE;
|
|
BOOL fAttribFound = FALSE;
|
|
|
|
// DWORDs
|
|
DWORD dwSize;
|
|
DWORD dwIndex;
|
|
DWORD dwType;
|
|
|
|
// Return Values;
|
|
ULONG ulPrinterAttribs;
|
|
|
|
LONG lRegRetVal;
|
|
|
|
struct tm tm;
|
|
|
|
WBEMTime wbemtime;
|
|
|
|
HKEY hkeyPrinter = NULL;
|
|
HKEY hkeyPrinters = NULL;
|
|
|
|
FILETIME ft;
|
|
|
|
// *** Set the properties associated with the default printer
|
|
|
|
|
|
// In "win.ini" file under "Windows" section "Device" represents the default printer
|
|
if(GetProfileString(lpctstrWindows, lpctstrDevice, "\0", tchBuffer, MAX_PATH) > 1)
|
|
{
|
|
// The Above GetProfileString returns "printerName", "PrinterDriver"
|
|
// and "PrinterPath" seperated by commas. Ignore "PrinterDriver"
|
|
// and use the other two to set the properties.
|
|
ptchToken = _tcstok(tchBuffer, _T(","));
|
|
if(ptchToken != NULL)
|
|
{
|
|
// ** name (token 1)
|
|
varValue = ptchToken;
|
|
if (pInstance->SetVariant(c_wszName, varValue) == FALSE)
|
|
ErrorTrace(TRACE_ID, "SetVariant on Name failed.");
|
|
|
|
// ** path (token 3)
|
|
ptchToken = _tcstok(NULL, _T(","));
|
|
if(ptchToken != NULL)
|
|
{
|
|
// gotta skip the 2nd token cuz it's the printer dirver & we
|
|
// don't give a rat's patoshki about it at this moment...
|
|
|
|
ptchToken = _tcstok(NULL, _T(","));
|
|
if(ptchToken != NULL)
|
|
{
|
|
varValue = ptchToken;
|
|
if (pInstance->SetVariant(c_wszPath, varValue) == FALSE)
|
|
ErrorTrace(TRACE_ID, "Set Variant on Path failed.");
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// couldn't fetch the properties of the default printer, so shove in some
|
|
// default values...
|
|
else
|
|
{
|
|
// set Name to "Not Available"
|
|
if (pInstance->SetVariant(c_wszName, varNotAvail) == FALSE)
|
|
ErrorTrace(TRACE_ID, "Se Variant on Name failed.");
|
|
|
|
// set Path to "Not Available"
|
|
if (pInstance->SetVariant(c_wszPath, varValue) == FALSE)
|
|
ErrorTrace(TRACE_ID, "Set Variant on Path failed.");
|
|
}
|
|
|
|
|
|
// *** Set the properties associated with using print manager spooling
|
|
|
|
|
|
// First try to get the Spooling information from the registry which is
|
|
// available if there are any installed printers
|
|
// HKLM\system\CCS\Control\Print\Printers
|
|
|
|
lRegRetVal = RegOpenKeyEx(HKEY_LOCAL_MACHINE, lpctstrPrintersHive, 0, KEY_READ, &hkeyPrinters);
|
|
if(lRegRetVal == ERROR_SUCCESS)
|
|
{
|
|
// Enumerate the keys under this hive.
|
|
ZeroMemory(&ft, sizeof(ft));
|
|
dwIndex = 0;
|
|
dwSize = MAX_PATH;
|
|
lRegRetVal = RegEnumKeyEx(hkeyPrinters, dwIndex, tchPrinterKeyName, &dwSize, NULL, NULL, NULL, &ft);
|
|
if(lRegRetVal == ERROR_SUCCESS)
|
|
{
|
|
// There is atleast one printer installed.
|
|
lRegRetVal = RegOpenKeyEx(hkeyPrinters, tchPrinterKeyName, 0, KEY_READ, &hkeyPrinter);
|
|
if(lRegRetVal == ERROR_SUCCESS)
|
|
{
|
|
// Opened the first printer key
|
|
// Query for , regname "Attributes"
|
|
dwSize = sizeof(DWORD);
|
|
lRegRetVal = RegQueryValueEx(hkeyPrinter, lpctstrAttributes, NULL, &dwType, (LPBYTE)&ulPrinterAttribs, &dwSize);
|
|
if(lRegRetVal == ERROR_SUCCESS)
|
|
{
|
|
// if the PRINTER_ATTRIBUTE_DIRECT bit in ulPrinterAttribs
|
|
// is set, then we have spooling...
|
|
if((ulPrinterAttribs & PRINTER_ATTRIBUTE_DIRECT) != 0)
|
|
varValue = VARIANT_FALSE;
|
|
else
|
|
varValue = VARIANT_TRUE;
|
|
|
|
if (ulPrinterAttribs > 0)
|
|
fAttribFound = TRUE;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
if (hkeyPrinter != NULL)
|
|
{
|
|
RegCloseKey(hkeyPrinter);
|
|
hkeyPrinter = NULL;
|
|
}
|
|
if (hkeyPrinters != NULL)
|
|
{
|
|
RegCloseKey(hkeyPrinters);
|
|
hkeyPrinters = NULL;
|
|
}
|
|
|
|
if(fAttribFound == FALSE)
|
|
{
|
|
// If not get the "spooler" key value from the win.ini file. If the entry is not present default to "yes".
|
|
if(GetProfileString(lpctstrWindows, lpctstrSpooler, _T("yes"), tchBuffer, MAX_PATH) > 1)
|
|
{
|
|
// if it's yes, then we have spooling...
|
|
if(_tcsicmp(tchBuffer, lpctstrYes) == 0)
|
|
varValue = VARIANT_TRUE;
|
|
else
|
|
varValue = VARIANT_FALSE;
|
|
}
|
|
}
|
|
|
|
// Set the Spooling Property.
|
|
if (pInstance->SetVariant(c_wszUsePrintMgrSpooling, varValue) == FALSE)
|
|
ErrorTrace(TRACE_ID, "SetVariant on usePrintManagerSpooling failed.");
|
|
|
|
|
|
// *** Set the properties associated with using print manager spooling
|
|
|
|
|
|
// Get the complete path for unidrv.dll
|
|
fDriverFound = getCompletePath(lpctstrUniDriver, bstrDriverWithPath);
|
|
if(fDriverFound)
|
|
{
|
|
// Need to use GetCIMDataFile to get the unidriver properties
|
|
if (SUCCEEDED(GetCIMDataFile(bstrDriverWithPath, &pFileObj)))
|
|
{
|
|
bstrDetails.Empty();
|
|
|
|
// Get the Version & append it to the value string...
|
|
varValue.Clear();
|
|
hr = pFileObj->Get(bstrVersion, 0, &varValue, NULL, NULL);
|
|
if(SUCCEEDED(hr))
|
|
{
|
|
if(varValue.vt == VT_BSTR)
|
|
{
|
|
bstrDetails.Append(varValue.bstrVal);
|
|
bstrDetails.Append(_T(" "));
|
|
}
|
|
}
|
|
|
|
// Get the FileSize & append it to the value string...
|
|
varValue.Clear();
|
|
hr = pFileObj->Get(bstrFileSize, 0, &varValue, NULL, NULL);
|
|
if(SUCCEEDED(hr))
|
|
{
|
|
if(varValue.vt == VT_BSTR)
|
|
{
|
|
bstrDetails.Append(varValue.bstrVal);
|
|
bstrDetails.Append(_T(" "));
|
|
}
|
|
}
|
|
|
|
// Get the date & time & append them to the value string...
|
|
varValue.Clear();
|
|
hr = pFileObj->Get(bstrModifiedDate, 0, &varValue, NULL, NULL);
|
|
if(SUCCEEDED(hr))
|
|
{
|
|
if(varValue.vt == VT_BSTR)
|
|
{
|
|
WCHAR *pwsz;
|
|
|
|
// there is a slight problem when WMI returns to us a
|
|
// time that has a '*' in it. The WBEMTime class plain
|
|
// refuses to deal with it. So change '*'s to '0's...
|
|
for (pwsz = varValue.bstrVal; *pwsz != L'\0'; pwsz++)
|
|
{
|
|
if (*pwsz == L'*')
|
|
*pwsz = L'0';
|
|
}
|
|
|
|
wbemtime = varValue.bstrVal;
|
|
if(wbemtime.GetStructtm(&tm))
|
|
{
|
|
varValue = asctime(&tm);
|
|
bstrDetails.Append(varValue.bstrVal);
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
// set the value
|
|
varValue.vt = VT_BSTR;
|
|
varValue.bstrVal = bstrDetails.Detach();
|
|
}
|
|
|
|
// Since I don't seem to have unindrv.dll installed, I can't verify
|
|
// this, but going by the other WMI providers, GetObject doesn't seem
|
|
// to like it when u release objects fetched by it. So, I am not
|
|
// going to release it.
|
|
if (pFileObj != NULL)
|
|
{
|
|
// pFileObj->Release();
|
|
pFileObj = NULL;
|
|
}
|
|
}
|
|
|
|
// the unidriver dll isn't present. Use a default value
|
|
else
|
|
{
|
|
varValue.Clear();
|
|
varValue = lpctstrNoUniDrv;
|
|
}
|
|
|
|
// set the property
|
|
if (pInstance->SetVariant(c_wszUniDrv, varValue) == FALSE)
|
|
ErrorTrace(TRACE_ID, "SetVariant on UniDriver failed.");
|
|
|
|
|
|
// *** Set the properties associated with using print manager spooling
|
|
|
|
|
|
// Get the complete path for gendrv.dll
|
|
bstrDriverWithPath.Empty();
|
|
fDriverFound = getCompletePath(lpctstrGenDriver, bstrDriverWithPath);
|
|
if(fDriverFound)
|
|
{
|
|
bstrDetails.Empty();
|
|
|
|
// Need to use GetCIMDataFile to get the gen driver properties
|
|
if(SUCCEEDED(GetCIMDataFile(bstrDriverWithPath, &pFileObj)))
|
|
{
|
|
// Get the Version & append it to the value string...
|
|
varValue.Clear();
|
|
hr = pFileObj->Get(bstrVersion, 0, &varValue, NULL, NULL);
|
|
if(SUCCEEDED(hr))
|
|
{
|
|
if(varValue.vt == VT_BSTR)
|
|
{
|
|
bstrDetails.Append(varValue.bstrVal);
|
|
bstrDetails.Append(_T(" "));
|
|
}
|
|
}
|
|
|
|
// Get the FileSize & append it to the value string...
|
|
varValue.Clear();
|
|
hr = pFileObj->Get(bstrFileSize, 0, &varValue, NULL, NULL);
|
|
if(SUCCEEDED(hr))
|
|
{
|
|
if(varValue.vt == VT_BSTR)
|
|
{
|
|
bstrDetails.Append(varValue.bstrVal);
|
|
bstrDetails.Append(_T(" "));
|
|
}
|
|
}
|
|
|
|
// Get the date & time & append them to the value string...
|
|
varValue.Clear();
|
|
hr = pFileObj->Get(bstrModifiedDate, 0, &varValue, NULL, NULL);
|
|
if(SUCCEEDED(hr))
|
|
{
|
|
if(varValue.vt == VT_BSTR)
|
|
{
|
|
WCHAR *pwsz;
|
|
|
|
// there is a slight problem when WMI returns to us a
|
|
// time that has a '*' in it. The WBEMTime class plain
|
|
// refuses to deal with it. So change '*'s to '0's...
|
|
for (pwsz = varValue.bstrVal; *pwsz != L'\0'; pwsz++)
|
|
{
|
|
if (*pwsz == L'*')
|
|
*pwsz = L'0';
|
|
}
|
|
|
|
wbemtime = varValue.bstrVal;
|
|
if(wbemtime.GetStructtm(&tm))
|
|
{
|
|
varValue = asctime(&tm);
|
|
bstrDetails.Append(varValue.bstrVal);
|
|
}
|
|
}
|
|
}
|
|
|
|
// set the value
|
|
varValue.vt = VT_BSTR;
|
|
varValue.bstrVal = bstrDetails.Detach();
|
|
}
|
|
|
|
// Since I don't seem to have gendrv.dll installed, I can't verify
|
|
// this, but going by the other WMI providers, GetObject doesn't seem
|
|
// to like it when u release objects fetched by it. So, I am not
|
|
// going to release it.
|
|
if (pFileObj != NULL)
|
|
{
|
|
// pFileObj->Release();
|
|
pFileObj = NULL;
|
|
}
|
|
}
|
|
|
|
// the gen driver dll is not present...
|
|
else
|
|
{
|
|
varValue.Clear();
|
|
varValue = lpctstrNoGenDrv;
|
|
}
|
|
|
|
if (pInstance->SetVariant(c_wszGenDrv, varValue) == FALSE)
|
|
ErrorTrace(TRACE_ID, "SetVariant on GenDrv failed.");
|
|
|
|
|
|
// WOOHOO!! We can commit now
|
|
hr = pInstance->Commit();
|
|
if(FAILED(hr))
|
|
ErrorTrace(TRACE_ID, "Error on commiting!");
|
|
|
|
TraceFunctLeave();
|
|
return hr;
|
|
}
|
|
|
|
// *****************************************************************************
|
|
HRESULT CPrintSys::ExecQuery(MethodContext *pMethodContext,
|
|
CFrameworkQuery& Query, long lFlags)
|
|
{
|
|
return WBEM_E_PROVIDER_NOT_CAPABLE;
|
|
}
|
|
|
|
// *****************************************************************************
|
|
HRESULT CPrintSys::PutInstance(const CInstance& Instance, long lFlags)
|
|
{
|
|
return WBEM_E_PROVIDER_NOT_CAPABLE;
|
|
}
|
|
|
|
// *****************************************************************************
|
|
HRESULT CPrintSys::DeleteInstance(const CInstance& Instance, long lFlags)
|
|
{
|
|
return WBEM_E_PROVIDER_NOT_CAPABLE;
|
|
}
|