📄 root.c
字号:
/*
**************************************************************
*
* hyperstone MS-DOS FAT File System Drivers
*
* FAT and Directory related routines
*
* Christoph Baumhof 2000-03-21
* Reinhard K乭ne 2000-03-21
* Mihajlo Varga 2000-03-21
*
* Copyright (C) 1997-2000 hyperstone electronics GmbH Konstanz
*
* 2000-03-21 initial release
*
* $Id$
*
* $Log$
*
**************************************************************
*
* Changes:
*
**************************************************************
*/
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <io.h>
#include "hybios.h"
#include "hy_dos.h"
extern int _fat12to16(int fatentry, char *);
extern int _fat16to12(int fatentry, char *, unsigned short);
#define FREE_CLUSTER_CODE 0
#define RESERVED_CLUSTER_CODE 0xFFF7
#define BAD_CLUSTER_CODE 0xFFF7
#define LAST_CLUSTER_CODE 0xFFF8
/* converts file name into directory entry format
for example: "demo.bat" --> "demo____bat"
" demo.s " --> "demo____s__"
*/
static int expand_fn8_3(char * destn, const char *srcnam) {
int i, count_n=0;
const char * srcn;
srcn = &srcnam[2];
while ((*srcn == ' ') || (*srcn == '\t') )
srcn++;
while ( (*srcn != ' ') && (*srcn != '.') && (*srcn) && (count_n < 8)) {
*destn++ = *srcn++;
count_n++;
}
if ((*srcn == ' ') || (!*srcn)) {
for (i=count_n; i < 11; i++)
*destn++ = ' ';
*destn = 0;
return 0;
}
srcn++;
for (i=count_n; i < 8; i++)
*destn++ = ' ';
count_n = 0;
while ( (*srcn != ' ') && (*srcn) && (count_n < 3)) {
*destn++ = *srcn++;
count_n++;
}
for (i=count_n; i < 3; i++)
*destn++ = ' ';
*destn = 0;
return 0;
}
static int MaxCluster(int drive, int partnum)
{
struct msdos_b_sect *b_sect;
b_sect = _hd_ident[drive].bootptr[partnum];
return b_sect->MaxCluster;
}
static int ClusterOk(unsigned int drive,
unsigned int partnum,
unsigned int cluster)
{
if (cluster < 2)
{
fprintf(stderr, "Error: cluster = %d\n", cluster);
return 0;
}
if ((cluster > RESERVED_CLUSTER_CODE) && (cluster < BAD_CLUSTER_CODE))
{
fprintf(stderr, "Reserved cluster = %d\n", cluster);
return 0;
}
if (cluster == BAD_CLUSTER_CODE)
{
fprintf(stderr, "Bad cluster = %d\n", cluster);
return 0;
}
if (cluster >= MaxCluster(drive, partnum))
{
fprintf(stderr, "cluster out of FAT = %d\n", cluster);
return 0;
}
return 1;
}
static int read_Fat(int drive, int partnum, int cluster_idx)
{
struct msdos_b_sect *b_sect;
unsigned short *tempbuf;
int FatMode;
char *tempchar;
b_sect = _hd_ident[drive].bootptr[partnum];
tempbuf = b_sect->FatStart;
tempchar = (unsigned char *)b_sect->FatStart;
FatMode = b_sect->FatSystem;
if (FatMode == 12)
return _fat12to16(cluster_idx, tempchar);
if (FatMode == 16)
return CvtByteOrder16(tempbuf[cluster_idx]);
// fprintf(stderr, "Bad FatMode = %d\n", FatMode);
return 0;
}
int ActFatSector = ILLEGAL_FATSECTOR;
int Flush_Fat(int drive, int partnum)
{
struct msdos_b_sect *b_sect;
int i;
b_sect = _hd_ident[drive].bootptr[partnum];
if (ActFatSector != ILLEGAL_FATSECTOR)
for (i=0; i<b_sect->nFats; i++)
r_w_Disk(drive, b_sect->nHidden+b_sect->resSectors+ActFatSector+
i*b_sect->sectPerFat,
1, b_sect->FatStart+(ActFatSector*SECTOR_SHORTS), WRITE);
ActFatSector = ILLEGAL_FATSECTOR;
}
static int write_Fat(unsigned int drive, unsigned int partnum,
unsigned int cluster_idx, unsigned int pattern)
{
struct msdos_b_sect *b_sect;
unsigned short *tempbuf;
int FatMode, NewFatSector;
char *tempchar;
b_sect = _hd_ident[drive].bootptr[partnum];
tempbuf = b_sect->FatStart;
tempchar = (unsigned char *)b_sect->FatStart;
FatMode = b_sect->FatSystem;
if (FatMode == 12)
{
_fat16to12(cluster_idx, tempchar, pattern);
NewFatSector = (cluster_idx*3)/FAT12_ENTRIES_FOR_3SECS;
if ((cluster_idx*3)%FAT12_ENTRIES_FOR_3SECS >= (FAT12_ENTRIES_FOR_3SECS-2))
{
if ((ActFatSector != ILLEGAL_FATSECTOR) &&
(ActFatSector != NewFatSector))
Flush_Fat(drive, partnum);
ActFatSector = NewFatSector;
NewFatSector++;
}
if ((ActFatSector != ILLEGAL_FATSECTOR) &&
(ActFatSector != NewFatSector))
Flush_Fat(drive, partnum);
ActFatSector = NewFatSector;
return 1;
}
if (FatMode == 16)
{
tempbuf[cluster_idx] = CvtByteOrder16(pattern);
NewFatSector = cluster_idx/FAT16_ENTRIES;
if ((ActFatSector != ILLEGAL_FATSECTOR) &&
(ActFatSector != NewFatSector))
Flush_Fat(drive, partnum);
ActFatSector = NewFatSector;
return 1;
}
// fprintf(stderr, "Bad FatMode = %d\n", FatMode);
return 0;
}
/**********************************************************/
/* delete all Fatentries of a file (unlink) */
/**********************************************************/
int delete_FatEntrys(int drive, int partnum, int startCluster)
{
unsigned short tmp, cluster;
cluster = startCluster;
do
{
if (!ClusterOk(drive, partnum, cluster))
return 0;
tmp = read_Fat(drive, partnum, cluster);
if (!write_Fat(drive, partnum, cluster, 0))
return 0;
cluster = tmp;
}
while (cluster < LAST_CLUSTER_CODE);
return 1;
}
int LastClusterFound = 1;
#if 0
static int find_free_FatEntry(int drive, int partnum)
{
int cluster;
cluster = 2;
while (read_Fat(drive, partnum, cluster) != FREE_CLUSTER_CODE)
{
cluster++;
if (cluster >= MaxCluster(drive, partnum))
return 0;
}
return cluster;
}
#else
static int find_free_FatEntry(int drive, int partnum)
{
int cluster;
for (cluster=LastClusterFound+1;
cluster<MaxCluster(drive, partnum) &&
read_Fat(drive, partnum, cluster)!=FREE_CLUSTER_CODE;
cluster++);
if (cluster<MaxCluster(drive, partnum))
{
LastClusterFound = cluster;
return cluster;
}
for (cluster=2; cluster<=LastClusterFound &&
cluster<MaxCluster(drive, partnum) &&
read_Fat(drive, partnum, cluster)!=FREE_CLUSTER_CODE;
cluster++);
LastClusterFound = cluster;
return (cluster<=LastClusterFound && cluster<MaxCluster(drive, partnum))?
cluster:0;
}
#endif
static int insert_FatEntry (int drive, int partnum,
int old_cluster_idx, int new_cluster_idx)
{
if (old_cluster_idx)
{
if (!write_Fat(drive, partnum, old_cluster_idx, new_cluster_idx))
return 0;
}
return write_Fat(drive, partnum, new_cluster_idx, LAST_CLUSTER_CODE);
}
static int appendFatEntry (int drive, int partnum, int cluster_idx)
{
int free_cluster_idx;
free_cluster_idx = find_free_FatEntry(drive, partnum);
if (free_cluster_idx)
{
if (cluster_idx)
{
if (!write_Fat(drive, partnum, cluster_idx, free_cluster_idx))
return 0;
}
if (!write_Fat(drive, partnum, free_cluster_idx, LAST_CLUSTER_CODE))
return 0;
return free_cluster_idx;
}
return 0;
}
#if 0
/**********************************************************/
/* returns count of true read/written Cluster */
/**********************************************************/
int r_w_Cluster(unsigned int drive, unsigned int partnum,
unsigned int startCluster, void *buf,
unsigned int ClusterCnt, unsigned int ClusterOffs, int rw)
{
struct msdos_b_sect *b_sect;
unsigned int FatMode, i;
b_sect = _hd_ident[drive].bootptr[partnum];
FatMode = b_sect->FatSystem;
if ((FatMode == 12) || (FatMode == 16))
{
unsigned int SectorNumber, j, PreviousCluster;
char *xbuf = (char *)buf;
if ((ClusterCnt == 0) || (!ClusterOk(drive, partnum, startCluster)))
return 0;
PreviousCluster = 0;
while ((startCluster < LAST_CLUSTER_CODE) && ClusterOffs)
{
// if (!ClusterOk(drive, partnum, startCluster))
// return 0;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -