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

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