Source code of Windows XP (NT5)
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.

411 lines
10 KiB

  1. //+--------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation, 1991 - 1992.
  5. //
  6. // File: stgview.cxx
  7. //
  8. // Contents: Storage viewer utility
  9. //
  10. // History: 10-Dec-91 DrewB Created
  11. //
  12. //---------------------------------------------------------------
  13. #include <memory.h>
  14. #include <stdlib.h>
  15. #include <stdio.h>
  16. #include <string.h>
  17. #include <time.h>
  18. #include <ctype.h>
  19. #include <windows.h>
  20. #if WIN32 != 300
  21. #include <storage.h>
  22. #endif
  23. #include <wchar.h>
  24. #include <dfmsp.hxx>
  25. #define FLG_RECURSIVE 0x00000001
  26. #define FLG_STREAMS 0x00000002
  27. #define FLG_VERBOSE 0x00000004
  28. #define DFTOUCH
  29. #ifdef DFTOUCH
  30. #define CB_BUFFER 1024
  31. #else
  32. #define CB_BUFFER 16
  33. #endif
  34. BYTE abBuffer[CB_BUFFER];
  35. char *szTypes[] =
  36. {
  37. "", "IStorage", "IStream", "ILockBytes"
  38. };
  39. void utMemFree(void *pv)
  40. {
  41. IMalloc FAR* pMalloc;
  42. if (SUCCEEDED(GetScode(CoGetMalloc(MEMCTX_TASK, &pMalloc))))
  43. {
  44. pMalloc->Free(pv);
  45. pMalloc->Release();
  46. }
  47. }
  48. void LevSpace(int iLevel)
  49. {
  50. int i;
  51. for (i = 0; i<iLevel; i++)
  52. printf(" ");
  53. }
  54. void PrintStat(STATSTG *psstg, ULONG flOptions, int iLevel)
  55. {
  56. LevSpace(iLevel);
  57. if (flOptions & FLG_VERBOSE)
  58. {
  59. #ifdef UNICODE
  60. wprintf(L"%s:%hs =>\n", psstg->pwcsName, szTypes[psstg->type]);
  61. #else
  62. printf("%s:%s =>\n", psstg->pwcsName, szTypes[psstg->type]);
  63. #endif
  64. #ifdef FLAT
  65. SYSTEMTIME systime;
  66. struct tm stime;
  67. LevSpace(iLevel+1);
  68. if (((psstg->ctime.dwHighDateTime != 0) ||
  69. (psstg->ctime.dwLowDateTime != 0 )) &&
  70. FileTimeToSystemTime(&psstg->ctime, &systime))
  71. {
  72. stime.tm_sec = systime.wSecond;
  73. stime.tm_min = systime.wMinute;
  74. stime.tm_hour = systime.wHour;
  75. stime.tm_mday = systime.wDay;
  76. stime.tm_mon = systime.wMonth - 1;
  77. stime.tm_year = systime.wYear - 1900;
  78. stime.tm_wday = systime.wDayOfWeek;
  79. stime.tm_yday = 0;
  80. stime.tm_isdst = 0;
  81. printf("Created : %s", asctime(&stime));
  82. }
  83. else
  84. printf("Created : %lx %lx (conversion unavailable)\n",
  85. psstg->ctime.dwHighDateTime, psstg->ctime.dwLowDateTime);
  86. LevSpace(iLevel+1);
  87. if (((psstg->mtime.dwHighDateTime != 0) ||
  88. (psstg->mtime.dwLowDateTime != 0 )) &&
  89. FileTimeToSystemTime(&psstg->mtime, &systime))
  90. {
  91. stime.tm_sec = systime.wSecond;
  92. stime.tm_min = systime.wMinute;
  93. stime.tm_hour = systime.wHour;
  94. stime.tm_mday = systime.wDay;
  95. stime.tm_mon = systime.wMonth - 1;
  96. stime.tm_year = systime.wYear - 1900;
  97. stime.tm_wday = systime.wDayOfWeek;
  98. stime.tm_yday = 0;
  99. stime.tm_isdst = 0;
  100. printf("Modified : %s", asctime(&stime));
  101. }
  102. else
  103. printf("Modified : %lx %lx (conversion unavailable)\n",
  104. psstg->ctime.dwHighDateTime, psstg->ctime.dwLowDateTime);
  105. LevSpace(iLevel+1);
  106. if (((psstg->atime.dwHighDateTime != 0) ||
  107. (psstg->atime.dwLowDateTime != 0 )) &&
  108. FileTimeToSystemTime(&psstg->mtime, &systime))
  109. {
  110. stime.tm_sec = systime.wSecond;
  111. stime.tm_min = systime.wMinute;
  112. stime.tm_hour = systime.wHour;
  113. stime.tm_mday = systime.wDay;
  114. stime.tm_mon = systime.wMonth - 1;
  115. stime.tm_year = systime.wYear - 1900;
  116. stime.tm_wday = systime.wDayOfWeek;
  117. stime.tm_yday = 0;
  118. stime.tm_isdst = 0;
  119. printf("Accessed : %s", asctime(&stime));
  120. }
  121. else
  122. printf("Accessed : %lx %lx (conversion unavailable)\n",
  123. psstg->ctime.dwHighDateTime, psstg->ctime.dwLowDateTime);
  124. #else
  125. LevSpace(iLevel+1);
  126. printf("Created : %lx %lx (conversion unavailable)\n",
  127. psstg->ctime.dwHighDateTime, psstg->ctime.dwLowDateTime);
  128. LevSpace(iLevel+1);
  129. printf("Modified : %lx %lx (conversion unavailable)\n",
  130. psstg->mtime.dwHighDateTime, psstg->mtime.dwLowDateTime);
  131. LevSpace(iLevel+1);
  132. printf("Accessed : %lx %lx (conversion unavailable)\n",
  133. psstg->atime.dwHighDateTime, psstg->atime.dwLowDateTime);
  134. #endif
  135. if (psstg->type == STGTY_STREAM || psstg->type == STGTY_LOCKBYTES)
  136. {
  137. LevSpace(iLevel+1);
  138. printf("Size: %lu:%lu\n", ULIGetHigh(psstg->cbSize),
  139. ULIGetLow(psstg->cbSize));
  140. }
  141. }
  142. else
  143. #ifdef UNICODE
  144. wprintf(L"%s\n", psstg->pwcsName);
  145. #else
  146. printf("%s\n", psstg->pwcsName);
  147. #endif
  148. }
  149. // ctype doesn't work properly
  150. #define dfisprint(c) ((c) >= ' ' && (c) < 127)
  151. void Stream(IStream *pstm, ULONG flOptions, int iLevel)
  152. {
  153. ULONG cbRead;
  154. #ifdef DFTOUCH
  155. ULONG cbTotal = 0;
  156. #endif
  157. SCODE sc;
  158. sc = GetScode(pstm->Read(abBuffer, CB_BUFFER, &cbRead));
  159. while (SUCCEEDED(sc) && (cbRead > 0))
  160. {
  161. LevSpace(iLevel);
  162. #ifdef DFTOUCH
  163. cbTotal += cbRead;
  164. printf("Read %lu bytes\n", cbTotal);
  165. #else
  166. for (ULONG ib = 0; ib < cbRead; ib++)
  167. {
  168. printf("%.2X", (int)abBuffer[ib]);
  169. }
  170. for (ib = ib; ib < CB_BUFFER + 1; ib++)
  171. {
  172. printf(" ");
  173. }
  174. for (ib = 0; ib < cbRead; ib++)
  175. {
  176. printf("%c", dfisprint(abBuffer[ib]) ? abBuffer[ib] : '.');
  177. }
  178. printf("\n");
  179. #endif
  180. sc = GetScode(pstm->Read(abBuffer, CB_BUFFER, &cbRead));
  181. }
  182. if (FAILED(sc))
  183. printf("Read failed with 0x%lX\n", sc);
  184. }
  185. void Contents(IStorage *pdf, ULONG flOptions, int iLevel)
  186. {
  187. IEnumSTATSTG *pdfi;
  188. SCODE sc;
  189. IStorage *pdfChild;
  190. IStream *pstmChild;
  191. STATSTG sstg;
  192. if (FAILED(pdf->EnumElements(0, NULL, 0, &pdfi)))
  193. {
  194. fprintf(stderr, "Unable to create iterator\n");
  195. return;
  196. }
  197. for (;;)
  198. {
  199. sc = GetScode(pdfi->Next(1, &sstg, NULL));
  200. if (sc != S_OK)
  201. break;
  202. PrintStat(&sstg, flOptions, iLevel);
  203. if ((sstg.type == STGTY_STORAGE) && (flOptions & FLG_RECURSIVE))
  204. {
  205. if (SUCCEEDED(pdf->OpenStorage(sstg.pwcsName, NULL,
  206. STGM_READ | STGM_SHARE_EXCLUSIVE,
  207. NULL, 0, &pdfChild)))
  208. {
  209. Contents(pdfChild, flOptions, iLevel+1);
  210. pdfChild->Release();
  211. }
  212. else
  213. fprintf(stderr, "%s: Unable to recurse\n", sstg.pwcsName);
  214. }
  215. else
  216. if ((sstg.type == STGTY_STREAM) && (flOptions & FLG_STREAMS))
  217. {
  218. if (SUCCEEDED(pdf->OpenStream(sstg.pwcsName, NULL,
  219. STGM_READ | STGM_SHARE_EXCLUSIVE,
  220. 0, &pstmChild)))
  221. {
  222. Stream(pstmChild, flOptions, iLevel+1);
  223. pstmChild->Release();
  224. }
  225. else
  226. fprintf(stderr, "%s: Unable to open\n", sstg.pwcsName);
  227. }
  228. utMemFree(sstg.pwcsName);
  229. }
  230. pdfi->Release();
  231. if (FAILED(sc))
  232. printf("Enumeration failed with 0x%lX\n", sc);
  233. }
  234. void Descend(IStorage *pdf, char *pszPath, IStorage **ppdf)
  235. {
  236. IStorage *pdfNext;
  237. char *pszNext = pszPath;
  238. char *pszEnd = strchr(pszNext, '\\');
  239. TCHAR atcName[CWCSTORAGENAME];
  240. while (pszNext != NULL)
  241. {
  242. if (pszEnd != NULL)
  243. {
  244. *pszEnd = '\0';
  245. }
  246. #ifdef UNICODE
  247. if (mbstowcs(atcName, pszNext, CWCSTORAGENAME) == (size_t)-1)
  248. {
  249. pdf = NULL;
  250. fprintf(stderr, "Unable to convert '%s' to Unicode\n", pszNext);
  251. break;
  252. }
  253. #else
  254. strcpy(atcName, pszNext);
  255. #endif
  256. if (SUCCEEDED(pdf->OpenStorage(atcName, NULL,
  257. STGM_READ | STGM_SHARE_EXCLUSIVE,
  258. NULL, 0, &pdfNext)))
  259. {
  260. pdf = pdfNext;
  261. if (pszEnd != NULL)
  262. {
  263. *pszEnd = '\\';
  264. pszNext = pszEnd + 1;
  265. pszEnd = strchr(pszNext, '\\');
  266. }
  267. else
  268. {
  269. pszNext = NULL;
  270. }
  271. }
  272. else
  273. {
  274. pdf = NULL;
  275. fprintf(stderr, "Unable to open '%s' in docfile\n", pszPath);
  276. break;
  277. }
  278. }
  279. *ppdf = pdf;
  280. }
  281. void __cdecl main(int argc, char **argv)
  282. {
  283. ULONG flOptions = 0;
  284. IStorage *pdf;
  285. IStorage *pdfRoot;
  286. STATSTG sstg;
  287. argc--;
  288. argv++;
  289. while ((argc > 0) && ((*argv)[0] == '-'))
  290. {
  291. for (int ich = 1; (*argv)[ich] != '\0'; ich++)
  292. {
  293. switch((*argv)[ich])
  294. {
  295. case 's':
  296. flOptions |= FLG_STREAMS;
  297. break;
  298. case 'v':
  299. flOptions |= FLG_VERBOSE;
  300. break;
  301. case 'r':
  302. flOptions |= FLG_RECURSIVE;
  303. break;
  304. default:
  305. fprintf(stderr, "Unknown switch '%c'\n", (*argv)[ich]);
  306. break;
  307. }
  308. }
  309. argc--;
  310. argv++;
  311. }
  312. if ((argc != 1) && (argc != 2))
  313. {
  314. printf("Usage: stgview [-v] [-s] [-r] docfile [path]\n");
  315. exit(1);
  316. }
  317. SCODE sc;
  318. #if WIN32 == 300
  319. if (FAILED(sc = GetScode(CoInitializeEx(NULL, COINIT_MULTITHREADED))))
  320. #else
  321. if (FAILED(sc = GetScode(CoInitialize(NULL))))
  322. #endif
  323. {
  324. fprintf(stderr, "CoInitialize failed with sc = %lx\n", sc);
  325. exit(1);
  326. }
  327. TCHAR atcName[_MAX_PATH];
  328. #ifdef UNICODE
  329. if (mbstowcs(atcName, *argv, _MAX_PATH) == (size_t)-1)
  330. {
  331. fprintf(stderr, "Unable to convert '%s' to Unicode\n", *argv);
  332. exit(1);
  333. }
  334. #else
  335. strcpy(atcName, *argv);
  336. #endif
  337. if (FAILED(StgOpenStorage(atcName, NULL, STGM_READ | STGM_SHARE_DENY_WRITE,
  338. NULL, 0, &pdf)))
  339. {
  340. fprintf(stderr, "Unable to open '%s'\n", *argv);
  341. exit(1);
  342. }
  343. else
  344. {
  345. if (argc == 2)
  346. {
  347. Descend(pdf, *(argv + 1), &pdfRoot);
  348. }
  349. else
  350. {
  351. pdf->AddRef();
  352. pdfRoot = pdf;
  353. }
  354. if (pdfRoot != NULL)
  355. {
  356. if (FAILED(pdfRoot->Stat(&sstg, 0)))
  357. fprintf(stderr, "Unable to stat root\n");
  358. else
  359. {
  360. PrintStat(&sstg, flOptions, 0);
  361. utMemFree(sstg.pwcsName);
  362. }
  363. Contents(pdfRoot, flOptions, 1);
  364. pdfRoot->Release();
  365. }
  366. pdf->Release();
  367. }
  368. CoUninitialize();
  369. }