Subversion Repositories Kolibri OS

Rev

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