📄 drobj.c
字号:
{
if (end_of_lfn)
lfi->lfname3[n] = 0xffff;
else
{
lfi->lfname3[n] = *lfn++;
if (lfi->lfname3[n] == 0)
end_of_lfn = TRUE;
}
}
if (end_of_lfn)
order |= FIRST_NAMESEG;
lfi->lfnorder = order;
lfi->lfnattribute = 0x0F;
lfi->lfnres = 0;
lfi->lfncksum = ncksum;
lfi->lfncluster = 0x0000;
}
}
#endif
BOOLEAN pc_seglist2disk(DDRIVE * pdrive, SEGDESC *s, char *lfn) /* __fn__*/
{
BLKBUFF *rbuf;
LFNINODE *lfi;
int ntodo;
if (!s->nsegs)
return(FALSE);
/* Read segblock[0] and copy text */
rbuf = pc_read_blk(pdrive, s->segblock[0]);
if (!rbuf)
return(FALSE);
lfi = (LFNINODE *) &rbuf->data[0];
lfi += s->segindex;
/* If the lfn segments span two blocks then segblock[0] contains the
second block and segblock[1] contains the first.
We delete all of the segments up to and including segindex
in the second block block value stored in segblock[0]. */
//DM: 3/14/99: fixed. Problem is that in some cases, ntodo is actually
// increased (by 1) rather than decreased. See comment in pc_deleteseglist()
// for more info (search ntodo).
if (s->nsegs > s->segindex+1)
// if (s->nsegs >= s->segindex) WRONG
ntodo = s->segindex+1;
else
ntodo = s->nsegs;
text2lfi(lfn, lfi, ntodo, s->ncksum, 1);
if ( !pc_write_blk ( rbuf ) )
{
pc_free_buf(rbuf,TRUE); /* Error. Chuck the buffer */
return (FALSE);
}
else
pc_free_buf(rbuf,FALSE);
if (s->segblock[1])
{
rbuf = pc_read_blk(pdrive, s->segblock[1]);
if (!rbuf)
return(FALSE);
lfi = (LFNINODE *) &rbuf->data[0];
lfi += 15; /* The last index */
text2lfi(lfn + (ntodo)*13, lfi, s->nsegs - (ntodo), s->ncksum, (byte) (ntodo+1));
if ( !pc_write_blk ( rbuf ) )
{
pc_free_buf(rbuf,TRUE); /* Error. Chuck the buffer */
return (FALSE);
}
else
pc_free_buf(rbuf,FALSE);
}
return(TRUE);
}
void lfi2text(char *lfn, LFNINODE *lfi, int nsegs) /* __fn__ */
{
int n;
for (;nsegs;nsegs--, lfi--)
{
for(n=0; n<10; n += 2)
*lfn++ = (char) lfi->lfname1[n];
for(n=0; n<12; n += 2)
*lfn++ = (char) lfi->lfname2[n];
for(n=0; n<4; n += 2)
*lfn++ = (char) lfi->lfname3[n];
*lfn = 0;
}
}
char *pc_seglist2text(DDRIVE * pdrive, SEGDESC *s, char *lfn) /* __fn__ */
{
BLKBUFF *rbuf;
LFNINODE *lfi;
int ntodo;
*lfn = 0;
if (!s->nsegs)
goto sl2_done;
/* Read segblock[0] and copy text */
rbuf = pc_read_blk(pdrive, s->segblock[0]);
if (!rbuf)
goto sl2_done;
lfi = (LFNINODE *) &rbuf->data[0];
lfi += s->segindex;
/* If the lfn segments span two blocks then segblock[0] contains the
second block and segblock[1] contains the first.
We delete all of the segments up to and including segindex
in the second block block value stored in segblock[0]. */
//DM: 3/14/99: fixed. Problem is that in some cases, ntodo is actually
// increased (by 1) rather than decreased. See comment in pc_deleteseglist()
// for more info (search ntodo).
if (s->nsegs > s->segindex+1)
// if (s->nsegs >= s->segindex) WRONG
ntodo = s->segindex+1;
else
ntodo = s->nsegs;
lfi2text(lfn, lfi, ntodo);
pc_free_buf(rbuf, FALSE);
if (s->segblock[1])
{
rbuf = pc_read_blk(pdrive, s->segblock[1]);
if (!rbuf)
goto sl2_done;
lfi = (LFNINODE *) &rbuf->data[0];
lfi += 15; /* The last index */
lfi2text(lfn + (ntodo)*13, lfi, s->nsegs - ntodo);
pc_free_buf(rbuf, FALSE);
}
sl2_done:
return(lfn);
}
void pc_zeroseglist(SEGDESC *s) /* __fn__ */
{
/* Note: we do not zero the checksum field here */
s->nsegs = 0;
s->segblock[0] =
s->segblock[1] =
s->segindex = 0;
}
void pc_addtoseglist(SEGDESC *s, BLOCKT my_block, int my_index) /*__fn__*/
{
s->nsegs += 1;
/* segblok[0][segindex] is always the last NAMESEG if disk order first
in lfn order */
if (!s->segblock[0])
{
s->segblock[0] = my_block;
}
if (s->segblock[0] != my_block)
{
s->segblock[1] = s->segblock[0];
s->segblock[0] = my_block;
}
s->segindex = my_index;
}
/* This function is used by pc_insert_inode(). That function builds a seglist
that is 1 segment longer then the lfn. The extra segment is where the
dosinode will be placed. Before we write the the lfn to disk we call this
function to reduce the segment list by one. */
void pc_reduceseglist(SEGDESC *s) /*__fn__ */
{
if (s->nsegs) /* This should always be true */
{
s->nsegs -= 1;
if (s->segblock[1] && s->segindex == 0)
{
s->segblock[0] = s->segblock[1];
s->segindex = INOPBLOCK-1;
}
else
{
if (s->segindex) /* This should always be true */
s->segindex -= 1;
}
}
}
#endif
/***************************************************************************
PC_FINDIN - Find a filename in the same directory as the argument.
Description
Look for the next match of filename or pattern filename:ext in the
subdirectory containing pobj. If found update pobj to contain the
new information (essentially getnext.) Called by pc_get_inode().
Note: Filename and ext must be right filled with spaces to 8 and 3 bytes
respectively. Null termination does not matter.
Returns
Returns TRUE if found or FALSE.
****************************************************************************/
/* Find filename in the directory containing pobj. If found, load the inode
section of pobj. If the inode is already in the inode buffers we free the current inode
and stitch the existing one in, bumping its open count */
BOOLEAN pc_findin( DROBJ *pobj, byte *filename, byte *fileext, BOOLEAN dowildcard) /*__fn__*/
{
BLKBUFF *rbuf;
DIRBLK *pd;
DOSINODE *pi;
FINODE *pfi;
#if (VFAT)
LFNINODE *lfn_node;
char sfn[13];
char lfn[256];
BOOLEAN matchfound;
SEGDESC s;
byte lastsegorder;
pc_zeroseglist(&s);
#endif
/* For convenience. We want to get at block info here */
pd = &pobj->blkinfo;
/* Read the data */
pobj->pblkbuff = rbuf = pc_read_blk(pobj->pdrive, pobj->blkinfo.my_block);
while (rbuf)
{
pi = (DOSINODE *) &rbuf->data[0];
/* Look at the current inode */
pi += pd->my_index;
/* And look for a match */
while ( pd->my_index < INOPBLOCK )
{
/* End of dir if name is 0 */
if (!pi->fname[0])
{
pc_free_buf(rbuf,FALSE);
return(FALSE);
}
#if (VFAT)
ARGSUSED_PVOID((PFVOID) fileext);
if (pi->fname[0] == PCDELETE)
{
pc_zeroseglist(&s);
}
else
{
/* Support long file names */
if (pi->fattribute == CHICAGO_EXT)
{
lfn_node = (LFNINODE *) pi;
if (lfn_node->lfnorder & FIRST_NAMESEG)
{
pc_addtoseglist(&s, pd->my_block, pd->my_index);
/* Here.. we could build up the name here too */
lastsegorder = lfn_node->lfnorder;
s.ncksum = lfn_node->lfncksum;
}
else
{
if (s.nsegs)/* if a chain already exists */
{
if ( ((lfn_node->lfnorder & NAMESEG_ORDER) == (lastsegorder & NAMESEG_ORDER) - 1) &&
(lfn_node->lfncksum == s.ncksum) )
{
/* Add new segment to lfn chain */
lastsegorder = lfn_node->lfnorder;
pc_addtoseglist(&s, pd->my_block, pd->my_index);
}
else
{
/* disconnect chain... segments do not match */
lastsegorder = 0;
pc_zeroseglist(&s);
}
}
}
}
else
{
/* Note: Patcmp won't match on deleted */
if (s.nsegs)
matchfound = pc_patcmp(filename, (byte*)pc_seglist2text(pobj->pdrive, &s,lfn),dowildcard);
else
matchfound = FALSE;
if (matchfound)
matchfound = (BOOLEAN)(pc_cksum( (byte*) pi ) == s.ncksum);
else
{
pc_mfile((byte*)sfn,pi->fname,pi->fext);
matchfound = pc_patcmp(filename, (byte*)sfn,dowildcard);
}
if (matchfound)
#else
/* Note: Patcmp won't match on deleted */
if (pc_patcmp(pi->fname, (byte*) filename, 8,dowildcard) && (pc_patcmp(pi->fext, (byte*) fileext, 3,dowildcard) ))
if (pi->fattribute != CHICAGO_EXT) /* Ignore chicago style names */
#endif
{
/* We found it */
/* See if it already exists in the inode list.
If so.. we use the copy from the inode list */
pfi = pc_scani(pobj->pdrive, rbuf->blockno, pd->my_index);
if (pfi)
{
pc_freei(pobj->finode);
pobj->finode = pfi;
}
else /* No inode in the inode list. Copy the data over
and mark where it came from */
{
pfi = pc_alloci();
if (pfi)
{
pc_freei(pobj->finode); /* Release the current */
pobj->finode = pfi;
pc_dos2inode(pobj->finode , pi );
pc_marki(pobj->finode , pobj->pdrive , pd->my_block,
pd->my_index );
#if (VFAT)
if (s.nsegs)
{
if (pc_cksum( (byte*) pi ) != s.ncksum)
{
pc_zeroseglist(&s);
lastsegorder = 0;
}
pobj->finode->s = s;
}
else
pc_zeroseglist(&pobj->finode->s);
#endif
}
else
{
pc_free_buf(rbuf,FALSE);
return (FALSE);
}
}
/* Free, no error */
pc_free_buf(rbuf,FALSE);
return (TRUE);
} /* if (match) */
#if (VFAT)
else /* disconnect chain... segments do not match */
{
pc_zeroseglist(&s);
}
} /* else (CHICAGO_EXT) */
} /* if (!PCDELETE) */
#endif
pd->my_index++;
pi++;
}
/* Not in that block. Try again */
pc_free_buf(rbuf,FALSE);
/* Update the objects block pointer */
if (!pc_next_block(pobj))
break;
pd->my_index = 0;
pobj->pblkbuff = rbuf = pc_read_blk(pobj->pdrive, pobj->blkinfo.my_block);
}
return (FALSE);
}
RTFS_FILE(getmom.c, pc_get_mom)
#ifndef __PCDISK__ /* This allows us to build the lib with subroutines split */
#include <pcdisk.h>
#endif
/**************************************************************************
PC_GET_MOM - Find the parent inode of a subdirectory.
Description
Given a DROBJ initialized with the contents of a subdirectory's ".."
entry, initialize a DROBJ which is the parent of the current directory.
Returns
Returns a DROBJ pointer or NULL if could something went wrong.
****************************************************************************/
#if (RTFS_SUBDIRS)
/*
* Get mom:
* if (!dotodot->cluster) Mom is root.
* getroot()
* else cluster points to mom.
* find .. in mom
* then search through the directory pointed to by moms .. until
* you find mom. This will be current block startblock etc for mom.
*/
DROBJ *pc_get_mom(DROBJ *pdotdot) /*__fn__*/
{
DROBJ *pmom;
DDRIVE *pdrive = pdotdot->pdrive;
BLOCKT sectorno;
BLKBUFF *rbuf;
DIRBLK *pd;
DOSINODE *pi;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -