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.

341 lines
10 KiB

  1. /*****************************************************************************\
  2. * MODULE: custom.cpp
  3. *
  4. * PURPOSE: OEM Customization support
  5. *
  6. * Copyright (C) 1997-1998 Microsoft Corporation
  7. *
  8. * History:
  9. *
  10. * 10/10/97 babakj Created
  11. *
  12. \*****************************************************************************/
  13. #include "stdafx.h"
  14. #include <strsafe.h>
  15. #include "gensph.h"
  16. #include "oleprn.h"
  17. #include "asphelp.h"
  18. TCHAR cszEverestVirRoot[] = TEXT("\\web\\printers");
  19. TCHAR cszManufacturerKey[] = TEXT("PnPData");
  20. TCHAR cszManufacturerValue[] = TEXT("Manufacturer");
  21. #define DEFAULTASPPAGE TEXT("Page1.asp")
  22. //
  23. // Caller allocs memory for pMonitorname.
  24. //
  25. // pMonitorName untouched if failure.
  26. //
  27. BOOL Casphelp::GetMonitorName( LPTSTR pMonitorName, DWORD cchBufSize )
  28. {
  29. PPORT_INFO_2 pPortInfo2 = NULL;
  30. BOOL fRet = FALSE;
  31. DWORD dwNeeded, dwReturned;
  32. // Now get all ports to find a match from.
  33. LPTSTR lpszServerName = m_pInfo2 ? m_pInfo2->pServerName : NULL;
  34. if( EnumPorts(lpszServerName, 2, NULL, 0, &dwNeeded, &dwReturned) ||
  35. (GetLastError() != ERROR_INSUFFICIENT_BUFFER) ||
  36. (NULL == (pPortInfo2 = (PPORT_INFO_2)LocalAlloc( LPTR, dwNeeded))) ||
  37. (!EnumPorts( lpszServerName , 2, (LPBYTE)pPortInfo2, dwNeeded, &dwNeeded, &dwReturned ))) {
  38. LocalFree( pPortInfo2 );
  39. SetAspHelpScriptingError(GetLastError());
  40. return FALSE;
  41. }
  42. if ( m_pInfo2 ) {
  43. for( DWORD i=0; i < dwReturned; i++ )
  44. if( !lstrcmpi( pPortInfo2[i].pPortName, m_pInfo2->pPortName )) {
  45. // Some monitors (like LPRMON) do not fill in pMonitorName, so we ignore them.
  46. if( pPortInfo2[i].pMonitorName ) {
  47. StringCchCopy( pMonitorName, cchBufSize, pPortInfo2[i].pMonitorName );
  48. fRet = TRUE;
  49. }
  50. break;
  51. }
  52. }
  53. LocalFree( pPortInfo2 );
  54. return fRet;
  55. }
  56. //
  57. // Get the model name (aka driver name) of the printer
  58. //
  59. // Caller allocs memory for pModel.
  60. //
  61. BOOL Casphelp::GetModel( LPTSTR pModel, DWORD cchBufSize )
  62. {
  63. if (!m_pInfo2)
  64. {
  65. Error(IDS_NO_PRINTER_OPEN, IID_Iasphelp, E_HANDLE);
  66. return FALSE;
  67. }
  68. StringCchCopy( pModel, cchBufSize, m_pInfo2->pDriverName );
  69. return TRUE;
  70. }
  71. //
  72. // Get the Manufacturer name (aka driver name) of the printer
  73. //
  74. // Caller allocs memory for pManufacturer.
  75. //
  76. BOOL Casphelp::GetManufacturer( LPTSTR pManufacturer, DWORD cchBufSize )
  77. {
  78. if (!m_hPrinter)
  79. {
  80. Error(IDS_NO_PRINTER_OPEN, IID_Iasphelp, E_HANDLE);
  81. return FALSE;
  82. }
  83. DWORD dwNeeded, dwType, dwRet;
  84. dwRet = GetPrinterDataEx( m_hPrinter,
  85. cszManufacturerKey,
  86. cszManufacturerValue,
  87. &dwType,
  88. (LPBYTE) pManufacturer,
  89. sizeof(TCHAR) * cchBufSize,
  90. &dwNeeded);
  91. if (dwRet != ERROR_SUCCESS || dwType != REG_SZ)
  92. {
  93. SetAspHelpScriptingError(dwRet);
  94. return FALSE;
  95. }
  96. else
  97. {
  98. pManufacturer[cchBufSize - 1] = 0;
  99. return TRUE;
  100. }
  101. }
  102. //
  103. // Returns:
  104. // bDeviceASP == TRUE: The relative path to the ASP file if the printer has INF-based ASP support.
  105. // bDeviceASP == FALSE: The relative path to the ASP file if the printer has per-manufacturer ASP support (i.e.
  106. // ASP support just based on its manufacturer name, rather than per model.
  107. //
  108. // Caller allocs memory for pAspPage.
  109. //
  110. // - pASPPage untouched if failure.
  111. //
  112. BOOL Casphelp::IsCustomASP( BOOL bDeviceASP, LPTSTR pASPPage, DWORD cchBufSize )
  113. {
  114. TCHAR szRelPath [MAX_PATH]; // Path relative to Winnt\web\printers, e.g. HP\LJ4si\page1.asp or .\hp (witout the .\)
  115. TCHAR szFinalPath [MAX_PATH]; // Absolute path for szRelPath.
  116. TCHAR szModel [MAX_PATH];
  117. int nLen;
  118. // The Printer virtual dir assumed to be winnt\web\printers. Construct it.
  119. if( !GetWindowsDirectory( szFinalPath, COUNTOF(szFinalPath))) // Return value is the length in chars w/o null char.
  120. return FALSE;
  121. // Append web\printers to the end
  122. StringCchCat( szFinalPath, ARRAYSIZE(szFinalPath), cszEverestVirRoot );
  123. // Prepare the relative path.
  124. if( !GetManufacturer( szRelPath, ARRAYSIZE(szRelPath)))
  125. return FALSE;
  126. if( bDeviceASP ) {
  127. // Add a '\' before we add the model name
  128. StringCchCat( szRelPath, ARRAYSIZE(szRelPath), L"\\" );
  129. // Append the Model name
  130. if( !GetModel(szModel, ARRAYSIZE(szModel)))
  131. return FALSE;
  132. StringCchCat( szRelPath, ARRAYSIZE(szRelPath), szModel );
  133. }
  134. // Append "page1.asp" to the end.
  135. StringCchCat( szRelPath, ARRAYSIZE(szRelPath), L"\\" );
  136. StringCchCat( szRelPath, ARRAYSIZE(szRelPath), DEFAULTASPPAGE );
  137. // At this point, szRelPath should be something like HP\LJ4si\page1.asp or HP\page1.asp.
  138. // Make an absolute path by concatanating szRelPath and szFinalPath
  139. StringCchCat( szFinalPath, ARRAYSIZE(szFinalPath), L"\\" );
  140. StringCchCat( szFinalPath, ARRAYSIZE(szFinalPath), szRelPath );
  141. // See if the file exists.
  142. if( (DWORD)(-1) == GetFileAttributes( szFinalPath ))
  143. return FALSE; // The file does not exist
  144. else {
  145. // The file exists, so the printer has per device or per manufacturer customization.
  146. StringCchCopy( pASPPage, cchBufSize, szRelPath );
  147. return TRUE;
  148. }
  149. }
  150. //
  151. // Returns: The relative path to the default ASP file, i.e. page1.asp, if the printer supports RFC 1759.
  152. //
  153. // Caller allocs memory for pAspPage.
  154. //
  155. // pASPPage untouched if failure.
  156. //
  157. BOOL Casphelp::IsSnmpSupportedASP( LPTSTR pASPPage, DWORD cchBufSize )
  158. {
  159. BOOL fIsSNMPSupported;
  160. HRESULT hr;
  161. hr = get_SNMPSupported( &fIsSNMPSupported );
  162. if( FAILED( hr ))
  163. return FALSE;
  164. if( fIsSNMPSupported )
  165. StringCchCopy( pASPPage, cchBufSize, DEFAULTASPPAGE );
  166. else
  167. *pASPPage = 0; // Return an empty string. Not an error case.
  168. return TRUE;
  169. }
  170. //
  171. // Caller allocs memory for pAspPage.
  172. //
  173. // pASPPage untouched if failure.
  174. //
  175. BOOL Casphelp::GetASPPageForUniversalMonitor( LPTSTR pASPPage, DWORD cchBufSize )
  176. {
  177. if( !IsCustomASP( TRUE, pASPPage, cchBufSize )) // Check for device ASP
  178. if( !IsCustomASP( FALSE, pASPPage, cchBufSize )) // Check for manufacturer ASP
  179. if( !IsSnmpSupportedASP( pASPPage, cchBufSize )) // Check for SNMP support
  180. return FALSE;
  181. return TRUE;
  182. }
  183. //
  184. // Caller allocs memory for pAspPage.
  185. //
  186. // pASPPage untouched if failure.
  187. //
  188. BOOL Casphelp::GetASPPageForOtherMonitors( LPTSTR pMonitorName, LPTSTR pASPPage, DWORD cchBufSize )
  189. {
  190. TCHAR szRelPath [MAX_PATH]; // Path relative to Winnt\web\printers, e.g. LexmarkMon\page1.asp
  191. TCHAR szFinalPath [MAX_PATH]; // Absolute path for szRelPath.
  192. int nLen;
  193. // The Printer virtual dir assumed to be winnt\web\printers. Construct it.
  194. if( !GetWindowsDirectory( szFinalPath, COUNTOF(szFinalPath))) // Return value is the length in chars w/o null char.
  195. return FALSE;
  196. // Append web\printers to the end
  197. StringCchCat( szFinalPath, ARRAYSIZE(szFinalPath), cszEverestVirRoot );
  198. // Prepare the relative path.
  199. StringCchCopy( szRelPath, ARRAYSIZE(szRelPath), pMonitorName );
  200. // Append "page1.asp" to the end.
  201. StringCchCat( szRelPath, ARRAYSIZE(szRelPath), L"\\" );
  202. StringCchCat( szRelPath, ARRAYSIZE(szRelPath), DEFAULTASPPAGE );
  203. // At this point, szRelPath should be something like LexmarkMon\page1.asp
  204. // Make an absolute path by concatanating szRelPath and szFinalPath
  205. StringCchCat( szFinalPath, ARRAYSIZE(szFinalPath), L"\\" );
  206. StringCchCat( szFinalPath, ARRAYSIZE(szFinalPath), szRelPath );
  207. // See if the file exists.
  208. if( (DWORD)(-1) == GetFileAttributes( szFinalPath ))
  209. return FALSE; // The file does not exist
  210. else {
  211. // The file exists, so the printer has per device or per manufacturer customization.
  212. StringCchCopy( pASPPage, cchBufSize, szRelPath );
  213. return TRUE;
  214. }
  215. }
  216. //
  217. // Returns a buffer containing the relative path of the ASP, or an empty string.
  218. //
  219. // Caller allocs memory for pAspPage.
  220. //
  221. // pASPPage untouched if failure.
  222. //
  223. BOOL Casphelp::GetASPPage( LPTSTR pASPPage, DWORD cchBufSize )
  224. {
  225. if( m_bTCPMonSupported ) {
  226. // The printer is using the Universal monitor
  227. if( !GetASPPageForUniversalMonitor( pASPPage, cchBufSize ))
  228. return FALSE;
  229. }
  230. else {
  231. TCHAR szMonitorName[MAX_PATH];
  232. if ( !GetMonitorName( szMonitorName, ARRAYSIZE(szMonitorName)))
  233. return FALSE;
  234. // The printer is NOT using the Universal monitor
  235. if( !GetASPPageForOtherMonitors( szMonitorName, pASPPage, cchBufSize))
  236. return FALSE;
  237. }
  238. return TRUE;
  239. }
  240. // STDMETHODIMP means "HRESULT _stdcall"
  241. STDMETHODIMP Casphelp::get_AspPage(DWORD dwPage, BSTR * pbstrVal)
  242. {
  243. TCHAR szASPPage[MAX_PATH];
  244. LPTSTR pUrl;
  245. if (!pbstrVal)
  246. return Error(IDS_OUT_OF_MEMORY, IID_Iasphelp, E_POINTER);
  247. if (m_hPrinter == NULL)
  248. return Error(IDS_NO_PRINTER_OPEN, IID_Iasphelp, E_HANDLE);
  249. if( !GetASPPage( szASPPage, ARRAYSIZE(szASPPage)))
  250. return Error(IDS_DATA_NOT_SUPPORTED, IID_Iasphelp, E_NOTIMPL);
  251. // Encode the URL by replacing ' ' with %20, etc.
  252. if (! (pUrl = EncodeString (szASPPage, TRUE)))
  253. return Error(IDS_OUT_OF_MEMORY, IID_Iasphelp, E_POINTER);
  254. if (!(*pbstrVal = SysAllocString( pUrl ))) {
  255. LocalFree (pUrl);
  256. return Error(IDS_OUT_OF_MEMORY, IID_Iasphelp, E_POINTER);
  257. }
  258. if (pUrl)
  259. LocalFree (pUrl);
  260. return S_OK;
  261. }