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.
 
 
 
 
 
 

479 lines
14 KiB

//+------------------------------------------------------------------------
//
// Microsoft Windows
// Copyright (C) Microsoft Corporation, 1993 - 1993
//
// File: tstgdir.cpp
//
// Contents: Recursive directory display of a storage
// document
//
// Functions: main
//
// History: 04 Nov 94 - Created by philh
//
//-------------------------------------------------------------------------
#include <windows.h>
#include <assert.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <memory.h>
#include <time.h>
static int indent = 0;
static BOOL fVerbose = FALSE;
static BOOL fDebug = FALSE;
static BOOL fRead = FALSE;
static BOOL fReadVerbose = FALSE;
static BOOL fBrief = FALSE;
#define READ_BUF_SIZE 10000
static BYTE readBuf[READ_BUF_SIZE];
static CLSID NullClsid;
typedef struct
{
SCODE sc;
char *text;
} StatusCodeText;
static StatusCodeText scodes[] =
{
S_OK, "S_OK",
S_FALSE, "S_FALSE",
STG_E_INVALIDFUNCTION, "STG_E_INVALIDFUNCTION",
STG_E_FILENOTFOUND, "STG_E_FILENOTFOUND",
STG_E_PATHNOTFOUND, "STG_E_PATHNOTFOUND",
STG_E_TOOMANYOPENFILES, "STG_E_TOOMANYOPENFILES",
STG_E_ACCESSDENIED, "STG_E_ACCESSDENIED",
STG_E_INVALIDHANDLE, "STG_E_INVALIDHANDLE",
STG_E_INSUFFICIENTMEMORY, "STG_E_INSUFFICIENTMEMORY",
STG_E_INVALIDPOINTER, "STG_E_INVALIDPOINTER",
STG_E_NOMOREFILES, "STG_E_NOMOREFILES",
STG_E_DISKISWRITEPROTECTED, "STG_E_DISKISWRITEPROTECTED",
STG_E_SEEKERROR, "STG_E_SEEKERROR",
STG_E_WRITEFAULT, "STG_E_WRITEFAULT",
STG_E_READFAULT, "STG_E_READFAULT",
STG_E_SHAREVIOLATION, "STG_E_SHAREVIOLATION",
STG_E_LOCKVIOLATION, "STG_E_LOCKVIOLATION",
STG_E_FILEALREADYEXISTS, "STG_E_FILEALREADYEXISTS",
STG_E_INVALIDPARAMETER, "STG_E_INVALIDPARAMETER",
STG_E_MEDIUMFULL, "STG_E_MEDIUMFULL",
STG_E_ABNORMALAPIEXIT, "STG_E_ABNORMALAPIEXIT",
STG_E_INVALIDHEADER, "STG_E_INVALIDHEADER",
STG_E_INVALIDNAME, "STG_E_INVALIDNAME",
STG_E_UNKNOWN, "STG_E_UNKNOWN",
STG_E_UNIMPLEMENTEDFUNCTION, "STG_E_UNIMPLEMENTEDFUNCTION",
STG_E_INVALIDFLAG, "STG_E_INVALIDFLAG",
STG_E_INUSE, "STG_E_INUSE",
STG_E_NOTCURRENT, "STG_E_NOTCURRENT",
STG_E_REVERTED, "STG_E_REVERTED",
STG_E_CANTSAVE, "STG_E_CANTSAVE",
STG_E_OLDFORMAT, "STG_E_OLDFORMAT",
STG_E_OLDDLL, "STG_E_OLDDLL",
STG_E_SHAREREQUIRED, "STG_E_SHAREREQUIRED",
STG_E_NOTFILEBASEDSTORAGE, "STG_E_NOTFILEBASEDSTORAGE",
STG_E_EXTANTMARSHALLINGS, "STG_E_EXTANTMARSHALLINGS",
E_NOINTERFACE, "E_NOINTERFACE",
STG_S_CONVERTED, "STG_S_CONVERTED"
};
#define NSCODETEXT (sizeof(scodes)/sizeof(scodes[0]))
// Convert a HRESULT to text
static char *hResultText(HRESULT hResult)
{
static char buf[80];
int i;
for (i = 0; i<NSCODETEXT; i++)
if (scodes[i].sc == hResult)
return scodes[i].text;
sprintf(buf, "%lx", hResult);
return buf;
}
static void DirPrintf(const char * Format, ...)
{
int i = indent;
va_list pArgs;
char aBuf[256];
while (i-- > 0)
printf(" ");
va_start( pArgs, Format );
vsprintf(aBuf, Format, pArgs);
printf("%s", aBuf);
}
#pragma pack(1)
struct SplitGuid
{
DWORD dw1;
WORD w1;
WORD w2;
BYTE b[8];
};
#pragma pack()
static char *GuidText(GUID *pguid)
{
static char buf[39];
SplitGuid *psg = (SplitGuid *)pguid;
sprintf(buf, "{%08lX-%04hX-%04hX-%02X%02X-%02X%02X%02X%02X%02X%02X}",
psg->dw1, psg->w1, psg->w2, psg->b[0], psg->b[1], psg->b[2],
psg->b[3], psg->b[4], psg->b[5], psg->b[6], psg->b[7]);
return buf;
}
static char *FileTimeText(FILETIME *pft)
{
static char buf[80];
FILETIME ftLocal;
struct tm ctm;
SYSTEMTIME st;
FileTimeToLocalFileTime(pft, &ftLocal);
if (FileTimeToSystemTime(&ftLocal, &st))
{
ctm.tm_sec = st.wSecond;
ctm.tm_min = st.wMinute;
ctm.tm_hour = st.wHour;
ctm.tm_mday = st.wDay;
ctm.tm_mon = st.wMonth-1;
ctm.tm_year = st.wYear-1900;
ctm.tm_wday = st.wDayOfWeek;
ctm.tm_yday = 0;
ctm.tm_isdst = 0;
strcpy(buf, asctime(&ctm));
buf[strlen(buf)-1] = 0;
}
else
sprintf(buf, "<FILETIME %08lX:%08lX>", pft->dwHighDateTime,
pft->dwLowDateTime);
return buf;
}
static void DispStatStg(STATSTG *pStatStg)
{
char *szSTGTY;
switch (pStatStg->type) {
case STGTY_STORAGE:
szSTGTY = "STGTY_STORAGE";
break;
case STGTY_STREAM:
szSTGTY = "STGTY_STREAM";
break;
case STGTY_LOCKBYTES:
szSTGTY = "STGTY_LOCKBYTES";
break;
default:
szSTGTY = "STGTY_???";
}
if (pStatStg->type == STGTY_STREAM)
DirPrintf("%S %s size:%ld\n", pStatStg->pwcsName, szSTGTY,
pStatStg->cbSize.LowPart);
else {
DirPrintf("%S %s\n", pStatStg->pwcsName, szSTGTY);
if (!fBrief && pStatStg->clsid != NullClsid)
DirPrintf("CLSID: %s\n", GuidText(&pStatStg->clsid));
}
if (fVerbose) {
DirPrintf("size: %ld,%ld Mode: %lx StateBits: %lx Locks: %ld\n",
pStatStg->cbSize.HighPart, pStatStg->cbSize.LowPart,
pStatStg->grfMode, pStatStg->grfStateBits,
pStatStg->grfLocksSupported);
if ((pStatStg->mtime.dwHighDateTime != 0) ||
(pStatStg->mtime.dwLowDateTime != 0))
DirPrintf("mtime %s\n", FileTimeText(&pStatStg->mtime));
if ((pStatStg->ctime.dwHighDateTime != 0) ||
(pStatStg->ctime.dwLowDateTime != 0))
DirPrintf("ctime %s\n", FileTimeText(&pStatStg->ctime));
if ((pStatStg->atime.dwHighDateTime != 0) ||
(pStatStg->atime.dwLowDateTime != 0))
DirPrintf("atime %s\n", FileTimeText(&pStatStg->atime));
}
}
#define CROW 16
void BinText(ULONG cbSize, BYTE *pb)
{
ULONG cb, i;
while (cbSize > 0)
{
cb = min(CROW, cbSize);
cbSize -= cb;
for (i = 0; i<cb; i++)
printf(" %02X", pb[i]);
for (i = cb; i<CROW; i++)
printf(" ");
printf(" '");
for (i = 0; i<cb; i++)
if (pb[i] >= 0x20 && pb[i] <= 0x7f)
printf("%c", pb[i]);
else
printf(".");
pb += cb;
printf("'\n");
}
}
void DispStream(IStream *pstm);
void DispStorage(IStorage *pstg);
void DispStream(IStream *pstm)
{
HRESULT hResult;
STATSTG statStg;
hResult = pstm->Stat(&statStg, STATFLAG_DEFAULT);
if (SUCCEEDED(hResult)) {
DispStatStg(&statStg);
if (statStg.pwcsName != NULL)
CoTaskMemFree(statStg.pwcsName);
} else {
DirPrintf("Stat => %lx\n", hResult);
return;
}
if (fRead) {
ULONG ulTotalRead = 0;
ULONG ulBytesRead;
int i = 0;
while (TRUE) {
ulBytesRead = 0;
hResult = pstm->Read(readBuf, READ_BUF_SIZE, &ulBytesRead);
if (FAILED(hResult)) {
DirPrintf("IStream->Read => %lx\n", hResult);
break;
}
if (fReadVerbose) {
DirPrintf("%lu bytes starting at offset: 0x%08lX\n",
ulBytesRead, ulTotalRead);
BinText(ulBytesRead, readBuf);
}
ulTotalRead += ulBytesRead;
if (ulBytesRead < READ_BUF_SIZE)
break;
i++;
if (i % 10 == 0) {
if (fReadVerbose)
DirPrintf("Read %ld bytes\n", ulTotalRead);
else
DirPrintf("Read %ld bytes\r", ulTotalRead);
}
}
DirPrintf("Read %ld bytes\n", ulTotalRead);
}
}
void DispStorage(IStorage *pstg)
{
HRESULT hResult;
DWORD grfMode;
STATSTG statStg;
CLSID readClsid;
IStorage *pstgChild;
IStream *pstmChild;
IEnumSTATSTG *penumStatStg;
hResult = pstg->Stat(&statStg, STATFLAG_DEFAULT);
if (SUCCEEDED(hResult)) {
DispStatStg(&statStg);
if (statStg.pwcsName != NULL)
CoTaskMemFree(statStg.pwcsName);
} else {
DirPrintf("Stat => %s\n", hResultText(hResult));
return;
}
hResult = ReadClassStg(pstg, &readClsid);
if (SUCCEEDED(hResult)) {
if (readClsid != statStg.clsid)
DirPrintf("ReadClassStg CLSID: %s\n", GuidText(&readClsid));
} else
DirPrintf("ReadClassStg => %s\n", hResultText(hResult));
indent += 2;
hResult = pstg->EnumElements(0, NULL, 0, &penumStatStg);
if (FAILED(hResult))
DirPrintf("EnumElements => %lx\n", hResult);
else {
while(TRUE) {
hResult = penumStatStg->Next(1, &statStg, NULL);
if (hResult == S_FALSE) break;
if (FAILED(hResult)) {
DirPrintf("EnumStatStg => %lx\n", hResult);
break;
} else {
switch (statStg.type) {
case STGTY_STORAGE:
if ((statStg.pwcsName == NULL) ||
(statStg.pwcsName[0] == L'.'))
DispStatStg(&statStg);
else {
grfMode =
STGM_DIRECT | STGM_READ | STGM_SHARE_EXCLUSIVE;
hResult = pstg->OpenStorage(
statStg.pwcsName,
NULL, // pstgPriority
grfMode,
NULL, // snbExclude
0, // dwReserved
&pstgChild);
if (FAILED(hResult)) {
DispStatStg(&statStg);
DirPrintf("OpenStorage => %lx\n", hResult);
} else {
if (fDebug) {
DirPrintf("--- Enum ---\n");
DispStatStg(&statStg);
DirPrintf("--- Enum ---\n");
}
DispStorage(pstgChild);
pstgChild->Release();
}
}
break;
case STGTY_STREAM:
if ((statStg.pwcsName == NULL) ||
(statStg.pwcsName[0] == L'.'))
DispStatStg(&statStg);
else {
grfMode =
STGM_DIRECT | STGM_READ | STGM_SHARE_EXCLUSIVE;
hResult = pstg->OpenStream(
statStg.pwcsName,
NULL, // pReserved1
grfMode,
0, // dwReserved2
&pstmChild);
if (FAILED(hResult)) {
DispStatStg(&statStg);
DirPrintf("OpenStream => %lx\n", hResult);
} else {
if (fDebug) {
DirPrintf("--- Enum ---\n");
DispStatStg(&statStg);
DirPrintf("--- Enum ---\n");
}
DispStream(pstmChild);
pstmChild->Release();
}
}
break;
default:
DispStatStg(&statStg);
}
if (statStg.pwcsName != NULL)
CoTaskMemFree(statStg.pwcsName);
}
} // while loop
penumStatStg->Release();
}
indent -= 2;
}
static void Usage(void)
{
printf("Usage: tstgdir [options] <filename>\n");
printf("Options are:\n");
printf(" -h - This message\n");
printf(" -b - Brief\n");
printf(" -d - Debug\n");
printf(" -r - Read streams (don't display)\n");
printf(" -R - Read streams (display contents)\n");
printf(" -v - Verbose\n");
printf("\n");
}
int _cdecl main(int argc, char * argv[])
{
WCHAR wcsFile[_MAX_PATH];
HRESULT hResult;
DWORD grfMode;
IStorage *pstgRoot;
wcscpy(wcsFile, L"");
while (--argc>0)
{
if (**++argv == '-')
{
switch(argv[0][1])
{
case 'b':
fBrief = TRUE;
break;
case 'd':
fDebug = TRUE;
break;
case 'R':
fReadVerbose = TRUE;
case 'r':
fRead = TRUE;
break;
case 'v':
fVerbose = TRUE;
break;
case 'h':
default:
Usage();
return -1;
}
}
else
mbstowcs(wcsFile, argv[0], strlen(argv[0]) + 1);
}
if (wcsFile[0] == L'\0') {
printf("missing filename\n");
Usage();
return -1;
}
if (fVerbose)
fBrief = FALSE;
if (FAILED(hResult = CoInitialize(NULL))) {
printf("CoInitialize => %s\n", hResultText(hResult));
return -1;
}
grfMode = STGM_DIRECT | STGM_READ | STGM_SHARE_DENY_WRITE;
hResult = StgOpenStorage(wcsFile,
NULL, //pstgPriority
grfMode,
NULL, // snbExclude
0, //dwReserved
&pstgRoot);
if (FAILED(hResult)) {
CoUninitialize();
printf("StgOpenStorage => %s\n", hResultText(hResult));
return -1;
}
DispStorage(pstgRoot);
pstgRoot->Release();
CoUninitialize();
return 0;
}