|
|
1.1 root 1: #define NOCOMM
2: #define NOVIRTUALKEYCODES
3: #define NOWINMESSAGES
4: #include "cardfile.h"
5:
6: /*********************************************************************/
7: /* Windows/PM Cardfile Shared Code */
8: /* */
9: /* (c) Copyright Microsoft Corp. 1987,1988 - All Rights Reserved */
10: /*********************************************************************/
11:
12: /*********************************************************************/
13: /* The following shared code was developed from the original */
14: /* Cardfile application. This code can be compiled to run under */
15: /* either the Windows or the PM manager environment. All */
16: /* functionality associated with bitmaps or printing has been */
17: /* deleted. Some comments refering to these functions may still be */
18: /* present in the code and should be disregarded. jw. */
19: /*********************************************************************/
20:
21:
22: /*********************************************************************/
23: /* This file contains the routines for writing and reading */
24: /* information to the disk. All of the procedures in this file */
25: /* consist entirely of shared code. */
26: /*********************************************************************/
27:
28:
29:
30: /*********************************************************************/
31: /* */
32: /* cardfile data files are layed out with the following format: */
33: /* three magic bytes "MGC" */
34: /* a word count of cards in the file */
35: /* array of cardheaders, each one containing: */
36: /* */
37: /* char reserved[6]; bytes available for future use */
38: /* unsigned long lfData; file offset of data */
39: /* unsigned char flags; flags */
40: /* char line[LINELENGTH+1]; 40 character lines plus null */
41: /* */
42: /* These are stored sorted in alphabetical order on the */
43: /* header (line). */
44: /* */
45: /* Following the headers are the cards' data. lfData in a card's */
46: /* header points to somewhere in this area. Each card's data is */
47: /* layed out like this: */
48: /* */
49: /* unsigned bmSize; size in bytes of the bitmap */
50: /* Ooops, this won't work so well when we get 64K bitmaps */
51: /* (Must be 0 for this time round!) */
52: /* */
53: /* If bmSize is > 0 then the card has a bitmap, and then next */
54: /* bytes contain: */
55: /* */
56: /* int cxBitmap; cx in pixels of bitmap */
57: /* int cyBitmap; cy in pixels of bitmap */
58: /* int cxEighths; (x coord of bitmap * 8) / cxFont */
59: /* int cyEighths; (y coord of bitmap * 8) / cyFont */
60: /* BYTE bmBits[bmSize] bitmap bits */
61: /* */
62: /* The x and y coords are in the funny format so that the bitmap */
63: /* will appear in roughly the same place on the card on different */
64: /* displays. */
65: /* */
66: /* Following the bitmap information is the card's text */
67: /* */
68: /* unsigned tSize; size in bytes */
69: /* char Text[tSize]; text characters */
70: /* */
71: /* */
72: /*********************************************************************/
73:
74:
75: /*********************************************************************/
76: /* MergeCardFile - */
77: /* Merges the file specified by pchName into the current file. */
78: /* */
79: /* Same for PM and Windows */
80: /*********************************************************************/
81:
82: BOOL FAR MergeCardFile(pchName)
83: PSTR pchName;
84: {
85: int fh;
86: unsigned i;
87: char buf[PATHMAX];
88: char MaGiC[4];
89: OFSTRUCT mergereopen;
90: LPSTR lpText;
91: HANDLE hText;
92: unsigned cMergeCards;
93: unsigned tSize;
94: unsigned lTemp;
95: unsigned long lCurPos;
96: int result = FALSE;
97:
98: /* if no extension, append the default one */
99: AppendExtension(pchName, buf);
100:
101: /* open file */
102: if ((fh = OpenFile((LPSTR)buf, (LPOFSTRUCT)&mergereopen,
103: OF_PROMPT | OF_CANCEL)) < 0)
104: return(FALSE);
105:
106: /* now read it in */
107: /* check that the first three bytes signify a Cardfile */
108: MaGiC[3] = 0;
109: myread(fh, MaGiC, 3);
110: if (Mylstrcmp(MaGiC, "MGC"))
111: {
112: CardfileOkError(IDS_ENOTVALIDFILE);
113: goto MergeClean;
114: }
115:
116: /* read the number of cards in the file */
117: myread(fh, (PSTR)&cMergeCards, sizeof(int));
118:
119: /* allocate enough memory for the file */
120: lTemp = (cCards+cMergeCards)*sizeof(CARDHEADER);
121: if (!GlobalReAlloc(hCards, lTemp, GMEM_MOVEABLE))
122: {
123: MergeInsMem:
124: CardfileOkError(IDS_EINSMEMORY);
125: goto MergeClean;
126: }
127:
128: /* allocate a buffer for the text on the cards */
129: hText = GlobalAlloc(GHND, (long)CARDTEXTSIZE);
130: if (!hText)
131: goto MergeInsMem;
132: lpText = GlobalLock(hText);
133:
134: /* for each card in the merged file */
135: for(i = 0; i < cMergeCards; ++i)
136: {
137: /* read its header */
138: myread(fh, (PSTR)&CurCardHead, sizeof(CARDHEADER));
139: /* save current position, and seek to the data */
140: lCurPos = MyLseek(fh, 0L, 1);
141: MyLseek(fh, CurCardHead.lfData, 0);
142:
143: CurCard.hBitmap = 0;
144:
145: /* if there's a bitmap, display an error */
146: myread(fh, (PSTR)&CurCard.bmSize, sizeof(int));
147: if (CurCard.bmSize)
148: {
149: CardfileOkError( IDS_NOBITMAP );
150: goto MergeClean;
151: }
152:
153: /* read text size */
154: myread(fh, (PSTR)&tSize, sizeof(int));
155:
156: /* make sure text is no bigger than buffer */
157: if (tSize >= CARDTEXTSIZE)
158: tSize = CARDTEXTSIZE-1;
159:
160: /* read text */
161: mylread(fh, (LPSTR)lpText, tSize);
162: *(lpText+tSize) = 0;
163:
164: /* write out the card, so we'll be able to get it in the future */
165: if (tSize = WriteCurCard(&CurCardHead, &CurCard, lpText))
166: {
167: iFirstCard = AddCurCard();
168: }
169:
170: /* seek to next header */
171: MyLseek(fh, lCurPos, 0);
172: if (!tSize)
173: goto MergeClean;
174: }
175: GlobalUnlock(hText);
176: GlobalFree(hText);
177: fFileDirty = TRUE;
178: result = TRUE;
179: MergeClean:
180: MyClose(fh);
181: return(result);
182: }
183:
184: /*********************************************************************/
185: /* ReadCardFile - */
186: /* Reads specified cardfile. */
187: /* */
188: /* Same for PM and Windows */
189: /*********************************************************************/
190:
191: BOOL FAR ReadCardFile(pchName)
192: PSTR pchName;
193: {
194: int fh;
195: LPCARDHEADER lpTCards;
196: unsigned i;
197: char buf[PATHMAX];
198: char MaGiC[4];
199: unsigned cNewCards;
200: unsigned lTemp;
201: int result = FALSE;
202: OFSTRUCT tmpmain;
203:
204: /* if no extension, append the default */
205: AppendExtension(pchName, buf);
206:
207: /* open file */
208: if ((fh = OpenFile((LPSTR)buf, (LPOFSTRUCT)&tmpmain,
209: OF_PROMPT | OF_CANCEL)) < 0)
210: return(FALSE);
211:
212: /* now read it in, and verify that it's a cardfile */
213: MaGiC[3] = 0;
214: myread(fh, (PSTR)MaGiC, 3);
215: if (Mylstrcmp(MaGiC, "MGC"))
216: {
217: CardfileOkError(IDS_ENOTVALIDFILE);
218: goto ReadClean;
219: }
220:
221: /* read the number of cards in the file */
222: myread(fh, (PSTR)&cNewCards, sizeof(int));
223:
224: /* allocate the object to hold all the headers */
225: lTemp = cNewCards * sizeof(CARDHEADER);
226: if (!GlobalReAlloc(hCards, lTemp, GMEM_MOVEABLE))
227: {
228: CardfileOkError(IDS_EINSMEMORY);
229: goto ReadClean;
230: }
231: /* save card count */
232: cCards = cNewCards;
233: lpTCards = (LPCARDHEADER) GlobalLock(hCards);
234:
235: /* for all cards */
236: for(i = 0; i < cNewCards; ++i)
237: {
238: /* read the header, and save it */
239: myread(fh, (PSTR)&CurCardHead, sizeof(CARDHEADER));
240: *lpTCards++ = CurCardHead;
241: }
242: GlobalUnlock(hCards);
243: fFileDirty = FALSE;
244:
245: mainreopen = tmpmain; /* save new OFSTRUCT */
246: Mylstrcpy((LPSTR)CurIFile, (LPSTR)mainreopen.szPathName);
247: result = TRUE;
248: ReadClean:
249: MyClose(fh);
250: return(result);
251: }
252:
253: /*********************************************************************/
254: /* AppendExtension - */
255: /* This routine checks for an extension, and if none exists, */
256: /* appends the default (CRD). A single '.' denotes an extension, so */
257: /* here is what this routine will do: */
258: /* FOO -> FOO.CRD */
259: /* FOO. -> FOO. */
260: /* FOO.BAR -> FOO.BAR */
261: /* */
262: /* Same for PM and Windows */
263: /*********************************************************************/
264:
265: void FAR AppendExtension(pchName, pchBuf)
266: PSTR pchName;
267: PSTR pchBuf;
268: {
269: char *pch1;
270: char ch;
271:
272: /* save name */
273: Mylstrcpy((LPSTR)pchBuf, (LPSTR)pchName);
274:
275: /* get to end */
276: pch1 = pchBuf + Mylstrlen((LPSTR)pchBuf);
277:
278: /* scan backwards for beginning or end of filename */
279: while ((ch = *pch1) != '.' && ch != '\\' && ch != ':' && pch1 > pchBuf)
280: pch1 = FAR_TO_NEAR( AnsiPrev((LPSTR)pchBuf, (LPSTR)pch1) );
281:
282: /* if no '.', need to tack on extension */
283: if (*pch1 != '.')
284: Mylstrcat((LPSTR)pchBuf, (LPSTR)".CRD");
285:
286: /* what the heck, upper case it */
287: AnsiUpper((LPSTR)pchBuf);
288: }
289:
290: /*********************************************************************/
291: /* WriteCardFile - */
292: /* This routine writes out a cardfile */
293: /* */
294: /* Same for PM and Windows */
295: /*********************************************************************/
296:
297: BOOL FAR WriteCardFile(pchName)
298: PSTR pchName;
299: {
300: LPCARDHEADER lpTCards = NULL; /* so cleaning works */
301: char bakName[PATHMAX];
302: unsigned i;
303: int fhBak;
304: int fhDollar;
305: int fhOld;
306: int fh;
307: unsigned long lCurLoc;
308: unsigned long lCardData;
309: unsigned bmSize;
310: HANDLE hText;
311: LPSTR lpText;
312: char buf[PATHMAX];
313: unsigned tSize;
314: int fSameFile;
315: char *pchFileName;
316: int result = FALSE;
317: CARDHEADER CardHeader;
318: LPCARDHEADER lpCards;
319: OFSTRUCT bakofStruct;
320:
321: /* if no extension, append the default one */
322: AppendExtension(pchName, buf);
323:
324: /* if saving to same file, need to save out to temporary one */
325: if (fSameFile = !Mylstrcmp(buf, CurIFile))
326: {
327: /* get a tempfile name */
328: if(!GetTempFileName(CurIFile[0] | TF_FORCEDRIVE, (LPSTR)"CRD", 0,
329: (LPSTR)bakName))
330: goto SaveTempProblem;
331: }
332: else
333: /* otherwise, just save to specified file */
334: Mylstrcpy((LPSTR)bakName, (LPSTR)buf);
335:
336: /* open the new file */
337: fhBak = OpenFile((LPSTR)bakName, (LPOFSTRUCT)&bakofStruct, OF_CREATE);
338: /* open files */
339: if (CurIFile[0])
340: pchFileName = CurIFile;
341: else
342: pchFileName = rgchCardData;
343: /* open temporary file */
344: if (fReadOnly)
345: goto SaveTempProblem;
346:
347: fhDollar = OpenFile((LPSTR)pchFileName, (LPOFSTRUCT)&tmpreopen,
348: OF_PROMPT | OF_REOPEN | 2);
349: if (fhDollar == -1)
350: {
351: SaveTempProblem:
352: CardfileOkError(IDS_EDISKFULLFILE);
353: return(FALSE);
354: }
355: if (fhBak < 0)
356: {
357: goto CantMakeFile;
358: }
359: /* if curifile is null, then won't use fhOld */
360: if (CurIFile[0])
361: fhOld = OpenFile((LPSTR)CurIFile, (LPOFSTRUCT)&mainreopen,
362: OF_PROMPT | OF_REOPEN);
363:
364: if (MyLseek(fhBak, 0L, 0) == -1)
365: {
366: if (CurIFile[0])
367: MyClose(fhOld);
368: CantMakeFile:
369: MyClose(fhDollar);
370: CardfileOkError(IDS_ECANTMAKEFILE);
371: return(FALSE);
372: }
373: /* truncate file */
374: mywrite(fhBak, (PSTR)"", 0);
375:
376: /* write out cardfile magic bytes */
377: mywrite(fhBak, (PSTR)"MGC", 3);
378:
379: /* write the number of cards in the file */
380: mywrite(fhBak, (PSTR)&cCards, sizeof(int));
381: lCardData = MyLseek(fhBak, 0L, 1) + (cCards * sizeof(CARDHEADER));
382:
383: /* allocate buf for card text */
384: hText = GlobalAlloc(GHND, (long)CARDTEXTSIZE);
385: if (!hText)
386: {
387: MyClose(fhBak);
388: MyClose(fhOld);
389: MyClose(fhDollar);
390: Fdelete(bakName);
391: CardfileOkError(IDS_EINSMEMORY);
392: goto WriteFileClean;
393: }
394:
395: lpText = (LPSTR)GlobalLock(hText);
396:
397: /* lock down the card headers */
398: lpCards = lpTCards = (LPCARDHEADER) GlobalLock(hCards);
399:
400: /* for each card in file */
401: for(i = 0; i < cCards; ++i)
402: {
403: /* see where the card's data is */
404: if (lpTCards->flags & FTMPFILE)
405: fh = fhDollar;
406: else
407: fh = fhOld;
408: /* seek to data */
409: MyLseek(fh, lpTCards->lfData, 0);
410: /* get header */
411: CardHeader = *lpTCards++;
412: /* clear out tmpfile bit */
413: CardHeader.flags &= (!FTMPFILE);
414: CardHeader.lfData = lCardData;
415: /* write header */
416: if (mylwrite(fhBak, (LPSTR)&CardHeader, sizeof(CARDHEADER))
417: < sizeof(CARDHEADER))
418: goto WFDiskFull;
419: lCurLoc = MyLseek(fhBak, 0L, 1);
420: /* seek to data spot in new file */
421: MyLseek(fhBak, lCardData, 0);
422: myread(fh, (PSTR)&bmSize, sizeof(int));
423: mywrite(fhBak, (PSTR)&bmSize, sizeof(int));
424:
425: /* save text */
426: myread(fh, (PSTR)&tSize, sizeof(int));
427: if (mywrite(fhBak, (PSTR)&tSize, sizeof(int)) < sizeof(int))
428: goto WFDiskFull;
429: mylread(fh, (LPSTR)lpText, tSize);
430: if (mylwrite(fhBak, (LPSTR)lpText, tSize) < tSize)
431: {
432: WFDiskFull:
433: MyClose(fhBak);
434: MyClose(fhOld);
435: MyClose(fhDollar);
436: Fdelete(bakName);
437: CardfileOkError(IDS_EDISKFULLFILE);
438: goto WriteFileClean;
439: }
440:
441: lCardData = MyLseek(fhBak, 0L, 1);
442: MyLseek(fhBak, lCurLoc, 0);
443: }
444: MyClose(fhBak);
445: if (CurIFile[0])
446: MyClose(fhOld);
447: MyLseek(fhDollar, 0L, 0);
448: mywrite(fhDollar, (PSTR)"", 0);
449: MyClose(fhDollar);
450: if (fSameFile)
451: {
452: Fdelete(buf);
453: Frename(bakName, buf);
454: fhOld = OpenFile((LPSTR)buf, (LPOFSTRUCT)&mainreopen, 2);
455: }
456: else
457: {
458: AnsiUpper((LPSTR)CurIFile);
459: fhOld = OpenFile((LPSTR)bakName, (LPOFSTRUCT)&mainreopen, 2);
460: }
461:
462: Mylstrcpy((LPSTR)CurIFile, (LPSTR)mainreopen.szPathName);
463:
464: MyLseek(fhOld, 5L, 0);
465: lpTCards = lpCards;
466: for(i = 0; i < cCards; ++i)
467: {
468: myread(fhOld, (PSTR)&CardHeader, sizeof(CARDHEADER));
469: *lpTCards++ = CardHeader;
470: }
471: MyClose(fhOld);
472: fFileDirty = FALSE;
473: result = TRUE;
474: WriteFileClean:
475: if (hText)
476: {
477: GlobalUnlock(hText);
478: GlobalFree(hText);
479: }
480: if (lpTCards)
481: GlobalUnlock(hCards);
482: return(result);
483: }
484:
485: /*********************************************************************/
486: /* WriteCurCard - */
487: /* Write out the data for the current card */
488: /* */
489: /* Same for PM and Windows */
490: /*********************************************************************/
491:
492: BOOL FAR WriteCurCard(pCardHead, pCard, lpText)
493: PCARDHEADER pCardHead;
494: PCARD pCard;
495: LPSTR lpText;
496: {
497: int fh;
498: unsigned long lEnd;
499: int zero = 0;
500: unsigned tSize;
501: char *pchFileName;
502: unsigned cchWritten;
503:
504: /* get right string in case of error */
505: if (CurIFile[0])
506: pchFileName = CurIFile;
507: else
508: pchFileName = rgchCardData;
509:
510: /* open temp file, if necessary asking for it */
511:
512: fh = OpenFile((LPSTR)pchFileName, (LPOFSTRUCT)&tmpreopen,
513: OF_CANCEL | OF_PROMPT | OF_REOPEN | 2);
514: if (fh == -1)
515: {
516: CardfileOkError(IDS_EOPENTEMPSAVE);
517: return(FALSE);
518: }
519:
520: /* seek to end of temp file */
521: lEnd = MyLseek(fh, 0L, 2);
522:
523: mywrite(fh, (PSTR)&zero, sizeof(int));
524:
525: /* save text */
526: tSize = Mylstrlen((LPSTR)lpText);
527: if (tSize >= CARDTEXTSIZE)
528: tSize = CARDTEXTSIZE-1;
529: if (mywrite(fh, (PSTR)&tSize, sizeof(int)) < sizeof(int))
530: goto WCDiskFull;
531: cchWritten = mylwrite(fh, (LPSTR)lpText, tSize);
532: MyClose(fh);
533: if (cchWritten < tSize)
534: {
535: WCDiskFull:
536: CardfileOkError(IDS_EDISKFULLSAVE);
537: return(FALSE);
538: }
539: pCardHead->flags |= FTMPFILE;
540: pCardHead->lfData = lEnd;
541: return(TRUE);
542: }
543:
544: /*********************************************************************/
545: /* ReadCurData - */
546: /* Read current card's data */
547: /* */
548: /* Same for PM and Windows */
549: /*********************************************************************/
550:
551: BOOL FAR ReadCurCardData(pCardHead, pCard, lpText)
552: PCARDHEADER pCardHead;
553: PCARD pCard;
554: LPSTR lpText;
555: {
556: int fh;
557: unsigned tSize;
558: char *pchFileName;
559: int result = TRUE;
560:
561: /* assume no bitmap */
562: pCard->hBitmap = 0;
563:
564: /* if a new card, then can't get it out of any file */
565: if (pCardHead->flags & FNEW)
566: {
567: /* no text */
568: lpText = (LPSTR)"";
569: return(result);
570: }
571:
572: /* if data is in temp file, get the right file handle */
573: if (pCardHead->flags & FTMPFILE)
574: {
575: if (CurIFile[0])
576: pchFileName = CurIFile;
577: else
578: pchFileName = rgchCardData;
579: fh = OpenFile((LPSTR)pchFileName, (LPOFSTRUCT)&tmpreopen,
580: OF_PROMPT | OF_REOPEN | 2);
581: }
582: else
583: fh = OpenFile((LPSTR)CurIFile, (LPOFSTRUCT)&mainreopen,
584: OF_PROMPT | OF_REOPEN);
585:
586: /* seek to data */
587: MyLseek(fh, pCardHead->lfData, 0);
588:
589: /* This must be 0 */
590: myread(fh, (PSTR)&(pCard->bmSize), sizeof(int));
591:
592: /* read text */
593: myread(fh, (PSTR)&tSize, sizeof(int));
594: if (tSize >= CARDTEXTSIZE)
595: tSize = CARDTEXTSIZE-1;
596: mylread(fh, (LPSTR)lpText, tSize);
597: *(lpText+tSize) = 0;
598: MyClose(fh);
599: return (result);
600: }
601:
602: /*********************************************************************/
603: /* MakeTmpFile - */
604: /* Create a temporary file, with a random name provided by system */
605: /* */
606: /* Same for PM and Windows */
607: /*********************************************************************/
608:
609: void FAR MakeTmpFile()
610: {
611: int fh;
612:
613: if(GetTempFileName(CurIFile[0], (LPSTR)"CRD", 0, (LPSTR)TmpFile))
614: {
615: if ((fh = OpenFile((LPSTR)TmpFile, (LPOFSTRUCT)&tmpreopen,
616: OF_CREATE)) < 0)
617: goto CantMakeTmp;
618: else
619: MyClose(fh);
620: }
621: else
622: {
623: /* if can't make temp file, mark "read only", although I'm sure */
624: /* this readonly stuff doesn't work well. Should rarely happen. */
625: CantMakeTmp:
626: CardfileOkError(IDS_ECANTMAKETEMP);
627: fReadOnly = TRUE;
628: }
629: }
630:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.