/*
	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