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.

606 lines
16 KiB

  1. /************************************************************/
  2. /* Windows Write, Copyright 1985-1992 Microsoft Corporation */
  3. /************************************************************/
  4. /* Open.c -- WRITE document opening */
  5. #define NOCLIPBOARD
  6. #define NOGDICAPMASKS
  7. #define NOVIRTUALKEYCODES
  8. #define NOWINMESSAGES
  9. #define NOSYSMETRICS
  10. #define NOMENUS
  11. #define NOICON
  12. #define NOKEYSTATE
  13. #define NOSYSCOMMANDS
  14. #define NORASTEROPS
  15. //#define NOATOM
  16. #define NOBITMAP
  17. #define NOPEN
  18. #define NODRAWTEXT
  19. #define NOCOLOR
  20. #define NOCREATESTRUCT
  21. #define NOHDC
  22. #define NOMETAFILE
  23. #define NOMSG
  24. #define NOPOINT
  25. #define NORECT
  26. #define NOREGION
  27. #define NOSCROLL
  28. #define NOWH
  29. #define NOWINOFFSETS
  30. #define NOSOUND
  31. #define NOCOMM
  32. #define NORESOURCE
  33. #include <windows.h>
  34. #include "mw.h"
  35. #include "doslib.h"
  36. #include "dispdefs.h"
  37. #define NOUAC
  38. #include "cmddefs.h"
  39. #include "wwdefs.h"
  40. #include "docdefs.h"
  41. #include "fontdefs.h"
  42. #include "editdefs.h"
  43. #include "filedefs.h"
  44. #include "propdefs.h"
  45. #include "fkpdefs.h"
  46. #define NOSTRUNDO
  47. #define NOSTRMERGE
  48. #include "str.h"
  49. #include "code.h"
  50. #include "prmdefs.h"
  51. #include "obj.h"
  52. #define PAGEONLY
  53. #include "printdef.h" /* printdefs.h */
  54. /*
  55. #include "dlgdefs.h"
  56. */
  57. /* These defines replace dlgdefs.h to combat compiler heap overflows */
  58. #define idiYes IDOK
  59. #define idiNo 3
  60. #define idiCancel IDCANCEL
  61. /* These defines replace heapdefs.h and heapdata.h for the same
  62. irritating reason */
  63. #define cwSaveAlloc (128)
  64. #define cwHeapMinPerWindow (50)
  65. #define cwHeapSpaceMin (60)
  66. /* E X T E R N A L S */
  67. extern CHAR (**vhrgbSave)[];
  68. extern HANDLE hParentWw;
  69. extern HANDLE hMmwModInstance;
  70. extern struct WWD rgwwd[];
  71. extern int wwMac;
  72. extern struct FCB (**hpfnfcb)[];
  73. extern struct DOD (**hpdocdod)[];
  74. extern int docMac;
  75. extern struct WWD *pwwdCur;
  76. extern int fnMac;
  77. extern CHAR stBuf[];
  78. #if WINVER >= 0x300
  79. extern BOOL fError;
  80. #endif
  81. short WCompSzC();
  82. CHAR (**HszCreate())[];
  83. struct FNTB **HfntbCreate();
  84. #ifdef CASHMERE
  85. struct SETB **HsetbCreate();
  86. #else
  87. struct SEP **HsepCreate();
  88. #endif
  89. struct PGTB **HpgtbCreate();
  90. CHAR *PchFromFc( int, typeFC, int * );
  91. CHAR *PchGetPn( int, typePN, int *, int );
  92. typeFC FcMacFromUnformattedFn( int );
  93. int CchReadAtPage( int, typePN, CHAR *, int, int );
  94. struct TBD (**HgtbdCreate(fn))[]
  95. int fn;
  96. { /* Create a MEMO tab table by reading the properties of the first
  97. para of the passed fn and returning a handle. The handle returned will
  98. be 0 if the tab table is not present or null */
  99. struct TBD (**hgtbd)[] = 0;
  100. struct PAP pap;
  101. Assert( (fn != fnNil) && (**hpfnfcb)[fn].fFormatted );
  102. bltc((int *)&pap, 0, cwPAP); /* else we will have garbage tabs */
  103. FcParaLim( fn, (typeFC)cfcPage, (**hpfnfcb)[fn].fcMac, &pap );
  104. if (pap.rgtbd[0].dxa && !FNoHeap( hgtbd = (struct TBD (**)[])HAllocate( cwTBD *
  105. itbdMax )))
  106. {
  107. register struct TBD *ptbd = &pap.rgtbd[0];
  108. pap.rgtbd[itbdMax - 1].dxa = 0; /* just in case a WORD document has more
  109. than 12 tabs */
  110. /* overwrite tabs and leading tab char that WRITE does not support */
  111. for ( ; ptbd->dxa != 0; ptbd++)
  112. {
  113. ptbd->tlc = tlcWhite;
  114. ptbd->opcode = 0;
  115. ptbd->chAlign = 0;
  116. if (ptbd->jc == jcCenter)
  117. ptbd->jc = jcLeft;
  118. else if (ptbd->jc == jcRight)
  119. ptbd->jc = jcBoth;
  120. }
  121. blt( &pap.rgtbd[0], *hgtbd, cwTBD * itbdMax );
  122. }
  123. return hgtbd;
  124. }
  125. struct SEP **HsepCreate(fn)
  126. int fn;
  127. { /* Given an fn for a formatted file, return a handle to an SEP
  128. giving section properties for the file. Returns NULL if
  129. standard properties should be used. If the file has a section
  130. table, the properties from the first section in the table are used */
  131. extern struct SEP vsepNormal;
  132. struct SETB *psetbFile;
  133. typePN pn;
  134. struct SEP **hsep;
  135. struct SED *psed;
  136. CHAR *pchFprop;
  137. int cch;
  138. Assert(fn != fnNil && (**hpfnfcb)[fn].fFormatted);
  139. if ((pn = (**hpfnfcb)[fn].pnSetb) == (**hpfnfcb)[fn].pnBftb)
  140. return (struct SEP **) 0;
  141. psetbFile = (struct SETB *) PchGetPn(fn, pn, &cch, false);
  142. if (psetbFile->csed == 0)
  143. return (struct SEP **)0;
  144. /* File has a section table; copy properties from first SEP */
  145. hsep = (struct SEP **) HAllocate( cwSEP );
  146. if (FNoHeap( hsep ))
  147. return (struct SEP **) hOverflow;
  148. blt( &vsepNormal, *hsep, cwSEP );
  149. psed = &psetbFile->rgsed [0];
  150. if (psed->fc == fcNil)
  151. return (struct SEP **)0;
  152. pchFprop = PchFromFc( fn, psed->fc, &cch );
  153. if (*pchFprop != 0)
  154. {
  155. struct SEP *psep = *hsep;
  156. bltbyte( pchFprop+1, psep, *pchFprop );
  157. #ifndef FIXED_PAGE
  158. /* Some of the section properties must be adjusted to the current page size
  159. (stored in vsepNormal). */
  160. if (psep->xaMac != vsepNormal.xaMac)
  161. {
  162. int dxa = vsepNormal.xaMac - psep->xaMac;
  163. psep->xaMac += dxa;
  164. psep->dxaText = max(psep->dxaText + dxa, dxaMinUseful);
  165. psep->xaPgn += dxa;
  166. }
  167. if (psep->yaMac != vsepNormal.yaMac)
  168. {
  169. int dya = vsepNormal.yaMac - psep->yaMac;
  170. psep->yaMac += dya;
  171. psep->dyaText = max(psep->dyaText + dya, dyaMinUseful);
  172. psep->yaRH2 += dya;
  173. }
  174. #endif /* not FIXED_PAGE */
  175. }
  176. return hsep;
  177. } /* end of H s e p C r e a t e */
  178. struct PGTB **HpgtbCreate(fn)
  179. int fn;
  180. { /* Create a page table from a formatted file */
  181. struct PGTB *ppgtbFile;
  182. typePN pn;
  183. int cchT;
  184. int cpgd;
  185. struct PGTB **hpgtb;
  186. int *pwPgtb;
  187. int cw;
  188. Assert(fn != fnNil && (**hpfnfcb)[fn].fFormatted);
  189. if ((pn = (**hpfnfcb)[fn].pnBftb) == (**hpfnfcb)[fn].pnFfntb)
  190. return (struct PGTB **)0;
  191. ppgtbFile = (struct PGTB *) PchGetPn(fn, pn, &cchT, false);
  192. if ((cpgd = ppgtbFile->cpgd) == 0)
  193. return (struct PGTB **)0;
  194. hpgtb = (struct PGTB **) HAllocate(cw = cwPgtbBase + cpgd * cwPGD);
  195. if (FNoHeap(hpgtb))
  196. return (struct PGTB **)hOverflow;
  197. pwPgtb = (int *) *hpgtb;
  198. blt(ppgtbFile, pwPgtb, min(cwSector, cw));
  199. while ((cw -= cwSector) > 0)
  200. { /* Copy the pgd's to heap */
  201. blt(PchGetPn(fn, ++pn, &cchT, false), pwPgtb += cwSector,
  202. min(cwSector, cw));
  203. }
  204. (*hpgtb)->cpgdMax = cpgd;
  205. return hpgtb;
  206. } /* end of H p g t b C r e a t e */
  207. int FnFromSz( sz ) /* filename is expected as ANSI */
  208. CHAR *sz;
  209. {
  210. int fn;
  211. struct FCB *pfcb;
  212. if (sz[0] == 0)
  213. return fnNil;
  214. /* Mod for Sand: Only return fn if it is on the "current" volume (disk) */
  215. for (fn = 0; fn < fnMac; fn++)
  216. if ((pfcb = &(**hpfnfcb)[fn])->rfn != rfnFree && (WCompSzC((PCH)sz, (PCH)**pfcb->hszFile) == 0)
  217. #ifdef SAND
  218. && (pfcb->vref == vrefFile)
  219. #endif /* SAND */
  220. )
  221. return fn;
  222. return fnNil;
  223. } /* end of F n F r o m S z */
  224. int FnOpenSz( szT, dty, fSearchPath ) /* filename is expected as ANSI */
  225. CHAR *szT;
  226. int dty;
  227. int fSearchPath;
  228. { /* Open an existing file. Returns fnNil if not found */
  229. int fn;
  230. struct FIB fib;
  231. struct FCB *pfcb;
  232. CHAR (**hsz)[];
  233. CHAR sz[cchMaxFile];
  234. bltsz( szT, sz );
  235. sz[cchMaxFile - 1] = 0;
  236. #ifdef DFILE
  237. CommSzSz("FnOpenSz: sz presumed ANSI = ",sz);
  238. #endif
  239. if (sz[0]=='\0')
  240. return fnNil;
  241. if ((fn = FnFromSz(sz)) != fnNil)
  242. { /* File is already open -- re-open it, in case it was changed by
  243. another app */
  244. FreeFn( fn );
  245. }
  246. if ((fn = FnAlloc()) == fnNil)
  247. return fnNil;
  248. if (FNoHeap((hsz = HszCreate((PCH)sz))))
  249. return fnNil;
  250. pfcb = &(**hpfnfcb)[fn];
  251. Assert( !pfcb->fSearchPath );
  252. if (fSearchPath)
  253. pfcb->fSearchPath = TRUE;
  254. pfcb->mdFile = mdBinary; /* Try R/W first, will be smashed to RO if needed */
  255. pfcb->dty = pfcb->mdExt = (dty == dtyNormNoExt) ? dtyNormal : dty;
  256. pfcb->hszFile = hsz;
  257. {
  258. OFSTRUCT of;
  259. SetErrorMode(1);
  260. if (OpenFile(sz, (LPOFSTRUCT) &of, OF_EXIST) == -1)
  261. /* this is much cleaner than FAccessFn() for check existance */
  262. {
  263. char szMsg[cchMaxSz];
  264. extern int vfInitializing;
  265. int fT = vfInitializing;
  266. vfInitializing = FALSE; /* Report this err, even during inz */
  267. MergeStrings ((of.nErrCode == dosxSharing) ? IDPMTCantShare:IDPMTCantOpen, sz, szMsg);
  268. IdPromptBoxSz(vhWndMsgBoxParent ? vhWndMsgBoxParent : hParentWw, szMsg, MB_OK|MB_ICONEXCLAMATION);
  269. vfInitializing = fT;
  270. FreeH( (**hpfnfcb) [fn].hszFile);
  271. return fnNil;
  272. }
  273. }
  274. /* dtyNormNoExt is directed at this call */
  275. if (!FAccessFn( fn, dty )) /* HM if error */
  276. {
  277. FreeH( (**hpfnfcb) [fn].hszFile);
  278. return fnNil;
  279. }
  280. /* kludge management (6.21.91) v-dougk */
  281. dty = (dty == dtyNormNoExt) ? dtyNormal : dty;
  282. Assert( (sizeof (struct FIB) == cfcPage) && (cfcPage == cbSector) );
  283. Assert( pfcb == &(**hpfnfcb) [fn] ); /* No HM if FAccessFn succeeds */
  284. if ( (CchReadAtPage( fn, (typePN) 0,
  285. (CHAR *) &fib, cbSector, TRUE ) != cbSector) ||
  286. (fib.wTool != wMagicTool) )
  287. { /* Not a formatted file */
  288. typeFC fcMac = fc0;
  289. int cfc;
  290. if (dty != dtyNormal)
  291. {
  292. char szMsg[cchMaxSz];
  293. PchFillPchId( szMsg, IDPMTBadFile, sizeof(szMsg) );
  294. if (MessageBox(hPARENTWINDOW, (LPSTR)szMsg,
  295. (LPSTR)szAppName, MB_ICONEXCLAMATION|MB_YESNO|MB_DEFBUTTON2) == IDNO)
  296. goto ErrRet;
  297. }
  298. pfcb->fFormatted = false;
  299. /* Obtain file size by seeking to end-of-file */
  300. if ((pfcb->fcMac = fcMac = FcMacFromUnformattedFn( fn )) == (typeFC) -1)
  301. /* Serious error while seeking to file's end */
  302. goto ErrRet;
  303. pfcb->pnMac = (fcMac + cfcPage - 1) / cfcPage;
  304. }
  305. else
  306. { /* File is formatted; use stored fcMac, create run table */
  307. if ((((fib.wIdent != wMagic) && (fib.wIdent != wOleMagic)) ||
  308. (fib.dty != dty)) ||
  309. // some bigwig media guy sent us a Write file whose fcMac was
  310. // trashed (all else was OK). We gotta try to detect this obsure
  311. // potentiality.
  312. (fib.fcMac >= (typeFC)fib.pnPara*128 ) ||
  313. (fib.fcMac > FcMacFromUnformattedFn( fn ))
  314. )
  315. { /* Wrong type of file or corrupted file */
  316. char szMsg[cchMaxSz];
  317. PchFillPchId( szMsg, IDPMTBadFile, sizeof(szMsg) );
  318. if (MessageBox(hPARENTWINDOW, (LPSTR)szMsg,
  319. (LPSTR)szAppName, MB_ICONEXCLAMATION|MB_YESNO|MB_DEFBUTTON2) == IDNO)
  320. goto ErrRet;
  321. }
  322. if ((fib.wIdent == wOleMagic) && !fOleEnabled)
  323. Error(IDPMTFileContainsObjects);
  324. if (fib.pnMac == (typePN)0)
  325. /* KLUDGE to load word files, which don't have ffntb entries. */
  326. fib.pnMac = fib.pnFfntb;
  327. pfcb->fFormatted = true;
  328. pfcb->fcMac = fib.fcMac;
  329. #ifdef p2bSector
  330. pfcb->pnChar = (fib.fcMac + cfcPage - 1) / cfcPage;
  331. #else
  332. pfcb->pnChar = (fib.fcMac + cfcPage - 1) / cfcPage;
  333. #endif
  334. pfcb->pnPara = fib.pnPara;
  335. pfcb->pnFntb = fib.pnFntb;
  336. pfcb->pnSep = fib.pnSep;
  337. pfcb->pnSetb = fib.pnSetb;
  338. pfcb->pnBftb = fib.pnBftb;
  339. pfcb->pnFfntb = fib.pnFfntb;
  340. pfcb->pnMac = fib.pnMac;
  341. if (dty != dtyPrd)
  342. {
  343. if (FNoHeap(hsz = HszCreate((PCH)fib.szSsht)))
  344. goto ErrRet;
  345. (**hpfnfcb)[fn].hszSsht = hsz;
  346. if (!FMakeRunTables(fn))
  347. goto ErrRet;
  348. }
  349. }
  350. return fn;
  351. ErrRet:
  352. (pfcb = &(**hpfnfcb)[fn])->rfn = rfnFree;
  353. FreeH(pfcb->hszFile);
  354. return fnNil;
  355. } /* end of F n O p e n S z */
  356. /*---------------------------------------------------------------------------
  357. -- Routine: WCompSzC(psz1,psz2)
  358. -- Description and Usage:
  359. Alphabetically compares the two null-terminated strings psz1 and psz2.
  360. Upper case alpha characters are mapped to lower case.
  361. Comparison of non-alpha characters is by ascii code.
  362. Returns 0 if they are equal, a negative number if psz1 precedes psz2, and
  363. a non-zero positive number if psz2 precedes psz1.
  364. -- Arguments:
  365. psz1, psz2 - pointers to two null-terminated strings to compare
  366. -- Returns:
  367. a short - 0 if strings are equal, negative number if psz1 precedes psz2,
  368. and non-zero positive number if psz2 precedes psz1.
  369. -- Side-effects: none
  370. -- Bugs:
  371. -- History:
  372. 3/14/83 - created (tsr)
  373. ----------------------------------------------------------------------------*/
  374. short
  375. WCompSzC(psz1,psz2)
  376. PCH psz1;
  377. PCH psz2;
  378. {
  379. int ch1;
  380. int ch2;
  381. for(ch1=ChLowerC(*psz1++),ch2=ChLowerC(*psz2++);
  382. ch1==ch2;
  383. ch1=ChLowerC(*psz1++),ch2=ChLowerC(*psz2++))
  384. {
  385. if(ch1 == '\0')
  386. return(0);
  387. }
  388. return(ch1-ch2);
  389. } /* end of W C o m p S z C */
  390. /*---------------------------------------------------------------------------
  391. -- Routine: ChLowerC(ch)
  392. -- Description and Usage:
  393. Converts its argument to lower case iff its argument is upper case.
  394. Returns the de-capitalized character or the initial char if it wasn't caps.
  395. -- Arguments:
  396. ch - character to be de-capitalized
  397. -- Returns:
  398. a character - initial character, de-capitalized if needed.
  399. -- Side-effects:
  400. -- Bugs:
  401. -- History:
  402. 3/14/83 - created (tsr)
  403. ----------------------------------------------------------------------------*/
  404. int
  405. ChLowerC(ch)
  406. register CHAR ch;
  407. {
  408. if(isupper(ch))
  409. return(ch + ('a' - 'A')); /* foreign is taken care of */
  410. else
  411. return ch;
  412. } /* end of C h L o w e r C */
  413. #ifdef JAPAN
  414. // Compare ch with halfsize-KANA code range, then return whether it is or not.
  415. BOOL IsKanaInDBCS(int ch)
  416. {
  417. ch &= 0x00ff;
  418. if(ch>=0xA1 && ch <= 0xDF) return TRUE;
  419. else return FALSE;
  420. }
  421. #endif
  422. typeFC (**HgfcCollect(fn, pnFirst, pnLim))[]
  423. typePN pnFirst, pnLim;
  424. { /* Create a table indexing fc's by fkp number */
  425. typeFC fcMac;
  426. typePN pn;
  427. int ifcMac, ifc;
  428. typeFC (**hgfc)[];
  429. struct FKP fkp;
  430. fcMac = (**hpfnfcb)[fn].fcMac;
  431. pn = pnFirst + 1;
  432. ifcMac = ifcMacInit; /* Length of table */
  433. hgfc = (typeFC (**)[])HAllocate((ifcMacInit * sizeof(typeFC)) / sizeof(int));
  434. if (FNoHeap(hgfc))
  435. return (typeFC (**)[])hOverflow;
  436. for (ifc = 0; ; ++ifc, ++pn)
  437. { /* Put first fcLim of each fkp in table */
  438. if (ifc >= ifcMac)
  439. { /* Must grow table */
  440. int cw = ((ifcMac += ifcMacInit) * sizeof (typeFC)) / sizeof(int);
  441. if (!FChngSizeH(hgfc, cw, false))
  442. {
  443. LHFGCErrRet:
  444. FreeH(hgfc);
  445. return (typeFC (**)[])hOverflow;
  446. }
  447. }
  448. if (pn < pnLim)
  449. { /* Get fcLimFkb from fcFirst of next page */
  450. int cch;
  451. cch = CchReadAtPage( fn, pn, (CHAR *) &fkp, cbSector, TRUE );
  452. if (cch != cfcPage)
  453. goto LHFGCErrRet;
  454. (**hgfc)[ifc] = fkp.fcFirst;
  455. }
  456. else
  457. { /* fcLimFkb is fcMac + 1 */
  458. (**hgfc)[ifc] = fcMac + 1;
  459. if (!FChngSizeH(hgfc, ((ifc + 1) * sizeof(typeFC)) / sizeof(int), true))
  460. {
  461. /* Previously ignored bad return value here ..pault 11/3/89 */
  462. goto LHFGCErrRet;
  463. }
  464. return hgfc;
  465. }
  466. }
  467. } /* end of H g f c C o l l e c t */
  468. /* F M A K E R U N T A B L E S */
  469. int FMakeRunTables(fn)
  470. { /* Create two tables of fc-dpn pairs, one for chr's and one for par's */
  471. typeFC (**hgfc)[];
  472. if (FNoHeap(hgfc = HgfcCollect(fn, (**hpfnfcb)[fn].pnChar, (**hpfnfcb)[fn].pnPara)))
  473. return false;
  474. (**hpfnfcb)[fn].hgfcChp = hgfc;
  475. if (FNoHeap(hgfc = HgfcCollect(fn, (**hpfnfcb)[fn].pnPara, (**hpfnfcb)[fn].pnFntb)))
  476. {
  477. FreeH( (**hpfnfcb) [fn].hgfcChp );
  478. return false;
  479. }
  480. (**hpfnfcb)[fn].hgfcPap = hgfc;
  481. return true;
  482. } /* end of F M a k e R u n T a b l e */
  483. FApplyOldWordSprm(doc)
  484. /* applies a sprm to this doc which causes all "old word" fonts to be remapped
  485. into new windows ones */
  486. {
  487. CHAR rgbSprm[7];
  488. extern int vfSysFull;
  489. /* set up the OldFtc sprm mapping */
  490. rgbSprm[0] = sprmCOldFtc;
  491. rgbSprm[1] = 5;
  492. rgbSprm[2 + iftcModern] = FtcScanDocFfn(doc, PffnDefault(FF_MODERN));
  493. rgbSprm[2 + iftcRoman] = FtcScanDocFfn(doc, PffnDefault(FF_ROMAN));
  494. rgbSprm[2 + iftcScript] = FtcScanDocFfn(doc, PffnDefault(FF_SCRIPT));
  495. rgbSprm[2 + iftcDecorative] = FtcScanDocFfn(doc, PffnDefault(FF_DECORATIVE));
  496. rgbSprm[2 + iftcSwiss] = FtcScanDocFfn(doc, PffnDefault(FF_SWISS));
  497. AddSprmCps(rgbSprm, doc, (typeCP)0, (**hpdocdod)[doc].cpMac);
  498. return(vfSysFull == 0);
  499. }
  500.