1119 lines
27 KiB
C++
1119 lines
27 KiB
C++
|
/*++
|
||
|
|
||
|
Copyright (C) 1997-1999 Microsoft Corporation
|
||
|
|
||
|
Module Name:
|
||
|
|
||
|
printer.cpp
|
||
|
|
||
|
Abstract:
|
||
|
|
||
|
This module implements CPrinter -- class that support printing
|
||
|
|
||
|
Author:
|
||
|
|
||
|
William Hsieh (williamh) created
|
||
|
|
||
|
Revision History:
|
||
|
|
||
|
|
||
|
--*/
|
||
|
|
||
|
#include "devmgr.h"
|
||
|
#include "printer.h"
|
||
|
#include "cdriver.h"
|
||
|
#include "sysinfo.h"
|
||
|
|
||
|
const TCHAR* const g_BlankLine = TEXT("");
|
||
|
const TCHAR* const g_NewLine = TEXT("\r\n");
|
||
|
const CHAR* const g_NewLineA = "\r\n";
|
||
|
//
|
||
|
// CPrinter Class implementation
|
||
|
//
|
||
|
|
||
|
BOOL CPrinter::s_UserAborted = FALSE;
|
||
|
HWND CPrinter::s_hCancelDlg = NULL;
|
||
|
|
||
|
|
||
|
void
|
||
|
CPrintCancelDialog::OnCommand(
|
||
|
WPARAM wParam,
|
||
|
LPARAM lParam
|
||
|
)
|
||
|
{
|
||
|
if (BN_CLICKED == HIWORD(wParam) && IDCANCEL == LOWORD(wParam)) {
|
||
|
|
||
|
CPrinter::s_UserAborted = TRUE;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
CPrinter::CPrinter(
|
||
|
HWND hwndOwner,
|
||
|
HDC hDC
|
||
|
)
|
||
|
{
|
||
|
m_hwndOwner = hwndOwner;
|
||
|
s_UserAborted = FALSE;
|
||
|
m_hDC = hDC;
|
||
|
ASSERT(hDC);
|
||
|
m_CurLine = 0;
|
||
|
m_CurPage = 0;
|
||
|
m_Indent = 0;
|
||
|
m_Status = 1;
|
||
|
TEXTMETRIC tm;
|
||
|
GetTextMetrics(m_hDC, &tm);
|
||
|
m_yChar = tm.tmHeight + tm.tmExternalLeading;
|
||
|
m_xChar = tm.tmAveCharWidth;
|
||
|
|
||
|
//
|
||
|
// Give a little room for dot matrix printers.
|
||
|
//
|
||
|
m_xMargin = GetDeviceCaps(m_hDC, LOGPIXELSX) * 3 / 4;
|
||
|
DWORD LinesPerPage;
|
||
|
|
||
|
LinesPerPage = GetDeviceCaps(m_hDC, VERTRES) / m_yChar;
|
||
|
m_yBottomMargin = LinesPerPage - 3; // Bottom Margin 3 lines from bottom of page.
|
||
|
m_CancelDlg.DoModaless(hwndOwner, (LPARAM)&m_CancelDlg);
|
||
|
s_hCancelDlg = m_CancelDlg.m_hDlg;
|
||
|
|
||
|
//
|
||
|
// Set the abort proc to allow cancel
|
||
|
//
|
||
|
SetAbortProc(m_hDC, AbortPrintProc);
|
||
|
|
||
|
//
|
||
|
// Four lines for top margin
|
||
|
//
|
||
|
m_yTopMargin = 4;
|
||
|
m_hLogFile = INVALID_HANDLE_VALUE;
|
||
|
}
|
||
|
|
||
|
int
|
||
|
CPrinter::StartDoc(
|
||
|
LPCTSTR DocTitle
|
||
|
)
|
||
|
{
|
||
|
if (m_hDC) {
|
||
|
|
||
|
if (m_hwndOwner) {
|
||
|
|
||
|
::EnableWindow(m_hwndOwner, FALSE);
|
||
|
}
|
||
|
|
||
|
//
|
||
|
// Initialize DOCINFO
|
||
|
//
|
||
|
DOCINFO DocInfo;
|
||
|
DocInfo.cbSize = sizeof(DocInfo);
|
||
|
TCHAR Temp[MAX_PATH];
|
||
|
lstrcpyn(Temp, DocTitle, ARRAYLEN(Temp));
|
||
|
DocInfo.lpszDocName = Temp;
|
||
|
|
||
|
DocInfo.lpszOutput = NULL;
|
||
|
DocInfo.lpszDatatype = NULL;
|
||
|
DocInfo.fwType = 0;
|
||
|
m_CurPage = 1;
|
||
|
m_CurLine = 0;
|
||
|
m_Status = ::StartDoc(m_hDC, &DocInfo);
|
||
|
}
|
||
|
|
||
|
else {
|
||
|
|
||
|
if (!DocTitle || _T('\0') == *DocTitle) {
|
||
|
|
||
|
m_Status = 0;
|
||
|
}
|
||
|
|
||
|
else {
|
||
|
|
||
|
m_hLogFile = CreateFile(DocTitle,
|
||
|
GENERIC_READ | GENERIC_WRITE,
|
||
|
0,
|
||
|
NULL,
|
||
|
CREATE_NEW,
|
||
|
FILE_ATTRIBUTE_NORMAL,
|
||
|
NULL);
|
||
|
|
||
|
m_Status = (INVALID_HANDLE_VALUE == m_hLogFile) ? 0 : 1;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return m_Status;
|
||
|
}
|
||
|
|
||
|
int
|
||
|
CPrinter::EndDoc()
|
||
|
{
|
||
|
|
||
|
if (m_hDC) {
|
||
|
|
||
|
if (m_hwndOwner) {
|
||
|
|
||
|
::EnableWindow(m_hwndOwner, TRUE);
|
||
|
}
|
||
|
|
||
|
if (s_hCancelDlg) {
|
||
|
|
||
|
DestroyWindow(s_hCancelDlg);
|
||
|
s_hCancelDlg = NULL;
|
||
|
}
|
||
|
|
||
|
if (!s_UserAborted) {
|
||
|
|
||
|
m_Status = ::EndDoc(m_hDC);
|
||
|
}
|
||
|
|
||
|
} else {
|
||
|
|
||
|
m_Status = 1;
|
||
|
|
||
|
if (INVALID_HANDLE_VALUE != m_hLogFile) {
|
||
|
|
||
|
CloseHandle(m_hLogFile);
|
||
|
|
||
|
} else {
|
||
|
|
||
|
m_Status = 0;
|
||
|
}
|
||
|
|
||
|
m_hLogFile = INVALID_HANDLE_VALUE;
|
||
|
}
|
||
|
|
||
|
return m_Status;
|
||
|
}
|
||
|
|
||
|
int
|
||
|
CPrinter::AbortDoc()
|
||
|
{
|
||
|
if (m_hDC) {
|
||
|
|
||
|
if (m_hwndOwner) {
|
||
|
|
||
|
::EnableWindow(m_hwndOwner, TRUE);
|
||
|
}
|
||
|
|
||
|
if (s_hCancelDlg) {
|
||
|
|
||
|
DestroyWindow(s_hCancelDlg);
|
||
|
s_hCancelDlg = NULL;
|
||
|
}
|
||
|
|
||
|
m_Status = ::AbortDoc(m_hDC);
|
||
|
|
||
|
} else {
|
||
|
|
||
|
m_Status = 1;
|
||
|
|
||
|
if (INVALID_HANDLE_VALUE != m_hLogFile) {
|
||
|
|
||
|
CloseHandle(m_hLogFile);
|
||
|
|
||
|
} else {
|
||
|
|
||
|
m_Status = 0;
|
||
|
}
|
||
|
|
||
|
m_hLogFile = INVALID_HANDLE_VALUE;
|
||
|
}
|
||
|
|
||
|
return m_Status;
|
||
|
}
|
||
|
|
||
|
int
|
||
|
CPrinter::FlushPage()
|
||
|
{
|
||
|
return PrintLine(NULL);
|
||
|
}
|
||
|
|
||
|
int
|
||
|
CPrinter::PrintLine(
|
||
|
LPCTSTR LineText
|
||
|
)
|
||
|
{
|
||
|
if (INVALID_HANDLE_VALUE != m_hLogFile) {
|
||
|
|
||
|
if (LineText) {
|
||
|
|
||
|
DWORD BytesWritten;
|
||
|
|
||
|
if (m_Indent) {
|
||
|
|
||
|
int Count = m_Indent * 2;
|
||
|
CHAR Blanks[MAX_PATH];
|
||
|
|
||
|
for (int i = 0; i < Count; i++) {
|
||
|
|
||
|
Blanks[i] = _T(' ');
|
||
|
}
|
||
|
|
||
|
WriteFile(m_hLogFile, Blanks, Count * sizeof(CHAR), &BytesWritten, NULL);
|
||
|
}
|
||
|
#ifdef UNICODE
|
||
|
int LenW = wcslen(LineText);
|
||
|
CHAR LineTextA[MAX_PATH];
|
||
|
int LenA;
|
||
|
LenA = WideCharToMultiByte(CP_ACP, 0, LineText, LenW, LineTextA, ARRAYLEN(LineTextA), NULL, NULL);
|
||
|
WriteFile(m_hLogFile, LineTextA, LenA * sizeof(CHAR), &BytesWritten, NULL);
|
||
|
WriteFile(m_hLogFile, g_NewLineA, strlen(g_NewLineA) * sizeof(CHAR), &BytesWritten, NULL);
|
||
|
#else
|
||
|
WriteFile(m_hLogFile, LineText, lstrlen(LineText) * sizeof(CHAR), &BytesWritten, NULL);
|
||
|
WriteFike(m_hLogFile, g_NewLine, lstrlen(g_NewLine) * sizeof(CHAR), &BytesWritten, NULL);
|
||
|
#endif
|
||
|
}
|
||
|
}
|
||
|
|
||
|
else {
|
||
|
|
||
|
//
|
||
|
// !LineText means flush the page
|
||
|
//
|
||
|
if ((!LineText && m_CurLine) || (m_CurLine > m_yBottomMargin)) {
|
||
|
|
||
|
m_CurLine = 0;
|
||
|
|
||
|
if (m_Status) {
|
||
|
|
||
|
m_Status = ::EndPage(m_hDC);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if (LineText) {
|
||
|
|
||
|
//
|
||
|
// If this is the first line and we are still in good shape,
|
||
|
// start a new page
|
||
|
//
|
||
|
if (!m_CurLine && m_Status) {
|
||
|
|
||
|
m_Status = ::StartPage(m_hDC);
|
||
|
|
||
|
if (m_Status) {
|
||
|
|
||
|
TCHAR PageTitle[MAX_PATH];
|
||
|
wsprintf(PageTitle, (LPCTSTR)m_strPageTitle, m_CurPage);
|
||
|
m_CurLine = m_yTopMargin;
|
||
|
TextOut(m_hDC, m_xMargin, m_yChar*m_CurLine, PageTitle, lstrlen(PageTitle));
|
||
|
|
||
|
//
|
||
|
// Have one blank line right after page title
|
||
|
//
|
||
|
LineFeed();
|
||
|
m_CurLine++;
|
||
|
m_CurPage++;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if (m_Status) {
|
||
|
|
||
|
TextOut(m_hDC, m_xMargin + m_xChar*m_Indent*2, m_yChar*m_CurLine, LineText, lstrlen(LineText));
|
||
|
}
|
||
|
|
||
|
m_CurLine++;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return m_Status;
|
||
|
}
|
||
|
|
||
|
inline
|
||
|
void
|
||
|
CPrinter::LineFeed()
|
||
|
{
|
||
|
PrintLine(g_BlankLine);
|
||
|
}
|
||
|
|
||
|
// the abort procedure
|
||
|
BOOL CALLBACK
|
||
|
AbortPrintProc(
|
||
|
HDC hDC,
|
||
|
int nCode
|
||
|
)
|
||
|
{
|
||
|
MSG msg;
|
||
|
|
||
|
while (!CPrinter::s_UserAborted && PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) {
|
||
|
|
||
|
if (!IsDialogMessage(CPrinter::s_hCancelDlg, &msg)) {
|
||
|
|
||
|
TranslateMessage(&msg);
|
||
|
DispatchMessage(&msg);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return !CPrinter::s_UserAborted;
|
||
|
}
|
||
|
|
||
|
//
|
||
|
// This function prints system summary.
|
||
|
// INPUT:
|
||
|
// Machine -- the machine
|
||
|
// OUTPUT:
|
||
|
// 0 -- failed else succeeded.
|
||
|
//
|
||
|
//
|
||
|
int
|
||
|
CPrinter::PrintSystemSummary(
|
||
|
CMachine& Machine
|
||
|
)
|
||
|
{
|
||
|
CSystemInfo SysInfo;
|
||
|
TCHAR Line[MAX_PATH];
|
||
|
TCHAR Buffer[MAX_PATH];
|
||
|
TCHAR Format[MAX_PATH];
|
||
|
TCHAR Unknown[30];
|
||
|
TCHAR szTemp[30];
|
||
|
DWORD Size, BufferSize;
|
||
|
BufferSize = ARRAYLEN(Buffer);
|
||
|
|
||
|
//
|
||
|
// Preload the "Unknown" string which will be used as default when
|
||
|
// the corresponding value can not found
|
||
|
//
|
||
|
LoadString(g_hInstance, IDS_PRINT_UNKNOWN, Unknown, ARRAYLEN(Unknown));
|
||
|
|
||
|
|
||
|
//
|
||
|
// Print System summary heading
|
||
|
//
|
||
|
LoadString(g_hInstance, IDS_PRINT_HEADING_SYSSUMMARY, Buffer, ARRAYLEN(Buffer));
|
||
|
LoadString(g_hInstance, IDS_PRINT_BANNER, Format, ARRAYLEN(Format));
|
||
|
wsprintf(Line, Format, Buffer);
|
||
|
PrintLine(Line);
|
||
|
LineFeed();
|
||
|
|
||
|
//
|
||
|
// Windows version
|
||
|
//
|
||
|
LoadString(g_hInstance, IDS_PRINT_WINVER, Line, ARRAYLEN(Line));
|
||
|
Size = SysInfo.WindowsVersion(Buffer, BufferSize);
|
||
|
lstrcat(Line, Size ? Buffer : Unknown);
|
||
|
PrintLine(Line);
|
||
|
|
||
|
//
|
||
|
// Registered Owner
|
||
|
//
|
||
|
LoadString(g_hInstance, IDS_PRINT_OWNER, Line, ARRAYLEN(Line));
|
||
|
Size = SysInfo.RegisteredOwner(Buffer, BufferSize);
|
||
|
lstrcat(Line, Size ? Buffer : Unknown);
|
||
|
PrintLine(Line);
|
||
|
|
||
|
//
|
||
|
// Registered Organization
|
||
|
//
|
||
|
LoadString(g_hInstance, IDS_PRINT_ORGANIZATION, Line, ARRAYLEN(Line));
|
||
|
Size = SysInfo.RegisteredOrganization(Buffer, BufferSize);
|
||
|
lstrcat(Line, Size ? Buffer : Unknown);
|
||
|
PrintLine(Line);
|
||
|
|
||
|
//
|
||
|
// Computer name
|
||
|
//
|
||
|
LoadString(g_hInstance, IDS_PRINT_COMPUTERNAME, Line, ARRAYLEN(Line));
|
||
|
lstrcat(Line, SysInfo.ComputerName());
|
||
|
PrintLine(Line);
|
||
|
|
||
|
//
|
||
|
// Machine Type
|
||
|
//
|
||
|
LoadString(g_hInstance, IDS_PRINT_MACHINE_TYPE, Line, ARRAYLEN(Line));
|
||
|
Size = SysInfo.MachineType(Buffer, BufferSize);
|
||
|
lstrcat(Line, Size ? Buffer : Unknown);
|
||
|
PrintLine(Line);
|
||
|
|
||
|
//
|
||
|
// System BIOS Version
|
||
|
//
|
||
|
LoadString(g_hInstance, IDS_PRINT_SYSBIOS_VERSION, Line, ARRAYLEN(Line));
|
||
|
Size = SysInfo.SystemBiosVersion(Buffer, BufferSize);
|
||
|
lstrcat(Line, Size ? Buffer : Unknown);
|
||
|
PrintLine(Line);
|
||
|
|
||
|
//
|
||
|
// System BIOS Date
|
||
|
//
|
||
|
LoadString(g_hInstance, IDS_PRINT_SYSBIOS_DATE, Line, ARRAYLEN(Line));
|
||
|
Size = SysInfo.SystemBiosDate(Buffer, BufferSize);
|
||
|
lstrcat(Line, Size ? Buffer : Unknown);
|
||
|
PrintLine(Line);
|
||
|
|
||
|
//
|
||
|
// Processor type
|
||
|
//
|
||
|
LoadString(g_hInstance, IDS_PRINT_PROCESSOR_TYPE, Line, ARRAYLEN(Line));
|
||
|
Size = SysInfo.ProcessorType(Buffer, BufferSize);
|
||
|
lstrcat(Line, Size ? Buffer : Unknown);
|
||
|
PrintLine(Line);
|
||
|
|
||
|
//
|
||
|
// Processor vendor
|
||
|
//
|
||
|
LoadString(g_hInstance, IDS_PRINT_PROCESSOR_VENDOR, Line, ARRAYLEN(Line));
|
||
|
Size = SysInfo.ProcessorVendor(Buffer, BufferSize);
|
||
|
lstrcat(Line, Size ? Buffer : Unknown);
|
||
|
PrintLine(Line);
|
||
|
|
||
|
//
|
||
|
// Number of processors
|
||
|
//
|
||
|
LoadString(g_hInstance, IDS_PRINT_PROCESSORS, Line, ARRAYLEN(Line));
|
||
|
DWORD NumProcessors = SysInfo.NumberOfProcessors();
|
||
|
|
||
|
if (NumProcessors) {
|
||
|
|
||
|
wsprintf(Buffer, TEXT("%u"), NumProcessors);
|
||
|
lstrcat(Line, Buffer);
|
||
|
|
||
|
} else {
|
||
|
|
||
|
lstrcat(Line, Unknown);
|
||
|
}
|
||
|
|
||
|
PrintLine(Line);
|
||
|
|
||
|
//
|
||
|
// Total physical memory
|
||
|
//
|
||
|
ULARGE_INTEGER MemorySize;
|
||
|
SysInfo.TotalPhysicalMemory(MemorySize);
|
||
|
LoadString(g_hInstance, IDS_PRINT_PHY_MEMORY, Line, ARRAYLEN(Line));
|
||
|
|
||
|
if (MemorySize.QuadPart) {
|
||
|
|
||
|
LoadString(g_hInstance, IDS_PRINT_MEMORY_UNIT, Format, ARRAYLEN(Format));
|
||
|
MemorySize.QuadPart += 1024*1024 - 1;
|
||
|
wsprintf(Buffer, Format, Int64ShrlMod32(MemorySize.QuadPart, 20));
|
||
|
lstrcat(Line, Buffer);
|
||
|
|
||
|
} else {
|
||
|
|
||
|
lstrcat(Line, Unknown);
|
||
|
}
|
||
|
|
||
|
PrintLine(Line);
|
||
|
LineFeed();
|
||
|
|
||
|
//
|
||
|
// Local disk drive information
|
||
|
//
|
||
|
// Print Disk info summary heading
|
||
|
//
|
||
|
LoadString(g_hInstance, IDS_PRINT_HEADING_DISKINFO, Buffer, ARRAYLEN(Buffer));
|
||
|
LoadString(g_hInstance, IDS_PRINT_BANNER, Format, ARRAYLEN(Format));
|
||
|
wsprintf(Line, Format, Buffer);
|
||
|
PrintLine(Line);
|
||
|
LineFeed();
|
||
|
|
||
|
DISK_INFO DiskInfo;
|
||
|
DiskInfo.cbSize = sizeof(DiskInfo);
|
||
|
|
||
|
for(int Drive = 0; Drive < 25; Drive++) {
|
||
|
|
||
|
// information we want to report on the drive:
|
||
|
// (1). drive letter and type
|
||
|
// (2). Total space
|
||
|
// (3). Free space(if available)
|
||
|
// (4). Cylinders
|
||
|
// (5). Heads
|
||
|
// (6). Sectors per track
|
||
|
// (7). Bytes per sector
|
||
|
|
||
|
Indent();
|
||
|
|
||
|
if(SysInfo.GetDiskInfo(Drive, DiskInfo)) {
|
||
|
|
||
|
TCHAR DriveLetter;
|
||
|
DriveLetter = Drive + _T('A');
|
||
|
LoadString(g_hInstance, IDS_PRINT_DRIVE_LETTER, Format, ARRAYLEN(Format));
|
||
|
wsprintf(Line, Format, DriveLetter);
|
||
|
PrintLine(Line);
|
||
|
Indent();
|
||
|
|
||
|
//
|
||
|
// Drive type
|
||
|
//
|
||
|
LoadString(g_hInstance, IDS_PRINT_DRIVE_TYPE, Format, ARRAYLEN(Format));
|
||
|
int StringId;
|
||
|
LoadString(g_hInstance,
|
||
|
IDS_MEDIA_BASE + (int)DiskInfo.MediaType,
|
||
|
Buffer, ARRAYLEN(Buffer));
|
||
|
wsprintf(Line, Format, Buffer);
|
||
|
PrintLine(Line);
|
||
|
|
||
|
//
|
||
|
//Total and free space
|
||
|
//
|
||
|
LoadString(g_hInstance, IDS_PRINT_TOTAL_SPACE, Format, ARRAYLEN(Format));
|
||
|
wsprintf(Line, Format, AddCommas64(DiskInfo.TotalSpace.QuadPart, szTemp, ARRAYLEN(szTemp)));
|
||
|
PrintLine(Line);
|
||
|
|
||
|
if (-1 != DiskInfo.FreeSpace.QuadPart) {
|
||
|
|
||
|
LoadString(g_hInstance, IDS_PRINT_FREE_SPACE, Format, ARRAYLEN(Format));
|
||
|
wsprintf(Line, Format, AddCommas64(DiskInfo.FreeSpace.QuadPart, szTemp, ARRAYLEN(szTemp)));
|
||
|
PrintLine(Line);
|
||
|
}
|
||
|
|
||
|
//
|
||
|
// Disk physical dimension
|
||
|
// skip CD-ROM because the dimension it reports is bogus
|
||
|
//
|
||
|
if (DRIVE_CDROM != DiskInfo.DriveType) {
|
||
|
|
||
|
//
|
||
|
// Heads
|
||
|
//
|
||
|
LoadString(g_hInstance, IDS_PRINT_HEADS, Format, ARRAYLEN(Format));
|
||
|
wsprintf(Line, Format, DiskInfo.Heads);
|
||
|
PrintLine(Line);
|
||
|
|
||
|
//
|
||
|
// Cylinders
|
||
|
//
|
||
|
if (DiskInfo.Cylinders.HighPart) {
|
||
|
|
||
|
LoadString(g_hInstance, IDS_PRINT_CYLINDERS_XL, Format, ARRAYLEN(Format));
|
||
|
wsprintf(Line, Format, DiskInfo.Cylinders.HighPart,
|
||
|
DiskInfo.Cylinders.LowPart);
|
||
|
PrintLine(Line);
|
||
|
|
||
|
} else {
|
||
|
LoadString(g_hInstance, IDS_PRINT_CYLINDERS, Format, ARRAYLEN(Format));
|
||
|
wsprintf(Line, Format, DiskInfo.Cylinders.LowPart);
|
||
|
PrintLine(Line);
|
||
|
}
|
||
|
|
||
|
//
|
||
|
// Sectors per track
|
||
|
//
|
||
|
LoadString(g_hInstance, IDS_PRINT_TRACKSIZE, Format, ARRAYLEN(Format));
|
||
|
wsprintf(Line, Format, DiskInfo.SectorsPerTrack);
|
||
|
PrintLine(Line);
|
||
|
|
||
|
//
|
||
|
// Bytes per sector
|
||
|
//
|
||
|
LoadString(g_hInstance, IDS_PRINT_SECTORSIZE, Format, ARRAYLEN(Format));
|
||
|
wsprintf(Line, Format, DiskInfo.BytesPerSector);
|
||
|
PrintLine(Line);
|
||
|
}
|
||
|
|
||
|
UnIndent();
|
||
|
LineFeed();
|
||
|
}
|
||
|
|
||
|
UnIndent();
|
||
|
}
|
||
|
|
||
|
return 1;
|
||
|
}
|
||
|
|
||
|
int
|
||
|
CPrinter::PrintResourceSummary(
|
||
|
CMachine& Machine
|
||
|
)
|
||
|
{
|
||
|
TCHAR Temp[MAX_PATH];
|
||
|
CResource* pResource;
|
||
|
String str;
|
||
|
String strBanner;
|
||
|
|
||
|
PrintSystemSummary(Machine);
|
||
|
|
||
|
//
|
||
|
// print IRQ summary heading
|
||
|
//
|
||
|
str.LoadString(g_hInstance, IDS_PRINT_HEADING_IRQSUMMARY);
|
||
|
strBanner.LoadString(g_hInstance, IDS_PRINT_BANNER);
|
||
|
wsprintf(Temp, (LPCTSTR)strBanner, (LPCTSTR)str);
|
||
|
PrintLine(Temp);
|
||
|
LineFeed();
|
||
|
CResourceList IrqSummary(&Machine, ResType_IRQ);
|
||
|
|
||
|
if (IrqSummary.GetCount()) {
|
||
|
|
||
|
CResource* pResRoot;
|
||
|
IrqSummary.CreateResourceTree(&pResRoot);
|
||
|
str.LoadString(g_hInstance, IDS_PRINT_IRQSUM);
|
||
|
PrintLine(str);
|
||
|
Indent();
|
||
|
PrintResourceSubtree(pResRoot);
|
||
|
UnIndent();
|
||
|
LineFeed();
|
||
|
}
|
||
|
|
||
|
//
|
||
|
// print DMA summary heading
|
||
|
//
|
||
|
str.LoadString(g_hInstance, IDS_PRINT_HEADING_DMASUMMARY);
|
||
|
wsprintf(Temp, (LPCTSTR)strBanner, (LPCTSTR)str);
|
||
|
PrintLine(Temp);
|
||
|
LineFeed();
|
||
|
CResourceList DmaSummary(&Machine, ResType_DMA);
|
||
|
|
||
|
if (DmaSummary.GetCount()) {
|
||
|
|
||
|
CResource* pResRoot;
|
||
|
DmaSummary.CreateResourceTree(&pResRoot);
|
||
|
str.LoadString(g_hInstance, IDS_PRINT_DMASUM);
|
||
|
PrintLine(str);
|
||
|
Indent();
|
||
|
PrintResourceSubtree(pResRoot);
|
||
|
UnIndent();
|
||
|
LineFeed();
|
||
|
}
|
||
|
|
||
|
//
|
||
|
// print MEM summary heading
|
||
|
//
|
||
|
str.LoadString(g_hInstance, IDS_PRINT_HEADING_MEMSUMMARY);
|
||
|
wsprintf(Temp, (LPCTSTR)strBanner, (LPCTSTR)str);
|
||
|
PrintLine(Temp);
|
||
|
LineFeed();
|
||
|
CResourceList MemSummary(&Machine, ResType_Mem);
|
||
|
|
||
|
if (MemSummary.GetCount()) {
|
||
|
|
||
|
CResource* pResRoot;
|
||
|
MemSummary.CreateResourceTree(&pResRoot);
|
||
|
str.LoadString(g_hInstance, IDS_PRINT_MEMSUM);
|
||
|
PrintLine(str);
|
||
|
Indent();
|
||
|
PrintResourceSubtree(pResRoot);
|
||
|
UnIndent();
|
||
|
LineFeed();
|
||
|
}
|
||
|
|
||
|
//
|
||
|
// print IO summary heading
|
||
|
//
|
||
|
str.LoadString(g_hInstance, IDS_PRINT_HEADING_IOSUMMARY);
|
||
|
wsprintf(Temp, (LPCTSTR)strBanner, (LPCTSTR)str);
|
||
|
PrintLine(Temp);
|
||
|
LineFeed();
|
||
|
CResourceList IoSummary(&Machine, ResType_IO);
|
||
|
|
||
|
if (IoSummary.GetCount()) {
|
||
|
|
||
|
CResource* pResRoot;
|
||
|
IoSummary.CreateResourceTree(&pResRoot);
|
||
|
str.LoadString(g_hInstance, IDS_PRINT_IOSUM);
|
||
|
PrintLine(str);
|
||
|
Indent();
|
||
|
PrintResourceSubtree(pResRoot);
|
||
|
UnIndent();
|
||
|
LineFeed();
|
||
|
}
|
||
|
|
||
|
return 1;
|
||
|
}
|
||
|
|
||
|
int
|
||
|
CPrinter::PrintResourceSubtree(
|
||
|
CResource* pResRoot
|
||
|
)
|
||
|
{
|
||
|
while (pResRoot)
|
||
|
{
|
||
|
DWORD Status, Problem;
|
||
|
|
||
|
if (pResRoot->m_pDevice->GetStatus(&Status, &Problem) && Problem ||
|
||
|
pResRoot->m_pDevice->IsDisabled()) {
|
||
|
|
||
|
TCHAR Temp[MAX_PATH];
|
||
|
Temp[0] = _T('*');
|
||
|
lstrcpy(&Temp[1], pResRoot->GetViewName());
|
||
|
PrintLine(Temp);
|
||
|
|
||
|
} else {
|
||
|
|
||
|
PrintLine(pResRoot->GetViewName());
|
||
|
}
|
||
|
|
||
|
if (pResRoot->GetChild()) {
|
||
|
|
||
|
if ((ResType_IO == pResRoot->ResType()) ||
|
||
|
(ResType_Mem == pResRoot->ResType())) {
|
||
|
|
||
|
Indent();
|
||
|
}
|
||
|
|
||
|
PrintResourceSubtree(pResRoot->GetChild());
|
||
|
|
||
|
if ((ResType_IO == pResRoot->ResType()) ||
|
||
|
(ResType_Mem == pResRoot->ResType())) {
|
||
|
|
||
|
UnIndent();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
pResRoot = pResRoot->GetSibling();
|
||
|
}
|
||
|
|
||
|
return 1;
|
||
|
}
|
||
|
|
||
|
int
|
||
|
CPrinter::PrintAllClassAndDevice(
|
||
|
CMachine* pMachine
|
||
|
)
|
||
|
{
|
||
|
|
||
|
if (!pMachine) {
|
||
|
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
String strHeading;
|
||
|
String strBanner;
|
||
|
TCHAR Temp[MAX_PATH];
|
||
|
strHeading.LoadString(g_hInstance, IDS_PRINT_HEADING_SYSDEVINFO);
|
||
|
strBanner.LoadString(g_hInstance, IDS_PRINT_BANNER);
|
||
|
wsprintf(Temp, (LPCTSTR)strBanner, (LPCTSTR)strHeading);
|
||
|
PrintLine(Temp);
|
||
|
LineFeed();
|
||
|
|
||
|
CClass* pClass;
|
||
|
PVOID Context;
|
||
|
|
||
|
if (pMachine->GetFirstClass(&pClass, Context)) {
|
||
|
|
||
|
do {
|
||
|
|
||
|
PrintClass(pClass, FALSE);
|
||
|
|
||
|
} while (pMachine->GetNextClass(&pClass, Context));
|
||
|
}
|
||
|
|
||
|
return 1;
|
||
|
}
|
||
|
|
||
|
int
|
||
|
CPrinter::PrintClass(
|
||
|
CClass* pClass,
|
||
|
BOOL PrintBanner
|
||
|
)
|
||
|
{
|
||
|
PVOID Context;
|
||
|
CDevice* pDevice;
|
||
|
|
||
|
if (!pClass) {
|
||
|
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
if (PrintBanner) {
|
||
|
|
||
|
String strHeading;
|
||
|
String strBanner;
|
||
|
TCHAR Temp[MAX_PATH];
|
||
|
strHeading.LoadString(g_hInstance, IDS_PRINT_HEADING_SYSDEVCLASS);
|
||
|
strBanner.LoadString(g_hInstance, IDS_PRINT_BANNER);
|
||
|
wsprintf(Temp, (LPCTSTR)strBanner, (LPCTSTR)strHeading);
|
||
|
PrintLine(Temp);
|
||
|
LineFeed();
|
||
|
}
|
||
|
|
||
|
if (pClass && pClass->GetFirstDevice(&pDevice, Context)) {
|
||
|
|
||
|
do {
|
||
|
|
||
|
//
|
||
|
// Do print banner on the device
|
||
|
//
|
||
|
PrintDevice(pDevice, FALSE);
|
||
|
|
||
|
} while (pClass->GetNextDevice(&pDevice, Context));
|
||
|
}
|
||
|
|
||
|
return 1;
|
||
|
}
|
||
|
|
||
|
int
|
||
|
CPrinter::PrintDevice(
|
||
|
CDevice* pDevice,
|
||
|
BOOL PrintBanner
|
||
|
)
|
||
|
{
|
||
|
|
||
|
if (!pDevice) {
|
||
|
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
String str;
|
||
|
TCHAR Temp[MAX_PATH];
|
||
|
|
||
|
if (PrintBanner) {
|
||
|
|
||
|
String strBanner;
|
||
|
str.LoadString(g_hInstance, IDS_PRINT_HEADING_SYSDEVICE);
|
||
|
strBanner.LoadString(g_hInstance, IDS_PRINT_BANNER);
|
||
|
wsprintf(Temp, (LPCTSTR)strBanner, (LPCTSTR)str);
|
||
|
PrintLine(Temp);
|
||
|
LineFeed();
|
||
|
}
|
||
|
|
||
|
DWORD Status, Problem;
|
||
|
|
||
|
if (pDevice->GetStatus(&Status, &Problem) && Problem ||
|
||
|
pDevice->IsDisabled()) {
|
||
|
|
||
|
LoadString(g_hInstance, IDS_PRINT_DEVICE_DISABLED, Temp, ARRAYLEN(Temp));
|
||
|
PrintLine(Temp);
|
||
|
}
|
||
|
|
||
|
str.LoadString(g_hInstance, IDS_PRINT_CLASS);
|
||
|
wsprintf(Temp, (LPCTSTR)str, pDevice->GetClassDisplayName());
|
||
|
PrintLine(Temp);
|
||
|
str.LoadString(g_hInstance, IDS_PRINT_DEVICE);
|
||
|
wsprintf(Temp, (LPCTSTR)str, pDevice->GetDisplayName());
|
||
|
PrintLine(Temp);
|
||
|
PrintDeviceResource(pDevice);
|
||
|
PrintDeviceDriver(pDevice);
|
||
|
return 1;
|
||
|
}
|
||
|
|
||
|
int
|
||
|
CPrinter::PrintAll(
|
||
|
CMachine& Machine
|
||
|
)
|
||
|
{
|
||
|
PrintResourceSummary(Machine);
|
||
|
PrintAllClassAndDevice(&Machine);
|
||
|
return 1;
|
||
|
}
|
||
|
|
||
|
//
|
||
|
// This function prints the given device's resource summary
|
||
|
//
|
||
|
int
|
||
|
CPrinter::PrintDeviceResource(
|
||
|
CDevice* pDevice
|
||
|
)
|
||
|
{
|
||
|
|
||
|
if (!pDevice) {
|
||
|
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
CResourceList IrqSummary(pDevice, ResType_IRQ);
|
||
|
CResourceList DmaSummary(pDevice, ResType_DMA);
|
||
|
CResourceList MemSummary(pDevice, ResType_Mem);
|
||
|
CResourceList IoSummary(pDevice, ResType_IO);
|
||
|
|
||
|
String str;
|
||
|
TCHAR Temp[MAX_PATH];
|
||
|
|
||
|
//
|
||
|
// If the device has any kind of resources, print it
|
||
|
//
|
||
|
if (IrqSummary.GetCount() || DmaSummary.GetCount() ||
|
||
|
MemSummary.GetCount() || IoSummary.GetCount()) {
|
||
|
|
||
|
str.LoadString(g_hInstance, IDS_PRINT_RESOURCE);
|
||
|
PrintLine(str);
|
||
|
|
||
|
//
|
||
|
// Start printing individual resources
|
||
|
//
|
||
|
Indent();
|
||
|
PVOID Context;
|
||
|
CResource* pResource;
|
||
|
DWORDLONG dlBase, dlLen;
|
||
|
TCHAR Format[MAX_PATH];
|
||
|
|
||
|
if (IrqSummary.GetFirst(&pResource, Context)) {
|
||
|
|
||
|
LoadString(g_hInstance, IDS_PRINT_IRQ_FORMAT, Temp, ARRAYLEN(Temp));
|
||
|
|
||
|
do {
|
||
|
|
||
|
pResource->GetValue(&dlBase, &dlLen);
|
||
|
str.Format(Temp, (ULONG)dlBase);
|
||
|
PrintLine((LPCTSTR)str);
|
||
|
|
||
|
} while (IrqSummary.GetNext(&pResource, Context));
|
||
|
}
|
||
|
|
||
|
if (DmaSummary.GetFirst(&pResource, Context)) {
|
||
|
|
||
|
LoadString(g_hInstance, IDS_PRINT_DMA_FORMAT, Temp, ARRAYLEN(Temp));
|
||
|
|
||
|
do {
|
||
|
|
||
|
pResource->GetValue(&dlBase, &dlLen);
|
||
|
str.Format(Temp, (ULONG)dlBase);
|
||
|
PrintLine((LPCTSTR)str);
|
||
|
|
||
|
} while (DmaSummary.GetNext(&pResource, Context));
|
||
|
}
|
||
|
|
||
|
if (MemSummary.GetFirst(&pResource, Context)) {
|
||
|
|
||
|
LoadString(g_hInstance, IDS_PRINT_MEM_FORMAT, Temp, ARRAYLEN(Temp));
|
||
|
|
||
|
do {
|
||
|
|
||
|
pResource->GetValue(&dlBase, &dlLen);
|
||
|
str.Format(Temp, (ULONG)dlBase, (ULONG)(dlBase + dlLen - 1));
|
||
|
PrintLine((LPCTSTR)str);
|
||
|
|
||
|
} while (MemSummary.GetNext(&pResource, Context));
|
||
|
}
|
||
|
|
||
|
if (IoSummary.GetFirst(&pResource, Context)) {
|
||
|
|
||
|
LoadString(g_hInstance, IDS_PRINT_IO_FORMAT, Temp, ARRAYLEN(Temp));
|
||
|
|
||
|
do {
|
||
|
|
||
|
pResource->GetValue(&dlBase, &dlLen);
|
||
|
str.Format(Temp, (ULONG)dlBase, (ULONG)(dlBase + dlLen -1));
|
||
|
PrintLine((LPCTSTR)str);
|
||
|
|
||
|
} while (IoSummary.GetNext(&pResource, Context));
|
||
|
}
|
||
|
|
||
|
UnIndent();
|
||
|
|
||
|
} else {
|
||
|
str.LoadString(g_hInstance, IDS_PRINT_NORES);
|
||
|
PrintLine(str);
|
||
|
}
|
||
|
|
||
|
return 1;
|
||
|
}
|
||
|
|
||
|
|
||
|
//
|
||
|
// This function prints the given device's driver information
|
||
|
// INPUT:
|
||
|
// pDevice -- the device
|
||
|
// OUTPUT:
|
||
|
// >0 if the function succeeded.
|
||
|
// 0 if the function failed.
|
||
|
//
|
||
|
int
|
||
|
CPrinter::PrintDeviceDriver(
|
||
|
CDevice* pDevice
|
||
|
)
|
||
|
{
|
||
|
if (!pDevice) {
|
||
|
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
String str;
|
||
|
TCHAR Temp[MAX_PATH];
|
||
|
|
||
|
CDriver* pDriver;
|
||
|
pDriver = pDevice->CreateDriver();
|
||
|
SafePtr<CDriver> DrvPtr;
|
||
|
|
||
|
if (pDriver) {
|
||
|
|
||
|
DrvPtr.Attach(pDriver);
|
||
|
str.LoadString(g_hInstance, IDS_PRINT_DRVINFO);
|
||
|
PrintLine(str);
|
||
|
PVOID Context;
|
||
|
CDriverFile* pDrvFile;
|
||
|
Indent();
|
||
|
|
||
|
if (pDriver->GetFirstDriverFile(&pDrvFile, Context)) {
|
||
|
|
||
|
do {
|
||
|
|
||
|
PrintLine(pDrvFile->GetFullPathName());
|
||
|
HANDLE hFile;
|
||
|
Indent();
|
||
|
hFile = CreateFile(pDrvFile->GetFullPathName(),
|
||
|
GENERIC_READ,
|
||
|
0,
|
||
|
NULL,
|
||
|
OPEN_EXISTING,
|
||
|
FILE_ATTRIBUTE_NORMAL |
|
||
|
FILE_ATTRIBUTE_READONLY |
|
||
|
FILE_ATTRIBUTE_SYSTEM |
|
||
|
FILE_ATTRIBUTE_HIDDEN,
|
||
|
NULL
|
||
|
);
|
||
|
|
||
|
if (INVALID_HANDLE_VALUE != hFile) {
|
||
|
|
||
|
DWORD FileSize;
|
||
|
FileSize = ::GetFileSize(hFile, NULL);
|
||
|
CloseHandle(hFile);
|
||
|
LoadString(g_hInstance, IDS_PRINT_FILESIZE, Temp, ARRAYLEN(Temp));
|
||
|
str.Format(Temp, FileSize);
|
||
|
PrintLine(str);
|
||
|
// print the driver version infomation
|
||
|
TCHAR Unknown[MAX_PATH];
|
||
|
LoadString(g_hInstance, IDS_PRINT_UNKNOWN, Unknown, ARRAYLEN(Unknown));
|
||
|
|
||
|
if (pDrvFile->HasVersionInfo()) {
|
||
|
|
||
|
LoadString(g_hInstance, IDS_PRINT_FILEVERSION, Temp, ARRAYLEN(Temp));
|
||
|
|
||
|
if (pDrvFile->GetVersion()) {
|
||
|
|
||
|
str.Format(Temp, pDrvFile->GetVersion());
|
||
|
|
||
|
} else {
|
||
|
|
||
|
str.Format(Temp, Unknown);
|
||
|
}
|
||
|
|
||
|
PrintLine(str);
|
||
|
|
||
|
LoadString(g_hInstance, IDS_PRINT_FILEMFG, Temp, ARRAYLEN(Temp));
|
||
|
|
||
|
if (pDrvFile->GetProvider()) {
|
||
|
|
||
|
str.Format(Temp, pDrvFile->GetProvider());
|
||
|
|
||
|
} else {
|
||
|
|
||
|
str.Format(Temp, Unknown);
|
||
|
}
|
||
|
|
||
|
PrintLine(str);
|
||
|
|
||
|
LoadString(g_hInstance, IDS_PRINT_FILECOPYRIGHT, Temp, ARRAYLEN(Temp));
|
||
|
|
||
|
if (pDrvFile->GetCopyright()) {
|
||
|
|
||
|
str.Format(Temp, pDrvFile->GetCopyright());
|
||
|
|
||
|
} else {
|
||
|
|
||
|
str.Format(Temp, Unknown);
|
||
|
}
|
||
|
|
||
|
PrintLine(str);
|
||
|
|
||
|
} else {
|
||
|
|
||
|
str.LoadString(g_hInstance, IDS_PRINT_NOVERSION);
|
||
|
PrintLine(str);
|
||
|
}
|
||
|
|
||
|
} else {
|
||
|
|
||
|
str.LoadString(g_hInstance, IDS_PRINT_DRVMISSING);
|
||
|
PrintLine(str);
|
||
|
}
|
||
|
|
||
|
UnIndent();
|
||
|
|
||
|
} while (pDriver->GetNextDriverFile(&pDrvFile, Context));
|
||
|
}
|
||
|
|
||
|
UnIndent();
|
||
|
}
|
||
|
|
||
|
LineFeed();
|
||
|
|
||
|
return 1;
|
||
|
}
|