aboutsummaryrefslogtreecommitdiff
path: root/libmpio
diff options
context:
space:
mode:
authorgermeier <germeier>2003-04-06 23:09:19 +0000
committergermeier <germeier>2003-04-06 23:09:19 +0000
commit50c439ffa36fed9e1cce65b211ec05bf50925cc2 (patch)
tree923c967c689a873b2497d5daf007531e194c61fc /libmpio
parentc4c88c7d7227834fe2d94f507d01cfafabe885b9 (diff)
downloadmpiosh-50c439ffa36fed9e1cce65b211ec05bf50925cc2.tar.gz
mpiosh-50c439ffa36fed9e1cce65b211ec05bf50925cc2.tar.bz2
mpiosh-50c439ffa36fed9e1cce65b211ec05bf50925cc2.zip
initial support for directories
BEWARE: this might have broken some things!!!
Diffstat (limited to 'libmpio')
-rw-r--r--libmpio/defs.h34
-rw-r--r--libmpio/directory.c379
-rw-r--r--libmpio/directory.h13
-rw-r--r--libmpio/fat.c53
-rw-r--r--libmpio/mpio.c38
-rw-r--r--libmpio/mpio.h12
6 files changed, 451 insertions, 78 deletions
diff --git a/libmpio/defs.h b/libmpio/defs.h
index 2e3d02d..0018591 100644
--- a/libmpio/defs.h
+++ b/libmpio/defs.h
@@ -1,7 +1,7 @@
/* -*- linux-c -*- */
/*
- * $Id: defs.h,v 1.17 2003/04/04 09:25:38 germeier Exp $
+ * $Id: defs.h,v 1.18 2003/04/06 23:09:20 germeier Exp $
*
* Library for USB MPIO-*
*
@@ -73,7 +73,9 @@ typedef enum { FTYPE_CHAN = 0x00,
FTYPE_OTHER = 'H',
FTYPE_MEMO = 'M',
FTYPE_WAV = 'V',
- FTYPE_ENTRY = 'R' } mpio_filetype_t;
+ FTYPE_ENTRY = 'R',
+ FTYPE_DIR = 'D',
+ FTYPE_PLAIN = '-'} mpio_filetype_t;
/* fixed filenames */
#define MPIO_CONFIG_FILE "CONFIG.DAT"
@@ -129,6 +131,7 @@ typedef struct {
char *msg;
} mpio_error_t;
+#define MPIO_OK 0
#define MPIO_ERR_FILE_NOT_FOUND -1
#define MPIO_ERR_NOT_ENOUGH_SPACE -2
#define MPIO_ERR_FILE_EXISTS -3
@@ -136,6 +139,10 @@ typedef struct {
#define MPIO_ERR_READING_FILE -5
#define MPIO_ERR_PERMISSION_DENIED -6
#define MPIO_ERR_WRITING_FILE -7
+#define MPIO_ERR_DIR_TOO_LONG -8
+#define MPIO_ERR_DIR_NOT_FOUND -9
+#define MPIO_ERR_DIR_NOT_A_DIR -10
+#define MPIO_ERR_DIR_NAME_ERROR -11
/* internal errors, occur when UI has errors! */
#define MPIO_ERR_INT_STRING_INVALID -101
@@ -172,6 +179,22 @@ typedef struct {
DWORD SumSector;
} mpio_disk_phy_t;
+/* */
+
+struct mpio_directory_tx {
+ BYTE name[INFO_LINE];
+ BYTE dir[BLOCK_SIZE];
+
+ BYTE *dentry;
+
+ struct mpio_directory_tx *prev;
+ struct mpio_directory_tx *next;
+
+};
+
+typedef struct mpio_directory_tx mpio_directory_t;
+
+
/* view of a SmartMedia(tm) card */
typedef struct {
BYTE id;
@@ -198,6 +221,10 @@ typedef struct {
int fat_nums; /* # of FATs */
BYTE * fat; /* *real FAT (like in block allocation :-) */
+ /* needed for directory support */
+ mpio_directory_t *root; /* root directory */
+ mpio_directory_t *cdir; /* current directory */
+
/* how many physical blocks are available
* for internal memory is this value equal to max_cluster
*/
@@ -207,9 +234,6 @@ typedef struct {
/* lookup table for phys.<->log. block mapping */
mpio_zonetable_t zonetable;
- /* seems to be a fixed size according to the
- Samsung documentation */
- BYTE dir[DIR_SIZE]; /* file index */
} mpio_smartmedia_t;
diff --git a/libmpio/directory.c b/libmpio/directory.c
index be1f00d..0dd8abd 100644
--- a/libmpio/directory.c
+++ b/libmpio/directory.c
@@ -1,6 +1,6 @@
/*
*
- * $Id: directory.c,v 1.15 2003/04/06 12:54:27 germeier Exp $
+ * $Id: directory.c,v 1.16 2003/04/06 23:09:20 germeier Exp $
*
* Library for USB MPIO-*
*
@@ -104,7 +104,90 @@ mpio_charset_set(mpio_t *m, BYTE *charset)
return r;
}
+int
+mpio_directory_init(mpio_t *m, mpio_mem_t mem, mpio_directory_t *dir,
+ WORD self, WORD parent)
+{
+ mpio_dir_entry_t *dentry;
+
+ memset(dir->dir, 0, BLOCK_SIZE);
+ memset(dir->dir, 0x20, 11);
+ memset(dir->dir+0x20, 0x20, 11);
+
+ dentry = (mpio_dir_entry_t *)dir->dir;
+
+ strncpy(dentry->name, ". ", 8);
+ strncpy(dentry->ext, " ", 3);
+ dentry->start[0] = self & 0xff;
+ dentry->start[1] = self / 0x100;
+ dentry->attr = 0x10;
+
+ dentry++;
+ strncpy(dentry->name, ".. ", 8);
+ strncpy(dentry->ext, " ", 3);
+ dentry->start[0] = parent & 0xff;
+ dentry->start[1] = parent / 0x100;
+ dentry->attr = 0x10;
+
+ hexdumpn(2, dir->dir, 64);
+
+ return 0;
+}
+
+
+int
+mpio_directory_read(mpio_t *m, mpio_mem_t mem, mpio_directory_t *dir)
+{
+ mpio_fatentry_t *f = 0;
+
+ f = mpio_dentry_get_startcluster(m, mem, dir->dentry);
+
+ if (!f)
+ {
+ debug("something bad has happened here!");
+ exit (-1);
+ }
+
+ mpio_io_block_read(m, mem, f, dir->dir);
+
+ hexdumpn(5, dir->dir, DIR_SIZE);
+
+ return 0;
+}
+
+int
+mpio_directory_write(mpio_t *m, mpio_mem_t mem, mpio_directory_t *dir)
+{
+ mpio_fatentry_t *f = 0;
+
+ f = mpio_dentry_get_startcluster(m, mem, dir->dentry);
+ if (!f)
+ {
+ debug("something bad has happened here!");
+ exit (-1);
+ }
+
+ if (mem==MPIO_INTERNAL_MEM)
+ {
+ f->i_fat[0x01]= f->i_index;
+ if (m->model >= MPIO_MODEL_FD100)
+ f->i_fat[0x0e] = f->i_index;
+
+ /* only one block needed for directory */
+ f->i_fat[0x02]=0;
+ f->i_fat[0x03]=1;
+
+ /* set type to directory */
+ f->i_fat[0x06] = FTYPE_ENTRY;
+ hexdumpn(0, f->i_fat, 16);
+ }
+
+ mpio_io_block_delete(m, mem, f);
+ mpio_io_block_write(m, mem, f, dir->dir);
+
+ return 0;
+}
/* directory operations */
BYTE *
@@ -113,12 +196,12 @@ mpio_directory_open(mpio_t *m, mpio_mem_t mem)
BYTE *out;
if (mem == MPIO_EXTERNAL_MEM) {
if (m->external.id) {
- out = m->external.dir;
+ out = m->external.cdir->dir;
} else {
return NULL;
}
} else {
- out = m->internal.dir;
+ out = m->internal.cdir->dir;
}
if (out[0] == 0x00)
@@ -132,6 +215,192 @@ mpio_directory_open(mpio_t *m, mpio_mem_t mem)
return out;
}
+int
+mpio_directory_make(mpio_t *m, mpio_mem_t mem, BYTE *dir)
+{
+ mpio_smartmedia_t *sm;
+ mpio_directory_t *new;
+ mpio_fatentry_t *f, *current;
+ WORD self, parent;
+ struct tm tt;
+
+ if (mem == MPIO_INTERNAL_MEM) sm = &m->internal;
+ if (mem == MPIO_EXTERNAL_MEM) sm = &m->external;
+
+ if ((strcmp(dir, "..") == 0) ||
+ (strcmp(dir, ".") == 0))
+ {
+ debugn(2, "directory name not allowed: %s\n", dir);
+ return MPIO_ERR_DIR_NAME_ERROR;
+ }
+
+ /* find free sector */
+ f = mpio_fatentry_find_free(m, mem, FTYPE_ENTRY);
+ if (!f)
+ {
+ debug("could not free cluster for file!\n");
+ return (MPIO_ERR_FAT_ERROR);
+ } else {
+ self=f->entry;
+ }
+
+ /* find file-id for internal memory */
+ if (mem==MPIO_INTERNAL_MEM)
+ {
+ f->i_index=mpio_fat_internal_find_fileindex(m);
+ debugn(2, "fileindex: %02x\n", f->i_index);
+ f->i_fat[0x01]= f->i_index;
+ if (m->model >= MPIO_MODEL_FD100)
+ f->i_fat[0x0e] = f->i_index;
+ self = f->i_index;
+
+ /* only one block needed for directory */
+ f->i_fat[0x02]=0;
+ f->i_fat[0x03]=1;
+ hexdumpn(0, f->i_fat, 16);
+ }
+
+ if (sm->cdir == sm->root)
+ {
+ parent=0;
+ } else {
+ current = mpio_dentry_get_startcluster(m, mem, sm->cdir->dentry);
+ if (mem==MPIO_INTERNAL_MEM)
+ {
+ parent = current->i_index;
+ } else {
+ parent = current->entry;
+ }
+ }
+
+
+ new = malloc(sizeof(mpio_directory_t));
+ mpio_directory_init(m, mem, new, self, parent);
+
+ mpio_fatentry_set_eof(m ,mem, f);
+ mpio_io_block_write(m, mem, f, new->dir);
+ mpio_dentry_put(m, mem,
+ dir, strlen(dir),
+ mktime(&tt),
+ 0, self, 0x10);
+
+ free(new);
+
+ return MPIO_OK;
+}
+
+int
+mpio_directory_cd(mpio_t *m, mpio_mem_t mem, BYTE *dir)
+{
+ mpio_smartmedia_t *sm;
+ BYTE *p;
+ BYTE month, day, hour, minute, type;
+ BYTE fname[100];
+ WORD year;
+ DWORD fsize;
+ int i, size;
+ BYTE pwd[INFO_LINE];
+ mpio_directory_t *old, *new;
+
+ if (strcmp(dir, ".")==0)
+ return MPIO_OK;
+
+ if (mem == MPIO_INTERNAL_MEM) sm = &m->internal;
+ if (mem == MPIO_EXTERNAL_MEM) sm = &m->external;
+
+ if (strcmp(dir, "..") == 0)
+ {
+ if (sm->cdir->prev)
+ {
+ old = sm->cdir;
+ sm->cdir = sm->cdir->prev;
+ sm->cdir->next = NULL;
+ free(old);
+ }
+
+ return MPIO_OK;
+ }
+
+ mpio_directory_pwd(m, mem, pwd);
+
+ if ((strlen(pwd) + strlen(dir) + 2) > INFO_LINE)
+ {
+ debugn(2, "directory name gets to long!\n");
+ return MPIO_ERR_DIR_TOO_LONG;
+ }
+
+
+ p = mpio_dentry_find_name(m, mem, dir);
+
+ /* second try */
+ if (!p)
+ p = mpio_dentry_find_name_8_3(m, mem, dir);
+
+ if (!p)
+ {
+ debugn(2, "could not find directory: %s\n", dir);
+ return MPIO_ERR_DIR_NOT_FOUND;
+ }
+
+ mpio_dentry_get(m, mem, p,
+ fname, 100,
+ &year, &month, &day,
+ &hour, &minute, &fsize,
+ &type);
+
+ if (type != FTYPE_DIR)
+ {
+ debugn(2, "this is not a directory: %s\n", dir);
+ return MPIO_ERR_DIR_NOT_A_DIR;
+ }
+
+ new = malloc(sizeof(mpio_directory_t));
+ strcpy(new->name, dir);
+ new->next = NULL;
+ new->prev = sm->cdir;
+ new->dentry = p;
+ sm->cdir->next = new;
+ sm->cdir = new;
+
+ mpio_directory_pwd(m, mem, pwd);
+
+ if (strcmp(dir, "/") != 0)
+ {
+ /* read new directory */
+ size=mpio_directory_read(m, mem, sm->cdir);
+ }
+
+ return MPIO_OK;
+
+}
+
+
+void
+mpio_directory_pwd(mpio_t *m, mpio_mem_t mem, BYTE pwd[INFO_LINE])
+{
+ mpio_smartmedia_t *sm;
+ mpio_directory_t *d;
+
+ if (mem == MPIO_INTERNAL_MEM) sm = &m->internal;
+ if (mem == MPIO_EXTERNAL_MEM) sm = &m->external;
+
+ d = sm->root->next;
+ pwd[0] = 0;
+
+ if (!d)
+ strcat(pwd, "/");
+
+ while (d)
+ {
+ strcat(pwd, "/");
+ debugn(2, "name: %s\n", d->name);
+ strcat(pwd, d->name);
+ d = d->next;
+ }
+
+ return;
+}
+
int
mpio_dentry_get_size(mpio_t *m, mpio_mem_t mem, BYTE *buffer)
{
@@ -225,13 +494,13 @@ int
mpio_dentry_get(mpio_t *m, mpio_mem_t mem, BYTE *buffer,
BYTE *filename, int filename_size,
WORD *year, BYTE *month, BYTE *day,
- BYTE *hour, BYTE *minute, DWORD *fsize)
+ BYTE *hour, BYTE *minute, DWORD *fsize, BYTE *type)
{
BYTE filename_8_3[13];
return mpio_dentry_get_real(m, mem, buffer, filename, filename_size,
filename_8_3,
- year, month, day, hour, minute, fsize);
+ year, month, day, hour, minute, fsize, type);
}
/* TODO: please clean me up !!! */
@@ -240,7 +509,8 @@ mpio_dentry_get_real(mpio_t *m, mpio_mem_t mem, BYTE *buffer,
BYTE *filename, int filename_size,
BYTE *filename_8_3,
WORD *year, BYTE *month, BYTE *day,
- BYTE *hour, BYTE *minute, DWORD *fsize)
+ BYTE *hour, BYTE *minute, DWORD *fsize,
+ BYTE *type)
{
int date, time;
int vfat = 0;
@@ -319,12 +589,19 @@ mpio_dentry_get_real(mpio_t *m, mpio_mem_t mem, BYTE *buffer,
i--;
filename_8_3[i] = 0;
hexdumpn(4, filename_8_3, 13);
-
+
if (!vfat)
{
if (filename_size >= 12)
{
snprintf(filename, 13, "%s", filename_8_3);
+ /* UGLY !! */
+ if (((strncmp(dentry->name, ". ", 8)==0) &&
+ (strncmp(dentry->ext, " ", 3) == 0)))
+ filename[1]=0;
+ if (((strncmp(dentry->name, ".. ", 8)==0) &&
+ (strncmp(dentry->ext, " ", 3) == 0)))
+ filename[2]=0;
} else {
snprintf(filename, filename_size, "%s", "ERROR");
}
@@ -347,6 +624,13 @@ mpio_dentry_get_real(mpio_t *m, mpio_mem_t mem, BYTE *buffer,
*fsize *= 0x100;
*fsize += dentry->size[0];
+ if (dentry->attr & 0x10) {
+ /* is this a directory? */
+ *type = FTYPE_DIR;
+ } else {
+ *type = FTYPE_PLAIN;
+ }
+
return(((BYTE *)dentry) - buffer);
}
@@ -365,7 +649,7 @@ mpio_rootdir_read (mpio_t *m, mpio_mem_t mem)
if (mpio_io_sector_read(m, mem, (sm->dir_offset + i), recvbuff))
return 1;
- memcpy(sm->dir + (i * SECTOR_SIZE), recvbuff, SECTOR_SIZE);
+ memcpy(sm->root->dir + (i * SECTOR_SIZE), recvbuff, SECTOR_SIZE);
}
return (0);
@@ -379,7 +663,7 @@ mpio_rootdir_clear (mpio_t *m, mpio_mem_t mem)
if (mem == MPIO_INTERNAL_MEM) sm=&m->internal;
if (mem == MPIO_EXTERNAL_MEM) sm=&m->external;
- memset(sm->dir, 0x00, DIR_SIZE);
+ memset(sm->root->dir, 0x00, DIR_SIZE);
return 0;
}
@@ -401,14 +685,18 @@ mpio_dentry_get_filesize(mpio_t *m, mpio_mem_t mem, BYTE *p)
s -= DIR_ENTRY_SIZE ;
}
- fsize = dentry->size[3];
- fsize *= 0x100;
- fsize += dentry->size[2];
- fsize *= 0x100;
- fsize += dentry->size[1];
- fsize *= 0x100;
- fsize += dentry->size[0];
-
+ if (dentry->attr & 0x10) {
+ fsize = BLOCK_SIZE;
+ } else {
+ fsize = dentry->size[3];
+ fsize *= 0x100;
+ fsize += dentry->size[2];
+ fsize *= 0x100;
+ fsize += dentry->size[1];
+ fsize *= 0x100;
+ fsize += dentry->size[0];
+ }
+
return fsize;
}
@@ -440,6 +728,7 @@ mpio_dentry_get_startcluster(mpio_t *m, mpio_mem_t mem, BYTE *p)
{
int s;
DWORD cluster;
+ BYTE i_index;
mpio_dir_slot_t *dentry;
mpio_fatentry_t *new;
@@ -456,7 +745,10 @@ mpio_dentry_get_startcluster(mpio_t *m, mpio_mem_t mem, BYTE *p)
cluster = dentry->start[1] * 0x100 + dentry->start[0];
if (mem == MPIO_INTERNAL_MEM)
- cluster = mpio_fat_internal_find_startsector(m, cluster);
+ {
+ i_index=dentry->start[0];
+ cluster = mpio_fat_internal_find_startsector(m, cluster);
+ }
if (cluster < 0)
return NULL;
@@ -465,8 +757,11 @@ mpio_dentry_get_startcluster(mpio_t *m, mpio_mem_t mem, BYTE *p)
if (mem == MPIO_INTERNAL_MEM)
{
new->entry=cluster;
+ new->i_index=i_index;
mpio_fatentry_entry2hw(m, new);
}
+
+ debugn(2,"i_index=0x%02x\n", new->i_index);
return new;
}
@@ -474,7 +769,7 @@ mpio_dentry_get_startcluster(mpio_t *m, mpio_mem_t mem, BYTE *p)
int
mpio_dentry_put(mpio_t *m, mpio_mem_t mem,
BYTE *filename, int filename_size,
- time_t date, DWORD fsize, WORD ssector)
+ time_t date, DWORD fsize, WORD ssector, BYTE attr)
{
BYTE *unicode = 0;
BYTE *back, *fback;
@@ -505,9 +800,9 @@ mpio_dentry_put(mpio_t *m, mpio_mem_t mem,
p += 0x20;
} else {
if (mem == MPIO_EXTERNAL_MEM)
- p = m->external.dir;
+ p = m->external.cdir->dir;
if (mem == MPIO_INTERNAL_MEM)
- p = m->internal.dir;
+ p = m->internal.cdir->dir;
}
/* generate vfat filename in UNICODE */
@@ -621,7 +916,7 @@ mpio_dentry_put(mpio_t *m, mpio_mem_t mem,
memcpy(dentry->name, f_8_3, 8);
memcpy(dentry->ext, f_8_3+9, 3);
- dentry->attr = 0x20;
+ dentry->attr = attr;
dentry->lcase = 0x00;
@@ -676,7 +971,7 @@ mpio_dentry_find_name_8_3(mpio_t *m, BYTE mem, BYTE *filename)
fname, 128,
fname_8_3,
&wdummy, &bdummy, &bdummy,
- &bdummy, &bdummy, &ddummy);
+ &bdummy, &bdummy, &ddummy, &bdummy);
if ((strcmp(fname_8_3, filename) == 0) &&
(strcmp(filename,fname_8_3) == 0)) {
found = p;
@@ -704,7 +999,7 @@ mpio_dentry_find_name(mpio_t *m, BYTE mem, BYTE *filename)
mpio_dentry_get (m, mem, p,
fname, 128,
&wdummy, &bdummy, &bdummy,
- &bdummy, &bdummy, &ddummy);
+ &bdummy, &bdummy, &ddummy, &bdummy);
if ((strcmp(fname,filename) == 0) && (strcmp(filename,fname) == 0)) {
found = p;
p = NULL;
@@ -751,13 +1046,13 @@ mpio_dentry_delete(mpio_t *m, BYTE mem, BYTE *filename)
/* clear new buffer */
memset(tmp, 0, DIR_SIZE);
/* copy before delete */
- if (start != sm->dir)
- memcpy(tmp, sm->dir, (start - (sm->dir)));
+ if (start != sm->cdir->dir)
+ memcpy(tmp, sm->cdir->dir, (start - (sm->cdir->dir)));
/* copy after delete */
- memcpy(tmp + (start - (sm->dir)), (start + size),
- (sm->dir + DIR_SIZE - (start + size)));
+ memcpy(tmp + (start - (sm->cdir->dir)), (start + size),
+ (sm->cdir->dir + DIR_SIZE - (start + size)));
- memcpy(sm->dir, tmp, DIR_SIZE);
+ memcpy(sm->cdir->dir, tmp, DIR_SIZE);
return 0;
}
@@ -789,7 +1084,7 @@ mpio_dentry_move(mpio_t *m,mpio_mem_t mem,BYTE *m_file,BYTE *a_file) {
// -- if a_file == NULL this is the start of the directory.
if(a_file==NULL) {
- b_file = sm->dir;
+ b_file = sm->cdir->dir;
} else {
b_file = a_file + a_file_s;
}
@@ -805,8 +1100,8 @@ mpio_dentry_move(mpio_t *m,mpio_mem_t mem,BYTE *m_file,BYTE *a_file) {
if(m_file > b_file) {
fprintf(stderr,"U ");
- t0 = sm->dir;
- s0 = b_file - sm->dir;
+ t0 = sm->cdir->dir;
+ s0 = b_file - sm->cdir->dir;
t1 = m_file;
s1 = m_file_s;
@@ -815,11 +1110,11 @@ mpio_dentry_move(mpio_t *m,mpio_mem_t mem,BYTE *m_file,BYTE *a_file) {
s2 = m_file - b_file;
t3 = m_file + m_file_s;
- s3 = DIR_SIZE - (m_file-sm->dir) - m_file_s;
+ s3 = DIR_SIZE - (m_file-sm->cdir->dir) - m_file_s;
} else {
fprintf(stderr,"D ");
- t0 = sm->dir;
- s0 = m_file - sm->dir;
+ t0 = sm->cdir->dir;
+ s0 = m_file - sm->cdir->dir;
t1 = m_file + m_file_s;
s1 = a_file + a_file_s - (m_file + m_file_s);
@@ -828,7 +1123,7 @@ mpio_dentry_move(mpio_t *m,mpio_mem_t mem,BYTE *m_file,BYTE *a_file) {
s2 = m_file_s;
t3 = b_file;
- s3 = DIR_SIZE - (b_file - sm->dir);
+ s3 = DIR_SIZE - (b_file - sm->cdir->dir);
}
if(s0) {
@@ -850,7 +1145,7 @@ mpio_dentry_move(mpio_t *m,mpio_mem_t mem,BYTE *m_file,BYTE *a_file) {
fprintf(stderr," -- t0=%ld, s0=%d, t1=%ld, s1=%d, t2=%ld, s2=%d, t3=%ld, s3=%d; sum=%d, DIRSIZE=%d\n",
(long)t0,s0,(long)t1,s1,(long)t2,s2,(long)t3,s3,s0+s1+s2+s3,DIR_SIZE);
- memcpy(sm->dir, tmp, DIR_SIZE);
+ memcpy(sm->cdir->dir, tmp, DIR_SIZE);
}
void
@@ -882,10 +1177,10 @@ mpio_dentry_switch(mpio_t *m, mpio_mem_t mem, BYTE *file1, BYTE *file2)
current = tmp;
memset(tmp, 0xff, DIR_SIZE);
/* before the first file */
- if (p1 != sm->dir)
+ if (p1 != sm->cdir->dir)
{
- memcpy(current, sm->dir, p1 - sm->dir);
- current += (p1 - sm->dir);
+ memcpy(current, sm->cdir->dir, p1 - sm->cdir->dir);
+ current += (p1 - sm->cdir->dir);
}
/* the second file*/
memcpy(current, p2, size2);
@@ -897,10 +1192,10 @@ mpio_dentry_switch(mpio_t *m, mpio_mem_t mem, BYTE *file1, BYTE *file2)
memcpy(current, p1, size1);
current += size1;
/* and the rest */
- memcpy(current, p2+size2, (sm->dir+DIR_SIZE-p2-size2));
+ memcpy(current, p2+size2, (sm->cdir->dir+DIR_SIZE-p2-size2));
/* really update the directory */
- memcpy(sm->dir, tmp, DIR_SIZE);
+ memcpy(sm->cdir->dir, tmp, DIR_SIZE);
return;
}
diff --git a/libmpio/directory.h b/libmpio/directory.h
index 6e54a04..8281bfa 100644
--- a/libmpio/directory.h
+++ b/libmpio/directory.h
@@ -1,6 +1,6 @@
/*
*
- * $Id: directory.h,v 1.7 2003/02/21 18:28:55 crunchy Exp $
+ * $Id: directory.h,v 1.8 2003/04/06 23:09:20 germeier Exp $
*
* Library for USB MPIO-*
*
@@ -38,11 +38,17 @@ int mpio_rootdir_read (mpio_t *, mpio_mem_t);
int mpio_rootdir_clear (mpio_t *, mpio_mem_t);
int mpio_rootdir_format(mpio_t *, mpio_mem_t);
+/* directory opertations */
+int mpio_directory_init(mpio_t *, mpio_mem_t, mpio_directory_t *,
+ WORD, WORD);
+int mpio_directory_read(mpio_t *, mpio_mem_t, mpio_directory_t *);
+int mpio_directory_write(mpio_t *, mpio_mem_t, mpio_directory_t *);
+
/* operations on a single directory entry */
int mpio_dentry_get_size(mpio_t *, mpio_mem_t, BYTE *);
int mpio_dentry_get_raw(mpio_t *, mpio_mem_t, BYTE *, BYTE *, int);
int mpio_dentry_put(mpio_t *, mpio_mem_t, BYTE *, int,
- time_t, DWORD, WORD);
+ time_t, DWORD, WORD, BYTE);
BYTE * mpio_dentry_find_name_8_3(mpio_t *, BYTE, BYTE *);
BYTE * mpio_dentry_find_name(mpio_t *, BYTE, BYTE *);
int mpio_dentry_delete(mpio_t *, BYTE, BYTE *);
@@ -63,7 +69,8 @@ void mpio_dentry_copy_from_slot(BYTE *, mpio_dir_slot_t *);
void mpio_dentry_copy_to_slot(BYTE *, mpio_dir_slot_t *);
int mpio_dentry_get_real(mpio_t *, mpio_mem_t, BYTE *, BYTE *,
int, BYTE[12],
- WORD *, BYTE *, BYTE *, BYTE *, BYTE *, DWORD *);
+ WORD *, BYTE *, BYTE *, BYTE *, BYTE *, DWORD *,
+ BYTE *);
#ifdef __cplusplus
}
diff --git a/libmpio/fat.c b/libmpio/fat.c
index f26f009..c24f56e 100644
--- a/libmpio/fat.c
+++ b/libmpio/fat.c
@@ -1,6 +1,6 @@
/*
*
- * $Id: fat.c,v 1.25 2003/04/04 22:08:53 germeier Exp $
+ * $Id: fat.c,v 1.26 2003/04/06 23:09:20 germeier Exp $
*
* Library for USB MPIO-*
*
@@ -837,24 +837,31 @@ mpio_fat_write(mpio_t *m, mpio_mem_t mem)
if (mem == MPIO_INTERNAL_MEM) {
sm = &m->internal;
- f=mpio_fatentry_new(m, mem, 0, FTYPE_MUSIC);
- mpio_io_block_delete(m, mem, f);
- free(f);
-
- memset(dummy, 0x00, BLOCK_SIZE);
-
- /* only write the FAT */
- for (i= 0; i< 0x20; i++)
- {
-
- if (i<DIR_NUM)
+ if (sm->cdir == sm->root)
+ {
+ f=mpio_fatentry_new(m, mem, 0, FTYPE_MUSIC);
+ mpio_io_block_delete(m, mem, f);
+ free(f);
+
+ memset(dummy, 0x00, BLOCK_SIZE);
+
+ /* only write the root dir */
+ for (i= 0; i< 0x20; i++)
{
- mpio_io_sector_write(m, mem, i, (sm->dir + SECTOR_SIZE * i));
- } else {
- /* fill the rest of the block with zeros */
- mpio_io_sector_write(m, mem, i, dummy);
- }
- }
+
+ if (i<DIR_NUM)
+ {
+ mpio_io_sector_write(m, mem, i,
+ (sm->root->dir + SECTOR_SIZE * i));
+ } else {
+ /* fill the rest of the block with zeros */
+ mpio_io_sector_write(m, mem, i, dummy);
+ }
+ }
+ } else {
+ mpio_directory_write(m, mem, sm->cdir);
+ }
+
}
if (mem == MPIO_EXTERNAL_MEM)
@@ -896,9 +903,15 @@ mpio_fat_write(mpio_t *m, mpio_mem_t mem)
if (i>=sm->dir_offset)
mpio_io_sector_write(m, mem, i,
- (sm->dir + (i - sm->dir_offset) * SECTOR_SIZE));
+ (sm->root->dir +
+ (i - sm->dir_offset) * SECTOR_SIZE));
}
- }
+
+ if (sm->cdir != sm->root)
+ mpio_directory_write(m, mem, sm->cdir);
+
+ }
+
return 0;
}
diff --git a/libmpio/mpio.c b/libmpio/mpio.c
index ea91ce2..0c6a7e8 100644
--- a/libmpio/mpio.c
+++ b/libmpio/mpio.c
@@ -1,6 +1,6 @@
/*
*
- * $Id: mpio.c,v 1.47 2003/04/05 12:19:49 germeier Exp $
+ * $Id: mpio.c,v 1.48 2003/04/06 23:09:20 germeier Exp $
*
* Library for USB MPIO-*
*
@@ -81,6 +81,14 @@ static mpio_error_t mpio_errors[] = {
"There are not enough rights to access the file/directory." },
{ MPIO_ERR_WRITING_FILE,
"There are no permisson to write to the selected file." },
+ { MPIO_ERR_DIR_TOO_LONG,
+ "The selected directory name is to long." },
+ { MPIO_ERR_DIR_NOT_FOUND,
+ "The selected directory can not be found." },
+ { MPIO_ERR_DIR_NOT_A_DIR,
+ "The selected directory is not a directory." },
+ { MPIO_ERR_DIR_NAME_ERROR,
+ "The selected directory name is not allowed." },
{ MPIO_ERR_INT_STRING_INVALID,
"Internal Error: Supported is invalid!" }
};
@@ -121,7 +129,7 @@ mpio_check_filename(mpio_filename_t filename)
void
mpio_init_internal(mpio_t *m)
{
- mpio_smartmedia_t *sm = &(m->internal);
+ mpio_smartmedia_t *sm = &m->internal;
BYTE i_offset = 0x18;
/* init main memory parameters */
@@ -187,7 +195,12 @@ mpio_init_internal(mpio_t *m)
/* Read directory from internal memory */
sm->dir_offset=0;
+ sm->root = malloc (sizeof(mpio_directory_t));
+ sm->root->name[0] = 0;
+ sm->root->next = NULL;
+ sm->root->prev = NULL;
mpio_rootdir_read(m, MPIO_INTERNAL_MEM);
+ sm->cdir = sm->root;
}
void
@@ -234,6 +247,14 @@ mpio_init_external(mpio_t *m)
sm->max_blocks = sm->size / 16 * 1024; /* 1 cluster == 16 KB */
sm->spare = malloc(sm->max_blocks * 0x10);
}
+
+ /* setup directory support */
+ sm->dir_offset=0;
+ sm->root = malloc (sizeof(mpio_directory_t));
+ sm->root->name[0] = 0;
+ sm->root->next = NULL;
+ sm->root->prev = NULL;
+ sm->cdir = sm->root;
}
mpio_t *
@@ -822,7 +843,7 @@ mpio_file_put_real(mpio_t *m, mpio_mem_t mem, mpio_filename_t i_filename,
mpio_dentry_put(m, mem,
o_filename, strlen(o_filename),
((memory)?mktime(&tt):file_stat.st_ctime),
- fsize, start);
+ fsize, start, 0x20);
}
return fsize-filesize;
@@ -1021,6 +1042,13 @@ mpio_file_del(mpio_t *m, mpio_mem_t mem, mpio_filename_t filename,
if (mem == MPIO_INTERNAL_MEM) sm = &m->internal;
if (mem == MPIO_EXTERNAL_MEM) sm = &m->external;
+ if ((strcmp(filename, "..") == 0) ||
+ (strcmp(filename, ".") == 0))
+ {
+ debugn(2, "directory name not allowed: %s\n", filename);
+ return MPIO_ERR_DIR_NAME_ERROR;
+ }
+
/* find file */
p = mpio_dentry_find_name(m, mem, filename);
if (!p)
@@ -1099,14 +1127,14 @@ mpio_memory_dump(mpio_t *m, mpio_mem_t mem)
if (mem == MPIO_INTERNAL_MEM)
{
hexdump(m->internal.fat, m->internal.max_blocks*0x10);
- hexdump(m->internal.dir, DIR_SIZE);
+ hexdump(m->internal.root->dir, DIR_SIZE);
}
if (mem == MPIO_EXTERNAL_MEM)
{
hexdump(m->external.spare, m->external.max_blocks*0x10);
hexdump(m->external.fat, m->external.fat_size*SECTOR_SIZE);
- hexdump(m->external.dir, DIR_SIZE);
+ hexdump(m->external.root->dir, DIR_SIZE);
}
for (i = 0 ; i<=0x100 ; i++)
diff --git a/libmpio/mpio.h b/libmpio/mpio.h
index 152c27a..94db5af 100644
--- a/libmpio/mpio.h
+++ b/libmpio/mpio.h
@@ -1,7 +1,7 @@
#/* -*- linux-c -*- */
/*
- * $Id: mpio.h,v 1.14 2003/02/21 18:28:56 crunchy Exp $
+ * $Id: mpio.h,v 1.15 2003/04/06 23:09:20 germeier Exp $
*
* Library for USB MPIO-*
*
@@ -75,11 +75,17 @@ BYTE mpio_charset_set(mpio_t *, BYTE *);
/* context, memory bank */
BYTE* mpio_directory_open(mpio_t *, mpio_mem_t);
+/* context, memory bank, directory name */
+int mpio_directory_make(mpio_t *, mpio_mem_t, BYTE *);
+/* context, memory bank, directory name */
+int mpio_directory_cd(mpio_t *, mpio_mem_t, BYTE *);
+/* context, memory bank, directory name buffer space */
+void mpio_directory_pwd(mpio_t *, mpio_mem_t, BYTE pwd[INFO_LINE]);
/* context, dir context */
BYTE* mpio_dentry_next(mpio_t *, mpio_mem_t, BYTE *);
/* context, dir context */
int mpio_dentry_get(mpio_t *, mpio_mem_t, BYTE *, BYTE *, int,WORD *,
- BYTE *, BYTE *, BYTE *, BYTE *, DWORD *);
+ BYTE *, BYTE *, BYTE *, BYTE *, DWORD *, BYTE *);
/*
* reading/writing/deleting of files
@@ -143,7 +149,7 @@ int mpio_file_move(mpio_t *,mpio_mem_t m,mpio_filename_t,mpio_filename_t);
int mpio_memory_format(mpio_t *, mpio_mem_t, mpio_callback_t);
/* mpio_sync has to be called after every set of mpio_file_{del,put}
- * operations to write the current state of FAT and root directory.
+ * operations to write the current state of FAT and (root) directory.
* This is done explicitly to avoid writing these informations to often
* and thereby exhausting the SmartMedia chips
*/