Choco OS  V.0.16.9.0
Join to the chocolate world
oc_vfs.c
Go to the documentation of this file.
1 
27 #include <oc_vfs.h>
28 #include <oc_filesystem_list.h>
29 #include <oc_list.h>
30 #include <oc_string.h>
31 #include <oc_processman.h>
32 #include <oc_ifnot.h>
33 
34 #define IsDirSign(Char) ( (Char) == '/' || (Char) == '\\' )
35 #define IsAbsolutePath(Path) ( IsDirSign((Path)[0]) )
36 
42 #define _________________________________________TYPES_SECTION______________________________________________________________________________
43 
44 typedef struct _MountedEntry_t
45 {
46  oC_FileSystem_t FileSystem;
48  char * MountedPoint;
49 } * MountedEntry_t;
50 
51 typedef struct _OpenedFileEntry_t
52 {
53  union
54  {
55  oC_File_t File;
56  oC_Dir_t Dir;
57  };
58 
59  MountedEntry_t MountedEntry;
60  oC_Process_t Process;
61 } * OpenedFileEntry_t;
62 
63 typedef enum
64 {
65  Cd_NewDir = 0,
66  Cd_NoMove = 1,
67  Cd_DirUp = 2
68 } Cd_t;
69 
70 #undef _________________________________________TYPES_SECTION______________________________________________________________________________
71 
77 #define _________________________________________LOCAL_PROTOTYPES_SECTION___________________________________________________________________
78 
79 static MountedEntry_t GetMountedFileSystem( const char * Path , bool WithParentDirs );
80 static char * GetPwd( void );
81 static uint32_t ConvertRelativeToAbsolute( const char * Relative , char * outAbsolute , uint32_t AbsoluteSize , bool TreatAsDir );
82 static char * ConvertToAbsoluteWithAllocation(const char * Relative , bool TreatAsDir );
83 static bool CheckIfDirExists( const char * Absolute );
84 
85 #undef _________________________________________LOCAL_PROTOTYPES_SECTION___________________________________________________________________
86 
87 
93 #define _________________________________________VARIABLES_SECTION__________________________________________________________________________
94 
95 static bool ModuleEnabledFlag = false;
96 static oC_List(oC_FileSystem_t) FileSystemsList = NULL;
97 static oC_List(MountedEntry_t) MountedEntries = NULL;
98 static oC_List(OpenedFileEntry_t) OpenedFilesEntries = NULL;
99 static const oC_Allocator_t Allocator = {
100  .Name = "Virtual File System"
101 };
102 
103 #undef _________________________________________VARIABLES_SECTION__________________________________________________________________________
104 
105 
111 #define _________________________________________INTERFACE_FUNCTIONS_SECTION________________________________________________________________
112 
113 
114 //==========================================================================================================================================
115 //==========================================================================================================================================
116 oC_ErrorCode_t oC_VirtualFileSystem_TurnOn( void )
117 {
118  oC_ErrorCode_t errorCode = oC_ErrorCode_ImplementError;
119 
120  if(oC_AssignErrorCodeIfFalse(&errorCode , ModuleEnabledFlag == false , oC_ErrorCode_ModuleIsTurnedOn))
121  {
122  FileSystemsList = oC_List_New(&Allocator,AllocationFlags_CanWait1Second);
123  MountedEntries = oC_List_New(&Allocator,AllocationFlags_CanWait1Second);
124  OpenedFilesEntries= oC_List_New(&Allocator,AllocationFlags_CanWait1Second);
125 
126  if(FileSystemsList && MountedEntries && OpenedFilesEntries)
127  {
128  ModuleEnabledFlag = true;
129  errorCode = oC_ErrorCode_None;
130 
131 #define ADD_FILE_SYSTEM(FileSystemName) oC_AssignErrorCode(&errorCode , oC_VirtualFileSystem_AddFileSystem(&FileSystemName));
132 #define DONT_ADD(FileSystemName)
133  CFG_LIST_FILE_SYSTEMS(ADD_FILE_SYSTEM,DONT_ADD)
134 #undef ADD_FILE_SYSTEM
135 #undef DONT_ADD
136 #define MOUNT(FileSystemName,MountPoint) \
137  if(CheckIfDirExists(MountPoint)==false) { oC_AssignErrorCode(&errorCode , oC_VirtualFileSystem_mkdir(MountPoint)); }\
138  oC_AssignErrorCode(&errorCode , oC_VirtualFileSystem_mount(FileSystemName,MountPoint));
139  CFG_LIST_MOUNTED_FILE_SYSTEMS(MOUNT)
140 #undef MOUNT
141  }
142  else
143  {
144  if(oC_List_IsCorrect(FileSystemsList) && !oC_List_Delete(FileSystemsList,AllocationFlags_CanWaitForever))
145  {
146  oC_SaveError("VFS: Cannot delete FileSystemsList" , oC_ErrorCode_ReleaseError);
147  }
148  if(oC_List_IsCorrect(MountedEntries) && !oC_List_Delete(MountedEntries,AllocationFlags_CanWaitForever))
149  {
150  oC_SaveError("VFS: Cannot delete MountedFileSystems" , oC_ErrorCode_ReleaseError);
151  }
152  if(oC_List_IsCorrect(OpenedFilesEntries) && !oC_List_Delete(OpenedFilesEntries,AllocationFlags_CanWaitForever))
153  {
154  oC_SaveError("VFS: Cannot delete OpenedFilesEntries" , oC_ErrorCode_ReleaseError);
155  }
156 
157  errorCode = oC_ErrorCode_AllocationError;
158  }
159  }
160 
161 
162  return errorCode;
163 }
164 
165 //==========================================================================================================================================
166 //==========================================================================================================================================
167 oC_ErrorCode_t oC_VirtualFileSystem_TurnOff( void )
168 {
169  oC_ErrorCode_t errorCode = oC_ErrorCode_ImplementError;
170 
171  if(oC_AssignErrorCodeIfFalse(&errorCode , ModuleEnabledFlag == true , oC_ErrorCode_ModuleNotStartedYet))
172  {
173  ModuleEnabledFlag = false;
174 
175  oC_List_Foreach(MountedEntries,mountedFileSystem)
176  {
177  if(kfree(mountedFileSystem->MountedPoint,AllocationFlags_CanWaitForever)==false)
178  {
179  errorCode = oC_ErrorCode_ReleaseError;
180  }
181 
182  if(kfree(mountedFileSystem,AllocationFlags_CanWaitForever)==false)
183  {
184  errorCode = oC_ErrorCode_ReleaseError;
185  }
186  }
187 
188  oC_List_Foreach(OpenedFilesEntries,openedFileEntry)
189  {
190  if(kfree(openedFileEntry,AllocationFlags_CanWaitForever)==false)
191  {
192  errorCode = oC_ErrorCode_ReleaseError;
193  }
194  }
195 
196  bool fileSystemsListDeleted = oC_List_Delete(FileSystemsList,AllocationFlags_CanWaitForever);
197  bool mountedListDeleted = oC_List_Delete(MountedEntries,AllocationFlags_CanWaitForever);
198  bool openedDeleted = oC_List_Delete(OpenedFilesEntries,AllocationFlags_CanWaitForever);
199  bool allReleased = oC_MemMan_FreeAllMemoryOfAllocator(&Allocator);
200 
201  if(fileSystemsListDeleted && mountedListDeleted && openedDeleted && allReleased)
202  {
203  errorCode = oC_ErrorCode_None;
204  }
205  else
206  {
207  errorCode = oC_ErrorCode_ReleaseError;
208  }
209  }
210 
211  return errorCode;
212 }
213 
214 //==========================================================================================================================================
215 //==========================================================================================================================================
216 oC_ErrorCode_t oC_VirtualFileSystem_AddFileSystem( oC_FileSystem_t FileSystem )
217 {
218  oC_ErrorCode_t errorCode = oC_ErrorCode_ImplementError;
219 
220  if(oC_AssignErrorCodeIfFalse(&errorCode , ModuleEnabledFlag == true , oC_ErrorCode_ModuleNotStartedYet))
221  {
222  bool pushed = oC_List_PushBack(FileSystemsList,FileSystem,&Allocator);
223 
224  if(pushed)
225  {
226  errorCode = oC_ErrorCode_None;
227  }
228  else
229  {
230  errorCode = oC_ErrorCode_CannotAddObjectToList;
231  }
232  }
233 
234  return errorCode;
235 }
236 
237 //==========================================================================================================================================
238 //==========================================================================================================================================
239 oC_ErrorCode_t oC_VirtualFileSystem_RemoveFileSystem( oC_FileSystem_t FileSystem )
240 {
241  oC_ErrorCode_t errorCode = oC_ErrorCode_ImplementError;
242 
243  if(oC_AssignErrorCodeIfFalse(&errorCode , ModuleEnabledFlag == true , oC_ErrorCode_ModuleNotStartedYet))
244  {
245  bool removed = oC_List_RemoveAll(FileSystemsList,FileSystem);
246 
247  if(removed)
248  {
249  errorCode = oC_ErrorCode_None;
250  }
251  else
252  {
253  errorCode = oC_ErrorCode_CannotRemoveObjectFromList;
254  }
255  }
256 
257  return errorCode;
258 }
259 
260 
261 //==========================================================================================================================================
262 //==========================================================================================================================================
263 oC_ErrorCode_t oC_VirtualFileSystem_mount( const char * FileSystem , const char * Path )
264 {
265  oC_ErrorCode_t errorCode = oC_ErrorCode_ImplementError;
266 
267  if(
268  oC_AssignErrorCodeIfFalse(&errorCode , ModuleEnabledFlag == true , oC_ErrorCode_ModuleNotStartedYet) &&
269  oC_AssignErrorCodeIfFalse(&errorCode , isaddresscorrect(Path) , oC_ErrorCode_WrongAddress ) &&
270  oC_AssignErrorCodeIfFalse(&errorCode , isaddresscorrect(FileSystem) , oC_ErrorCode_WrongAddress ) &&
271  oC_AssignErrorCodeIfFalse(&errorCode , strlen(Path) >= 1 , oC_ErrorCode_SizeNotCorrect) &&
272  oC_AssignErrorCodeIfFalse(&errorCode , Path[0] == '/' , oC_ErrorCode_PathNotCorrect) &&
273  oC_AssignErrorCodeIfFalse(&errorCode , Path[strlen(Path)-1] == '/' , oC_ErrorCode_PathNotCorrect)
274  )
275  {
276  oC_FileSystem_t fileSystemEntry = NULL;
277  char * absolute = ConvertToAbsoluteWithAllocation(Path,true);
278 
279  if(oC_AssignErrorCodeIfFalse(&errorCode , isram(absolute) , oC_ErrorCode_AllocationError ))
280  {
281  MountedEntry_t mountedFileSystem = GetMountedFileSystem(absolute,false);
282  MountedEntry_t mountedEntry = kmalloc(sizeof(struct _MountedEntry_t),&Allocator,AllocationFlags_CanWait1Second);
283  bool dirExists = CheckIfDirExists(absolute);
284 
285  oC_List_Foreach(FileSystemsList,fileSystem)
286  {
287  if(strcmp(FileSystem,fileSystem->Name) == 0)
288  {
289  fileSystemEntry = fileSystem;
290  break;
291  }
292  }
293 
294  if(
295  oC_AssignErrorCodeIfFalse(&errorCode , fileSystemEntry != NULL , oC_ErrorCode_ObjectNotFoundOnList) &&
296  oC_AssignErrorCodeIfFalse(&errorCode , mountedFileSystem == NULL , oC_ErrorCode_PathAlreadyUsed) &&
297  oC_AssignErrorCodeIfFalse(&errorCode , dirExists , oC_ErrorCode_NoSuchFile) &&
298  oC_AssignErrorCodeIfFalse(&errorCode , isaddresscorrect(fileSystemEntry->init) , oC_ErrorCode_FileSystemNotCorrect) &&
299  oC_AssignErrorCode( &errorCode , fileSystemEntry->init(&mountedEntry->Context)) &&
300  oC_AssignErrorCodeIfFalse(&errorCode , mountedEntry != NULL , oC_ErrorCode_AllocationError )
301  )
302  {
303  oC_UInt_t pathLength = strlen(absolute) + 1;
304  mountedEntry->FileSystem = fileSystemEntry;
305  mountedEntry->MountedPoint = kmalloc(pathLength ,&Allocator , AllocationFlags_CanWait1Second);
306 
307  if(oC_AssignErrorCodeIfFalse(&errorCode , mountedEntry->MountedPoint , oC_ErrorCode_AllocationError ))
308  {
309  bool pushed = false;
310  oC_UInt_t pushIndex = 0;
311 
312  strcpy(mountedEntry->MountedPoint,absolute);
313 
314  oC_List_Foreach(MountedEntries,mountedEntryForeach)
315  {
316  if(strlen(mountedEntryForeach->MountedPoint) <= pathLength )
317  {
318  break;
319  }
320  else
321  {
322  pushIndex++;
323  }
324  }
325 
326  pushed = oC_List_InsertBefore(MountedEntries,mountedEntry,pushIndex,&Allocator);
327 
328  if(pushed)
329  {
330  errorCode = oC_ErrorCode_None;
331  }
332  else
333  {
334  errorCode = oC_ErrorCode_CannotAddObjectToList;
335  }
336  }
337  }
338 
339  if(oC_ErrorOccur(errorCode))
340  {
341  if(mountedEntry)
342  {
343  if(mountedEntry->MountedPoint && !kfree(mountedEntry->MountedPoint,AllocationFlags_CanWaitForever))
344  {
345  oC_SaveError("Cannot release mounted point",oC_ErrorCode_ReleaseError);
346  }
347  if(!kfree(mountedEntry,AllocationFlags_CanWaitForever))
348  {
349  oC_SaveError("Cannot release mounted entry",oC_ErrorCode_ReleaseError);
350  }
351  }
352  }
353 
354  ifnot(ksmartfree(absolute,strlen(absolute)+1,AllocationFlags_CanWaitForever))
355  {
356  oC_SaveError("vfs-mount: cannot release temp buffer ",oC_ErrorCode_ReleaseError);
357  }
358  }
359  }
360 
361 
362  return errorCode;
363 }
364 
365 //==========================================================================================================================================
366 //==========================================================================================================================================
367 oC_ErrorCode_t oC_VirtualFileSystem_umount( const char * Path )
368 {
369  oC_ErrorCode_t errorCode = oC_ErrorCode_ImplementError;
370 
371  if(
372  oC_AssignErrorCodeIfFalse(&errorCode , ModuleEnabledFlag == true , oC_ErrorCode_ModuleNotStartedYet ) &&
373  oC_AssignErrorCodeIfFalse(&errorCode , isaddresscorrect(Path) , oC_ErrorCode_WrongAddress ) &&
374  oC_AssignErrorCodeIfFalse(&errorCode , strlen(Path) > 1 , oC_ErrorCode_SizeNotCorrect) &&
375  oC_AssignErrorCodeIfFalse(&errorCode , Path[0] == '/' , oC_ErrorCode_PathNotCorrect)
376  )
377  {
378  oC_FileSystem_t fileSystem = NULL;
379  char * absolute = ConvertToAbsoluteWithAllocation(Path,true);
380 
381  if(oC_AssignErrorCodeIfFalse(&errorCode , isram(absolute) , oC_ErrorCode_AllocationError ))
382  {
383  MountedEntry_t mountedEntry = GetMountedFileSystem(absolute,false);
384 
385  if(oC_AssignErrorCodeIfFalse(&errorCode,mountedEntry != NULL , oC_ErrorCode_NoFileSystemMounted))
386  {
387  fileSystem = mountedEntry->FileSystem;
388  errorCode = oC_ErrorCode_None;
389 
390  oC_List_Foreach(OpenedFilesEntries,openedEntry)
391  {
392  if(openedEntry->MountedEntry==mountedEntry)
393  {
394  oC_AssignErrorCode(&errorCode , oC_VirtualFileSystem_fclose(openedEntry->File));
395  }
396  }
397 
398  oC_AssignErrorCodeIfFalse(&errorCode , kfree(mountedEntry->MountedPoint , AllocationFlags_CanWaitForever) , oC_ErrorCode_ReleaseError );
399  oC_AssignErrorCodeIfFalse(&errorCode , isaddresscorrect(fileSystem->deinit) , oC_ErrorCode_FileSystemNotCorrect );
400  oC_AssignErrorCode( &errorCode , fileSystem->deinit(mountedEntry->Context) );
401  oC_AssignErrorCodeIfFalse(&errorCode , kfree(mountedEntry , AllocationFlags_CanWaitForever) , oC_ErrorCode_ReleaseError );
402 
403  bool removed = oC_List_RemoveAll(MountedEntries,mountedEntry);
404 
405  oC_AssignErrorCodeIfFalse(&errorCode , removed , oC_ErrorCode_CannotRemoveObjectFromList );
406 
407  }
408  ifnot(ksmartfree(absolute,strlen(absolute)+1,AllocationFlags_CanWaitForever))
409  {
410  oC_SaveError("vfs-umount: cannot release temp buffer ",oC_ErrorCode_ReleaseError);
411  }
412  }
413 
414  }
415 
416  return errorCode;
417 }
418 
419 //==========================================================================================================================================
420 //==========================================================================================================================================
421 oC_ErrorCode_t oC_VirtualFileSystem_fopen( oC_File_t * outFile , const char * Path , oC_FileSystem_ModeFlags_t Mode , oC_FileSystem_FileAttributes_t Attributes )
422 {
423  oC_ErrorCode_t errorCode = oC_ErrorCode_ImplementError;
424 
425  if(
426  oC_AssignErrorCodeIfFalse(&errorCode , ModuleEnabledFlag == true , oC_ErrorCode_ModuleNotStartedYet ) &&
427  oC_AssignErrorCodeIfFalse(&errorCode , isram(outFile) , oC_ErrorCode_OutputAddressNotInRAM ) &&
428  oC_AssignErrorCodeIfFalse(&errorCode , isaddresscorrect(Path) , oC_ErrorCode_WrongAddress ) &&
429  oC_AssignErrorCodeIfFalse(&errorCode , strlen(Path) > 1 , oC_ErrorCode_SizeNotCorrect)
430  )
431  {
432  char * absolute = ConvertToAbsoluteWithAllocation(Path,false);
433 
434  if(oC_AssignErrorCodeIfFalse(&errorCode , isram(absolute) , oC_ErrorCode_AllocationError ))
435  {
436  MountedEntry_t mountedEntry = GetMountedFileSystem(absolute,true);
437 
438  if(
439  oC_AssignErrorCodeIfFalse(&errorCode , mountedEntry != NULL , oC_ErrorCode_NoFileSystemMounted ) &&
440  oC_AssignErrorCodeIfFalse(&errorCode , isaddresscorrect(mountedEntry->FileSystem) , oC_ErrorCode_FileSystemNotCorrect) &&
441  oC_AssignErrorCodeIfFalse(&errorCode , isaddresscorrect(mountedEntry->FileSystem->fopen) , oC_ErrorCode_NoSupportedByFileSystem)
442  )
443  {
444  oC_UInt_t mountedPathLength = strlen(mountedEntry->MountedPoint);
445 
446  errorCode = mountedEntry->FileSystem->fopen( mountedEntry->Context , outFile , &absolute[mountedPathLength-1] , Mode , Attributes );
447 
448  if(!oC_ErrorOccur(errorCode))
449  {
450  OpenedFileEntry_t openedEntry = smartalloc(sizeof(struct _OpenedFileEntry_t),AllocationFlags_CanWait1Second);
451 
452  if(openedEntry)
453  {
454  openedEntry->File = *outFile;
455  openedEntry->MountedEntry = mountedEntry;
456  openedEntry->Process = oC_ProcessMan_GetCurrentProcess();
457 
458  bool pushed = oC_List_PushBack(OpenedFilesEntries,openedEntry,&Allocator);
459 
460  if(!pushed)
461  {
462  if(!smartfree(openedEntry,sizeof(struct _OpenedFileEntry_t),AllocationFlags_CanWaitForever))
463  {
464  oC_SaveError("VFS: fopen " , oC_ErrorCode_ReleaseError);
465  }
466 
467  errorCode = oC_ErrorCode_CannotAddObjectToList;
468  }
469  }
470  else
471  {
472  errorCode = oC_ErrorCode_AllocationError;
473  }
474  }
475  }
476 
477  ifnot(ksmartfree(absolute,strlen(absolute)+1,AllocationFlags_CanWaitForever))
478  {
479  oC_SaveError("vfs-umount: cannot release temp buffer ",oC_ErrorCode_ReleaseError);
480  }
481  }
482  }
483 
484  return errorCode;
485 }
486 
487 //==========================================================================================================================================
488 //==========================================================================================================================================
489 oC_ErrorCode_t oC_VirtualFileSystem_fclose( oC_File_t File )
490 {
491  oC_ErrorCode_t errorCode = oC_ErrorCode_ImplementError;
492 
493  if(oC_AssignErrorCodeIfFalse(&errorCode , ModuleEnabledFlag == true , oC_ErrorCode_ModuleNotStartedYet ))
494  {
495  oC_List_Foreach(OpenedFilesEntries,openedEntry)
496  {
497  if(openedEntry->File == File)
498  {
499  MountedEntry_t mountedEntry = openedEntry->MountedEntry;
500 
501  if(
502  oC_AssignErrorCodeIfFalse(&errorCode , isaddresscorrect(mountedEntry->FileSystem) , oC_ErrorCode_FileSystemNotCorrect) &&
503  oC_AssignErrorCodeIfFalse(&errorCode , isaddresscorrect(mountedEntry->FileSystem->fclose) , oC_ErrorCode_NoSupportedByFileSystem)
504  )
505  {
506  errorCode = mountedEntry->FileSystem->fclose(mountedEntry->Context,File);
507  }
508 
509  if(!smartfree(openedEntry,sizeof(struct _OpenedFileEntry_t),AllocationFlags_CanWaitForever))
510  {
511  oC_SaveError("VFS: fclose " , errorCode);
512  }
513 
514  bool removed = oC_List_RemoveAll(OpenedFilesEntries,openedEntry);
515 
516  oC_AssignErrorCodeIfFalse(&errorCode , removed , oC_ErrorCode_CannotRemoveObjectFromList);
517  break;
518  }
519  }
520  }
521 
522  return errorCode;
523 }
524 
525 //==========================================================================================================================================
526 //==========================================================================================================================================
527 oC_ErrorCode_t oC_VirtualFileSystem_fcloseFromProcess( oC_Process_t Process )
528 {
529  oC_ErrorCode_t errorCode = oC_ErrorCode_ImplementError;
530 
531  if(oC_AssignErrorCodeIfFalse(&errorCode , ModuleEnabledFlag == true , oC_ErrorCode_ModuleNotStartedYet ))
532  {
533  errorCode = oC_ErrorCode_None;
534 
535  oC_List_Foreach(OpenedFilesEntries,openedEntry)
536  {
537  if(openedEntry->Process == Process )
538  {
539  oC_AssignErrorCode(&errorCode , oC_VirtualFileSystem_fclose(openedEntry->File));
540  }
541  }
542  }
543 
544  return errorCode;
545 }
546 
547 //==========================================================================================================================================
548 //==========================================================================================================================================
549 oC_ErrorCode_t oC_VirtualFileSystem_fread( oC_File_t File , void * outBuffer , uint32_t * Size )
550 {
551  oC_ErrorCode_t errorCode = oC_ErrorCode_ImplementError;
552 
553  if(oC_AssignErrorCodeIfFalse(&errorCode , ModuleEnabledFlag == true , oC_ErrorCode_ModuleNotStartedYet ))
554  {
555  errorCode = oC_ErrorCode_NoSuchFile;
556 
557  oC_List_Foreach(OpenedFilesEntries,openedEntry)
558  {
559  if(openedEntry->File == File )
560  {
561  if(oC_AssignErrorCodeIfFalse(&errorCode , isaddresscorrect(openedEntry->MountedEntry->FileSystem->fread) , oC_ErrorCode_NoSupportedByFileSystem))
562  {
563  errorCode = openedEntry->MountedEntry->FileSystem->fread(openedEntry->MountedEntry->Context,File,outBuffer,Size);
564  break;
565  }
566  }
567  }
568  }
569 
570  return errorCode;
571 }
572 
573 //==========================================================================================================================================
574 //==========================================================================================================================================
575 oC_ErrorCode_t oC_VirtualFileSystem_fwrite( oC_File_t File , const void * Buffer , uint32_t * Size )
576 {
577  oC_ErrorCode_t errorCode = oC_ErrorCode_ImplementError;
578 
579  if(oC_AssignErrorCodeIfFalse(&errorCode , ModuleEnabledFlag == true , oC_ErrorCode_ModuleNotStartedYet ))
580  {
581  errorCode = oC_ErrorCode_NoSuchFile;
582 
583  oC_List_Foreach(OpenedFilesEntries,openedEntry)
584  {
585  if(openedEntry->File == File )
586  {
587  if(oC_AssignErrorCodeIfFalse(&errorCode , isaddresscorrect(openedEntry->MountedEntry->FileSystem->fwrite) , oC_ErrorCode_NoSupportedByFileSystem))
588  {
589  errorCode = openedEntry->MountedEntry->FileSystem->fwrite(openedEntry->MountedEntry->Context,File,Buffer,Size);
590  break;
591  }
592  }
593  }
594  }
595 
596  return errorCode;
597 }
598 
599 //==========================================================================================================================================
600 //==========================================================================================================================================
601 oC_ErrorCode_t oC_VirtualFileSystem_lseek( oC_File_t File , uint32_t Offset )
602 {
603  oC_ErrorCode_t errorCode = oC_ErrorCode_ImplementError;
604 
605  if(oC_AssignErrorCodeIfFalse(&errorCode , ModuleEnabledFlag == true , oC_ErrorCode_ModuleNotStartedYet ))
606  {
607  errorCode = oC_ErrorCode_NoSuchFile;
608 
609  oC_List_Foreach(OpenedFilesEntries,openedEntry)
610  {
611  if(openedEntry->File == File )
612  {
613  if(oC_AssignErrorCodeIfFalse(&errorCode , isaddresscorrect(openedEntry->MountedEntry->FileSystem->lseek) , oC_ErrorCode_NoSupportedByFileSystem))
614  {
615  errorCode = openedEntry->MountedEntry->FileSystem->lseek(openedEntry->MountedEntry->Context,File,Offset);
616  break;
617  }
618  }
619  }
620  }
621 
622  return errorCode;
623 }
624 
625 //==========================================================================================================================================
626 //==========================================================================================================================================
627 oC_ErrorCode_t oC_VirtualFileSystem_ioctl( oC_File_t File , oC_Ioctl_Command_t Command , void * Pointer)
628 {
629  oC_ErrorCode_t errorCode = oC_ErrorCode_ImplementError;
630 
631  if(oC_AssignErrorCodeIfFalse(&errorCode , ModuleEnabledFlag == true , oC_ErrorCode_ModuleNotStartedYet ))
632  {
633  errorCode = oC_ErrorCode_NoSuchFile;
634 
635  oC_List_Foreach(OpenedFilesEntries,openedEntry)
636  {
637  if(openedEntry->File == File )
638  {
639  if(oC_AssignErrorCodeIfFalse(&errorCode , isaddresscorrect(openedEntry->MountedEntry->FileSystem->ioctl) , oC_ErrorCode_NoSupportedByFileSystem))
640  {
641  errorCode = openedEntry->MountedEntry->FileSystem->ioctl(openedEntry->MountedEntry->Context,File,Command,Pointer);
642  break;
643  }
644  }
645  }
646  }
647 
648  return errorCode;
649 }
650 
651 //==========================================================================================================================================
652 //==========================================================================================================================================
653 oC_ErrorCode_t oC_VirtualFileSystem_sync( oC_File_t File )
654 {
655  oC_ErrorCode_t errorCode = oC_ErrorCode_ImplementError;
656 
657  if(oC_AssignErrorCodeIfFalse(&errorCode , ModuleEnabledFlag == true , oC_ErrorCode_ModuleNotStartedYet ))
658  {
659  errorCode = oC_ErrorCode_NoSuchFile;
660 
661  oC_List_Foreach(OpenedFilesEntries,openedEntry)
662  {
663  if(openedEntry->File == File )
664  {
665  if(oC_AssignErrorCodeIfFalse(&errorCode , isaddresscorrect(openedEntry->MountedEntry->FileSystem->sync) , oC_ErrorCode_NoSupportedByFileSystem))
666  {
667  errorCode = openedEntry->MountedEntry->FileSystem->sync(openedEntry->MountedEntry->Context,File);
668  break;
669  }
670  }
671  }
672  }
673 
674  return errorCode;
675 }
676 
677 //==========================================================================================================================================
678 //==========================================================================================================================================
679 oC_ErrorCode_t oC_VirtualFileSystem_getc( char * outCharacter , oC_File_t File )
680 {
681  oC_ErrorCode_t errorCode = oC_ErrorCode_ImplementError;
682 
683  if(oC_AssignErrorCodeIfFalse(&errorCode , ModuleEnabledFlag == true , oC_ErrorCode_ModuleNotStartedYet ))
684  {
685  errorCode = oC_ErrorCode_NoSuchFile;
686 
687  oC_List_Foreach(OpenedFilesEntries,openedEntry)
688  {
689  if(openedEntry->File == File )
690  {
691  if(oC_AssignErrorCodeIfFalse(&errorCode , isaddresscorrect(openedEntry->MountedEntry->FileSystem->Getc) , oC_ErrorCode_NoSupportedByFileSystem))
692  {
693  errorCode = openedEntry->MountedEntry->FileSystem->Getc(openedEntry->MountedEntry->Context,outCharacter,File);
694  break;
695  }
696  }
697  }
698  }
699 
700  return errorCode;
701 }
702 
703 //==========================================================================================================================================
704 //==========================================================================================================================================
705 oC_ErrorCode_t oC_VirtualFileSystem_putc( char Character , oC_File_t File )
706 {
707  oC_ErrorCode_t errorCode = oC_ErrorCode_ImplementError;
708 
709  if(oC_AssignErrorCodeIfFalse(&errorCode , ModuleEnabledFlag == true , oC_ErrorCode_ModuleNotStartedYet ))
710  {
711  errorCode = oC_ErrorCode_NoSuchFile;
712 
713  oC_List_Foreach(OpenedFilesEntries,openedEntry)
714  {
715  if(openedEntry->File == File )
716  {
717  if(oC_AssignErrorCodeIfFalse(&errorCode , isaddresscorrect(openedEntry->MountedEntry->FileSystem->Putc) , oC_ErrorCode_NoSupportedByFileSystem))
718  {
719  errorCode = openedEntry->MountedEntry->FileSystem->Putc(openedEntry->MountedEntry->Context,Character,File);
720  break;
721  }
722  }
723  }
724  }
725 
726  return errorCode;
727 }
728 
729 //==========================================================================================================================================
730 //==========================================================================================================================================
731 int32_t oC_VirtualFileSystem_tell( oC_File_t File )
732 {
733  int32_t bytes = 0;
734 
736  {
737  oC_List_Foreach(OpenedFilesEntries,openedEntry)
738  {
739  if(openedEntry->File == File )
740  {
741  if(isaddresscorrect(openedEntry->MountedEntry->FileSystem->tell))
742  {
743  bytes = openedEntry->MountedEntry->FileSystem->tell(openedEntry->MountedEntry->Context,File);
744  break;
745  }
746  }
747  }
748  }
749 
750  return bytes;
751 }
752 
753 //==========================================================================================================================================
754 //==========================================================================================================================================
755 bool oC_VirtualFileSystem_eof( oC_File_t File )
756 {
757  bool eof = false;
758 
760  {
761  oC_List_Foreach(OpenedFilesEntries,openedEntry)
762  {
763  if(openedEntry->File == File )
764  {
765  if(isaddresscorrect(openedEntry->MountedEntry->FileSystem->eof))
766  {
767  eof = openedEntry->MountedEntry->FileSystem->eof(openedEntry->MountedEntry->Context,File);
768  break;
769  }
770  }
771  }
772  }
773 
774  return eof;
775 }
776 
777 //==========================================================================================================================================
778 //==========================================================================================================================================
779 uint32_t oC_VirtualFileSystem_size( oC_File_t File )
780 {
781  uint32_t bytes = 0;
782 
784  {
785  oC_List_Foreach(OpenedFilesEntries,openedEntry)
786  {
787  if(openedEntry->File == File )
788  {
789  if(isaddresscorrect(openedEntry->MountedEntry->FileSystem->size))
790  {
791  bytes = openedEntry->MountedEntry->FileSystem->size(openedEntry->MountedEntry->Context,File);
792  break;
793  }
794  }
795  }
796  }
797 
798  return bytes;
799 }
800 
801 //==========================================================================================================================================
802 //==========================================================================================================================================
803 oC_ErrorCode_t oC_VirtualFileSystem_opendir( oC_Dir_t * outDir , const char * Path )
804 {
805  oC_ErrorCode_t errorCode = oC_ErrorCode_ImplementError;
806 
807  if(
808  oC_AssignErrorCodeIfFalse(&errorCode , ModuleEnabledFlag == true , oC_ErrorCode_ModuleNotStartedYet ) &&
809  oC_AssignErrorCodeIfFalse(&errorCode , isram(outDir) , oC_ErrorCode_OutputAddressNotInRAM ) &&
810  oC_AssignErrorCodeIfFalse(&errorCode , isaddresscorrect(Path) , oC_ErrorCode_WrongAddress ) &&
811  oC_AssignErrorCodeIfFalse(&errorCode , strlen(Path) >= 1 , oC_ErrorCode_SizeNotCorrect)
812  )
813  {
814  char * absolute = ConvertToAbsoluteWithAllocation(Path,true);
815 
816  if(oC_AssignErrorCodeIfFalse(&errorCode , isram(absolute) , oC_ErrorCode_AllocationError ))
817  {
818  MountedEntry_t mountedEntry = GetMountedFileSystem(absolute,true);
819 
820  if(
821  oC_AssignErrorCodeIfFalse(&errorCode , mountedEntry != NULL , oC_ErrorCode_NoFileSystemMounted ) &&
822  oC_AssignErrorCodeIfFalse(&errorCode , isaddresscorrect(mountedEntry->FileSystem) , oC_ErrorCode_FileSystemNotCorrect) &&
823  oC_AssignErrorCodeIfFalse(&errorCode , isaddresscorrect(mountedEntry->FileSystem->opendir) , oC_ErrorCode_NoSupportedByFileSystem)
824  )
825  {
826  oC_UInt_t mountedPathLength = strlen(mountedEntry->MountedPoint);
827 
828  errorCode = mountedEntry->FileSystem->opendir( mountedEntry->Context , outDir , &absolute[mountedPathLength-1] );
829 
830  if(!oC_ErrorOccur(errorCode))
831  {
832  OpenedFileEntry_t openedEntry = smartalloc(sizeof(struct _OpenedFileEntry_t),AllocationFlags_CanWait1Second);
833 
834  if(openedEntry)
835  {
836  openedEntry->Dir = *outDir;
837  openedEntry->MountedEntry = mountedEntry;
838  openedEntry->Process = oC_ProcessMan_GetCurrentProcess();
839 
840  bool pushed = oC_List_PushBack(OpenedFilesEntries,openedEntry,&Allocator);
841 
842  if(!pushed)
843  {
844  if(!smartfree(openedEntry,sizeof(struct _OpenedFileEntry_t),AllocationFlags_CanWaitForever))
845  {
846  oC_SaveError("VFS: opendir " , oC_ErrorCode_ReleaseError);
847  }
848 
849  errorCode = oC_ErrorCode_CannotAddObjectToList;
850  }
851  }
852  else
853  {
854  errorCode = oC_ErrorCode_AllocationError;
855  }
856  }
857  }
858 
859  ifnot(ksmartfree(absolute,strlen(absolute)+1,AllocationFlags_CanWaitForever))
860  {
861  oC_SaveError("vfs-umount: cannot release temp buffer ",oC_ErrorCode_ReleaseError);
862  }
863  }
864  }
865 
866  return errorCode;
867 }
868 
869 //==========================================================================================================================================
870 //==========================================================================================================================================
871 oC_ErrorCode_t oC_VirtualFileSystem_closedir( oC_Dir_t Dir )
872 {
873  oC_ErrorCode_t errorCode = oC_ErrorCode_ImplementError;
874 
875  if(oC_AssignErrorCodeIfFalse(&errorCode , ModuleEnabledFlag == true , oC_ErrorCode_ModuleNotStartedYet ))
876  {
877  oC_List_Foreach(OpenedFilesEntries,openedEntry)
878  {
879  if(openedEntry->Dir == Dir)
880  {
881  MountedEntry_t mountedEntry = openedEntry->MountedEntry;
882 
883  if(
884  oC_AssignErrorCodeIfFalse(&errorCode , isaddresscorrect(mountedEntry->FileSystem) , oC_ErrorCode_FileSystemNotCorrect) &&
885  oC_AssignErrorCodeIfFalse(&errorCode , isaddresscorrect(mountedEntry->FileSystem->closedir) , oC_ErrorCode_NoSupportedByFileSystem)
886  )
887  {
888  errorCode = mountedEntry->FileSystem->closedir(mountedEntry->Context,Dir);
889  }
890 
891  if(!smartfree(openedEntry,sizeof(struct _OpenedFileEntry_t),AllocationFlags_CanWaitForever))
892  {
893  oC_SaveError("VFS: closedir " , errorCode);
894  }
895 
896  bool removed = oC_List_RemoveAll(OpenedFilesEntries,openedEntry);
897 
898  oC_AssignErrorCodeIfFalse(&errorCode , removed , oC_ErrorCode_CannotRemoveObjectFromList);
899  break;
900  }
901  }
902  }
903 
904  return errorCode;
905 }
906 
907 //==========================================================================================================================================
908 //==========================================================================================================================================
909 oC_ErrorCode_t oC_VirtualFileSystem_readdir( oC_Dir_t Dir , oC_FileInfo_t * outFileInfo )
910 {
911  oC_ErrorCode_t errorCode = oC_ErrorCode_ImplementError;
912 
913  if(oC_AssignErrorCodeIfFalse(&errorCode , ModuleEnabledFlag == true , oC_ErrorCode_ModuleNotStartedYet ))
914  {
915  errorCode = oC_ErrorCode_NoSuchFile;
916 
917  oC_List_Foreach(OpenedFilesEntries,openedEntry)
918  {
919  if(openedEntry->Dir == Dir )
920  {
921  if(oC_AssignErrorCodeIfFalse(&errorCode , isaddresscorrect(openedEntry->MountedEntry->FileSystem->readdir) , oC_ErrorCode_NoSupportedByFileSystem))
922  {
923  errorCode = openedEntry->MountedEntry->FileSystem->readdir(openedEntry->MountedEntry->Context,Dir,outFileInfo);
924  break;
925  }
926  }
927  }
928  }
929 
930  return errorCode;
931 }
932 
933 //==========================================================================================================================================
934 //==========================================================================================================================================
935 oC_ErrorCode_t oC_VirtualFileSystem_stat( const char * Path , oC_FileInfo_t * outFileInfo)
936 {
937  oC_ErrorCode_t errorCode = oC_ErrorCode_ImplementError;
938 
939  if(
940  oC_AssignErrorCodeIfFalse(&errorCode , ModuleEnabledFlag == true , oC_ErrorCode_ModuleNotStartedYet ) &&
941  oC_AssignErrorCodeIfFalse(&errorCode , isram(outFileInfo) , oC_ErrorCode_OutputAddressNotInRAM ) &&
942  oC_AssignErrorCodeIfFalse(&errorCode , isaddresscorrect(Path) , oC_ErrorCode_WrongAddress ) &&
943  oC_AssignErrorCodeIfFalse(&errorCode , strlen(Path) >= 1 , oC_ErrorCode_SizeNotCorrect)
944  )
945  {
946  char * absolute = ConvertToAbsoluteWithAllocation(Path,true);
947 
948  if(oC_AssignErrorCodeIfFalse(&errorCode , isram(absolute) , oC_ErrorCode_AllocationError ))
949  {
950  MountedEntry_t mountedEntry = GetMountedFileSystem(absolute,true);
951 
952  if(
953  oC_AssignErrorCodeIfFalse(&errorCode , isaddresscorrect(mountedEntry) , oC_ErrorCode_NoFileSystemMounted) &&
954  oC_AssignErrorCodeIfFalse(&errorCode , isaddresscorrect(mountedEntry->FileSystem->stat) , oC_ErrorCode_NoSupportedByFileSystem)
955  )
956  {
957  oC_UInt_t mountedPathLength = strlen(mountedEntry->MountedPoint);
958  errorCode = mountedEntry->FileSystem->stat(mountedEntry->Context,&absolute[mountedPathLength],outFileInfo);
959  }
960 
961  ifnot(ksmartfree(absolute,strlen(absolute)+1,AllocationFlags_CanWaitForever))
962  {
963  oC_SaveError("vfs-umount: cannot release temp buffer ",oC_ErrorCode_ReleaseError);
964  }
965  }
966  }
967 
968  return errorCode;
969 }
970 
971 //==========================================================================================================================================
972 //==========================================================================================================================================
973 oC_ErrorCode_t oC_VirtualFileSystem_unlink( const char * Path)
974 {
975  oC_ErrorCode_t errorCode = oC_ErrorCode_ImplementError;
976 
977  if(
978  oC_AssignErrorCodeIfFalse(&errorCode , ModuleEnabledFlag == true , oC_ErrorCode_ModuleNotStartedYet ) &&
979  oC_AssignErrorCodeIfFalse(&errorCode , isaddresscorrect(Path) , oC_ErrorCode_WrongAddress ) &&
980  oC_AssignErrorCodeIfFalse(&errorCode , strlen(Path) >= 1 , oC_ErrorCode_SizeNotCorrect)
981  )
982  {
983  char * absolute = ConvertToAbsoluteWithAllocation(Path,true);
984 
985  if(oC_AssignErrorCodeIfFalse(&errorCode , isram(absolute) , oC_ErrorCode_AllocationError ))
986  {
987  MountedEntry_t mountedEntry = GetMountedFileSystem(absolute,true);
988 
989  if(
990  oC_AssignErrorCodeIfFalse(&errorCode , isaddresscorrect(mountedEntry) , oC_ErrorCode_NoFileSystemMounted) &&
991  oC_AssignErrorCodeIfFalse(&errorCode , isaddresscorrect(mountedEntry->FileSystem->unlink) , oC_ErrorCode_NoSupportedByFileSystem)
992  )
993  {
994  oC_UInt_t mountedPathLength = strlen(mountedEntry->MountedPoint);
995  errorCode = mountedEntry->FileSystem->unlink(mountedEntry->Context,&absolute[mountedPathLength]);
996  }
997 
998  ifnot(ksmartfree(absolute,strlen(absolute)+1,AllocationFlags_CanWaitForever))
999  {
1000  oC_SaveError("vfs-umount: cannot release temp buffer ",oC_ErrorCode_ReleaseError);
1001  }
1002  }
1003  }
1004 
1005  return errorCode;
1006 }
1007 
1008 //==========================================================================================================================================
1009 //==========================================================================================================================================
1010 oC_ErrorCode_t oC_VirtualFileSystem_rename( const char * OldName , const char * NewName)
1011 {
1012  return oC_ErrorCode_NotImplemented;
1013 }
1014 
1015 //==========================================================================================================================================
1016 //==========================================================================================================================================
1017 oC_ErrorCode_t oC_VirtualFileSystem_chmod( const char * Path, oC_FileSystem_FileAttributes_t Attributes , oC_FileSystem_FileAttributes_t Mask)
1018 {
1019  oC_ErrorCode_t errorCode = oC_ErrorCode_ImplementError;
1020 
1021  if(
1022  oC_AssignErrorCodeIfFalse(&errorCode , ModuleEnabledFlag == true , oC_ErrorCode_ModuleNotStartedYet ) &&
1023  oC_AssignErrorCodeIfFalse(&errorCode , isaddresscorrect(Path) , oC_ErrorCode_WrongAddress ) &&
1024  oC_AssignErrorCodeIfFalse(&errorCode , strlen(Path) >= 1 , oC_ErrorCode_SizeNotCorrect)
1025  )
1026  {
1027  char * absolute = ConvertToAbsoluteWithAllocation(Path,true);
1028 
1029  if(oC_AssignErrorCodeIfFalse(&errorCode , isram(absolute) , oC_ErrorCode_AllocationError ))
1030  {
1031  MountedEntry_t mountedEntry = GetMountedFileSystem(absolute,true);
1032 
1033  if(
1034  oC_AssignErrorCodeIfFalse(&errorCode , isaddresscorrect(mountedEntry) , oC_ErrorCode_NoFileSystemMounted) &&
1035  oC_AssignErrorCodeIfFalse(&errorCode , isaddresscorrect(mountedEntry->FileSystem->chmod) , oC_ErrorCode_NoSupportedByFileSystem)
1036  )
1037  {
1038  oC_UInt_t mountedPathLength = strlen(mountedEntry->MountedPoint);
1039  errorCode = mountedEntry->FileSystem->chmod(mountedEntry->Context,&absolute[mountedPathLength],Attributes,Mask);
1040  }
1041 
1042  ifnot(ksmartfree(absolute,strlen(absolute)+1,AllocationFlags_CanWaitForever))
1043  {
1044  oC_SaveError("vfs-umount: cannot release temp buffer ",oC_ErrorCode_ReleaseError);
1045  }
1046  }
1047  }
1048 
1049  return errorCode;
1050 }
1051 
1052 //==========================================================================================================================================
1053 //==========================================================================================================================================
1054 oC_ErrorCode_t oC_VirtualFileSystem_utime( const char * Path , oC_Timestamp_t Timestamp )
1055 {
1056  oC_ErrorCode_t errorCode = oC_ErrorCode_ImplementError;
1057 
1058  if(
1059  oC_AssignErrorCodeIfFalse(&errorCode , ModuleEnabledFlag == true , oC_ErrorCode_ModuleNotStartedYet ) &&
1060  oC_AssignErrorCodeIfFalse(&errorCode , isaddresscorrect(Path) , oC_ErrorCode_WrongAddress ) &&
1061  oC_AssignErrorCodeIfFalse(&errorCode , strlen(Path) >= 1 , oC_ErrorCode_SizeNotCorrect)
1062  )
1063  {
1064  char * absolute = ConvertToAbsoluteWithAllocation(Path,true);
1065 
1066  if(oC_AssignErrorCodeIfFalse(&errorCode , isram(absolute) , oC_ErrorCode_AllocationError ))
1067  {
1068  MountedEntry_t mountedEntry = GetMountedFileSystem(absolute,true);
1069 
1070  if(
1071  oC_AssignErrorCodeIfFalse(&errorCode , isaddresscorrect(mountedEntry) , oC_ErrorCode_NoFileSystemMounted) &&
1072  oC_AssignErrorCodeIfFalse(&errorCode , isaddresscorrect(mountedEntry->FileSystem->utime) , oC_ErrorCode_NoSupportedByFileSystem)
1073  )
1074  {
1075  oC_UInt_t mountedPathLength = strlen(mountedEntry->MountedPoint);
1076  errorCode = mountedEntry->FileSystem->utime(mountedEntry->Context,&absolute[mountedPathLength],Timestamp);
1077  }
1078 
1079  ifnot(ksmartfree(absolute,strlen(absolute)+1,AllocationFlags_CanWaitForever))
1080  {
1081  oC_SaveError("vfs-umount: cannot release temp buffer ",oC_ErrorCode_ReleaseError);
1082  }
1083  }
1084  }
1085 
1086  return errorCode;
1087 }
1088 
1089 //==========================================================================================================================================
1090 //==========================================================================================================================================
1091 oC_ErrorCode_t oC_VirtualFileSystem_mkdir( const char * Path)
1092 {
1093  oC_ErrorCode_t errorCode = oC_ErrorCode_ImplementError;
1094 
1095  if(
1096  oC_AssignErrorCodeIfFalse(&errorCode , ModuleEnabledFlag == true , oC_ErrorCode_ModuleNotStartedYet ) &&
1097  oC_AssignErrorCodeIfFalse(&errorCode , isaddresscorrect(Path) , oC_ErrorCode_WrongAddress ) &&
1098  oC_AssignErrorCodeIfFalse(&errorCode , strlen(Path) >= 1 , oC_ErrorCode_SizeNotCorrect)
1099  )
1100  {
1101  char * absolutePath = ConvertToAbsoluteWithAllocation(Path,true);
1102 
1103  if(absolutePath)
1104  {
1105  MountedEntry_t mountedEntry = GetMountedFileSystem(absolutePath,true);
1106 
1107  if(
1108  oC_AssignErrorCodeIfFalse(&errorCode , isaddresscorrect(mountedEntry) , oC_ErrorCode_NoFileSystemMounted) &&
1109  oC_AssignErrorCodeIfFalse(&errorCode , isaddresscorrect(mountedEntry->FileSystem->mkdir) , oC_ErrorCode_NoSupportedByFileSystem)
1110  )
1111  {
1112  oC_UInt_t mountedPathLength = strlen(mountedEntry->MountedPoint);
1113 
1114  errorCode = mountedEntry->FileSystem->mkdir(mountedEntry->Context,&absolutePath[mountedPathLength-1]);
1115  }
1116 
1117  ifnot(ksmartfree(absolutePath,strlen(absolutePath)+1,AllocationFlags_CanWaitForever))
1118  {
1119  oC_SaveError("vfs-mkdir: cannot release temp buffer ",oC_ErrorCode_ReleaseError);
1120  }
1121  }
1122  else
1123  {
1124  errorCode = oC_ErrorCode_AllocationError;
1125  }
1126 
1127  }
1128 
1129  return errorCode;
1130 }
1131 
1132 //==========================================================================================================================================
1133 //==========================================================================================================================================
1134 oC_ErrorCode_t oC_VirtualFileSystem_chdir( const char * Path)
1135 {
1136  oC_ErrorCode_t errorCode = oC_ErrorCode_ImplementError;
1137 
1138  if(oC_AssignErrorCodeIfFalse(&errorCode , ModuleEnabledFlag == true , oC_ErrorCode_ModuleNotStartedYet ))
1139  {
1140  MountedEntry_t mountedEntry = GetMountedFileSystem(Path,true);
1141 
1142  if(
1143  oC_AssignErrorCodeIfFalse(&errorCode , isaddresscorrect(mountedEntry) , oC_ErrorCode_NoFileSystemMounted)
1144  )
1145  {
1146  }
1147  }
1148 
1149  return errorCode;
1150 }
1151 
1152 //==========================================================================================================================================
1153 //==========================================================================================================================================
1154 oC_ErrorCode_t oC_VirtualFileSystem_getcwd( char * outBuffer , uint32_t Size )
1155 {
1156  oC_ErrorCode_t errorCode = oC_ErrorCode_ImplementError;
1157 
1158  if(
1159  oC_AssignErrorCodeIfFalse(&errorCode , ModuleEnabledFlag , oC_ErrorCode_ModuleNotStartedYet ) &&
1160  oC_AssignErrorCodeIfFalse(&errorCode , isram(outBuffer) , oC_ErrorCode_OutputAddressNotInRAM ) &&
1161  oC_AssignErrorCodeIfFalse(&errorCode , Size > 0 , oC_ErrorCode_SizeNotCorrect ) &&
1162  oC_AssignErrorCodeIfFalse(&errorCode , isarrayinram(outBuffer,Size) , oC_ErrorCode_ArraySizeTooBig )
1163 
1164  )
1165  {
1166 
1167  }
1168 
1169  return errorCode;
1170 }
1171 
1172 //==========================================================================================================================================
1173 //==========================================================================================================================================
1174 oC_ErrorCode_t oC_VirtualFileSystem_getpwd( char * outPwd , uint32_t Size )
1175 {
1176  oC_ErrorCode_t errorCode = oC_ErrorCode_ImplementError;
1177 
1178  if(
1179  oC_AssignErrorCodeIfFalse(&errorCode , ModuleEnabledFlag , oC_ErrorCode_ModuleNotStartedYet ) &&
1180  oC_AssignErrorCodeIfFalse(&errorCode , isram(outPwd) , oC_ErrorCode_OutputAddressNotInRAM ) &&
1181  oC_AssignErrorCodeIfFalse(&errorCode , Size > 0 , oC_ErrorCode_SizeNotCorrect ) &&
1182  oC_AssignErrorCodeIfFalse(&errorCode , isarrayinram(outPwd,Size) , oC_ErrorCode_ArraySizeTooBig )
1183 
1184  )
1185  {
1186  char * pwd = GetPwd();
1187 
1188  if( strlen(pwd) > Size )
1189  {
1190  errorCode = oC_ErrorCode_OutputArrayToSmall;
1191  }
1192  else
1193  {
1194  strcpy(outPwd,pwd);
1195  errorCode = oC_ErrorCode_None;
1196  }
1197  }
1198 
1199  return errorCode;
1200 }
1201 
1202 //==========================================================================================================================================
1203 //==========================================================================================================================================
1204 oC_ErrorCode_t oC_VirtualFileSystem_ConvertRelativeToAbsolute( const char * Relative , char * outAbsolute , uint32_t * AbsoluteSize , bool TreatAsDir )
1205 {
1206  oC_ErrorCode_t errorCode = oC_ErrorCode_ImplementError;
1207 
1208  if(
1209  oC_AssignErrorCodeIfFalse(&errorCode , ModuleEnabledFlag , oC_ErrorCode_ModuleNotStartedYet ) &&
1210  oC_AssignErrorCodeIfFalse(&errorCode , isaddresscorrect(Relative) , oC_ErrorCode_WrongAddress ) &&
1211  oC_AssignErrorCodeIfFalse(&errorCode , isram(AbsoluteSize) , oC_ErrorCode_OutputAddressNotInRAM )
1212  )
1213  {
1214  *AbsoluteSize = ConvertRelativeToAbsolute(Relative,outAbsolute,*AbsoluteSize,TreatAsDir);
1215  errorCode = oC_ErrorCode_None;
1216  }
1217 
1218  return errorCode;
1219 }
1220 
1221 //==========================================================================================================================================
1222 //==========================================================================================================================================
1223 bool oC_VirtualFileSystem_DirExists( const char * Path )
1224 {
1225  bool exists = false;
1226 
1227  if(ModuleEnabledFlag && isaddresscorrect(Path))
1228  {
1229  char * absolute = ConvertToAbsoluteWithAllocation(Path,true);
1230 
1231  if(isram(absolute))
1232  {
1233  exists = CheckIfDirExists(absolute);
1234 
1235  ifnot(ksmartfree(absolute,strlen(absolute)+1,AllocationFlags_CanWaitForever))
1236  {
1237  oC_SaveError("vfs-dir-exists: cannot release temp buffer ",oC_ErrorCode_ReleaseError);
1238  }
1239  }
1240  else
1241  {
1242  oC_SaveError("vfs-dir-exists: cannot allocate memory for temp buffer",oC_ErrorCode_AllocationError);
1243  }
1244  }
1245 
1246  return exists;
1247 }
1248 
1249 #undef _________________________________________INTERFACE_FUNCTIONS_SECTION________________________________________________________________
1250 
1256 #define _________________________________________LOCAL_FUNCTIONS_SECTION___________________________________________________________________
1257 
1258 //==========================================================================================================================================
1259 //==========================================================================================================================================
1260 static MountedEntry_t GetMountedFileSystem( const char * Path , bool WithParentDirs )
1261 {
1262  MountedEntry_t mountedEntry = NULL;
1263  oC_UInt_t pathLength = strlen(Path);
1264 
1265  oC_List_Foreach(MountedEntries,mounted)
1266  {
1267  oC_UInt_t mountPointLength = strlen(mounted->MountedPoint);
1268 
1269  if(
1270  (WithParentDirs && pathLength >= mountPointLength && strncmp(mounted->MountedPoint,Path,mountPointLength)==0) ||
1271  (!WithParentDirs && pathLength == mountPointLength && strcmp(mounted->MountedPoint,Path)==0)
1272  )
1273  {
1274  mountedEntry = mounted;
1275  break;
1276  }
1277  }
1278 
1279  return mountedEntry;
1280 }
1281 
1282 //==========================================================================================================================================
1283 //==========================================================================================================================================
1284 static char * GetPwd( void )
1285 {
1286  return oC_Process_GetPwd(oC_ProcessMan_GetCurrentProcess());
1287 }
1288 
1289 //==========================================================================================================================================
1290 //==========================================================================================================================================
1291 static uint32_t ConvertRelativeToAbsolute( const char * Relative , char * outAbsolute , uint32_t AbsoluteSize , bool TreatAsDir )
1292 {
1293  uint32_t requiredSize = 0;
1294  uint32_t relativeLength = strlen(Relative);
1295  char * pwd = GetPwd();
1296  uint32_t pwdLength = strlen(pwd);
1297  bool lastSlashPushed = false;
1298 
1299 #define _putc(c) if( ((c) == '/' && !lastSlashPushed) || ((c) != '/') ) {if(outAbsolute != NULL && requiredSize < AbsoluteSize) { outAbsolute[requiredSize] = c; } requiredSize++; lastSlashPushed = (c) == '/';}
1300 
1301  if(relativeLength>0 && pwdLength > 0)
1302  {
1303  uint32_t tempBufferLength = pwdLength + relativeLength;
1304 
1305  if(!IsDirSign(pwd[pwdLength-1]))
1306  {
1307  /* Plus 1 for '/' sign */
1308  tempBufferLength++;
1309  }
1310 
1311  if(IsAbsolutePath(Relative))
1312  {
1313  tempBufferLength = relativeLength;
1314  }
1315 
1316  if(TreatAsDir && !IsDirSign(Relative[relativeLength-1]))
1317  {
1318  /* For a '/' sign at the end of the string */
1319  tempBufferLength++;
1320  }
1321 
1322  char * tempBuffer = ksmartalloc(tempBufferLength+1, &Allocator, AllocationFlags_CanWait1Second);
1323 
1324  if(oC_SaveIfFalse("VFS::ConvertRelativeToAbsolute - Cannot allocate memory - ", tempBuffer != NULL, oC_ErrorCode_AllocationError))
1325  {
1326  if(IsAbsolutePath(Relative))
1327  {
1328  strcpy(tempBuffer,Relative);
1329  }
1330  else
1331  {
1332  strncpy(tempBuffer,pwd,pwdLength);
1333 
1334  if(!IsDirSign(pwd[pwdLength-1]))
1335  {
1336  tempBuffer[pwdLength] = '/';
1337  strncpy(&tempBuffer[pwdLength+1],Relative,relativeLength);
1338  }
1339  else
1340  {
1341  strncpy(&tempBuffer[pwdLength],Relative,relativeLength);
1342  }
1343 
1344  }
1345 
1346  if(TreatAsDir && !IsDirSign(Relative[relativeLength-1]))
1347  {
1348  /* For a '/' sign at the end of the string */
1349  tempBuffer[tempBufferLength-1] = '/';
1350  }
1351 
1352  tempBuffer[tempBufferLength] = 0;
1353 
1354  uint32_t dirsToSkip = 0;
1355  uint32_t foundDots = 0;
1356  bool foundFileName = TreatAsDir;
1357 
1358  for(uint32_t tempBufferIndex = tempBufferLength - 1; tempBufferIndex > 0 ; tempBufferIndex--)
1359  {
1360  if(IsDirSign(tempBuffer[tempBufferIndex]))
1361  {
1362  if(foundFileName)
1363  {
1364  if( dirsToSkip == 0)
1365  {
1366  _putc('/');
1367  }
1368 
1369  if( dirsToSkip > 0 )
1370  {
1371  dirsToSkip--;
1372  }
1373  }
1374  else
1375  {
1376  if(foundDots >= 2)
1377  {
1378  dirsToSkip++;
1379  }
1380  }
1381  foundFileName = false;
1382  foundDots = 0;
1383  }
1384  else if(!foundFileName && tempBuffer[tempBufferIndex] == '.')
1385  {
1386  foundDots++;
1387  }
1388  else
1389  {
1390  while(foundDots>0)
1391  {
1392  if( dirsToSkip == 0 )
1393  {
1394  _putc('.');
1395  }
1396  foundDots--;
1397  }
1398 
1399  if( dirsToSkip == 0 )
1400  {
1401  _putc(tempBuffer[tempBufferIndex]);
1402  }
1403 
1404  foundFileName = true;
1405  }
1406  }
1407 
1408  /* We are skipping the first sign, so we should put the '/' to the begin of the string (the string will be reverted) */
1409  _putc('/');
1410 
1411  /* Put the NULL terminator to end of the string (the null terminator in reversion is not moved) */
1412  _putc(0);
1413 
1414  if(outAbsolute != NULL)
1415  {
1416  /* Reverse a string, because it was pushed from the end */
1417  string_reverse(outAbsolute);
1418  }
1419 
1420  if(ksmartfree(tempBuffer,tempBufferLength+1,AllocationFlags_CanWaitForever)==false)
1421  {
1422  oC_SaveError("VFS,ConvertRelativeToAbsolute: cannot relase temp buffer" , oC_ErrorCode_ReleaseError);
1423  }
1424 
1425  }
1426  else
1427  {
1428  strcpy(outAbsolute,"VFS error");
1429  }
1430  }
1431 
1432 #undef _putc
1433  return requiredSize;
1434 }
1435 
1436 //==========================================================================================================================================
1437 //==========================================================================================================================================
1438 static char * ConvertToAbsoluteWithAllocation(const char * Relative , bool TreatAsDir )
1439 {
1440  uint32_t requiredSize = ConvertRelativeToAbsolute(Relative,NULL,0,TreatAsDir);
1441  char * absolute = ksmartalloc(requiredSize,&Allocator,AllocationFlags_CanWait1Second);
1442 
1443  if(absolute)
1444  {
1445  ConvertRelativeToAbsolute(Relative,absolute,requiredSize,TreatAsDir);
1446  }
1447 
1448  return absolute;
1449 }
1450 
1451 //==========================================================================================================================================
1452 //==========================================================================================================================================
1453 static bool CheckIfDirExists( const char * Absolute )
1454 {
1455  bool exists = strcmp(Absolute,"/") == 0;
1456 
1457  MountedEntry_t mountedEntry = GetMountedFileSystem(Absolute,true);
1458 
1459  if(isaddresscorrect(mountedEntry) && isaddresscorrect(mountedEntry->FileSystem->DirExists))
1460  {
1461  oC_UInt_t mountedPathLength = strlen(mountedEntry->MountedPoint);
1462  exists = mountedEntry->FileSystem->DirExists(mountedEntry->Context,&Absolute[mountedPathLength-1]);
1463  }
1464 
1465  return exists;
1466 }
1467 
1468 #undef _________________________________________LOCAL_FUNCTIONS_SECTION___________________________________________________________________
static bool ModuleEnabledFlag
Definition: oc_memman.c:211
const char * Name
Definition: oc_stdlib.h:161
identifier for allocations
Definition: oc_stdlib.h:159
With ifnot definition.
bool oC_MemMan_FreeAllMemoryOfAllocator(Allocator_t Allocator)
release all memory of allocator
Definition: oc_memman.c:985
The file with interface for process manager.
The file with list library.
The file with interface for Virtual File System.
oC_FileSystem_ModeFlags_t
Definition: oc_fs.h:54
stores ETH context
Definition: oc_eth.c:97
The file with interface for string library.
static const oC_Allocator_t Allocator
Definition: oc_eth.c:152
Definition: oc_devfs.c:60
#define NULL
pointer to a zero
Definition: oc_null.h:37