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

📄 lowl.c

📁 nucleus 文件系统,内核和彩色图形系统,在小系统上非常好用
💻 C
📖 第 1 页 / 共 4 页
字号:
            return (NO);
        }
        else
            pc_free_buf(pbuff,NO);

    }

    return (YES);
}


/****************************************************************************
    PC_DRNO2DR -  Convert a drive number to a pointer to DDRIVE

 Description
    Given a drive number look up the DDRIVE structure associated with it.

 Returns
    Returns NULL if driveno is not an open drive.

****************************************************************************/

DDRIVE  *pc_drno2dr(COUNT driveno)                                  /*__fn__*/
{
DDRIVE  *pdr;

    /* Check drive number */
    if ((driveno >= 0) && (driveno  < NDRIVES))
    {
        pdr = mem_drives_structures+driveno;
        if (pdr->opencount)
            return(pdr);
    }
    return(NULL);
}

/***************************************************************************
    PC_DSKFREE -  Deallocate all core associated with a disk structure

 Description
    Given a valid drive number. If the drive open count goes to zero, free the
    file allocation table and the block zero information associated with the
    drive. If unconditional is true, ignore the open count and release the 
    drive. 
    If open count reaches zero or unconditional, all future accesses to
    driveno will fail until re-opened.

 Returns
    Returns NO if driveno is not an open drive.

****************************************************************************/


/* free up all core associated with the drive 
   called by close. A drive restart would consist of 
    pc_dskfree(driveno, YES), pc_dskopen() */ 
BOOL pc_dskfree(COUNT driveno, BOOL  unconditional)                  /*__fn__*/
{
    DDRIVE *pdr;
/*    DROBJ *pcwd; */

    pdr = pc_drno2dr(driveno);
    if (!pdr)
    {
        return(NO);
    }

    /* If unconditional close. Fake it out by setting open count to 1 */
    if (unconditional)
        pdr->opencount = 1;

    if (pdr->opencount == 1)
    {
       /* Free the current working directory for this drive for all users */
        pc_free_all_users(driveno);
        /* Free all files, finodes & blocks associated with the drive */
        pc_free_all_fil(pdr);
        pc_free_all_i(pdr);
        pc_free_all_blk(pdr);
        
        /* Free fat blocks */
        pc_memory_fat_blocks_free(driveno, pdr->fat_swap_structure.data_array, pdr->fat_swap_structure.n_blocks_total);
        /* Tell the device driver we are done. */
        pc_bdevsw[driveno].close_proc(driveno);
    }

    pdr->opencount -= 1;
    return (YES);
}


/***************************************************************************
    PC_IFREE - Count the number of free bytes remaining on a disk (internal)

 Description
    Given a drive number count the number of free bytes on the drive. (called
    by pc_free).

 Returns
     The number of free bytes or zero if the drive is full or 
     it it not open or out of range.
    
     NOTE:  To speed up this operation we maintain a variable in the
            drive structure.  known_free_clusters. If this variable is
            non zero a multiple of this value will be returned. To force
            the free count to be recalculated just set field to zero
            before calling this function.

****************************************************************************/


LONG pc_ifree(COUNT driveno)                                        /*__fn__*/
{
    DDRIVE  *pdr;
    UCOUNT i;
    UCOUNT nxt;
    UCOUNT freecount = 0;
    LONG nbad = 0L;
    LONG nres = 0L;
    LONG ltemp;

    pdr = pc_drno2dr(driveno);

    if (!pdr)
    {
        return(0L);
    }

    if (pdr->known_free_clusters)
        freecount = pdr->known_free_clusters;
    else
    {
        for (i = 2 ; i <= pdr->maxfindex; i++)
        {
            if (!pc_faxx(pdr, i, &nxt))
            {
                return(0L);
            }
            if (nxt == 0)
                freecount++;
        
            if ( (pdr->fasize == 3 && nxt == 0xff7) ||
                 (pdr->fasize == 4 && nxt == 0xfff7) )
            {
                nbad += 1;
            }
            if (pdr->fasize == 4 &&  (nxt >= 0xfff0 && nxt <= 0xfff6))
                nres += 1;
            else if (pdr->fasize == 3 &&  (nxt >= 0xff0 && nxt <= 0xff6))
                nres += 1;
        }
        pdr->known_free_clusters = freecount;
    }
    ltemp = (LONG) freecount;
    ltemp *=  pdr->bytespcluster;

    return (ltemp);
}

/****************************************************************************
    PC_SEC2CLUSTER - Convert a block number to its cluster representation.

 Description
    Convert blockno to its cluster representation if it is in cluster space.

 Returns
    Returns 0 if the block is not in cluster space, else returns the
    cluster number associated with block.

****************************************************************************/
 
/* Cluster<->sector conversion routines */
/* Convert sector to cluster. 0 == s error */
UCOUNT pc_sec2cluster(DDRIVE *pdrive, BLOCKT blockno)                /*__fn__*/
{

    BLOCKT answer;

    if (blockno >= pdrive->numsecs)
         return (0);
    else if ( pdrive->firstclblock > blockno)
        return (0);
    else
    {
        /*  (2 + (blockno - pdrive->firstclblock)/pdrive->secpalloc) */
        answer = blockno - pdrive->firstclblock;
        answer = answer >> pdrive->log2_secpalloc;
        answer += 2;
        return ((UCOUNT) answer);
    }
}

/****************************************************************************
    PC_SEC2INDEX - Calculate the offset into a cluster for a block.

 Description
    Given a block number offset from the beginning of the drive, calculate
    which block number within a cluster it will be. If the block number
    coincides with a cluster boundary, the return value will be zero. If it
    coincides with a cluster boundary + 1 block, the value will be 1, etc.

   
 Returns
    0,1,2 upto blockspcluster -1.

***************************************************************************/
 
/* Convert sector to index into a cluster . No error detection */
UCOUNT pc_sec2index(DDRIVE *pdrive, BLOCKT blockno)               /*__fn__*/
{
   BLOCKT answer;

    /*  ((blockno - pdrive->firstclblock) % pdrive->secpalloc) ); */
    
    answer = blockno - pdrive->firstclblock;
    answer = answer % pdrive->secpalloc;

    return ( (UCOUNT) answer);
}



/***************************************************************************
    PC_CL2SECTOR - Convert a cluster number to block number representation.

 Description
    Convert cluster number to a blocknumber.

 Returns
    Returns 0 if the cluster is out of range. else returns the
    block number of the beginning of the cluster.

               
****************************************************************************/

/* Convert cluster. to sector */
BLOCKT pc_cl2sector(DDRIVE *pdrive, UCOUNT cluster)               /*__fn__*/
{
    BLOCKT blockno;
    ULONG t;

    if (cluster < 2)
        return (BLOCKEQ0);
    else 
    {
        t = cluster - 2;
        t = t << pdrive->log2_secpalloc;
        blockno = pdrive->firstclblock + t;
    }
    if (blockno >= pdrive->numsecs)
        return (BLOCKEQ0);
    else 
        return (blockno);
}


/******************************************************************************
    EXT_PARTITION_INIT -  Partition table interpretor

 Description
    Given a physical drive number and the addresses of two tables, 
    partition start and partition end, this routine interprets the
    partion tables on the physical drive and fills in the start and end
    blocks of each partition. Extended partitions are supported. If there
    are more than max partitions, only max will be returned.
    
    Note: the physical drive must be in a raw state so no partition mapping
          takes place.

 Returns
    The number of partitions found on the drive.

****************************************************************************/

COUNT ext_partition_init(COUNT driveno, ULONG *pstart, ULONG *pend, COUNT max)  /*__fn__*/
{
    COUNT nparts;
    PTABLE *ppart;
    char workbuf[256];
    char buf[512];
    char *pbuf;
    ULONG ltemp;
    ULONG ltemp2;
    UCOUNT stemp;
    UCOUNT i;
    ULONG partition_address;
 
    nparts = 0;
    partition_address = 0L;
    
    while(YES)
    {
        if (nparts == max)
            goto done;
        /* Read block zero */
        if (!pc_bdevsw[driveno].io_proc(driveno, partition_address , buf , 1 , YES))
            goto done;
        /* Copy the table to a word alligned buffer so some compilers don't screw up */
        pbuf = &buf[0];
        pbuf += 0x1be;           /* The info starts at buf[1be] */
        copybuff(workbuf, pbuf, sizeof(PTABLE));
        ppart = (PTABLE *) workbuf;
        stemp = ppart->signature;
        if (to_WORD((UTINY *) &stemp)  !=  0xAA55)  
            goto done;
        /* Read through the partition table. Find the primary DOS partition */
        for (i = 0; i < 4; i++)
        {
            if ( (ppart->ents[i].p_typ == 0x01) ||
                 (ppart->ents[i].p_typ == 0x04) ||
                 (ppart->ents[i].p_typ == 0x06) )
            {
            /* Get the relative start and size */
                ltemp = ppart->ents[i].r_sec;
                ltemp2 = to_DWORD ((UTINY *) &ltemp);
                ltemp2 += partition_address;
                *(pstart+nparts) = ltemp2;
                ltemp = (ppart->ents[i].r_sec + ppart->ents[i].p_size) - 1L;
                ltemp2 = to_DWORD ((UTINY *) &ltemp);
                ltemp2 += partition_address;
                *(pend+nparts) = ltemp2;
                nparts++;
                break;
            }
        }
        /* Now see if we have an extended partion */
        for (i = 0; i < 4; i++)
        {
            if ( (ppart->ents[i].p_typ == 0x05) )
            {
                /* Get the address of the extended partition. */
                ltemp = ppart->ents[i].r_sec;
                ltemp2 = to_DWORD ((UTINY *) &ltemp);
                ltemp2 += partition_address;
                partition_address = ltemp2;
                break;
            }
        }
        if (i == 4)        /* No extended partitions, bail */
            break;
    }
done:
    return(nparts);
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -