⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 drobj.c

📁 ertfs文件系统里面既有完整ucos程序
💻 C
📖 第 1 页 / 共 5 页
字号:
        {
            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 + -