1 #include <iostream>
2 #include <pthread.h>
3 #include <stdlib.h>
4 #include <stdio.h>
5 #include <sstream>
6 #include <stdarg.h>
7 #include "string.h"
8 #include "rartypes.hpp"
9 #include "rardefs.hpp"
10 #include "system.hpp"
11 #include "timefn.hpp"
12 #include "errhnd.hpp"
13 #include "strfn.hpp"
14 #include "os.hpp"
15 #include "array.hpp"
16 #include "global.hpp"
17
18 #include "file.hpp"
19
20 static const File *CreatedFiles[256];
21 //char *_i64toa( int64 value, char *string, int radix );
22 /**
23 File constructor - After this is called, one <b>must</b> call the <code>InitFile(...)</code> function
24 */
File()25 File::File() :
26 ptrlocation(), initptrlocation(), ptrlength(), hFile(), LastWrite(),
27 HandleType(), SkipClose(), IgnoreReadErrors(), NewFile(), AllowDelete(),
28 AllowExceptions(), OpenShared(), ErrorType(), CloseCount()
29 { //Constructor
30 hFile=BAD_HANDLE;
31 *FileName=0;
32 *FileNameW=0;
33 NewFile=false;
34 LastWrite=false;
35 HandleType=FILE_HANDLENORMAL;
36 SkipClose=false;
37 IgnoreReadErrors=false;
38 ErrorType=FILE_SUCCESS;
39 OpenShared=false;
40 AllowDelete=true;
41 CloseCount=0;
42 AllowExceptions=true;
43 initptrlocation = 0; //set the pointer location to null. The Init function will set this.
44 ptrlocation = 0; //set the pointer location to null. The Init function will set this.
45 #ifdef _WIN_ALL
46 NoSequentialRead=false;
47 #endif
48 }
49
File(const File & copy)50 File::File(const File ©) :
51 ptrlocation(), initptrlocation(), ptrlength(), hFile(), LastWrite(),
52 HandleType(), SkipClose(), IgnoreReadErrors(), NewFile(), AllowDelete(),
53 AllowExceptions(), OpenShared(), ErrorType(), CloseCount()
54 {
55 *this = copy;
56 }
57
58
~File()59 File::~File()
60 {//Destructor class
61 if (hFile!=BAD_HANDLE && !SkipClose)
62 {
63 if (NewFile)
64 {
65 Delete();
66 }
67 else
68 {
69 Close();
70 }
71 }
72 }
73
74 /**
75 This function initializes the file class to read information from memory.
76
77 @param ptr - a pointer to the location in memory where the RAR file lives
78 @param length - The length of the location in memory where the RAR file lives
79 */
InitFile(void * ptr,int64 length)80 void File::InitFile(void* ptr, int64 length)
81 {//initialize the data to point to the RAR pointer in memory
82 //set the pointer to the right place so we can read from it later on.
83 //also, store the initial location in case we have to go back there later on.
84 initptrlocation = (byte*)ptr; //initialize the initial pointer location
85 ptrlocation = (byte*)ptr; //initialize the current pointer location
86 ptrlength = length; //set the length of the file
87 return;
88 }
89
90 /**
91 This function is not called in bulk_extractor
92 */
operator =(const File & SrcFile)93 const File& File::operator=(const File &SrcFile)
94 {//This is not called in bulk_extractor
95 hFile=SrcFile.hFile;
96 strcpy(FileName,SrcFile.FileName);
97 NewFile=SrcFile.NewFile;
98 LastWrite=SrcFile.LastWrite;
99 HandleType=SrcFile.HandleType;
100 //SrcFile.SkipClose=true;
101 initptrlocation = SrcFile.initptrlocation; //save the initial ptr location
102 ptrlocation = SrcFile.ptrlocation; //save the ptr location
103
104 return *this;
105 }
106
107
Open(const char * Name,const wchar * NameW,bool OpenShared_,bool Update)108 bool File::Open(const char *Name,const wchar *NameW,bool OpenShared_,bool Update)
109 { //This function does nothing. It simply complies with the File class.
110 //This class should utilize the Init(void* ptr) function to open a file.
111 //hFile = hNewFile;
112 return true;
113 /* ErrorType=FILE_SUCCESS;
114 FileHandle hNewFile;
115 if (BenFile::OpenShared_)
116 OpenShared_=true;
117 #ifdef _WIN_ALL
118 uint Access=GENERIC_READ;
119 if (Update)
120 Access|=GENERIC_WRITE;
121 uint ShareMode=FILE_SHARE_READ;
122 if (OpenShared_)
123 ShareMode|=FILE_SHARE_WRITE;
124 uint Flags=NoSequentialRead ? 0:FILE_FLAG_SEQUENTIAL_SCAN;
125 if (WinNT() && NameW!=NULL && *NameW!=0)
126 hNewFile=CreateFileW(NameW,Access,ShareMode,NULL,OPEN_EXISTING,Flags,NULL);
127 else
128 hNewFile=CreateFileA(Name,Access,ShareMode,NULL,OPEN_EXISTING,Flags,NULL);
129
130 if (hNewFile==BAD_HANDLE && GetLastError()==ERROR_FILE_NOT_FOUND)
131 ErrorType=FILE_NOTFOUND;
132 #else
133 int flags=Update ? O_RDWR:O_RDONLY;
134 #ifdef O_BINARY
135 flags|=O_BINARY;
136 #if defined(_AIX) && defined(_LARGE_FILE_API)
137 flags|=O_LARGEFILE;
138 #endif
139 #endif
140 #if defined(_EMX) && !defined(_DJGPP)
141 int sflags=OpenShared_ ? SH_DENYNO:SH_DENYWR;
142 int handle=sopen(Name,flags,sflags);
143 #else
144 int handle=open(Name,flags);
145 #ifdef LOCK_EX
146
147 #ifdef _OSF_SOURCE
148 extern "C" int flock(int, int);
149 #endif
150
151 if (!OpenShared_ && Update && handle>=0 && flock(handle,LOCK_EX|LOCK_NB)==-1)
152 {
153 close(handle);
154 return(false);
155 }
156 #endif
157 #endif
158 hNewFile=handle==-1 ? BAD_HANDLE:fdopen(handle,Update ? UPDATEBINARY:READBINARY);
159 if (hNewFile==BAD_HANDLE && errno==ENOENT)
160 ErrorType=FILE_NOTFOUND;
161 #endif
162 NewFile=false;
163 HandleType=FILE_HANDLENORMAL;
164 SkipClose=false;
165 bool Success=hNewFile!=BAD_HANDLE;
166 if (Success)
167 {
168 hFile=hNewFile;
169
170 // We use memove instead of strcpy and wcscpy to avoid problems
171 // with overlapped buffers. While we do not call this function with
172 // really overlapped buffers yet, we do call it with Name equal to
173 // FileName like Arc.Open(Arc.FileName,Arc.FileNameW).
174 if (NameW!=NULL)
175 memmove(FileNameW,NameW,(wcslen(NameW)+1)*sizeof(*NameW));
176 else
177 *FileNameW=0;
178 if (Name!=NULL)
179 memmove(FileName,Name,strlen(Name)+1);
180 else
181 WideToChar(NameW,FileName);
182 AddFileToList(hFile);
183 }
184 return(Success);*/
185 }
186
187
188 #if !defined(SHELL_EXT) && !defined(SFX_MODULE)
189 /**
190 This function is not called in bulk_extractor
191 */
TOpen(const char * Name,const wchar * NameW)192 void File::TOpen(const char *Name,const wchar *NameW)
193 { //Nothing to do for this function
194 if (!WOpen(Name,NameW))
195 ErrHandler.Exit(OPEN_ERROR);
196 }
197 #endif
198
199 /**
200 This function does nothing. It simply complies with the <code>File</code> class.
201 */
WOpen(const char * Name,const wchar * NameW)202 bool File::WOpen(const char *Name,const wchar *NameW)
203 { //This class should utilize the Init(void* ptr) function to open a file.
204 bool result = true;
205 if(ptrlocation == NULL || ptrlength == 0)
206 result = false;
207 // else
208 // hFile = FileHandle.;
209 return result;
210 /* if (Open(Name,NameW))
211 return(true);
212 ErrHandler.OpenErrorMsg(Name,NameW);
213 return(false);*/
214 }
215
216 /**
217 This function does nothing. It simply complies with the File class.
218 */
Create(const char * Name,const wchar * NameW,bool ShareRead)219 bool File::Create(const char *Name,const wchar *NameW,bool ShareRead)
220 {
221 return true;
222 /*
223 #ifdef _WIN_ALL
224 DWORD ShareMode=(ShareRead || BenFile::OpenShared) ? FILE_SHARE_READ:0;
225 if (WinNT() && NameW!=NULL && *NameW!=0)
226 hFile=CreateFileW(NameW,GENERIC_READ|GENERIC_WRITE,ShareMode,NULL,
227 CREATE_ALWAYS,0,NULL);
228 else
229 hFile=CreateFileA(Name,GENERIC_READ|GENERIC_WRITE,ShareMode,NULL,
230 CREATE_ALWAYS,0,NULL);
231 #else
232 hFile=fopen(Name,CREATEBINARY);
233 #endif
234 NewFile=true;
235 HandleType=FILE_HANDLENORMAL;
236 SkipClose=false;
237 if (NameW!=NULL)
238 wcscpy(FileNameW,NameW);
239 else
240 *FileNameW=0;
241 if (Name!=NULL)
242 strcpy(FileName,Name);
243 else
244 WideToChar(NameW,FileName);
245 AddFileToList(hFile);
246 return(hFile!=BAD_HANDLE);*/
247 }
248
249 /**
250 This is not called in bulk_extractor
251 */
AddFileToList(FileHandle hFile_)252 void File::AddFileToList(FileHandle hFile_)
253 {
254 if (hFile_!=BAD_HANDLE)
255 for (unsigned I=0;I<sizeof(CreatedFiles)/sizeof(CreatedFiles[0]);I++)
256 if (CreatedFiles[I]==NULL)
257 {
258 CreatedFiles[I]=this;
259 break;
260 }
261 }
262
263
264 #if !defined(SHELL_EXT) && !defined(SFX_MODULE)
265 /**
266 This is not called in bulk_extractor
267 */
TCreate(const char * Name,const wchar * NameW,bool ShareRead)268 void File::TCreate(const char *Name,const wchar *NameW,bool ShareRead)
269 {
270 if (!WCreate(Name,NameW,ShareRead))
271 ErrHandler.Exit(FATAL_ERROR);
272 }
273 #endif
274
275 /**
276 This is not called in bulk_extractor
277 */
WCreate(const char * Name,const wchar * NameW,bool ShareRead)278 bool File::WCreate(const char *Name,const wchar *NameW,bool ShareRead)
279 {
280 if (Create(Name,NameW,ShareRead))
281 return(true);
282 ErrHandler.SetErrorCode(CREATE_ERROR);
283 ErrHandler.CreateErrorMsg(Name,NameW);
284 return(false);
285 }
286
287 /**
288 This function does nothing. It simply complies with the File class.
289 */
Close()290 bool File::Close()
291 {
292 ptrlocation = initptrlocation; //reset Pointer location to the initial spot
293 return true;
294 /*bool Success=true;
295 if (HandleType!=FILE_HANDLENORMAL)
296 HandleType=FILE_HANDLENORMAL;
297 else
298 if (hFile!=BAD_HANDLE)
299 {
300 if (!SkipClose)
301 {
302 #ifdef _WIN_ALL
303 Success=CloseHandle(hFile)==TRUE;
304 #else
305 Success=fclose(hFile)!=EOF;
306 #endif
307 if (Success || !RemoveCreatedActive)
308 for (int I=0;I<sizeof(CreatedFiles)/sizeof(CreatedFiles[0]);I++)
309 if (CreatedFiles[I]==this)
310 {
311 CreatedFiles[I]=NULL;
312 break;
313 }
314 }
315 hFile=BAD_HANDLE;
316 if (!Success && AllowExceptions)
317 ErrHandler.CloseError(FileName,FileNameW);
318 }
319 CloseCount++;
320 return(Success);*/
321 }
322
323 /**
324 This is not called in bulk_extractor.
325 */
Flush()326 void File::Flush()
327 {
328 #ifdef _WIN_ALL
329 FlushFileBuffers(hFile);
330 #else
331 fflush(hFile);
332 #endif
333 }
334
335 /**
336 This is not called in bulk_extractor.
337 */
Delete()338 bool File::Delete()
339 {
340 if (HandleType!=FILE_HANDLENORMAL)
341 return(false);
342 if (hFile!=BAD_HANDLE)
343 Close();
344 if (!AllowDelete)
345 return(false);
346 return(DelFile(FileName,FileNameW));
347 }
348
349 /**
350 This function should never be called since the file name should never be changed
351 */
Rename(const char * NewName,const wchar * NewNameW)352 bool File::Rename(const char *NewName,const wchar *NewNameW)
353 {
354 // we do not need to rename if names are already same
355 bool Success=strcmp(FileName,NewName)==0;
356 if (Success && *FileNameW!=0 && *NullToEmpty(NewNameW)!=0)
357 Success=wcscmp(FileNameW,NewNameW)==0;
358
359 if (!Success)
360 Success=RenameFile(FileName,FileNameW,NewName,NewNameW);
361
362 if (Success)
363 {
364 // renamed successfully, storing the new name
365 strcpy(FileName,NewName);
366 wcscpy(FileNameW,NullToEmpty(NewNameW));
367 }
368 return(Success);
369 }
370
371 /**
372 This is not called in bulk_extractor
373 */
Write(const void * Data,size_t Size)374 void File::Write(const void *Data,size_t Size)
375 { //This is not called in bulk_extractor
376 if (Size==0)
377 return;
378 #ifndef _WIN_CE
379 if (HandleType!=FILE_HANDLENORMAL)
380 switch(HandleType)
381 {
382 case FILE_HANDLESTD:
383 #ifdef _WIN_ALL
384 hFile=GetStdHandle(STD_OUTPUT_HANDLE);
385 #else
386 hFile=stdout;
387 #endif
388 break;
389 case FILE_HANDLEERR:
390 #ifdef _WIN_ALL
391 hFile=GetStdHandle(STD_ERROR_HANDLE);
392 #else
393 hFile=stderr;
394 #endif
395 break;
396 default:
397 break;
398 }
399 #endif
400 while (1)
401 {
402 bool Success=false;
403 #ifdef _WIN_ALL
404 DWORD Written=0;
405 if (HandleType!=FILE_HANDLENORMAL)
406 {
407 // writing to stdout can fail in old Windows if data block is too large
408 const size_t MaxSize=0x4000;
409 for (size_t I=0;I<Size;I+=MaxSize)
410 {
411 Success=WriteFile(hFile,(byte *)Data+I,(DWORD)Min(Size-I,MaxSize),&Written,NULL)==TRUE; //Writing happens here
412 if (!Success)
413 break;
414 }
415 }
416 else
417 Success=WriteFile(hFile,Data,(DWORD)Size,&Written,NULL)==TRUE;
418 #else
419 size_t Written=fwrite(Data,1,Size,hFile);
420 Success=Written==Size && !ferror(hFile);
421 #endif
422 if (!Success && AllowExceptions && HandleType==FILE_HANDLENORMAL)
423 {
424 #if defined(_WIN_ALL) && !defined(SFX_MODULE) && !defined(RARDLL)
425 int ErrCode=GetLastError();
426 int64 FilePos=Tell();
427 uint64 FreeSize=GetFreeDisk(FileName);
428 SetLastError(ErrCode);
429 if (FreeSize>Size && FilePos-Size<=0xffffffff && FilePos+Size>0xffffffff)
430 ErrHandler.WriteErrorFAT(FileName,FileNameW);
431 #endif
432 if (ErrHandler.AskRepeatWrite(FileName,FileNameW,false))
433 {
434 #ifndef _WIN_ALL
435 clearerr(hFile);
436 #endif
437 if (Written<Size && Written>0)
438 Seek(Tell()-Written,SEEK_SET);
439 continue;
440 }
441 ErrHandler.WriteError(NULL,NULL,FileName,FileNameW);
442 }
443 break;
444 }
445 LastWrite=true;
446 }
447
448 /**
449 Read data from memory of size <code>Size</code>. Calls the <code>DirectRead(Data,Size)</code> function.
450 @param Data - a pointer to the memory location of the RAR file to be extracted
451 @param Size - the length, in bytes, of the <code>Data</code> variable
452 @return the size that was read from the memory location
453 */
Read(void * Data,size_t Size)454 int File::Read(void *Data,size_t Size)
455 { //Read data from memory of size 'Size'
456
457 //call directRead
458 int readsize = DirectRead(Data, Size);
459
460 return readsize;
461
462 /*int64 FilePos=0; // Initialized only to suppress some compilers warning.
463
464 if (IgnoreReadErrors)
465 FilePos=Tell();
466 int ReadSize;
467 while (true)
468 {
469 ReadSize=DirectRead(Data,Size);
470 if (ReadSize==-1)
471 {
472 ErrorType=FILE_READERROR;
473 if (AllowExceptions)
474 if (IgnoreReadErrors)
475 {
476 ReadSize=0;
477 for (size_t I=0;I<Size;I+=512)
478 {
479 Seek(FilePos+I,SEEK_SET);
480 size_t SizeToRead=Min(Size-I,512);
481 int ReadCode=DirectRead(Data,SizeToRead);
482 ReadSize+=(ReadCode==-1) ? 512:ReadCode;
483 }
484 }
485 else
486 {
487 if (HandleType==FILE_HANDLENORMAL && ErrHandler.AskRepeatRead(FileName,FileNameW))
488 continue;
489 ErrHandler.ReadError(FileName,FileNameW);
490 }
491 }
492 break;
493 }
494 return(ReadSize);*/
495 }
496
497 /**
498 Read data from memory of size <code>Size</code>. Calls the <code>DirectRead(Data,Size)</code> function.
499 @param Data - a pointer to the memory location of the RAR file to be extracted
500 @param Size - the length, in bytes, of the <code>Data</code> variable
501 @return the size that was read from the memory location
502 */
DirectRead(void * Data,size_t Size)503 int File::DirectRead(void *Data,size_t Size)
504 { //Calls DirectRead function
505 return DirectRead((byte*)Data, Size);
506 }
507
508
509 /**
510 Read data from memory of size <code>Size</code>. Calls the <code>DirectRead(Data,Size)</code> function.
511 @param Data - a pointer to the memory location of the RAR file to be extracted
512 @param Size - the length, in bytes, of the <code>Data</code> variable
513 @return the size that was read from the memory location. If a '-1' is returned, an error has occurred.
514 */
DirectRead(byte * Data,size_t Size)515 int File::DirectRead(byte *Data,size_t Size)
516 { //Reads from memory the size as spcified by 'Size'
517
518 //read the amount of information from memory
519 //set the pointers to the correct location
520 //send off results
521
522 //int result = -1;
523 int result = 0;
524 if(Tell(ptrlocation + Size) <= ptrlength)
525 { //verifies that we will be in bounds
526 result = Size;
527 memcpy(Data, ptrlocation, Size);
528
529
530 ptrlocation += Size; //adjust the pointer location
531
532 //Tell(); //for debugging purposes
533 /*for(int i = 0; i < result; i++)
534 {
535 Data = ptrlocation;
536 Data++;
537 ptrlocation++;
538 }*/
539 }
540
541
542 return result;
543
544 /*
545 #ifdef _WIN_ALL
546 const size_t MaxDeviceRead=20000;
547 #endif
548 #ifndef _WIN_CE
549 if (HandleType==FILE_HANDLESTD)
550 {
551 #ifdef _WIN_ALL
552 if (Size>MaxDeviceRead)
553 Size=MaxDeviceRead;
554 hFile=GetStdHandle(STD_INPUT_HANDLE);
555 #else
556 hFile=stdin;
557 #endif
558 }
559 #endif
560 #ifdef _WIN_ALL
561 DWORD Read;
562 if (!ReadFile(hFile,Data,(DWORD)Size,&Read,NULL))
563 {
564 if (IsDevice() && Size>MaxDeviceRead)
565 return(DirectRead(Data,MaxDeviceRead));
566 if (HandleType==FILE_HANDLESTD && GetLastError()==ERROR_BROKEN_PIPE)
567 return(0);
568 return(-1);
569 }
570 return(Read);
571 #else
572 if (LastWrite)no
573 {
574 fflush(hFile);
575 LastWrite=false;
576 }
577 clearerr(hFile);
578 size_t ReadSize=fread(Data,1,Size,hFile);
579 if (ferror(hFile))
580 return(-1);
581 return((int)ReadSize);
582 #endif*/
583 }
584
585 /**
586 Moves the pointer in the file to a specified location. Calls the <code>RawSeek</code> function.
587 @param Offset - the length from the current position
588 @param Method - the method to move the pointer.
589 If <code>SEEK_SET</code>, move the pointer <code>Offset</code> number of bytes to the new location in memory.
590 If <code>SEEK_END</code>, move the pointer to the end of the file (NOT IMPLEMENTED)
591 If <code>SEEK_CUR</code>, move the pointer (NOT IMPLEMENTED).
592 */
Seek(int64 Offset,int Method)593 void File::Seek(int64 Offset,int Method)
594 { //Calls RawSeek function
595 RawSeek(Offset,Method);
596 /*if (!RawSeek(Offset,Method) && AllowExceptions)
597 ErrHandler.SeekError(FileName,FileNameW);*/
598 }
599
600 /**
601 Moves the pointer in the file to a specified location
602 @param Offset - the length from the current position
603 @param Method - the method to move the pointer.
604 If <code>SEEK_SET</code>, move the pointer <code>Offset</code> number of bytes to the new location in memory.
605 If <code>SEEK_END</code>, move the pointer to the end of the file (NOT IMPLEMENTED)
606 If <code>SEEK_CUR</code>, move the pointer (NOT IMPLEMENTED).
607 */
RawSeek(int64 Offset,int Method)608 bool File::RawSeek(int64 Offset,int Method)
609 { //Seeks file location
610 /* if (hFile==BAD_HANDLE)
611 return(true);*/ //we will assume all is well if we have gone this far.
612
613
614 if(Method == SEEK_SET)
615 {
616 /*if(&ptrlocation + Offset > &initptrlocation + ptrlength)
617 return(false); //we have overun the bounds
618
619 if(&ptrlocation + Offset < &initptrlocation)
620 return(false); //we have overrun the bounds*/
621
622 //ptrlocation = (byte*)Offset;
623
624 bool result = true;
625 byte * tempptrlocation = ptrlocation;
626
627 if(Offset > Tell())
628 {
629 byte newdiff = (byte)Offset - Tell();
630 tempptrlocation += newdiff;
631 //int64 telldebugging = Tell();
632 //int64 telldebugging2 = Tell(tempptrlocation);
633 //ptrlocation += newdiff;
634 if(Tell(tempptrlocation) > ptrlength )
635 {//the new pointer length is farther than the length of the RAR file
636 result = false;
637 }
638 else
639 {// the new pointer length is within range of the length of the RAR file
640 ptrlocation += newdiff;
641 result = true;
642 }
643 }
644 else if(Offset < Tell())
645 {
646 byte newdiff = Tell() - (byte)Offset;
647 tempptrlocation -= newdiff;
648
649 //ptrlocation -= newdiff;
650 if(Tell(tempptrlocation) < Tell(initptrlocation))
651 {//the new pointer length is before the range of the RAR file
652 result = false;
653 }
654 else{//the new pointer is within range of the length of the file
655 ptrlocation -= newdiff;
656 result = true;
657 }
658
659 }
660
661 //Tell(); //debugging function
662 return(result);
663 }
664
665 else if(Method == SEEK_END)
666 {
667 //we should go to the end of the file
668 ptrlocation = initptrlocation; //reset the pointer location to the beginning of the RAR file
669 ptrlocation += ptrlength; //set the pointer to the end of the RAR file
670 return true;
671 }
672 else if(Method == SEEK_CUR)
673 {
674 //we should do something else
675 return false;
676 }
677
678 else
679 {//unknown method...
680 return false;
681 }
682
683 /* if (Offset<0 && Method!=SEEK_SET)
684 {
685 Offset=(Method==SEEK_CUR ? Tell():FileLength())+Offset;
686 Method=SEEK_SET;
687 }
688 #ifdef _WIN_ALL
689 LONG HighDist=(LONG)(Offset>>32);
690 if (SetFilePointer(hFile,(LONG)Offset,&HighDist,Method)==0xffffffff &&
691 GetLastError()!=NO_ERROR)
692 return(false);
693 #else
694 LastWrite=false;
695 #if defined(_LARGEFILE_SOURCE) && !defined(_OSF_SOURCE) && !defined(__VMS)
696 if (fseeko(hFile,Offset,Method)!=0)
697 #else
698 if (fseek(hFile,(long)Offset,Method)!=0)
699 #endif
700 return(false);
701 #endif
702 return(true);*/
703 }
704
705 /**
706 @param ptrlocation - location that should be used to find the offset from the beginning of the file class
707 @return the location of the pointer offset that has been supplied in a <code>int64</code> format.
708 */
Tell(byte * theptrlocation)709 int64 File::Tell(byte* theptrlocation)
710 {
711 return ((int64)theptrlocation - (int64)initptrlocation);
712 }
713
714 /**
715 @return the location of the pointer offset in a <code>int64</code> format.
716 */
Tell()717 int64 File::Tell()
718 {//returns the offset value where the iterator lies
719
720 return ((int64)ptrlocation - (int64)initptrlocation);
721 /* if (hFile==BAD_HANDLE)
722 if (AllowExceptions)
723 ErrHandler.SeekError(FileName,FileNameW);
724 else
725 return(-1);
726 #ifdef _WIN_ALL
727 LONG HighDist=0;
728 uint LowDist=SetFilePointer(hFile,0,&HighDist,FILE_CURRENT);
729 if (LowDist==0xffffffff && GetLastError()!=NO_ERROR)
730 if (AllowExceptions)
731 ErrHandler.SeekError(FileName,FileNameW);
732 else
733 return(-1);
734 return(INT32TO64(HighDist,LowDist));
735 #else
736 #if defined(_LARGEFILE_SOURCE) && !defined(_OSF_SOURCE)
737 return(ftello(hFile));
738 #else
739 return(ftell(hFile));
740 #endif
741 #endif*/
742 }
743
744 /**
745 this is not needed for bulk_extractor
746 */
Prealloc(int64 Size)747 void File::Prealloc(int64 Size)
748 {
749 #ifdef _WIN_ALL
750 if (RawSeek(Size,SEEK_SET))
751 {
752 Truncate();
753 Seek(0,SEEK_SET);
754 }
755 #endif
756
757 #if defined(_UNIX) && defined(USE_FALLOCATE)
758 // fallocate is rather new call. Only latest kernels support it.
759 // So we are not using it by default yet.
760 int fd = fileno(hFile);
761 if (fd >= 0)
762 fallocate(fd, 0, 0, Size);
763 #endif
764 }
765
766 /**
767 Obtain a byte worth of data from the memory space
768 */
GetByte()769 byte File::GetByte()
770 {
771 byte Byte=0;
772 Read(&Byte,1);
773 return(Byte);
774 }
775
776 /**
777 this is not needed for bulk_extractor
778 */
PutByte(byte Byte)779 void File::PutByte(byte Byte)
780 {
781 Write(&Byte,1);
782 }
783
784 /**
785 this is not needed for bulk_extractor
786 */
Truncate()787 bool File::Truncate()
788 {
789 #ifdef _WIN_ALL
790 return(SetEndOfFile(hFile)==TRUE);
791 #else
792 return(false);
793 #endif
794 }
795
796 /**
797 this is not needed for bulk_extractor
798 */
SetOpenFileTime(RarTime * ftm,RarTime * ftc,RarTime * fta)799 void File::SetOpenFileTime(RarTime *ftm,RarTime *ftc,RarTime *fta)
800 { //We probably don't need to worry about this at all
801 #ifdef _WIN_ALL
802 bool sm=ftm!=NULL && ftm->IsSet();
803 bool sc=ftc!=NULL && ftc->IsSet();
804 bool sa=fta!=NULL && fta->IsSet();
805 FILETIME fm,fc,fa;
806 if (sm)
807 ftm->GetWin32(&fm);
808 if (sc)
809 ftc->GetWin32(&fc);
810 if (sa)
811 fta->GetWin32(&fa);
812 SetFileTime(hFile,sc ? &fc:NULL,sa ? &fa:NULL,sm ? &fm:NULL);
813 #endif
814 }
815
816 /**
817 this is not needed for bulk_extractor
818 */
SetCloseFileTime(RarTime * ftm,RarTime * fta)819 void File::SetCloseFileTime(RarTime *ftm,RarTime *fta)
820 { //We probably don't need to worry about this at all.
821 //int i = 1+1;
822 #if defined(_UNIX) || defined(_EMX)
823 SetCloseFileTimeByName(FileName,ftm,fta);
824 #endif
825 }
826
827 /**
828 this is not needed for bulk_extractor
829 */
SetCloseFileTimeByName(const char * Name,RarTime * ftm,RarTime * fta)830 void File::SetCloseFileTimeByName(const char *Name,RarTime *ftm,RarTime *fta)
831 { //We probably don't need to worry about this at all.
832 //int i = 1+1;
833
834 #if defined(_UNIX) || defined(_EMX)
835 bool setm=ftm!=NULL && ftm->IsSet();
836 bool seta=fta!=NULL && fta->IsSet();
837 if (setm || seta)
838 {
839 utimbuf ut;
840 if (setm)
841 ut.modtime=ftm->GetUnix();
842 else
843 ut.modtime=fta->GetUnix();
844 if (seta)
845 ut.actime=fta->GetUnix();
846 else
847 ut.actime=ut.modtime;
848 utime(Name,&ut);
849 }
850 #endif
851 }
852
853 /**
854 this is not needed for bulk_extractor
855 */
GetOpenFileTime(RarTime * ft)856 void File::GetOpenFileTime(RarTime *ft)
857 { //We probably don't need to worry about this at all.
858 #ifdef _WIN_ALL
859 FILETIME FileTime;
860 GetFileTime(hFile,NULL,NULL,&FileTime);
861 *ft=FileTime;
862 #endif
863 #if defined(_UNIX) || defined(_EMX)
864 struct stat st;
865 fstat(fileno(hFile),&st);
866 *ft=st.st_mtime;
867 #endif
868 }
869
870 /**
871 @return the length of the memory, in bytes, that has been allocated for the <code>File</code> class.
872 */
FileLength()873 int64 File::FileLength()
874 { //returns length of file
875 return ptrlength;
876
877 /* SaveFilePos SavePos(*this);
878 Seek(0,SEEK_END);
879 return(Tell());*/
880 //Tell();
881 }
882
883 /**
884 this is not needed for bulk_extractor
885 */
SetHandleType(FILE_HANDLETYPE Type)886 void File::SetHandleType(FILE_HANDLETYPE Type)
887 {
888 HandleType=Type;
889 }
890
891 /**
892 Always returns false as we are never reading from a device
893 */
IsDevice()894 bool File::IsDevice()
895 { //This really doesn't have to be called
896 return false; //No, we are not reading from a device
897 /* if (hFile==BAD_HANDLE)
898 return(false);
899 #ifdef _WIN_ALL
900 uint Type=GetFileType(hFile);
901 return(Type==FILE_TYPE_CHAR || Type==FILE_TYPE_PIPE);
902 #else
903 return(isatty(fileno(hFile)));
904 #endif*/
905 }
906
907
908 #ifndef SFX_MODULE
909 /**
910 this is not needed for bulk_extractor
911 */
fprintf(const char * fmt,...)912 void File::fprintf(const char *fmt,...)
913 { //This function is not called in bulk_extractor
914 va_list argptr;
915 va_start(argptr,fmt);
916 safebuf char Msg[2*NM+1024],OutMsg[2*NM+1024];
917 vsprintf(Msg,fmt,argptr);
918 #ifdef _WIN_ALL
919 for (int Src=0,Dest=0;;Src++)
920 {
921 char CurChar=Msg[Src];
922 if (CurChar=='\n')
923 OutMsg[Dest++]='\r';
924 OutMsg[Dest++]=CurChar;
925 if (CurChar==0)
926 break;
927 }
928 #else
929 strcpy(OutMsg,Msg);
930 #endif
931 Write(OutMsg,strlen(OutMsg));
932 va_end(argptr);
933 }
934 #endif
935
936 /**
937 this is not needed for bulk_extractor
938 */
RemoveCreated()939 bool File::RemoveCreated()
940 { //This file is not called in bulk_extractor
941 return false;
942 }
943
944
945 #ifndef SFX_MODULE
946 /**
947 this is not needed for bulk_extractor
948 */
Copy(File & Dest,int64 Length)949 int64 File::Copy(File &Dest,int64 Length)
950 { //This file is not called in bulk_extractor
951 Array<char> Buffer(0x10000);
952 int64 CopySize=0;
953 bool CopyAll=(Length==INT64NDF);
954
955 while (CopyAll || Length>0)
956 {
957 Wait();
958 size_t SizeToRead=(!CopyAll && Length<(int64)Buffer.Size()) ? (size_t)Length:Buffer.Size();
959 int ReadSize=Read(&Buffer[0],SizeToRead);
960 if (ReadSize==0)
961 break;
962 Dest.Write(&Buffer[0],ReadSize);
963 CopySize+=ReadSize;
964 if (!CopyAll)
965 Length-=ReadSize;
966 }
967 return(CopySize);
968 }
969
970 /**
971 @return the current pointer location as a <code>void*</code> type pointer
972 */
GetPtrLocation()973 void* File::GetPtrLocation()
974 {
975 return ptrlocation;
976 }
977
978 /**
979 @return the initial pointer location when the <code>File</code> object was created
980 */
GetInitPtrLocation()981 void * File::GetInitPtrLocation()
982 {
983 return initptrlocation;
984 }
985
986 #endif
987