kolibrios-gitea/programs/develop/libraries/libs_v2/fs.c
pavelyakov befac9b242 source code library
git-svn-id: svn://kolibrios.org@5936 a494cfbc-eb01-0410-851d-a64ba20cac60
2015-11-27 09:20:48 +00:00

897 lines
20 KiB
C

/*
2015
Author: Pavel Yakovlev.
*/
#define LIB_NAME "fs"
#include "coff.h"
#include <kolibri.c>
#include <stdlib.c>
//char _PATH_[4096];
char *_PATH_;
dword *_ADR_ = 32;
char *FS_SELF_PATH;
char *FS_SELF_DIR=0;
char TMP1[4096] = {0};
char TMP2[4096] = {0};
static void*(* _stdcall pointer_callback_copy)(void);
static void*(* _stdcall pointer_callback_move)(void);
static void*(* _stdcall pointer_callback_remove)(void);
#pragma pack(push,1)
typedef struct
{
unsigned p00;
unsigned p04;
unsigned p08;
unsigned p12;
unsigned p16;
char p20;
char *p21;
} FS_struct70;
#pragma pack(pop)
#pragma pack(push,1)
typedef struct
{
unsigned p00;
char p04;
char p05[3];
unsigned p08;
unsigned p12;
unsigned p16;
unsigned p20;
unsigned p24;
unsigned p28;
//unsigned p32[2];
long long p32;
unsigned p40;
} FS_struct_BDVK;
#pragma pack(pop)
#define FS_COPY_BUFFER_SET 0x100000
static inline char BUF_COPY[FS_COPY_BUFFER_SET] = {0};
static inline char *string_error_code(char code)
{
if(!code)return "Successfully!";
if(code==1)return "Not defined basis and / or hard disk partition (sub-functions 7, 8 function 21)!";
if(code==2)return "Function is not supported for this file system!";
if(code==3)return "Unknown file system!";
if(code==4)return "Reserved, never returned to the current implementation!";
if(code==5)return "File not found!";
if(code==6)return "The file is ended!";
if(code==7)return "Pointer out the application memory!";
if(code==8)return "Disk is full!";
if(code==9)return "FAT table is destroyed!";
if(code==10)return "Access is denied!";
if(code==11)return "Device error!";
return "An unexpected error!";
}
static inline dword sprintf(char *mstr,const char *fmt,...)
{
dword *arg = &fmt;
char *tmp = 0;
char *pos = mstr;
--pos;
--fmt;
while(*++fmt)
{
char s = *fmt;
if(s=='%')
{
s = *++fmt;
if(s=='s')
{
tmp = *++arg;
while(*tmp)*++pos = *tmp++;
}
else
{
*++pos='%';
--fmt;
}
}
else *++pos=s;
}
*++pos = 0;
return pos-mstr;
}
static inline int FS_file_70(FS_struct70 *k)
{
asm volatile ("int $0x40"::"a"(70), "b"(k));
}
FS_struct_BDVK ret_struct;
static inline char get_bdvk(char *path)
{
FS_struct70 file_read_struct;
file_read_struct.p00 = 5;
file_read_struct.p04 = 0;
file_read_struct.p08 = 0;
file_read_struct.p12 = 0;
file_read_struct.p16 = (unsigned)&ret_struct;
file_read_struct.p20 = 0;
file_read_struct.p21 = path;
return FS_file_70(&file_read_struct);
//return (FS_struct_BDVK*)&ret_struct;
}
static inline char set_bdvk(char *path,FS_struct_BDVK *bdvk)
{
FS_struct70 file_read_struct;
file_read_struct.p00 = 6;
file_read_struct.p04 = 0;
file_read_struct.p08 = 0;
file_read_struct.p12 = 0;
file_read_struct.p16 = bdvk;
file_read_struct.p20 = 0;
file_read_struct.p21 = path;
return FS_file_70(&file_read_struct);
}
static inline long long file_size(char *path)
{
FS_struct_BDVK *data = get_bdvk(path);
return data->p32;
}
static inline byte file_isdir(char *path)
{
FS_struct_BDVK *data = get_bdvk(path);
if(data->p00&0b10000)return 1;
return 0;
}
static inline byte file_ismetka(char *path)
{
FS_struct_BDVK *data = get_bdvk(path);
if(data->p00&0b1000)return 1;
return 0;
}
static inline byte file_isfile()
{
//FS_struct_BDVK *data = get_bdvk(path);
if(ret_struct.p00&0b11000)return 0;
return 1;
}
static inline int file_run(char *path,char *arg)
{
FS_struct70 file_read_struct;
file_read_struct.p00 = 7;
file_read_struct.p04 = 0;
file_read_struct.p08 = arg;
file_read_struct.p12 = 0;
file_read_struct.p16 = 0;
file_read_struct.p20 = 0;
file_read_struct.p21 = path;
return FS_file_70(&file_read_struct);
}
static inline int file_read_binary(char *path,unsigned pos,unsigned size,void *adr)
{
FS_struct70 file_read_struct;
file_read_struct.p00 = 0;
file_read_struct.p04 = pos;
file_read_struct.p08 = 0;
file_read_struct.p12 = size;
file_read_struct.p16 = (unsigned)adr;
file_read_struct.p20 = 0;
file_read_struct.p21 = path;
char c = FS_file_70(&file_read_struct);
if(c)
{
sprintf(&BUF_COPY,"'Error read file (%s) file: %s.'E",string_error_code(c),path);
file_run("/sys/@notify",&BUF_COPY);
}
return c;
}
static inline int file_delete(char *path)
{
FS_struct70 file_read_struct;
file_read_struct.p00 = 8;
file_read_struct.p04 = 0;
file_read_struct.p08 = 0;
file_read_struct.p12 = 0;
file_read_struct.p16 = 0;
file_read_struct.p20 = 0;
file_read_struct.p21 = path;
char c = FS_file_70(&file_read_struct);
if(c)
{
sprintf(&BUF_COPY,"'Error delete file: %s. Info: %s'E",string_error_code(c),path);
file_run("/sys/@notify",&BUF_COPY);
}
return c;
}
static inline int file_mkdir(char *path)
{
FS_struct70 file_read_struct;
file_read_struct.p00 = 9;
file_read_struct.p04 = 0;
file_read_struct.p08 = 0;
file_read_struct.p12 = 0;
file_read_struct.p16 = 0;
file_read_struct.p20 = 0;
file_read_struct.p21 = path;
char c = FS_file_70(&file_read_struct);
if(c)
{
sprintf(&BUF_COPY,"'Error make dir: %s. Info: %s.'E",string_error_code(c),path);
file_run("/sys/@notify",&BUF_COPY);
}
return c;
}
static inline int file_write(char *path,void *ukaz,dword size)
{
FS_struct70 file_read_struct;
file_read_struct.p00 = 2;
file_read_struct.p04 = 0;
file_read_struct.p08 = 0;
file_read_struct.p12 = size;
file_read_struct.p16 = ukaz;
file_read_struct.p20 = 0;
file_read_struct.p21 = path;
char c = FS_file_70(&file_read_struct);
if(c)
{
sprintf(&BUF_COPY,"'Error write file: %s. Info: %s.'E",string_error_code(c),path);
file_run("/sys/@notify",&BUF_COPY);
}
return c;
}
static inline int file_rewrite(char *path,dword pos1,dword pos2,void *ukaz,dword size)
{
FS_struct70 file_read_struct;
file_read_struct.p00 = 3;
file_read_struct.p04 = pos1;
file_read_struct.p08 = pos2;
file_read_struct.p12 = size;
file_read_struct.p16 = ukaz;
file_read_struct.p20 = 0;
file_read_struct.p21 = path;
char c = FS_file_70(&file_read_struct);
if(c)
{
sprintf(&BUF_COPY,"'Error rewrite file (%s) file: %s.'E",string_error_code(c),path);
file_run("/sys/@notify",&BUF_COPY);
}
return c;
}
static inline char file_copy(char *path1,char *path2)
{
long long size = file_size(path1);
if(!size)file_write(path2,&BUF_COPY,0);
long long cel = size;
cel /= FS_COPY_BUFFER_SET;
dword ost = size-cel*FS_COPY_BUFFER_SET;
long long i = 0;
char err=0;
if(cel)
{
if(file_read_binary(path1,0,FS_COPY_BUFFER_SET,&BUF_COPY))goto ERROR;
if(file_write(path2,&BUF_COPY,FS_COPY_BUFFER_SET))goto ERROR;
++i;
}
else
{
if(file_read_binary(path1,0,ost,&BUF_COPY))goto ERROR;
if(file_write(path2,&BUF_COPY,ost))goto ERROR;
return 1;
}
while(i<cel)
{
if(file_read_binary(path1,FS_COPY_BUFFER_SET*i,FS_COPY_BUFFER_SET,&BUF_COPY))goto ERROR;
if(file_rewrite(path2,FS_COPY_BUFFER_SET*i,0,&BUF_COPY,FS_COPY_BUFFER_SET))goto ERROR;
++i;
}
if(file_read_binary(path1,FS_COPY_BUFFER_SET*i,ost,&BUF_COPY))goto ERROR;
if(file_rewrite(path2,FS_COPY_BUFFER_SET*i,0,&BUF_COPY,ost))goto ERROR;
return 1;
ERROR:
//asm("":"=a"(err));
//sprintf(&BUF_COPY,"Error %s file: %s.",string_error_code(err),path1);
//file_run("/sys/@notify",&BUF_COPY);
return 0;
}
/*
dword FS_COPY_BUFFER_SET_POINT = 0x100000;
dword BUF_COPY_POINT = 0;
static inline char file_copy(char *path1,char *path2)
{
long long size = file_size(path1);
if(!size)file_write(path2,BUF_COPY_POINT,0);
long long cel = size;
cel /= FS_COPY_BUFFER_SET_POINT;
dword ost = size-cel*FS_COPY_BUFFER_SET_POINT;
long long i = 0;
char err=0;
if(cel)
{
if(file_read_binary(path1,0,FS_COPY_BUFFER_SET_POINT,BUF_COPY_POINT))goto ERROR;
if(file_write(path2,BUF_COPY_POINT,FS_COPY_BUFFER_SET_POINT))goto ERROR;
++i;
}
else
{
if(file_read_binary(path1,0,ost,BUF_COPY_POINT))goto ERROR;
if(file_write(path2,BUF_COPY_POINT,ost))goto ERROR;
return 1;
}
while(i<cel)
{
if(file_read_binary(path1,FS_COPY_BUFFER_SET_POINT*i,FS_COPY_BUFFER_SET_POINT,BUF_COPY_POINT))goto ERROR;
if(file_rewrite(path2,FS_COPY_BUFFER_SET_POINT*i,0,BUF_COPY_POINT,FS_COPY_BUFFER_SET_POINT))goto ERROR;
++i;
}
if(file_read_binary(path1,FS_COPY_BUFFER_SET_POINT*i,ost,BUF_COPY_POINT))goto ERROR;
if(file_rewrite(path2,FS_COPY_BUFFER_SET_POINT*i,0,BUF_COPY_POINT,ost))goto ERROR;
return 1;
ERROR:
//asm("":"=a"(err));
//sprintf(BUF_COPY_POINT,"Error %s file: %s.",string_error_code(err),path1);
//file_run("/sys/@notify",BUF_COPY_POINT);
return 0;
}
*/
/*
#define FS_COPY_BUFFER_SET 0x100000
char BUF_COPY[FS_COPY_BUFFER_SET] = {0};
static inline char file_copy(char *path1,char *path2)
{
long long size = file_size(path1);
if(!size)file_write(path2,&BUF_COPY,0);
long long cel = size;
cel /= FS_COPY_BUFFER_SET;
dword ost = size-cel*FS_COPY_BUFFER_SET;
long long i = 0;
if(cel)
{
file_read_binary(path1,0,FS_COPY_BUFFER_SET,&BUF_COPY);
file_write(path2,&BUF_COPY,FS_COPY_BUFFER_SET);
++i;
}
else
{
file_read_binary(path1,0,ost,&BUF_COPY);
file_write(path2,&BUF_COPY,ost);
return 1;
}
while(i<cel)
{
file_read_binary(path1,FS_COPY_BUFFER_SET*i,FS_COPY_BUFFER_SET,&BUF_COPY);
file_rewrite(path2,FS_COPY_BUFFER_SET*i,0,&BUF_COPY,FS_COPY_BUFFER_SET);
++i;
}
file_read_binary(path1,FS_COPY_BUFFER_SET*i,ost,&BUF_COPY);
file_rewrite(path2,FS_COPY_BUFFER_SET*i,0,&BUF_COPY,ost);
return 1;
}
*/
long long size_long_file=0;
static inline void *file_read(char *path)
{
size_long_file = file_size(path);
void *data = malloc(size_long_file+1);
if(file_read_binary(path,0,size_long_file,data))return 0;
return data;
}
static inline void *file_readKPACK(char *path)
{
void *data = 0;
dword size=0;
asm ("int $0x40":"=a"(data),"=d"(size):"a"(68), "b"(27), "c"(path));
size_long_file = size;
asm volatile(""::"c"(size));
return data;
}
static inline int file_read_dir(dword begin,dword file_count,dword read_buffer,char *dir_path)
{
FS_struct70 file_read_struct;
file_read_struct.p00 = 1;
file_read_struct.p04 = begin;
file_read_struct.p08 = 0;
file_read_struct.p12 = file_count;
file_read_struct.p16 = read_buffer;
file_read_struct.p20 = 0;
file_read_struct.p21 = dir_path;
return FS_file_70(&file_read_struct);
}
static inline byte strncmp(char *s1,const char *s2, dword n)
{
while(n)
{
if(*s1!=*s2)return *s1-*s2;
++s1;
++s2;
--n;
}
return 0;
}
char *strdup(char *str)
{
char *r = malloc(strlen(str));
strcpy(r,str);
return r;
}
char *self_get_dir(void)
{
if(!FS_SELF_DIR)
{
FS_SELF_DIR = malloc(4096);
//FS_SELF_PATH = malloc(4096);
//strcpy(FS_SELF_PATH,*_ADR_);
FS_SELF_PATH = *_ADR_;
int pos=0;
int tmp=0;
while(FS_SELF_PATH[pos])
{
FS_SELF_DIR[pos] = FS_SELF_PATH[pos];
if(FS_SELF_PATH[pos]=='/')tmp = pos;
++pos;
}
if(tmp)pos=tmp;
FS_SELF_DIR[pos]=0;
}
return FS_SELF_DIR;
}
char *get_full_path(char *path)
{
self_get_dir();
if(!path) return FS_SELF_DIR;
char *pos = path;
if(!_PATH_) _PATH_ = malloc(4096);
if(*pos=='/')
{
++pos;
if(!strncmp(pos,"sys/",4)) return path;
if(!strncmp(pos,"kolibrios/",10)) return path;
if(!strncmp(pos,"rd/",3)) return path;
if(!strncmp(pos,"fd/",3)) return path;
if(!strncmp(pos,"cd",2)) return path;
if(!strncmp(pos,"hd",2)) return path;
if(!strncmp(pos,"bd",2)) return path;
if(!strncmp(pos,"tmp",3)) return path;
if(!strncmp(pos,"usbhd",5)) return path;
if(!*pos)return path;
strcpy(_PATH_,"/sys");
strcpy(_PATH_+4,path);
return _PATH_;
}
if(!strncmp(path,"./",2)) return path;
sprintf(_PATH_,"%s/%s",FS_SELF_DIR,path);
return _PATH_;
}
long long FS_LENGHT=0;
dword *__BUF__COUNT__ = 0;
int COUNT_FILE = 0;
int _get_entries_count(char *path)
{
//char BUF[32];
if(!__BUF__COUNT__)__BUF__COUNT__=malloc(32);
if(!file_read_dir(0,0, __BUF__COUNT__, path))
{
if(strcmp(path,"/"))COUNT_FILE = *(__BUF__COUNT__+2)-2;
else COUNT_FILE = *(__BUF__COUNT__+2);
return COUNT_FILE;
}
COUNT_FILE = -1;
return -1;
}
int get_entries_count(char *path)
{
return _get_entries_count(get_full_path(path));
}
dword _get_dir_info(char *path)
{
_get_entries_count(path);
if(!strcmp(path,"/"))
{
if(COUNT_FILE==-1)return 0;
dword buffer = malloc(304*COUNT_FILE+72);
file_read_dir(0,COUNT_FILE,buffer,path);
return buffer;
}
if(COUNT_FILE==-1)return 0;
dword buffer = malloc(304*COUNT_FILE+72);
file_read_dir(2,COUNT_FILE+2,buffer,path);
return buffer;
}
dword get_dir_info(char *path)
{
return _get_dir_info(get_full_path(path));
}
dword get_dir_position(dword a,dword i)
{
return i*344+32+a;
}
char *get_file_name(void *args)
{
return args+40;
}
char BUF_HEADER[5]={0};
dword read(char *path)
{
dword *adr = &BUF_HEADER;
path = get_full_path(path);
file_read_binary(path,0,4,adr);
if(*adr=='KCPK') return file_readKPACK(path);
dword ret = file_read(path);
//FS_LENGHT = size_long_file;
asm volatile(""::"c"((long)size_long_file));
return ret;
}
dword quantity_dir = 0,quantity_file = 0;
long long fs_size_global = 0;
long long LOOP_SIZE(char *path)
{
dword tmp_len = file_size(path);
if(ret_struct.p00&0b10000)
{
++quantity_dir;
dword tmp_buf = get_dir_info(path);
if(COUNT_FILE<1) return 0;
char *new_path_file = malloc(4096);
int tmp_count = COUNT_FILE;
int i = 0;
fs_size_global = 0;
while(i<tmp_count)
{
sprintf(new_path_file,"%s/%s",path,304*i+tmp_buf+72);
fs_size_global += LOOP_SIZE(new_path_file);
++i;
}
free(tmp_buf);
free(new_path_file);
return fs_size_global;
}
++quantity_file;
return tmp_len;
}
dword get_size(char *path)
{
quantity_dir = 0;
quantity_file = 0;
long long size = LOOP_SIZE(get_full_path(path));
if(quantity_dir>0)--quantity_dir;
asm volatile(""::"c"(quantity_dir),"d"(quantity_file));
return (dword)size;
}
/*
char set_attributes_loop(char *path,dword strucs)
{
if(get_bdvk(path))return 0;
dword tmp = (ret_struct.p00^strucs)&0b111;
ret_struct.p00=(tmp^ret_struct.p00)^0xFFFFFFFF;
if(ret_struct.p00&0b10000)
{
dword tmp_buf = _get_dir_info(path);
if(!COUNT_FILE) goto END;
char *new_path_file = malloc(4096);
int tmp_count = COUNT_FILE;
int i = 0;
char *position = tmp_buf+72;
while(i<tmp_count)
{
sprintf(new_path_file,"%s/%s",path,position);
position+=304;
if(!set_attributes_loop(new_path_file,strucs))
{
free(tmp_buf);
free(new_path_file);
return 0;
}
++i;
}
free(new_path_file);
END:
free(tmp_buf);
}
if(set_bdvk(path,&ret_struct))return 0;
return 1;
}
char set_attributes(char *path,dword strucs,char cmd)
{
if(cmd)return set_attributes_loop(get_full_path(path),strucs);
}
*/
char remove_loop(char *path)
{
if(get_bdvk(path))return 0;
if(ret_struct.p00&0b10000)
{
dword tmp_buf = _get_dir_info(path);
if(!COUNT_FILE) goto END;
char *new_path_file = malloc(4096);
int tmp_count = COUNT_FILE;
int i = 0;
char *position = tmp_buf+72;
while(i<tmp_count)
{
sprintf(new_path_file,"%s/%s",path,position);
position+=304;
if(!remove_loop(new_path_file))
{
free(tmp_buf);
free(new_path_file);
return 0;
}
++i;
}
free(new_path_file);
END:
free(tmp_buf);
}
if(file_delete(path))return 0;
return 1;
}
char remove(char *path)
{
return remove_loop(get_full_path(path));
}
int make_dir(char *path)
{
return file_mkdir(get_full_path(path));
}
char copy_loop(char *path1,char *path2)
{
if(get_bdvk(path1))return 0;
if(ret_struct.p00&0b10000)
{
file_mkdir(path2);
set_bdvk(path2,&ret_struct);
dword tmp_buf = _get_dir_info(path1);
if(!COUNT_FILE) goto END;
char *new_path_file1 = malloc(4096);
char *new_path_file2 = malloc(4096);
int tmp_count = COUNT_FILE;
int i = 0;
dword position = tmp_buf+72;
while(i<tmp_count)
{
sprintf(new_path_file1,"%s/%s",path1,position);
sprintf(new_path_file2,"%s/%s",path2,position);
if(pointer_callback_copy)
{
asm volatile(""::"c"(new_path_file1),"d"(new_path_file2));
pointer_callback_copy();
}
position+=304;
if(!copy_loop(new_path_file1,new_path_file2))
{
free(tmp_buf);
free(new_path_file1);
free(new_path_file2);
return 0;
}
++i;
}
free(new_path_file1);
free(new_path_file2);
END:
free(tmp_buf);
return 1;
}
char r = file_copy(path1,path2);
set_bdvk(path2,&ret_struct);
return r;
}
char copy(char *path1,char *path2)
{
char *tmp = get_full_path(path1);
path1 = malloc(4096);
strcpy(path1,tmp);
char *r=copy_loop(path1,get_full_path(path2));
free(path1);
return r;
}
char move_loop(char *path1,char *path2)
{
if(get_bdvk(path1))return 0;
if(ret_struct.p00&0b10000)
{
file_mkdir(path2);
set_bdvk(path2,&ret_struct);
dword tmp_buf = _get_dir_info(path1);
if(!COUNT_FILE) goto END;
char *new_path_file1 = malloc(4096);
char *new_path_file2 = malloc(4096);
int tmp_count = COUNT_FILE;
int i = 0;
dword position = tmp_buf+72;
while(i<tmp_count)
{
sprintf(new_path_file1,"%s/%s",path1,position);
sprintf(new_path_file2,"%s/%s",path2,position);
if(pointer_callback_move)
{
asm volatile(""::"c"(new_path_file1),"d"(new_path_file2));
pointer_callback_copy();
}
position+=304;
if(!move_loop(new_path_file1,new_path_file2))
{
free(tmp_buf);
free(new_path_file1);
free(new_path_file2);
return 0;
}
++i;
}
free(new_path_file1);
free(new_path_file2);
END:
free(tmp_buf);
if(file_delete(path1)) return 0;
return 1;
}
char r = 0;
if(file_copy(path1,path2)) if(!file_delete(path1))r=1;
if(r)set_bdvk(path2,&ret_struct);
return r;
}
char move(char *path1,char *path2)
{
char *tmp = get_full_path(path1);
path1 = malloc(4096);
strcpy(path1,tmp);
char *r=move_loop(path1,get_full_path(path2));
free(path1);
return r;
}
char write(char *path,void *data,dword size)
{
if(file_write(get_full_path(path),data,size))return 0;
return 1;
}
dword execute(char *path,char *arg)
{
return file_run(get_full_path(path),arg);
}
dword open(char *path)
{
return file_run("/sys/@open",get_full_path(path));
}
char rename(char *path,char *new_name)
{
if(!strcmp(path,new_name))return 0;
char *pos = path;
char *pos1 = &TMP1;
char *tmp = 0;
while(*pos)
{
*pos1=*pos;
if(*pos=='/')
{
if(*++pos)tmp = pos1;
}
else ++pos;
++pos1;
}
if(tmp)
{
while(*new_name)*++tmp = *new_name++;
*++tmp = 0;
return move(path,&TMP1);
}
return move(path,new_name);
}
char callback_copy(char *path1,char *path2,dword func)
{
pointer_callback_copy = func;
return copy(path1,path2);
}
char callback_move(char *path1,char *path2,dword func)
{
pointer_callback_move = func;
return move(path1,path2);
}
char callback_remove(char *path,dword func)
{
pointer_callback_remove = func;
return remove(path);
}
char *version = "Ver. 1.3, Author:Pavel Yakovlev, http://vk.com/pavelyakov39";
EXPORT_
export(execute)
export(open)
export(read)
export(write)
export(copy)
export(move)
export(remove)
export(rename)
export(get_size)
//export(set_attributes)
export(get_entries_count)
export(get_dir_info)
export(get_dir_position)
export(get_file_name)
export(get_full_path)
export(make_dir)
export(callback_copy)
export(callback_move)
export(callback_remove)
export(pointer_callback_copy)
export(pointer_callback_move)
export(pointer_callback_remove)
export(version)
_EXPORT