00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #include <stdio.h>
00023 #include <stdlib.h>
00024 #include <string.h>
00025 #include <assert.h>
00026
00027 #include "ram.h"
00028
00029 #include "fsvfs.h"
00030 #include "dirtree.h"
00031
00032
00033 #define VFSFILEHEADER_SIGNATURE 0x30304656
00034
00035 #define VCFSFILEHEADER_SIGNATURE 0x30304643
00036
00037
00038 #define VFSFILE_SIGNATURE 0x31304656
00039
00040
00041 #define VFSFINDER_SIGNATURE 0x32304656
00042
00043 #define HEADER_VERSION 0
00044
00045 typedef struct VFSFileHeader
00046 {
00047 unsigned int Signature;
00048 unsigned short Version;
00049 geBoolean Dispersed;
00050 long DirectoryOffset;
00051 long DataLength;
00052 long EndPosition;
00053 } VFSFileHeader;
00054
00055
00056
00057
00058 typedef struct VFSFile
00059 {
00060 unsigned int Signature;
00061
00062 geVFile * RWOps;
00063 struct VFSFile *System;
00064
00065 DirTree * DirEntry;
00066 DirTree * Directory;
00067
00068 long RWOpsStartPos;
00069 long CurrentRelPos;
00070 long Length;
00071 char Mask;
00072
00073 unsigned int OpenModeFlags;
00074
00075
00076 long EndPosition;
00077 geBoolean IsSystem;
00078 long DataLength;
00079 geBoolean Dispersed;
00080
00081 } VFSFile;
00082
00083 typedef struct VFSFinder
00084 {
00085 unsigned int Signature;
00086 VFSFile * File;
00087 DirTree_Finder * Finder;
00088 DirTree * LastFind;
00089 } VFSFinder;
00090
00091 #define CHECK_HANDLE(H) assert(H);assert(H->Signature == VFSFILE_SIGNATURE);
00092 #define CHECK_FINDER(F) assert(F);assert(F->Signature == VFSFINDER_SIGNATURE);
00093
00094 static void * GENESISCC FSVFS_FinderCreate(
00095 geVFile * FS,
00096 void * Handle,
00097 const char * FileSpec)
00098 {
00099 VFSFinder * Finder;
00100 VFSFile * File;
00101
00102 assert(FileSpec != NULL);
00103
00104 File = Handle;
00105
00106 CHECK_HANDLE(File);
00107
00108 if (!File->Directory)
00109 return NULL;
00110
00111 Finder = geRam_Allocate(sizeof(*Finder));
00112 if (!Finder)
00113 return NULL;
00114
00115 memset(Finder, 0, sizeof(*Finder));
00116
00117 Finder->Signature = VFSFINDER_SIGNATURE;
00118 Finder->File = File;
00119 Finder->Finder = DirTree_CreateFinder(File->Directory, FileSpec);
00120 if (!Finder->Finder)
00121 {
00122 geRam_Free(Finder);
00123 return NULL;
00124 }
00125
00126 return (void *)Finder;
00127 }
00128
00129 static geBoolean GENESISCC FSVFS_FinderGetNextFile(void *Handle)
00130 {
00131 VFSFinder * Finder;
00132
00133 Finder = Handle;
00134
00135 CHECK_FINDER(Finder);
00136
00137 Finder->LastFind = DirTree_FinderGetNextFile(Finder->Finder);
00138 if (Finder->LastFind)
00139 return GE_TRUE;
00140
00141 return GE_FALSE;
00142 }
00143
00144 static geBoolean GENESISCC FSVFS_FinderGetProperties(void *Handle, geVFile_Properties *Properties)
00145 {
00146 VFSFinder * Finder;
00147
00148 assert(Properties);
00149
00150 Finder = Handle;
00151
00152 CHECK_FINDER(Finder);
00153
00154 if (!Finder->LastFind)
00155 return GE_FALSE;
00156
00157 DirTree_GetFileTime(Finder->LastFind, &Properties->Time);
00158 DirTree_GetFileAttributes(Finder->LastFind, &Properties->AttributeFlags);
00159 DirTree_GetFileSize(Finder->LastFind, &Properties->Size);
00160 DirTree_GetFileHints(Finder->LastFind, &Properties->Hints);
00161 return DirTree_GetName(Finder->LastFind, &Properties->Name[0], sizeof(Properties->Name));
00162 }
00163
00164 static void GENESISCC FSVFS_FinderDestroy(void *Handle)
00165 {
00166 VFSFinder * Finder;
00167
00168 Finder = Handle;
00169
00170 CHECK_FINDER(Finder);
00171
00172 assert(Finder->Finder);
00173
00174 Finder->Signature = 0;
00175 DirTree_DestroyFinder(Finder->Finder);
00176 geRam_Free(Finder);
00177 }
00178
00179 static void * GENESISCC FSVFS_Open(
00180 geVFile * FS,
00181 void * Handle,
00182 const char * Name,
00183 void * Dummy,
00184 unsigned int OpenModeFlags)
00185 {
00186 VFSFile * Context;
00187 VFSFile * NewFile;
00188 DirTree * FileEntry;
00189
00190 Context = Handle;
00191
00192 CHECK_HANDLE(Context);
00193
00194 assert(Name);
00195
00196 if (!Context->Directory)
00197 return NULL;
00198
00199
00200
00201
00202
00203
00204
00205 if ((OpenModeFlags & GE_VFILE_OPEN_UPDATE) &&
00206 !(OpenModeFlags & GE_VFILE_OPEN_DIRECTORY) &&
00207 !(OpenModeFlags & GE_VFILE_OPEN_CREATE) &&
00208 !(Context->System->OpenModeFlags & GE_VFILE_OPEN_CREATE))
00209 return NULL;
00210
00211 FileEntry = DirTree_FindExact(Context->Directory, Name);
00212 if (OpenModeFlags & GE_VFILE_OPEN_CREATE)
00213 {
00214 if (FileEntry)
00215 return NULL;
00216
00217 FileEntry = DirTree_AddFile(Context->Directory,
00218 Name,
00219 (OpenModeFlags & GE_VFILE_OPEN_DIRECTORY) ? GE_TRUE : GE_FALSE);
00220 if (!FileEntry)
00221 return NULL;
00222 }
00223 else
00224 {
00225 if (!FileEntry)
00226 return NULL;
00227 }
00228
00229 NewFile = geRam_Allocate(sizeof(*NewFile));
00230 if (!NewFile)
00231 return NewFile;
00232
00233 memset(NewFile, 0, sizeof(*NewFile));
00234
00235 NewFile->Signature = VFSFILE_SIGNATURE;
00236 NewFile->DirEntry = FileEntry;
00237 NewFile->RWOps = Context->RWOps;
00238 NewFile->Dispersed = GE_FALSE;
00239 NewFile->System = Context->System;
00240 NewFile->Mask = Context->Mask;
00241
00242
00243 if (OpenModeFlags & GE_VFILE_OPEN_DIRECTORY)
00244 {
00245 NewFile->Directory = FileEntry;
00246 }
00247 else
00248 {
00249 if (OpenModeFlags & GE_VFILE_OPEN_CREATE)
00250 {
00251 NewFile->RWOpsStartPos = Context->System->DataLength +
00252 Context->System->RWOpsStartPos;
00253 }
00254 else
00255 {
00256 DirTree_GetFileOffset(FileEntry, &NewFile->RWOpsStartPos);
00257 }
00258 }
00259
00260 NewFile->OpenModeFlags = OpenModeFlags;
00261
00262 if (!(OpenModeFlags & GE_VFILE_OPEN_DIRECTORY))
00263 {
00264 if (OpenModeFlags & GE_VFILE_OPEN_CREATE)
00265 {
00266 DirTree_SetFileOffset(FileEntry, NewFile->RWOpsStartPos);
00267 }
00268 else
00269 {
00270 assert(!(OpenModeFlags & GE_VFILE_OPEN_UPDATE));
00271 DirTree_GetFileSize(FileEntry, &NewFile->Length);
00272 }
00273 }
00274
00275
00276 NewFile->IsSystem = GE_FALSE;
00277
00278 return (void *)NewFile;
00279 }
00280
00281 static void * GENESISCC FSVFS_OpenNewSystem(
00282 geVFile * RWOps,
00283 const char * Name,
00284 void * Context,
00285 unsigned int OpenModeFlags)
00286 {
00287 VFSFile * NewFS;
00288 long RWOpsStartPos;
00289 char *TStr;
00290 char EString[256];
00291 char Mask;
00292
00293 assert(RWOps != NULL);
00294 assert(Name == NULL);
00295 if(Context == NULL)
00296 Mask = 0;
00297 else
00298 {
00299 TStr = (char *)Context;
00300 strncpy(EString, TStr, 8);
00301 Mask = EString[0] & 0x01;
00302 Mask |= EString[7] & 0x02;
00303 Mask |= EString[1] & 0x04;
00304 Mask |= EString[6] & 0x08;
00305 Mask |= EString[2] & 0x10;
00306 Mask |= EString[5] & 0x20;
00307 Mask |= EString[3] & 0x40;
00308 Mask |= EString[4] & 0x80;
00309
00310
00311
00312
00313
00314 }
00315
00316
00317 if (!(OpenModeFlags & GE_VFILE_OPEN_DIRECTORY))
00318 return NULL;
00319
00320 if (geVFile_Tell(RWOps, &RWOpsStartPos) == GE_FALSE)
00321 return NULL;
00322
00323 if (!(OpenModeFlags & GE_VFILE_OPEN_CREATE))
00324 {
00325 VFSFileHeader Header;
00326 long DirectoryStartPos;
00327 long DirectoryEndPos;
00328
00329
00330
00331 if (geVFile_Read(RWOps, &Header, sizeof(Header)) == GE_FALSE)
00332 return NULL;
00333
00334 if (!((Header.Signature == VFSFILEHEADER_SIGNATURE) || (Header.Signature == VCFSFILEHEADER_SIGNATURE)))
00335 return NULL;
00336
00337 if (Header.Version != HEADER_VERSION)
00338 return NULL;
00339
00340 if (Header.Dispersed == GE_TRUE)
00341 {
00342 assert(!"Not implemented");
00343 return NULL;
00344 }
00345
00346
00347 if (geVFile_Seek(RWOps, Header.DirectoryOffset, GE_VFILE_SEEKSET) == GE_FALSE)
00348 return NULL;
00349
00350
00351 if (geVFile_Tell(RWOps, &DirectoryStartPos) == GE_FALSE)
00352 return NULL;
00353
00354 NewFS = geRam_Allocate(sizeof(*NewFS));
00355 if (!NewFS)
00356 return NewFS;
00357 memset(NewFS, 0, sizeof(*NewFS));
00358
00359 NewFS->RWOps = RWOps;
00360 NewFS->RWOpsStartPos = RWOpsStartPos;
00361 NewFS->DataLength = Header.DataLength;
00362 NewFS->EndPosition = Header.EndPosition;
00363 NewFS->Mask = Mask;
00364
00365
00366 NewFS->Directory = DirTree_CreateFromFile(RWOps);
00367 if (!NewFS->Directory)
00368 {
00369 geRam_Free(NewFS);
00370 return NULL;
00371 }
00372
00373
00374 if (geVFile_Tell(RWOps, &DirectoryEndPos) == GE_FALSE)
00375 {
00376 DirTree_Destroy(NewFS->Directory);
00377 geRam_Free(NewFS);
00378 return NULL;
00379 }
00380 }
00381 else
00382 {
00383 NewFS = geRam_Allocate(sizeof(*NewFS));
00384 if (!NewFS)
00385 return NewFS;
00386 memset(NewFS, 0, sizeof(*NewFS));
00387
00388 NewFS->RWOps = RWOps;
00389 NewFS->RWOpsStartPos = RWOpsStartPos;
00390 NewFS->Directory = DirTree_Create();
00391 NewFS->DataLength = sizeof(VFSFileHeader);
00392 NewFS->Mask = Mask;
00393 }
00394
00395 NewFS->Signature = VFSFILE_SIGNATURE;
00396 NewFS->IsSystem = GE_TRUE;
00397 NewFS->System = NewFS;
00398 NewFS->OpenModeFlags = OpenModeFlags;
00399
00400 return NewFS;
00401 }
00402
00403 static geBoolean GENESISCC FSVFS_UpdateContext(
00404 geVFile * FS,
00405 void * Handle,
00406 void * Context,
00407 int ContextSize)
00408 {
00409 return GE_FALSE;
00410 }
00411
00412 static void GENESISCC FSVFS_Close(void *Handle)
00413 {
00414 VFSFile * File;
00415
00416 File = Handle;
00417
00418 CHECK_HANDLE(File);
00419
00420 if (File->Directory)
00421 {
00422 if (File->IsSystem == GE_TRUE)
00423 {
00424
00425 assert(File == File->System);
00426
00427 if (File->OpenModeFlags & (GE_VFILE_OPEN_CREATE | GE_VFILE_OPEN_UPDATE))
00428 {
00429 VFSFileHeader Header;
00430 long EndPosition;
00431
00432
00433 if (geVFile_Seek(File->RWOps, File->RWOpsStartPos + File->DataLength, GE_VFILE_SEEKSET) == GE_FALSE)
00434 {
00435
00436 assert(!"Can't fail");
00437 }
00438 if (DirTree_WriteToFile(File->Directory, File->RWOps) == GE_FALSE)
00439 {
00440
00441 assert(!"Can't fail");
00442 }
00443 geVFile_Tell(File->RWOps, &EndPosition);
00444 if (geVFile_Seek(File->RWOps, File->RWOpsStartPos, GE_VFILE_SEEKSET) == GE_FALSE)
00445 {
00446
00447 assert(!"Can't fail");
00448 }
00449 if(File->Mask==0)
00450 Header.Signature = VFSFILEHEADER_SIGNATURE;
00451 else
00452 Header.Signature = VCFSFILEHEADER_SIGNATURE;
00453 Header.Version = HEADER_VERSION;
00454 Header.Dispersed = GE_FALSE;
00455 Header.EndPosition = EndPosition;
00456
00457 Header.DirectoryOffset = File->RWOpsStartPos + File->DataLength;
00458 Header.DataLength = File->DataLength;
00459 if (geVFile_Write(File->RWOps, &Header, sizeof(Header)) == GE_FALSE)
00460 {
00461
00462 assert(!"Can't fail");
00463 }
00464
00465
00466 geVFile_Seek(File->RWOps, EndPosition, GE_VFILE_SEEKSET);
00467 }
00468 else
00469 {
00470
00471
00472
00473 geVFile_Seek(File->RWOps, File->EndPosition, GE_VFILE_SEEKSET);
00474 }
00475
00476 DirTree_Destroy(File->Directory);
00477 }
00478 }
00479 else
00480 {
00481
00482
00483 assert(File->System);
00484 File->System->DataLength += File->Length;
00485 DirTree_SetFileSize(File->DirEntry, File->Length);
00486 }
00487
00488 geRam_Free(File);
00489 }
00490
00491 static geBoolean GENESISCC ForceFilePos(VFSFile *File)
00492 {
00493 assert(File);
00494 assert(File->RWOps);
00495 assert(!File->Directory);
00496
00497 assert(File->CurrentRelPos >= 0);
00498 assert(File->CurrentRelPos <= File->Length);
00499
00500 return geVFile_Seek(File->RWOps,
00501 File->RWOpsStartPos + File->CurrentRelPos,
00502 GE_VFILE_SEEKSET);
00503 }
00504
00505 static int ClampOperationSize(const VFSFile *File, int Size)
00506 {
00507 assert(!File->Directory);
00508 assert(File->CurrentRelPos >= 0);
00509 return min(File->Length - File->CurrentRelPos, Size);
00510 }
00511
00512 static void GENESISCC UpdateFilePos(VFSFile *File)
00513 {
00514 long RWOpsPos;
00515
00516 assert(!File->Directory);
00517 assert(File->CurrentRelPos >= 0);
00518
00519 geVFile_Tell(File->RWOps, &RWOpsPos);
00520
00521 File->CurrentRelPos = RWOpsPos - File->RWOpsStartPos;
00522 if (File->CurrentRelPos > File->Length)
00523 File->Length = File->CurrentRelPos;
00524
00525 assert(File->CurrentRelPos >= 0);
00526 }
00527
00528 static geBoolean GENESISCC FSVFS_GetS(void *Handle, void *Buff, int MaxLen)
00529 {
00530 VFSFile * File;
00531 geBoolean Res;
00532
00533 assert(Buff);
00534 assert(MaxLen != 0);
00535
00536 File = Handle;
00537
00538 CHECK_HANDLE(File);
00539
00540 if (File->Directory)
00541 return GE_FALSE;
00542
00543 assert(File->CurrentRelPos >= 0);
00544 assert(File->CurrentRelPos <= File->Length);
00545
00546 if (!ForceFilePos(File))
00547 return GE_FALSE;
00548
00549 MaxLen = ClampOperationSize(File, MaxLen);
00550
00551 Res = geVFile_GetS(File->RWOps, Buff, MaxLen);
00552
00553 UpdateFilePos(File);
00554
00555 return Res;
00556 }
00557
00558 static geBoolean GENESISCC FSVFS_Read(void *Handle, void *Buff, int Count)
00559 {
00560 VFSFile * File;
00561 geBoolean Res;
00562 int i;
00563 char Bbyte;
00564 char *TBuffer;
00565
00566 #ifndef NDEBUG
00567 int CurRelPos;
00568 #endif
00569
00570 assert(Buff);
00571 assert(Count != 0);
00572
00573 File = Handle;
00574
00575 CHECK_HANDLE(File);
00576
00577 if (File->Directory)
00578 return GE_FALSE;
00579
00580 assert(File->CurrentRelPos >= 0);
00581 assert(File->CurrentRelPos <= File->Length);
00582
00583 if (!ForceFilePos(File))
00584 return GE_FALSE;
00585
00586 if (ClampOperationSize(File, Count) != Count)
00587 return GE_FALSE;
00588
00589 #ifndef NDEBUG
00590 CurRelPos = File->CurrentRelPos;
00591 #endif
00592 Res = geVFile_Read(File->RWOps, Buff, Count);
00593 TBuffer = Buff;
00594 for(i=0;i<Count;i++)
00595 {
00596 memcpy(&Bbyte, (TBuffer+i),1);
00597 Bbyte ^=File->Mask;
00598 memcpy((TBuffer+i),&Bbyte,1);
00599 }
00600
00601 UpdateFilePos(File);
00602 assert(File->CurrentRelPos - CurRelPos == Count);
00603
00604 return Res;
00605 }
00606
00607 static geBoolean GENESISCC FSVFS_Write(void *Handle, const void *Buff, int Count)
00608 {
00609 VFSFile * File;
00610 geBoolean Res;
00611 int i;
00612 char Bbyte;
00613 char *TBuffer;
00614
00615 #ifndef NDEBUG
00616 int CurRelPos;
00617 #endif
00618
00619 assert(Buff);
00620 assert(Count != 0);
00621
00622 File = Handle;
00623
00624 CHECK_HANDLE(File);
00625
00626 if (File->Directory)
00627 return GE_FALSE;
00628
00629 if (File->OpenModeFlags & GE_VFILE_OPEN_READONLY)
00630 return GE_FALSE;
00631
00632 assert(File->CurrentRelPos >= 0);
00633 assert(File->CurrentRelPos <= File->Length);
00634
00635 if (!ForceFilePos(File))
00636 return GE_FALSE;
00637
00638 #ifndef NDEBUG
00639 CurRelPos = File->CurrentRelPos;
00640 #endif
00641 TBuffer = (char *)Buff;
00642 for(i=0;i<Count;i++)
00643 {
00644 memcpy(&Bbyte, (TBuffer+i),1);
00645 Bbyte ^=File->Mask;
00646 memcpy((TBuffer+i),&Bbyte,1);
00647 }
00648 Res = geVFile_Write(File->RWOps, Buff, Count);
00649
00650 UpdateFilePos(File);
00651 assert(File->CurrentRelPos - CurRelPos == Count);
00652
00653 return Res;
00654 }
00655
00656 static geBoolean GENESISCC FSVFS_Seek(void *Handle, int Where, geVFile_Whence Whence)
00657 {
00658 VFSFile * File;
00659 geBoolean Res;
00660 long AbsolutePos=0;
00661
00662 File = Handle;
00663
00664 CHECK_HANDLE(File);
00665
00666 if (File->Directory)
00667 return GE_FALSE;
00668
00669 assert(File->CurrentRelPos >= 0);
00670 assert(File->CurrentRelPos <= File->Length);
00671
00672 switch (Whence)
00673 {
00674 case GE_VFILE_SEEKSET:
00675 AbsolutePos = File->RWOpsStartPos + Where;
00676 break;
00677
00678 case GE_VFILE_SEEKEND:
00679 AbsolutePos = File->RWOpsStartPos + File->Length - Where;
00680 break;
00681
00682 case GE_VFILE_SEEKCUR:
00683 AbsolutePos = File->RWOpsStartPos + File->CurrentRelPos + Where;
00684 break;
00685
00686 default:
00687 assert(!"Illegal seek case");
00688 }
00689
00690 if (AbsolutePos < File->RWOpsStartPos)
00691 return GE_FALSE;
00692
00693 Res = geVFile_Seek(File->RWOps, AbsolutePos, GE_VFILE_SEEKSET);
00694
00695 UpdateFilePos(File);
00696
00697 return Res;
00698 }
00699
00700 static geBoolean GENESISCC FSVFS_EOF(const void *Handle)
00701 {
00702 const VFSFile * File;
00703
00704 File = Handle;
00705
00706 CHECK_HANDLE(File);
00707
00708 if (File->Directory)
00709 return GE_FALSE;
00710
00711 assert(File->CurrentRelPos >= 0);
00712 assert(File->CurrentRelPos <= File->Length);
00713
00714 if (File->CurrentRelPos == File->Length)
00715 return GE_TRUE;
00716
00717 return GE_FALSE;
00718 }
00719
00720 static geBoolean GENESISCC FSVFS_Tell(const void *Handle, long *Position)
00721 {
00722 const VFSFile * File;
00723
00724 File = Handle;
00725
00726 CHECK_HANDLE(File);
00727
00728 if (File->Directory)
00729 return GE_FALSE;
00730
00731 assert(File->CurrentRelPos >= 0);
00732 assert(File->CurrentRelPos <= File->Length);
00733
00734 *Position = File->CurrentRelPos;
00735
00736 return GE_TRUE;
00737 }
00738
00739 static geBoolean GENESISCC FSVFS_Size(const void *Handle, long *Size)
00740 {
00741 const VFSFile * File;
00742
00743 File = Handle;
00744
00745 CHECK_HANDLE(File);
00746
00747 if (File->Directory != NULL)
00748 return GE_FALSE;
00749
00750 assert(File->CurrentRelPos >= 0);
00751 assert(File->CurrentRelPos <= File->Length);
00752
00753 *Size = File->Length;
00754
00755 return GE_TRUE;
00756 }
00757
00758 static geBoolean GENESISCC FSVFS_GetProperties(const void *Handle, geVFile_Properties *Properties)
00759 {
00760 const VFSFile * File;
00761
00762 File = Handle;
00763
00764 CHECK_HANDLE(File);
00765
00766 assert(File->DirEntry);
00767
00768 DirTree_GetFileTime(File->DirEntry, &Properties->Time);
00769 DirTree_GetFileAttributes(File->DirEntry, &Properties->AttributeFlags);
00770 DirTree_GetFileSize(File->DirEntry, &Properties->Size);
00771 DirTree_GetFileHints(File->DirEntry, &Properties->Hints);
00772 return DirTree_GetName(File->DirEntry, &Properties->Name[0], sizeof(Properties->Name));
00773 }
00774
00775 static geBoolean GENESISCC FSVFS_SetSize(void *Handle, long Size)
00776 {
00777 assert(!"Not implemented");
00778 return GE_FALSE;
00779 }
00780
00781 static geBoolean GENESISCC FSVFS_SetAttributes(void *Handle, geVFile_Attributes Attributes)
00782 {
00783 const VFSFile * File;
00784
00785 File = Handle;
00786
00787 CHECK_HANDLE(File);
00788
00789 assert(File->DirEntry);
00790
00791 if (Attributes & ~GE_VFILE_ATTRIB_READONLY)
00792 return GE_FALSE;
00793
00794 DirTree_SetFileAttributes(File->DirEntry, Attributes);
00795
00796 return GE_TRUE;
00797 }
00798
00799 static geBoolean GENESISCC FSVFS_SetTime(void *Handle, const geVFile_Time *Time)
00800 {
00801 const VFSFile * File;
00802
00803 File = Handle;
00804
00805 CHECK_HANDLE(File);
00806
00807 assert(File->DirEntry);
00808
00809 DirTree_SetFileTime(File->DirEntry, Time);
00810
00811 return GE_FALSE;
00812 }
00813
00814 static geBoolean GENESISCC FSVFS_SetHints(void *Handle, const geVFile_Hints *Hints)
00815 {
00816 const VFSFile * File;
00817
00818 File = Handle;
00819
00820 CHECK_HANDLE(File);
00821
00822 assert(File->DirEntry);
00823
00824 return DirTree_SetFileHints(File->DirEntry, Hints);
00825 }
00826
00827 static geBoolean GENESISCC FSVFS_FileExists(geVFile *FS, void *Handle, const char *Name)
00828 {
00829 VFSFile * File;
00830
00831 File = Handle;
00832
00833 CHECK_HANDLE(File);
00834
00835 if (!File->Directory)
00836 return GE_FALSE;
00837
00838 return DirTree_FileExists(File->Directory, Name);
00839 }
00840
00841 static geBoolean GENESISCC FSVFS_Disperse(
00842 geVFile * FS,
00843 void * Handle,
00844 const char *Directory,
00845 geBoolean Recursive)
00846 {
00847 assert(!"Not implemented");
00848 return GE_FALSE;
00849 }
00850
00851 static geBoolean GENESISCC FSVFS_DeleteFile(geVFile *FS, void *Handle, const char *Name)
00852 {
00853 assert(!"Not implemented");
00854 return GE_FALSE;
00855 }
00856
00857 static geBoolean GENESISCC FSVFS_RenameFile(geVFile *FS, void *Handle, const char *Name, const char *NewName)
00858 {
00859 assert(!"Not implemented");
00860 return GE_FALSE;
00861 }
00862
00863 static geVFile_SystemAPIs FSVFS_APIs =
00864 {
00865 FSVFS_FinderCreate,
00866 FSVFS_FinderGetNextFile,
00867 FSVFS_FinderGetProperties,
00868 FSVFS_FinderDestroy,
00869
00870 FSVFS_OpenNewSystem,
00871 FSVFS_UpdateContext,
00872 FSVFS_Open,
00873 FSVFS_DeleteFile,
00874 FSVFS_RenameFile,
00875 FSVFS_FileExists,
00876 FSVFS_Disperse,
00877 FSVFS_Close,
00878
00879 FSVFS_GetS,
00880 FSVFS_Read,
00881 FSVFS_Write,
00882 FSVFS_Seek,
00883 FSVFS_EOF,
00884 FSVFS_Tell,
00885 FSVFS_Size,
00886
00887 FSVFS_GetProperties,
00888
00889 FSVFS_SetSize,
00890 FSVFS_SetAttributes,
00891 FSVFS_SetTime,
00892 FSVFS_SetHints,
00893 };
00894
00895 const geVFile_SystemAPIs * GENESISCC FSVFS_GetAPIs(void)
00896 {
00897 return &FSVFS_APIs;
00898 }
00899