unrarsrc  6.1.7
About: unrar extracts, views and tests the contents of archives created with the RAR archiver.
  Fossies Dox: unrarsrc-6.1.7.tar.gz  ("unofficial" and yet experimental doxygen-generated source code documentation)  

filefn.cpp
Go to the documentation of this file.
1#include "rar.hpp"
2
3MKDIR_CODE MakeDir(const wchar *Name,bool SetAttr,uint Attr)
4{
5#ifdef _WIN_ALL
6 // Windows automatically removes dots and spaces in the end of directory
7 // name. So we detect such names and process them with \\?\ prefix.
8 wchar *LastChar=PointToLastChar(Name);
9 bool Special=*LastChar=='.' || *LastChar==' ';
10 BOOL RetCode=Special ? FALSE : CreateDirectory(Name,NULL);
11 if (RetCode==0 && !FileExist(Name))
12 {
13 wchar LongName[NM];
14 if (GetWinLongPath(Name,LongName,ASIZE(LongName)))
15 RetCode=CreateDirectory(LongName,NULL);
16 }
17 if (RetCode!=0) // Non-zero return code means success for CreateDirectory.
18 {
19 if (SetAttr)
20 SetFileAttr(Name,Attr);
21 return MKDIR_SUCCESS;
22 }
23 int ErrCode=GetLastError();
24 if (ErrCode==ERROR_FILE_NOT_FOUND || ErrCode==ERROR_PATH_NOT_FOUND)
25 return MKDIR_BADPATH;
26 return MKDIR_ERROR;
27#elif defined(_UNIX)
28 char NameA[NM];
29 WideToChar(Name,NameA,ASIZE(NameA));
30 mode_t uattr=SetAttr ? (mode_t)Attr:0777;
31 int ErrCode=mkdir(NameA,uattr);
32 if (ErrCode==-1)
33 return errno==ENOENT ? MKDIR_BADPATH:MKDIR_ERROR;
34 return MKDIR_SUCCESS;
35#else
36 return MKDIR_ERROR;
37#endif
38}
39
40
41bool CreatePath(const wchar *Path,bool SkipLastName,bool Silent)
42{
43 if (Path==NULL || *Path==0)
44 return false;
45
46#if defined(_WIN_ALL) || defined(_EMX)
47 uint DirAttr=0;
48#else
49 uint DirAttr=0777;
50#endif
51
52 bool Success=true;
53
54 for (const wchar *s=Path;*s!=0;s++)
55 {
56 wchar DirName[NM];
57 if (s-Path>=ASIZE(DirName))
58 break;
59
60 // Process all kinds of path separators, so user can enter Unix style
61 // path in Windows or Windows in Unix. s>Path check avoids attempting
62 // creating an empty directory for paths starting from path separator.
63 if (IsPathDiv(*s) && s>Path)
64 {
65#ifdef _WIN_ALL
66 // We must not attempt to create "D:" directory, because first
67 // CreateDirectory will fail, so we'll use \\?\D:, which forces Wine
68 // to create "D:" directory.
69 if (s==Path+2 && Path[1]==':')
70 continue;
71#endif
72 wcsncpy(DirName,Path,s-Path);
73 DirName[s-Path]=0;
74
75 Success=MakeDir(DirName,true,DirAttr)==MKDIR_SUCCESS;
76 if (Success && !Silent)
77 {
78 mprintf(St(MCreatDir),DirName);
79 mprintf(L" %s",St(MOk));
80 }
81 }
82 }
83 if (!SkipLastName && !IsPathDiv(*PointToLastChar(Path)))
84 Success=MakeDir(Path,true,DirAttr)==MKDIR_SUCCESS;
85 return Success;
86}
87
88
89void SetDirTime(const wchar *Name,RarTime *ftm,RarTime *ftc,RarTime *fta)
90{
91#if defined(_WIN_ALL)
92 bool sm=ftm!=NULL && ftm->IsSet();
93 bool sc=ftc!=NULL && ftc->IsSet();
94 bool sa=fta!=NULL && fta->IsSet();
95
96 uint DirAttr=GetFileAttr(Name);
97 bool ResetAttr=(DirAttr!=0xffffffff && (DirAttr & FILE_ATTRIBUTE_READONLY)!=0);
98 if (ResetAttr)
99 SetFileAttr(Name,0);
100
101 HANDLE hFile=CreateFile(Name,GENERIC_WRITE,FILE_SHARE_READ|FILE_SHARE_WRITE,
102 NULL,OPEN_EXISTING,FILE_FLAG_BACKUP_SEMANTICS,NULL);
103 if (hFile==INVALID_HANDLE_VALUE)
104 {
105 wchar LongName[NM];
106 if (GetWinLongPath(Name,LongName,ASIZE(LongName)))
107 hFile=CreateFile(LongName,GENERIC_WRITE,FILE_SHARE_READ|FILE_SHARE_WRITE,
108 NULL,OPEN_EXISTING,FILE_FLAG_BACKUP_SEMANTICS,NULL);
109 }
110
111 if (hFile==INVALID_HANDLE_VALUE)
112 return;
113 FILETIME fm,fc,fa;
114 if (sm)
115 ftm->GetWinFT(&fm);
116 if (sc)
117 ftc->GetWinFT(&fc);
118 if (sa)
119 fta->GetWinFT(&fa);
120 SetFileTime(hFile,sc ? &fc:NULL,sa ? &fa:NULL,sm ? &fm:NULL);
121 CloseHandle(hFile);
122 if (ResetAttr)
123 SetFileAttr(Name,DirAttr);
124#endif
125#if defined(_UNIX) || defined(_EMX)
126 File::SetCloseFileTimeByName(Name,ftm,fta);
127#endif
128}
129
130
131bool IsRemovable(const wchar *Name)
132{
133#if defined(_WIN_ALL)
134 wchar Root[NM];
135 GetPathRoot(Name,Root,ASIZE(Root));
136 int Type=GetDriveType(*Root!=0 ? Root:NULL);
137 return Type==DRIVE_REMOVABLE || Type==DRIVE_CDROM;
138#else
139 return false;
140#endif
141}
142
143
144#ifndef SFX_MODULE
146{
147#ifdef _WIN_ALL
148 wchar Root[NM];
149 GetFilePath(Name,Root,ASIZE(Root));
150
151 ULARGE_INTEGER uiTotalSize,uiTotalFree,uiUserFree;
152 uiUserFree.u.LowPart=uiUserFree.u.HighPart=0;
153 if (GetDiskFreeSpaceEx(*Root!=0 ? Root:NULL,&uiUserFree,&uiTotalSize,&uiTotalFree) &&
154 uiUserFree.u.HighPart<=uiTotalFree.u.HighPart)
155 return INT32TO64(uiUserFree.u.HighPart,uiUserFree.u.LowPart);
156 return 0;
157#elif defined(_UNIX)
158 wchar Root[NM];
159 GetFilePath(Name,Root,ASIZE(Root));
160 char RootA[NM];
161 WideToChar(Root,RootA,ASIZE(RootA));
162 struct statvfs sfs;
163 if (statvfs(*RootA!=0 ? RootA:".",&sfs)!=0)
164 return 0;
165 int64 FreeSize=sfs.f_bsize;
166 FreeSize=FreeSize*sfs.f_bavail;
167 return FreeSize;
168#else
169 return 0;
170#endif
171}
172#endif
173
174
175#if defined(_WIN_ALL) && !defined(SFX_MODULE) && !defined(SILENT)
176// Return 'true' for FAT and FAT32, so we can adjust the maximum supported
177// file size to 4 GB for these file systems.
178bool IsFAT(const wchar *Name)
179{
180 wchar Root[NM];
181 GetPathRoot(Name,Root,ASIZE(Root));
182 wchar FileSystem[MAX_PATH+1];
183 if (GetVolumeInformation(Root,NULL,0,NULL,NULL,NULL,FileSystem,ASIZE(FileSystem)))
184 return wcscmp(FileSystem,L"FAT")==0 || wcscmp(FileSystem,L"FAT32")==0;
185 return false;
186}
187#endif
188
189
190bool FileExist(const wchar *Name)
191{
192#ifdef _WIN_ALL
193 return GetFileAttr(Name)!=0xffffffff;
194#elif defined(ENABLE_ACCESS)
195 char NameA[NM];
196 WideToChar(Name,NameA,ASIZE(NameA));
197 return access(NameA,0)==0;
198#else
199 FindData FD;
200 return FindFile::FastFind(Name,&FD);
201#endif
202}
203
204
205bool WildFileExist(const wchar *Name)
206{
207 if (IsWildcard(Name))
208 {
209 FindFile Find;
210 Find.SetMask(Name);
211 FindData fd;
212 return Find.Next(&fd);
213 }
214 return FileExist(Name);
215}
216
217
218bool IsDir(uint Attr)
219{
220#ifdef _WIN_ALL
221 return Attr!=0xffffffff && (Attr & FILE_ATTRIBUTE_DIRECTORY)!=0;
222#endif
223#if defined(_UNIX)
224 return (Attr & 0xF000)==0x4000;
225#endif
226}
227
228
230{
231#if defined(_UNIX) && defined(S_ISFIFO) && defined(S_ISSOCK) && defined(S_ISCHR)
232 return S_ISFIFO(Attr) || S_ISSOCK(Attr) || S_ISCHR(Attr);
233#endif
234 return false;
235}
236
237
238bool IsLink(uint Attr)
239{
240#ifdef _UNIX
241 return (Attr & 0xF000)==0xA000;
242#elif defined(_WIN_ALL)
243 return (Attr & FILE_ATTRIBUTE_REPARSE_POINT)!=0;
244#else
245 return false;
246#endif
247}
248
249
250
251
252
253
254bool IsDeleteAllowed(uint FileAttr)
255{
256#ifdef _WIN_ALL
257 return (FileAttr & (FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM|FILE_ATTRIBUTE_HIDDEN))==0;
258#else
259 return (FileAttr & (S_IRUSR|S_IWUSR))==(S_IRUSR|S_IWUSR);
260#endif
261}
262
263
264void PrepareToDelete(const wchar *Name)
265{
266#if defined(_WIN_ALL) || defined(_EMX)
267 SetFileAttr(Name,0);
268#endif
269#ifdef _UNIX
270 if (Name!=NULL)
271 {
272 char NameA[NM];
273 WideToChar(Name,NameA,ASIZE(NameA));
274 chmod(NameA,S_IRUSR|S_IWUSR|S_IXUSR);
275 }
276#endif
277}
278
279
281{
282#ifdef _WIN_ALL
283 DWORD Attr=GetFileAttributes(Name);
284 if (Attr==0xffffffff)
285 {
286 wchar LongName[NM];
287 if (GetWinLongPath(Name,LongName,ASIZE(LongName)))
288 Attr=GetFileAttributes(LongName);
289 }
290 return Attr;
291#else
292 char NameA[NM];
293 WideToChar(Name,NameA,ASIZE(NameA));
294 struct stat st;
295 if (stat(NameA,&st)!=0)
296 return 0;
297 return st.st_mode;
298#endif
299}
300
301
302bool SetFileAttr(const wchar *Name,uint Attr)
303{
304#ifdef _WIN_ALL
305 bool Success=SetFileAttributes(Name,Attr)!=0;
306 if (!Success)
307 {
308 wchar LongName[NM];
309 if (GetWinLongPath(Name,LongName,ASIZE(LongName)))
310 Success=SetFileAttributes(LongName,Attr)!=0;
311 }
312 return Success;
313#elif defined(_UNIX)
314 char NameA[NM];
315 WideToChar(Name,NameA,ASIZE(NameA));
316 return chmod(NameA,(mode_t)Attr)==0;
317#else
318 return false;
319#endif
320}
321
322
323#if 0
324wchar *MkTemp(wchar *Name,size_t MaxSize)
325{
326 size_t Length=wcslen(Name);
327
328 RarTime CurTime;
329 CurTime.SetCurrentTime();
330
331 // We cannot use CurTime.GetWin() as is, because its lowest bits can
332 // have low informational value, like being a zero or few fixed numbers.
333 uint Random=(uint)(CurTime.GetWin()/100000);
334
335 // Using PID we guarantee that different RAR copies use different temp names
336 // even if started in exactly the same time.
337 uint PID=0;
338#ifdef _WIN_ALL
339 PID=(uint)GetCurrentProcessId();
340#elif defined(_UNIX)
341 PID=(uint)getpid();
342#endif
343
344 for (uint Attempt=0;;Attempt++)
345 {
346 uint Ext=Random%50000+Attempt;
347 wchar RndText[50];
348 swprintf(RndText,ASIZE(RndText),L"%u.%03u",PID,Ext);
349 if (Length+wcslen(RndText)>=MaxSize || Attempt==1000)
350 return NULL;
351 wcsncpyz(Name+Length,RndText,MaxSize-Length);
352 if (!FileExist(Name))
353 break;
354 }
355 return Name;
356}
357#endif
358
359
360#if !defined(SFX_MODULE)
361void CalcFileSum(File *SrcFile,uint *CRC32,byte *Blake2,uint Threads,int64 Size,uint Flags)
362{
363 int64 SavePos=SrcFile->Tell();
364#ifndef SILENT
365 int64 FileLength=Size==INT64NDF ? SrcFile->FileLength() : Size;
366#endif
367
368 if ((Flags & (CALCFSUM_SHOWTEXT|CALCFSUM_SHOWPERCENT))!=0)
370
371 if ((Flags & CALCFSUM_CURPOS)==0)
372 SrcFile->Seek(0,SEEK_SET);
373
374 const size_t BufSize=0x100000;
375 Array<byte> Data(BufSize);
376
377
378 DataHash HashCRC,HashBlake2;
379 HashCRC.Init(HASH_CRC32,Threads);
380 HashBlake2.Init(HASH_BLAKE2,Threads);
381
382 int64 BlockCount=0;
383 int64 TotalRead=0;
384 while (true)
385 {
386 size_t SizeToRead;
387 if (Size==INT64NDF) // If we process the entire file.
388 SizeToRead=BufSize; // Then always attempt to read the entire buffer.
389 else
390 SizeToRead=(size_t)Min((int64)BufSize,Size);
391 int ReadSize=SrcFile->Read(&Data[0],SizeToRead);
392 if (ReadSize==0)
393 break;
394 TotalRead+=ReadSize;
395
396 if ((++BlockCount & 0xf)==0)
397 {
398#ifndef SILENT
399 if ((Flags & CALCFSUM_SHOWPROGRESS)!=0)
400 {
401 // Update only the current file progress in WinRAR, set the total to 0
402 // to keep it as is. It looks better for WinRAR,
403 uiExtractProgress(TotalRead,FileLength,0,0);
404 }
405 else
406 {
407 if ((Flags & CALCFSUM_SHOWPERCENT)!=0)
408 uiMsg(UIEVENT_FILESUMPROGRESS,ToPercent(TotalRead,FileLength));
409 }
410#endif
411 Wait();
412 }
413
414 if (CRC32!=NULL)
415 HashCRC.Update(&Data[0],ReadSize);
416 if (Blake2!=NULL)
417 HashBlake2.Update(&Data[0],ReadSize);
418
419 if (Size!=INT64NDF)
420 Size-=ReadSize;
421 }
422 SrcFile->Seek(SavePos,SEEK_SET);
423
424 if ((Flags & CALCFSUM_SHOWPERCENT)!=0)
426
427 if (CRC32!=NULL)
428 *CRC32=HashCRC.GetCRC32();
429 if (Blake2!=NULL)
430 {
431 HashValue Result;
432 HashBlake2.Result(&Result);
433 memcpy(Blake2,Result.Digest,sizeof(Result.Digest));
434 }
435}
436#endif
437
438
439bool RenameFile(const wchar *SrcName,const wchar *DestName)
440{
441#ifdef _WIN_ALL
442 bool Success=MoveFile(SrcName,DestName)!=0;
443 if (!Success)
444 {
445 wchar LongName1[NM],LongName2[NM];
446 if (GetWinLongPath(SrcName,LongName1,ASIZE(LongName1)) &&
447 GetWinLongPath(DestName,LongName2,ASIZE(LongName2)))
448 Success=MoveFile(LongName1,LongName2)!=0;
449 }
450 return Success;
451#else
452 char SrcNameA[NM],DestNameA[NM];
453 WideToChar(SrcName,SrcNameA,ASIZE(SrcNameA));
454 WideToChar(DestName,DestNameA,ASIZE(DestNameA));
455 bool Success=rename(SrcNameA,DestNameA)==0;
456 return Success;
457#endif
458}
459
460
461bool DelFile(const wchar *Name)
462{
463#ifdef _WIN_ALL
464 bool Success=DeleteFile(Name)!=0;
465 if (!Success)
466 {
467 wchar LongName[NM];
468 if (GetWinLongPath(Name,LongName,ASIZE(LongName)))
469 Success=DeleteFile(LongName)!=0;
470 }
471 return Success;
472#else
473 char NameA[NM];
474 WideToChar(Name,NameA,ASIZE(NameA));
475 bool Success=remove(NameA)==0;
476 return Success;
477#endif
478}
479
480
481bool DelDir(const wchar *Name)
482{
483#ifdef _WIN_ALL
484 bool Success=RemoveDirectory(Name)!=0;
485 if (!Success)
486 {
487 wchar LongName[NM];
488 if (GetWinLongPath(Name,LongName,ASIZE(LongName)))
489 Success=RemoveDirectory(LongName)!=0;
490 }
491 return Success;
492#else
493 char NameA[NM];
494 WideToChar(Name,NameA,ASIZE(NameA));
495 bool Success=rmdir(NameA)==0;
496 return Success;
497#endif
498}
499
500
501#if defined(_WIN_ALL) && !defined(SFX_MODULE)
502bool SetFileCompression(const wchar *Name,bool State)
503{
504 HANDLE hFile=CreateFile(Name,FILE_READ_DATA|FILE_WRITE_DATA,
505 FILE_SHARE_READ|FILE_SHARE_WRITE,NULL,OPEN_EXISTING,
506 FILE_FLAG_BACKUP_SEMANTICS|FILE_FLAG_SEQUENTIAL_SCAN,NULL);
507 if (hFile==INVALID_HANDLE_VALUE)
508 {
509 wchar LongName[NM];
510 if (GetWinLongPath(Name,LongName,ASIZE(LongName)))
511 hFile=CreateFile(LongName,FILE_READ_DATA|FILE_WRITE_DATA,
512 FILE_SHARE_READ|FILE_SHARE_WRITE,NULL,OPEN_EXISTING,
513 FILE_FLAG_BACKUP_SEMANTICS|FILE_FLAG_SEQUENTIAL_SCAN,NULL);
514 }
515 if (hFile==INVALID_HANDLE_VALUE)
516 return false;
517 SHORT NewState=State ? COMPRESSION_FORMAT_DEFAULT:COMPRESSION_FORMAT_NONE;
518 DWORD Result;
519 int RetCode=DeviceIoControl(hFile,FSCTL_SET_COMPRESSION,&NewState,
520 sizeof(NewState),NULL,0,&Result,NULL);
521 CloseHandle(hFile);
522 return RetCode!=0;
523}
524
525
526void ResetFileCache(const wchar *Name)
527{
528 // To reset file cache in Windows it is enough to open it with
529 // FILE_FLAG_NO_BUFFERING and then close it.
530 HANDLE hSrc=CreateFile(Name,GENERIC_READ,
531 FILE_SHARE_READ|FILE_SHARE_WRITE,
532 NULL,OPEN_EXISTING,FILE_FLAG_NO_BUFFERING,NULL);
533 if (hSrc!=INVALID_HANDLE_VALUE)
534 CloseHandle(hSrc);
535}
536#endif
537
538
539
540
541
542
543
544
545
546
void Init(HASH_TYPE Type, uint MaxThreads)
Definition: hash.cpp:67
void Update(const void *Data, size_t DataSize)
Definition: hash.cpp:84
void Result(HashValue *Result)
Definition: hash.cpp:106
uint GetCRC32()
Definition: hash.cpp:122
Definition: file.hpp:57
virtual void Seek(int64 Offset, int Method)
Definition: file.cpp:514
int64 FileLength()
Definition: file.cpp:750
virtual int Read(void *Data, size_t Size)
Definition: file.cpp:374
static void SetCloseFileTimeByName(const wchar *Name, RarTime *ftm, RarTime *fta)
Definition: file.cpp:701
virtual int64 Tell()
Definition: file.cpp:576
void SetMask(const wchar *Mask)
Definition: find.cpp:27
bool Next(FindData *fd, bool GetSymLink=false)
Definition: find.cpp:34
static bool FastFind(const wchar *FindMask, FindData *fd, bool GetSymLink=false)
Definition: find.cpp:108
uint64 GetWin()
Definition: timefn.cpp:151
void SetCurrentTime()
Definition: timefn.cpp:305
bool IsSet()
Definition: timefn.hpp:58
void mprintf(const wchar *fmt,...)
Definition: consio.cpp:118
uint CRC32(uint StartCRC, const void *Addr, size_t Size)
Definition: crc.cpp:62
bool IsUnreadable(uint Attr)
Definition: filefn.cpp:229
bool DelFile(const wchar *Name)
Definition: filefn.cpp:461
uint GetFileAttr(const wchar *Name)
Definition: filefn.cpp:280
void PrepareToDelete(const wchar *Name)
Definition: filefn.cpp:264
bool IsLink(uint Attr)
Definition: filefn.cpp:238
bool IsRemovable(const wchar *Name)
Definition: filefn.cpp:131
int64 GetFreeDisk(const wchar *Name)
Definition: filefn.cpp:145
bool CreatePath(const wchar *Path, bool SkipLastName, bool Silent)
Definition: filefn.cpp:41
void CalcFileSum(File *SrcFile, uint *CRC32, byte *Blake2, uint Threads, int64 Size, uint Flags)
Definition: filefn.cpp:361
void SetDirTime(const wchar *Name, RarTime *ftm, RarTime *ftc, RarTime *fta)
Definition: filefn.cpp:89
bool DelDir(const wchar *Name)
Definition: filefn.cpp:481
bool WildFileExist(const wchar *Name)
Definition: filefn.cpp:205
bool IsDir(uint Attr)
Definition: filefn.cpp:218
bool RenameFile(const wchar *SrcName, const wchar *DestName)
Definition: filefn.cpp:439
MKDIR_CODE MakeDir(const wchar *Name, bool SetAttr, uint Attr)
Definition: filefn.cpp:3
bool SetFileAttr(const wchar *Name, uint Attr)
Definition: filefn.cpp:302
bool FileExist(const wchar *Name)
Definition: filefn.cpp:190
bool IsDeleteAllowed(uint FileAttr)
Definition: filefn.cpp:254
@ CALCFSUM_SHOWPROGRESS
Definition: filefn.hpp:34
@ CALCFSUM_SHOWPERCENT
Definition: filefn.hpp:34
@ CALCFSUM_SHOWTEXT
Definition: filefn.hpp:34
@ CALCFSUM_CURPOS
Definition: filefn.hpp:34
MKDIR_CODE
Definition: filefn.hpp:4
@ MKDIR_BADPATH
Definition: filefn.hpp:4
@ MKDIR_SUCCESS
Definition: filefn.hpp:4
@ MKDIR_ERROR
Definition: filefn.hpp:4
@ HASH_CRC32
Definition: hash.hpp:4
@ HASH_BLAKE2
Definition: hash.hpp:4
#define MCreatDir
Definition: loclang.hpp:214
#define MOk
Definition: loclang.hpp:183
#define FALSE
Definition: os.hpp:4
bool IsWildcard(const wchar *Str)
Definition: pathfn.cpp:121
void GetPathRoot(const wchar *Path, wchar *Root, size_t MaxSize)
Definition: pathfn.cpp:591
bool IsPathDiv(int Ch)
Definition: pathfn.cpp:134
void GetFilePath(const wchar *FullName, wchar *Path, size_t MaxLength)
Definition: pathfn.cpp:196
wchar * PointToLastChar(const wchar *Path)
Definition: pathfn.cpp:12
#define Min(x, y)
Definition: rardefs.hpp:4
#define ASIZE(x)
Definition: rardefs.hpp:10
#define INT64NDF
Definition: rartypes.hpp:30
wchar_t wchar
Definition: rartypes.hpp:13
int64_t int64
Definition: rartypes.hpp:12
unsigned int uint
Definition: rartypes.hpp:8
#define INT32TO64(high, low)
Definition: rartypes.hpp:19
const wchar * St(MSGID StringId)
Definition: resource.cpp:8
int ToPercent(int64 N1, int64 N2)
Definition: smallfn.cpp:3
void wcsncpyz(wchar *dest, const wchar *src, size_t maxlen)
Definition: strfn.cpp:275
Definition: find.hpp:9
byte Digest[SHA256_DIGEST_SIZE]
Definition: hash.hpp:16
void Wait()
Definition: system.cpp:80
void uiMsg(UIMESSAGE_CODE Code)
Definition: ui.hpp:148
@ UIEVENT_FILESUMEND
Definition: ui.hpp:62
@ UIEVENT_FILESUMSTART
Definition: ui.hpp:61
@ UIEVENT_FILESUMPROGRESS
Definition: ui.hpp:61
void uiExtractProgress(int64 CurFileSize, int64 TotalFileSize, int64 CurSize, int64 TotalSize)
Definition: uiconsole.cpp:72
bool WideToChar(const wchar *Src, char *Dest, size_t DestSize)
Definition: unicode.cpp:20