Merge pull request #4324 from FernetMenta/wasapi
[vuplus_xbmc] / lib / UnrarXLib / find.cpp
1 #include "rar.hpp"
2
3 FindFile::FindFile()
4 {
5   *FindMask=0;
6   *FindMaskW=0;
7   FirstCall=TRUE;
8 #ifdef _WIN_32
9   hFind=INVALID_HANDLE_VALUE;
10 #else
11   dirp=NULL;
12 #endif
13 }
14
15
16 FindFile::~FindFile()
17 {
18 #ifdef _WIN_32
19   if (hFind!=INVALID_HANDLE_VALUE)
20     FindClose(hFind);
21 #else
22   if (dirp!=NULL)
23     closedir(dirp);
24 #endif
25 }
26
27
28 void FindFile::SetMask(const char *FindMask)
29 {
30   strcpy(FindFile::FindMask,FindMask);
31   if (*FindMaskW==0)
32     CharToWide(FindMask,FindMaskW);
33   FirstCall=TRUE;
34 }
35
36
37 void FindFile::SetMaskW(const wchar *FindMaskW)
38 {
39   if (FindMaskW==NULL)
40     return;
41   strcpyw(FindFile::FindMaskW,FindMaskW);
42   if (*FindMask==0)
43     WideToChar(FindMaskW,FindMask);
44   FirstCall=TRUE;
45 }
46
47
48 bool FindFile::Next(struct FindData *fd,bool GetSymLink)
49 {
50   fd->Error=false;
51   if (*FindMask==0)
52     return(false);
53 #ifdef _WIN_32
54   if (FirstCall)
55   {
56     if ((hFind=Win32Find(INVALID_HANDLE_VALUE,FindMask,FindMaskW,fd))==INVALID_HANDLE_VALUE)
57       return(false);
58   }
59   else
60     if (Win32Find(hFind,FindMask,FindMaskW,fd)==INVALID_HANDLE_VALUE)
61       return(false);
62 #else
63   if (FirstCall)
64   {
65     char DirName[NM];
66     strcpy(DirName,FindMask);
67     RemoveNameFromPath(DirName);
68     if (*DirName==0)
69       strcpy(DirName,".");
70 /*
71     else
72     {
73       int Length=strlen(DirName);
74       if (Length>1 && DirName[Length-1]==CPATHDIVIDER && (Length!=3 || !IsDriveDiv(DirName[1])))
75         DirName[Length-1]=0;
76     }
77 */
78     if ((dirp=opendir(DirName))==NULL)
79     {
80       fd->Error=(errno!=ENOENT);
81       return(false);
82     }
83   }
84   while (1)
85   {
86     struct dirent *ent=readdir(dirp);
87     if (ent==NULL)
88       return(false);
89     if (strcmp(ent->d_name,".")==0 || strcmp(ent->d_name,"..")==0)
90       continue;
91     if (CmpName(FindMask,ent->d_name,MATCH_NAMES))
92     {
93       char FullName[NM];
94       strcpy(FullName,FindMask);
95       strcpy(PointToName(FullName),ent->d_name);
96       if (!FastFind(FullName,NULL,fd,GetSymLink))
97       {
98         ErrHandler.OpenErrorMsg(FullName);
99         continue;
100       }
101       strcpy(fd->Name,FullName);
102       break;
103     }
104   }
105   *fd->NameW=0;
106 #ifdef _APPLE
107   if (!LowAscii(fd->Name))
108     UtfToWide(fd->Name,fd->NameW,sizeof(fd->NameW));
109 #elif defined(UNICODE_SUPPORTED)
110   if (!LowAscii(fd->Name) && UnicodeEnabled())
111     CharToWide(fd->Name,fd->NameW);
112 #endif
113 #endif
114   fd->IsDir=IsDir(fd->FileAttr);
115   FirstCall=FALSE;
116   char *Name=PointToName(fd->Name);
117   if (strcmp(Name,".")==0 || strcmp(Name,"..")==0)
118     return(Next(fd));
119   return(true);
120 }
121
122
123 bool FindFile::FastFind(const char *FindMask,const wchar *FindMaskW,struct FindData *fd,bool GetSymLink)
124 {
125   fd->Error=false;
126 #ifndef _UNIX
127   if (IsWildcard(FindMask,FindMaskW))
128     return(false);
129 #endif    
130 #ifdef _WIN_32
131   HANDLE hFind=Win32Find(INVALID_HANDLE_VALUE,FindMask,FindMaskW,fd);
132   if (hFind==INVALID_HANDLE_VALUE)
133     return(false);
134   FindClose(hFind);
135 #else
136   struct stat st;
137   if (GetSymLink)
138   {
139 #ifdef SAVE_LINKS
140     if (lstat(FindMask,&st)!=0)
141 #else
142     if (stat(FindMask,&st)!=0)
143 #endif
144     {
145       fd->Error=(errno!=ENOENT);
146       return(false);
147     }
148   }
149   else
150     if (stat(FindMask,&st)!=0)
151     {
152       fd->Error=(errno!=ENOENT);
153       return(false);
154     }
155 #ifdef _DJGPP
156   fd->FileAttr=chmod(FindMask,0);
157 #elif defined(_EMX)
158   fd->FileAttr=st.st_attr;
159 #else
160   fd->FileAttr=st.st_mode;
161 #endif
162   fd->IsDir=IsDir(st.st_mode);
163   fd->Size=st.st_size;
164   fd->mtime=st.st_mtime;
165   fd->atime=st.st_atime;
166   fd->ctime=st.st_ctime;
167   fd->FileTime=fd->mtime.GetDos();
168   strcpy(fd->Name,FindMask);
169   *fd->NameW=0;
170 #ifdef _APPLE
171   if (!LowAscii(fd->Name))
172     UtfToWide(fd->Name,fd->NameW,sizeof(fd->NameW));
173 #elif defined(UNICODE_SUPPORTED)
174   if (!LowAscii(fd->Name) && UnicodeEnabled())
175     CharToWide(fd->Name,fd->NameW);
176 #endif
177 #endif
178   fd->IsDir=IsDir(fd->FileAttr);
179   return(true);
180 }
181
182
183 #ifdef _WIN_32
184 HANDLE FindFile::Win32Find(HANDLE hFind,const char *Mask,const wchar *MaskW,struct FindData *fd)
185 {
186 #if !defined(TARGET_POSIX)
187 #ifndef _WIN_CE
188   if (WinNT())
189 #endif
190   {
191     wchar WideMask[NM];
192     if (MaskW!=NULL && *MaskW!=0)
193       strcpyw(WideMask,MaskW);
194     else
195       CharToWide(Mask,WideMask);
196
197     WIN32_FIND_DATAW FindData;
198     if (hFind==INVALID_HANDLE_VALUE)
199     {
200       hFind=FindFirstFileW(WideMask,&FindData);
201       if (hFind==INVALID_HANDLE_VALUE)
202       {
203         int SysErr=GetLastError();
204         fd->Error=(SysErr!=ERROR_FILE_NOT_FOUND &&
205                    SysErr!=ERROR_PATH_NOT_FOUND &&
206                    SysErr!=ERROR_NO_MORE_FILES);
207       }
208     }
209     else
210       if (!FindNextFileW(hFind,&FindData))
211       {
212         hFind=INVALID_HANDLE_VALUE;
213         fd->Error=GetLastError()!=ERROR_NO_MORE_FILES;
214       }
215
216     if (hFind!=INVALID_HANDLE_VALUE)
217     {
218       strcpyw(fd->NameW,WideMask);
219       strcpyw(PointToName(fd->NameW),FindData.cFileName);
220       WideToChar(fd->NameW,fd->Name);
221       fd->Size=int32to64(FindData.nFileSizeHigh,FindData.nFileSizeLow);
222       fd->FileAttr=FindData.dwFileAttributes;
223       WideToChar(FindData.cAlternateFileName,fd->ShortName);
224       fd->ftCreationTime=FindData.ftCreationTime;
225       fd->ftLastAccessTime=FindData.ftLastAccessTime;
226       fd->ftLastWriteTime=FindData.ftLastWriteTime;
227       fd->mtime=FindData.ftLastWriteTime;
228       fd->ctime=FindData.ftCreationTime;
229       fd->atime=FindData.ftLastAccessTime;
230       fd->FileTime=fd->mtime.GetDos();
231
232 #ifndef _WIN_CE
233       if (LowAscii(fd->NameW))
234         *fd->NameW=0;
235 #endif
236     }
237   }
238 #ifndef _WIN_CE
239   else
240 #endif
241   {
242     char CharMask[NM];
243     if (Mask!=NULL && *Mask!=0)
244       strcpy(CharMask,Mask);
245     else
246       WideToChar(MaskW,CharMask);
247
248     WIN32_FIND_DATA FindData;
249     if (hFind==INVALID_HANDLE_VALUE)
250     {
251       hFind=FindFirstFile(CharMask,&FindData);
252       if (hFind==INVALID_HANDLE_VALUE)
253       {
254         int SysErr=GetLastError();
255         fd->Error=SysErr!=ERROR_FILE_NOT_FOUND && SysErr!=ERROR_PATH_NOT_FOUND;
256       }
257     }
258     else
259       if (!FindNextFile(hFind,&FindData))
260       {
261         hFind=INVALID_HANDLE_VALUE;
262         fd->Error=GetLastError()!=ERROR_NO_MORE_FILES;
263       }
264
265     if (hFind!=INVALID_HANDLE_VALUE)
266     {
267       strcpy(fd->Name,CharMask);
268       strcpy(PointToName(fd->Name),FindData.cFileName);
269       CharToWide(fd->Name,fd->NameW);
270       fd->Size=int32to64(FindData.nFileSizeHigh,FindData.nFileSizeLow);
271       fd->FileAttr=FindData.dwFileAttributes;
272       strcpy(fd->ShortName,FindData.cAlternateFileName);
273       fd->ftCreationTime=FindData.ftCreationTime;
274       fd->ftLastAccessTime=FindData.ftLastAccessTime;
275       fd->ftLastWriteTime=FindData.ftLastWriteTime;
276       fd->mtime=FindData.ftLastWriteTime;
277       fd->ctime=FindData.ftCreationTime;
278       fd->atime=FindData.ftLastAccessTime;
279       fd->FileTime=fd->mtime.GetDos();
280       if (LowAscii(fd->Name))
281         *fd->NameW=0;
282     }
283   }
284 #endif
285   return(hFind);
286 }
287 #endif
288