|
|
//+--------------------------------------------------------------
//
// Microsoft Windows
// Copyright (C) Microsoft Corporation, 1991 - 1992.
//
// File: stgview.cxx
//
// Contents: Storage viewer utility
//
// History: 10-Dec-91 DrewB Created
//
//---------------------------------------------------------------
#include <memory.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <time.h>
#include <ctype.h>
#include <windows.h>
#if WIN32 != 300
#include <storage.h>
#endif
#include <wchar.h>
#include <dfmsp.hxx>
#define FLG_RECURSIVE 0x00000001
#define FLG_STREAMS 0x00000002
#define FLG_VERBOSE 0x00000004
#define DFTOUCH
#ifdef DFTOUCH
#define CB_BUFFER 1024
#else
#define CB_BUFFER 16
#endif
BYTE abBuffer[CB_BUFFER];
char *szTypes[] = { "", "IStorage", "IStream", "ILockBytes" };
void utMemFree(void *pv) { IMalloc FAR* pMalloc; if (SUCCEEDED(GetScode(CoGetMalloc(MEMCTX_TASK, &pMalloc)))) { pMalloc->Free(pv); pMalloc->Release(); } }
void LevSpace(int iLevel) { int i;
for (i = 0; i<iLevel; i++) printf(" "); }
void PrintStat(STATSTG *psstg, ULONG flOptions, int iLevel) { LevSpace(iLevel); if (flOptions & FLG_VERBOSE) { #ifdef UNICODE
wprintf(L"%s:%hs =>\n", psstg->pwcsName, szTypes[psstg->type]); #else
printf("%s:%s =>\n", psstg->pwcsName, szTypes[psstg->type]); #endif
#ifdef FLAT
SYSTEMTIME systime; struct tm stime;
LevSpace(iLevel+1); if (((psstg->ctime.dwHighDateTime != 0) || (psstg->ctime.dwLowDateTime != 0 )) && FileTimeToSystemTime(&psstg->ctime, &systime)) { stime.tm_sec = systime.wSecond; stime.tm_min = systime.wMinute; stime.tm_hour = systime.wHour; stime.tm_mday = systime.wDay; stime.tm_mon = systime.wMonth - 1; stime.tm_year = systime.wYear - 1900; stime.tm_wday = systime.wDayOfWeek; stime.tm_yday = 0; stime.tm_isdst = 0;
printf("Created : %s", asctime(&stime)); } else printf("Created : %lx %lx (conversion unavailable)\n", psstg->ctime.dwHighDateTime, psstg->ctime.dwLowDateTime);
LevSpace(iLevel+1); if (((psstg->mtime.dwHighDateTime != 0) || (psstg->mtime.dwLowDateTime != 0 )) && FileTimeToSystemTime(&psstg->mtime, &systime)) { stime.tm_sec = systime.wSecond; stime.tm_min = systime.wMinute; stime.tm_hour = systime.wHour; stime.tm_mday = systime.wDay; stime.tm_mon = systime.wMonth - 1; stime.tm_year = systime.wYear - 1900; stime.tm_wday = systime.wDayOfWeek; stime.tm_yday = 0; stime.tm_isdst = 0;
printf("Modified : %s", asctime(&stime)); } else printf("Modified : %lx %lx (conversion unavailable)\n", psstg->ctime.dwHighDateTime, psstg->ctime.dwLowDateTime);
LevSpace(iLevel+1); if (((psstg->atime.dwHighDateTime != 0) || (psstg->atime.dwLowDateTime != 0 )) && FileTimeToSystemTime(&psstg->mtime, &systime)) { stime.tm_sec = systime.wSecond; stime.tm_min = systime.wMinute; stime.tm_hour = systime.wHour; stime.tm_mday = systime.wDay; stime.tm_mon = systime.wMonth - 1; stime.tm_year = systime.wYear - 1900; stime.tm_wday = systime.wDayOfWeek; stime.tm_yday = 0; stime.tm_isdst = 0;
printf("Accessed : %s", asctime(&stime)); } else printf("Accessed : %lx %lx (conversion unavailable)\n", psstg->ctime.dwHighDateTime, psstg->ctime.dwLowDateTime); #else
LevSpace(iLevel+1); printf("Created : %lx %lx (conversion unavailable)\n", psstg->ctime.dwHighDateTime, psstg->ctime.dwLowDateTime); LevSpace(iLevel+1); printf("Modified : %lx %lx (conversion unavailable)\n", psstg->mtime.dwHighDateTime, psstg->mtime.dwLowDateTime); LevSpace(iLevel+1); printf("Accessed : %lx %lx (conversion unavailable)\n", psstg->atime.dwHighDateTime, psstg->atime.dwLowDateTime); #endif
if (psstg->type == STGTY_STREAM || psstg->type == STGTY_LOCKBYTES) { LevSpace(iLevel+1); printf("Size: %lu:%lu\n", ULIGetHigh(psstg->cbSize), ULIGetLow(psstg->cbSize)); } } else #ifdef UNICODE
wprintf(L"%s\n", psstg->pwcsName); #else
printf("%s\n", psstg->pwcsName); #endif
}
// ctype doesn't work properly
#define dfisprint(c) ((c) >= ' ' && (c) < 127)
void Stream(IStream *pstm, ULONG flOptions, int iLevel) { ULONG cbRead; #ifdef DFTOUCH
ULONG cbTotal = 0; #endif
SCODE sc;
sc = GetScode(pstm->Read(abBuffer, CB_BUFFER, &cbRead)); while (SUCCEEDED(sc) && (cbRead > 0)) { LevSpace(iLevel); #ifdef DFTOUCH
cbTotal += cbRead; printf("Read %lu bytes\n", cbTotal); #else
for (ULONG ib = 0; ib < cbRead; ib++) { printf("%.2X", (int)abBuffer[ib]); } for (ib = ib; ib < CB_BUFFER + 1; ib++) { printf(" "); }
for (ib = 0; ib < cbRead; ib++) { printf("%c", dfisprint(abBuffer[ib]) ? abBuffer[ib] : '.'); } printf("\n"); #endif
sc = GetScode(pstm->Read(abBuffer, CB_BUFFER, &cbRead)); } if (FAILED(sc)) printf("Read failed with 0x%lX\n", sc); }
void Contents(IStorage *pdf, ULONG flOptions, int iLevel) { IEnumSTATSTG *pdfi; SCODE sc; IStorage *pdfChild; IStream *pstmChild; STATSTG sstg;
if (FAILED(pdf->EnumElements(0, NULL, 0, &pdfi))) { fprintf(stderr, "Unable to create iterator\n"); return; } for (;;) { sc = GetScode(pdfi->Next(1, &sstg, NULL)); if (sc != S_OK) break; PrintStat(&sstg, flOptions, iLevel); if ((sstg.type == STGTY_STORAGE) && (flOptions & FLG_RECURSIVE)) { if (SUCCEEDED(pdf->OpenStorage(sstg.pwcsName, NULL, STGM_READ | STGM_SHARE_EXCLUSIVE, NULL, 0, &pdfChild))) { Contents(pdfChild, flOptions, iLevel+1); pdfChild->Release(); } else fprintf(stderr, "%s: Unable to recurse\n", sstg.pwcsName); } else if ((sstg.type == STGTY_STREAM) && (flOptions & FLG_STREAMS)) { if (SUCCEEDED(pdf->OpenStream(sstg.pwcsName, NULL, STGM_READ | STGM_SHARE_EXCLUSIVE, 0, &pstmChild))) { Stream(pstmChild, flOptions, iLevel+1); pstmChild->Release(); } else fprintf(stderr, "%s: Unable to open\n", sstg.pwcsName); } utMemFree(sstg.pwcsName); } pdfi->Release(); if (FAILED(sc)) printf("Enumeration failed with 0x%lX\n", sc); }
void Descend(IStorage *pdf, char *pszPath, IStorage **ppdf) { IStorage *pdfNext; char *pszNext = pszPath; char *pszEnd = strchr(pszNext, '\\'); TCHAR atcName[CWCSTORAGENAME];
while (pszNext != NULL) { if (pszEnd != NULL) { *pszEnd = '\0'; }
#ifdef UNICODE
if (mbstowcs(atcName, pszNext, CWCSTORAGENAME) == (size_t)-1) { pdf = NULL;
fprintf(stderr, "Unable to convert '%s' to Unicode\n", pszNext); break; } #else
strcpy(atcName, pszNext); #endif
if (SUCCEEDED(pdf->OpenStorage(atcName, NULL, STGM_READ | STGM_SHARE_EXCLUSIVE, NULL, 0, &pdfNext))) { pdf = pdfNext;
if (pszEnd != NULL) { *pszEnd = '\\';
pszNext = pszEnd + 1; pszEnd = strchr(pszNext, '\\'); } else { pszNext = NULL; } } else { pdf = NULL;
fprintf(stderr, "Unable to open '%s' in docfile\n", pszPath); break; } }
*ppdf = pdf; }
void __cdecl main(int argc, char **argv) { ULONG flOptions = 0; IStorage *pdf; IStorage *pdfRoot; STATSTG sstg;
argc--; argv++; while ((argc > 0) && ((*argv)[0] == '-')) { for (int ich = 1; (*argv)[ich] != '\0'; ich++) { switch((*argv)[ich]) { case 's': flOptions |= FLG_STREAMS; break; case 'v': flOptions |= FLG_VERBOSE; break; case 'r': flOptions |= FLG_RECURSIVE; break; default: fprintf(stderr, "Unknown switch '%c'\n", (*argv)[ich]); break; } }
argc--; argv++; }
if ((argc != 1) && (argc != 2)) { printf("Usage: stgview [-v] [-s] [-r] docfile [path]\n"); exit(1); }
SCODE sc;
#if WIN32 == 300
if (FAILED(sc = GetScode(CoInitializeEx(NULL, COINIT_MULTITHREADED)))) #else
if (FAILED(sc = GetScode(CoInitialize(NULL)))) #endif
{ fprintf(stderr, "CoInitialize failed with sc = %lx\n", sc); exit(1); }
TCHAR atcName[_MAX_PATH]; #ifdef UNICODE
if (mbstowcs(atcName, *argv, _MAX_PATH) == (size_t)-1) { fprintf(stderr, "Unable to convert '%s' to Unicode\n", *argv); exit(1); } #else
strcpy(atcName, *argv); #endif
if (FAILED(StgOpenStorage(atcName, NULL, STGM_READ | STGM_SHARE_DENY_WRITE, NULL, 0, &pdf))) { fprintf(stderr, "Unable to open '%s'\n", *argv); exit(1); } else { if (argc == 2) { Descend(pdf, *(argv + 1), &pdfRoot); } else { pdf->AddRef(); pdfRoot = pdf; }
if (pdfRoot != NULL) { if (FAILED(pdfRoot->Stat(&sstg, 0))) fprintf(stderr, "Unable to stat root\n"); else { PrintStat(&sstg, flOptions, 0); utMemFree(sstg.pwcsName); } Contents(pdfRoot, flOptions, 1); pdfRoot->Release(); } pdf->Release(); }
CoUninitialize(); }
|