📄 fat.c
字号:
/*
* fat.c read FAT12 and FAT16
*
* This file is part of the BETA version of DISKLIB
* Copyright (C) 1998, Gregg Jennings
*
* See README.TXT for information about re-distribution.
* See DISKLIB.TXT for information about usage.
*
* 11-Nov-1998 greggj added the search...() functions
*
*/
#include <stdlib.h>
#include <string.h>
#include "dosio.h"
#include "disklib.h"
#include "fat.h"
#ifdef NEED_LARGE
#include <malloc.h>
#define lmalloc(n) halloc(n,1)
#define lfree(p) hfree(p)
#define SIZE_T long
#else
#define lmalloc(n) malloc(n)
#define lfree(p) free(p)
#define SIZE_T unsigned int
#endif
int readfat12(int disk, int nclusters, long sector, int secsfat,
unsigned short LARGE *clusters);
int readfat16(int disk, unsigned short nclusters, long sector, int secsfat,
unsigned short LARGE *clusters);
/*
* readfat reads the FAT into an array of integers (front end)
*
*/
unsigned short LARGE *readfat(int disk, unsigned short nclusters, long sector,
int secsfat)
{
int i;
SIZE_T bufsiz;
unsigned short LARGE *buf;
bufsiz = ((SIZE_T)nclusters+2) * sizeof(short);
if (bufsiz & 1)
++bufsiz;
if ((buf = lmalloc(bufsiz)) == NULL)
return NULL;
#ifndef NEED_LARGE
memset(buf,0,bufsiz);
#endif
if (nclusters < 4096)
i = readfat12(disk,nclusters,sector,secsfat,buf);
else
i = readfat16(disk,nclusters,sector,secsfat,buf);
if (i != 1) {
lfree(buf);
return NULL;
}
return buf;
}
/*
* readfat12 reads 12-bit FAT
*
* returns 1 okay, 0 disk i/o error, -1 malloc error
*/
int readfat12(int disk, int nclusters, long sector, int secsfat,
unsigned short LARGE *clusters)
{
int h,i;
size_t bufsiz;
unsigned char *buf;
unsigned short *pc,c;
bufsiz = (size_t)secsfat * 512;
if ((buf = malloc(bufsiz)) == NULL)
return -1;
if (disk_read(disk,sector,buf,secsfat) != DISK_OK) {
free(buf);
return 0;
}
buf += 3;
for (h = 2; h <= nclusters; buf++)
{
for (i = 0; i < 2; i++)
{
pc = (unsigned short *)(buf++);
if (i&1)
c = *pc >> 4; /* odd */
else
c = *pc & 0xFFF; /* even */
clusters[h] = (unsigned short)c;
if (++h > nclusters)
break;
}
}
free(buf);
return 1;
}
/*
* readfat16 reads 16-bit FAT
*
* returns 1 okay, 0 disk i/o error, -1 malloc error
*/
int readfat16(int disk, unsigned short nclusters, long sector, int secsfat,
unsigned short LARGE *clusters)
{
long size;
unsigned int h; /* Watcom 11.0 bug: DON'T use `unsigned short h'! */
unsigned short *buf;
unsigned int n,bufsiz;
int (*diskread)(int disk, long sector, void *buffer, int nsecs);
/*
TODO: There should be a way, either here or another function,
to use another disk read function.
*/
#ifndef _WINNT
drive_size(disk,&size);
if (size > (1024L*1024L*32))
diskread = disk_read_ext;
else
#endif
diskread = disk_read;
clusters[0] = clusters[1] = 0;
if (secsfat < 128)
{
bufsiz = (size_t)secsfat * 512;
if ((buf = malloc(bufsiz)) != NULL)
{
if (diskread(disk,sector,buf,secsfat) != DISK_OK)
{
free(buf);
return 0;
}
n = 0;
for (h = 2; h <= nclusters; )
clusters[h] = buf[n++];
free(buf);
return 1;
}
}
bufsiz = 512/2;
if ((buf = malloc(512 * sizeof(short))) == NULL)
return -1;
h = 2;
for ( ; secsfat; --secsfat)
{
if (diskread(disk,sector++,buf,1) != DISK_OK)
{
free(buf);
return 0;
}
if (h == 2)
n = 1;
else
n = 0;
for (; n < bufsiz; n++)
{
clusters[h] = buf[n];
if (++h > nclusters)
break;
}
}
free(buf);
return 1;
}
/*
* serchfat12 reads 12-bit FAT
*
*/
unsigned short searchfat12(int disk, int nclusters, long sector, int secsfat,
unsigned short value)
{
int h,i;
size_t bufsiz;
unsigned char *buf;
unsigned short *pc,c,cluster;
bufsiz = (size_t)secsfat * 512;
if ((buf = malloc(bufsiz)) == NULL)
return -1;
if (disk_read(disk,sector,buf,secsfat) != DISK_OK) {
free(buf);
return 0;
}
buf += 3;
cluster = 0;
for (h = 2; h <= nclusters; buf++)
{
for (i = 0; i < 2; i++)
{
pc = (unsigned short *)(buf++);
if (i&1)
c = *pc >> 4; /* odd */
else
c = *pc & 0xFFF; /* even */
if (c)
cluster = h;
if (++h > nclusters)
break;
}
}
free(buf);
return cluster;
}
/*
* searchfat16 reads 16-bit FAT
*
*/
unsigned short searchfat16(int disk, unsigned short nclusters, long sector,
int secsfat, unsigned short value)
{
long size;
unsigned int n;
unsigned int h,cluster;
unsigned short buf[512];
int (*diskread)(int disk, long sector, void *buffer, int nsecs);
/*
TODO: There should be a way, either here or another function,
to use another disk read function.
*/
#ifndef _WINNT
drive_size(disk,&size);
if (size > (1024L*1024L*32))
diskread = disk_read_ext;
else
#endif
diskread = disk_read;
h = 2;
cluster = 0;
for ( ; secsfat; --secsfat)
{
if (diskread(disk,sector++,buf,1) != DISK_OK)
return 0;
if (h == 2)
n = 1;
else
n = 0;
for (; n < 512/2; n++)
{
if (buf[n])
cluster = h;
if (++h > nclusters)
break;
}
}
return h;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -