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.

696 lines
25 KiB

  1. //+----------------------------------------------------------------------------// File: DF2T.CXX
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation, 1991 - 1992.
  5. //
  6. // Contents: utility program for converting a Docfile to a directory tree.
  7. // Given a Docfile,it is walked with an enumerator and each
  8. // embedded IStorage creates a directory in the specified
  9. // destination tree while each IStream creates a file within
  10. // the appropriate directory. Finally, a tree compare is
  11. // performed on the source and destination trees.
  12. //
  13. // Classes: IStorage - Container class
  14. // IStream - Contained stream class
  15. // IEnumSTATSTG - Enumerator class for IStorages
  16. //
  17. // Command line: df2c -f/-b -(n)ameofDocfile -(s)rcTree -(d)estTree -T -W
  18. // -f forward conversion (docfile --> tree)
  19. // -b backward conversion (tree --> docfile)
  20. // -n name for root docfile
  21. // -s name of the source directory tree
  22. // -d name of the destination directory tree
  23. // -t specifies STGM_TRANSACTED mode
  24. // -w specifies STGM_SHARE_DENY_WRITE mode for root docfile
  25. //
  26. // -f and -b cannot be both specified in one command.
  27. //
  28. // The default conversion is from Docfile to tree.
  29. // Therefore, -n and -d(est) must be specified when forward
  30. // conversion -f is used. Otherwise, -b should be accompanied
  31. // by -s(rc) and -n(doc).
  32. //
  33. // This utility defaults to running in DIRECT mode so that all
  34. // operations at all levels are performed immediately on the
  35. // base copy of the root docfile.
  36. //
  37. // With the -T switch, this runs in STGM_TRANSACTED mode for
  38. // all IStorage creation and instantiation so that scratch
  39. // streams are created and committed, but only made permanent
  40. // in the persistent version by Commit of the root docfile.
  41. //
  42. // With the -W switch, this runs in STGM_TRANSACTED mode
  43. // with STGM_SHARE_DENY_WRITE for root docfile creation and
  44. // instantiation so that operations are performed on the base
  45. // copy of the docfile.
  46. //
  47. // Requires: Windows 3.x. MSF.DLL and DOCFILE.DLL should be in same dir
  48. // as executable or in \windows\system
  49. //
  50. // Returns: 0 if successful, exits with error code otherwise
  51. //
  52. // Notes: uses whcar and 'mbtowcs' conversions for wide char support
  53. // returns STG_E_NOTCURRENT if docfile-to-be-created
  54. // already exists.
  55. //
  56. // Created: RichE, January 13, 1992 Original program
  57. // Revised: t-chrisy, June 25, 1992 convert the test program to a utility
  58. // dftc.cxx --> df2t.cxx
  59. //-----------------------------------------------------------------------------
  60. #include <stdlib.h>
  61. #include <string.h>
  62. #include <dos.h>
  63. #include <direct.h>
  64. #include "w4ctsupp.hxx"
  65. #define WILD_CARD "\\*.*"
  66. #define BACK_SLASH "\\"
  67. #define NS_INCL (STGTY_STORAGE | STGTY_STREAM)
  68. #define FIND_ATTRS _A_SUBDIR | _A_NORMAL | _A_RDONLY | _A_HIDDEN
  69. #define FILE_BUF_SIZE 32768 // msf is optimized for file size of 4K or 512bytes
  70. #define DOCTOTREE 0
  71. #define TREETODOC 1
  72. //function prototypes
  73. void CopyTreeToDocfile(IStorage *pstgParent);
  74. void CopyDocfileToTree(IStorage *pstgParent, TCHAR *ptcsDFName);
  75. void CopyFileToStream(IStorage *pstgParent, char *FileName);
  76. void CopyStreamToFile(IStorage *pstgParent, TCHAR *ptcsStreamName);
  77. int GetOptions(int argc, char *argv[]);
  78. void Usage(char *pszProgName);
  79. //buffers for file/dir path calls and docfile name (default assignments)
  80. char szDestDocfile[_MAX_PATH + 1] = "";
  81. char szSrcPath[_MAX_PATH + 1] = "";
  82. char szDestPath[_MAX_PATH + 1] = "";
  83. int iSrcPathEnd = sizeof(_MAX_PATH); //length minus terminating '\0'
  84. int iDestPathEnd = sizeof(_MAX_PATH);
  85. //buffers for converting to/from wide characters
  86. TCHAR wcsWideName[_MAX_PATH + 1];
  87. char szName[_MAX_PATH + 1];
  88. //modifiers to flags for root and child docfiles (GetOptions may modify)
  89. DWORD dwRootFlags = STGM_READWRITE | STGM_SHARE_DENY_WRITE;
  90. DWORD dwChildFlags = STGM_READWRITE | STGM_SHARE_EXCLUSIVE;
  91. void utMemFree(void *pv)
  92. {
  93. IMalloc FAR* pMalloc;
  94. if (SUCCEEDED(GetScode(CoGetMalloc(MEMCTX_TASK, &pMalloc))))
  95. {
  96. pMalloc->Free(pv);
  97. pMalloc->Release();
  98. }
  99. }
  100. //+----------------------------------------------------------------------------
  101. // Function: main, public
  102. //
  103. // Synopsis: main body of program, controls overall flow
  104. //
  105. // Effects: initialize. Depending on the direction of converionsn,
  106. // call functions to create a tree, given a DocFile;
  107. // call functions to create a DocFile, given a tree.
  108. //
  109. // Created: RichE January 13, 1992 original program
  110. // Revised: t-chrisy June 25, 1992 modified to convert docfile to tree;
  111. // and vice versa.
  112. //
  113. //-----------------------------------------------------------------------------
  114. void main(int argc, char *argv[])
  115. {
  116. IStorage *pstgDest = NULL;
  117. SCODE scRc;
  118. short ret;
  119. #if WIN32 == 300
  120. if (FAILED(scRc = GetScode(CoInitializeEx(NULL, COINIT_MULTITHREADED))))
  121. #else
  122. if (FAILED(scRc = GetScode(CoInitialize(NULL))))
  123. #endif
  124. {
  125. fprintf(stderr, "CoInitialize failed with sc = %lx\n", scRc);
  126. exit(1);
  127. }
  128. ret=GetOptions(argc, argv);
  129. if (ret==DOCTOTREE)
  130. {
  131. tprintf(bDestOut, "Converting Docfile to tree....\n");
  132. if ((!strcmp(szDestDocfile,"\0"))||(!strcmp(szDestPath,"\0")))
  133. {
  134. tprintf(bDestOut, "Invalid switches used.\n");
  135. tprintf(bDestOut,
  136. "If -f is indicated, -n and -d must also be specified.\n");
  137. exit(1);
  138. }
  139. }
  140. else
  141. {
  142. tprintf(bDestOut, "Converting a directory tree to Docfile....\n");
  143. if ((!strcmp(szDestDocfile,"\0")||(!strcmp(szSrcPath,"\0"))))
  144. {
  145. tprintf(bDestOut, "Invalid switches used.\n");
  146. tprintf(bDestOut,
  147. "If -b is chosen, -s and -n must also be specified.\n");
  148. exit(1);
  149. }
  150. }
  151. if (dwRootFlags & STGM_TRANSACTED)
  152. {
  153. tprintf(bDestOut, "STGM_TRANSACTED mode ");
  154. if ((dwRootFlags & 0x70) == STGM_SHARE_EXCLUSIVE)
  155. {
  156. tprintf(bDestOut, "with STGM_SHARE_EXCLUSIVE");
  157. }
  158. else
  159. {
  160. tprintf(bDestOut, "without STGM_SHARE_EXCLUSIVE");
  161. }
  162. }
  163. else
  164. {
  165. tprintf(bDestOut, "STGM_DIRECT mode (with STGM_SHARE_EXCLUSIVE)");
  166. }
  167. tprintf(bDestOut, " operation\n");
  168. MakeWide(wcsWideName, szDestDocfile);
  169. if (ret==DOCTOTREE) // Docfile to tree...
  170. {
  171. MakePath(szDestPath);
  172. CopyDocfileToTree((IStorage *) NULL, wcsWideName);
  173. }
  174. else
  175. {
  176. // Create root docfile with specified mode, nuke if already exists
  177. tprintf(bDestOut, "Create root docfile %s\n", szDestDocfile);
  178. scRc = GetScode(StgCreateDocfile(wcsWideName,
  179. dwRootFlags | STGM_CREATE, 0,
  180. &pstgDest));
  181. tprintf(bDestOut, "Returned %lu\n", scRc);
  182. tprintf(bDestOut, "Root docfile %s %s, pointer %p\n", szDestDocfile,
  183. pstgDest == NULL ? "FALSE" : "TRUE", pstgDest);
  184. if (pstgDest == NULL || FAILED(scRc))
  185. {
  186. ErrExit(DEST_LOG, scRc, "Error creating root docfile %s\n",
  187. szDestDocfile);
  188. }
  189. CopyTreeToDocfile(pstgDest);
  190. }
  191. }
  192. //+----------------------------------------------------------------------------
  193. // Function: CopyTreeToDocfile, private
  194. //
  195. // Synopsis: traverses and reads source tree and creates docfile image
  196. //
  197. // Effects: for each directory in source tree, an IStorage is created, for each
  198. // file, a contained stream is created. this function is recursive.
  199. //
  200. // Arguments: [pstgParent] - current parent IStorage for new containees
  201. //
  202. // Created: RichE, January 13, 1992
  203. // Revised: RichE March 5, 1992 Df APIs to method calls
  204. // Revised: RichE March 6, 1992 TRANSACTED mode operation
  205. // Revised: RichE March 17, 1992 convert to OLE interfaces
  206. //-----------------------------------------------------------------------------
  207. void CopyTreeToDocfile(IStorage *pstgParent)
  208. {
  209. struct find_t FileInfo;
  210. SCODE scRc;
  211. USHORT usEndOfBasePath;
  212. IStorage *pstgChild;
  213. // Save pointer to base of pure path at this level
  214. usEndOfBasePath = strlen(szSrcPath) + 1;
  215. scRc = _dos_findfirst(strcat(szSrcPath, WILD_CARD), FIND_ATTRS, &FileInfo);
  216. while (scRc==0)
  217. {
  218. // If not '.' or '..' directories
  219. if (FileInfo.name[0] != '.')
  220. {
  221. // Restore pure path and add current file/dir name to it
  222. szSrcPath[usEndOfBasePath] = NIL;
  223. strcat(szSrcPath, FileInfo.name);
  224. if (FileInfo.attrib == _A_SUBDIR)
  225. {
  226. MakeWide(wcsWideName, FileInfo.name);
  227. // Create new IStorage inside current one,
  228. // use dir name for name
  229. tprintf(bDestOut,
  230. "Create embedded DF %s inside pstgParent %p\n",
  231. szSrcPath, pstgParent);
  232. scRc = GetScode(pstgParent->CreateStorage(wcsWideName,
  233. dwChildFlags |
  234. STGM_FAILIFTHERE,
  235. 0, 0,
  236. &pstgChild));
  237. tprintf(bDestOut, "Returned: %lu, pointer = %p\n",
  238. scRc, pstgChild);
  239. if (pstgChild == NULL || FAILED(scRc))
  240. {
  241. ErrExit(DEST_LOG, scRc,
  242. "Error creating child IStorage %s\n",
  243. FileInfo.name);
  244. }
  245. CopyTreeToDocfile(pstgChild);
  246. }
  247. else
  248. {
  249. CopyFileToStream(pstgParent, FileInfo.name);
  250. }
  251. }
  252. scRc = _dos_findnext(&FileInfo);
  253. }
  254. if (dwRootFlags & STGM_TRANSACTED)
  255. {
  256. tprintf(bDestOut, "Committing pstgParent %p\n", pstgParent);
  257. if (scRc = GetScode(pstgParent->Commit(STGC_ONLYIFCURRENT)))
  258. {
  259. ErrExit(DEST_LOG, scRc, "Error committing IStorage %p\n",
  260. pstgParent);
  261. }
  262. }
  263. tprintf(bDestOut, "Releasing pstgParent %p\n", pstgParent);
  264. pstgParent->Release();
  265. }
  266. //+----------------------------------------------------------------------------
  267. // Function: CopyFileToStream, private
  268. //
  269. // Synopsis: copies supplied file to stream inside of parent IStorage
  270. //
  271. // Arguments: [pstgParent] - parent IStorage for stream created
  272. // [FileName] - name of source file to copy to stream
  273. //
  274. // Created: RichE, January 13, 1992
  275. // Revised: RichE March 5, 1992 Df APIs to method calls
  276. // Revised: RichE March 6, 1992 TRANSACTED mode operation
  277. // Revised: RichE March 15, 1992 streams no longer TRANSACTED
  278. // Revised: RichE March 17, 1992 convert to OLE interfaces
  279. //-----------------------------------------------------------------------------
  280. void CopyFileToStream(IStorage *pstgParent, char *FileName)
  281. {
  282. IStream *pstmStream = NULL;
  283. FILE *FileToCopy;
  284. SCODE scRc;
  285. ULONG cNumRead;
  286. ULONG cNumWritten;
  287. BYTE *FileBuf;
  288. tprintf(bDestOut, " File %s\n", szSrcPath);
  289. FileToCopy = fopen(szSrcPath, "rb");
  290. if (FileToCopy == NULL)
  291. {
  292. ErrExit(DEST_LOG, ERR, "Cannot open file %s\n", szSrcPath);
  293. }
  294. MakeWide(wcsWideName, FileName);
  295. // Create a stream inside parent IStorage
  296. tprintf(bDestOut,
  297. "Create embedded stream inside parent pstgParent = %p\n",
  298. pstgParent);
  299. scRc = GetScode(pstgParent->CreateStream(wcsWideName, STGM_STREAM |
  300. STGM_FAILIFTHERE, 0, 0,
  301. &pstmStream));
  302. tprintf(bDestOut, "Returned: %lu, pointer = %p\n", scRc, pstmStream);
  303. if (pstmStream == NULL || FAILED(scRc))
  304. {
  305. ErrExit(DEST_LOG, scRc, "Error creating stream %s\n", szSrcPath);
  306. }
  307. FileBuf = (BYTE * ) Allocate(FILE_BUF_SIZE * sizeof(BYTE));
  308. //while still reading from source file, write what was just read to Stream
  309. while (cNumRead = fread(FileBuf, 1, FILE_BUF_SIZE, FileToCopy))
  310. {
  311. if (ferror(FileToCopy))
  312. {
  313. ErrExit(DEST_LOG, ERR, "Error during stream read of %s\n",
  314. szSrcPath);
  315. }
  316. tprintf(bDestOut, "Try Stream write of %lu bytes on stream %p\n",
  317. cNumRead, pstmStream);
  318. scRc = GetScode(pstmStream->Write(FileBuf, cNumRead, &cNumWritten));
  319. tprintf(bDestOut, "Returned: %lu, bytes written %lu\n",
  320. scRc, cNumWritten);
  321. if (cNumWritten != cNumRead)
  322. {
  323. tprintf(bDestOut, "Write: scRc = %lu, cNumWritten = %lu, ",
  324. scRc, cNumWritten);
  325. tprintf(bDestOut, "cNumRead = %lu\n", cNumRead);
  326. }
  327. if (FAILED(scRc))
  328. {
  329. ErrExit(DEST_LOG, ERR, "Error writing stream %p\n", pstmStream);
  330. }
  331. }
  332. tprintf(bDestOut, "Releasing stream %p\n", pstmStream);
  333. pstmStream->Release();
  334. fclose(FileToCopy);
  335. free(FileBuf);
  336. }
  337. //+----------------------------------------------------------------------------// Function: CopyDocfileToTree, private
  338. //
  339. // Synopsis: enumerates and reads docfile and creates directory tree
  340. //
  341. // Effects: for each child IStorage in the root docfile, a subdir is created,
  342. // for each child stream, a file is created. this function is
  343. // recursive.
  344. //
  345. // Arguments: [pstgParent] - current parent IStorage for reading containees
  346. // [ptcsDFName] - name of IStorage to instantiate
  347. //
  348. // Created: RichE, January 13, 1992
  349. // Revised: RichE March 5, 1992 Df APIs to method calls
  350. // Revised: RichE March 6, 1992 TRANSACTED mode operation
  351. // Revised: RichE March 17, 1992 convert to OLE interfaces
  352. // Revised: t-chrisy June 30, 1992 removed the section on unlinking docfile
  353. //-----------------------------------------------------------------------------
  354. void CopyDocfileToTree(IStorage *pstgParent, TCHAR *ptcsDFName)
  355. {
  356. IStorage *pstgSrc = NULL;
  357. IEnumSTATSTG *penmWalk;
  358. USHORT usEndOfBasePath;
  359. SCODE scRc;
  360. STATSTG sstg;
  361. int iRc;
  362. // Add back slash & save pointer to base of pure path at this level
  363. strcat(szDestPath, BACK_SLASH);
  364. usEndOfBasePath = strlen(szDestPath);
  365. MakeSingle(szName, ptcsDFName);
  366. // If not first call (parent != NULL) then instantiate child IStorage with
  367. // method call, else instantiate root docfile via Df API call
  368. if (pstgParent != NULL)
  369. {
  370. tprintf(bDestOut, "Get embedded IStorage %s in parent %p\n",
  371. szName, pstgParent);
  372. scRc = GetScode(pstgParent->OpenStorage(ptcsDFName, NULL, dwChildFlags,
  373. NULL, 0, &pstgSrc));
  374. }
  375. else
  376. {
  377. tprintf(bDestOut, "Instantiate root docfile %s\n", szName);
  378. dwRootFlags |= STGM_READ;
  379. scRc = GetScode(StgOpenStorage(ptcsDFName, NULL, dwRootFlags, NULL,
  380. 0, &pstgSrc));
  381. }
  382. tprintf(bDestOut, "Return code: %lu, IStorage pointer %p\n",
  383. scRc, pstgSrc);
  384. if (pstgSrc == NULL || FAILED(scRc))
  385. {
  386. ErrExit(DEST_LOG, scRc, "Error instantiating IStorage %s\n", szName);
  387. }
  388. // Get an enumerator on the IStorage we just instantiated
  389. scRc = GetScode(pstgSrc->EnumElements(0, NULL, 0, &penmWalk));
  390. tprintf(bDestOut, "Got enumerator %p on IStorage %p, returned %lu\n",
  391. penmWalk, pstgSrc, scRc);
  392. if (penmWalk == NULL || FAILED(scRc))
  393. {
  394. ErrExit(DEST_LOG, scRc,
  395. "Error obtaining enumerator for IStorage %p\n", pstgSrc);
  396. }
  397. // Loop until GetNext returns other than S_OK, then break out of loop
  398. while (TRUE)
  399. {
  400. if (GetScode(penmWalk->Next(1, &sstg, NULL)) != S_OK)
  401. {
  402. tprintf(bDestOut, "No more to enumerate with enumerator %p\n",
  403. penmWalk);
  404. break;
  405. }
  406. else
  407. {
  408. MakeSingle(szName, sstg.pwcsName);
  409. tprintf(bDestOut, "Got item type %lu, Name %s, w/enumerator %p\n",
  410. sstg.type, szName, penmWalk);
  411. // Restore to path + BACK_SLASH and add file/dir name to DestPath
  412. szDestPath[usEndOfBasePath] = NIL;
  413. strcat(szDestPath, szName);
  414. tprintf(bDestOut, "Path Name: %s is ", szDestPath);
  415. if (sstg.type == STGTY_STORAGE)
  416. {
  417. tprintf(bDestOut, "STGTY_STORAGE\n");
  418. iRc = _mkdir(szDestPath);
  419. tprintf(bDestOut,
  420. "Trying to make directory %s, returned %d\n",
  421. szDestPath, iRc);
  422. CopyDocfileToTree(pstgSrc, sstg.pwcsName);
  423. }
  424. else
  425. {
  426. tprintf(bDestOut, "STGTY_STREAM\n");
  427. CopyStreamToFile(pstgSrc, sstg.pwcsName);
  428. }
  429. }
  430. utMemFree(sstg.pwcsName);
  431. }
  432. tprintf(bDestOut, "Releasing enumerator %p\n", penmWalk);
  433. penmWalk->Release();
  434. }
  435. //+----------------------------------------------------------------------------
  436. // Function: CopyStreamToFile, private
  437. //
  438. // Synopsis: copies supplied embedded stream to file in current dubdir
  439. //
  440. // Arguments: [pstgParent] - parent IStorage for stream to copy
  441. // [ptcsStreamName] - name of stream to copy to file
  442. //
  443. // Created: RichE, January 13, 1992
  444. // Revised: RichE March 5, 1992 Df APIs to method calls
  445. // Revised: RichE March 6, 1992 TRANSACTED mode operation
  446. // Revised: RichE March 15, 1992 streams no longer TRANSACTED
  447. // Revised: RichE March 17, 1992 convert to OLE interfaces
  448. //-----------------------------------------------------------------------------
  449. void CopyStreamToFile(IStorage *pstgParent, TCHAR *ptcsStreamName)
  450. {
  451. IStream *pstmStream = NULL;
  452. FILE *FileToWrite;
  453. ULONG cNumRead = 1;
  454. ULONG cNumWritten;
  455. BYTE *FileBuf;
  456. SCODE scRc;
  457. tprintf(bDestOut, "Copying embedded stream to file %s\n", szDestPath);
  458. // Instantiate named stream within parent IStorage
  459. tprintf(bDestOut, "Get stream in parent %p\n", pstgParent);
  460. scRc = GetScode(pstgParent->OpenStream(ptcsStreamName, NULL, STGM_STREAM,
  461. 0, &pstmStream));
  462. tprintf(bDestOut, "Returned: %lu, stream pointer %p\n", scRc, pstmStream);
  463. if (pstmStream == NULL || FAILED(scRc))
  464. {
  465. ErrExit(DEST_LOG, scRc, "Error opening stream %s\n", szDestPath);
  466. }
  467. FileToWrite = fopen(szDestPath, "wb");
  468. if (FileToWrite == NULL)
  469. {
  470. ErrExit(DEST_LOG, ERR, "Cannot open file %s\n", szDestPath);
  471. }
  472. FileBuf = (BYTE * ) Allocate(FILE_BUF_SIZE * sizeof(BYTE));
  473. // While still reading Stream, write what was just read to file.
  474. tprintf(bDestOut, "Starting to read stream %p\n", pstmStream);
  475. while (cNumRead > 0)
  476. {
  477. scRc = GetScode(pstmStream->Read(FileBuf, FILE_BUF_SIZE, &cNumRead));
  478. tprintf(bDestOut, "Read %lu bytes from stream %p, returned %lu\n",
  479. cNumRead, pstmStream, scRc);
  480. if (FAILED(scRc))
  481. {
  482. ErrExit(DEST_LOG, scRc, "Error reading stream %p\n", pstmStream);
  483. }
  484. cNumWritten = (ULONG)fwrite(FileBuf, 1, (size_t)cNumRead, FileToWrite);
  485. if (ferror(FileToWrite))
  486. {
  487. ErrExit(DEST_LOG, ERR, "Error writing to file %s\n", szDestPath);
  488. }
  489. if (cNumWritten != cNumRead)
  490. {
  491. tprintf(bDestOut, "Fwrite: cNumRead = %lu, cNumWritten = %lu\n",
  492. cNumRead, cNumWritten);
  493. }
  494. }
  495. tprintf(bDestOut, "Attempting to release stream %p in IStorage %p\n",
  496. pstmStream, pstgParent);
  497. pstmStream->Release();
  498. fclose(FileToWrite);
  499. free(FileBuf);
  500. }
  501. //+----------------------------------------------------------------------------
  502. // Function: GetOptions, private
  503. // Returns: DOCTOTREE or TREETODOC to indicate the direction of conversion.
  504. //
  505. // Synopsis: parses command line and sets global program options/variables
  506. //
  507. // Arguments: [argc] and [**argv] passed from main() function
  508. //
  509. // Modifies: [szSrcPath, szDestPath, szDestDocfile]
  510. //
  511. // Created: RichE, January 13, 1992
  512. // Revised: RichE, March 15, 1992 added -T and -W switches
  513. // Revised: RichE, March 19, 1992 fixed bug displaying error usage
  514. // Revised: t-chrisy, June 25, 1992 added -f and -b switches
  515. //-----------------------------------------------------------------------------
  516. int GetOptions(int argc, char *argv[])
  517. {
  518. char *pszArg;
  519. char *pszProgName;
  520. BOOL ArgsOK = TRUE;
  521. short ret=DOCTOTREE;
  522. // Bump past command name (argv[0])
  523. pszProgName = *argv++;
  524. // For each command line arg, if it begins with a '-' or '/' check the
  525. // next letter for a valid argument. return error for invalid args
  526. while ((pszArg = *argv++) != NULL)
  527. {
  528. if (*pszArg == '-' || *pszArg == '/')
  529. {
  530. switch (tolower(*(++pszArg)))
  531. {
  532. case 'w':
  533. dwRootFlags |= STGM_TRANSACTED;
  534. dwChildFlags |= STGM_TRANSACTED;
  535. break;
  536. case 't':
  537. dwRootFlags |= STGM_TRANSACTED;
  538. dwChildFlags |= STGM_TRANSACTED;
  539. break;
  540. case 's':
  541. strcpy(szSrcPath, ++pszArg);
  542. iSrcPathEnd = strlen(pszArg);
  543. break;
  544. case 'd':
  545. strcpy(szDestPath, ++pszArg);
  546. iDestPathEnd = strlen(pszArg);
  547. break;
  548. case 'z':
  549. LogFile(++pszArg,LOG_INIT);
  550. break;
  551. case 'y':
  552. SetDebugMode(tolower(*(++pszArg)));
  553. break;
  554. case 'n':
  555. if (strlen(++pszArg) <= _MAX_PATH)
  556. {
  557. strcpy(szDestDocfile, pszArg);
  558. }
  559. else
  560. {
  561. tprintf(DEST_LOG, "Dest DocFile Name too long: %s\n",
  562. pszArg);
  563. tprintf(DEST_LOG, "Max len = %d\n", _MAX_PATH);
  564. tprintf(DEST_LOG, "Specified len = %d\n", strlen(pszArg));
  565. ArgsOK = FALSE;
  566. }
  567. break;
  568. case 'f':
  569. // Docfile to tree
  570. dwRootFlags &= ~0x03; // clear access bits
  571. dwRootFlags |= STGM_READ;
  572. ret=DOCTOTREE;
  573. break;
  574. case 'b':
  575. // Tree to docfile
  576. dwRootFlags &= ~0x70;
  577. dwRootFlags |= STGM_SHARE_EXCLUSIVE;
  578. ret=TREETODOC;
  579. break;
  580. default:
  581. ArgsOK = FALSE;
  582. break;
  583. }
  584. }
  585. else
  586. ArgsOK = FALSE;
  587. if (ArgsOK == FALSE)
  588. {
  589. tprintf(DEST_LOG,
  590. "Invalid command line argument: %s\n", --pszArg);
  591. Usage(pszProgName);
  592. }
  593. }
  594. return ret;
  595. }
  596. //+----------------------------------------------------------------------------
  597. // Function: Usage, private
  598. //
  599. // Synopsis: displays program syntax and example and exits with error
  600. //
  601. // Arguments: [pszProgramName] - name of this executable file for error usage
  602. //
  603. // Created: RichE, January 15, 1992
  604. // Revised: t-chrisy, June 30, 1992 Added -f and -b options.
  605. //+----------------------------------------------------------------------------
  606. void Usage(char *pszProgName)
  607. {
  608. tprintf(DEST_ERR, "Usage: %s\n", pszProgName);
  609. tprintf(DEST_ERR, " [-f] - forward conversion"
  610. "(docfile-->tree) DEFAULT\n");
  611. tprintf(DEST_ERR, " -n and -d must be specified.");
  612. tprintf(DEST_ERR, " [-b] - backward conversion"
  613. "(tree-->docfile)\n");
  614. tprintf(DEST_ERR, " -s and -n must be specified.");
  615. tprintf(DEST_ERR, " [-sSRCDIR] \n");
  616. tprintf(DEST_ERR, " [-nDOCFILENAME] \n");
  617. tprintf(DEST_ERR, " [-dDESTDIR] \n");
  618. tprintf(DEST_ERR, " [-t] - for transacted mode\n");
  619. tprintf(DEST_ERR, " [-w] - for deny write mode\n");
  620. ErrExit(DEST_ERR, ERR, " ex: %df2t -b -sc:\\dos -nd:\\docfile.dfl\n",
  621. pszProgName);
  622. }