source: trunk/tools/dbginfo/kHll.cpp@ 3245

Last change on this file since 3245 was 3245, checked in by bird, 25 years ago

Corrected write.

File size: 24.6 KB
Line 
1/* $Id: kHll.cpp,v 1.5 2000-03-27 07:26:54 bird Exp $
2 *
3 * kHll - Implementation of the class kHll.
4 * That class is used to create HLL debuginfo.
5 *
6 * Copyright (c) 2000 knut st. osmundsen (knut.stange.osmundsen@pmsc.no)
7 *
8 * Project Odin Software License can be found in LICENSE.TXT
9 *
10 */
11
12
13/*******************************************************************************
14* Defined Constants And Macros *
15*******************************************************************************/
16#define INCL_TYPES
17#define INCL_DOSERRORS
18#define FOR_EXEHDR 1 /* exe386.h flag */
19#define DWORD ULONG /* Used by exe386.h / newexe.h */
20#define WORD USHORT /* Used by exe386.h / newexe.h */
21
22
23/*******************************************************************************
24* Internal Functions *
25*******************************************************************************/
26#include <os2.h>
27#include <newexe.h>
28#include <exe386.h>
29
30#include <malloc.h>
31#include <stdio.h>
32#include <string.h>
33#include <stddef.h>
34#include <stdlib.h>
35#include <assert.h>
36
37#include "hll.h"
38#include "kList.h"
39#include "kHll.h"
40
41
42
43
44
45
46/*******************************************************************************
47* *
48* kHllBaseEntry *
49* *
50* kHllBaseEntry *
51* *
52*******************************************************************************/
53
54
55/**
56 * Writes a list to disk.
57 * @returns Number of bytes written.
58 * @returns Count of bytes written on success. (includes 0)
59 * -3 Invalid offsets.
60 * -2 Seek error.
61 * -1 Write error.
62 * @param phFile Output filehandle.
63 * @param pEntry Pointer to the start of the list which is to be written.
64 */
65int kHllBaseEntry::writeList(FILE *phFile, kHllBaseEntry *pEntry)
66{
67 int cch;
68 int cchWritten = 0;
69
70 /*
71 * Loop thru the list and write all the entries to disk.
72 */
73 while (pEntry != NULL)
74 {
75 cchWritten += cch = pEntry->write(phFile);
76 if (cch < 0)
77 return cch;
78 if (cch == 0)
79 return -1;
80 pEntry = (kHllBaseEntry*)pEntry->getNext();
81 }
82
83 return cchWritten;
84}
85
86
87
88
89
90
91/*******************************************************************************
92* *
93* kHllPubSymEntry *
94* *
95* kHllPubSymEntry *
96* *
97*******************************************************************************/
98
99
100
101/**
102 * Creates an HLL public symbol entry.
103 * @param pachName Symbol name.
104 * @param cchName Length of symbol name.
105 * @param off Offset into the object.
106 * @param iObject LX Object index.
107 * @param iType Type index. (index into type table)
108 */
109kHllPubSymEntry::kHllPubSymEntry(
110 const char * pachName,
111 int cchName,
112 unsigned long off,
113 unsigned short iObject,
114 unsigned short iType
115 )
116{
117 pPubSym = (PHLLPUBLICSYM)malloc(cchName + sizeof(HLLPUBLICSYM));
118 assert(pPubSym != NULL);
119
120 pPubSym->cchName = cchName;
121 pPubSym->achName[0] = '\0';
122 strncat((char*)&pPubSym->achName[0], pachName, cchName);
123 pPubSym->off = off;
124 pPubSym->iObject = iObject;
125 pPubSym->iType = iType;
126}
127
128
129
130/**
131 * Destructor.
132 */
133kHllPubSymEntry::~kHllPubSymEntry()
134{
135 if (pPubSym != NULL)
136 free(pPubSym);
137 pPubSym = NULL;
138}
139
140
141
142/**
143 * Write this entry to file.
144 * @returns Number of bytes written.
145 * @param phFile File handle.
146 */
147int kHllPubSymEntry::write(FILE *phFile)
148{
149 assert(pPubSym != NULL);
150 return fwrite(pPubSym,
151 1,
152 offsetof(HLLPUBLICSYM, achName) + pPubSym->cchName,
153 phFile);
154}
155
156
157
158
159
160/*******************************************************************************
161* *
162* kHllModuleEntry *
163* *
164* kHllModuleEntry *
165* *
166*******************************************************************************/
167
168
169
170
171
172
173
174/**
175 * Creates an HLL module entry.
176 * @param pszName Module name. (NULL is not allowed!)
177 * @param iLib Library index.
178 * @param cSegInfo Number of objects in the array.
179 * @param paSegInfo Pointer to an array of objects.
180 */
181kHllModuleEntry::kHllModuleEntry(
182 const char * pszName,
183 unsigned short iLib,
184 unsigned char cSegInfo/*= 0 */,
185 PHLLSEGINFO paSegInfo/*= NULL */
186 )
187: fValidOffsetsAndSizes(FALSE)
188{
189 int i;
190 int cchName;
191 PHLLSEGINFO pSegInfo;
192
193 /*
194 * Debug parameter validations.
195 */
196 assert(pszName != NULL);
197 assert(cSegInfo == 0 || paSegInfo != NULL);
198
199 /*
200 * Allocate data storage and fill HLL structure.
201 */
202 cchName = strlen(pszName);
203 pModule = (PHLLMODULE)malloc(sizeof(HLLMODULE) + cchName +
204 sizeof(HLLSEGINFO) * min((cSegInfo - 1), 3));
205 assert(pModule != NULL);
206 memset(pModule, 0, sizeof(*pModule));
207 pModule->cchName = cchName;
208 strcpy((char*)&pModule->achName[0], pszName);
209 pModule->chVerMajor = 4;
210 pModule->chVerMinor = 0;
211 pModule->cSegInfo = cSegInfo;
212 pModule->iLib = iLib;
213 pModule->usDebugStyle = HLL_MOD_STYLE;
214 pModule->overlay = 0;
215 pModule->pad = 0;
216
217 /* objects */
218 if (cSegInfo > 0)
219 {
220 pModule->SegInfo0.iObject = paSegInfo->iObject;
221 pModule->SegInfo0.cb = paSegInfo->cb;
222 pModule->SegInfo0.off = paSegInfo->off;
223
224 for (i = 1, pSegInfo = (PHLLSEGINFO)&pModule->achName[cchName]; i < cSegInfo; i++, pSegInfo++)
225 {
226 pSegInfo->iObject = paSegInfo[i].iObject;
227 pSegInfo->cb = paSegInfo[i].cb;
228 pSegInfo->off = paSegInfo[i].off;
229 }
230 }
231}
232
233
234/**
235 * Destructor - free storage.
236 */
237kHllModuleEntry::~kHllModuleEntry()
238{
239 if (pModule != NULL)
240 free(pModule);
241 pModule = NULL;
242}
243
244
245
246/**
247 * Adds an object to the module.
248 * @returns Success indicator.
249 * @param iObject LX Object index.
250 * @param off Offset into the object to the module data.
251 * @param cb Size of module data (in the object).
252 */
253BOOL kHllModuleEntry::addSegInfo(
254 unsigned short int iObject,
255 unsigned long off,
256 unsigned long cb
257 )
258{
259 assert(pModule != NULL);
260
261 /*
262 * Reallocate? (Note that we'll initially allocated space for 3 objects.)
263 */
264 if (pModule->cSegInfo >= 3)
265 {
266 void *pv = realloc(pModule, sizeof(HLLMODULE) + pModule->cchName
267 + (pModule->cSegInfo + 1) * sizeof(HLLSEGINFO));
268 assert(pv != NULL);
269 if (pv == NULL)
270 return FALSE;
271 pModule = (PHLLMODULE)pv;
272 }
273
274
275 /*
276 * Add module.
277 */
278 if (pModule->cSegInfo == 0)
279 {
280 pModule->SegInfo0.cb = cb;
281 pModule->SegInfo0.off = off;
282 pModule->SegInfo0.iObject = iObject;
283 }
284 else
285 {
286 PHLLSEGINFO pSegInfo = (PHLLSEGINFO)(pModule->cSegInfo * sizeof(HLLSEGINFO)
287 + pModule->achName[pModule->cchName]);
288 pSegInfo->cb = cb;
289 pSegInfo->off = off;
290 pSegInfo->iObject = iObject;
291 }
292 pModule->cSegInfo++;
293
294 return TRUE;
295}
296
297
298
299/**
300 * Adds a public symbol.
301 * @returns Handle to the symbol. NULL on error.
302 * @param pszName Symbol name.
303 * @param off Offset into the LX Object of the symbol.
304 * @param iObject LX Object index.
305 * @param pvType Type handle. NULL if not type.
306 */
307const void * kHllModuleEntry::addPublicSymbol(
308 const char * pszName,
309 unsigned long int off,
310 unsigned short int iObject,
311 const void * pvType
312 )
313{
314 assert(pszName != NULL);
315 return addPublicSymbol(pszName, strlen(pszName), off, iObject, pvType);
316}
317
318
319
320/**
321 * Adds a public symbol.
322 * @returns Handle to the symbol. NULL on error.
323 * @param pachName Symbol name.
324 * @param cchName Name length.
325 * @param off Offset into the LX Object of the symbol.
326 * @param iObject LX Object index.
327 * @param pvType Type handle. NULL if not type.
328 */
329const void * kHllModuleEntry::addPublicSymbol(
330 const char * pachName,
331 int cchName,
332 unsigned long int off,
333 unsigned short int iObject,
334 const void * pvType
335 )
336{
337 kHllPubSymEntry * pEntry;
338
339 /* parameter assertion */
340 assert(pachName != NULL);
341
342 /*
343 * Create a public symbol entry
344 * Insert into it's list.
345 * Invalidate offsets.
346 */
347 pEntry = new kHllPubSymEntry(
348 pachName,
349 cchName,
350 off,
351 iObject,
352 pvType == NULL ? 0 : -1 //FIXME/TODO: Types->getIndex(pvType); check if 0 or -1.
353 );
354
355 PublicSymbols.insert(pEntry);
356
357 fValidOffsetsAndSizes = FALSE;
358
359 return pEntry;
360}
361
362
363
364
365/**
366 * Write this HLL entry to file.
367 * @returns Count of bytes written. -1 on error.
368 * @param phFile Filehandle.
369 * @param off Current offset into the HLL data.
370 * This is stored and used when making the directory
371 * entries for this module.
372 */
373int kHllModuleEntry::write(FILE *phFile, unsigned long off)
374{
375 int cch;
376 int cchWritten = 0;
377
378 /* validate object state */
379 assert(pModule != NULL);
380
381 /*
382 * Write module HLL data.
383 */
384 offModule = off;
385 cch = fwrite(pModule, 1, offsetof(HLLMODULE, achName) + pModule->cchName, phFile);
386 if (cch != offsetof(HLLMODULE, achName) + pModule->cchName)
387 return -1;
388 cchWritten += cch;
389 cbModule = cch;
390 off += cch;
391
392 /*
393 * Write the lists.
394 * Public Symbols
395 * Types
396 * Symbols
397 * Source
398 */
399 offPublicSymbols = off;
400 cbPublicSymbols = cch = kHllBaseEntry::writeList(phFile, PublicSymbols.getFirst());
401 if (cch < 0)
402 return cch;
403 cchWritten += cch;
404 off += cch;
405
406 /*
407 offTypes = off;
408 cbTypes = cch = kHllBaseEntry::writeList(phFile, Types.getFirst());
409 if (cch < 0)
410 return cch;
411 cchWritten += cch;
412 off += cch;
413
414
415 offSymbols = off;
416 cbSymbols = cch = kHllBaseEntry::writeList(phFile, Symbols.getFirst());
417 if (cch < 0)
418 return cch;
419 cchWritten += cch;
420 off += cch;
421
422 offSource = off;
423 cbSource = cch = kHllBaseEntry::writeList(phFile, Source.getFirst());
424 if (cch < 0)
425 return cch;
426 cchWritten += cch;
427 off += cch;
428 */
429
430 /*
431 * Marks offsets and sizes valid and returns succesfully.
432 */
433 fValidOffsetsAndSizes = TRUE;
434 return cchWritten;
435}
436
437
438
439/**
440 * Writes the directory entries for this module to file.
441 * @returns Count of bytes written on success.
442 * -3 Invalid offsets.
443 * -2 Seek error.
444 * -1 Write error.
445 * 0 no data written (this is an error condition!)
446 * @param phFile Filehandle.
447 * @param iMod Index of this module.
448 */
449int kHllModuleEntry::writeDirEntries(FILE *phFile, unsigned short iMod)
450{
451 HLLDIRENTRY hllDirEntry;
452 int cch;
453 int cchWritten = 0;
454
455 /*
456 * Check that offsets are valid!
457 */
458 assert(fValidOffsetsAndSizes);
459 if (!fValidOffsetsAndSizes)
460 return -3;
461
462 /*
463 * Write Directory Entries.
464 * Module.
465 * Public Symbols. (if any)
466 * Types. (if any)
467 * Symbols. (if any)
468 * Source. (if any)
469 */
470 hllDirEntry.usType = HLL_DE_MODULES;
471 hllDirEntry.cb = cbModule;
472 hllDirEntry.off = offModule;
473 hllDirEntry.iMod = iMod;
474 cch = fwrite(&hllDirEntry, 1, sizeof(hllDirEntry), phFile);
475 if (cch != sizeof(hllDirEntry))
476 return -1;
477 cchWritten += cch;
478
479 if (cbPublicSymbols > 0)
480 {
481 hllDirEntry.usType = HLL_DE_PUBLICS;
482 hllDirEntry.cb = cbPublicSymbols;
483 hllDirEntry.off = offPublicSymbols;
484 hllDirEntry.iMod = iMod;
485 cch = fwrite(&hllDirEntry, 1, sizeof(hllDirEntry), phFile);
486 if (cch != sizeof(hllDirEntry))
487 return -1;
488 cchWritten += cch;
489 }
490
491 /*
492 if (cbTypes > 0)
493 {
494 hllDirEntry.usType = HLL_DE_TYPES;
495 hllDirEntry.cb = cbTypes;
496 hllDirEntry.off = offTypes;
497 hllDirEntry.iMod = iMod;
498 cch = fwrite(&hllDirEntry, 1, sizeof(hllDirEntry), phFile);
499 if (cch != sizeof(hllDirEntry))
500 return -1;
501 cchWritten += cch;
502 }
503
504 if (cbSymbols > 0)
505 {
506 hllDirEntry.usType = HLL_DE_SYMBOLS;
507 hllDirEntry.cb = cbSymbols;
508 hllDirEntry.off = offSymbols;
509 hllDirEntry.iMod = iMod;
510 cch = fwrite(&hllDirEntry, 1, sizeof(hllDirEntry), phFile);
511 if (cch != sizeof(hllDirEntry))
512 return -1;
513 cchWritten += cch;
514 }
515
516 if (cbSource > 0)
517 {
518 hllDirEntry.usType = HLL_DE_IBMSRC;
519 hllDirEntry.cb = cbSource;
520 hllDirEntry.off = offSource;
521 hllDirEntry.iMod = iMod;
522 cch = fwrite(&hllDirEntry, 1, sizeof(hllDirEntry), phFile);
523 if (cch != sizeof(hllDirEntry))
524 return -1;
525 cchWritten += cch;
526 }
527
528 */
529
530 return cchWritten;
531}
532
533
534
535
536
537
538
539
540
541
542
543
544/*******************************************************************************
545* *
546* kHll *
547* *
548* kHll *
549* *
550*******************************************************************************/
551
552
553
554/**
555 * Writes HLL debuginfo to the given file at the current position.
556 * The file should be opened in write mode.
557 * @returns Number of bytes written.
558 * @param phFile Filehandle to output file. Starts writing at current pos.
559 */
560int kHll::write(FILE *phFile)
561{
562 HLLHDR hllHdr;
563 HLLDIR hllDir;
564 kHllModuleEntry * pModule;
565 int cch; /* Number of bytes written to the file in an operation. */
566 int cchWritten = 0; /* Number of bytes written to the file. */
567 long int lPosStart; /* Starting position. */
568 long int lPosDir; /* Directory position. */
569 long int lPos; /* A file position. */
570 int iMod; /* Module index (passed in to writeDirEntries) */
571
572 /* Get starting position. */
573 lPosStart = ftell(phFile);
574
575 /* Make temporary header and write it */
576 memcpy(hllHdr.achSignature, "NB04", 4);
577 hllHdr.offDirectory = 0;
578 hllHdr.ulReserved = 1;
579 cch = fwrite(&hllHdr, 1, sizeof(hllHdr), phFile);
580 if (cch != sizeof(hllHdr))
581 return -1;
582 cchWritten += cch;
583
584
585 /*
586 * Start writing modules
587 */
588 pModule = (kHllModuleEntry*)Modules.getFirst();
589 while (pModule != NULL)
590 {
591 cch = pModule->write(phFile, cchWritten);
592 if (cch <= 0)
593 return cch;
594 cchWritten += cch;
595 pModule = (kHllModuleEntry *)pModule->getNext();
596 }
597
598
599 /*
600 * Write libraries.
601 */
602 //Not implemented yet - TODO/FIXME!
603
604
605 /*
606 * Write directory.
607 * Make and write temporary directory header.
608 * Write directory entries per module.
609 * Write directory entry for libraries.
610 * Remake and rewrite directory header. (correct cEntries)
611 */
612 lPosDir = ftell(phFile);
613 hllDir.cEntries = 0;
614 hllDir.ulReserved = 0; //FIXME/TODO - not quite sure what this is or should be!
615 cch = fwrite(&hllDir, 1, offsetof(HLLDIR, aEntries), phFile);
616 if (cch != offsetof(HLLDIR, aEntries))
617 return -1;
618 cchWritten += cch;
619
620 iMod = 1;
621 pModule = (kHllModuleEntry*)Modules.getFirst();
622 while (pModule != NULL)
623 {
624 cch = pModule->writeDirEntries(phFile, iMod);
625 if (cch == -1)
626 return -1;
627 cchWritten += cch;
628 pModule = (kHllModuleEntry *)pModule->getNext();
629 iMod++;
630 }
631
632 //Library - TODO/FIXME
633
634 lPos = ftell(phFile);
635 hllDir.cEntries = (lPos - lPosDir - offsetof(HLLDIR, aEntries)) / sizeof(HLLDIRENTRY);
636 if (fseek(phFile, lPosDir, SEEK_SET) != 0)
637 return -2;
638 cch = fwrite(&hllDir, 1, offsetof(HLLDIR, aEntries), phFile);
639 if (cch != offsetof(HLLDIR, aEntries))
640 return -1;
641
642 /*
643 * Rewrite HLL header (with correct directory offset).
644 */
645 hllHdr.offDirectory = lPosDir - lPosStart;
646 if (fseek(phFile, lPosStart, SEEK_SET) != 0)
647 return -2;
648 cch = fwrite(&hllHdr, 1, sizeof(hllHdr), phFile);
649 if (cch != sizeof(hllHdr))
650 return -1;
651
652 return cchWritten;
653}
654
655
656
657/**
658 * Constructor - Creates an empty HLL object.
659 */
660kHll::kHll()
661{
662}
663
664
665
666/**
667 * Destructor.
668 */
669kHll::~kHll()
670{
671}
672
673
674
675/**
676 * Adds a module.
677 * @returns Pointer to the module object added. NULL on error.
678 * @param pszName Module name
679 * @param pvLib Library module handle.
680 * @param cSegInfo Number of objects in the array.
681 * @param paSegInfo Pointer to an array of objects.
682 */
683kHllModuleEntry * kHll::addModule(
684 const char * pszName,
685 const void * pvLib,
686 unsigned cSegInfo,
687 PHLLSEGINFO paSegInfo)
688{
689 kHllModuleEntry * pEntry;
690 assert(pszName != NULL);
691
692 pEntry = new kHllModuleEntry(
693 pszName,
694 pvLib == NULL ? 0 : -1, //FIXME/TODO: Libs->getIndex(pvLib); check if 0 or -1;
695 cSegInfo,
696 paSegInfo);
697
698 Modules.insert(pEntry);
699 return pEntry;
700}
701
702
703
704/**
705 * Adds a module.
706 * @returns Pointer to the module object added. NULL on error.
707 * @param pachName Module name
708 * @param cchName Length of modulename
709 * @param pvLib Library module handle.
710 * @param cSegInfo Number of objects in the array.
711 * @param paSegInfo Pointer to an array of objects.
712 */
713kHllModuleEntry * kHll::addModule(
714 const char * pachName,
715 unsigned cchName,
716 const void * pvLib,
717 unsigned cSegInfo,
718 PHLLSEGINFO paSegInfo)
719{
720 char szModName[256];
721 kHllModuleEntry * pEntry;
722 assert(pachName != NULL && cchName > 0);
723
724 szModName[0] = '\0';
725 strncat(szModName, pachName, min(cchName, 255));
726 pEntry = new kHllModuleEntry(
727 szModName,
728 pvLib == NULL ? 0 : -1, //FIXME/TODO: Libs->getIndex(pvLib); check if 0 or -1;
729 cSegInfo,
730 paSegInfo);
731
732 Modules.insert(pEntry);
733 return pEntry;
734}
735
736
737
738/**
739 * Writes the HLL info to a file. (Not LX?)
740 * @returns Success indicator.
741 * @param pszFilename Name of the output file.
742 * @remark IMPORTANT! This is mostly for debugging!
743 * It completely overwrites the file if it exists!
744 */
745BOOL kHll::write(
746 const char *pszFilename
747 )
748{
749 FILE * phFile;
750
751 phFile = fopen(pszFilename, "wb");
752 if (phFile != NULL)
753 {
754 int cch = write(phFile);
755 if (cch > 0)
756 {
757 fclose(phFile);
758 return TRUE;
759 }
760 else
761 fprintf(stderr, "write failed with cch=%d\n", cch);
762 fclose(phFile);
763 }
764
765 return FALSE;
766}
767
768
769
770/**
771 * Writes the HLL info to a file. (Not LX?)
772 * Failes if there is debuginfo in the file.
773 * No backup is made. (sorry)
774 * @returns OS2 return code.
775 * @param pszFilename Name of the output file.
776 */
777APIRET kHll::writeToLX(
778 const char *pszFilename
779 )
780{
781 APIRET rc;
782 FILE * phFile;
783
784 phFile = fopen(pszFilename, "rb+");
785 if (phFile != NULL)
786 {
787 struct exe_hdr ehdr;
788 struct e32_exe e32;
789 int cch;
790 long lPosLXHdr;
791
792 /*
793 * Read exe header
794 */
795 cch = fread(&ehdr, 1, sizeof(ehdr), phFile);
796 if (cch == sizeof(ehdr))
797 {
798 if (ehdr.e_magic == EMAGIC)
799 lPosLXHdr = ehdr.e_lfanew;
800 else
801 lPosLXHdr = 0;
802 if (fseek(phFile, lPosLXHdr, SEEK_SET) == 0)
803 {
804 cch = fread(&e32, 1, sizeof(e32), phFile);
805 if (cch == sizeof(e32))
806 {
807 if (*(unsigned short*)&e32.e32_magic[0] == E32MAGIC)
808 {
809 /*
810 * Found exeheader.
811 * Check if there is any debug info.
812 */
813 if (e32.e32_debuginfo == 0 && e32.e32_debuginfo == 0)
814 {
815 long lPosDebug;
816
817 /*
818 * Go to end of file and write debug info.
819 */
820 if (fseek(phFile, 0, SEEK_END) == 0
821 &&
822 (lPosDebug = ftell(phFile)) != -1
823 )
824 {
825 /*
826 * Write the HLL data to disk.
827 */
828 cch = write(phFile);
829 if (cch > 0)
830 {
831 /*
832 * Update exeheader.
833 */
834 e32.e32_debuglen = cch;
835 e32.e32_debuginfo = lPosDebug;
836 if (fseek(phFile, lPosLXHdr, SEEK_SET) == 0)
837 {
838 /*
839 * Write the updated header to disk.
840 */
841 cch = fwrite(&e32, 1, sizeof(e32), phFile);
842 if (cch == sizeof(e32))
843 rc = NO_ERROR;
844 else
845 rc = ERROR_WRITE_FAULT;
846 }
847 else
848 rc = ERROR_SEEK;
849 }
850 else
851 {
852 fprintf(stderr, "error - write failed with cch=%d\n", cch);
853 rc = ERROR_WRITE_FAULT;
854 }
855 }
856 else
857 rc = ERROR_SEEK;
858 }
859 else
860 {
861 fprintf(stderr, "error - debuginfo exists\n");
862 rc = ERROR_BAD_EXE_FORMAT;
863 }
864
865 }
866 else
867 rc = ERROR_INVALID_EXE_SIGNATURE;
868 }
869 else
870 rc = ERROR_BAD_EXE_FORMAT;
871 }
872 else
873 rc = ERROR_BAD_EXE_FORMAT;
874 }
875 else
876 rc = ERROR_READ_FAULT;
877
878 fclose(phFile);
879 }
880 else
881 rc = ERROR_ACCESS_DENIED; //?
882
883
884 return rc;
885}
886
887
888
Note: See TracBrowser for help on using the repository browser.