char d_name[NAME_MAX + 1];
};
+struct file;
+
typedef struct {
- uint16_t dd_stat;
- uint16_t dd_sect;
- uint64_t dd_offset;
- char dd_name[NAME_MAX + 1];
+ struct file *dd_dir;
} DIR;
__extern DIR *opendir(const char *);
int rv = -1;
if (dir) {
- /*
- com32sys_t regs;
- memset(®s, 0, sizeof regs);
- regs.eax.w[0] = 0x0022;
- regs.esi.l = OFFS_WRT(dir, 0);
- __com32.cs_intcall(0x22, ®s, ®s);
- */
- free(dir);
- rv = 0;
+ com32sys_t regs;
+ memset(®s, 0, sizeof regs);
+ regs.eax.w[0] = 0x0022;
+ regs.esi.l = (uint32_t)dir;
+ __com32.cs_intcall(0x22, ®s, ®s);
+ free(dir);
+ rv = 0;
}
return rv;
if (!(regs.eflags.l & EFLAGS_CF)) {
/* Initialization: malloc() then zero */
newdir = calloc(1, sizeof(DIR));
- strcpy(newdir->dd_name, pathname);
- newdir->dd_sect = regs.eax.l;
- newdir->dd_offset = 0;
- newdir->dd_stat = 0;
+ newdir->dd_dir = (struct file *)regs.eax.l;
}
-
+
/* We're done */
return newdir;
}
struct dirent *readdir(DIR * dir)
{
- struct dirent *newde = NULL;;
+ struct dirent *newde;
com32sys_t regs;
- if ((dir !=NULL) && (dir->dd_sect != 0) && (dir->dd_stat != 0xffff)) {
memset(®s, 0, sizeof(regs));
regs.eax.w[0] = 0x0021;
regs.esi.l = (uint32_t)dir;
__com32.cs_intcall(0x22, ®s, ®s);
newde = (struct dirent *)(regs.eax.l);
- }
return newde;
}
}
dir = opendir(argv[1]);
+ printf("back from in main ...? \n");
if (dir == NULL) {
printf("Unable to read dir: %s\n", argv[1]);
return 0;
filepos = 0;
d = opendir(filestr);
if (d != NULL) {
- printf("DIR:'%s' %08x %8d\n", d->dd_name, (int)d->dd_sect,
- d->dd_offset);
+ //printf("DIR:'%s' %08x %8d\n", d->dd_name, (int)d->dd_sect, d->dd_offset);
de = readdir(d);
while (de != NULL) {
filepos++;
; INT 22h AX=0020h Open directory
;
%if IS_SYSLINUX
+ global comapi_opendir
comapi_opendir:
mov es,P_ES
mov si,P_SI
cmp eax,0
jz comapi_err ; Found nothing
mov P_EAX,eax
- mov P_CX,SECTOR_SIZE
- mov P_SI,si
clc
ret
%else
;
; INT 22h AX=0022h Close directory
;
-comapi_closedir equ comapi_close
+comapi_closedir:
+ mov esi,P_ESI ; The address of DIR structure
+ pm_call closedir
+ ret
;
; INT 22h AX=0023h Query shuffler size
#include <fs.h>
#include <core.h>
-/* The dir log structure, to log the status of the dir_buf. */
-struct dir_log {
- int offset; /* how far from the dir_buf */
- int index; /* which dir entry have we go */
-};
-static struct dir_log log = {0, 0};
-
-/* The dir buffer used by fill_dir to store the newly read dirs*/
-#define DB_SIZE 2048
-char dir_buf[DB_SIZE];
+extern struct fs_info *this_fs;
+/*
+ * open dir, return the file structure pointer in _eax_, or NULL if failed
+ */
void opendir(com32sys_t *regs)
{
- int ds = regs->ds; /* save ds */
-
- regs->ds = regs->es;
- regs->es = ds;
- mangle_name(regs);
- regs->ds = ds; /* restore ds */
- searchdir(regs);
-}
-
-/*
- * Fill the dir buffer; return 1 for not full, 0 for full
- */
-int fill_dir(struct dirent *de)
-{
- int de_len = de->d_reclen;
- if (log.offset + de_len <= DB_SIZE) {
- memcpy(dir_buf + log.offset, de, de_len);
- log.offset += de_len;
- log.index ++;
- return 1;
- }
-
- return 0;
+ this_fs->fs_ops->opendir(regs);
+ regs->eax.l = (uint32_t)handle_to_file(regs->esi.w[0]);
}
/*
*/
void readdir(com32sys_t *regs)
{
- extern struct fs_info *this_fs;
- DIR *dir = (DIR *)regs->esi.l;
+ DIR *dir = (DIR *)regs->esi.l;
struct dirent *de = NULL;
- static int offset;
-
- /* If we haven't fill the dir buffer, fill it */
- if (log.index == 0) {
- this_fs->fs_ops->readdir(this_fs, dir);
- if (log.offset == 0) {
- regs->eax.l = 0;
- return;
- }
- offset = 0; /* reset the _offset_ */
- }
-
- if (offset < log.offset) {
- de = (struct dirent *)(dir_buf + offset);
- offset += de->d_reclen;
- }
- if (offset >= log.offset) /* reach the end of buffer, reset it */
- memset(&log, 0, sizeof log);
+ if (dir->dd_dir)
+ de = this_fs->fs_ops->readdir(dir->dd_dir);
+ else
+ de = NULL;
+
/* Return the newly read de in _eax_ register */
regs->eax.l = (uint32_t)de;
}
void closedir(com32sys_t *regs)
{
- regs->esi.w[0] = 0;
+ DIR *dir = (DIR *)regs->esi.l;
+ _close_file(dir->dd_dir);
}
extern unmangle_name, close_file
; dir.c
- extern opendir, readdir, readdir
+ extern opendir, readdir, closedir
%endif ; EXTERN_INC
struct fs_info fs;
/* Actual file structures (we don't have malloc yet...) */
-static struct file Files[MAX_OPEN];
+struct file files[MAX_OPEN];
+/*
+ * Convert between a 16-bit file handle and a file structure
+ */
+inline uint16_t file_to_handle(struct file *file)
+{
+ return file ? (file - files)+1 : 0;
+}
+inline struct file *handle_to_file(uint16_t handle)
+{
+ return handle ? &files[handle-1] : NULL;
+}
/*
* Get an empty file structure
static struct file *alloc_file(void)
{
int i;
- struct file *file = Files;
+ struct file *file = files;
for (i = 0; i < MAX_OPEN; i++) {
if (!file->open_file)
memset(file, 0, sizeof *file);
}
-static void _close_file(struct file *file)
+void _close_file(struct file *file)
{
if (file->open_file)
file->fs->fs_ops->close_file(file);
free_file(file);
}
-/*
- * Convert between a 16-bit file handle and a file structure
- */
-static inline uint16_t file_to_handle(struct file *file)
-{
- return file ? (file - Files)+1 : 0;
-}
-static inline struct file *handle_to_file(uint16_t handle)
-{
- return handle ? &Files[handle-1] : NULL;
-}
-
void load_config(com32sys_t *regs)
{
this_fs->fs_ops->load_config(regs);
if (attr & 0x10) {
found_dir:
open_file = alloc_fill_dir(dir_sector);
- /*
- * for dir, we use the file->file_len to store the sector number
- * where the dir is.
- */
- file_len = dir_sector;
- } else if ((attr & 0x18) || (file_len == 0)) {
+ } else if ((attr & 0x18) || (file_len == 0)) {
fail:
file_len = 0;
open_file = NULL;
file->open_file = open_file;
}
-
-
+/*
+ * The open dir function, just call the searchdir function directly.
+ * I don't think we need call the mangle_name function first
+ */
+void vfat_opendir(com32sys_t *regs)
+{
+ char *src = MK_PTR(regs->es, regs->esi.w[0]);
+ char *dst = MK_PTR(regs->ds, regs->edi.w[0]);
+ strcpy(dst, src);
+ searchdir(regs);
+}
/*
- * read one file from a directory
- * return 1 if error, or 0 if success
+ * read one file from a directory; return the newly read de structure
*/
-void vfat_readdir(struct fs_info *fs, DIR *dir)
+struct dirent* vfat_readdir(struct file *dir)
{
uint32_t sector, sec_off;
/* make it to be 1 to check if we have met a long name entry before */
uint8_t checksum = 0;
uint8_t entries_left;
int i;
- int not_full = 1;
- struct dirent de;
+ static struct dirent de;
char *de_name = de.d_name;
struct cache_struct *cs;
struct fat_dir_entry *fat_dir;
- struct fat_long_name_entry *long_dir;
-
- sector = dir->dd_sect;
- sec_off = dir->dd_offset;
+ struct fat_long_name_entry *long_dir;
+ struct open_file_t *file = dir->open_file;
+ struct fs_info *fs = dir->fs;
+
+ sector = file->file_sector;
+ sec_off = file->file_bytesleft;
if (!sector)
- return 1;
+ return NULL;
entries_left = (SECTOR_SIZE - sec_off) >> 5;
cs = get_cache_block(this_fs->fs_dev, sector);
fat_dir = (struct fat_dir_entry *)(cs->data + sec_off);/* resume last position in sector */
- while (not_full) {
+ while (1) {
if (!entries_left) {
sector = nextsector(fs, sector);
if (!sector)
- goto end;
+ return NULL;
cs = get_cache_block(fs->fs_dev, sector);
fat_dir = (struct fat_dir_entry *)cs->data;
}
if (fat_dir->name[0] == 0)
- goto end;
+ return NULL;
if (fat_dir->attr == FAT_ATTR_LONG_NAME) {
/* it's a long name */
long_dir = (struct fat_long_name_entry *)fat_dir;
if (!id) {
/* Got a long name match */
- //if (get_checksum(fat_dir->name) != checksum)
- //goto next_entry;
+ if (get_checksum(fat_dir->name) != checksum)
+ goto next_entry;
- /* reset _id_ and _checksum_ */
- id = 1;
- checksum = 0;
- goto fill;
+ break;
}
if (fat_dir->attr & FAT_ATTR_VOLUME_ID ||
else
*de_name = '\0';
- fill:
- de.d_type = fat_dir->attr;
- de.d_reclen = DIR_REC_LEN(de.d_name);
- not_full = fill_dir(&de);
- de_name = de.d_name; /* reset the de_name pointer */
+ break;
}
next_entry:
entries_left --;
fat_dir ++;
}
-
- /* dir buffer filled, now it's time to update the DIR structure */
+
+ /* found what we want, fill the de structure */
+ de.d_reclen = DIR_REC_LEN(de.d_name);
+ de.d_type = fat_dir->attr;
+
+ /* update the DIR structure */
+ entries_left--;
if (!entries_left) {
- sector = nextsector(fs, sector);
- if (!sector)
- return 1;
- dir->dd_offset = 0;
+ sector = nextsector(fs, sector);
+ file->file_bytesleft = 0;
} else {
- dir->dd_offset = SECTOR_SIZE - (entries_left << 5);
+ file->file_bytesleft = SECTOR_SIZE - (entries_left << 5);
}
- dir->dd_sect = sector;
- return;
-
- end:
- /* Reach the end of this directory */
- dir->dd_stat = -1;
+ file->file_sector = sector;
+
+ return &de;
}
static void vfat_load_config(com32sys_t *regs)
.mangle_name = vfat_mangle_name,
.unmangle_name = generic_unmangle_name,
.load_config = vfat_load_config,
+ .opendir = vfat_opendir,
.readdir = vfat_readdir
};
#include <string.h>
#include <com32.h>
#include "disk.h"
+#include "fs.h"
struct dirent {
uint32_t d_ino;
char d_name[256];
};
+struct file;
+
typedef struct {
- uint16_t dd_stat;
- uint16_t dd_sect;
- sector_t dd_offset;
- char dd_name[256];
+ struct file *dd_dir;
} DIR;
#define DIR_REC_LEN(name) (12 + strlen(name) + 1 + 3) & ~3
-/*
- * funtions
- */
-int fill_dir(struct dirent *);
#endif /* dir.h */
void (*load_config)(com32sys_t *);
/* the _dir_ stuff */
- void (*readdir)(struct fs_info *, DIR *);
+ void (*opendir)(com32sys_t *);
+ struct dirent * (*readdir)(struct file *);
};
enum dev_type {CHS, EDD};
*/
void mangle_name(com32sys_t *);
void searchdir(com32sys_t *);
-
-
+void _close_file(struct file *);
+inline uint16_t file_to_handle(struct file *);
+inline struct file *handle_to_file(uint16_t);
#endif /* FS_H */