windows-nt/Source/XPSP1/NT/admin/pchealth/client/datacoll/atprov/printsys.cpp
2020-09-26 16:20:57 +08:00

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;
}