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

/*++
Copyright (C) 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("");
//
// CPrinter Class implementation
//
BOOL CPrinter::s_UserAborted = FALSE;
HWND CPrinter::s_hCancelDlg = NULL;
void
CPrintCancelDialog::OnCommand(
WPARAM wParam,
LPARAM lParam
)
{
UNREFERENCED_PARAMETER(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;
}
int
CPrinter::StartDoc(
LPCTSTR DocTitle
)
{
m_Status = 0;
if (m_hDC) {
if (m_hwndOwner) {
::EnableWindow(m_hwndOwner, FALSE);
}
//
// Initialize DOCINFO
//
DOCINFO DocInfo;
DocInfo.cbSize = sizeof(DocInfo);
DocInfo.lpszDocName = DocTitle;
DocInfo.lpszOutput = NULL;
DocInfo.lpszDatatype = NULL;
DocInfo.fwType = 0;
m_CurPage = 1;
m_CurLine = 0;
m_Status = ::StartDoc(m_hDC, &DocInfo);
}
return m_Status;
}
int
CPrinter::EndDoc()
{
m_Status = 0;
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);
}
}
return m_Status;
}
int
CPrinter::AbortDoc()
{
m_Status = 0;
if (m_hDC) {
if (m_hwndOwner) {
::EnableWindow(m_hwndOwner, TRUE);
}
if (s_hCancelDlg) {
DestroyWindow(s_hCancelDlg);
s_hCancelDlg = NULL;
}
m_Status = ::AbortDoc(m_hDC);
}
return m_Status;
}
int
CPrinter::FlushPage()
{
return PrintLine(NULL);
}
int
CPrinter::PrintLine(
LPCTSTR LineText
)
{
//
// NULL 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) {
String strPageTitle;
strPageTitle.Format((LPCTSTR)m_strPageTitle, m_CurPage);
m_CurLine = m_yTopMargin;
TextOut(m_hDC, m_xMargin, m_yChar*m_CurLine, (LPTSTR)strPageTitle, strPageTitle.GetLength());
//
// 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;
UNREFERENCED_PARAMETER(hDC);
UNREFERENCED_PARAMETER(nCode);
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(
void
)
{
CSystemInfo SysInfo;
String strLine;
String strFormat;
String strBuffer;
String strUnknown;
TCHAR Buffer[MAX_PATH];
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
//
strUnknown.LoadString(g_hInstance, IDS_PRINT_UNKNOWN);
//
// Print System summary heading
//
LoadString(g_hInstance, IDS_PRINT_HEADING_SYSSUMMARY, Buffer, ARRAYLEN(Buffer));
strFormat.LoadString(g_hInstance, IDS_PRINT_BANNER);
strLine.Format((LPCTSTR)strFormat, Buffer);
PrintLine((LPCTSTR)strLine);
LineFeed();
//
// Windows version
//
strLine.LoadString(g_hInstance, IDS_PRINT_WINVER);
Size = SysInfo.WindowsVersion(Buffer, BufferSize);
strLine += Size ? (LPCTSTR)Buffer : strUnknown;
PrintLine((LPCTSTR)strLine);
//
// Registered Owner
//
strLine.LoadString(g_hInstance, IDS_PRINT_OWNER);
Size = SysInfo.RegisteredOwner(Buffer, BufferSize);
strLine += Size ? (LPCTSTR)Buffer : strUnknown;
PrintLine((LPCTSTR)strLine);
//
// Registered Organization
//
strLine.LoadString(g_hInstance, IDS_PRINT_ORGANIZATION);
Size = SysInfo.RegisteredOrganization(Buffer, BufferSize);
strLine += Size ? (LPCTSTR)Buffer : strUnknown;
PrintLine((LPCTSTR)strLine);
//
// Computer name
//
strLine.LoadString(g_hInstance, IDS_PRINT_COMPUTERNAME);
strLine += (LPCTSTR)SysInfo.ComputerName();
PrintLine((LPCTSTR)strLine);
//
// Machine Type
//
strLine.LoadString(g_hInstance, IDS_PRINT_MACHINE_TYPE);
Size = SysInfo.MachineType(Buffer, BufferSize);
strLine += Size ? (LPCTSTR)Buffer : strUnknown;
PrintLine((LPCTSTR)strLine);
//
// System BIOS Version
//
strLine.LoadString(g_hInstance, IDS_PRINT_SYSBIOS_VERSION);
Size = SysInfo.SystemBiosVersion(Buffer, BufferSize);
strLine += Size ? (LPCTSTR)Buffer : strUnknown;
PrintLine((LPCTSTR)strLine);
//
// System BIOS Date
//
strLine.LoadString(g_hInstance, IDS_PRINT_SYSBIOS_DATE);
Size = SysInfo.SystemBiosDate(Buffer, BufferSize);
strLine += Size ? (LPCTSTR)Buffer : strUnknown;
PrintLine((LPCTSTR)strLine);
//
// Processor type
//
strLine.LoadString(g_hInstance, IDS_PRINT_PROCESSOR_TYPE);
Size = SysInfo.ProcessorType(Buffer, BufferSize);
strLine += Size ? (LPCTSTR)Buffer : strUnknown;
PrintLine((LPCTSTR)strLine);
//
// Processor vendor
//
strLine.LoadString(g_hInstance, IDS_PRINT_PROCESSOR_VENDOR);
Size = SysInfo.ProcessorVendor(Buffer, BufferSize);
strLine += Size ? (LPCTSTR)Buffer : strUnknown;
PrintLine((LPCTSTR)strLine);
//
// Number of processors
//
strLine.LoadString(g_hInstance, IDS_PRINT_PROCESSORS);
DWORD NumProcessors = SysInfo.NumberOfProcessors();
if (NumProcessors) {
strFormat.Format(TEXT("%u"), NumProcessors);
strLine += strFormat;
} else {
strLine += strUnknown;
}
PrintLine((LPCTSTR)strLine);
//
// Total physical memory
//
ULARGE_INTEGER MemorySize;
SysInfo.TotalPhysicalMemory(MemorySize);
strLine.LoadString(g_hInstance, IDS_PRINT_PHY_MEMORY);
if (MemorySize.QuadPart) {
strFormat.LoadString(g_hInstance, IDS_PRINT_MEMORY_UNIT);
MemorySize.QuadPart += 1024*1024 - 1;
strBuffer.Format((LPCTSTR)strFormat, Int64ShrlMod32(MemorySize.QuadPart, 20));
strLine += strBuffer;
} else {
strLine += strUnknown;
}
PrintLine((LPCTSTR)strLine);
LineFeed();
//
// Local disk drive information
//
// Print Disk info summary heading
//
strBuffer.LoadString(g_hInstance, IDS_PRINT_HEADING_DISKINFO);
strFormat.LoadString(g_hInstance, IDS_PRINT_BANNER);
strLine.Format((LPCTSTR)strFormat, (LPCTSTR)strBuffer);
PrintLine((LPCTSTR)strLine);
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 = (TCHAR)(Drive + _T('A'));
strFormat.LoadString(g_hInstance, IDS_PRINT_DRIVE_LETTER);
strLine.Format((LPCTSTR)strFormat, DriveLetter);
PrintLine((LPCTSTR)strLine);
Indent();
//
// Drive type
//
strFormat.LoadString(g_hInstance, IDS_PRINT_DRIVE_TYPE);
strBuffer.LoadString(g_hInstance, IDS_MEDIA_BASE + (int)DiskInfo.MediaType);
strLine.Format((LPCTSTR)strFormat, (LPCTSTR)strBuffer);
PrintLine((LPCTSTR)strLine);
//
//Total and free space
//
strFormat.LoadString(g_hInstance, IDS_PRINT_TOTAL_SPACE);
strLine.Format((LPCTSTR)strFormat, AddCommas64(DiskInfo.TotalSpace.QuadPart, szTemp, ARRAYLEN(szTemp)));
PrintLine((LPCTSTR)strLine);
if (-1 != DiskInfo.FreeSpace.QuadPart) {
strFormat.LoadString(g_hInstance, IDS_PRINT_FREE_SPACE);
strLine.Format((LPCTSTR)strFormat, AddCommas64(DiskInfo.FreeSpace.QuadPart, szTemp, ARRAYLEN(szTemp)));
PrintLine((LPCTSTR)strLine);
}
//
// Disk physical dimension
// skip CD-ROM because the dimension it reports is bogus
//
if (DRIVE_CDROM != DiskInfo.DriveType) {
//
// Heads
//
strFormat.LoadString(g_hInstance, IDS_PRINT_HEADS);
strLine.Format((LPCTSTR)strFormat, DiskInfo.Heads);
PrintLine((LPCTSTR)strLine);
//
// Cylinders
//
if (DiskInfo.Cylinders.HighPart) {
strFormat.LoadString(g_hInstance, IDS_PRINT_CYLINDERS_XL);
strLine.Format((LPCTSTR)strFormat, DiskInfo.Cylinders.HighPart,
DiskInfo.Cylinders.LowPart);
PrintLine((LPCTSTR)strLine);
} else {
strFormat.LoadString(g_hInstance, IDS_PRINT_CYLINDERS);
strLine.Format((LPCTSTR)strFormat, DiskInfo.Cylinders.LowPart);
PrintLine((LPCTSTR)strLine);
}
//
// Sectors per track
//
strFormat.LoadString(g_hInstance, IDS_PRINT_TRACKSIZE);
strLine.Format((LPCTSTR)strFormat, DiskInfo.SectorsPerTrack);
PrintLine((LPCTSTR)strLine);
//
// Bytes per sector
//
strFormat.LoadString(g_hInstance, IDS_PRINT_SECTORSIZE);
strLine.Format((LPCTSTR)strFormat, DiskInfo.BytesPerSector);
PrintLine((LPCTSTR)strLine);
}
UnIndent();
LineFeed();
}
UnIndent();
}
return 1;
}
int
CPrinter::PrintResourceSummary(
CMachine& Machine
)
{
String strLine;
String str;
String strBanner;
if (Machine.IsLocal()) {
PrintSystemSummary();
}
//
// print IRQ summary heading
//
str.LoadString(g_hInstance, IDS_PRINT_HEADING_IRQSUMMARY);
strBanner.LoadString(g_hInstance, IDS_PRINT_BANNER);
strLine.Format((LPCTSTR)strBanner, (LPCTSTR)str);
PrintLine((LPCTSTR)strLine);
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);
strLine.Format((LPCTSTR)strBanner, (LPCTSTR)str);
PrintLine((LPCTSTR)strLine);
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);
strLine.Format((LPCTSTR)strBanner, (LPCTSTR)str);
PrintLine((LPCTSTR)strLine);
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);
strLine.Format((LPCTSTR)strBanner, (LPCTSTR)str);
PrintLine((LPCTSTR)strLine);
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('*');
StringCchCopy(&Temp[1], (ARRAYLEN(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;
String strLine;
strHeading.LoadString(g_hInstance, IDS_PRINT_HEADING_SYSDEVINFO);
strBanner.LoadString(g_hInstance, IDS_PRINT_BANNER);
strLine.Format((LPCTSTR)strBanner, (LPCTSTR)strHeading);
PrintLine((LPCTSTR)strLine);
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;
String strLine;
strHeading.LoadString(g_hInstance, IDS_PRINT_HEADING_SYSDEVCLASS);
strBanner.LoadString(g_hInstance, IDS_PRINT_BANNER);
strLine.Format((LPCTSTR)strBanner, (LPCTSTR)strHeading);
PrintLine((LPCTSTR)strLine);
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;
String strLine;
if (PrintBanner) {
String strBanner;
str.LoadString(g_hInstance, IDS_PRINT_HEADING_SYSDEVICE);
strBanner.LoadString(g_hInstance, IDS_PRINT_BANNER);
strLine.Format((LPCTSTR)strBanner, (LPCTSTR)str);
PrintLine((LPCTSTR)strLine);
LineFeed();
}
DWORD Status, Problem;
if (pDevice->GetStatus(&Status, &Problem) && Problem ||
pDevice->IsDisabled()) {
strLine.LoadString(g_hInstance, IDS_PRINT_DEVICE_DISABLED);
PrintLine((LPCTSTR)strLine);
}
str.LoadString(g_hInstance, IDS_PRINT_CLASS);
strLine.Format((LPCTSTR)str, pDevice->GetClassDisplayName());
PrintLine((LPCTSTR)strLine);
str.LoadString(g_hInstance, IDS_PRINT_DEVICE);
strLine.Format((LPCTSTR)str, pDevice->GetDisplayName());
PrintLine((LPCTSTR)strLine);
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;
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();
//
// Build up a list of function and filter drivers for this device.
//
pDriver->BuildDriverList();
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;
}