ReactOS  0.4.12-dev-18-gf469aca
available.cpp
Go to the documentation of this file.
1 /*
2  * PROJECT: ReactOS Applications Manager
3  * LICENSE: GPL-2.0+ (https://spdx.org/licenses/GPL-2.0+)
4  * FILE: base/applications/rapps/available.cpp
5  * PURPOSE: Classes for working with available applications
6  * COPYRIGHT: Copyright 2009 Dmitry Chapyshev (dmitry@reactos.org)
7  * Copyright 2015 Ismael Ferreras Morezuelas (swyterzone+ros@gmail.com)
8  * Copyright 2017 Alexander Shaposhnikov (sanchaez@reactos.org)
9  */
10 #include "rapps.h"
11 
12 #include "available.h"
13 #include "misc.h"
14 #include "dialogs.h"
15 
16 #include <atlcoll.h>
17 #include <atlsimpcoll.h>
18 #include <atlstr.h>
19 
20  // CAvailableApplicationInfo
22  : m_IsSelected(FALSE), m_LicenseType(LICENSE_NONE), m_sFileName(sFileNameParam),
23  m_IsInstalled(FALSE), m_HasLanguageInfo(FALSE), m_HasInstalledVersion(FALSE)
24 {
26 }
27 
29 {
31  {
33  }
34 }
35 
36 // Lazily load general info from the file
38 {
40 
41  m_Parser->GetInt(L"Category", m_Category);
42 
43  if (!GetString(L"Name", m_szName)
44  || !GetString(L"URLDownload", m_szUrlDownload))
45  {
46  delete m_Parser;
47  return;
48  }
49 
50  GetString(L"RegName", m_szRegName);
51  GetString(L"Version", m_szVersion);
52  GetString(L"License", m_szLicense);
53  GetString(L"Description", m_szDesc);
54  GetString(L"URLSite", m_szUrlSite);
55  GetString(L"CDPath", m_szCDPath);
56  GetString(L"Language", m_szRegName);
57  GetString(L"SHA1", m_szSHA1);
58 
59  RetrieveSize();
63 
64  if (m_IsInstalled)
65  {
67  }
68 
69  delete m_Parser;
70 }
71 
73 {
76 }
77 
79 {
80  ATL::CStringW szNameVersion;
81  szNameVersion = m_szName + L" " + m_szVersion;
84  || ::GetInstalledVersion(&m_szInstalledVersion, szNameVersion);
85 }
86 
88 {
89  const WCHAR cDelimiter = L'|';
90  ATL::CStringW szBuffer;
91 
92  // TODO: Get multiline parameter
93  if (!m_Parser->GetString(L"Languages", szBuffer))
94  {
96  return;
97  }
98 
99  // Parse parameter string
100  ATL::CStringW m_szLocale;
101  INT iLCID;
102  for (INT i = 0; szBuffer[i] != UNICODE_NULL; ++i)
103  {
104  if (szBuffer[i] != cDelimiter && szBuffer[i] != L'\n')
105  {
106  m_szLocale += szBuffer[i];
107  }
108  else
109  {
110  if (StrToIntExW(m_szLocale.GetString(), STIF_DEFAULT, &iLCID))
111  {
112  m_LanguageLCIDs.Add(static_cast<LCID>(iLCID));
113  m_szLocale.Empty();
114  }
115  }
116  }
117 
118  // For the text after delimiter
119  if (!m_szLocale.IsEmpty())
120  {
121  if (StrToIntExW(m_szLocale.GetString(), STIF_DEFAULT, &iLCID))
122  {
123  m_LanguageLCIDs.Add(static_cast<LCID>(iLCID));
124  }
125  }
126 
128 }
129 
131 {
132  INT IntBuffer;
133 
134  m_Parser->GetInt(L"LicenseType", IntBuffer);
135 
136  if (IsLicenseType(IntBuffer))
137  {
138  m_LicenseType = static_cast<LicenseType>(IntBuffer);
139  }
140  else
141  {
143  }
144 }
145 
147 {
148  INT iSizeBytes;
149 
150  if (!m_Parser->GetInt(L"SizeBytes", iSizeBytes))
151  {
152  // fall back to "Size" string
153  GetString(L"Size", m_szSize);
154  return;
155  }
156 
159 }
160 
162 {
163  if (!m_HasLanguageInfo)
164  {
165  return FALSE;
166  }
167 
168  //Find locale code in the list
169  const INT nLanguagesSize = m_LanguageLCIDs.GetSize();
170  for (INT i = 0; i < nLanguagesSize; ++i)
171  {
172  if (m_LanguageLCIDs[i] == what)
173  {
174  return TRUE;
175  }
176  }
177 
178  return FALSE;
179 }
180 
182 {
183  return m_HasLanguageInfo;
184 }
185 
187 {
189 }
190 
192 {
194 }
195 
197 {
198  return m_IsInstalled;
199 }
200 
202 {
203  return m_HasInstalledVersion;
204 }
205 
207 {
209 }
210 
212 {
213  RtlCopyMemory(&m_ftCacheStamp, ftTime, sizeof(FILETIME));
214 }
215 
217 {
218  if (!m_Parser->GetString(lpKeyName, ReturnedString))
219  {
220  ReturnedString.Empty();
221  return FALSE;
222  }
223  return TRUE;
224 }
225 // CAvailableApplicationInfo
226 
227 // AvailableStrings
229 {
230  //FIXME: maybe provide a fallback?
232  {
233  szAppsPath = szPath + L"\\rapps\\";
234  szCabName = L"rappmgr.cab";
235  szCabDir = szPath;
236  szCabPath = (szCabDir + L"\\") + szCabName;
237  szSearchPath = szAppsPath + L"*.txt";
238  }
239 }
240 // AvailableStrings
241 
242 // CAvailableApps
244 
246 {
247 }
248 
250 {
251  POSITION InfoListPosition = m_InfoList.GetHeadPosition();
252 
253  /* loop and deallocate all the cached app infos in the list */
254  while (InfoListPosition)
255  {
256  CAvailableApplicationInfo* Info = m_InfoList.GetNext(InfoListPosition);
257  delete Info;
258  }
259 
260  m_InfoList.RemoveAll();
261 }
262 
264 {
266  WIN32_FIND_DATAW FindFileData;
267 
268  hFind = FindFirstFileW(m_Strings.szSearchPath.GetString(), &FindFileData);
269 
270  if (hFind != INVALID_HANDLE_VALUE)
271  {
273  do
274  {
275  szTmp = m_Strings.szAppsPath + FindFileData.cFileName;
276  DeleteFileW(szTmp.GetString());
277  } while (FindNextFileW(hFind, &FindFileData) != 0);
278  FindClose(hFind);
279  }
280 
281  RemoveDirectoryW(m_Strings.szAppsPath);
282  RemoveDirectoryW(m_Strings.szPath);
283 }
284 
286 {
288  WIN32_FIND_DATAW FindFileData;
289 
290  if (!CreateDirectoryW(m_Strings.szPath, NULL) && GetLastError() != ERROR_ALREADY_EXISTS)
291  {
292  return FALSE;
293  }
294 
295  //if there are some files in the db folder - we're good
296  hFind = FindFirstFileW(m_Strings.szSearchPath, &FindFileData);
297  if (hFind != INVALID_HANDLE_VALUE)
298  {
299  FindClose(hFind);
300  return TRUE;
301  }
302 
304 
305  if (!ExtractFilesFromCab(m_Strings.szCabName,
306  m_Strings.szCabDir,
307  m_Strings.szAppsPath))
308  {
309  return FALSE;
310  }
311 
312  DeleteFileW(m_Strings.szCabPath);
313 
314  return TRUE;
315 }
316 
318 {
319  DeleteCurrentAppsDB();
320  return UpdateAppsDB();
321 }
322 
324 {
325 
327  WIN32_FIND_DATAW FindFileData;
328 
329  hFind = FindFirstFileW(m_Strings.szSearchPath.GetString(), &FindFileData);
330 
331  if (hFind == INVALID_HANDLE_VALUE)
332  {
333  //no db yet
334  return FALSE;
335  }
336 
337  do
338  {
339  // loop for all the cached entries
340  POSITION CurrentListPosition = m_InfoList.GetHeadPosition();
342 
343  while (CurrentListPosition != NULL)
344  {
345  POSITION LastListPosition = CurrentListPosition;
346  Info = m_InfoList.GetNext(CurrentListPosition);
347 
348  // do we already have this entry in cache?
349  if (Info->m_sFileName == FindFileData.cFileName)
350  {
351  // is it current enough, or the file has been modified since our last time here?
352  if (CompareFileTime(&FindFileData.ftLastWriteTime, &Info->m_ftCacheStamp) == 1)
353  {
354  // recreate our cache, this is the slow path
355  m_InfoList.RemoveAt(LastListPosition);
356 
357  delete Info;
358  Info = NULL;
359  break;
360  }
361  else
362  {
363  // speedy path, compare directly, we already have the data
364  goto skip_if_cached;
365  }
366  }
367  }
368 
369  // create a new entry
370  Info = new CAvailableApplicationInfo(FindFileData.cFileName);
371 
372  // set a timestamp for the next time
373  Info->SetLastWriteTime(&FindFileData.ftLastWriteTime);
374  m_InfoList.AddTail(Info);
375 
376 skip_if_cached:
377  if (EnumType == Info->m_Category
378  || EnumType == ENUM_ALL_AVAILABLE
379  || (EnumType == ENUM_CAT_SELECTED && Info->m_IsSelected))
380  {
381  Info->RefreshAppInfo();
382 
383  if (lpEnumProc)
384  lpEnumProc(Info, m_Strings.szAppsPath.GetString());
385  }
386  } while (FindNextFileW(hFind, &FindFileData) != 0);
387 
388  FindClose(hFind);
389  return TRUE;
390 }
391 
393 {
394  if (m_InfoList.IsEmpty())
395  {
396  return NULL;
397  }
398 
399  // linear search
400  POSITION CurrentListPosition = m_InfoList.GetHeadPosition();
402  while (CurrentListPosition != NULL)
403  {
404  info = m_InfoList.GetNext(CurrentListPosition);
405  if (info->m_szName.CompareNoCase(szAppName) == 0)
406  {
407  return info;
408  }
409  }
410  return NULL;
411 }
412 
414 {
416  for (INT i = 0; i < arrAppsNames.GetSize(); ++i)
417  {
418  CAvailableApplicationInfo* Info = FindInfo(arrAppsNames[i]);
419  if (Info)
420  {
421  result.Add(*Info);
422  }
423  }
424  return result;
425 }
426 
428 {
430  POSITION CurrentListPosition = m_InfoList.GetHeadPosition();
432 
433  while (CurrentListPosition != NULL)
434  {
435  Info = m_InfoList.GetNext(CurrentListPosition);
436  if (Info->m_IsSelected)
437  {
438  result.Add(*Info);
439  }
440  }
441  return result;
442 }
443 
445 {
446  return m_Strings.szPath;
447 }
448 
450 {
451  return m_Strings.szAppsPath;
452 }
453 
455 {
456  return m_Strings.szCabPath;
457 }
458 // CAvailableApps
BOOL WINAPI CreateDirectoryW(IN LPCWSTR lpPathName, IN LPSECURITY_ATTRIBUTES lpSecurityAttributes)
Definition: dir.c:90
ATL::CStringW m_szRegName
Definition: available.h:31
BOOL WINAPI FindNextFileW(IN HANDLE hFindFile, OUT LPWIN32_FIND_DATAW lpFindFileData)
Definition: find.c:382
LPWSTR WINAPI StrFormatByteSizeW(LONGLONG llBytes, LPWSTR lpszDest, UINT cchMax)
Definition: string.c:2376
#define MAKELCID(lgid, srtid)
const ATL::CStringW & GetAppPath() const
Definition: available.cpp:449
BOOL ExtractFilesFromCab(const ATL::CStringW &szCabName, const ATL::CStringW &szCabDir, const ATL::CStringW &szOutputDir)
Definition: cabinet.cpp:257
#define TRUE
Definition: types.h:120
NTSYSAPI VOID NTAPI RtlCopyMemory(VOID UNALIGNED *Destination, CONST VOID UNALIGNED *Source, ULONG Length)
#define APPLICATION_DATABASE_URL
Definition: defines.h:32
BOOL Add(const T &t)
Definition: atlsimpcoll.h:58
#define STIF_DEFAULT
Definition: shlwapi.h:1451
BOOL GetInstalledVersion(ATL::CStringW *pszVersion, const ATL::CStringW &szRegName)
Definition: misc.cpp:316
BOOL HasNativeLanguage() const
Definition: available.cpp:186
__wchar_t WCHAR
Definition: xmlstorage.h:180
ATL::CStringW m_szName
Definition: available.h:30
#define SUBLANG_DEFAULT
Definition: nls.h:168
int CompareNoCase(_In_z_ PCXSTR psz) const
Definition: cstringt.h:610
const WCHAR * LPCWSTR
Definition: xmlstorage.h:185
#define INVALID_HANDLE_VALUE
Definition: compat.h:391
DWORD WINAPI GetLastError(VOID)
Definition: except.c:1059
ATL::CStringW m_szVersion
Definition: available.h:32
DWORD LCID
Definition: nls.h:13
LCID WINAPI GetUserDefaultLCID(void)
Definition: lang.c:523
BOOL GetInt(const ATL::CStringW &KeyName, INT &iResult)
Definition: misc.cpp:395
LicenseType m_LicenseType
Definition: available.h:29
BOOL IsLicenseType(INT x)
Definition: available.h:20
static BOOL UpdateAppsDB()
Definition: available.cpp:285
int GetSize() const
Definition: atlsimpcoll.h:104
int32_t INT
Definition: typedefs.h:56
struct TraceInfo Info
struct _test_info info[]
Definition: SetCursorPos.c:19
ATL::CSimpleArray< CAvailableApplicationInfo > GetSelected() const
Definition: available.cpp:427
CAvailableApplicationInfo * FindInfo(const ATL::CStringW &szAppName) const
Definition: available.cpp:392
ATL::CStringW m_szLicense
Definition: available.h:33
GLenum GLclampf GLint i
Definition: glfuncs.h:14
void ReleaseBuffer(_In_ int nNewLength=-1)
Definition: atlsimpstr.h:372
#define UNICODE_NULL
ATL::CSimpleArray< CAvailableApplicationInfo > FindInfoList(const ATL::CSimpleArray< ATL::CStringW > &arrAppsNames) const
Definition: available.cpp:413
BOOL WINAPI DeleteFileW(IN LPCWSTR lpFileName)
Definition: delete.c:39
ATL::CStringW m_szDesc
Definition: available.h:34
VOID FreeCachedEntries()
Definition: available.cpp:249
smooth NULL
Definition: ftsmooth.c:416
BOOL(CALLBACK * AVAILENUMPROC)(CAvailableApplicationInfo *Info, LPCWSTR szFolderPath)
Definition: available.h:82
BOOL WINAPI RemoveDirectoryW(IN LPCWSTR lpPathName)
Definition: dir.c:732
const ATL::CStringW & GetFolderPath() const
Definition: available.cpp:444
unsigned int BOOL
Definition: ntddk_ex.h:94
LONG WINAPI CompareFileTime(IN CONST FILETIME *lpFileTime1, IN CONST FILETIME *lpFileTime2)
Definition: time.c:106
static AvailableStrings m_Strings
Definition: available.h:98
#define SORT_DEFAULT
#define MAX_PATH
Definition: compat.h:26
PCXSTR GetString() const
Definition: atlsimpstr.h:361
static VOID DeleteCurrentAppsDB()
Definition: available.cpp:263
BOOL GetStorageDirectory(ATL::CStringW &lpDirectory)
Definition: misc.cpp:187
BOOL WINAPI StrToIntExW(LPCWSTR lpszStr, DWORD dwFlags, LPINT lpiRet)
Definition: string.c:970
#define LANG_ENGLISH
Definition: nls.h:52
char szTmp[512]
static const WCHAR L[]
Definition: oid.c:1087
ATL::CStringW m_sFileName
Definition: available.h:42
BOOL Enum(INT EnumType, AVAILENUMPROC lpEnumProc)
Definition: available.cpp:323
ATL::CStringW m_szUrlDownload
Definition: available.h:37
ATL::CStringW m_szSHA1
Definition: available.h:46
LicenseType
Definition: available.h:10
static BOOL ForceUpdateAppsDB()
Definition: available.cpp:317
TCHAR szAppName[128]
Definition: solitaire.cpp:16
bool IsEmpty() const
Definition: atlsimpstr.h:379
VOID SetLastWriteTime(FILETIME *ftTime)
Definition: available.cpp:211
LPCWSTR szPath
Definition: env.c:35
static VOID DownloadApplicationsDB(LPCWSTR lpUrl)
Definition: loaddlg.cpp:956
BOOL GetString(const ATL::CStringW &KeyName, ATL::CStringW &ResultString)
Definition: misc.cpp:357
BOOL HasLanguageInfo() const
Definition: available.cpp:181
BOOL HasInstalledVersion() const
Definition: available.cpp:201
ATL::CStringW m_szUrlSite
Definition: available.h:36
ATL::CStringW m_szCDPath
Definition: available.h:38
CAvailableApplicationInfo(const ATL::CStringW &sFileNameParam)
Definition: available.cpp:21
BOOL FindInLanguages(LCID what) const
Definition: available.cpp:161
BOOL HasEnglishLanguage() const
Definition: available.cpp:191
ATL::CSimpleArray< LCID > m_LanguageLCIDs
Definition: available.h:39
#define MAKELANGID(p, s)
Definition: nls.h:15
const ATL::CStringW & GetCabPath() const
Definition: available.cpp:454
#define ERROR_ALREADY_EXISTS
Definition: disk.h:80
int Compare(_In_z_ PCXSTR psz) const
Definition: cstringt.h:605
ATL::CStringW m_szSize
Definition: available.h:35
BOOL GetString(LPCWSTR lpKeyName, ATL::CStringW &ReturnedString)
Definition: available.cpp:216
CConfigParser * m_Parser
Definition: available.h:68
GLuint64EXT * result
Definition: glext.h:11304
ATL::CStringW m_szInstalledVersion
Definition: available.h:47
HANDLE WINAPI FindFirstFileW(IN LPCWSTR lpFileName, OUT LPWIN32_FIND_DATAW lpFindFileData)
Definition: find.c:320
BOOL WINAPI FindClose(HANDLE hFindFile)
Definition: find.c:502