Subversion Repositories Kolibri OS

Rev

Rev 9689 | 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
 
9689 leency 259
/* This implementation of dir_exists() is faster than
260
   previous but here virtual folders like
261
   '/' and '/tmp' are not recognised as FOLDERS
262
   by GetFileInfo() => BDVK.isfolder attribute :( */
263
bool real_dir_exists(dword fpath)
7219 leency 264
{
3440 leency 265
	BDVK fpath_atr;
6930 leency 266
	if (GetFileInfo(fpath, #fpath_atr) != 0) return false;
5487 leency 267
	return fpath_atr.isfolder;
3440 leency 268
}
7219 leency 269
 
7202 leency 270
:bool file_exists(dword fpath)
6251 leency 271
{
272
	BDVK ReadFile_atr;
273
	if (! GetFileInfo(fpath, #ReadFile_atr)) return true;
274
	return false;
275
}
3877 leency 276
 
3444 leency 277
enum
3363 leency 278
{
3444 leency 279
	DIRS_ALL,
280
	DIRS_NOROOT,
281
	DIRS_ONLYREAL
282
};
283
:int GetDir(dword dir_buf, file_count, path, doptions)
7878 leency 284
dword buf, fcount, error;
285
char readbuf[32];
3444 leency 286
{
7878 leency 287
	error = ReadDir(0, #readbuf, path);
3363 leency 288
	if (!error)
289
	{
7878 leency 290
		fcount = ESDWORD[#readbuf+8];
291
		buf = malloc(fcount+1*304+32);
3363 leency 292
		ReadDir(fcount, buf, path);
3440 leency 293
		//fcount=EBX;
3444 leency 294
 
295
		if (doptions == DIRS_ONLYREAL)
296
		{
297
			if (!strcmp(".",buf+72)) {fcount--; memmov(buf,buf+304,fcount*304);}
298
			if (!strcmp("..",buf+72)) {fcount--; memmov(buf,buf+304,fcount*304);}
299
		}
300
		if (doptions == DIRS_NOROOT)
301
		{
302
			if (!strcmp(".",buf+72)) {fcount--; memmov(buf,buf+304,fcount*304);}
303
		}
304
 
3363 leency 305
		ESDWORD[dir_buf] = buf;
306
		ESDWORD[file_count] = fcount;
307
	}
3440 leency 308
	else
3067 leency 309
	{
7878 leency 310
		ESDWORD[dir_buf] = 0;
3440 leency 311
		ESDWORD[file_count] = 0;
3067 leency 312
	}
3440 leency 313
	return error;
3067 leency 314
}
315
 
3432 leency 316
:dword abspath(dword relative_path) //GetAbsolutePathFromRelative()
317
{
9516 leency 318
	char absolute_path[PATHLEN];
4137 leency 319
	if (ESBYTE[relative_path]=='/')
320
	{
321
		strcpy(#absolute_path, relative_path);
322
	}
323
	else
324
	{
6735 leency 325
		strcpy(#absolute_path, I_Path);
4137 leency 326
		absolute_path[strrchr(#absolute_path, '/')] = '\0';
327
		strcat(#absolute_path, relative_path);
328
	}
3432 leency 329
	return #absolute_path;
330
}
5483 leency 331
 
7202 leency 332
:dword GetIni(dword ini_path, ini_name) //search it on /kolibrios/ then on /sys/
7197 leency 333
{
7202 leency 334
	strcpy(ini_path, "/kolibrios/settings/");
335
	strcat(ini_path, ini_name);
336
	if (!file_exists(ini_path)) {
7213 leency 337
		strcpy(ini_path, "/sys/SETTINGS/");
7202 leency 338
		strcat(ini_path, ini_name);
7197 leency 339
	}
7202 leency 340
	return ini_path;
7197 leency 341
}
342
 
7369 leency 343
:dword notify(dword notify_param)
344
{
345
	return RunProgram("/sys/@notify", notify_param);
346
}
347
 
348
:void die(dword _last_msg)
349
{
350
	notify(_last_msg);
351
	ExitProcess();
352
}
353
 
8946 leency 354
:bool file_name_is_8_3(dword name)
355
{
356
	strlen(name);
357
	if (EAX>12) return false;
358
	$push eax
359
	strrchr(name, '.');
360
	$pop ebx
361
 
362
	//EAX = dot pos
363
	//EBX = name length
364
 
365
	if (EAX) {
366
		if (EBX-EAX>3) return false;
367
	} else {
368
		if (EBX>8) return false;
369
	}
370
	return true;
371
}
372
 
7369 leency 373
//===================================================//
374
//                                                   //
375
//                   Convert Size                    //
376
//                                                   //
377
//===================================================//
378
 
5591 pavelyakov 379
:byte ConvertSize_size_prefix[8];
5576 pavelyakov 380
:dword ConvertSize(dword bytes)
5483 leency 381
{
5591 pavelyakov 382
  byte size_nm[4];
9301 leency 383
  if (bytes>=1073741824) strlcpy(#size_nm, "GB",2);
384
  else if (bytes>=1048576) strlcpy(#size_nm, "MB",2);
385
  else if (bytes>=1024) strlcpy(#size_nm, "KB",2);
9003 leency 386
  else strlcpy(#size_nm, "B ",2);
6989 leency 387
  while (bytes>1023) bytes >>= 10;
5591 pavelyakov 388
  sprintf(#ConvertSize_size_prefix,"%d %s",bytes,#size_nm);
389
  return #ConvertSize_size_prefix;
5493 leency 390
}
7219 leency 391
 
6988 leency 392
:dword ConvertSize64(dword bytes_lo, bytes_hi)
393
{
394
  if (bytes_hi > 0) {
9685 leency 395
		if (bytes_lo>=1073741824) bytes_lo >>= 30; else bytes_lo = 0;
396
		sprintf(#ConvertSize_size_prefix,"%d GB",bytes_hi<<2 + bytes_lo);
397
		return #ConvertSize_size_prefix;
6988 leency 398
  }
399
  else return ConvertSize(bytes_lo);
400
}
7219 leency 401
 
7369 leency 402
:unsigned char size[25];
5493 leency 403
:dword ConvertSizeToKb(unsigned int bytes)
404
{
405
	dword kb_line;
406
 
6568 leency 407
	if (bytes >= 1024)
408
	{
409
		kb_line = itoa(bytes / 1024);
410
		strcpy(#size, kb_line);
9301 leency 411
		strcat(#size, " KB");
6568 leency 412
	}
413
	else {
414
		kb_line = itoa(bytes);
415
		strcpy(#size, kb_line);
9003 leency 416
		strcat(#size, " B");
6568 leency 417
	}
5493 leency 418
 
419
	return #size;
5598 pavelyakov 420
}
7210 leency 421
 
7369 leency 422
//===================================================//
423
//                                                   //
424
//                      Copy                         //
425
//                                                   //
426
//===================================================//
427
 
7210 leency 428
:int CopyFileAtOnce(dword size, copyFrom, copyTo)
429
dword cbuf;
430
int error;
431
{
432
	cbuf = malloc(size);
433
	if (error = ReadFile(0, size, cbuf, copyFrom))
434
	{
435
		debugln("Error: CopyFileAtOnce->ReadFile");
436
	}
437
	else
438
	{
7227 leency 439
		if (error = CreateFile(size, cbuf, copyTo)) debugln("Error: CopyFileAtOnce->CreateFile");
7210 leency 440
	}
441
	free(cbuf);
442
	return error;
443
}
444
 
445
:int CopyFileByBlocks(dword size, copyFrom, copyTo)
446
dword cbuf;
447
int error=-1;
448
dword offpos=0;
7227 leency 449
int block_size=1024*1024*4; //copy by 4 MiB
7210 leency 450
{
7227 leency 451
	if (GetFreeRAM()>1024*78) {
452
		//Set block size 32 MiB
453
		block_size <<= 3;
454
	}
7210 leency 455
	cbuf = malloc(block_size);
7227 leency 456
	if (error = CreateFile(0, 0, copyTo))
457
	{
458
		debugln("Error: CopyFileByBlocks->CreateFile");
459
		size = -1;
460
	}
7210 leency 461
	while(offpos < size)
462
	{
463
		error = ReadFile(offpos, block_size, cbuf, copyFrom);
464
		if (error = 6) { //File ended before last byte was readed
465
			block_size = EBX;
7227 leency 466
			if (block_size+offpos>=size) error=0;
7210 leency 467
		}
468
		else
7227 leency 469
			if (error!=0) {
470
				debugln("Error: CopyFileByBlocks->ReadFile");
471
				break;
472
			}
473
		if (error = WriteFile(offpos, block_size, cbuf, copyTo)) {
474
			debugln("Error: CopyFileByBlocks->WriteFile");
475
			break;
476
		}
7210 leency 477
		offpos += block_size;
478
	}
479
	free(cbuf);
480
	return error;
481
}
482
 
7369 leency 483
//===================================================//
484
//                                                   //
485
//                  Directory Size                   //
486
//                                                   //
487
//===================================================//
7210 leency 488
 
7878 leency 489
:struct DIR_SIZE
7369 leency 490
{
491
	BDVK dir_info;
492
	dword folders;
493
	dword files;
9693 leency 494
	dword sizelo;
495
	dword sizehi;
7878 leency 496
	dword get();
497
	dword calculate_loop();
498
};
7369 leency 499
 
7878 leency 500
:dword DIR_SIZE::get(dword way1)
7369 leency 501
{
9693 leency 502
	folders = files = sizelo = sizehi = 0;
7878 leency 503
	if (!way1) return 0;
504
	calculate_loop(way1);
7369 leency 505
}
506
 
7878 leency 507
:dword DIR_SIZE::calculate_loop(dword way)
7369 leency 508
{
509
	dword dirbuf, fcount, i, filename;
510
	dword cur_file;
7878 leency 511
	if (!way) return 0;
7369 leency 512
	if (dir_exists(way))
513
	{
9516 leency 514
		cur_file = malloc(PATHLEN);
7369 leency 515
		// In the process of recursive descent, memory must be allocated dynamically,
516
		// because the static memory -> was a bug !!! But unfortunately pass away to sacrifice speed.
517
		GetDir(#dirbuf, #fcount, way, DIRS_ONLYREAL);
518
		for (i=0; i
519
		{
520
			filename = i*304+dirbuf+72;
521
			sprintf(cur_file,"%s/%s",way,filename);
522
 
8944 leency 523
			if (ESDWORD[filename-40] & ATR_FOLDER )
7369 leency 524
			{
525
				folders++;
526
				calculate_loop(cur_file);
527
			}
528
			else
529
			{
530
				GetFileInfo(cur_file, #dir_info);
9693 leency 531
				sizelo += dir_info.sizelo;
532
				sizehi += dir_info.sizehi;
7369 leency 533
				files++;
534
			}
535
		}
536
		free(cur_file);
537
		free(dirbuf);
538
	}
7878 leency 539
	return files;
7369 leency 540
}
541
 
7878 leency 542
 
5598 pavelyakov 543
#endif