windows-nt/Source/XPSP1/NT/admin/pchealth/sr/nttest/srdiag2/fileinfo.cxx
2020-09-26 16:20:57 +08:00

345 lines
9.7 KiB
C++

/******************************************************************************
*
* Copyright (c) 2000 Microsoft Corporation
*
* Module Name:
* FileInfo.cxx
*
* Abstract:
* Tool for getting file information
*
* Revision History:
*
* Weiyou Cui (weiyouc) 02-May-2001
* - Created
*
*****************************************************************************/
#include "srheader.hxx"
//+---------------------------------------------------------------------------
//
// Function prototypes
//
//----------------------------------------------------------------------------
HRESULT InfoPerFile(LPTSTR ptszLogFile, LPTSTR ptszFileName);
//+---------------------------------------------------------------------------
//
// Some global structures and variables
//
//----------------------------------------------------------------------------
struct LANGANDCODEPAGE {
WORD wLanguage;
WORD wCodePage;
} *lpTranslate;
LPCTSTR g_tszFileVersionList[] =
{
TEXT("\\system32\\drivers\\sr.sys"),
TEXT("\\system32\\srclient.dll"),
TEXT("\\system32\\srsvc.dll"),
TEXT("\\system32\\srrstr.dll"),
TEXT("\\system32\\restore\\filelist.xml"),
TEXT("\\system32\\restore\\rstrui.exe"),
TEXT("\\system32\\restore\\srframe.mmf"),
TEXT("\\system32\\restore\\sr.mof"),
};
LPCTSTR g_tszVersionResource[] =
{
TEXT("Comments"),
TEXT("CompanyName"),
TEXT("FileDescription"),
TEXT("FileVersion"),
TEXT("InternalName"),
TEXT("LegalCopyright"),
TEXT("LegalTrademarks"),
TEXT("OriginalFilename"),
TEXT("ProductName"),
TEXT("ProductVersion"),
TEXT("PrivateBuild"),
TEXT("SpecialBuild"),
};
extern LPCTSTR g_tszMonth[];
extern LPCTSTR g_tszDay[];
//+---------------------------------------------------------------------------
//
// Function: SRGetFileInfo
//
// Synopsis: This is the wrapper function for InfoPerFile, where I will assemble
// the file path for each of the relevant files that we need to get
// file statistics.
//
// Arguments: [ptszLogFile] -- log file name
//
// Returns: HRESULT
//
// History: 9/21/00 SHeffner Created
//
// 03-May-2001 Weiyouc ReWritten
//
//----------------------------------------------------------------------------
HRESULT GetSRFileInfo(LPTSTR ptszLogFile)
{
HRESULT hr = S_OK;
int iCount = 0;
TCHAR tszFileName[MAX_PATH];
DH_VDATEPTRIN(ptszLogFile, TCHAR);
for (iCount = 0; iCount < ARRAYSIZE(g_tszFileVersionList); iCount++)
{
//
// Assemble the path, since I just have the relative path from windir
//
_tcscpy(tszFileName, _tgetenv(TEXT("WINDIR")));
_tcscat(tszFileName, g_tszFileVersionList[iCount]);
//
// Call function to do the work since we have full path
//
hr = InfoPerFile(ptszLogFile, tszFileName);
DH_HRCHECK_ABORT(hr, TEXT("InfoPerFile"));
}
ErrReturn:
return hr;
}
//+---------------------------------------------------------------------------
//
// Function: InfoPerFile
//
// Synopsis: This function takes the log file path, and the filename,
// and then will put out the relevant information from the
// file to be logged.
//
//
// Arguments: [ptszLogFile] -- Log file name
// [ptszFileName] -- File to be examined
//
// Returns: HRESULT
//
// History: 9/21/00 SHeffner Created
//
// 03-May-2001 WeiyouC ReWritten
//
//----------------------------------------------------------------------------
HRESULT InfoPerFile(LPTSTR ptszLogFile, LPTSTR ptszFileName)
{
HRESULT hr = S_OK;
HANDLE hFile = INVALID_HANDLE_VALUE;
FILE* fpLog = NULL;
void* pvBuf = NULL;
UINT uLen = 0;;
DWORD dwSize = 0;
DWORD dwResult = 0;
DWORD i = 0;;
TCHAR szString[MAX_PATH];
BY_HANDLE_FILE_INFORMATION FileInfo;
SYSTEMTIME SysTime;
VS_FIXEDFILEINFO FixedFileInfo;
DH_VDATEPTRIN(ptszLogFile, TCHAR);
DH_VDATEPTRIN(ptszFileName, TCHAR);
//
// Open up our log file, and log the file we are processing
//
fpLog = _tfopen(ptszLogFile, TEXT("a"));
DH_ABORTIF(NULL == fpLog,
E_FAIL,
TEXT("a"));
fprintf(fpLog, "\n%S\n", ptszFileName);
//
// Open up the file so that we can get the information from the handle
// If we are unable to do this we will just log the generic not
// able to find file.
//
hFile = CreateFile(ptszFileName,
GENERIC_READ,
FILE_SHARE_READ,
NULL,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
NULL);
if (INVALID_HANDLE_VALUE != hFile)
{
if (FALSE != GetFileInformationByHandle(hFile, &FileInfo))
{
//
// Get file creation time
//
FileTimeToSystemTime(&FileInfo.ftCreationTime, &SysTime);
fprintf(fpLog,
"\tCreation Date=%S %S %lu, %lu %lu:%lu:%lu\n",
g_tszDay[SysTime.wDayOfWeek],
g_tszMonth[SysTime.wMonth - 1],
SysTime.wDay,
SysTime.wYear,
SysTime.wHour,
SysTime.wMinute,
SysTime.wSecond);
//
// Get file last access time
//
FileTimeToSystemTime(&FileInfo.ftLastAccessTime, &SysTime);
fprintf(fpLog,
"\tLast Access Date=%S %S %lu, %lu %lu:%lu:%lu\n",
g_tszDay[SysTime.wDayOfWeek],
g_tszMonth[SysTime.wMonth - 1],
SysTime.wDay,
SysTime.wYear,
SysTime.wHour,
SysTime.wMinute,
SysTime.wSecond);
//
// Get file last write time
//
FileTimeToSystemTime(&FileInfo.ftLastWriteTime, &SysTime);
fprintf(fpLog,
"\tLast Write Date=%S %S %lu, %lu %lu:%lu:%lu\n",
g_tszDay[SysTime.wDayOfWeek],
g_tszMonth[SysTime.wMonth - 1],
SysTime.wDay,
SysTime.wYear,
SysTime.wHour,
SysTime.wMinute,
SysTime.wSecond);
//
// Get file attributes
//
_tcscpy(szString, FileInfo.dwFileAttributes & FILE_ATTRIBUTE_ARCHIVE ? TEXT("ARCHIVE ") : TEXT(""));
_tcscat(szString, FileInfo.dwFileAttributes & FILE_ATTRIBUTE_COMPRESSED ? TEXT("COMPRESSED ") : TEXT(""));
_tcscat(szString, FileInfo.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY ? TEXT("DIRECTORY ") : TEXT(""));
_tcscat(szString, FileInfo.dwFileAttributes & FILE_ATTRIBUTE_ENCRYPTED ? TEXT("ENCRYPTED ") : TEXT(""));
_tcscat(szString, FileInfo.dwFileAttributes & FILE_ATTRIBUTE_HIDDEN ? TEXT("HIDDEN ") : TEXT(""));
_tcscat(szString, FileInfo.dwFileAttributes & FILE_ATTRIBUTE_NORMAL ? TEXT("NORMAL ") : TEXT(""));
_tcscat(szString, FileInfo.dwFileAttributes & FILE_ATTRIBUTE_OFFLINE ? TEXT("OFFLINE ") : TEXT(""));
_tcscat(szString, FileInfo.dwFileAttributes & FILE_ATTRIBUTE_READONLY ? TEXT("READONLY ") : TEXT(""));
_tcscat(szString, FileInfo.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT ? TEXT("REPARSE_POINT ") : TEXT(""));
_tcscat(szString, FileInfo.dwFileAttributes & FILE_ATTRIBUTE_SPARSE_FILE ? TEXT("SPARSE_FILE ") : TEXT(""));
_tcscat(szString, FileInfo.dwFileAttributes & FILE_ATTRIBUTE_SYSTEM ? TEXT("SYSTEM ") : TEXT(""));
_tcscat(szString, FileInfo.dwFileAttributes & FILE_ATTRIBUTE_TEMPORARY ? TEXT("TEMPORARY ") : TEXT(""));
fprintf(fpLog, "\tAttributes=%S\n", szString);
//
// Get the VolumeSerialNumber, FileSize, and Number of Links
//
fprintf(fpLog,
"\tVolumeSerialNumber=%lu\n",
FileInfo.dwVolumeSerialNumber);
fprintf(fpLog,
"\tFileSize=%lu%lu\n",
FileInfo.nFileSizeHigh,
FileInfo.nFileSizeLow);
fprintf(fpLog,
"\tNumberOfLinks=%lu\n",
FileInfo.nNumberOfLinks);
dwSize = GetFileVersionInfoSize(ptszFileName, &dwResult);
if (0 != dwSize)
{
pvBuf = malloc(dwSize);
DH_ABORTIF(NULL == pvBuf,
E_OUTOFMEMORY,
TEXT("malloc"));
GetFileVersionInfo(ptszFileName,
dwResult,
dwSize,
(LPVOID) pvBuf);
//
// Read the list of languages and code pages.
//
VerQueryValue(pvBuf,
TEXT("\\VarFileInfo\\Translation"),
(LPVOID*)&lpTranslate,
&uLen);
//
// Read the Version info for each language and code page.
//
for (i=0; i < (uLen / sizeof(struct LANGANDCODEPAGE)); i++ )
{
char* lpBuffer;
DWORD dwBytes, dwCount = 0;
fprintf(fpLog,
"\tLanguage=%x%x\n",
lpTranslate[i].wLanguage,
lpTranslate[i].wCodePage);
for (dwCount = 0; dwCount < ARRAYSIZE(g_tszVersionResource); dwCount++)
{
//
// Generate the string, for getting the resource
// based on the language, then retrieve this, and
// then put it to the log file.
//
_stprintf(szString,
TEXT("\\StringFileInfo\\%04x%04x\\%s"),
lpTranslate[i].wLanguage,
lpTranslate[i].wCodePage,
g_tszVersionResource[dwCount]);
VerQueryValue(pvBuf,
szString,
(LPVOID *) &lpBuffer,
&uLen);
if (0 != uLen)
{
fprintf(fpLog,
"\t%S=%S\n",
g_tszVersionResource[dwCount],
lpBuffer);
}
} //While loop end, for each resource
} //for loop end for each language
} //If check for getting the fileversioninfosize
} //if check for GetFileInformationByHandle on the file
} //if check on can I open this file
ErrReturn:
if (INVALID_HANDLE_VALUE != hFile)
{
CloseHandle(hFile);
hFile = INVALID_HANDLE_VALUE;
}
if (NULL != fpLog)
{
fclose(fpLog);
}
if (NULL != pvBuf)
{
free(pvBuf);
}
return hr;
}