mirror of https://github.com/lianthony/NT4.0
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.
724 lines
23 KiB
724 lines
23 KiB
/*****************************************************************/
|
|
/** Microsoft LAN Manager **/
|
|
/** Copyright(c) Microsoft Corp., 1988-1990 **/
|
|
/*****************************************************************/
|
|
/*** DISPLAY.C - Routines to display objects
|
|
*
|
|
* DAMAGE
|
|
* Gregory A. Jones
|
|
*
|
|
* Modification history:
|
|
* G.A. Jones 09/07/88 Original for Pinball testing.
|
|
* G.A. Jones 09/08/88 Coded initial displays and commands.
|
|
* G.A. Jones 09/09/88 Coded more displays, D, N, P, B cmds.
|
|
* G.A. Jones 09/09/88 Moved command stuff to CMD.C.
|
|
* G.A. Jones 09/12/88 Coded DIRBLK display.
|
|
* G.A. Jones 09/13/88 Added bitmap displays.
|
|
* G.A. Jones 09/13/88 Added data and pathname displays.
|
|
* G.A. Jones 09/16/88 Added bad block list displays.
|
|
* G.A. Jones 09/19/88 Removed DIR_UID, DIR_UPRM, etc.
|
|
* G.A. Jones 10/12/88 Moved ATIM, CTIM from FNODE to DIRENT.
|
|
* G.A. Jones 10/19/88 Added dirblk banding support.
|
|
* P.A. Williams 05/31/89 Don't print off end of spare block
|
|
* if have bad SPB_SDBMAX field.
|
|
*/
|
|
|
|
#include <stdio.h>
|
|
#include <time.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
#include "defs.h"
|
|
#include "types.h"
|
|
#include "globals.h"
|
|
|
|
/*** get_time - get pointer to time string
|
|
*
|
|
* This function is called to convert a filesystem structure's
|
|
* timestamp into a displayable string.
|
|
*
|
|
* get_time (time)
|
|
*
|
|
* ENTRY time - number of seconds since 01/01/70
|
|
*
|
|
* EXIT Returns pointer to time string
|
|
*
|
|
* CALLS asctime
|
|
* gmtime
|
|
*
|
|
* WARNINGS Each call to get_time destroys the results of
|
|
* the previous call.
|
|
*
|
|
* EFFECTS None
|
|
*/
|
|
UCHAR *get_time(ULONG time)
|
|
{
|
|
struct tm *tm;
|
|
|
|
time_t Time1;
|
|
|
|
Time1 = (time_t)time;
|
|
|
|
tm = gmtime (&Time1);
|
|
return ((tm != NULL) ? asctime (tm) : "(null)\n");
|
|
}
|
|
|
|
/*** sb_flags - display flags of a superblock
|
|
*
|
|
* This function is called to display the flags field of the super
|
|
* block. It displays an appropriate string for each bit set in
|
|
* the number passed. A newline is printed after the display.
|
|
* All the flags are shown on the same line.
|
|
*
|
|
* sb_flags (flags)
|
|
*
|
|
* ENTRY flags - SB_FLAG field of the super block
|
|
*
|
|
* EXIT No return value
|
|
*
|
|
* CALLS printf
|
|
*
|
|
* WARNINGS None
|
|
*
|
|
* EFFECTS Writes to standard output
|
|
*/
|
|
void sb_flags (ULONG flags)
|
|
{
|
|
if (!flags) {
|
|
printf ("(none)\n");
|
|
return;
|
|
}
|
|
|
|
if (flags & SPF_DIRT)
|
|
printf ("DIRT ");
|
|
if (flags & SPF_SPARE)
|
|
printf ("SPARE ");
|
|
if (flags & SPF_BADSEC)
|
|
printf ("BADSEC ");
|
|
if (flags & SPF_VER)
|
|
printf ("VER ");
|
|
|
|
printf ("\n");
|
|
}
|
|
|
|
/*** ab_flags - display flags of an ALBLK
|
|
*
|
|
* This function is called to display the flags field of an ALBLK
|
|
* structure. It displays an appropriate string for each bit set in
|
|
* the number passed. A newline is printed after the display. All
|
|
* the flags are shown on the same line.
|
|
*
|
|
* ab_flags (flags)
|
|
*
|
|
* ENTRY flags - AB_FLAG field of the ALBLK
|
|
*
|
|
* EXIT No return value
|
|
*
|
|
* CALLS printf
|
|
*
|
|
* WARNINGS The AB_FLAG2 field is not currently used.
|
|
*
|
|
* EFFECTS Writes to standard output
|
|
*/
|
|
void ab_flags (UCHAR flags)
|
|
{
|
|
if (!flags) {
|
|
printf ("(none)\n");
|
|
return;
|
|
}
|
|
|
|
if (flags & ABF_NODE)
|
|
printf ("NODE ");
|
|
if (flags & ABF_BIN)
|
|
printf ("BIN ");
|
|
if (flags & ABF_FNP)
|
|
printf ("FNP ");
|
|
|
|
printf ("\n");
|
|
}
|
|
|
|
/*** dir_flags - display flags of a DIRENT
|
|
*
|
|
* This function is called to display the flags field of a directory
|
|
* entry. It displays an appropriate string for each bit set in the
|
|
* number passed. A newline is printed after the display. All the
|
|
* flags are shown on the same line.
|
|
*
|
|
* Currently, the only DOS flags supported are "directory" and "archive".
|
|
* Of course, all Pinball flags (END, BTP, etc.) are supported.
|
|
*
|
|
* dir_flags (flags)
|
|
*
|
|
* ENTRY flags - DIR_FLAG field of the DIRENT
|
|
*
|
|
* EXIT No return value
|
|
*
|
|
* CALLS printf
|
|
*
|
|
* WARNINGS None
|
|
*
|
|
* EFFECTS Writes to standard output
|
|
*/
|
|
void dir_flags (ULONG flags)
|
|
{
|
|
if (!flags) {
|
|
printf ("(none)\n");
|
|
return;
|
|
}
|
|
|
|
if (flags & DF_SPEC)
|
|
printf ("SPEC ");
|
|
if (flags & DF_ACL)
|
|
printf ("ACL ");
|
|
if (flags & DF_BTP)
|
|
printf ("BTP ");
|
|
if (flags & DF_END)
|
|
printf ("END ");
|
|
if (flags & DF_XACL)
|
|
printf ("XACL ");
|
|
#ifdef CODEPAGE
|
|
if (flags & DF_NEEDEAS)
|
|
printf ("NEAS ");
|
|
#endif
|
|
|
|
#ifndef CODEPAGE
|
|
printf ("| ");
|
|
|
|
if (flags & 0x1000)
|
|
printf ("Dir ");
|
|
if (flags & 0x2000)
|
|
printf ("Arc ");
|
|
#else
|
|
if (flags & 0x1000)
|
|
printf ("| Dir ");
|
|
if (flags & 0x2000)
|
|
printf ("| Arc ");
|
|
if (flags & 0x4000)
|
|
printf ("| New ");
|
|
#endif
|
|
|
|
printf ("\n");
|
|
}
|
|
|
|
/*** display_object - display the contents of an object
|
|
*
|
|
* This function is called to display the contents of an object on
|
|
* the screen. The display is formatted according to the type of
|
|
* the object. Structures are shown with their fields labeled with
|
|
* item numbers, so that the user can easily choose an item to change
|
|
* or push into. DIRBLKs are displayed as the DIRBLK header followed
|
|
* by the DIRENT currently being examined. Data is displayed either
|
|
* as ASCII text or in a debug-style hex dump.
|
|
*
|
|
* display_object ()
|
|
*
|
|
* ENTRY No parameters
|
|
*
|
|
* EXIT No return value
|
|
*
|
|
* CALLS printf
|
|
*
|
|
* WARNINGS None
|
|
*
|
|
* EFFECTS Displays an object on the screen
|
|
*/
|
|
void display_object ()
|
|
{
|
|
struct SuperSpare *s;
|
|
struct FNODE *f;
|
|
struct DIRBLK *d;
|
|
struct ALSEC *a;
|
|
PCPINFOSEC cp;
|
|
PCPINFOENT cpi;
|
|
PCPDATASEC cps;
|
|
PCPDATAENT cpd;
|
|
union dp dp;
|
|
ULONG *l, offset, btp;
|
|
UCHAR *p;
|
|
USHORT i, j;
|
|
|
|
#ifdef TRACE
|
|
fprintf (stderr, "display_object ()\n");
|
|
fflush (stderr);
|
|
#endif
|
|
|
|
switch (currobj.type) {
|
|
case TYPE_SUPERB:
|
|
s = (struct SuperSpare *)currobj.mem;
|
|
if (currobj.offset == FIELDOFFSET (struct SuperSpare, spb)) {
|
|
printf ("Spareblock:\n");
|
|
printf (" 1) SPB_SIG1: %08lx ", s->spb.SPB_SIG1);
|
|
if (s->spb.SPB_SIG1 == SPSIG1)
|
|
printf ("(correct)\n");
|
|
else
|
|
printf ("(should be %08lx)\n", SPSIG1);
|
|
printf (" 2) SPB_SIG2: %08lx ", s->spb.SPB_SIG2);
|
|
if (s->spb.SPB_SIG2 == SPSIG2)
|
|
printf ("(correct)\n");
|
|
else
|
|
printf ("(should be %08lx)\n", SPSIG2);
|
|
printf (" 3) SPB_FLAG: ");
|
|
sb_flags (s->spb.SPB_FLAG);
|
|
printf (" 4) SPB_HFSEC: %08lx\n", s->spb.SPB_HFSEC);
|
|
printf (" 5) SPB_HFUSE: %08lx\n", s->spb.SPB_HFUSE);
|
|
printf (" 6) SPB_HFMAX: %08lx\n", s->spb.SPB_HFMAX);
|
|
printf (" 7) SPB_SDBCNT: %08lx\n", s->spb.SPB_SDBCNT);
|
|
#ifndef CODEPAGE
|
|
printf (" 8) SPB_SDBMAX: %08lx\n\n", s->spb.SPB_SDBMAX);
|
|
#ifdef CHECKSUMS
|
|
printf (" 9) SPB_SUPERBSUM: %08lx\n", s->spb.SPB_SUPERBSUM);
|
|
printf (" 10) SPB_SPAREBSUM: %08lx\n\n", s->spb.SPB_SPAREBSUM);
|
|
#endif
|
|
|
|
/* don't go past end of spare block if have bad SPB_SDBMAX field */
|
|
j = (s->spb.SPB_SDBMAX > 55L) ? 55 : s->spb.SPB_SDBMAX;
|
|
|
|
for (i=0; i<j; i++) {
|
|
#ifdef CHECKSUMS
|
|
printf ("%3d) %08lx ", i+11, s->spb.SPB_SPARDB [i]);
|
|
#else
|
|
printf ("%3d) %08lx ", i+9, s->spb.SPB_SPARDB [i]);
|
|
#endif
|
|
if (!((i+1) % 5))
|
|
printf ("\n");
|
|
}
|
|
if (i % 5)
|
|
printf ("\n");
|
|
}
|
|
#else
|
|
printf (" 8) SPB_SDBMAX: %08lx\n", s->spb.SPB_SDBMAX);
|
|
printf (" 9) SPB_CPSEC: %08lx\n", s->spb.SPB_CPSEC);
|
|
printf (" 10) SPB_CPCNT: %08lx\n\n", s->spb.SPB_CPCNT);
|
|
|
|
/* don't go past end of spare block if have bad SPB_SDBMAX field */
|
|
j = (s->spb.SPB_SDBMAX > 55L) ? 55 : s->spb.SPB_SDBMAX;
|
|
|
|
for (i=0; i<j; i++) {
|
|
printf ("%3d) %08lx ", i+11, s->spb.SPB_SPARDB [i]);
|
|
if (!((i+1) % 5))
|
|
printf ("\n");
|
|
}
|
|
if (i % 5)
|
|
printf ("\n");
|
|
}
|
|
#endif
|
|
else {
|
|
printf ("Superblock:\n");
|
|
printf (" 1) SB_SIG1: %08lx ", s->sb.SB_SIG1);
|
|
if (s->sb.SB_SIG1 == SBSIG1)
|
|
printf ("(correct)\n");
|
|
else
|
|
printf ("(should be %08lx)\n", SBSIG1);
|
|
printf (" 2) SB_SIG2: %08lx ", s->sb.SB_SIG2);
|
|
if (s->sb.SB_SIG2 == SBSIG2)
|
|
printf ("(correct)\n");
|
|
else
|
|
printf ("(should be %08lx)\n", SBSIG2);
|
|
printf (" 3) SB_VER: %02x\n", s->sb.SB_VER);
|
|
printf (" 4) SB_FVER: %02x\n", s->sb.SB_FVER);
|
|
printf (" 5) SB_ROOT: %08lx\n", s->sb.SB_ROOT);
|
|
printf (" 6) SB_SEC: %08lx\n", s->sb.SB_SEC);
|
|
printf (" 7) SB_BSEC: %08lx\n", s->sb.SB_BSEC);
|
|
printf (" 8) SB_BII.P: %08lx\n", s->sb.SB_BII.P);
|
|
printf (" 9) SB_BBL.P: %08lx\n", s->sb.SB_BBL.P);
|
|
printf ("10) SB_CDDAT: %s", get_time (s->sb.SB_CDDAT));
|
|
printf ("11) SB_DODAT: %s", get_time (s->sb.SB_DODAT));
|
|
printf ("12) SB_DBSIZE: %08lx\n", s->sb.SB_DBSIZE);
|
|
printf ("13) SB_DBLOW: %08lx\n", s->sb.SB_DBLOW);
|
|
printf ("14) SB_DBHIGH: %08lx\n", s->sb.SB_DBHIGH);
|
|
printf ("15) SB_DBMAP: %08lx\n", s->sb.SB_DBMAP);
|
|
printf ("16) Spareblock: {..}\n");
|
|
}
|
|
break;
|
|
case TYPE_DBBIT:
|
|
p = (UCHAR *)currobj.mem + currobj.offset;
|
|
printf ("DIRBLK bitmap at sector %08lx, mapping DIRBLKs %04lx to %04lx:\n",
|
|
currobj.sec, currobj.offset * 8L, (currobj.offset + 128L) * 8L - 1);
|
|
for (i=0; i<16; i++) {
|
|
printf ("%06lx ", (currobj.offset + (i * 8)) * 8);
|
|
for (j=0; j<8; j++) {
|
|
_itoa ((unsigned int)(p [i*8+j]), scratch, 2);
|
|
strrev (scratch);
|
|
while (strlen (scratch) < 8)
|
|
strcat (scratch, "0");
|
|
printf (" %s", scratch);
|
|
}
|
|
printf ("\n");
|
|
}
|
|
break;
|
|
case TYPE_BII:
|
|
l = (ULONG *)((UCHAR *)currobj.mem + currobj.offset);
|
|
printf ("Bitmap indirect block at sector %08lx, offset %04x bytes:\n",
|
|
currobj.sec, currobj.offset);
|
|
for (i=1; (i<=100) && (i*4+currobj.offset <= 2048); i++) {
|
|
printf ("%3d) %08lx ", i, l [i-1]);
|
|
if (!(i % 5))
|
|
printf ("\n");
|
|
}
|
|
if ((i-1) % 5)
|
|
printf ("\n");
|
|
break;
|
|
case TYPE_BITMAP:
|
|
p = (UCHAR *)currobj.mem + currobj.offset;
|
|
printf ("Bitmap at sector %08lx, mapping sectors %06lx to %06lx:\n",
|
|
currobj.sec, (currobj.scratch * 2048L + currobj.offset) * 8L,
|
|
(currobj.scratch * 2048L + currobj.offset + 128L) * 8L - 1);
|
|
for (i=0; i<16; i++) {
|
|
printf ("%06lx ",
|
|
(currobj.scratch * 2048L + currobj.offset + (i * 8)) * 8);
|
|
for (j=0; j<8; j++) {
|
|
_itoa ((unsigned int)(p [i*8+j]), scratch, 2);
|
|
strrev (scratch);
|
|
while (strlen (scratch) < 8)
|
|
strcat (scratch, "0");
|
|
printf (" %s", scratch);
|
|
}
|
|
printf ("\n");
|
|
}
|
|
break;
|
|
case TYPE_BBL:
|
|
l = (ULONG *)((UCHAR *)currobj.mem + currobj.offset);
|
|
printf ("Bad block list block at sector %08lx, entries %d-%d:\n",
|
|
currobj.sec, (USHORT)currobj.offset / 4,
|
|
(currobj.offset > 2048-396) ? 511 : ((currobj.offset / 4) + 99));
|
|
printf (" 1) Forward link: %08lx\n\n", *(ULONG *)currobj.mem);
|
|
for (i=1; (i<=100) && (i*4+currobj.offset <= 2048); i++) {
|
|
printf ("%3d) %08lx ", i+1, l [i-1]);
|
|
if (!(i % 5))
|
|
printf ("\n");
|
|
}
|
|
if ((i-1) % 5)
|
|
printf ("\n");
|
|
break;
|
|
case TYPE_HFSEC:
|
|
l = (ULONG *)currobj.mem + currobj.offset;
|
|
|
|
printf ("Hotfix list at sector %08lx, entries %d-%d:\n", currobj.sec,
|
|
(int)currobj.offset + 1,
|
|
(currobj.offset+20 > hfmax) ?
|
|
(int)(hfmax - currobj.offset) : (int)currobj.offset+20);
|
|
printf ("Replacement\tReplaces\tContaining FNODE\n");
|
|
|
|
for (i=0; (i<20) && (currobj.offset+i < hfmax); i++)
|
|
printf ("%3d) %08lx\t%3d) %08lx\t%3d) %08lx\n", i*3+1, *(l+i+hfmax),
|
|
i*3+2, *(l+i), i*3+3, *(l+i+2*hfmax));
|
|
break;
|
|
#ifdef CODEPAGE
|
|
case TYPE_CPSEC:
|
|
cp = (PCPINFOSEC)currobj.mem;
|
|
printf ("Code page information at sector %08lx:\n\n", currobj.sec);
|
|
|
|
if (currobj.offset == FIELDOFFSET (CPINFOSEC, CP_INFO[0])) {
|
|
printf ("CP_INFO CPI_CNTRY CPI_CPID CPI_CHKSUM CPI_DATASEC");
|
|
printf (" CPI_INDEX CPI_RNGECNT\n");
|
|
|
|
for (i = 0; i < cp->CP_INFOCNT; i++) {
|
|
cpi = &cp->CP_INFO[i];
|
|
printf (" [%2d] %3d) %04x %3d) %04x %3d) %08lx",
|
|
i,
|
|
i*iCPI_RNGECNT+1, cpi->CPI_CNTRY,
|
|
i*iCPI_RNGECNT+2, cpi->CPI_CPID,
|
|
i*iCPI_RNGECNT+3, cpi->CPI_CHKSUM);
|
|
printf (" %3d) %08lx %3d) %04x %3d) %04x\n",
|
|
i*iCPI_RNGECNT+4, cpi->CPI_DATASEC,
|
|
i*iCPI_RNGECNT+5, cpi->CPI_INDEX,
|
|
i*iCPI_RNGECNT+6, cpi->CPI_RNGECNT);
|
|
}
|
|
} else {
|
|
|
|
printf (" 1) CP_SIG: %08lx ", cp->CP_SIG);
|
|
if (cp->CP_SIG == CPSIGVAL)
|
|
printf ("(correct)\n");
|
|
else
|
|
printf ("(should be %08lx)\n", CPSIGVAL);
|
|
printf (" 2) CP_INFOCNT: %08lx\n", cp->CP_INFOCNT);
|
|
printf (" 3) CP_INDEX: %08lx\n", cp->CP_INDEX);
|
|
printf (" 4) CP_NEXTSEC: %08lx\n", cp->CP_NEXTSEC);
|
|
printf (" 5) CP_INFO[%2d]: {..}\n", cp->CP_INFOCNT);
|
|
}
|
|
break;
|
|
|
|
case TYPE_CPDATA:
|
|
cps = (PCPDATASEC)currobj.mem;
|
|
printf ("Code page data at sector %08lx:\n\n", currobj.sec);
|
|
|
|
if (currobj.offset == ((PCPDATASEC)currobj.mem)->CPS_OFFSET[0]) {
|
|
cpd = (PCPDATAENT)((UCHAR *)currobj.mem
|
|
+ cps->CPS_OFFSET[currobj.scratch]);
|
|
printf ("Data Entry[%d]:\n", currobj.scratch);
|
|
printf (" 1) CPD_CNTRY: %04x\n", cpd->CPD_CNTRY);
|
|
printf (" 2) CPD_CPID: %04x\n", cpd->CPD_CPID);
|
|
printf (" 3) CPD_RNGECNT: %04x\n", cpd->CPD_RNGECNT);
|
|
printf (" 4) CPD_TABLE[128]:");
|
|
for (j = 0; j < 128; j++)
|
|
if ( (j % 22) == 0 )
|
|
printf ("\n [%3d-%3d]:", j, j>128-22 ? 127 : j+21);
|
|
else
|
|
printf (" %02x", cpd->CPD_TABLE[j]);
|
|
|
|
printf("\n\n");
|
|
|
|
for (j = 0; j <= cpd->CPD_RNGECNT; j++)
|
|
printf("%2d) CPD_RNGE[%d].start: %02x %2d) CPD_RNGE[%d].end: %02x\n",
|
|
iCPD_RNGE+2*j, j, cpd->CPD_RNGE[j].dbcs_rnge_start,
|
|
iCPD_RNGE+2*j+1, j, cpd->CPD_RNGE[j].dbcs_rnge_end);
|
|
} else {
|
|
printf (" 1) CPS_SIG: %08lx ", cps->CPS_SIG);
|
|
if (cps->CPS_SIG == CPSSIGVAL)
|
|
printf ("(correct)\n");
|
|
else
|
|
printf ("(should be %08lx)\n", CPSSIGVAL);
|
|
printf (" 2) CPS_DATACNT: %04x\n", cps->CPS_DATACNT);
|
|
printf (" 3) CPS_INDEX: %04x\n\n", cps->CPS_INDEX);
|
|
|
|
for (i = 0; i < cps->CPS_DATACNT; i++)
|
|
printf ("%2d) CPS_CHKSUM[%2d]: %08lx %2d) CPS_OFFSET[%2d]: %04x\n",
|
|
iCPS_CHKSUM+2*i, i, cps->CPS_CHKSUM[i],
|
|
iCPS_CHKSUM+1+2*i, i, cps->CPS_OFFSET[i]);
|
|
|
|
printf("%2d) Data Entries {..}\n", iCPS_CHKSUM+2*i);
|
|
}
|
|
break;
|
|
#endif
|
|
case TYPE_FNODE:
|
|
f = (struct FNODE *)currobj.mem;
|
|
if (!currobj.offset) {
|
|
printf ("FNODE at sector %08lx for %s:\n", currobj.sec,
|
|
*curpath ? curpath : "root directory");
|
|
printf (" 1) FN_SIG: %08lx ", f->FN_SIG);
|
|
if (f->FN_SIG == FNSIGVAL)
|
|
printf ("(correct)\n");
|
|
else
|
|
printf ("(should be %08lx)\n", FNSIGVAL);
|
|
printf (" 2) FN_SRH: %08lx\n", f->FN_SRH);
|
|
printf (" 3) FN_FRH: %08lx\n", f->FN_FRH);
|
|
printf (" 4) FN_XXX: %08lx\n", f->FN_SIG);
|
|
printf (" 5) FN_HCNT: %02x\n", f->FN_HCNT);
|
|
printf (" 6) FN_CONTFN: %08lx\n", f->FN_CONTFN);
|
|
#ifndef CODEPAGE
|
|
printf (" 7) FN_ACL.AI_DAL: %08lx\n", f->FN_AclDiskLength);
|
|
printf (" 8) FN_ACL.AI_SEC: %08lx\n", f->FN_AclSector);
|
|
printf (" 9) FN_ACL.AI_FNL: %04x\n", f->FN_AclFnodeLength);
|
|
printf ("10) FN_ACL.AI_DAT: %02x\n", f->FN_AclDataFlag);
|
|
printf ("11) FN_EA.AI_DAL: %08lx\n", f->FN_EaDiskLength);
|
|
printf ("12) FN_EA.AI_SEC: %08lx\n", f->FN_EaSector);
|
|
printf ("13) FN_EA.AI_FNL: %04x\n", f->FN_EaFnodeLength);
|
|
printf ("14) FN_EA.AI_DAT: %02x\n", f->FN_EaDataFlag);
|
|
printf ("15) FN_AB: {..}\n");
|
|
printf ("16) FN_ALREC: {..}\n");
|
|
if (f->FN_EaFnodeLength)
|
|
printf ("17) FN_FREE (EAs): {..}\n");
|
|
}
|
|
#else
|
|
printf (" 7) FN_ACLBASE: %04x\n", f->FN_ACLBASE);
|
|
printf (" 8) FN_ACL.AI_DAL: %08lx\n", f->FN_AclDiskLength);
|
|
printf (" 9) FN_ACL.AI_SEC: %08lx\n", f->FN_AclSector);
|
|
printf ("10) FN_ACL.AI_FNL: %04x\n", f->FN_AclFnodeLength);
|
|
printf ("11) FN_ACL.AI_DAT: %02x\n", f->FN_AclDataFlag);
|
|
printf ("12) FN_EA.AI_DAL: %08lx\n", f->FN_EaDiskLength);
|
|
printf ("13) FN_EA.AI_SEC: %08lx\n", f->FN_EaSector);
|
|
printf ("14) FN_EA.AI_FNL: %04x\n", f->FN_EaFnodeLength);
|
|
printf ("15) FN_EA.AI_DAT: %02x\n", f->FN_EaDataFlag);
|
|
printf ("16) FN_AB: {..}\n");
|
|
printf ("17) FN_ALREC: {..}\n");
|
|
printf ("18) FN_VLEN: %08lx\n", f->FN_VLEN);
|
|
printf ("19) FN_NEACNT: %08lx\n", f->FN_NEACNT);
|
|
if (f->FN_EaFnodeLength)
|
|
printf ("20) FN_FREE (EAs): {..}\n");
|
|
}
|
|
#endif
|
|
else if (currobj.offset == FIELDOFFSET (struct FNODE, FN_AB)) {
|
|
printf ("FNODE at sector %08lx for %s (FN_AB):\n", currobj.sec,
|
|
*curpath ? curpath : "root directory");
|
|
printf (" 1) AB_FLAG: ");
|
|
ab_flags (f->FN_AB.AB_FLAG);
|
|
printf (" 2) AB_FCNT: %02x\n", f->FN_AB.AB_FCNT);
|
|
printf (" 3) AB_OCNT: %02x\n", f->FN_AB.AB_OCNT);
|
|
printf (" 4) AB_FREP: %04x\n", f->FN_AB.AB_FREP);
|
|
}
|
|
else if (currobj.offset == FIELDOFFSET (struct FNODE, FN_ALREC [0])) {
|
|
printf ("FNODE at sector %08lx for %s (FN_ALREC):\n", currobj.sec,
|
|
*curpath ? curpath : "root directory");
|
|
l = (ULONG *)f->FN_ALREC;
|
|
if (f->FN_AB.AB_FLAG & ABF_NODE) {
|
|
for (i=0; i<12; i++) {
|
|
printf ("ALREC [%02d]: %2d) AN_LOF: %08lx ", i, i*2+1, *l);
|
|
printf ("%2d) AN_SEC: %08lx\n", i*2+2, *(l+1));
|
|
l += 2;
|
|
}
|
|
}
|
|
else {
|
|
for (i=0; i<8; i++) {
|
|
printf ("ALREC [%02d]: %2d) AL_LOF: %08lx ", i, i*3+1, *l);
|
|
printf ("%2d) AL_LEN: %08lx ", i*3+2, *(l+1));
|
|
printf ("%2d) AL_POF: %08lx\n", i*3+3, *(l+2));
|
|
l += 3;
|
|
}
|
|
}
|
|
}
|
|
else if (currobj.offset == FIELDOFFSET (struct FNODE, FN_FREE [0]) +
|
|
f->FN_AclFnodeLength) {
|
|
p = (UCHAR *)currobj.mem + currobj.offset;
|
|
printf ("Extended attributes in FNODE for %s:\n",
|
|
*curpath ? curpath : "root directory");
|
|
for (i=0; (i<23) && (i*16 < f->FN_EaFnodeLength); i++) {
|
|
sprintf (scratch, "%04x %02x %02x %02x %02x %02x %02x %02x %02x-",
|
|
i * 16, p [i*16], p [i*16+1], p [i*16+2], p [i*16+3], p [i*16+4],
|
|
p [i*16+5], p [i*16+6], p [i*16+7]);
|
|
sprintf (scratch + strlen (scratch),
|
|
"%02x %02x %02x %02x %02x %02x %02x %02x | ",
|
|
p [i*16+8], p [i*16+9], p [i*16+10], p [i*16+11],
|
|
p [i*16+12], p [i*16+13], p [i*16+14], p [i*16+15]);
|
|
if (i*16 + 15 >= f->FN_EaFnodeLength)
|
|
memset (&scratch [(f->FN_EaFnodeLength % 16) * 3 + 6], ' ',
|
|
(16 - (f->FN_EaFnodeLength % 16)) * 3);
|
|
|
|
printf ("%s", scratch);
|
|
|
|
for (j=0; (j<16) && (i*16 + j < f->FN_EaFnodeLength); j++) {
|
|
if (p [i*16+j] < ' ')
|
|
scratch [j] = '.';
|
|
else
|
|
scratch [j] = p [i*16+j];
|
|
}
|
|
scratch [j] = '\0';
|
|
printf ("%s\n", scratch);
|
|
}
|
|
}
|
|
else {
|
|
printf ("Unknown offset in FNODE, returning to start.\n");
|
|
currobj.offset = 0;
|
|
}
|
|
break;
|
|
case TYPE_DIRBLK:
|
|
d = (struct DIRBLK *)currobj.mem;
|
|
printf ("DIRBLK at sector %08lx for %s:\n", currobj.sec,
|
|
*curpath ? curpath : "root directory");
|
|
printf (" 1) DB_SIG: %08lx ", d->DB_SIG);
|
|
if (d->DB_SIG == DBSIGVAL)
|
|
printf ("(correct)\n");
|
|
else
|
|
printf ("(should be %08lx)\n", DBSIGVAL);
|
|
printf (" 2) DB_FREP: %08lx\n", d->DB_FREP);
|
|
printf (" 3) DB_CCNT: %08lx\n", d->DB_CCNT);
|
|
printf (" 4) DB_PAR: %08lx\n", d->DB_PAR);
|
|
printf (" 5) DB_SEC: %08lx\n\n", d->DB_SEC);
|
|
|
|
dp.p = (UCHAR *)currobj.mem + currobj.offset;
|
|
|
|
printf ("DIRENT at offset %04x:\n", currobj.offset);
|
|
printf (" 6) DIR_ELEN: %04x\n", dp.d->DIR_ELEN);
|
|
printf (" 7) DIR_FLAG: ");
|
|
dir_flags (dp.d->DIR_FLAG);
|
|
printf (" 8) DIR_FN: %08lx\n", dp.d->DIR_FN);
|
|
printf (" 9) DIR_MTIM: %s", get_time (dp.d->DIR_MTIM));
|
|
printf ("10) DIR_SIZE: %08lx\n", dp.d->DIR_SIZE);
|
|
printf ("11) DIR_ATIM: %s", get_time (dp.d->DIR_ATIM));
|
|
printf ("12) DIR_CTIM: %s", get_time (dp.d->DIR_CTIM));
|
|
printf ("13) DIR_EALEN: %08lx\n", dp.d->DIR_EALEN);
|
|
#ifndef CODEPAGE
|
|
printf ("14) DIR_NAML: %02x\n", dp.d->DIR_NAML);
|
|
strncpy (scratch, &dp.d->DIR_NAMA, dp.d->DIR_NAML);
|
|
scratch [dp.d->DIR_NAML] = '\0';
|
|
printf ("15) DIR_NAMA: `%s'\n", scratch);
|
|
if (dp.d->DIR_FLAG & DF_BTP)
|
|
printf ("16) DIR_BTP: %08lx\n", DOWN_PTR (dp));
|
|
break;
|
|
#else
|
|
printf ("14) DIR_FLEX: %02x\n", dp.d->DIR_FLEX);
|
|
printf ("15) DIR_CPAGE: %02x\n", dp.d->DIR_CPAGE);
|
|
printf ("16) DIR_NAML: %02x\n", dp.d->DIR_NAML);
|
|
strncpy (scratch, &dp.d->DIR_NAMA, dp.d->DIR_NAML);
|
|
scratch [dp.d->DIR_NAML] = '\0';
|
|
printf ("17) DIR_NAMA: `%s'\n", scratch);
|
|
if (dp.d->DIR_FLAG & DF_BTP) {
|
|
if (dp.d->DIR_ELEN > SECTORS_PER_DIRBLK*512) // DIR_ELEN must be good
|
|
// for DOWN_PTR()
|
|
btp = *(ULONG *)(dp.p + ((sizeof(struct DIRENT)+dp.d->DIR_NAML+3U) & ~3U));
|
|
else
|
|
btp = DOWN_PTR (dp);
|
|
|
|
printf ("18) DIR_BTP: %08lx\n", btp);
|
|
}
|
|
break;
|
|
#endif
|
|
case TYPE_ALSEC:
|
|
a = (struct ALSEC *)currobj.mem;
|
|
if (!currobj.offset) {
|
|
printf ("ALSEC at sector %08lx for %s (header):\n", currobj.sec,
|
|
*curpath ? curpath : "root directory");
|
|
printf (" 1) AS_SIG: %08lx ", a->AS_SIG);
|
|
if (a->AS_SIG == ABSIGVAL)
|
|
printf ("(correct)\n");
|
|
else
|
|
printf ("(should be %08lx)\n", ABSIGVAL);
|
|
printf (" 2) AS_SEC: %08lx\n", a->AS_SEC);
|
|
printf (" 3) AS_RENT: %08lx\n", a->AS_RENT);
|
|
printf (" 4) AB_FLAG: ");
|
|
ab_flags (a->AS_ALBLK.AB_FLAG);
|
|
printf (" 5) AB_FCNT: %02x\n", a->AS_ALBLK.AB_FCNT);
|
|
printf (" 6) AB_OCNT: %02x\n", a->AS_ALBLK.AB_OCNT);
|
|
printf (" 7) AB_FREP: %04x\n", a->AS_ALBLK.AB_FREP);
|
|
if (a->AS_ALBLK.AB_FLAG & ABF_NODE)
|
|
printf (" 8) Node records: {..}\n");
|
|
else
|
|
printf (" 8) Leaf records: {..}\n");
|
|
}
|
|
else {
|
|
printf ("ALSEC at sector %08lx for %s (records):\n", currobj.sec,
|
|
*curpath ? curpath : "root directory");
|
|
l = (ULONG *)((UCHAR *)currobj.mem + currobj.offset);
|
|
if (a->AS_ALBLK.AB_FLAG & ABF_NODE) {
|
|
for (i=0; i<20; i++) {
|
|
printf ("Node %02d: %2d) AN_LOF: %08lx %2d) AN_SEC: %08lx\n",
|
|
(USHORT)(currobj.offset-sizeof (struct ALSEC))/sizeof (struct ALNODE)+i+1,
|
|
i*2+1, *l, i*2+2, *(l+1));
|
|
l += 2;
|
|
}
|
|
}
|
|
else {
|
|
for (i=0; i<20; i++) {
|
|
printf (
|
|
"Leaf %02d: %2d) AL_LOF: %08lx %2d) AL_LEN: %08lx %2d) AL_POF: %08lx\n",
|
|
(USHORT)(currobj.offset-sizeof (struct ALSEC))/sizeof (struct ALLEAF)+i+1,
|
|
i*3+1, *l, i*3+2, *(l+1), i*3+3, *(l+2));
|
|
l += 3;
|
|
}
|
|
}
|
|
}
|
|
|
|
break;
|
|
case TYPE_DATA:
|
|
p = (UCHAR *)currobj.mem + currobj.scratch;
|
|
offset = currobj.offset * 512L + currobj.scratch;
|
|
printf ("Hex data at %08lx, offset %08lx, file %s:\n", currobj.sec,
|
|
offset, *curpath ? curpath : "root directory");
|
|
for (i=0; (i<16) && (offset + i*16 < filesize); i++) {
|
|
sprintf (scratch, "%08lx %02x %02x %02x %02x %02x %02x %02x %02x-",
|
|
currobj.offset * 512L + currobj.scratch + i * 16,
|
|
p [i*16], p [i*16+1], p [i*16+2], p [i*16+3], p [i*16+4],
|
|
p [i*16+5], p [i*16+6], p [i*16+7]);
|
|
sprintf (scratch + strlen (scratch),
|
|
"%02x %02x %02x %02x %02x %02x %02x %02x | ",
|
|
p [i*16+8], p [i*16+9], p [i*16+10], p [i*16+11],
|
|
p [i*16+12], p [i*16+13], p [i*16+14], p [i*16+15]);
|
|
if (offset + i*16 + 15 >= filesize)
|
|
memset (&scratch [(filesize % 16) * 3 + 10], ' ',
|
|
(16 - (filesize % 16)) * 3);
|
|
|
|
printf ("%s", scratch);
|
|
|
|
for (j=0; (j<16) && (offset + i*16 + j < filesize); j++) {
|
|
if (p [i*16+j] < ' ')
|
|
scratch [j] = '.';
|
|
else
|
|
scratch [j] = p [i*16+j];
|
|
}
|
|
scratch [j] = '\0';
|
|
printf ("%s\n", scratch);
|
|
}
|
|
|
|
break;
|
|
default:
|
|
printf ("Unknown type %d encountered.\n", currobj.type);
|
|
}
|
|
}
|