Note
Access to this page requires authorization. You can try signing in or changing directories.
Access to this page requires authorization. You can try changing directories.
This topic shows how to enumerate log containers.
Sample Code
The following example shows how to:
- Open a log
- Retrieve the log file information
- Initialize the context
- Scan log containers
// LogInfo.cpp : Defines the entry point for the console application.
//
#ifndef UNICODE
#define UNICODE
#endif
#include <windows.h>
#include <wchar.h>
#include <iostream>
#include <iomanip>
#include <clfsw32.h>
#include <Clfsmgmtw32.h>
#pragma comment(lib, "Clfsw32.lib")
using std::wcout;
using std::cout;
using std::cerr;
using std::endl;
using std::hex;
using std::dec;
using std::setw;
using std::left;
const unsigned long MAX_SCAN_CONTAINERS = 1;
void usage(wchar_t cmd[])
{
wcout << "Usage: " << cmd << " <LogFileName>" << endl << endl
<< " LogFileName: The relative or absolute path to " << endl
<< "the physical log file" << endl
<< " NOTE: do not add the .BLF extension" << endl;
exit(-1);
}
void ErrorExit(const char* id)
{
DWORD errNum = GetLastError();
cerr << "Encountered unexpected error from " << id
<< ": " << errNum << endl;
exit (errNum);
}
std::wostream&
operator << (std::wostream& ostr, const GUID &g)
{
ostr << "["
<< hex << g.Data1 << "-"
<< hex << g.Data2 << "-"
<< hex << g.Data3 << "-"
<< hex << (DWORD)g.Data4 << "]" << dec << endl;
return ostr;
}
std::wostream&
operator << (std::wostream& ostr, const CLFS_LSN &lsn)
{
ostr << "["
<< LsnContainer(&lsn) << ":"
<< LsnBlockOffset(&lsn) << ":"
<< LsnRecordSequence(&lsn) << "]";
return ostr;
}
std::wostream&
operator << (std::wostream& ostr, const CLFS_INFORMATION &logInfo)
{
ostr << left << setw(35) << "Total Space Available: "
<< logInfo.TotalAvailable << endl;
ostr << left << setw(35) << "Current Available: "
<< logInfo.CurrentAvailable << endl;
ostr << left << setw(35) << "Total Reserved: "
<< logInfo.TotalReservation << endl;
ostr << left << setw(35) << "BLF filesize: "
<< logInfo.BaseFileSize << endl;
ostr << left << setw(35) << "Container Size: "
<< logInfo.ContainerSize << endl;
ostr << left << setw(35) << "Number of containers: "
<< logInfo.TotalContainers << endl;
// Specifies the number of containers not in active log.
ostr << left << setw(35) << "Number of free containers: "
<< logInfo.FreeContainers << endl;
ostr << left << setw(35) << "Number of managed clients: "
<< logInfo.TotalClients << endl;
ostr << left << setw(35) << "Log Attributes: ";
if (logInfo.Attributes & FILE_ATTRIBUTE_ARCHIVE)
ostr << "Non-Ephemeral";
else ostr << "Ephemeral";
if (logInfo.Attributes & FILE_ATTRIBUTE_DEDICATED)
ostr << "; Dedicated";
else ostr << "; Multiplexed";
if (logInfo.Attributes & FILE_ATTRIBUTE_READONLY)
ostr << "; ReadOnly";
else ostr << "; Modifiable";
if (logInfo.Attributes & FILE_ATTRIBUTE_SYSTEM)
ostr << "; System"; // Vista
if (logInfo.Attributes & FILE_ATTRIBUTE_HIDDEN)
ostr << "; Hidden"; // Vista
ostr << endl;
ostr << left << setw(35) << "Flush threshold: "
<< logInfo.FlushThreshold << endl;
ostr << left << setw(35) << "Sector size: "
<< logInfo.SectorSize << endl;
ostr << left << setw(35) << "Archive Tail LSN: "
<< logInfo.MinArchiveTailLsn << endl;
ostr << left << setw(35) << "Base LSN: " << logInfo.BaseLsn
<< endl;
ostr << left << setw(35) << "Last flushed LSN: "
<< logInfo.LastFlushedLsn << endl;
ostr << left << setw(35) << "Last LSN in Active Region: "
<< logInfo.LastLsn << endl;
ostr << left << setw(35) << "LSN of the latest restart record: "
<< logInfo.RestartLsn << endl;
ostr << left << setw(35) << "Log GUID: " << logInfo.Identity;
return ostr;
}
std::wostream&
operator << (std::wostream& ostr, const FILETIME* fileTime)
{
static const int DATE_BUFSIZE = 60;
wchar_t buffer[60];
FILETIME localTime;
if (!FileTimeToLocalFileTime(fileTime, &localTime))
ErrorExit("FileTimeToLocalTime");
SYSTEMTIME sysTime;
if (!FileTimeToSystemTime(&localTime, &sysTime))
ErrorExit("FileTimeToSystemTime");
GetDateFormat(LOCALE_USER_DEFAULT,
DATE_LONGDATE,
&sysTime,
NULL,
buffer,
DATE_BUFSIZE);
ostr << buffer;
GetTimeFormat(LOCALE_USER_DEFAULT,
LOCALE_NOUSEROVERRIDE,
&sysTime,
NULL,
buffer,
DATE_BUFSIZE);
ostr << " " << buffer;
return ostr;
}
std::wostream&
operator << (std::wostream& ostr,
const CLFS_CONTAINER_INFORMATION &cInfo)
{
// File Attributes
ostr << setw(25) << "ContainerLogicalId: "
<< cInfo.LogicalContainerId << endl;
ostr << setw(25) << "ContainerPhyscialId: "
<< cInfo.PhysicalContainerId << endl;
ostr << setw(25) << "ContainerPath: " << cInfo.FileName << endl;
ostr << setw(25) << "ContainerSize: " << cInfo.ContainerSize
<< endl;
ostr << setw(25) << "CreationTime: "
<< (FILETIME*)&cInfo.CreationTime << endl;
ostr << setw(25) << "LastAccessTime: " <<
(FILETIME*)&cInfo.LastAccessTime << endl;
ostr << setw(25) << "LastWriteTime: "
<< (FILETIME*)&cInfo.LastWriteTime << endl;
ostr << setw(25) << "State: ";
switch (cInfo.State)
{
case ClfsContainerInitializing: ostr
<< "Initializing"; break;
case ClfsContainerInactive: ostr
<< "Inactive"; break;
case ClfsContainerActive: ostr
<< "Active"; break;
case ClfsContainerActivePendingDelete: ostr
<< "Active Pending Delete"; break;
case ClfsContainerPendingArchive: ostr
<< "Pending Archive"; break;
case ClfsContainerPendingArchiveAndDelete: ostr
<< "Pending Archive and Delete"; break;
default: ostr
<< "Unknown"; break;
}
return ostr;
}
int wmain(int argc, wchar_t* argv[])
{
// Check arguments
if (argc != 2)
usage(argv[0]);
// Open log file
std::wstring logFileName = L"LOG:";
std::wstring inputName = argv[1];
logFileName += inputName;
HANDLE logHndl = CreateLogFile(logFileName.c_str(),
GENERIC_READ, FILE_SHARE_READ |
FILE_SHARE_WRITE |FILE_SHARE_DELETE,
NULL,
OPEN_EXISTING,
0 );
if (logHndl == INVALID_HANDLE_VALUE)
ErrorExit("CreateLogFile");
// Retrieve log info
CLFS_INFORMATION logInfo;
ULONG infoSize = sizeof(logInfo);
if (!GetLogFileInformation(logHndl, &logInfo, &infoSize))
ErrorExit("GetLogFileInformation");
wcout << logInfo << endl;
// Create the container list
// Initialize the context structures
CLFS_SCAN_CONTEXT ctx;
if (!CreateLogContainerScanContext(logHndl,
0,
MAX_SCAN_CONTAINERS,
CLFS_SCAN_FORWARD,
&ctx,
NULL))
if (GetLastError() != ERROR_NO_MORE_ITEMS)
ErrorExit("CreateLogContainerScanContext");
// The first scan was made by create
for (unsigned int i = 0; i < ctx.cContainersReturned; ++i)
wcout << ctx.pinfoContainer[i] << endl << endl;
// Continue to scan
while (GetLastError() != ERROR_NO_MORE_ITEMS)
{
if (!ScanLogContainers(&ctx, CLFS_SCAN_FORWARD, NULL))
{
if (GetLastError() != ERROR_NO_MORE_ITEMS)
ErrorExit("ScanLogContainers");
}
for (unsigned int i = 0; i < ctx.cContainersReturned; ++i)
wcout << ctx.pinfoContainer[i] << endl << endl;
}
return 0;
}