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.

728 lines
16 KiB

  1. /*++
  2. Copyright (C) Microsoft Corporation, 1998 - 1999
  3. All rights reserved.
  4. Module Name:
  5. prndata.cxx
  6. Abstract:
  7. Type safe printer data class
  8. Author:
  9. Steve Kiraly (SteveKi) 24-Aug-1998
  10. Revision History:
  11. --*/
  12. #include <precomp.hxx>
  13. #pragma hdrstop
  14. #include "prndata.hxx"
  15. TPrinterDataAccess::
  16. TPrinterDataAccess(
  17. IN LPCTSTR pszPrinter,
  18. IN EResourceType eResourceType,
  19. IN EAccessType eAccessType
  20. )
  21. {
  22. DBGMSG( DBG_TRACE, ("TPrinterDataAccess::TPrinterDataAccess\n") );
  23. InitializeClassVariables();
  24. PRINTER_DEFAULTS Access = {0, 0, PrinterAccessFlags( eResourceType, eAccessType ) };
  25. //
  26. // Null string indicate the local server.
  27. //
  28. pszPrinter = (pszPrinter && *pszPrinter) ? pszPrinter : NULL;
  29. if (OpenPrinter( const_cast<LPTSTR>( pszPrinter ), &m_hPrinter, &Access))
  30. {
  31. m_eAccessType = eAccessType;
  32. }
  33. }
  34. TPrinterDataAccess::
  35. TPrinterDataAccess(
  36. IN HANDLE hPrinter
  37. )
  38. {
  39. DBGMSG( DBG_TRACE, ("TPrinterDataAccess::TPrinterDataAccess\n") );
  40. InitializeClassVariables();
  41. m_hPrinter = hPrinter;
  42. m_bAcceptedHandle = TRUE;
  43. }
  44. TPrinterDataAccess::
  45. ~TPrinterDataAccess(
  46. VOID
  47. )
  48. {
  49. DBGMSG( DBG_TRACE, ("TPrinterDataAccess::~TPrinterDataAccess\n") );
  50. if( !m_bAcceptedHandle && m_hPrinter )
  51. {
  52. ClosePrinter( m_hPrinter );
  53. }
  54. }
  55. BOOL
  56. TPrinterDataAccess::
  57. Init(
  58. VOID
  59. ) const
  60. {
  61. return m_hPrinter != NULL;
  62. }
  63. HRESULT
  64. TPrinterDataAccess::
  65. Get(
  66. IN LPCTSTR pszValue,
  67. IN OUT BOOL &bData
  68. )
  69. {
  70. return GetDataHelper( NULL, pszValue, kDataTypeBool, &bData, sizeof( BOOL ), NULL );
  71. }
  72. HRESULT
  73. TPrinterDataAccess::
  74. Get(
  75. IN LPCTSTR pszValue,
  76. IN OUT DWORD &dwData
  77. )
  78. {
  79. return GetDataHelper( NULL, pszValue, kDataTypeDword, &dwData, sizeof( DWORD ), NULL );
  80. }
  81. HRESULT
  82. TPrinterDataAccess::
  83. Get(
  84. IN LPCTSTR pszValue,
  85. IN OUT TString &strString
  86. )
  87. {
  88. return GetDataStringHelper( NULL, pszValue, strString );
  89. }
  90. HRESULT
  91. TPrinterDataAccess::
  92. Get(
  93. IN LPCTSTR pszValue,
  94. IN OUT TString **ppstrString,
  95. IN OUT UINT &nItemCount
  96. )
  97. {
  98. return GetDataMuliSzStringHelper( NULL, pszValue, ppstrString, nItemCount );
  99. }
  100. HRESULT
  101. TPrinterDataAccess::
  102. Get(
  103. IN LPCTSTR pszValue,
  104. IN OUT PVOID pData,
  105. IN UINT nSize
  106. )
  107. {
  108. return GetDataHelper( NULL, pszValue, kDataTypeStruct, pData, nSize, NULL );
  109. }
  110. HRESULT
  111. TPrinterDataAccess::
  112. Get(
  113. IN LPCTSTR pszKey,
  114. IN LPCTSTR pszValue,
  115. IN OUT BOOL &bData
  116. )
  117. {
  118. return GetDataHelper( pszKey, pszValue, kDataTypeBool, &bData, sizeof( BOOL ), NULL );
  119. }
  120. HRESULT
  121. TPrinterDataAccess::
  122. Get(
  123. IN LPCTSTR pszKey,
  124. IN LPCTSTR pszValue,
  125. IN OUT DWORD &dwData
  126. )
  127. {
  128. return GetDataHelper( pszKey, pszValue, kDataTypeDword, &dwData, sizeof( DWORD ), NULL );
  129. }
  130. HRESULT
  131. TPrinterDataAccess::
  132. Get(
  133. IN LPCTSTR pszKey,
  134. IN LPCTSTR pszValue,
  135. IN OUT TString &strString
  136. )
  137. {
  138. return GetDataStringHelper( pszKey, pszValue, strString );
  139. }
  140. HRESULT
  141. TPrinterDataAccess::
  142. Get(
  143. IN LPCTSTR pszKey,
  144. IN LPCTSTR pszValue,
  145. IN OUT PVOID pData,
  146. IN UINT nSize
  147. )
  148. {
  149. return GetDataHelper( pszKey, pszValue, kDataTypeStruct, pData, nSize, NULL );
  150. }
  151. HRESULT
  152. TPrinterDataAccess::
  153. Get(
  154. IN LPCTSTR pszKey,
  155. IN LPCTSTR pszValue,
  156. IN OUT TString **ppstrString,
  157. IN OUT UINT &nItemCount
  158. )
  159. {
  160. return GetDataMuliSzStringHelper( pszKey, pszValue, ppstrString, nItemCount );
  161. }
  162. HRESULT
  163. TPrinterDataAccess::
  164. Set(
  165. IN LPCTSTR pszValue,
  166. IN BOOL bData
  167. )
  168. {
  169. return SetDataHelper( NULL, pszValue, kDataTypeBool, &bData, sizeof( BOOL ) );
  170. }
  171. HRESULT
  172. TPrinterDataAccess::
  173. Set(
  174. IN LPCTSTR pszValue,
  175. IN DWORD dwData
  176. )
  177. {
  178. return SetDataHelper( NULL, pszValue, kDataTypeDword, &dwData, sizeof( DWORD ) );
  179. }
  180. HRESULT
  181. TPrinterDataAccess::
  182. Set(
  183. IN LPCTSTR pszValue,
  184. IN TString &strString
  185. )
  186. {
  187. return SetDataHelper( NULL,
  188. pszValue,
  189. kDataTypeString,
  190. reinterpret_cast<PVOID>( const_cast<LPTSTR>( static_cast<LPCTSTR>( strString ) ) ),
  191. (strString.uLen() + 1) * sizeof( TCHAR ) );
  192. }
  193. HRESULT
  194. TPrinterDataAccess::
  195. Set(
  196. IN LPCTSTR pszValue,
  197. IN PVOID pData,
  198. IN UINT nSize
  199. )
  200. {
  201. return SetDataHelper( NULL, pszValue, kDataTypeStruct, pData, nSize );
  202. }
  203. HRESULT
  204. TPrinterDataAccess::
  205. Set(
  206. IN LPCTSTR pszKey,
  207. IN LPCTSTR pszValue,
  208. IN PVOID pData,
  209. IN UINT nSize
  210. )
  211. {
  212. return SetDataHelper( pszKey, pszValue, kDataTypeStruct, pData, nSize );
  213. }
  214. HRESULT
  215. TPrinterDataAccess::
  216. Set(
  217. IN LPCTSTR pszKey,
  218. IN LPCTSTR pszValue,
  219. IN BOOL bData
  220. )
  221. {
  222. return SetDataHelper( pszKey, pszValue, kDataTypeBool, &bData, sizeof( BOOL ) );
  223. }
  224. HRESULT
  225. TPrinterDataAccess::
  226. Set(
  227. IN LPCTSTR pszKey,
  228. IN LPCTSTR pszValue,
  229. IN DWORD dwData
  230. )
  231. {
  232. return SetDataHelper( pszKey, pszValue, kDataTypeDword, &dwData, sizeof( DWORD ) );
  233. }
  234. HRESULT
  235. TPrinterDataAccess::
  236. Set(
  237. IN LPCTSTR pszKey,
  238. IN LPCTSTR pszValue,
  239. IN TString &strString
  240. )
  241. {
  242. return SetDataHelper( pszKey,
  243. pszValue,
  244. kDataTypeString,
  245. reinterpret_cast<PVOID>( const_cast<LPTSTR>( static_cast<LPCTSTR>( strString ) ) ),
  246. (strString.uLen() + 1) * sizeof( TCHAR ) );
  247. }
  248. HRESULT
  249. TPrinterDataAccess::
  250. Delete(
  251. IN LPCTSTR pszValue
  252. )
  253. {
  254. return DeleteDataHelper( NULL, pszValue );
  255. }
  256. HRESULT
  257. TPrinterDataAccess::
  258. Delete(
  259. IN LPCTSTR pszKey,
  260. IN LPCTSTR pszValue
  261. )
  262. {
  263. return DeleteDataHelper( pszKey, pszValue );
  264. }
  265. HRESULT
  266. TPrinterDataAccess::
  267. GetDataSize(
  268. IN LPCTSTR pszValue,
  269. IN DWORD dwType,
  270. IN DWORD &nSize
  271. )
  272. {
  273. return GetDataSizeHelper( NULL, pszValue, dwType, &nSize );
  274. }
  275. VOID
  276. TPrinterDataAccess::
  277. RelaxReturnTypeCheck(
  278. IN BOOL bCheckState
  279. )
  280. {
  281. m_bRelaxReturnedTypeCheck = bCheckState;
  282. }
  283. //
  284. // Private functions.
  285. //
  286. VOID
  287. TPrinterDataAccess::
  288. InitializeClassVariables(
  289. VOID
  290. )
  291. {
  292. m_hPrinter = NULL;
  293. m_eAccessType = kAccessUnknown;
  294. m_bAcceptedHandle = FALSE;
  295. m_bRelaxReturnedTypeCheck = FALSE;
  296. }
  297. ACCESS_MASK
  298. TPrinterDataAccess::
  299. PrinterAccessFlags(
  300. IN EResourceType eResourceType,
  301. IN EAccessType eAccessType
  302. ) const
  303. {
  304. static const DWORD adwAccessPrinter[] =
  305. {
  306. PRINTER_ALL_ACCESS,
  307. PRINTER_READ,
  308. 0,
  309. };
  310. static const DWORD adwAccessServer[] =
  311. {
  312. SERVER_ALL_ACCESS,
  313. SERVER_READ,
  314. 0,
  315. };
  316. DWORD dwAccess = 0;
  317. UINT uAccessType = eAccessType > 3 ? 2 : eAccessType;
  318. switch( eResourceType )
  319. {
  320. case kResourceServer:
  321. dwAccess = adwAccessServer[uAccessType];
  322. break;
  323. case kResourcePrinter:
  324. dwAccess = adwAccessPrinter[uAccessType];
  325. break;
  326. case kResourceUnknown:
  327. default:
  328. break;
  329. }
  330. return dwAccess;
  331. }
  332. DWORD
  333. TPrinterDataAccess::
  334. ClassTypeToRegType(
  335. IN EDataType eDataType
  336. ) const
  337. {
  338. static const DWORD adwRegTypes[] =
  339. {
  340. REG_DWORD,
  341. REG_DWORD,
  342. REG_SZ,
  343. REG_BINARY,
  344. REG_MULTI_SZ,
  345. };
  346. UINT uDataType = eDataType;
  347. return adwRegTypes[eDataType];
  348. }
  349. TPrinterDataAccess::EDataType
  350. TPrinterDataAccess::
  351. RegTypeToClassType(
  352. IN DWORD dwDataType
  353. ) const
  354. {
  355. static const ClassTypeMap aClassMap[] =
  356. {
  357. {REG_DWORD, kDataTypeBool},
  358. {REG_DWORD, kDataTypeDword},
  359. {REG_SZ, kDataTypeString},
  360. {REG_BINARY, kDataTypeStruct}
  361. };
  362. EDataType eReturnDataType = kDataTypeUnknown;
  363. for( UINT i = 0; i < sizeof(aClassMap) / sizeof(ClassTypeMap); i++ )
  364. {
  365. if (aClassMap[i].Reg == dwDataType)
  366. {
  367. eReturnDataType = aClassMap[i].Class;
  368. break;
  369. }
  370. }
  371. return eReturnDataType;
  372. }
  373. HRESULT
  374. TPrinterDataAccess::
  375. GetDataSizeHelper(
  376. IN LPCTSTR pszKey,
  377. IN LPCTSTR pszValue,
  378. IN DWORD dwType,
  379. IN LPDWORD pdwNeeded
  380. )
  381. {
  382. return GetDataHelper( pszKey,
  383. pszValue,
  384. RegTypeToClassType( dwType ),
  385. NULL,
  386. 0,
  387. pdwNeeded );
  388. }
  389. HRESULT
  390. TPrinterDataAccess::
  391. GetDataHelper(
  392. IN LPCTSTR pszKey,
  393. IN LPCTSTR pszValue,
  394. IN EDataType eDataType,
  395. IN PVOID pData,
  396. IN UINT nSize,
  397. IN LPDWORD pdwNeeded
  398. )
  399. {
  400. DWORD dwNeeded = 0;
  401. DWORD dwType = ClassTypeToRegType( eDataType );
  402. DWORD dwStatus = ERROR_SUCCESS;
  403. SPLASSERT( pszValue );
  404. if (pszKey)
  405. {
  406. #if _WIN32_WINNT >= 0x0500
  407. dwStatus = GetPrinterDataEx( m_hPrinter,
  408. const_cast<LPTSTR>( pszKey ),
  409. const_cast<LPTSTR>( pszValue ),
  410. &dwType,
  411. reinterpret_cast<PBYTE>( pData ),
  412. nSize,
  413. &dwNeeded );
  414. #else
  415. dwStatus = ERROR_INVALID_PARAMETER;
  416. #endif
  417. }
  418. else
  419. {
  420. dwStatus = GetPrinterData( m_hPrinter,
  421. const_cast<LPTSTR>( pszValue ),
  422. &dwType,
  423. reinterpret_cast<PBYTE>( pData ),
  424. nSize,
  425. &dwNeeded );
  426. }
  427. if (!m_bRelaxReturnedTypeCheck && dwType != ClassTypeToRegType( eDataType ))
  428. {
  429. dwStatus = ERROR_INVALID_PARAMETER;
  430. }
  431. if (pdwNeeded && dwStatus == ERROR_MORE_DATA)
  432. {
  433. *pdwNeeded = dwNeeded;
  434. dwStatus = ERROR_SUCCESS;
  435. }
  436. return HRESULT_FROM_WIN32( dwStatus );
  437. }
  438. HRESULT
  439. TPrinterDataAccess::
  440. SetDataHelper(
  441. IN LPCTSTR pszKey,
  442. IN LPCTSTR pszValue,
  443. IN EDataType eDataType,
  444. IN PVOID pData,
  445. IN UINT nSize
  446. )
  447. {
  448. SPLASSERT( pszValue );
  449. SPLASSERT( pData );
  450. DWORD dwStatus = ERROR_SUCCESS;
  451. DWORD dwType = ClassTypeToRegType( eDataType );
  452. if (pszKey)
  453. {
  454. #if _WIN32_WINNT >= 0x0500
  455. dwStatus = SetPrinterDataEx( m_hPrinter,
  456. const_cast<LPTSTR>( pszKey ),
  457. const_cast<LPTSTR>( pszValue ),
  458. dwType,
  459. reinterpret_cast<PBYTE>( pData ),
  460. nSize );
  461. #else
  462. dwStatus = ERROR_INVALID_PARAMETER;
  463. #endif
  464. }
  465. else
  466. {
  467. dwStatus = SetPrinterData( m_hPrinter,
  468. const_cast<LPTSTR>( pszValue ),
  469. dwType,
  470. reinterpret_cast<PBYTE>( pData ),
  471. nSize );
  472. }
  473. //
  474. // SetPrinterData may return an error code that is successful but
  475. // not ERROR_SUCCESS.
  476. //
  477. if( dwStatus == ERROR_SUCCESS_RESTART_REQUIRED )
  478. {
  479. return MAKE_HRESULT( 0, FACILITY_WIN32, dwStatus );
  480. }
  481. return HRESULT_FROM_WIN32( dwStatus );
  482. }
  483. HRESULT
  484. TPrinterDataAccess::
  485. DeleteDataHelper(
  486. IN LPCTSTR pszKey,
  487. IN LPCTSTR pszValue
  488. )
  489. {
  490. SPLASSERT( pszValue );
  491. DWORD dwStatus = ERROR_SUCCESS;
  492. if (pszKey)
  493. {
  494. #if _WIN32_WINNT >= 0x0500
  495. SPLASSERT( !pszKey );
  496. dwStatus = DeletePrinterDataEx( m_hPrinter,
  497. const_cast<LPTSTR>( pszKey ),
  498. const_cast<LPTSTR>( pszValue ) );
  499. #endif
  500. }
  501. else
  502. {
  503. dwStatus = DeletePrinterData( m_hPrinter,
  504. const_cast<LPTSTR>( pszValue ) );
  505. }
  506. return HRESULT_FROM_WIN32( dwStatus );
  507. }
  508. HRESULT
  509. TPrinterDataAccess::
  510. GetDataStringHelper(
  511. IN LPCTSTR pszKey,
  512. IN LPCTSTR pszValue,
  513. IN OUT TString &strString
  514. )
  515. {
  516. SPLASSERT( pszValue );
  517. DWORD nSize = 0;
  518. HRESULT hr = GetDataSizeHelper( pszKey, pszValue, REG_SZ, &nSize );
  519. if (SUCCEEDED( hr ))
  520. {
  521. auto_ptr<TCHAR> pData = new TCHAR[nSize+1];
  522. if (pData.get())
  523. {
  524. hr = GetDataHelper( pszKey, pszValue, kDataTypeString, pData.get(), nSize, NULL );
  525. if (SUCCEEDED( hr ))
  526. {
  527. hr = strString.bUpdate( pData.get() ) ? S_OK : E_FAIL;
  528. }
  529. }
  530. else
  531. {
  532. hr = E_OUTOFMEMORY;
  533. }
  534. }
  535. return hr;
  536. }
  537. HRESULT
  538. TPrinterDataAccess::
  539. GetDataMuliSzStringHelper(
  540. IN LPCTSTR pszKey,
  541. IN LPCTSTR pszValue,
  542. IN OUT TString **ppstrString,
  543. IN UINT &nItemCount
  544. )
  545. {
  546. SPLASSERT( pszValue );
  547. SPLASSERT( ppstrString );
  548. //
  549. // Get the size of the multi-sz string.
  550. //
  551. DWORD nSize = 0;
  552. if( ppstrString )
  553. {
  554. *ppstrString = NULL;
  555. }
  556. HRESULT hr = GetDataSizeHelper( pszKey, pszValue, REG_MULTI_SZ, &nSize );
  557. if(SUCCEEDED(hr))
  558. {
  559. //
  560. // Allocate the multi-sz string buffer.
  561. //
  562. auto_ptr<TCHAR> pszMultiSzString = new TCHAR [nSize+1];
  563. if (pszMultiSzString.get())
  564. {
  565. //
  566. // Get the actual data now.
  567. //
  568. hr = GetDataHelper( pszKey, pszValue, kDataTypeStruct, pszMultiSzString.get(), nSize*sizeof(TCHAR), NULL );
  569. if( SUCCEEDED(hr) )
  570. {
  571. //
  572. // Count the number of strings.
  573. //
  574. nItemCount = 0;
  575. for( LPCTSTR psz = pszMultiSzString.get(); psz && *psz; psz += _tcslen( psz ) + 1 )
  576. {
  577. nItemCount++;
  578. }
  579. //
  580. // Not much to do if there are no strings.
  581. //
  582. if( nItemCount )
  583. {
  584. //
  585. // Allocate an array of string objects.
  586. //
  587. *ppstrString = new TString[nItemCount];
  588. if( *ppstrString )
  589. {
  590. //
  591. // Copy the multi-sz string into the array strings.
  592. //
  593. UINT i = 0;
  594. for( psz = pszMultiSzString.get(); psz && *psz; psz += _tcslen( psz ) + 1, i++ )
  595. {
  596. if( !(*ppstrString)[i].bUpdate( psz ) )
  597. {
  598. break;
  599. }
  600. }
  601. //
  602. // Set the return value.
  603. //
  604. hr = ( i != nItemCount ) ? E_FAIL : S_OK;
  605. }
  606. else
  607. {
  608. hr = E_OUTOFMEMORY;
  609. }
  610. }
  611. }
  612. }
  613. else
  614. {
  615. hr = E_OUTOFMEMORY;
  616. }
  617. }
  618. //
  619. // Something failed then abandon the whole
  620. // operation and relase the string and nuke the count.
  621. //
  622. if(FAILED(hr))
  623. {
  624. delete [] *ppstrString;
  625. *ppstrString = NULL;
  626. nItemCount = 0;
  627. }
  628. return hr;
  629. }