Leaked source code of windows server 2003
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.

1636 lines
53 KiB

  1. /*****************************************************************************\
  2. * MODULE: asphelp.cpp
  3. *
  4. * PURPOSE: Implementation of the printer helper library
  5. *
  6. * Copyright (C) 1997-1998 Microsoft Corporation
  7. *
  8. * History:
  9. *
  10. * 09/12/97 weihaic Created
  11. *
  12. \*****************************************************************************/
  13. #include "stdafx.h"
  14. #include <strsafe.h>
  15. #include "gensph.h"
  16. #include "oleprn.h"
  17. #include "printer.h"
  18. #include "asphelp.h"
  19. Casphelp::Casphelp()
  20. {
  21. DWORD dwSize = MAX_COMPUTERNAME_LENGTH + 1;
  22. m_bOnStartPageCalled = FALSE;
  23. m_bTCPMonSupported = FALSE;
  24. m_hPrinter = NULL;
  25. m_hXcvPrinter = NULL;
  26. m_pInfo2 = NULL;
  27. m_bCalcJobETA = FALSE;
  28. m_pPrinter = NULL;
  29. if ( ! GetComputerName (m_szComputerName, &dwSize) )
  30. // Set the first char to '\0'.
  31. m_szComputerName[0] = 0;
  32. }
  33. /////////////////////////////////////////////////////////////////////////////
  34. // Casphelp
  35. STDMETHODIMP Casphelp::OnStartPage (IUnknown* pUnk)
  36. {
  37. if ( !pUnk )
  38. return E_POINTER;
  39. CComPtr<IScriptingContext> spContext;
  40. HRESULT hr;
  41. // Get the IScriptingContext Interface
  42. hr = pUnk->QueryInterface(IID_IScriptingContext, (void **)&spContext);
  43. if ( FAILED(hr) )
  44. return hr;
  45. // Get Request Object Pointer
  46. hr = spContext->get_Request(&m_piRequest);
  47. if ( FAILED(hr) ) {
  48. spContext.Release();
  49. return hr;
  50. }
  51. // Get Response Object Pointer
  52. hr = spContext->get_Response(&m_piResponse);
  53. if ( FAILED(hr) ) {
  54. m_piRequest.Release();
  55. return hr;
  56. }
  57. // Get Server Object Pointer
  58. hr = spContext->get_Server(&m_piServer);
  59. if ( FAILED(hr) ) {
  60. m_piRequest.Release();
  61. m_piResponse.Release();
  62. return hr;
  63. }
  64. // Get Session Object Pointer
  65. hr = spContext->get_Session(&m_piSession);
  66. if ( FAILED(hr) ) {
  67. m_piRequest.Release();
  68. m_piResponse.Release();
  69. m_piServer.Release();
  70. return hr;
  71. }
  72. // Get Application Object Pointer
  73. hr = spContext->get_Application(&m_piApplication);
  74. if ( FAILED(hr) ) {
  75. m_piRequest.Release();
  76. m_piResponse.Release();
  77. m_piServer.Release();
  78. m_piSession.Release();
  79. return hr;
  80. }
  81. m_bOnStartPageCalled = TRUE;
  82. return S_OK;
  83. }
  84. STDMETHODIMP Casphelp::OnEndPage ()
  85. {
  86. m_bOnStartPageCalled = FALSE;
  87. // Release all interfaces
  88. m_piRequest.Release();
  89. m_piResponse.Release();
  90. m_piServer.Release();
  91. m_piSession.Release();
  92. m_piApplication.Release();
  93. return S_OK;
  94. }
  95. /*****************************************************************************\
  96. * FUNCTION: Open
  97. *
  98. * PURPOSE: Open method, try to open a printer and get the printer info2
  99. *
  100. * ARGUMENTS:
  101. *
  102. * pPrinterName: Printer Name
  103. *
  104. * RETURN VALUE:
  105. * S_OK: If succeed.
  106. *
  107. * 0x8007000 | Win32Error Code:
  108. * If any call to win32 API fails, we return the 32 bit error
  109. * including the Severity Code, Facility Code and the Win32 Error
  110. * Code.
  111. * A possible list of Win32ErrorCode are
  112. * ERROR_INVALID_PRINTER_NAME: Invalid printer name
  113. * ERROR_NOT_ENOUGH_MEMORY: Out of memory.
  114. *
  115. *
  116. \*****************************************************************************/
  117. STDMETHODIMP Casphelp::Open(BSTR pPrinterName)
  118. {
  119. static const TCHAR cszPrefix[] = TEXT(",XcvPort ");
  120. static const TCHAR cszPattern[] = TEXT("%s\\,XcvPort %s");
  121. LPTSTR pszXcvPortName = NULL;
  122. DWORD dwXcvPortNameLength = 0;
  123. TCHAR szMonitorName[MAX_PATH] = TEXT("");
  124. BOOL bRet = FALSE;
  125. if ( ! (m_pPrinter = new CPrinter) ) {
  126. SetLastError (ERROR_INVALID_PRINTER_NAME);
  127. goto CleanOut;
  128. }
  129. if ( ! (m_pPrinter->Open (pPrinterName, &m_hPrinter))) {
  130. goto CleanOut;
  131. }
  132. if ( ! (m_pInfo2 = m_pPrinter->GetPrinterInfo2 ()) ) {
  133. goto CleanOut;
  134. }
  135. // Open the XcvPrinter
  136. // Compose the openprinter string
  137. if ( m_pInfo2->pServerName && lstrcmp(m_pInfo2->pServerName, TEXT ("")) ) {
  138. // Alloc the memeory for open printer string with server name
  139. dwXcvPortNameLength = lstrlen(cszPattern) + lstrlen (m_pInfo2->pServerName) + lstrlen (m_pInfo2->pPortName) + 1;
  140. if ( ! (pszXcvPortName = (LPTSTR) LocalAlloc (LPTR, sizeof(TCHAR) * dwXcvPortNameLength)) ) {
  141. goto CleanOut;
  142. }
  143. // Construct the OpenPrinter String with the server name
  144. StringCchPrintf(pszXcvPortName, dwXcvPortNameLength, cszPattern, m_pInfo2->pServerName, m_pInfo2->pPortName);
  145. } else {
  146. // Alloc the memeory for open printer string without server name
  147. dwXcvPortNameLength = lstrlen(cszPrefix) + lstrlen (m_pInfo2->pPortName) + 1;
  148. if ( ! (pszXcvPortName = (LPTSTR) LocalAlloc (LPTR, sizeof (TCHAR) * dwXcvPortNameLength)) ) {
  149. goto CleanOut;
  150. }
  151. // Construct the OpenPrinter String with the server name
  152. StringCchCopy (pszXcvPortName, dwXcvPortNameLength, cszPrefix);
  153. StringCchCat (pszXcvPortName, dwXcvPortNameLength, m_pInfo2->pPortName);
  154. }
  155. // Now the openprinter string is ready, call the openprinter
  156. // We open the port using the default access previlige, because that is
  157. // enought for getting all the XcvData we need.
  158. if ( !OpenPrinter(pszXcvPortName, &m_hXcvPrinter, NULL) ) {
  159. // Reset the handle
  160. m_hXcvPrinter = NULL;
  161. }
  162. // Check if we're using the standard universal monitor "TCPMON.DLL"
  163. if ( GetMonitorName(szMonitorName, ARRAYSIZE(szMonitorName)) )
  164. m_bTCPMonSupported = !(lstrcmpi(szMonitorName, STANDARD_SNMP_MONITOR_NAME));
  165. else
  166. m_bTCPMonSupported = FALSE;
  167. bRet = TRUE;
  168. CleanOut:
  169. if (pszXcvPortName)
  170. LocalFree (pszXcvPortName);
  171. if (bRet) {
  172. return S_OK;
  173. }
  174. else {
  175. Cleanup ();
  176. return SetAspHelpScriptingError(GetLastError ());
  177. }
  178. }
  179. /*****************************************************************************\
  180. * FUNCTION: Close
  181. *
  182. * PURPOSE: Close method, cleanup the allocated handle/memory
  183. *
  184. * ARGUMENTS:
  185. *
  186. * RETURN VALUE:
  187. * S_OK: always.
  188. *
  189. \*****************************************************************************/
  190. STDMETHODIMP Casphelp::Close()
  191. {
  192. Cleanup();
  193. return S_OK;
  194. }
  195. /*****************************************************************************\
  196. * FUNCTION: get_IPAddress
  197. *
  198. * PURPOSE: Get operation for IPAddress property
  199. *
  200. * ARGUMENTS:
  201. *
  202. * pbstrVal: Return value for the IpAddress.
  203. *
  204. * RETURN VALUE:
  205. * S_OK: If succeed.
  206. * E_HANDLE: Open method has not been called.
  207. * E_OUTOFMEMORY: Out of memory.
  208. *
  209. * 0x8007000 | Win32Error Code:
  210. * If any call to win32 API fails, we return the 32 bit error
  211. * including the Severity Code, Facility Code and the Win32 Error
  212. * Code.
  213. * A possible list of Win32ErrorCode is
  214. * ERROR_NOT_ENOUGH_MEMORY: Out of memory.
  215. *
  216. *
  217. \*****************************************************************************/
  218. STDMETHODIMP Casphelp::get_IPAddress(BSTR * pbstrVal)
  219. {
  220. return GetXcvDataBstr (L"IPAddress", pbstrVal);
  221. }
  222. /*****************************************************************************\
  223. * FUNCTION: get_Community
  224. *
  225. * PURPOSE: Get operation for Community property
  226. *
  227. * ARGUMENTS:
  228. *
  229. * pbstrVal: Return value for the Community.
  230. *
  231. * RETURN VALUE:
  232. * S_OK: If succeed.
  233. * E_HANDLE: Open method has not been called.
  234. * E_OUTOFMEMORY: Out of memory.
  235. *
  236. * 0x8007000 | Win32Error Code:
  237. * If any call to win32 API fails, we return the 32 bit error
  238. * including the Severity Code, Facility Code and the Win32 Error
  239. * Code.
  240. * A possible list of Win32ErrorCode is
  241. * ERROR_NOT_ENOUGH_MEMORY: Out of memory.
  242. *
  243. *
  244. \*****************************************************************************/
  245. STDMETHODIMP Casphelp::get_Community(BSTR * pbstrVal)
  246. {
  247. return GetXcvDataBstr (L"SNMPCommunity", pbstrVal);
  248. }
  249. /*****************************************************************************\
  250. * FUNCTION: get_SNMPDevice
  251. *
  252. * PURPOSE: Get operation for SNMPDevice property
  253. *
  254. * ARGUMENTS:
  255. *
  256. * pbstrVal: Return value for the SNMPDevice.
  257. *
  258. * RETURN VALUE:
  259. * S_OK: If succeed.
  260. * E_HANDLE: Open method has not been called.
  261. * E_OUTOFMEMORY: Out of memory.
  262. *
  263. * 0x8007000 | Win32Error Code:
  264. * If any call to win32 API fails, we return the 32 bit error
  265. * including the Severity Code, Facility Code and the Win32 Error
  266. * Code.
  267. * A possible list of Win32ErrorCode is
  268. * ERROR_NOT_ENOUGH_MEMORY: Out of memory.
  269. *
  270. *
  271. \*****************************************************************************/
  272. STDMETHODIMP Casphelp::get_SNMPDevice(DWORD * pdwVal)
  273. {
  274. return GetXcvDataDword (L"SNMPDeviceIndex", pdwVal);
  275. }
  276. /*****************************************************************************\
  277. * FUNCTION: get_SNMPSupported
  278. *
  279. * PURPOSE: Get operation for SNMPSupported property
  280. *
  281. * ARGUMENTS:
  282. *
  283. * pbVal: Return value for the SNMPSupported. (TRUE or FALSE)
  284. *
  285. * RETURN VALUE:
  286. * S_OK: If succeed.
  287. * E_HANDLE: Open method has not been called.
  288. * E_OUTOFMEMORY: Out of memory.
  289. *
  290. * 0x8007000 | Win32Error Code:
  291. * If any call to win32 API fails, we return the 32 bit error
  292. * including the Severity Code, Facility Code and the Win32 Error
  293. * Code.
  294. * A possible list of Win32ErrorCode is
  295. * ERROR_NOT_ENOUGH_MEMORY: Out of memory.
  296. *
  297. *
  298. \*****************************************************************************/
  299. STDMETHODIMP Casphelp::get_SNMPSupported(BOOL * pbVal)
  300. {
  301. DWORD dwVal;
  302. HRESULT hr;
  303. *pbVal = FALSE;
  304. // Find out if it is an SNMP monitor
  305. hr = GetXcvDataDword (L"SNMPEnabled", &dwVal);
  306. if ( SUCCEEDED (hr) )
  307. *pbVal = dwVal;
  308. return hr;
  309. }
  310. STDMETHODIMP Casphelp::get_IsHTTP(BOOL * pbVal)
  311. {
  312. static const TCHAR c_szHttp[] = TEXT("http://");
  313. static const TCHAR c_szHttps[] = TEXT("https://");
  314. *pbVal = FALSE;
  315. if ( !m_pInfo2 )
  316. return Error(IDS_NO_PRINTER_OPEN, IID_Iasphelp, E_HANDLE);
  317. //
  318. // Check if it is a masq printer and connected to an http port
  319. // then the port name is the url.
  320. //
  321. if ( ( m_pInfo2->Attributes & PRINTER_ATTRIBUTE_LOCAL ) &&
  322. ( m_pInfo2->Attributes & PRINTER_ATTRIBUTE_NETWORK ) ) {
  323. if ( m_pInfo2->pPortName ) {
  324. //
  325. // Compare the port name prefex to see if it is an HTTP port.
  326. //
  327. if ( !_tcsnicmp( m_pInfo2->pPortName, c_szHttp, _tcslen( c_szHttp ) ) ||
  328. !_tcsnicmp( m_pInfo2->pPortName, c_szHttps, _tcslen( c_szHttps ) ) ) {
  329. //
  330. // Masq printers connected via a http print provider do have not
  331. // useful job status information therefor the standard win32
  332. // queue view is not the preferred view.
  333. //
  334. *pbVal = TRUE;
  335. }
  336. }
  337. }
  338. return S_OK;
  339. }
  340. VOID Casphelp::Cleanup()
  341. {
  342. if ( m_hXcvPrinter != NULL ) {
  343. ClosePrinter (m_hXcvPrinter);
  344. m_hXcvPrinter = NULL;
  345. }
  346. if ( m_pPrinter ) {
  347. delete (m_pPrinter);
  348. m_pPrinter = NULL;
  349. }
  350. m_bTCPMonSupported = FALSE;
  351. return;
  352. }
  353. Casphelp::~Casphelp()
  354. {
  355. Cleanup();
  356. }
  357. HRESULT Casphelp::GetXcvDataBstr(LPCTSTR pszId, BSTR *pbstrVal)
  358. {
  359. *pbstrVal = NULL;
  360. if ( !m_bTCPMonSupported ) {
  361. *pbstrVal = SysAllocString (TEXT (""));
  362. return S_OK;
  363. } else {
  364. if ( m_hXcvPrinter == NULL )
  365. return Error(IDS_NO_XCVDATA, IID_Iasphelp, E_HANDLE);
  366. else { // Real case
  367. DWORD dwNeeded = 0;
  368. DWORD dwStatus = ERROR_SUCCESS;
  369. LPTSTR pszBuffer = NULL;
  370. XcvData(m_hXcvPrinter,
  371. pszId,
  372. NULL, // Input Data
  373. 0, // Input Data Size
  374. (LPBYTE)NULL, // Output Data
  375. 0, // Output Data Size
  376. &dwNeeded, // size of output buffer server wants to return
  377. &dwStatus); // return status value from remote component
  378. if ( dwStatus != ERROR_INSUFFICIENT_BUFFER ) {
  379. return SetAspHelpScriptingError(dwStatus);
  380. } else {
  381. pszBuffer = (LPTSTR) LocalAlloc (LPTR, dwNeeded);
  382. if ( !XcvData(m_hXcvPrinter,
  383. pszId,
  384. NULL, // Input Data
  385. 0, // Input Data Size
  386. (LPBYTE)pszBuffer, // Output Data
  387. dwNeeded, // Output Data Size
  388. &dwNeeded, // size of output buffer server wants to return
  389. &dwStatus)
  390. || dwStatus != ERROR_SUCCESS ) { // return status value from remote component
  391. if ( pszBuffer )
  392. LocalFree (pszBuffer);
  393. return SetAspHelpScriptingError(dwStatus);
  394. }
  395. *pbstrVal = SysAllocString(pszBuffer);
  396. LocalFree (pszBuffer);
  397. if ( ! *pbstrVal )
  398. return Error(IDS_OUT_OF_MEMORY, IID_Iasphelp, E_OUTOFMEMORY);
  399. else
  400. return S_OK;
  401. }
  402. }
  403. }
  404. }
  405. HRESULT Casphelp::GetXcvDataDword(LPCTSTR pszId, DWORD * pdwVal)
  406. {
  407. *pdwVal = 0;
  408. if ( m_hXcvPrinter == NULL )
  409. return Error(IDS_NO_XCVDATA, IID_Iasphelp, E_HANDLE);
  410. else { // Real case
  411. DWORD dwStatus = ERROR_SUCCESS;
  412. DWORD dwBuffer;
  413. DWORD dwNeeded = sizeof (dwBuffer);
  414. if ( !XcvData(m_hXcvPrinter,
  415. pszId,
  416. NULL, // Input Data
  417. 0, // Input Data Size
  418. (LPBYTE)&dwBuffer, // Output Data
  419. sizeof (dwBuffer), // Output Data Size
  420. &dwNeeded, // size of output buffer server wants to return
  421. &dwStatus)
  422. || dwStatus != ERROR_SUCCESS ) { // return status value from remote component
  423. return SetAspHelpScriptingError(dwStatus);
  424. }
  425. *pdwVal = dwBuffer;
  426. return S_OK;
  427. }
  428. }
  429. /*****************************************************************************\
  430. * FUNCTION: get_IsTCPMonSupported
  431. *
  432. * PURPOSE: Get operation for IsTCPMonSupported property
  433. *
  434. * ARGUMENTS:
  435. *
  436. * pbVal: Return value for the IsTCPMonSupported. (TRUE if the specified
  437. * printer is using TCP Monitor, FALSE otherwise)
  438. *
  439. * RETURN VALUE:
  440. * S_OK: If succeed.
  441. * E_HANDLE: Open method has not been called.
  442. * E_OUTOFMEMORY: Out of memory.
  443. *
  444. * 0x8007000 | Win32Error Code:
  445. * If any call to win32 API fails, we return the 32 bit error
  446. * including the Severity Code, Facility Code and the Win32 Error
  447. * Code.
  448. * A possible list of Win32ErrorCode is
  449. * ERROR_NOT_ENOUGH_MEMORY: Out of memory.
  450. *
  451. *
  452. \*****************************************************************************/
  453. STDMETHODIMP Casphelp::get_IsTCPMonSupported(BOOL * pbVal)
  454. {
  455. *pbVal = FALSE;
  456. if ( m_hPrinter == NULL )
  457. return Error(IDS_NO_PRINTER_OPEN, IID_Iasphelp, E_HANDLE);
  458. *pbVal = m_bTCPMonSupported;
  459. return S_OK;
  460. }
  461. /*****************************************************************************\
  462. * FUNCTION: get_Color
  463. *
  464. * PURPOSE: Get operation for Color property
  465. *
  466. * ARGUMENTS:
  467. *
  468. * pbVal: Return value for the Color. (TRUE if the specified
  469. * printer supports Color, FALSE otherwise)
  470. *
  471. * RETURN VALUE:
  472. * S_OK: If succeed.
  473. * E_HANDLE: Open method has not been called.
  474. * E_OUTOFMEMORY: Out of memory.
  475. *
  476. * 0x8007000 | Win32Error Code:
  477. * If any call to win32 API fails, we return the 32 bit error
  478. * including the Severity Code, Facility Code and the Win32 Error
  479. * Code.
  480. * A possible list of Win32ErrorCode is
  481. * ERROR_NOT_ENOUGH_MEMORY: Out of memory.
  482. *
  483. *
  484. \*****************************************************************************/
  485. STDMETHODIMP Casphelp::get_Color(BOOL * pVal)
  486. {
  487. *pVal = FALSE;
  488. if ( !m_pInfo2 )
  489. return Error(IDS_NO_PRINTER_OPEN, IID_Iasphelp, E_HANDLE);
  490. DWORD dwRet = MyDeviceCapabilities(m_pInfo2->pPrinterName,
  491. m_pInfo2->pPortName,
  492. DC_COLORDEVICE,
  493. NULL,
  494. NULL);
  495. if ( dwRet == DWERROR )
  496. return SetAspHelpScriptingError(GetLastError());
  497. *pVal = (BOOLEAN) dwRet;
  498. return S_OK;
  499. }
  500. /*****************************************************************************\
  501. * FUNCTION: get_Duplex
  502. *
  503. * PURPOSE: Get operation for Duplex property
  504. *
  505. * ARGUMENTS:
  506. *
  507. * pbVal: Return value for the Duplex. (TRUE if the specified
  508. * printer supports Duplex, FALSE otherwise)
  509. *
  510. * RETURN VALUE:
  511. * S_OK: If succeed.
  512. * E_HANDLE: Open method has not been called.
  513. * E_OUTOFMEMORY: Out of memory.
  514. *
  515. * 0x8007000 | Win32Error Code:
  516. * If any call to win32 API fails, we return the 32 bit error
  517. * including the Severity Code, Facility Code and the Win32 Error
  518. * Code.
  519. * A possible list of Win32ErrorCode is
  520. * ERROR_NOT_ENOUGH_MEMORY: Out of memory.
  521. *
  522. *
  523. \*****************************************************************************/
  524. STDMETHODIMP Casphelp::get_Duplex(BOOL * pVal)
  525. {
  526. *pVal = FALSE;
  527. if ( !m_pInfo2 )
  528. return Error(IDS_NO_PRINTER_OPEN, IID_Iasphelp, E_HANDLE);
  529. DWORD dwRet = MyDeviceCapabilities(m_pInfo2->pPrinterName,
  530. m_pInfo2->pPortName,
  531. DC_DUPLEX,
  532. NULL,
  533. NULL);
  534. if ( dwRet == DWERROR )
  535. return SetAspHelpScriptingError(GetLastError());
  536. *pVal = (BOOL) dwRet;
  537. return S_OK;
  538. }
  539. /*****************************************************************************\
  540. * FUNCTION: get_MaximumResolution
  541. *
  542. * PURPOSE: Get operation for MaximumResolution property
  543. *
  544. * ARGUMENTS:
  545. *
  546. * pVal: Return value of Maximum Resolution (in DPI)
  547. *
  548. * RETURN VALUE:
  549. * S_OK: If succeed.
  550. * E_HANDLE: Open method has not been called.
  551. * E_OUTOFMEMORY: Out of memory.
  552. *
  553. * 0x8007000 | Win32Error Code:
  554. * If any call to win32 API fails, we return the 32 bit error
  555. * including the Severity Code, Facility Code and the Win32 Error
  556. * Code.
  557. * A possible list of Win32ErrorCode is
  558. * ERROR_NOT_ENOUGH_MEMORY: Out of memory.
  559. *
  560. *
  561. \*****************************************************************************/
  562. STDMETHODIMP Casphelp::get_MaximumResolution(long * pVal)
  563. {
  564. *pVal = 0;
  565. if ( !m_pInfo2 )
  566. return Error(IDS_NO_PRINTER_OPEN, IID_Iasphelp, E_HANDLE);
  567. DWORD cbNeeded;
  568. DWORD dwRet = GetPrinterDataEx(m_hPrinter,
  569. SPLDS_DRIVER_KEY,
  570. SPLDS_PRINT_MAX_RESOLUTION_SUPPORTED,
  571. NULL,
  572. (LPBYTE) pVal,
  573. sizeof(DWORD),
  574. &cbNeeded);
  575. if ( dwRet != ERROR_SUCCESS ) {
  576. *pVal = 0;
  577. return SetAspHelpScriptingError(dwRet);
  578. }
  579. return S_OK;
  580. }
  581. STDMETHODIMP Casphelp::get_MediaReady(VARIANT * pVal)
  582. {
  583. return GetPaperAndMedia(pVal, DC_MEDIAREADY);
  584. }
  585. /*****************************************************************************\
  586. * FUNCTION: get_PaperNames
  587. *
  588. * PURPOSE: Get operation for PaperNames property
  589. *
  590. * ARGUMENTS:
  591. *
  592. * pVal: Return a list of supported paper names (in an array of BSTR)
  593. *
  594. * RETURN VALUE:
  595. * S_OK: If succeed.
  596. * E_HANDLE: Open method has not been called.
  597. * E_OUTOFMEMORY: Out of memory.
  598. *
  599. * 0x8007000 | Win32Error Code:
  600. * If any call to win32 API fails, we return the 32 bit error
  601. * including the Severity Code, Facility Code and the Win32 Error
  602. * Code.
  603. * A possible list of Win32ErrorCode is
  604. * ERROR_NOT_ENOUGH_MEMORY: Out of memory.
  605. *
  606. *
  607. \*****************************************************************************/
  608. STDMETHODIMP Casphelp::get_PaperNames(VARIANT * pVal)
  609. {
  610. return GetPaperAndMedia(pVal, DC_PAPERNAMES);
  611. }
  612. HRESULT Casphelp::GetPaperAndMedia(VARIANT * pVal, WORD wDCFlag)
  613. {
  614. SAFEARRAY *psa = NULL;
  615. SAFEARRAYBOUND rgsabound[1];
  616. long ix[1];
  617. VARIANT var;
  618. DWORD i;
  619. HRESULT hr = E_FAIL;
  620. if ( !m_pInfo2 )
  621. return Error(IDS_NO_PRINTER_OPEN, IID_Iasphelp, E_HANDLE);
  622. DWORD dwRet = MyDeviceCapabilities(m_pInfo2->pPrinterName,
  623. m_pInfo2->pPortName,
  624. wDCFlag,
  625. NULL,
  626. NULL);
  627. if ( dwRet == DWERROR )
  628. return SetAspHelpScriptingError(GetLastError());
  629. LPTSTR lpMedia = (LPTSTR) LocalAlloc(LPTR, sizeof(TCHAR) * dwRet * LENGTHOFPAPERNAMES);
  630. if ( !lpMedia )
  631. return SetAspHelpScriptingError(GetLastError());
  632. dwRet = MyDeviceCapabilities(m_pInfo2->pPrinterName,
  633. m_pInfo2->pPortName,
  634. wDCFlag,
  635. lpMedia,
  636. NULL);
  637. if ( dwRet == DWERROR ) {
  638. hr = SetAspHelpScriptingError(GetLastError());
  639. goto BailOut;
  640. }
  641. // Paper Names are now in MULTI_SZ lpMedia
  642. rgsabound[0].lLbound = 0;
  643. rgsabound[0].cElements = dwRet;
  644. // Create a SafeArray to eventually return
  645. if ( ! (psa = SafeArrayCreate(VT_VARIANT, 1, rgsabound)) ) {
  646. hr = Error(IDS_OUT_OF_MEMORY, IID_Iasphelp, E_OUTOFMEMORY);
  647. goto BailOut;
  648. }
  649. VariantInit(&var);
  650. // Fill in the SafeArray
  651. for ( i = 0; i < dwRet; i++ ) {
  652. var.vt = VT_BSTR;
  653. if ( ! (var.bstrVal = SysAllocString(lpMedia + (i*LENGTHOFPAPERNAMES))) ) {
  654. hr = Error(IDS_OUT_OF_MEMORY, IID_Iasphelp, E_OUTOFMEMORY);
  655. goto BailOut;
  656. }
  657. ix[0] = i;
  658. hr = SafeArrayPutElement(psa, ix, &var);
  659. if (FAILED ( hr )) {
  660. hr = Error(IDS_OUT_OF_MEMORY, IID_Iasphelp, E_OUTOFMEMORY);
  661. goto BailOut;
  662. }
  663. VariantClear(&var);
  664. }
  665. // Assign good stuff to Out param
  666. VariantInit(pVal);
  667. pVal->vt = VT_ARRAY | VT_VARIANT;
  668. pVal->parray = psa;
  669. LocalFree(lpMedia);
  670. return S_OK;
  671. BailOut:
  672. LocalFree(lpMedia);
  673. if ( psa )
  674. SafeArrayDestroy(psa);
  675. return hr;
  676. }
  677. /*****************************************************************************\
  678. * FUNCTION: get_PageRate
  679. *
  680. * PURPOSE: Get operation for PageRate property
  681. *
  682. * ARGUMENTS:
  683. *
  684. * pVal: Return a PageRate of the specified printer
  685. * (Unit: PPM / CPS / LPM / IPM)
  686. *
  687. * RETURN VALUE:
  688. * S_OK: If succeed.
  689. * E_HANDLE: Open method has not been called.
  690. * E_OUTOFMEMORY: Out of memory.
  691. *
  692. * 0x8007000 | Win32Error Code:
  693. * If any call to win32 API fails, we return the 32 bit error
  694. * including the Severity Code, Facility Code and the Win32 Error
  695. * Code.
  696. * A possible list of Win32ErrorCode is
  697. * ERROR_NOT_ENOUGH_MEMORY: Out of memory.
  698. *
  699. *
  700. \*****************************************************************************/
  701. STDMETHODIMP Casphelp::get_PageRate(long * pVal)
  702. {
  703. *pVal = 0;
  704. if ( !m_pInfo2 )
  705. return Error(IDS_NO_PRINTER_OPEN, IID_Iasphelp, E_HANDLE);
  706. DWORD dwRet;
  707. dwRet = MyDeviceCapabilities(m_pInfo2->pPrinterName,
  708. m_pInfo2->pPortName,
  709. DC_PRINTRATE,
  710. NULL,
  711. NULL);
  712. if ( dwRet == DWERROR )
  713. return SetAspHelpScriptingError(GetLastError());
  714. *pVal = (long) dwRet;
  715. return S_OK;
  716. }
  717. /*****************************************************************************\
  718. * FUNCTION: get_PageRateUnit
  719. *
  720. * PURPOSE: Get operation for PageRate property
  721. *
  722. * ARGUMENTS:
  723. *
  724. * pVal: Return a Unit of the Page Rate of a specified printer
  725. * (Unit: PPM / CPS / LPM / IPM)
  726. *
  727. * RETURN VALUE:
  728. * S_OK: If succeed.
  729. * E_HANDLE: Open method has not been called.
  730. * E_OUTOFMEMORY: Out of memory.
  731. *
  732. * 0x8007000 | Win32Error Code:
  733. * If any call to win32 API fails, we return the 32 bit error
  734. * including the Severity Code, Facility Code and the Win32 Error
  735. * Code.
  736. * A possible list of Win32ErrorCode is
  737. * ERROR_NOT_ENOUGH_MEMORY: Out of memory.
  738. *
  739. *
  740. \*****************************************************************************/
  741. STDMETHODIMP Casphelp::get_PageRateUnit (long * pVal)
  742. {
  743. *pVal = 0;
  744. if ( !m_pInfo2 )
  745. return Error(IDS_NO_PRINTER_OPEN, IID_Iasphelp, E_HANDLE);
  746. DWORD dwRet = MyDeviceCapabilities(m_pInfo2->pPrinterName,
  747. m_pInfo2->pPortName,
  748. DC_PRINTRATEUNIT,
  749. NULL,
  750. NULL);
  751. if ( dwRet == DWERROR )
  752. return SetAspHelpScriptingError(GetLastError());
  753. *pVal = (long) dwRet;
  754. return S_OK;
  755. }
  756. /*****************************************************************************\
  757. * FUNCTION: get_PortName
  758. *
  759. * PURPOSE: Get operation for PortName property
  760. *
  761. * ARGUMENTS:
  762. *
  763. * pVal: Return the port name of the specified printer
  764. *
  765. * RETURN VALUE:
  766. * S_OK: If succeed.
  767. * E_HANDLE: Open method has not been called.
  768. * E_OUTOFMEMORY: Out of memory.
  769. *
  770. * 0x8007000 | Win32Error Code:
  771. * If any call to win32 API fails, we return the 32 bit error
  772. * including the Severity Code, Facility Code and the Win32 Error
  773. * Code.
  774. * A possible list of Win32ErrorCode is
  775. * ERROR_NOT_ENOUGH_MEMORY: Out of memory.
  776. *
  777. *
  778. \*****************************************************************************/
  779. STDMETHODIMP Casphelp::get_PortName(BSTR * pbstrVal)
  780. {
  781. HRESULT hRet = S_OK;
  782. if ( !m_pInfo2 )
  783. return Error(IDS_NO_PRINTER_OPEN, IID_Iasphelp, E_HANDLE);
  784. if ( !(*pbstrVal = SysAllocString (m_pInfo2->pPortName)) )
  785. hRet = Error(IDS_OUT_OF_MEMORY, IID_Iasphelp, E_OUTOFMEMORY);
  786. return hRet;
  787. }
  788. /*****************************************************************************\
  789. * FUNCTION: get_DriverName
  790. *
  791. * PURPOSE: Get operation for DriverName property
  792. *
  793. * ARGUMENTS:
  794. *
  795. * pVal: Return the driver name of the specified printer
  796. *
  797. * RETURN VALUE:
  798. * S_OK: If succeed.
  799. * E_HANDLE: Open method has not been called.
  800. * E_OUTOFMEMORY: Out of memory.
  801. *
  802. * 0x8007000 | Win32Error Code:
  803. * If any call to win32 API fails, we return the 32 bit error
  804. * including the Severity Code, Facility Code and the Win32 Error
  805. * Code.
  806. * A possible list of Win32ErrorCode is
  807. * ERROR_NOT_ENOUGH_MEMORY: Out of memory.
  808. *
  809. *
  810. \*****************************************************************************/
  811. STDMETHODIMP Casphelp::get_DriverName(BSTR * pbstrVal)
  812. {
  813. HRESULT hRet = S_OK;
  814. if ( !m_pInfo2 )
  815. return Error(IDS_NO_PRINTER_OPEN, IID_Iasphelp, E_HANDLE);
  816. if ( !(*pbstrVal = SysAllocString (m_pInfo2->pDriverName)) )
  817. hRet = Error(IDS_OUT_OF_MEMORY, IID_Iasphelp, E_OUTOFMEMORY);
  818. return hRet;
  819. }
  820. /*****************************************************************************\
  821. * FUNCTION: get_ComputerName
  822. *
  823. * PURPOSE: Get operation for ComputerName property
  824. *
  825. * ARGUMENTS:
  826. *
  827. * pVal: Return the computer name of the server
  828. *
  829. * RETURN VALUE:
  830. * S_OK: If succeed.
  831. * E_OUTOFMEMORY: Out of memory.
  832. *
  833. \*****************************************************************************/
  834. STDMETHODIMP Casphelp::get_ComputerName(BSTR * pVal)
  835. {
  836. if ( !(*pVal = SysAllocString (m_szComputerName)) )
  837. return Error(IDS_OUT_OF_MEMORY, IID_Iasphelp, E_OUTOFMEMORY);
  838. return S_OK;
  839. }
  840. HRESULT Casphelp::SetAspHelpScriptingError(DWORD dwError)
  841. {
  842. return (SetScriptingError(CLSID_asphelp, IID_Iasphelp, dwError));
  843. }
  844. /*****************************************************************************\
  845. * FUNCTION: get_LongPaperName
  846. *
  847. * PURPOSE: Get operation for LongPaperName property
  848. * Translate the short paper name to the long paper name
  849. *
  850. * ARGUMENTS:
  851. *
  852. * bstrShortName: The short paper name
  853. * pVal: Pointer to the long paper name
  854. *
  855. * RETURN VALUE:
  856. * S_OK: If succeed.
  857. * E_OUTOFMEMORY: Out of memory.
  858. *
  859. * 0x8007000 | Win32Error Code:
  860. * If any call to win32 API fails, we return the 32 bit error
  861. * including the Severity Code, Facility Code and the Win32 Error
  862. * Code.
  863. * A possible list of Win32ErrorCode is
  864. * ERROR_NOT_ENOUGH_MEMORY: Out of memory.
  865. *
  866. *
  867. \*****************************************************************************/
  868. STDMETHODIMP Casphelp::get_LongPaperName(BSTR bstrShortName, BSTR * pVal)
  869. {
  870. struct PaperNameMapping {
  871. LPCWSTR pShortName;
  872. DWORD dwLongNameID;
  873. };
  874. static const WCHAR cHyphen = L'-';
  875. static const WCHAR cszUnknown[] = L"Unknown";
  876. static const LPCWSTR pMediaArray[] = {
  877. L"-envelope", L"-white", L"-transparent", L"-coloured", NULL};
  878. static const PaperNameMapping nameMapping[] = {
  879. {L"iso-a0", IDS_A0_841_X_1189_MM},
  880. {L"iso-a1", IDS_A1_594_X_841_MM},
  881. {L"iso-a2", IDS_A2_420_X_594_MM},
  882. {L"iso-a3", IDS_A3_297_X_420_MM},
  883. {L"iso-a4", IDS_A4_210_X_297_MM},
  884. {L"iso-a5", IDS_A5_148_X_210_MM},
  885. {L"iso-a6", IDS_A6_105_X_148_MM},
  886. {L"iso-a7", IDS_A7_74_X_105_MM},
  887. {L"iso-a8", IDS_A8_52_X_74_MM},
  888. {L"iso-a9", IDS_A9_37_X_52_MM},
  889. {L"iso-a10", IDS_A10_26_X_37_MM},
  890. {L"iso-b0", IDS_B0_1000_X_1414_MM},
  891. {L"iso-b1", IDS_B1_707_X_1000_MM},
  892. {L"iso-b2", IDS_B2_500_X_707_MM},
  893. {L"iso-b3", IDS_B3_353_X_500_MM},
  894. {L"iso-b4", IDS_B4_250_X_353_MM},
  895. {L"iso-b5", IDS_B5_176_X_250_MM},
  896. {L"iso-b6", IDS_B6_125_X_176_MM},
  897. {L"iso-b7", IDS_B7_88_X_125_MM},
  898. {L"iso-b8", IDS_B8_62_X_88_MM},
  899. {L"iso-b9", IDS_B9_44_X_62_MM},
  900. {L"iso-b10", IDS_B10_31_X_44_MM},
  901. {L"iso-c0", IDS_C0_917_X_1297_MM},
  902. {L"iso-c1", IDS_C1_648_X_917_MM},
  903. {L"iso-c2", IDS_C2_458_X_648_MM},
  904. {L"iso-c3", IDS_C3_324_X_458_MM},
  905. {L"iso-c4", IDS_C4_ENVELOPE_229_X_324_MM},
  906. {L"iso-c5", IDS_C5_ENVELOPE_162_X_229_MM},
  907. {L"iso-c6", IDS_C6_114_X_162_MM},
  908. {L"iso-c7", IDS_C7_81_X_114_MM},
  909. {L"iso-c8", IDS_C8_57_X_81_MM},
  910. {L"iso-designated", IDS_DL_ENVELOPE_110_X_220_MM},
  911. {L"jis-b0", IDS_B0_1030_X_1456_MM},
  912. {L"jis-b1", IDS_B1_728_X_1030_MM},
  913. {L"jis-b2", IDS_B2_515_X_728_MM},
  914. {L"jis-b3", IDS_B3_364_X_515_MM},
  915. {L"jis-b4", IDS_B4_257_X_364_MM},
  916. {L"jis-b5", IDS_B5_182_X_257_MM},
  917. {L"jis-b6", IDS_B6_128_X_182_MM},
  918. {L"jis-b7", IDS_B7_91_X_128_MM},
  919. {L"jis-b8", IDS_B8_64_X_91_MM},
  920. {L"jis-b9", IDS_B9_45_X_64_MM},
  921. {L"jis-b10", IDS_B10_32_X_45_MM},
  922. {L"na-letter", IDS_LETTER_8_5_X_11_IN},
  923. {L"letter", IDS_LETTER_8_5_X_11_IN},
  924. {L"na-legal", IDS_LEGAL_8_5_X_14_IN},
  925. {L"legal", IDS_LEGAL_8_5_X_14_IN},
  926. {L"na-10x13", IDS_ENVELOPE_10X13},
  927. {L"na-9x12x", IDS_ENVELOPE_9X12},
  928. {L"na-number-10", IDS_ENVELOPE_10},
  929. {L"na-7x9", IDS_ENVELOPE_7X9},
  930. {L"na-9x11x", IDS_ENVELOPE_9X11},
  931. {L"na-10x14", IDS_ENVELOPE_10X14},
  932. {L"na-number-9", IDS_ENVELOPE_9},
  933. {L"na-6x9", IDS_ENVELOPE_6X9},
  934. {L"na-10x15", IDS_ENVELOPE_10X15},
  935. {L"a", IDS_ENGINEERING_A_8_5_X_11_IN},
  936. {L"b", IDS_ENGINEERING_B_11_X_17_IN},
  937. {L"c", IDS_ENGINEERING_C_17_X_22_IN},
  938. {L"d", IDS_ENGINEERING_D_22_X_34_IN},
  939. {L"e", IDS_ENGINEERING_E_34_X_44_IN},
  940. {NULL, 0}
  941. };
  942. const PaperNameMapping *pMapping = nameMapping;
  943. LPWSTR pTail = NULL ;
  944. DWORD dwLongNameID = 0;
  945. WCHAR szBuffer [cdwBufSize];
  946. PWSTR pBuffer = szBuffer;
  947. HRESULT hr = S_OK;
  948. if ( !bstrShortName ) {
  949. hr = E_POINTER;
  950. }
  951. if (SUCCEEDED (hr))
  952. {
  953. //
  954. // find the last char '-'
  955. //
  956. pTail = wcsrchr(bstrShortName, cHyphen );
  957. if ( pTail ) {
  958. const LPCWSTR *pMedia = pMediaArray;
  959. while ( *pMedia ) {
  960. if ( !lstrcmpi (*pMedia, pTail) ) {
  961. //
  962. // Mark it to be NULL;
  963. //
  964. *pTail = 0;
  965. break;
  966. }
  967. pMedia++;
  968. }
  969. }
  970. while ( pMapping->pShortName ) {
  971. if ( !lstrcmpi (pMapping->pShortName, bstrShortName) ) {
  972. //
  973. // Found a match
  974. //
  975. dwLongNameID = pMapping->dwLongNameID;
  976. break;
  977. }
  978. pMapping++;
  979. }
  980. if ( pTail )
  981. *pTail = cHyphen;
  982. if (dwLongNameID)
  983. {
  984. if ( !LoadString( _Module.GetResourceInstance(),
  985. dwLongNameID, szBuffer, cdwBufSize) )
  986. {
  987. hr = SetAspHelpScriptingError(GetLastError());
  988. }
  989. if (SUCCEEDED (hr))
  990. {
  991. if ( !(*pVal = SysAllocString (pBuffer)) )
  992. {
  993. hr = Error(IDS_OUT_OF_MEMORY, IID_Iasphelp, E_OUTOFMEMORY);
  994. }
  995. }
  996. }
  997. else
  998. {
  999. if ( !(*pVal = SysAllocString (cszUnknown)) )
  1000. {
  1001. hr = Error(IDS_OUT_OF_MEMORY, IID_Iasphelp, E_OUTOFMEMORY);
  1002. }
  1003. }
  1004. }
  1005. return hr;
  1006. }
  1007. /*****************************************************************************\
  1008. * FUNCTION: get_MibErrorDscp
  1009. *
  1010. * PURPOSE: Get operation for MibErrorDscp property
  1011. * Map the mib error code to the error description
  1012. *
  1013. * ARGUMENTS:
  1014. *
  1015. * dwError: The error code
  1016. * pVal: Pointer to the error description
  1017. *
  1018. * RETURN VALUE:
  1019. * S_OK: If succeed.
  1020. * E_OUTOFMEMORY: Out of memory.
  1021. *
  1022. * 0x8007000 | Win32Error Code:
  1023. * If any call to win32 API fails, we return the 32 bit error
  1024. * including the Severity Code, Facility Code and the Win32 Error
  1025. * Code.
  1026. * A possible list of Win32ErrorCode is
  1027. * ERROR_NOT_ENOUGH_MEMORY: Out of memory.
  1028. *
  1029. *
  1030. \*****************************************************************************/
  1031. STDMETHODIMP Casphelp::get_MibErrorDscp(DWORD dwError, BSTR * pVal)
  1032. {
  1033. static ErrorMapping errorMapping[] = {
  1034. {1, IDS_MIBERR_OTHER},
  1035. {2, IDS_MIBERR_UNKNOWN},
  1036. {3, IDS_MIBERR_COVEROPEN},
  1037. {4, IDS_MIBERR_COVERCLOSED},
  1038. {5, IDS_MIBERR_INTERLOCKOPEN},
  1039. {6, IDS_MIBERR_INTERLOCKCLOSED},
  1040. {7, IDS_MIBERR_CONFIGURATIONCHANGE},
  1041. {8, IDS_MIBERR_JAM},
  1042. {501, IDS_MIBERR_DOOROPEN},
  1043. {502, IDS_MIBERR_DOORCLOSED},
  1044. {503, IDS_MIBERR_POWERUP},
  1045. {504, IDS_MIBERR_POWERDOWN},
  1046. {801, IDS_MIBERR_INPUTMEDIATRAYMISSING},
  1047. {802, IDS_MIBERR_INPUTMEDIASIZECHANGE},
  1048. {803, IDS_MIBERR_INPUTMEDIAWEIGHTCHANGE},
  1049. {804, IDS_MIBERR_INPUTMEDIATYPECHANGE},
  1050. {805, IDS_MIBERR_INPUTMEDIACOLORCHANGE},
  1051. {806, IDS_MIBERR_INPUTMEDIAFORMPARTSCHANGE},
  1052. {807, IDS_MIBERR_INPUTMEDIASUPPLYLOW},
  1053. {808, IDS_MIBERR_INPUTMEDIASUPPLYEMPTY},
  1054. {901, IDS_MIBERR_OUTPUTMEDIATRAYMISSING},
  1055. {902, IDS_MIBERR_OUTPUTMEDIATRAYALMOSTFULL},
  1056. {903, IDS_MIBERR_OUTPUTMEDIATRAYFULL},
  1057. {1001, IDS_MIBERR_MARKERFUSERUNDERTEMPERATURE},
  1058. {1002, IDS_MIBERR_MARKERFUSEROVERTEMPERATURE},
  1059. {1101, IDS_MIBERR_MARKERTONEREMPTY},
  1060. {1102, IDS_MIBERR_MARKERINKEMPTY},
  1061. {1103, IDS_MIBERR_MARKERPRINTRIBBONEMPTY},
  1062. {1104, IDS_MIBERR_MARKERTONERALMOSTEMPTY},
  1063. {1105, IDS_MIBERR_MARKERINKALMOSTEMPTY},
  1064. {1106, IDS_MIBERR_MARKERPRINTRIBBONALMOSTEMPTY},
  1065. {1107, IDS_MIBERR_MARKERWASTETONERRECEPTACLEALMOSTFULL},
  1066. {1108, IDS_MIBERR_MARKERWASTEINKRECEPTACLEALMOSTFULL},
  1067. {1109, IDS_MIBERR_MARKERWASTETONERRECEPTACLEFULL},
  1068. {1110, IDS_MIBERR_MARKERWASTEINKRECEPTACLEFULL},
  1069. {1111, IDS_MIBERR_MARKEROPCLIFEALMOSTOVER},
  1070. {1112, IDS_MIBERR_MARKEROPCLIFEOVER},
  1071. {1113, IDS_MIBERR_MARKERDEVELOPERALMOSTEMPTY},
  1072. {1114, IDS_MIBERR_MARKERDEVELOPEREMPTY},
  1073. {1301, IDS_MIBERR_MEDIAPATHMEDIATRAYMISSING},
  1074. {1302, IDS_MIBERR_MEDIAPATHMEDIATRAYALMOSTFULL},
  1075. {1303, IDS_MIBERR_MEDIAPATHMEDIATRAYFULL},
  1076. {1501, IDS_MIBERR_INTERPRETERMEMORYINCREASE},
  1077. {1502, IDS_MIBERR_INTERPRETERMEMORYDECREASE},
  1078. {1503, IDS_MIBERR_INTERPRETERCARTRIDGEADDED},
  1079. {1504, IDS_MIBERR_INTERPRETERCARTRIDGEDELETED},
  1080. {1505, IDS_MIBERR_INTERPRETERRESOURCEADDED},
  1081. {1506, IDS_MIBERR_INTERPRETERRESOURCEDELETED},
  1082. {1507, IDS_MIBERR_INTERPRETERRESOURCEUNAVAILABLE},
  1083. {0, 0}
  1084. };
  1085. ErrorMapping *pMapping = errorMapping;
  1086. DWORD dwErrorDscpID = 0;
  1087. TCHAR szBuffer [cdwBufSize];
  1088. if ( !pVal )
  1089. return E_POINTER;
  1090. szBuffer[0] = 0;
  1091. while ( pMapping->dwError ) {
  1092. if ( pMapping->dwError == dwError ) {
  1093. // Found a match
  1094. dwErrorDscpID = pMapping->dwErrorDscpID;
  1095. break;
  1096. }
  1097. pMapping++;
  1098. }
  1099. if ( dwErrorDscpID ) {
  1100. if ( !LoadString( _Module.GetResourceInstance(),
  1101. dwErrorDscpID, szBuffer, cdwBufSize) )
  1102. return SetAspHelpScriptingError(GetLastError());
  1103. }
  1104. if ( !(*pVal = SysAllocString (szBuffer)) )
  1105. return Error(IDS_OUT_OF_MEMORY, IID_Iasphelp, E_OUTOFMEMORY);
  1106. return S_OK;
  1107. }
  1108. /*****************************************************************************\
  1109. * FUNCTION: CalcJobETA
  1110. *
  1111. * PURPOSE: Calculate Job Completion Time
  1112. *
  1113. * ARGUMENTS:
  1114. *
  1115. * RETURN VALUE:
  1116. * S_OK: If succeed.
  1117. * E_HANDLE: Open method has not been called.
  1118. * E_OUTOFMEMORY: Out of memory.
  1119. *
  1120. * 0x8007000 | Win32Error Code:
  1121. * If any call to win32 API fails, we return the 32 bit error
  1122. * including the Severity Code, Facility Code and the Win32 Error
  1123. * Code.
  1124. * A possible list of Win32ErrorCode is
  1125. * ERROR_NOT_ENOUGH_MEMORY: Out of memory.
  1126. *
  1127. *
  1128. \*****************************************************************************/
  1129. STDMETHODIMP Casphelp::CalcJobETA()
  1130. {
  1131. if (m_pPrinter &&
  1132. (m_pPrinter->CalJobEta() || GetLastError () == ERROR_INVALID_DATA) &&
  1133. // If the error is ERROR_INVALID_DATA, m_dwJobCompletionMinute = -1
  1134. (m_pPrinter->GetJobEtaData (m_dwJobCompletionMinute,
  1135. m_dwPendingJobCount,
  1136. m_dwAvgJobSize,
  1137. m_dwAvgJobSizeUnit))) {
  1138. m_bCalcJobETA = TRUE;
  1139. return S_OK;
  1140. }
  1141. else
  1142. return Error(IDS_NO_PRINTER_OPEN, IID_Iasphelp, E_HANDLE);
  1143. }
  1144. /*****************************************************************************\
  1145. *
  1146. * FUNCTION: get_PendingJobCount
  1147. *
  1148. * PURPOSE: Get the number of pending jobs. This value is calculated in
  1149. * CalcJobETA()
  1150. *
  1151. * ARGUMENTS:
  1152. *
  1153. * pVal: The number of pending jobs
  1154. *
  1155. * RETURN VALUE:
  1156. * S_OK: If succeed.
  1157. * E_HANDLE: Open method has not been called.
  1158. * E_OUTOFMEMORY: Out of memory.
  1159. *
  1160. * 0x8007000 | Win32Error Code:
  1161. * If any call to win32 API fails, we return the 32 bit error
  1162. * including the Severity Code, Facility Code and the Win32 Error
  1163. * Code.
  1164. * A possible list of Win32ErrorCode is
  1165. * ERROR_NOT_ENOUGH_MEMORY: Out of memory.
  1166. *
  1167. *
  1168. \*****************************************************************************/
  1169. STDMETHODIMP Casphelp::get_PendingJobCount(long * pVal)
  1170. {
  1171. HRESULT hr = E_HANDLE;
  1172. if (pVal)
  1173. if ( m_bCalcJobETA ) {
  1174. *pVal = m_dwPendingJobCount;
  1175. hr = S_OK;
  1176. }
  1177. else
  1178. *pVal = 0;
  1179. if (hr != S_OK)
  1180. return Error(IDS_NO_PRINTER_OPEN, IID_Iasphelp, hr);
  1181. else
  1182. return S_OK;
  1183. }
  1184. /*****************************************************************************\
  1185. *
  1186. * FUNCTION: get_JobCompletionMinute
  1187. *
  1188. * PURPOSE: Get the minute when the pending jobs are expected to complete.
  1189. * This value is calculated in CalcJobETA()
  1190. *
  1191. * ARGUMENTS:
  1192. *
  1193. * pVal: The value of the minute
  1194. *
  1195. * RETURN VALUE:
  1196. * S_OK: If succeed.
  1197. * E_HANDLE: Open method has not been called.
  1198. * E_OUTOFMEMORY: Out of memory.
  1199. *
  1200. * 0x8007000 | Win32Error Code:
  1201. * If any call to win32 API fails, we return the 32 bit error
  1202. * including the Severity Code, Facility Code and the Win32 Error
  1203. * Code.
  1204. * A possible list of Win32ErrorCode is
  1205. * ERROR_NOT_ENOUGH_MEMORY: Out of memory.
  1206. *
  1207. *
  1208. \*****************************************************************************/
  1209. STDMETHODIMP Casphelp::get_JobCompletionMinute(long * pVal)
  1210. {
  1211. HRESULT hr = E_HANDLE;
  1212. if (pVal)
  1213. if ( m_bCalcJobETA ) {
  1214. *pVal = m_dwJobCompletionMinute;
  1215. hr = S_OK;
  1216. }
  1217. else
  1218. *pVal = 0;
  1219. if (hr != S_OK)
  1220. return Error(IDS_NO_PRINTER_OPEN, IID_Iasphelp, hr);
  1221. else
  1222. return S_OK;
  1223. }
  1224. /*****************************************************************************\
  1225. *
  1226. * FUNCTION: get_AvgJobSizeUnit
  1227. *
  1228. * PURPOSE: Get the unit (either PagePerJob or BytePerJob) of the
  1229. * average job size.
  1230. * This value is calculated in CalcJobETA()
  1231. *
  1232. * ARGUMENTS:
  1233. *
  1234. * pVal: The value of the unit
  1235. *
  1236. * RETURN VALUE:
  1237. * S_OK: If succeed.
  1238. * E_HANDLE: Open method has not been called.
  1239. * E_OUTOFMEMORY: Out of memory.
  1240. *
  1241. * 0x8007000 | Win32Error Code:
  1242. * If any call to win32 API fails, we return the 32 bit error
  1243. * including the Severity Code, Facility Code and the Win32 Error
  1244. * Code.
  1245. * A possible list of Win32ErrorCode is
  1246. * ERROR_NOT_ENOUGH_MEMORY: Out of memory.
  1247. *
  1248. \*****************************************************************************/
  1249. STDMETHODIMP Casphelp::get_AvgJobSizeUnit(long * pVal)
  1250. {
  1251. HRESULT hr = E_HANDLE;
  1252. if (pVal)
  1253. if ( m_bCalcJobETA ) {
  1254. *pVal = m_dwAvgJobSizeUnit;
  1255. hr = S_OK;
  1256. }
  1257. else
  1258. *pVal = 0;
  1259. if (hr != S_OK)
  1260. return Error(IDS_NO_PRINTER_OPEN, IID_Iasphelp, hr);
  1261. else
  1262. return S_OK;
  1263. }
  1264. /*****************************************************************************\
  1265. *
  1266. * FUNCTION: get_AvgJobSize
  1267. *
  1268. * PURPOSE: Get the average job size.
  1269. * This value is calculated in CalcJobETA()
  1270. *
  1271. * ARGUMENTS:
  1272. *
  1273. * pVal: The value of the average job size
  1274. *
  1275. * RETURN VALUE:
  1276. * S_OK: If succeed.
  1277. * E_HANDLE: Open method has not been called.
  1278. * E_OUTOFMEMORY: Out of memory.
  1279. *
  1280. * 0x8007000 | Win32Error Code:
  1281. * If any call to win32 API fails, we return the 32 bit error
  1282. * including the Severity Code, Facility Code and the Win32 Error
  1283. * Code.
  1284. * A possible list of Win32ErrorCode is
  1285. * ERROR_NOT_ENOUGH_MEMORY: Out of memory.
  1286. *
  1287. *
  1288. \*****************************************************************************/
  1289. STDMETHODIMP Casphelp::get_AvgJobSize(long * pVal)
  1290. {
  1291. HRESULT hr = E_HANDLE;
  1292. if (pVal)
  1293. if ( m_bCalcJobETA ) {
  1294. *pVal = m_dwAvgJobSize;
  1295. hr = S_OK;
  1296. }
  1297. else
  1298. *pVal = 0;
  1299. if (hr != S_OK)
  1300. return Error(IDS_NO_PRINTER_OPEN, IID_Iasphelp, hr);
  1301. else
  1302. return S_OK;
  1303. }
  1304. /*****************************************************************************\
  1305. *
  1306. * FUNCTION: get_Status
  1307. *
  1308. * PURPOSE: Get the printer status.
  1309. * The difference between Status and the one got
  1310. * from PRINTER_INFO_2 is that when the printer is offline
  1311. * This function return a status with PRINTE_STATUS_OFFLINE
  1312. * set.
  1313. *
  1314. * ARGUMENTS:
  1315. *
  1316. * pVal: The value of the average job size
  1317. *
  1318. * RETURN VALUE:
  1319. * S_OK: If succeed.
  1320. * E_HANDLE: Open method has not been called.
  1321. * E_OUTOFMEMORY: Out of memory.
  1322. *
  1323. * 0x8007000 | Win32Error Code:
  1324. * If any call to win32 API fails, we return the 32 bit error
  1325. * including the Severity Code, Facility Code and the Win32 Error
  1326. * Code.
  1327. * A possible list of Win32ErrorCode is
  1328. * ERROR_NOT_ENOUGH_MEMORY: Out of memory.
  1329. *
  1330. *
  1331. \*****************************************************************************/
  1332. STDMETHODIMP Casphelp::get_Status(long * pVal)
  1333. {
  1334. *pVal = 0;
  1335. if ( !m_pInfo2 )
  1336. return Error(IDS_NO_PRINTER_OPEN, IID_Iasphelp, E_HANDLE);
  1337. *pVal = m_pInfo2->Status;
  1338. return S_OK;
  1339. }
  1340. /*****************************************************************************\
  1341. *
  1342. * FUNCTION: get_ErrorDscp
  1343. *
  1344. * PURPOSE: Convert the error code to a descriptive string.
  1345. *
  1346. * ARGUMENTS:
  1347. *
  1348. * lErrCode: The error code
  1349. * pVal: Pointer to the descriptive string.
  1350. *
  1351. * RETURN VALUE:
  1352. * S_OK: If succeed.
  1353. * E_HANDLE: Open method has not been called.
  1354. * E_OUTOFMEMORY: Out of memory.
  1355. *
  1356. * 0x8007000 | Win32Error Code:
  1357. * If any call to win32 API fails, we return the 32 bit error
  1358. * including the Severity Code, Facility Code and the Win32 Error
  1359. * Code.
  1360. * A possible list of Win32ErrorCode is
  1361. * ERROR_NOT_ENOUGH_MEMORY: Out of memory.
  1362. *
  1363. *
  1364. \*****************************************************************************/
  1365. STDMETHODIMP Casphelp::get_ErrorDscp(long lErrCode, BSTR * pVal)
  1366. {
  1367. static ErrorMapping errorMapping[] = {
  1368. {ERROR_NOT_SUPPORTED, IDS_ERROR_CPUNOTSUPPORTED},
  1369. {ERROR_DRIVER_NOT_FOUND, IDS_ERROR_DRIVERNOTFOUND},
  1370. {ERROR_WPNPINST_TERMINATED, IDS_ERROR_WPNPINST_TERMINATED},
  1371. {ERROR_INTERNAL_SERVER, IDS_ERROR_INTERNAL_SERVER},
  1372. {ERROR_SERVER_DISK_FULL, IDS_ERROR_SERVER_DISK_FULL},
  1373. {ERROR_TRUST_E_NOSIGNATURE, IDS_ERROR_TRUST_E_NOSIGNATURE},
  1374. {ERROR_SPAPI_E_NO_CATALOG, IDS_ERROR_TRUST_E_NOSIGNATURE},
  1375. {ERROR_TRUST_E_BAD_DIGEST, IDS_ERROR_TRUST_E_NOSIGNATURE},
  1376. {ERROR_LOCAL_PRINTER_ACCESS,IDS_ERROR_LOCAL_PRINTER_ACCESS},
  1377. {ERROR_IE_SECURITY_DENIED, IDS_ERROR_IE_SECURITY_DENIED},
  1378. {CRYPT_E_FILE_ERROR, IDS_CRYPT_E_FILE_ERROR},
  1379. {0, 0}
  1380. };
  1381. ErrorMapping *pMapping = errorMapping;
  1382. DWORD dwErrorDscpID = 0;
  1383. DWORD dwError = ((DWORD)lErrCode) & 0xFFFF;
  1384. TCHAR szBuffer [cdwBufSize];
  1385. if ( !pVal )
  1386. return E_POINTER;
  1387. szBuffer[0] = 0;
  1388. while ( pMapping->dwError ) {
  1389. if ( pMapping->dwError == dwError ) {
  1390. // Found a match
  1391. dwErrorDscpID = pMapping->dwErrorDscpID;
  1392. break;
  1393. }
  1394. pMapping++;
  1395. }
  1396. if ( dwErrorDscpID ) {
  1397. if ( !LoadString( _Module.GetResourceInstance(),
  1398. dwErrorDscpID, szBuffer, cdwBufSize) )
  1399. return SetAspHelpScriptingError(GetLastError());
  1400. }
  1401. else {
  1402. if ( !FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM,
  1403. NULL,
  1404. dwError,
  1405. 0,
  1406. szBuffer,
  1407. cdwBufSize,
  1408. NULL) ) {
  1409. return SetAspHelpScriptingError(GetLastError());
  1410. }
  1411. }
  1412. if ( !(*pVal = SysAllocString (szBuffer)) )
  1413. return Error(IDS_OUT_OF_MEMORY, IID_Iasphelp, E_OUTOFMEMORY);
  1414. return S_OK;
  1415. }
  1416. /*****************************************************************************\
  1417. * FUNCTION: get_ShareName
  1418. *
  1419. * PURPOSE: Get operation for ShareName property
  1420. *
  1421. * ARGUMENTS:
  1422. *
  1423. * pVal: Return the share name of the specified printer
  1424. *
  1425. * RETURN VALUE:
  1426. * S_OK: If succeed.
  1427. * E_HANDLE: Open method has not been called.
  1428. * E_OUTOFMEMORY: Out of memory.
  1429. *
  1430. * 0x8007000 | Win32Error Code:
  1431. * If any call to win32 API fails, we return the 32 bit error
  1432. * including the Severity Code, Facility Code and the Win32 Error
  1433. * Code.
  1434. * A possible list of Win32ErrorCode is
  1435. * ERROR_NOT_ENOUGH_MEMORY: Out of memory.
  1436. *
  1437. *
  1438. \*****************************************************************************/
  1439. STDMETHODIMP Casphelp::get_ShareName(BSTR * pbstrVal)
  1440. {
  1441. HRESULT hRet = S_OK;
  1442. if ( !m_pInfo2 )
  1443. return Error(IDS_NO_PRINTER_OPEN, IID_Iasphelp, E_HANDLE);
  1444. if ( !(*pbstrVal = SysAllocString (m_pInfo2->pShareName)) )
  1445. hRet = Error(IDS_OUT_OF_MEMORY, IID_Iasphelp, E_OUTOFMEMORY);
  1446. return hRet;
  1447. }
  1448. STDMETHODIMP Casphelp::get_IsCluster(BOOL * pbVal)
  1449. {
  1450. DWORD dwClusterState;
  1451. *pbVal = FALSE;
  1452. if ((GetNodeClusterState (NULL, &dwClusterState) == ERROR_SUCCESS) &&
  1453. (dwClusterState == ClusterStateRunning)) {
  1454. *pbVal = TRUE;
  1455. }
  1456. return S_OK;
  1457. }