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.

669 lines
15 KiB

  1. /*++
  2. Copyright (C) Microsoft Corporation, 1998 - 1999
  3. All rights reserved.
  4. Module Name:
  5. PrnPrst.cxx
  6. Abstract:
  7. TPrinterPersist member definitions.
  8. This class implements methods for storing , restoring printer settings into a file
  9. Also , implements read, write , seek methods to operate a file likewise a stream
  10. Author:
  11. Adina Trufinescu (AdinaTru) 4-Nov-1998
  12. Revision History:
  13. --*/
  14. #include "precomp.h"
  15. #pragma hdrstop
  16. #include "prnprst.hxx"
  17. /*++
  18. Title:
  19. TPrinterPersist
  20. Routine Description:
  21. Initialise m_pPrnStream to NULL.
  22. TPrinterPersist functionality is implemented through this object methods call.
  23. m_pPrnStream is created when BindPrinterAndFile is called. If this function fails,
  24. any subsequent method call will fail too.
  25. Arguments:
  26. None
  27. Return Value:
  28. Nothing
  29. --*/
  30. TPrinterPersist::
  31. TPrinterPersist()
  32. {
  33. m_pPrnStream = NULL;
  34. }
  35. /*++
  36. Title:
  37. ~TPrinterPersist
  38. Routine Description:
  39. destructor: if created , deletes PrnStream object
  40. Arguments:
  41. None
  42. Return Value:
  43. Nothing
  44. --*/
  45. TPrinterPersist::
  46. ~TPrinterPersist()
  47. {
  48. if(m_pPrnStream)
  49. {
  50. delete m_pPrnStream;
  51. }
  52. }
  53. /*++
  54. Title:
  55. BindPrinterAndFile
  56. Routine Description:
  57. Create a TPrnStream object and if succeeded , bind it to a printer and a file
  58. Arguments:
  59. pszPrinter - printer to bind to
  60. pszFile - file to bind to
  61. Return Value:
  62. BindPrinterAndFile could return E_OUTOFMEMORY if failed to allocate memory,
  63. an error code mapped to HRESULT with storage facility set if failed to open printer in TPrnStream::BindPrnStream
  64. or S_OK if suceeded
  65. --*/
  66. HRESULT
  67. TPrinterPersist::
  68. BindPrinterAndFile(
  69. IN LPCTSTR pszPrinter,
  70. IN LPCTSTR pszFile
  71. )
  72. {
  73. TStatusB bStatus;
  74. TStatusH hr;
  75. //
  76. // Create a TPrnStream obj ant initialise it with printer name and file name
  77. //
  78. m_pPrnStream = new TPrnStream(pszPrinter, pszFile);
  79. bStatus DBGCHK = (m_pPrnStream != NULL);
  80. if(bStatus)
  81. {
  82. DBGMSG(DBG_TRACE , ("BindPrinterAndFile to : " TSTR " \n" , pszPrinter));
  83. //
  84. // calls TPrnStream bind method; it will open the printer with maximum access rights
  85. // and will create a TStream object that will open the file
  86. //
  87. hr DBGCHK = m_pPrnStream->BindPrnStream();
  88. //
  89. // if failed to bind TPrnStream to printer and file , delete it!!!
  90. //
  91. if(FAILED(hr))
  92. {
  93. delete m_pPrnStream;
  94. m_pPrnStream = NULL;
  95. }
  96. }
  97. else
  98. {
  99. hr DBGCHK = E_OUTOFMEMORY;
  100. }
  101. return hr;
  102. }
  103. /*++
  104. Title:
  105. UnBindPrinterAndFile
  106. Routine Description:
  107. Call UnBindPrnStream method of m_pPrnStream.After this function is called , any subsequent method call will fail.
  108. Arguments:
  109. None
  110. Return Value:
  111. S_OK if succeeded
  112. PRN_PERSIST_ERROR error code mapped to HRESULT(FACILITY_ITF) if failed
  113. --*/
  114. HRESULT
  115. TPrinterPersist::
  116. UnBindPrinterAndFile(
  117. )
  118. {
  119. TStatusH hr;
  120. DBGMSG(DBG_TRACE , ("UnBindPrinterAndFile!!! \n"));
  121. hr DBGNOCHK = E_FAIL;
  122. //
  123. // if BindPrinterAndFile wasn't called or failed , this funct will fail also
  124. //
  125. if(m_pPrnStream != NULL)
  126. {
  127. hr DBGCHK = m_pPrnStream->UnBindPrnStream();
  128. }
  129. return hr;
  130. }
  131. /*++
  132. Title:
  133. bGetPrinterAndFile
  134. Routine Description:
  135. Query m_pPrnStream for printer and file it is binded
  136. Arguments:
  137. pszPrinter - outs printer name
  138. pszFile - outs file name
  139. Return Value:
  140. TRUE if m_pPrnStream is initialized
  141. FALSE otherwise
  142. --*/
  143. BOOL
  144. TPrinterPersist::
  145. bGetPrinterAndFile(
  146. OUT LPCTSTR& pszPrinter,
  147. OUT LPCTSTR& pszFile
  148. )
  149. {
  150. TStatusB bStatus;
  151. if(m_pPrnStream != NULL)
  152. {
  153. pszPrinter = m_pPrnStream->GetPrinterName();
  154. pszFile = m_pPrnStream->GetFileName();
  155. bStatus DBGNOCHK = TRUE;
  156. }
  157. else
  158. {
  159. bStatus DBGCHK = FALSE;
  160. }
  161. return bStatus;
  162. }
  163. /*++
  164. Title:
  165. Read
  166. Routine Description:
  167. Indirects call to PrnStream which , in turns , idirects it to TStream
  168. Eventually , this function will be called through IStream interface
  169. Arguments the same as IStream::Read
  170. Arguments:
  171. pv - The buffer that the bytes are read into
  172. cb - The offset in the stream to begin reading from.
  173. pcbRead - The number of bytes to read
  174. Return Value:
  175. S_OK if succeeded
  176. ReadFile Win32 error mapped to HRESULT(FACILITY_STORAGE) if failed
  177. --*/
  178. HRESULT
  179. TPrinterPersist::
  180. Read(
  181. IN VOID * pv,
  182. IN ULONG cb,
  183. IN ULONG * pcbRead
  184. )
  185. {
  186. if(m_pPrnStream)
  187. {
  188. return m_pPrnStream->GetIStream()->Read(pv, cb, pcbRead);
  189. }
  190. else
  191. {
  192. return STG_E_NOMOREFILES;
  193. }
  194. }
  195. /*++
  196. Title:
  197. Write
  198. Routine Description:
  199. Indirects call to PrnStream which , in turns , idirects it to TStream
  200. Eventually , this function will be called through IStream interface
  201. Arguments the same as IStream::Write
  202. Arguments:
  203. pv - The buffer to write from.
  204. cb - The offset in the array to begin writing from
  205. pcbRead - The number of bytes to write
  206. Return Value:
  207. S_OK if succeeded
  208. WriteFile Win32 error mapped to HRESULT(FACILITY_STORAGE) if failed
  209. --*/
  210. HRESULT
  211. TPrinterPersist::
  212. Write(
  213. IN VOID const* pv,
  214. IN ULONG cb,
  215. IN ULONG* pcbWritten
  216. )
  217. {
  218. if(m_pPrnStream)
  219. {
  220. return m_pPrnStream->GetIStream()->Write(pv, cb, pcbWritten);
  221. }
  222. else
  223. {
  224. return STG_E_NOMOREFILES;
  225. }
  226. }
  227. /*++
  228. Title:
  229. Seek
  230. Routine Description:
  231. Indirects call to PrnStream which , in turns , idirects it to TStream
  232. Arguments the same as IStream::Seek
  233. Eventually , this function will be called through IStream interface
  234. Arguments:
  235. dlibMove - The offset relative to dwOrigin
  236. dwOrigin - The origin of the offset
  237. plibNewPosition - Pointer to value of the new seek pointer from the beginning of the stream
  238. Return Value:
  239. S_OK if succeeded
  240. SetFilePointer Win32 error mapped to HRESULT(FACILITY_STORAGE) if failed
  241. --*/
  242. HRESULT
  243. TPrinterPersist::
  244. Seek(
  245. IN LARGE_INTEGER dlibMove,
  246. IN DWORD dwOrigin,
  247. IN ULARGE_INTEGER * plibNewPosition
  248. )
  249. {
  250. if(m_pPrnStream)
  251. {
  252. return m_pPrnStream->GetIStream()->Seek(dlibMove, dwOrigin, plibNewPosition);
  253. }
  254. else
  255. {
  256. return STG_E_NOMOREFILES;
  257. }
  258. }
  259. /*++
  260. Title:
  261. bStorePrinterInfo
  262. Routine Description:
  263. Writes the printer settings into file.
  264. Depending on specified flags, call TPrnStream methods to store printer data
  265. This function must be called after calling BindPrinterAndFile which bind the object to
  266. a printer and to a file.For that fnct to succeed, current user must have PRINTER_READ rights
  267. on specified printer.
  268. Arguments:
  269. Flags - specifies what settings should be stored
  270. StoredFlags - specifies what settings were actually stored
  271. Return Value:
  272. S_OK if succeeded
  273. PRN_PERSIST_ERROR error code mapped to HRESULT(FACILITY_ITF) if failed
  274. --*/
  275. HRESULT
  276. TPrinterPersist::
  277. StorePrinterInfo(
  278. IN DWORD Flags,
  279. OUT DWORD& StoredFlags
  280. )
  281. {
  282. TStatusH hr;
  283. DBGMSG(DBG_TRACE , ("Store Printer Flag %x \n" , Flags));
  284. hr DBGNOCHK = E_FAIL;
  285. //
  286. // if BindPrinterAndFile wasn't called or failed , this funct will fail also
  287. //
  288. if(m_pPrnStream != NULL)
  289. {
  290. hr DBGCHK = m_pPrnStream->StorePrinterInfo(Flags, StoredFlags);
  291. }
  292. DBGMSG( DBG_TRACE, ( "Store Completed :: %x \n" ,hr));
  293. return hr;
  294. }
  295. /*++
  296. Title:
  297. RestorePrinterInfo
  298. Routine Description:
  299. Depending on specified flags, call TPrnStream methods to restore printer data
  300. This function must be called after calling BindPrinterAndFile which bind the object to
  301. a printer and to a file.For that fnct to succeed, current user has to have PRINTER_ALL_ACCESS rights.
  302. If he don't , BindPrinterAndFile will bind to printer with PRINTER_READ which will lead to
  303. SetPrinter failure.
  304. Arguments:
  305. Flags - specifies what settings should be restored
  306. RestoredFlags - specifies what settings were actually restored
  307. Return Value:
  308. S_OK if succeeded
  309. PRN_PERSIST_ERROR error code mapped to HRESULT(FACILITY_ITF) if failed
  310. --*/
  311. HRESULT
  312. TPrinterPersist::
  313. RestorePrinterInfo(
  314. IN DWORD Flags,
  315. OUT DWORD& RestoredFlags
  316. )
  317. {
  318. TStatusH hr;
  319. TStatusB bStatus;
  320. hr DBGNOCHK = E_FAIL;
  321. RestoredFlags = 0;
  322. DBGMSG(DBG_TRACE , ("Restore Printer info %x \n" , Flags));
  323. //
  324. // if BindPrinterAndFile wasn't called or failed , this funct will fail also
  325. //
  326. if(m_pPrnStream != NULL)
  327. {
  328. hr DBGCHK = m_pPrnStream->CheckPrinterNameIntegrity(Flags);
  329. if(SUCCEEDED(hr))
  330. {
  331. DBGMSG( DBG_TRACE, ( "CheckPrinterNameIntegrity OK!!! %x \n" , hr));
  332. hr DBGCHK = m_pPrnStream->RestorePrinterInfo(Flags, RestoredFlags);
  333. }
  334. }
  335. DBGMSG( DBG_TRACE, ( "RESTORE END!!! %x \n" , hr));
  336. return hr;
  337. }
  338. /*++
  339. Title:
  340. SafeRestorePrinterInfo
  341. Routine Description:
  342. Before restoring ant flags, create a new temporary persistent object binded to also to printer which stores current printer settings.
  343. If something fails at the restoring, we are able to roll back all the changes made and we will leave printer in the
  344. initial state.
  345. A temporary file which holds initial printer settings are created by invoking StorePrinterInfo for temporary object.
  346. This file will be deleted by calling UnBindPrinterAndFile for temporary object.
  347. Arguments:
  348. Flags - specifies what settings should be restored
  349. Return Value:
  350. S_OK if succeeded
  351. PRN_PERSIST_ERROR error code mapped to HRESULT(FACILITY_ITF) if failed
  352. --*/
  353. HRESULT
  354. TPrinterPersist::
  355. SafeRestorePrinterInfo(
  356. IN DWORD Flags
  357. )
  358. {
  359. LPTSTR pszPrinterTemp;
  360. LPTSTR pszFile;
  361. TString strFileTempPrefix(_T("Prst"));
  362. TCHAR szTempFileName[MAX_PATH];
  363. TCHAR szTempPath[MAX_PATH];
  364. TStatusH hr;
  365. TStatusH hrBkp;
  366. DWORD StoredFlags;
  367. DWORD RestoredFlags;
  368. //
  369. // initialize hr to Backup error; if something wrong happens when trying to build backup version of file,
  370. // fnct will return Back-up Error
  371. //
  372. hr DBGNOCHK = MakePrnPersistHResult(PRN_PERSIST_ERROR_BACKUP);
  373. hrBkp DBGNOCHK = MakePrnPersistHResult(PRN_PERSIST_ERROR_BACKUP);
  374. //
  375. // Create temporary object for storing current settings
  376. // In case the main restoring fails , current settings can be restored
  377. //
  378. TPrinterPersist* pPrnPersistTemp = new TPrinterPersist;
  379. if(pPrnPersistTemp != NULL)
  380. {
  381. if(bGetPrinterAndFile(pszPrinterTemp, pszFile))
  382. {
  383. TStatus Status;
  384. //
  385. // create a temp file for saving current settings
  386. //
  387. Status DBGNOCHK = GetTempPathW(MAX_PATH, szTempPath);
  388. if (Status > 0 && Status <= MAX_PATH) {
  389. GetTempFileName(szTempPath, strFileTempPrefix, 0, szTempFileName);
  390. }
  391. else {
  392. GetTempFileName(_T("."), strFileTempPrefix, 0, szTempFileName);
  393. }
  394. hrBkp DBGCHK = pPrnPersistTemp->BindPrinterAndFile(pszPrinterTemp, szTempFileName);
  395. if(SUCCEEDED(hrBkp))
  396. {
  397. hrBkp DBGCHK = pPrnPersistTemp->StorePrinterInfo(Flags, StoredFlags);
  398. if(SUCCEEDED(hrBkp))
  399. {
  400. hr DBGCHK = RestorePrinterInfo(Flags, RestoredFlags);
  401. if(FAILED(hr))
  402. {
  403. //
  404. // if main restoring failed , try backup restoring with flags set to:
  405. // flags successfully restored
  406. // &
  407. // flags that were successfully stored in backup file
  408. // fct will still return hr = reason for main restoring failure
  409. //
  410. // PRST_FORCE_NAME must be always set on force for a scenario like this:
  411. // restore settings from file ( printer P1 stored) on top of printer P2 with f flag set
  412. // restoring fails (printer P2 could become P1 at this point) and back-up is needed;
  413. // in back-up file , printer name is P2 . This means we have to force printer name from back-up file,
  414. // in order to become P2 again
  415. // If it's not the case then printer was renamed and the restoring failed,f flag is harmless
  416. //
  417. hrBkp DBGCHK = pPrnPersistTemp->RestorePrinterInfo((StoredFlags & RestoredFlags) | PRST_FORCE_NAME , RestoredFlags);
  418. if(FAILED(hrBkp))
  419. {
  420. // if backup restoring failed also,
  421. // set hr to FATAL Error
  422. //
  423. hr DBGCHK = MakePrnPersistHResult(PRN_PERSIST_ERROR_FATAL);
  424. }
  425. }
  426. }
  427. }
  428. pPrnPersistTemp->UnBindPrinterAndFile();
  429. }
  430. delete pPrnPersistTemp;
  431. }
  432. return hr;
  433. }
  434. /*++
  435. Title:
  436. QueryPrinterInfo
  437. Routine Description:
  438. Read from
  439. Arguments:
  440. Flags - specifies what settings should be restored
  441. pPrstInfo - pointer to union that holds a pointer to read item
  442. Return Value:
  443. S_OK if succeeded;
  444. ERROR_INVALID_PARAMETER maped to HRESULT if more than one flag specified;
  445. PRN_PERSIST_ERROR error code mapped to HRESULT(FACILITY_ITF) if failed;
  446. --*/
  447. HRESULT
  448. TPrinterPersist::
  449. QueryPrinterInfo(
  450. IN PrinterPersistentQueryFlag Flag,
  451. OUT PersistentInfo *pPrstInfo
  452. )
  453. {
  454. TStatusH hr;
  455. TStatusB bStatus;
  456. hr DBGNOCHK = E_FAIL;
  457. DBGMSG(DBG_TRACE , ("Restore Printer info %x \n" , Flag));
  458. //
  459. // if BindPrinterAndFile wasn't called or failed , this funct will fail also
  460. //
  461. if(m_pPrnStream != NULL)
  462. {
  463. hr DBGCHK = m_pPrnStream->QueryPrinterInfo(Flag, pPrstInfo);
  464. }
  465. DBGMSG( DBG_TRACE, ( "QueryPrinterInfo END!!! %x \n" , hr));
  466. return hr;
  467. }