Subversion Repositories Kolibri OS

Rev

Rev 9636 | Rev 9689 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
5598 pavelyakov 1
#ifndef INCLUDE_FILESYSTEM_H
2
#define INCLUDE_FILESYSTEM_H
7219 leency 3
#print "[include ]\n"
5598 pavelyakov 4
 
5640 pavelyakov 5
#ifndef INCLUDE_DATE_H
6
#include "../lib/date.h"
5598 pavelyakov 7
#endif
8
 
7878 leency 9
#ifndef INCLUDE_COLLECTION_H
10
#include "../lib/collection.h"
11
#endif
12
 
9516 leency 13
#define PATHLEN 4096
14
 
7369 leency 15
//===================================================//
16
//                                                   //
17
//              Basic System Functions               //
18
//                                                   //
19
//===================================================//
20
 
8750 leency 21
:struct F70{
3067 leency 22
	dword	func;
23
	dword	param1;
24
	dword	param2;
25
	dword	param3;
26
	dword	param4;
27
	char	rezerv;
28
	dword	name;
8750 leency 29
} f70;
3067 leency 30
 
5487 leency 31
:struct BDVK {
9422 leency 32
	dword   readonly:1, hidden:1, system:1, volume_label:1, isfolder:1, notarchived:1, :0;
33
	byte    type_name, rez1, rez2, selected; //name encoding
9636 leency 34
	time    timecreate; //+8
9422 leency 35
	date    datecreate;
9636 leency 36
	time    timelastaccess;
9422 leency 37
	date    datelastaccess;
9636 leency 38
	time    timelastedit;
9422 leency 39
	date    datelastedit;
40
	dword   sizelo;
41
	dword   sizehi;
42
	char    name[520];
3067 leency 43
};
8949 leency 44
#define ATR_READONLY 1
45
#define ATR_HIDDEN 2
46
#define ATR_SYSTEM 4
47
#define ATR_VOL_LABEL 8
8944 leency 48
#define ATR_FOLDER 0x10
8949 leency 49
#define ATR_NONARH 0x20
3067 leency 50
 
51
 
3440 leency 52
:dword GetFileInfo(dword file_path, bdvk_struct)
53
{
8750 leency 54
    f70.func = 5;
55
    f70.param1 =
56
    f70.param2 =
57
    f70.param3 = 0;
58
    f70.param4 = bdvk_struct;
59
    f70.rezerv = 0;
60
    f70.name = file_path;
3440 leency 61
    $mov eax,70
8750 leency 62
    $mov ebx,#f70.func
3444 leency 63
    $int 0x40
3440 leency 64
}
65
 
9277 leency 66
:dword GetVolumeLabel(dword _path)
67
{
68
	BDVK bdvk;
69
	//if (ESBYTE[_path+1]=='k') || (ESBYTE[_path+2]=='y') return NULL;
70
	f70.func = 5;
71
	f70.param1 = 0;
72
	f70.param2 = 1;
73
	f70.param3 = 1;
74
	f70.param4 = #bdvk;
75
	f70.rezerv = 0;
76
	f70.name = _path;
77
	$mov eax,70
78
	$mov ebx,#f70.func
79
	$int 0x40
80
	return #bdvk.name;
81
}
82
 
5554 punk_joker 83
:dword SetFileInfo(dword file_path, bdvk_struct)
84
{
8750 leency 85
    f70.func = 6;
86
    f70.param1 =
87
    f70.param2 =
88
    f70.param3 = 0;
89
    f70.param4 = bdvk_struct;
90
    f70.rezerv = 0;
91
    f70.name = file_path;
5554 punk_joker 92
    $mov eax,70
8750 leency 93
    $mov ebx,#f70.func
5554 punk_joker 94
    $int 0x40
95
}
96
 
5472 leency 97
:signed int RunProgram(dword run_path, run_param)
3067 leency 98
{
8750 leency 99
    f70.func = 7;
100
    f70.param1 =
101
    f70.param3 =
102
    f70.param4 =
103
    f70.rezerv = 0;
104
    f70.param2 = run_param;
105
    f70.name = run_path;
3067 leency 106
    $mov eax,70
8750 leency 107
    $mov ebx,#f70.func
3067 leency 108
    $int 0x40
109
}
110
 
111
:int CreateDir(dword new_folder_path)
112
{
8750 leency 113
	f70.func = 9;
114
	f70.param1 =
115
	f70.param2 =
116
	f70.param3 =
117
	f70.param4 =
118
	f70.rezerv = 0;
119
	f70.name = new_folder_path;
3067 leency 120
	$mov eax,70
8750 leency 121
	$mov ebx,#f70.func
3067 leency 122
	$int 0x40
123
}
124
 
125
:int DeleteFile(dword del_file_path)
126
{
8750 leency 127
	f70.func = 8;
128
	f70.param1 =
129
	f70.param2 =
130
	f70.param3 =
131
	f70.param4 =
132
	f70.rezerv = 0;
133
	f70.name = del_file_path;
3067 leency 134
	$mov eax,70
8750 leency 135
	$mov ebx,#f70.func
3067 leency 136
	$int 0x40
137
}
138
 
7210 leency 139
:int ReadFile(dword offset, data_size, buffer, file_path)
3067 leency 140
{
8750 leency 141
	f70.func = 0;
142
	f70.param1 = offset;
143
	f70.param2 = 0;
144
	f70.param3 = data_size;
145
	f70.param4 = buffer;
146
	f70.rezerv = 0;
147
	f70.name = file_path;
3067 leency 148
	$mov eax,70
8750 leency 149
	$mov ebx,#f70.func
3067 leency 150
	$int 0x40
151
}
152
 
7227 leency 153
:int CreateFile(dword data_size, buffer, file_path)
3067 leency 154
{
8750 leency 155
	f70.func = 2;
156
	f70.param1 = 0;
157
	f70.param2 = 0;
158
	f70.param3 = data_size;
159
	f70.param4 = buffer;
160
	f70.rezerv = 0;
161
	f70.name = file_path;
3067 leency 162
	$mov eax,70
8750 leency 163
	$mov ebx,#f70.func
3067 leency 164
	$int 0x40
5542 leency 165
}
3067 leency 166
 
5640 pavelyakov 167
  ////////////////////////////////////////
168
 //     WriteInFileThatAlredyExists    //
169
////////////////////////////////////////
7227 leency 170
:int WriteFile(dword offset, data_size, buffer, file_path)
5542 leency 171
{
8750 leency 172
	f70.func = 3;
173
	f70.param1 = offset;
174
	f70.param2 = 0;
175
	f70.param3 = data_size;
176
	f70.param4 = buffer;
177
	f70.rezerv = 0;
178
	f70.name = file_path;
5542 leency 179
	$mov eax,70
8750 leency 180
	$mov ebx,#f70.func
5542 leency 181
	$int 0x40
7210 leency 182
}
5542 leency 183
 
8750 leency 184
:int RenameMove(dword path_to, path_from)
185
{
186
	f70.func = 10;
187
	f70.param1 =
188
	f70.param2 =
189
	f70.param3 = 0;
190
	f70.param4 = path_to;
191
	f70.rezerv = 0;
192
	f70.name = path_from;
193
	$mov eax,70
194
	$mov ebx,#f70.func
195
	$int 0x40
196
}
197
 
3067 leency 198
:int ReadDir(dword file_count, read_buffer, dir_path)
3363 leency 199
{
8750 leency 200
	f70.func = 1;
201
	f70.param1 =
202
	f70.param2 =
203
	f70.rezerv = 0;
204
	f70.param3 = file_count;
205
	f70.param4 = read_buffer;
206
	f70.name = dir_path;
3067 leency 207
	$mov eax,70
8750 leency 208
	$mov ebx,#f70.func
3067 leency 209
	$int 0x40
210
}
211
 
7533 leency 212
//ECX - buf pointer
7422 leency 213
inline fastcall void SetCurDir( ECX)
214
{
215
	EAX=30;
216
	EBX=1;
217
	$int 0x40
218
}
219
 
7533 leency 220
//ECX - buf pointer
221
//EDX - buf size
222
inline fastcall void GetCurDir( ECX, EDX)
223
{
224
	EAX=30;
225
	EBX=2;
226
	$int 0x40
227
}
228
 
8949 leency 229
:void read_file(dword path1, buf, size)
8383 leency 230
{
231
	EAX = 68;
232
	EBX = 27;
233
	ECX = path1;
234
	$int 0x40;
235
	ESDWORD[size] = EDX;
236
	ESDWORD[buf] = EAX;
237
}
238
 
7369 leency 239
//===================================================//
240
//                                                   //
241
//                        Misc                       //
242
//                                                   //
243
//===================================================//
244
 
7202 leency 245
:bool dir_exists(dword fpath)
3440 leency 246
{
7219 leency 247
	char buf[32];
248
	if (!ReadDir(0, #buf, fpath)) return true;
249
	return false;
250
}
251
 
8392 leency 252
:dword get_file_size(dword _path)
253
{
254
	BDVK bdvk;
255
	if (GetFileInfo(_path, #bdvk)!=0) return 0;
256
	else return bdvk.sizelo;
257
}
258
 
7219 leency 259
/*
260
// This implementation of dir_exists() is faster than
261
// previous but here virtual folders like
262
// '/' and '/tmp' are not recognised as FOLDERS
263
// by GetFileInfo() => BDVK.isfolder attribute :(
264
 
265
:bool dir_exists(dword fpath)
266
{
3440 leency 267
	BDVK fpath_atr;
6930 leency 268
	if (GetFileInfo(fpath, #fpath_atr) != 0) return false;
5487 leency 269
	return fpath_atr.isfolder;
3440 leency 270
}
7219 leency 271
*/
272
 
7202 leency 273
:bool file_exists(dword fpath)
6251 leency 274
{
275
	BDVK ReadFile_atr;
276
	if (! GetFileInfo(fpath, #ReadFile_atr)) return true;
277
	return false;
278
}
3877 leency 279
 
3444 leency 280
enum
3363 leency 281
{
3444 leency 282
	DIRS_ALL,
283
	DIRS_NOROOT,
284
	DIRS_ONLYREAL
285
};
286
:int GetDir(dword dir_buf, file_count, path, doptions)
7878 leency 287
dword buf, fcount, error;
288
char readbuf[32];
3444 leency 289
{
7878 leency 290
	error = ReadDir(0, #readbuf, path);
3363 leency 291
	if (!error)
292
	{
7878 leency 293
		fcount = ESDWORD[#readbuf+8];
294
		buf = malloc(fcount+1*304+32);
3363 leency 295
		ReadDir(fcount, buf, path);
3440 leency 296
		//fcount=EBX;
3444 leency 297
 
298
		if (doptions == DIRS_ONLYREAL)
299
		{
300
			if (!strcmp(".",buf+72)) {fcount--; memmov(buf,buf+304,fcount*304);}
301
			if (!strcmp("..",buf+72)) {fcount--; memmov(buf,buf+304,fcount*304);}
302
		}
303
		if (doptions == DIRS_NOROOT)
304
		{
305
			if (!strcmp(".",buf+72)) {fcount--; memmov(buf,buf+304,fcount*304);}
306
		}
307
 
3363 leency 308
		ESDWORD[dir_buf] = buf;
309
		ESDWORD[file_count] = fcount;
310
	}
3440 leency 311
	else
3067 leency 312
	{
7878 leency 313
		ESDWORD[dir_buf] = 0;
3440 leency 314
		ESDWORD[file_count] = 0;
3067 leency 315
	}
3440 leency 316
	return error;
3067 leency 317
}
318
 
3432 leency 319
:dword abspath(dword relative_path) //GetAbsolutePathFromRelative()
320
{
9516 leency 321
	char absolute_path[PATHLEN];
4137 leency 322
	if (ESBYTE[relative_path]=='/')
323
	{
324
		strcpy(#absolute_path, relative_path);
325
	}
326
	else
327
	{
6735 leency 328
		strcpy(#absolute_path, I_Path);
4137 leency 329
		absolute_path[strrchr(#absolute_path, '/')] = '\0';
330
		strcat(#absolute_path, relative_path);
331
	}
3432 leency 332
	return #absolute_path;
333
}
5483 leency 334
 
7202 leency 335
:dword GetIni(dword ini_path, ini_name) //search it on /kolibrios/ then on /sys/
7197 leency 336
{
7202 leency 337
	strcpy(ini_path, "/kolibrios/settings/");
338
	strcat(ini_path, ini_name);
339
	if (!file_exists(ini_path)) {
7213 leency 340
		strcpy(ini_path, "/sys/SETTINGS/");
7202 leency 341
		strcat(ini_path, ini_name);
7197 leency 342
	}
7202 leency 343
	return ini_path;
7197 leency 344
}
345
 
7369 leency 346
:dword notify(dword notify_param)
347
{
348
	return RunProgram("/sys/@notify", notify_param);
349
}
350
 
351
:void die(dword _last_msg)
352
{
353
	notify(_last_msg);
354
	ExitProcess();
355
}
356
 
8946 leency 357
:bool file_name_is_8_3(dword name)
358
{
359
	strlen(name);
360
	if (EAX>12) return false;
361
	$push eax
362
	strrchr(name, '.');
363
	$pop ebx
364
 
365
	//EAX = dot pos
366
	//EBX = name length
367
 
368
	if (EAX) {
369
		if (EBX-EAX>3) return false;
370
	} else {
371
		if (EBX>8) return false;
372
	}
373
	return true;
374
}
375
 
7369 leency 376
//===================================================//
377
//                                                   //
378
//                   Convert Size                    //
379
//                                                   //
380
//===================================================//
381
 
5591 pavelyakov 382
:byte ConvertSize_size_prefix[8];
5576 pavelyakov 383
:dword ConvertSize(dword bytes)
5483 leency 384
{
5591 pavelyakov 385
  byte size_nm[4];
9301 leency 386
  if (bytes>=1073741824) strlcpy(#size_nm, "GB",2);
387
  else if (bytes>=1048576) strlcpy(#size_nm, "MB",2);
388
  else if (bytes>=1024) strlcpy(#size_nm, "KB",2);
9003 leency 389
  else strlcpy(#size_nm, "B ",2);
6989 leency 390
  while (bytes>1023) bytes >>= 10;
5591 pavelyakov 391
  sprintf(#ConvertSize_size_prefix,"%d %s",bytes,#size_nm);
392
  return #ConvertSize_size_prefix;
5493 leency 393
}
7219 leency 394
 
6988 leency 395
:dword ConvertSize64(dword bytes_lo, bytes_hi)
396
{
397
  if (bytes_hi > 0) {
9685 leency 398
		if (bytes_lo>=1073741824) bytes_lo >>= 30; else bytes_lo = 0;
399
		sprintf(#ConvertSize_size_prefix,"%d GB",bytes_hi<<2 + bytes_lo);
400
		return #ConvertSize_size_prefix;
6988 leency 401
  }
402
  else return ConvertSize(bytes_lo);
403
}
7219 leency 404
 
7369 leency 405
:unsigned char size[25];
5493 leency 406
:dword ConvertSizeToKb(unsigned int bytes)
407
{
408
	dword kb_line;
409
 
6568 leency 410
	if (bytes >= 1024)
411
	{
412
		kb_line = itoa(bytes / 1024);
413
		strcpy(#size, kb_line);
9301 leency 414
		strcat(#size, " KB");
6568 leency 415
	}
416
	else {
417
		kb_line = itoa(bytes);
418
		strcpy(#size, kb_line);
9003 leency 419
		strcat(#size, " B");
6568 leency 420
	}
5493 leency 421
 
422
	return #size;
5598 pavelyakov 423
}
7210 leency 424
 
7369 leency 425
//===================================================//
426
//                                                   //
427
//                      Copy                         //
428
//                                                   //
429
//===================================================//
430
 
7210 leency 431
:int CopyFileAtOnce(dword size, copyFrom, copyTo)
432
dword cbuf;
433
int error;
434
{
435
	cbuf = malloc(size);
436
	if (error = ReadFile(0, size, cbuf, copyFrom))
437
	{
438
		debugln("Error: CopyFileAtOnce->ReadFile");
439
	}
440
	else
441
	{
7227 leency 442
		if (error = CreateFile(size, cbuf, copyTo)) debugln("Error: CopyFileAtOnce->CreateFile");
7210 leency 443
	}
444
	free(cbuf);
445
	return error;
446
}
447
 
448
:int CopyFileByBlocks(dword size, copyFrom, copyTo)
449
dword cbuf;
450
int error=-1;
451
dword offpos=0;
7227 leency 452
int block_size=1024*1024*4; //copy by 4 MiB
7210 leency 453
{
7227 leency 454
	if (GetFreeRAM()>1024*78) {
455
		//Set block size 32 MiB
456
		block_size <<= 3;
457
	}
7210 leency 458
	cbuf = malloc(block_size);
7227 leency 459
	if (error = CreateFile(0, 0, copyTo))
460
	{
461
		debugln("Error: CopyFileByBlocks->CreateFile");
462
		size = -1;
463
	}
7210 leency 464
	while(offpos < size)
465
	{
466
		error = ReadFile(offpos, block_size, cbuf, copyFrom);
467
		if (error = 6) { //File ended before last byte was readed
468
			block_size = EBX;
7227 leency 469
			if (block_size+offpos>=size) error=0;
7210 leency 470
		}
471
		else
7227 leency 472
			if (error!=0) {
473
				debugln("Error: CopyFileByBlocks->ReadFile");
474
				break;
475
			}
476
		if (error = WriteFile(offpos, block_size, cbuf, copyTo)) {
477
			debugln("Error: CopyFileByBlocks->WriteFile");
478
			break;
479
		}
7210 leency 480
		offpos += block_size;
481
	}
482
	free(cbuf);
483
	return error;
484
}
485
 
7369 leency 486
//===================================================//
487
//                                                   //
488
//                  Directory Size                   //
489
//                                                   //
490
//===================================================//
7210 leency 491
 
7878 leency 492
:struct DIR_SIZE
7369 leency 493
{
494
	BDVK dir_info;
495
	dword folders;
496
	dword files;
497
	dword bytes;
9685 leency 498
	dword bytes_high;
7878 leency 499
	dword get();
500
	dword calculate_loop();
501
};
7369 leency 502
 
7878 leency 503
:dword DIR_SIZE::get(dword way1)
7369 leency 504
{
9685 leency 505
	folders = files = bytes = bytes_high = 0;
7878 leency 506
	if (!way1) return 0;
507
	calculate_loop(way1);
7369 leency 508
}
509
 
7878 leency 510
:dword DIR_SIZE::calculate_loop(dword way)
7369 leency 511
{
512
	dword dirbuf, fcount, i, filename;
513
	dword cur_file;
7878 leency 514
	if (!way) return 0;
7369 leency 515
	if (dir_exists(way))
516
	{
9516 leency 517
		cur_file = malloc(PATHLEN);
7369 leency 518
		// In the process of recursive descent, memory must be allocated dynamically,
519
		// because the static memory -> was a bug !!! But unfortunately pass away to sacrifice speed.
520
		GetDir(#dirbuf, #fcount, way, DIRS_ONLYREAL);
521
		for (i=0; i
522
		{
523
			filename = i*304+dirbuf+72;
524
			sprintf(cur_file,"%s/%s",way,filename);
525
 
8944 leency 526
			if (ESDWORD[filename-40] & ATR_FOLDER )
7369 leency 527
			{
528
				folders++;
529
				calculate_loop(cur_file);
530
			}
531
			else
532
			{
533
				GetFileInfo(cur_file, #dir_info);
534
				bytes += dir_info.sizelo;
9685 leency 535
				bytes_high += dir_info.sizehi;
7369 leency 536
				files++;
537
			}
538
		}
539
		free(cur_file);
540
		free(dirbuf);
541
	}
7878 leency 542
	return files;
7369 leency 543
}
544
 
7878 leency 545
 
5598 pavelyakov 546
#endif