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.

1027 lines
26 KiB

  1. /*++
  2. Copyright (C) Microsoft Corporation
  3. Module Name:
  4. printer.cpp
  5. Abstract:
  6. This module implements CPrinter -- class that support printing
  7. Author:
  8. William Hsieh (williamh) created
  9. Revision History:
  10. --*/
  11. #include "devmgr.h"
  12. #include "printer.h"
  13. #include "cdriver.h"
  14. #include "sysinfo.h"
  15. const TCHAR* const g_BlankLine = TEXT("");
  16. //
  17. // CPrinter Class implementation
  18. //
  19. BOOL CPrinter::s_UserAborted = FALSE;
  20. HWND CPrinter::s_hCancelDlg = NULL;
  21. void
  22. CPrintCancelDialog::OnCommand(
  23. WPARAM wParam,
  24. LPARAM lParam
  25. )
  26. {
  27. UNREFERENCED_PARAMETER(lParam);
  28. if (BN_CLICKED == HIWORD(wParam) && IDCANCEL == LOWORD(wParam)) {
  29. CPrinter::s_UserAborted = TRUE;
  30. }
  31. }
  32. CPrinter::CPrinter(
  33. HWND hwndOwner,
  34. HDC hDC
  35. )
  36. {
  37. m_hwndOwner = hwndOwner;
  38. s_UserAborted = FALSE;
  39. m_hDC = hDC;
  40. ASSERT(hDC);
  41. m_CurLine = 0;
  42. m_CurPage = 0;
  43. m_Indent = 0;
  44. m_Status = 1;
  45. TEXTMETRIC tm;
  46. GetTextMetrics(m_hDC, &tm);
  47. m_yChar = tm.tmHeight + tm.tmExternalLeading;
  48. m_xChar = tm.tmAveCharWidth;
  49. //
  50. // Give a little room for dot matrix printers.
  51. //
  52. m_xMargin = GetDeviceCaps(m_hDC, LOGPIXELSX) * 3 / 4;
  53. DWORD LinesPerPage;
  54. LinesPerPage = GetDeviceCaps(m_hDC, VERTRES) / m_yChar;
  55. m_yBottomMargin = LinesPerPage - 3; // Bottom Margin 3 lines from bottom of page.
  56. m_CancelDlg.DoModaless(hwndOwner, (LPARAM)&m_CancelDlg);
  57. s_hCancelDlg = m_CancelDlg.m_hDlg;
  58. //
  59. // Set the abort proc to allow cancel
  60. //
  61. SetAbortProc(m_hDC, AbortPrintProc);
  62. //
  63. // Four lines for top margin
  64. //
  65. m_yTopMargin = 4;
  66. }
  67. int
  68. CPrinter::StartDoc(
  69. LPCTSTR DocTitle
  70. )
  71. {
  72. m_Status = 0;
  73. if (m_hDC) {
  74. if (m_hwndOwner) {
  75. ::EnableWindow(m_hwndOwner, FALSE);
  76. }
  77. //
  78. // Initialize DOCINFO
  79. //
  80. DOCINFO DocInfo;
  81. DocInfo.cbSize = sizeof(DocInfo);
  82. DocInfo.lpszDocName = DocTitle;
  83. DocInfo.lpszOutput = NULL;
  84. DocInfo.lpszDatatype = NULL;
  85. DocInfo.fwType = 0;
  86. m_CurPage = 1;
  87. m_CurLine = 0;
  88. m_Status = ::StartDoc(m_hDC, &DocInfo);
  89. }
  90. return m_Status;
  91. }
  92. int
  93. CPrinter::EndDoc()
  94. {
  95. m_Status = 0;
  96. if (m_hDC) {
  97. if (m_hwndOwner) {
  98. ::EnableWindow(m_hwndOwner, TRUE);
  99. }
  100. if (s_hCancelDlg) {
  101. DestroyWindow(s_hCancelDlg);
  102. s_hCancelDlg = NULL;
  103. }
  104. if (!s_UserAborted) {
  105. m_Status = ::EndDoc(m_hDC);
  106. }
  107. }
  108. return m_Status;
  109. }
  110. int
  111. CPrinter::AbortDoc()
  112. {
  113. m_Status = 0;
  114. if (m_hDC) {
  115. if (m_hwndOwner) {
  116. ::EnableWindow(m_hwndOwner, TRUE);
  117. }
  118. if (s_hCancelDlg) {
  119. DestroyWindow(s_hCancelDlg);
  120. s_hCancelDlg = NULL;
  121. }
  122. m_Status = ::AbortDoc(m_hDC);
  123. }
  124. return m_Status;
  125. }
  126. int
  127. CPrinter::FlushPage()
  128. {
  129. return PrintLine(NULL);
  130. }
  131. int
  132. CPrinter::PrintLine(
  133. LPCTSTR LineText
  134. )
  135. {
  136. //
  137. // NULL LineText means flush the page
  138. //
  139. if ((!LineText && m_CurLine) || (m_CurLine > m_yBottomMargin)) {
  140. m_CurLine = 0;
  141. if (m_Status) {
  142. m_Status = ::EndPage(m_hDC);
  143. }
  144. }
  145. if (LineText) {
  146. //
  147. // If this is the first line and we are still in good shape,
  148. // start a new page
  149. //
  150. if (!m_CurLine && m_Status) {
  151. m_Status = ::StartPage(m_hDC);
  152. if (m_Status) {
  153. String strPageTitle;
  154. strPageTitle.Format((LPCTSTR)m_strPageTitle, m_CurPage);
  155. m_CurLine = m_yTopMargin;
  156. TextOut(m_hDC, m_xMargin, m_yChar*m_CurLine, (LPTSTR)strPageTitle, strPageTitle.GetLength());
  157. //
  158. // Have one blank line right after page title
  159. //
  160. LineFeed();
  161. m_CurLine++;
  162. m_CurPage++;
  163. }
  164. }
  165. if (m_Status) {
  166. TextOut(m_hDC, m_xMargin + m_xChar*m_Indent*2, m_yChar*m_CurLine, LineText, lstrlen(LineText));
  167. }
  168. m_CurLine++;
  169. }
  170. return m_Status;
  171. }
  172. inline
  173. void
  174. CPrinter::LineFeed()
  175. {
  176. PrintLine(g_BlankLine);
  177. }
  178. // the abort procedure
  179. BOOL CALLBACK
  180. AbortPrintProc(
  181. HDC hDC,
  182. int nCode
  183. )
  184. {
  185. MSG msg;
  186. UNREFERENCED_PARAMETER(hDC);
  187. UNREFERENCED_PARAMETER(nCode);
  188. while (!CPrinter::s_UserAborted && PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) {
  189. if (!IsDialogMessage(CPrinter::s_hCancelDlg, &msg)) {
  190. TranslateMessage(&msg);
  191. DispatchMessage(&msg);
  192. }
  193. }
  194. return !CPrinter::s_UserAborted;
  195. }
  196. //
  197. // This function prints system summary.
  198. // INPUT:
  199. // Machine -- the machine
  200. // OUTPUT:
  201. // 0 -- failed else succeeded.
  202. //
  203. //
  204. int
  205. CPrinter::PrintSystemSummary(
  206. void
  207. )
  208. {
  209. CSystemInfo SysInfo;
  210. String strLine;
  211. String strFormat;
  212. String strBuffer;
  213. String strUnknown;
  214. TCHAR Buffer[MAX_PATH];
  215. TCHAR szTemp[30];
  216. DWORD Size, BufferSize;
  217. BufferSize = ARRAYLEN(Buffer);
  218. //
  219. // Preload the "Unknown" string which will be used as default when
  220. // the corresponding value can not found
  221. //
  222. strUnknown.LoadString(g_hInstance, IDS_PRINT_UNKNOWN);
  223. //
  224. // Print System summary heading
  225. //
  226. LoadString(g_hInstance, IDS_PRINT_HEADING_SYSSUMMARY, Buffer, ARRAYLEN(Buffer));
  227. strFormat.LoadString(g_hInstance, IDS_PRINT_BANNER);
  228. strLine.Format((LPCTSTR)strFormat, Buffer);
  229. PrintLine((LPCTSTR)strLine);
  230. LineFeed();
  231. //
  232. // Windows version
  233. //
  234. strLine.LoadString(g_hInstance, IDS_PRINT_WINVER);
  235. Size = SysInfo.WindowsVersion(Buffer, BufferSize);
  236. strLine += Size ? (LPCTSTR)Buffer : strUnknown;
  237. PrintLine((LPCTSTR)strLine);
  238. //
  239. // Registered Owner
  240. //
  241. strLine.LoadString(g_hInstance, IDS_PRINT_OWNER);
  242. Size = SysInfo.RegisteredOwner(Buffer, BufferSize);
  243. strLine += Size ? (LPCTSTR)Buffer : strUnknown;
  244. PrintLine((LPCTSTR)strLine);
  245. //
  246. // Registered Organization
  247. //
  248. strLine.LoadString(g_hInstance, IDS_PRINT_ORGANIZATION);
  249. Size = SysInfo.RegisteredOrganization(Buffer, BufferSize);
  250. strLine += Size ? (LPCTSTR)Buffer : strUnknown;
  251. PrintLine((LPCTSTR)strLine);
  252. //
  253. // Computer name
  254. //
  255. strLine.LoadString(g_hInstance, IDS_PRINT_COMPUTERNAME);
  256. strLine += (LPCTSTR)SysInfo.ComputerName();
  257. PrintLine((LPCTSTR)strLine);
  258. //
  259. // Machine Type
  260. //
  261. strLine.LoadString(g_hInstance, IDS_PRINT_MACHINE_TYPE);
  262. Size = SysInfo.MachineType(Buffer, BufferSize);
  263. strLine += Size ? (LPCTSTR)Buffer : strUnknown;
  264. PrintLine((LPCTSTR)strLine);
  265. //
  266. // System BIOS Version
  267. //
  268. strLine.LoadString(g_hInstance, IDS_PRINT_SYSBIOS_VERSION);
  269. Size = SysInfo.SystemBiosVersion(Buffer, BufferSize);
  270. strLine += Size ? (LPCTSTR)Buffer : strUnknown;
  271. PrintLine((LPCTSTR)strLine);
  272. //
  273. // System BIOS Date
  274. //
  275. strLine.LoadString(g_hInstance, IDS_PRINT_SYSBIOS_DATE);
  276. Size = SysInfo.SystemBiosDate(Buffer, BufferSize);
  277. strLine += Size ? (LPCTSTR)Buffer : strUnknown;
  278. PrintLine((LPCTSTR)strLine);
  279. //
  280. // Processor type
  281. //
  282. strLine.LoadString(g_hInstance, IDS_PRINT_PROCESSOR_TYPE);
  283. Size = SysInfo.ProcessorType(Buffer, BufferSize);
  284. strLine += Size ? (LPCTSTR)Buffer : strUnknown;
  285. PrintLine((LPCTSTR)strLine);
  286. //
  287. // Processor vendor
  288. //
  289. strLine.LoadString(g_hInstance, IDS_PRINT_PROCESSOR_VENDOR);
  290. Size = SysInfo.ProcessorVendor(Buffer, BufferSize);
  291. strLine += Size ? (LPCTSTR)Buffer : strUnknown;
  292. PrintLine((LPCTSTR)strLine);
  293. //
  294. // Number of processors
  295. //
  296. strLine.LoadString(g_hInstance, IDS_PRINT_PROCESSORS);
  297. DWORD NumProcessors = SysInfo.NumberOfProcessors();
  298. if (NumProcessors) {
  299. strFormat.Format(TEXT("%u"), NumProcessors);
  300. strLine += strFormat;
  301. } else {
  302. strLine += strUnknown;
  303. }
  304. PrintLine((LPCTSTR)strLine);
  305. //
  306. // Total physical memory
  307. //
  308. ULARGE_INTEGER MemorySize;
  309. SysInfo.TotalPhysicalMemory(MemorySize);
  310. strLine.LoadString(g_hInstance, IDS_PRINT_PHY_MEMORY);
  311. if (MemorySize.QuadPart) {
  312. strFormat.LoadString(g_hInstance, IDS_PRINT_MEMORY_UNIT);
  313. MemorySize.QuadPart += 1024*1024 - 1;
  314. strBuffer.Format((LPCTSTR)strFormat, Int64ShrlMod32(MemorySize.QuadPart, 20));
  315. strLine += strBuffer;
  316. } else {
  317. strLine += strUnknown;
  318. }
  319. PrintLine((LPCTSTR)strLine);
  320. LineFeed();
  321. //
  322. // Local disk drive information
  323. //
  324. // Print Disk info summary heading
  325. //
  326. strBuffer.LoadString(g_hInstance, IDS_PRINT_HEADING_DISKINFO);
  327. strFormat.LoadString(g_hInstance, IDS_PRINT_BANNER);
  328. strLine.Format((LPCTSTR)strFormat, (LPCTSTR)strBuffer);
  329. PrintLine((LPCTSTR)strLine);
  330. LineFeed();
  331. DISK_INFO DiskInfo;
  332. DiskInfo.cbSize = sizeof(DiskInfo);
  333. for(int Drive = 0; Drive < 25; Drive++) {
  334. // information we want to report on the drive:
  335. // (1). drive letter and type
  336. // (2). Total space
  337. // (3). Free space(if available)
  338. // (4). Cylinders
  339. // (5). Heads
  340. // (6). Sectors per track
  341. // (7). Bytes per sector
  342. Indent();
  343. if(SysInfo.GetDiskInfo(Drive, DiskInfo)) {
  344. TCHAR DriveLetter;
  345. DriveLetter = (TCHAR)(Drive + _T('A'));
  346. strFormat.LoadString(g_hInstance, IDS_PRINT_DRIVE_LETTER);
  347. strLine.Format((LPCTSTR)strFormat, DriveLetter);
  348. PrintLine((LPCTSTR)strLine);
  349. Indent();
  350. //
  351. // Drive type
  352. //
  353. strFormat.LoadString(g_hInstance, IDS_PRINT_DRIVE_TYPE);
  354. strBuffer.LoadString(g_hInstance, IDS_MEDIA_BASE + (int)DiskInfo.MediaType);
  355. strLine.Format((LPCTSTR)strFormat, (LPCTSTR)strBuffer);
  356. PrintLine((LPCTSTR)strLine);
  357. //
  358. //Total and free space
  359. //
  360. strFormat.LoadString(g_hInstance, IDS_PRINT_TOTAL_SPACE);
  361. strLine.Format((LPCTSTR)strFormat, AddCommas64(DiskInfo.TotalSpace.QuadPart, szTemp, ARRAYLEN(szTemp)));
  362. PrintLine((LPCTSTR)strLine);
  363. if (-1 != DiskInfo.FreeSpace.QuadPart) {
  364. strFormat.LoadString(g_hInstance, IDS_PRINT_FREE_SPACE);
  365. strLine.Format((LPCTSTR)strFormat, AddCommas64(DiskInfo.FreeSpace.QuadPart, szTemp, ARRAYLEN(szTemp)));
  366. PrintLine((LPCTSTR)strLine);
  367. }
  368. //
  369. // Disk physical dimension
  370. // skip CD-ROM because the dimension it reports is bogus
  371. //
  372. if (DRIVE_CDROM != DiskInfo.DriveType) {
  373. //
  374. // Heads
  375. //
  376. strFormat.LoadString(g_hInstance, IDS_PRINT_HEADS);
  377. strLine.Format((LPCTSTR)strFormat, DiskInfo.Heads);
  378. PrintLine((LPCTSTR)strLine);
  379. //
  380. // Cylinders
  381. //
  382. if (DiskInfo.Cylinders.HighPart) {
  383. strFormat.LoadString(g_hInstance, IDS_PRINT_CYLINDERS_XL);
  384. strLine.Format((LPCTSTR)strFormat, DiskInfo.Cylinders.HighPart,
  385. DiskInfo.Cylinders.LowPart);
  386. PrintLine((LPCTSTR)strLine);
  387. } else {
  388. strFormat.LoadString(g_hInstance, IDS_PRINT_CYLINDERS);
  389. strLine.Format((LPCTSTR)strFormat, DiskInfo.Cylinders.LowPart);
  390. PrintLine((LPCTSTR)strLine);
  391. }
  392. //
  393. // Sectors per track
  394. //
  395. strFormat.LoadString(g_hInstance, IDS_PRINT_TRACKSIZE);
  396. strLine.Format((LPCTSTR)strFormat, DiskInfo.SectorsPerTrack);
  397. PrintLine((LPCTSTR)strLine);
  398. //
  399. // Bytes per sector
  400. //
  401. strFormat.LoadString(g_hInstance, IDS_PRINT_SECTORSIZE);
  402. strLine.Format((LPCTSTR)strFormat, DiskInfo.BytesPerSector);
  403. PrintLine((LPCTSTR)strLine);
  404. }
  405. UnIndent();
  406. LineFeed();
  407. }
  408. UnIndent();
  409. }
  410. return 1;
  411. }
  412. int
  413. CPrinter::PrintResourceSummary(
  414. CMachine& Machine
  415. )
  416. {
  417. String strLine;
  418. String str;
  419. String strBanner;
  420. if (Machine.IsLocal()) {
  421. PrintSystemSummary();
  422. }
  423. //
  424. // print IRQ summary heading
  425. //
  426. str.LoadString(g_hInstance, IDS_PRINT_HEADING_IRQSUMMARY);
  427. strBanner.LoadString(g_hInstance, IDS_PRINT_BANNER);
  428. strLine.Format((LPCTSTR)strBanner, (LPCTSTR)str);
  429. PrintLine((LPCTSTR)strLine);
  430. LineFeed();
  431. CResourceList IrqSummary(&Machine, ResType_IRQ);
  432. if (IrqSummary.GetCount()) {
  433. CResource* pResRoot;
  434. IrqSummary.CreateResourceTree(&pResRoot);
  435. str.LoadString(g_hInstance, IDS_PRINT_IRQSUM);
  436. PrintLine(str);
  437. Indent();
  438. PrintResourceSubtree(pResRoot);
  439. UnIndent();
  440. LineFeed();
  441. }
  442. //
  443. // print DMA summary heading
  444. //
  445. str.LoadString(g_hInstance, IDS_PRINT_HEADING_DMASUMMARY);
  446. strLine.Format((LPCTSTR)strBanner, (LPCTSTR)str);
  447. PrintLine((LPCTSTR)strLine);
  448. LineFeed();
  449. CResourceList DmaSummary(&Machine, ResType_DMA);
  450. if (DmaSummary.GetCount()) {
  451. CResource* pResRoot;
  452. DmaSummary.CreateResourceTree(&pResRoot);
  453. str.LoadString(g_hInstance, IDS_PRINT_DMASUM);
  454. PrintLine(str);
  455. Indent();
  456. PrintResourceSubtree(pResRoot);
  457. UnIndent();
  458. LineFeed();
  459. }
  460. //
  461. // print MEM summary heading
  462. //
  463. str.LoadString(g_hInstance, IDS_PRINT_HEADING_MEMSUMMARY);
  464. strLine.Format((LPCTSTR)strBanner, (LPCTSTR)str);
  465. PrintLine((LPCTSTR)strLine);
  466. LineFeed();
  467. CResourceList MemSummary(&Machine, ResType_Mem);
  468. if (MemSummary.GetCount()) {
  469. CResource* pResRoot;
  470. MemSummary.CreateResourceTree(&pResRoot);
  471. str.LoadString(g_hInstance, IDS_PRINT_MEMSUM);
  472. PrintLine(str);
  473. Indent();
  474. PrintResourceSubtree(pResRoot);
  475. UnIndent();
  476. LineFeed();
  477. }
  478. //
  479. // print IO summary heading
  480. //
  481. str.LoadString(g_hInstance, IDS_PRINT_HEADING_IOSUMMARY);
  482. strLine.Format((LPCTSTR)strBanner, (LPCTSTR)str);
  483. PrintLine((LPCTSTR)strLine);
  484. LineFeed();
  485. CResourceList IoSummary(&Machine, ResType_IO);
  486. if (IoSummary.GetCount()) {
  487. CResource* pResRoot;
  488. IoSummary.CreateResourceTree(&pResRoot);
  489. str.LoadString(g_hInstance, IDS_PRINT_IOSUM);
  490. PrintLine(str);
  491. Indent();
  492. PrintResourceSubtree(pResRoot);
  493. UnIndent();
  494. LineFeed();
  495. }
  496. return 1;
  497. }
  498. int
  499. CPrinter::PrintResourceSubtree(
  500. CResource* pResRoot
  501. )
  502. {
  503. while (pResRoot)
  504. {
  505. DWORD Status, Problem;
  506. if (pResRoot->m_pDevice->GetStatus(&Status, &Problem) && Problem ||
  507. pResRoot->m_pDevice->IsDisabled()) {
  508. TCHAR Temp[MAX_PATH];
  509. Temp[0] = _T('*');
  510. StringCchCopy(&Temp[1], (ARRAYLEN(Temp) - 1), pResRoot->GetViewName());
  511. PrintLine(Temp);
  512. } else {
  513. PrintLine(pResRoot->GetViewName());
  514. }
  515. if (pResRoot->GetChild()) {
  516. if ((ResType_IO == pResRoot->ResType()) ||
  517. (ResType_Mem == pResRoot->ResType())) {
  518. Indent();
  519. }
  520. PrintResourceSubtree(pResRoot->GetChild());
  521. if ((ResType_IO == pResRoot->ResType()) ||
  522. (ResType_Mem == pResRoot->ResType())) {
  523. UnIndent();
  524. }
  525. }
  526. pResRoot = pResRoot->GetSibling();
  527. }
  528. return 1;
  529. }
  530. int
  531. CPrinter::PrintAllClassAndDevice(
  532. CMachine* pMachine
  533. )
  534. {
  535. if (!pMachine) {
  536. return 0;
  537. }
  538. String strHeading;
  539. String strBanner;
  540. String strLine;
  541. strHeading.LoadString(g_hInstance, IDS_PRINT_HEADING_SYSDEVINFO);
  542. strBanner.LoadString(g_hInstance, IDS_PRINT_BANNER);
  543. strLine.Format((LPCTSTR)strBanner, (LPCTSTR)strHeading);
  544. PrintLine((LPCTSTR)strLine);
  545. LineFeed();
  546. CClass* pClass;
  547. PVOID Context;
  548. if (pMachine->GetFirstClass(&pClass, Context)) {
  549. do {
  550. PrintClass(pClass, FALSE);
  551. } while (pMachine->GetNextClass(&pClass, Context));
  552. }
  553. return 1;
  554. }
  555. int
  556. CPrinter::PrintClass(
  557. CClass* pClass,
  558. BOOL PrintBanner
  559. )
  560. {
  561. PVOID Context;
  562. CDevice* pDevice;
  563. if (!pClass) {
  564. return 0;
  565. }
  566. if (PrintBanner) {
  567. String strHeading;
  568. String strBanner;
  569. String strLine;
  570. strHeading.LoadString(g_hInstance, IDS_PRINT_HEADING_SYSDEVCLASS);
  571. strBanner.LoadString(g_hInstance, IDS_PRINT_BANNER);
  572. strLine.Format((LPCTSTR)strBanner, (LPCTSTR)strHeading);
  573. PrintLine((LPCTSTR)strLine);
  574. LineFeed();
  575. }
  576. if (pClass && pClass->GetFirstDevice(&pDevice, Context)) {
  577. do {
  578. //
  579. // Do print banner on the device
  580. //
  581. PrintDevice(pDevice, FALSE);
  582. } while (pClass->GetNextDevice(&pDevice, Context));
  583. }
  584. return 1;
  585. }
  586. int
  587. CPrinter::PrintDevice(
  588. CDevice* pDevice,
  589. BOOL PrintBanner
  590. )
  591. {
  592. if (!pDevice) {
  593. return 0;
  594. }
  595. String str;
  596. String strLine;
  597. if (PrintBanner) {
  598. String strBanner;
  599. str.LoadString(g_hInstance, IDS_PRINT_HEADING_SYSDEVICE);
  600. strBanner.LoadString(g_hInstance, IDS_PRINT_BANNER);
  601. strLine.Format((LPCTSTR)strBanner, (LPCTSTR)str);
  602. PrintLine((LPCTSTR)strLine);
  603. LineFeed();
  604. }
  605. DWORD Status, Problem;
  606. if (pDevice->GetStatus(&Status, &Problem) && Problem ||
  607. pDevice->IsDisabled()) {
  608. strLine.LoadString(g_hInstance, IDS_PRINT_DEVICE_DISABLED);
  609. PrintLine((LPCTSTR)strLine);
  610. }
  611. str.LoadString(g_hInstance, IDS_PRINT_CLASS);
  612. strLine.Format((LPCTSTR)str, pDevice->GetClassDisplayName());
  613. PrintLine((LPCTSTR)strLine);
  614. str.LoadString(g_hInstance, IDS_PRINT_DEVICE);
  615. strLine.Format((LPCTSTR)str, pDevice->GetDisplayName());
  616. PrintLine((LPCTSTR)strLine);
  617. PrintDeviceResource(pDevice);
  618. PrintDeviceDriver(pDevice);
  619. return 1;
  620. }
  621. int
  622. CPrinter::PrintAll(
  623. CMachine& Machine
  624. )
  625. {
  626. PrintResourceSummary(Machine);
  627. PrintAllClassAndDevice(&Machine);
  628. return 1;
  629. }
  630. //
  631. // This function prints the given device's resource summary
  632. //
  633. int
  634. CPrinter::PrintDeviceResource(
  635. CDevice* pDevice
  636. )
  637. {
  638. if (!pDevice) {
  639. return 0;
  640. }
  641. CResourceList IrqSummary(pDevice, ResType_IRQ);
  642. CResourceList DmaSummary(pDevice, ResType_DMA);
  643. CResourceList MemSummary(pDevice, ResType_Mem);
  644. CResourceList IoSummary(pDevice, ResType_IO);
  645. String str;
  646. TCHAR Temp[MAX_PATH];
  647. //
  648. // If the device has any kind of resources, print it
  649. //
  650. if (IrqSummary.GetCount() || DmaSummary.GetCount() ||
  651. MemSummary.GetCount() || IoSummary.GetCount()) {
  652. str.LoadString(g_hInstance, IDS_PRINT_RESOURCE);
  653. PrintLine(str);
  654. //
  655. // Start printing individual resources
  656. //
  657. Indent();
  658. PVOID Context;
  659. CResource* pResource;
  660. DWORDLONG dlBase, dlLen;
  661. if (IrqSummary.GetFirst(&pResource, Context)) {
  662. LoadString(g_hInstance, IDS_PRINT_IRQ_FORMAT, Temp, ARRAYLEN(Temp));
  663. do {
  664. pResource->GetValue(&dlBase, &dlLen);
  665. str.Format(Temp, (ULONG)dlBase);
  666. PrintLine((LPCTSTR)str);
  667. } while (IrqSummary.GetNext(&pResource, Context));
  668. }
  669. if (DmaSummary.GetFirst(&pResource, Context)) {
  670. LoadString(g_hInstance, IDS_PRINT_DMA_FORMAT, Temp, ARRAYLEN(Temp));
  671. do {
  672. pResource->GetValue(&dlBase, &dlLen);
  673. str.Format(Temp, (ULONG)dlBase);
  674. PrintLine((LPCTSTR)str);
  675. } while (DmaSummary.GetNext(&pResource, Context));
  676. }
  677. if (MemSummary.GetFirst(&pResource, Context)) {
  678. LoadString(g_hInstance, IDS_PRINT_MEM_FORMAT, Temp, ARRAYLEN(Temp));
  679. do {
  680. pResource->GetValue(&dlBase, &dlLen);
  681. str.Format(Temp, (ULONG)dlBase, (ULONG)(dlBase + dlLen - 1));
  682. PrintLine((LPCTSTR)str);
  683. } while (MemSummary.GetNext(&pResource, Context));
  684. }
  685. if (IoSummary.GetFirst(&pResource, Context)) {
  686. LoadString(g_hInstance, IDS_PRINT_IO_FORMAT, Temp, ARRAYLEN(Temp));
  687. do {
  688. pResource->GetValue(&dlBase, &dlLen);
  689. str.Format(Temp, (ULONG)dlBase, (ULONG)(dlBase + dlLen -1));
  690. PrintLine((LPCTSTR)str);
  691. } while (IoSummary.GetNext(&pResource, Context));
  692. }
  693. UnIndent();
  694. } else {
  695. str.LoadString(g_hInstance, IDS_PRINT_NORES);
  696. PrintLine(str);
  697. }
  698. return 1;
  699. }
  700. //
  701. // This function prints the given device's driver information
  702. // INPUT:
  703. // pDevice -- the device
  704. // OUTPUT:
  705. // >0 if the function succeeded.
  706. // 0 if the function failed.
  707. //
  708. int
  709. CPrinter::PrintDeviceDriver(
  710. CDevice* pDevice
  711. )
  712. {
  713. if (!pDevice) {
  714. return 0;
  715. }
  716. String str;
  717. TCHAR Temp[MAX_PATH];
  718. CDriver* pDriver;
  719. pDriver = pDevice->CreateDriver();
  720. SafePtr<CDriver> DrvPtr;
  721. if (pDriver) {
  722. DrvPtr.Attach(pDriver);
  723. str.LoadString(g_hInstance, IDS_PRINT_DRVINFO);
  724. PrintLine(str);
  725. PVOID Context;
  726. CDriverFile* pDrvFile;
  727. Indent();
  728. //
  729. // Build up a list of function and filter drivers for this device.
  730. //
  731. pDriver->BuildDriverList();
  732. if (pDriver->GetFirstDriverFile(&pDrvFile, Context)) {
  733. do {
  734. PrintLine(pDrvFile->GetFullPathName());
  735. HANDLE hFile;
  736. Indent();
  737. hFile = CreateFile(pDrvFile->GetFullPathName(),
  738. GENERIC_READ,
  739. 0,
  740. NULL,
  741. OPEN_EXISTING,
  742. FILE_ATTRIBUTE_NORMAL |
  743. FILE_ATTRIBUTE_READONLY |
  744. FILE_ATTRIBUTE_SYSTEM |
  745. FILE_ATTRIBUTE_HIDDEN,
  746. NULL
  747. );
  748. if (INVALID_HANDLE_VALUE != hFile) {
  749. DWORD FileSize;
  750. FileSize = ::GetFileSize(hFile, NULL);
  751. CloseHandle(hFile);
  752. LoadString(g_hInstance, IDS_PRINT_FILESIZE, Temp, ARRAYLEN(Temp));
  753. str.Format(Temp, FileSize);
  754. PrintLine(str);
  755. // print the driver version infomation
  756. TCHAR Unknown[MAX_PATH];
  757. LoadString(g_hInstance, IDS_PRINT_UNKNOWN, Unknown, ARRAYLEN(Unknown));
  758. if (pDrvFile->HasVersionInfo()) {
  759. LoadString(g_hInstance, IDS_PRINT_FILEVERSION, Temp, ARRAYLEN(Temp));
  760. if (pDrvFile->GetVersion()) {
  761. str.Format(Temp, pDrvFile->GetVersion());
  762. } else {
  763. str.Format(Temp, Unknown);
  764. }
  765. PrintLine(str);
  766. LoadString(g_hInstance, IDS_PRINT_FILEMFG, Temp, ARRAYLEN(Temp));
  767. if (pDrvFile->GetProvider()) {
  768. str.Format(Temp, pDrvFile->GetProvider());
  769. } else {
  770. str.Format(Temp, Unknown);
  771. }
  772. PrintLine(str);
  773. LoadString(g_hInstance, IDS_PRINT_FILECOPYRIGHT, Temp, ARRAYLEN(Temp));
  774. if (pDrvFile->GetCopyright()) {
  775. str.Format(Temp, pDrvFile->GetCopyright());
  776. } else {
  777. str.Format(Temp, Unknown);
  778. }
  779. PrintLine(str);
  780. } else {
  781. str.LoadString(g_hInstance, IDS_PRINT_NOVERSION);
  782. PrintLine(str);
  783. }
  784. } else {
  785. str.LoadString(g_hInstance, IDS_PRINT_DRVMISSING);
  786. PrintLine(str);
  787. }
  788. UnIndent();
  789. } while (pDriver->GetNextDriverFile(&pDrvFile, Context));
  790. }
  791. UnIndent();
  792. }
  793. LineFeed();
  794. return 1;
  795. }