2025-04-27 07:49:33 -04:00

291 lines
5.5 KiB
C++

#include <windows.h>
#include <stdio.h>
#include <stdlib.h>
#include "tigtypes.h"
#include "baseheap.h"
VOID
WINAPI
ShowUsage (
VOID
);
VOID
WINAPI
ParseSwitch (
CHAR chSwitch,
int *pArgc,
char **pArgv[]
);
ARTICLEID
ArticleIdMapper(
ARTICLEID dw
);
DWORD
ByteSwapper(
DWORD dw
);
BOOL fScanNws = FALSE;
CHAR szDir [MAX_PATH+1];
int _cdecl
main (
int argc,
char *argv[],
char *envp[]
)
{
char chChar, *pchChar;
BOOL fRet = TRUE;
char szFile[ MAX_PATH ];
int cbString = 0 ;
szFile[0] = '\0' ;
// defaults
lstrcpy( szDir, "c:\\winnt\\system32" );
while (--argc)
{
pchChar = *++argv;
if (*pchChar == '/' || *pchChar == '-')
{
while (chChar = *++pchChar)
{
ParseSwitch (chChar, &argc, &argv);
}
}
}
if( fScanNws ) {
//
// Build a heap of NWS files
//
cbString = wsprintf( szFile, "%s\\*.nws", szDir );
printf("heaptst will scan NWS files in dir %s and build a heap of such files\n", szDir );
CArticleHeap ArtHeap;
ArtHeap.ForgetAll();
//
// Scan files in specified dir to build a heap
//
if( szFile[0] != '\0' )
{
WIN32_FIND_DATA FileStats;
HANDLE hFind = FindFirstFile( szFile, &FileStats );
if ( INVALID_HANDLE_VALUE != hFind )
{
do
{
printf("Scanning file %s\n", FileStats.cFileName );
ArtHeap.Insert( FileStats.ftLastWriteTime, 1, 1, FileStats.nFileSizeLow );
} while ( FindNextFile( hFind, &FileStats ) );
FindClose( hFind );
}
}
//
// Dump the heap
//
FILETIME ft;
SYSTEMTIME st;
GROUPID GroupId;
ARTICLEID ArticleId;
DWORD ArticleSize;
while ( ArtHeap.ExtractOldest( ft, GroupId, ArticleId, ArticleSize ) )
{
FileTimeToSystemTime( (const FILETIME*)&ft, &st );
printf("File size is %d SystemTime is %d::%d::%d\n", ArticleSize, st.wMonth, st.wDay, st.wYear );
}
if( ArtHeap.isEmpty() ) {
printf("NWS Heap is empty\n");
}
}
//
// Build a heap of XIX files
//
cbString = wsprintf( szFile, "%s\\*.xix", szDir );
printf("heaptst will scan XIX files in dir %s and build a heap of such files\n", szDir );
CXIXHeap XixHeap;
XixHeap.ForgetAll();
//
// Scan files in specified dir to build a heap
//
if( szFile[0] != '\0' )
{
WIN32_FIND_DATA FileStats;
HANDLE hFind = FindFirstFile( szFile, &FileStats );
if ( INVALID_HANDLE_VALUE != hFind )
{
do
{
printf("Scanning file %s\n", FileStats.cFileName );
ARTICLEID iArticleIdBase;
PCHAR p=strtok(FileStats.cFileName,".");
if ( p == NULL ) {
printf("Cannot get article ID base number from %s",FileStats.cFileName);
continue;
}
if( sscanf( p, "%x", &iArticleIdBase ) != 1 )
continue ;
iArticleIdBase = ArticleIdMapper( iArticleIdBase ) ;
XixHeap.Insert( FileStats.ftCreationTime, 1, iArticleIdBase );
} while ( FindNextFile( hFind, &FileStats ) );
FindClose( hFind );
}
}
//
// Dump the heap
//
FILETIME ft;
SYSTEMTIME st;
GROUPID GroupId;
ARTICLEID ArticleIdBase;
while ( XixHeap.ExtractOldest( ft, GroupId, ArticleIdBase ) )
{
FileTimeToSystemTime( (const FILETIME*)&ft, &st );
printf("ArticleIdBase is %d SystemTime is %d::%d::%d\n", ArticleIdBase, st.wMonth, st.wDay, st.wYear );
}
if( XixHeap.isEmpty() ) {
printf("XIX Heap is empty\n");
}
return 1;
}
VOID
WINAPI
ShowUsage (
VOID
)
{
fputs ("usage: heaptst [switches]\n"
" [-?] show this message\n"
" [-n] scan NWS\n"
" [-d] directory \n"
,stderr);
exit (1);
}
VOID
WINAPI
ParseSwitch (
CHAR chSwitch,
int *pArgc,
char **pArgv[]
)
{
switch (toupper (chSwitch))
{
case '?':
ShowUsage ();
break;
case 'N':
fScanNws = TRUE;
break;
case 'D':
if (!--(*pArgc))
{
ShowUsage ();
}
(*pArgv)++;
lstrcpy( szDir, *(*pArgv) );
break;
default:
fprintf (stderr, "heaptst: Invalid switch - /%c\n", chSwitch);
ShowUsage ();
break;
}
}
DWORD
ByteSwapper(
DWORD dw
) {
/*++
Routine Description :
Given a DWORD reorder all the bytes within the DWORD.
Arguments :
dw - DWORD to shuffle
Return Value ;
Shuffled DWORD
--*/
WORD w = LOWORD( dw ) ;
BYTE lwlb = LOBYTE( w ) ;
BYTE lwhb = HIBYTE( w ) ;
w = HIWORD( dw ) ;
BYTE hwlb = LOBYTE( w ) ;
BYTE hwhb = HIBYTE( w ) ;
return MAKELONG( MAKEWORD( hwhb, hwlb ), MAKEWORD( lwhb, lwlb ) ) ;
}
ARTICLEID
ArticleIdMapper(
ARTICLEID dw
) {
/*++
Routine Description :
Given an articleid mess with the id to get something that when
converted to a string will build nice even B-trees on NTFS file systems.
At the same time, the function must be easily reversible.
In fact -
ARTICLEID == ArticleMapper( ArticleMapper( ARTICLEID ) )
Arguments :
articleId - the Article Id to mess with
Return Value :
A new article id
--*/
return ByteSwapper( dw ) ;
}