Subversion Repositories Kolibri OS

Rev

Rev 8383 | Rev 8750 | Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | Download | RSS feed

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