Subversion Repositories Kolibri OS

Rev

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