2 * PROJECT: ReactOS Applications Manager
3 * LICENSE: GPL - See COPYING in the top level directory
4 * FILE: base/applications/rapps/available.cpp
5 * PURPOSE: Classes for working with available applications
6 * PROGRAMMERS: Dmitry Chapyshev (dmitry@reactos.org)
7 * Ismael Ferreras Morezuelas (swyterzone+ros@gmail.com)
8 * Alexander Shaposhnikov (chaez.san@gmail.com)
12 #include "available.h"
17 #include <atlsimpcoll.h>
20 // CAvailableApplicationInfo
21 CAvailableApplicationInfo::CAvailableApplicationInfo(const ATL::CStringW
& sFileNameParam
)
22 : m_Parser(sFileNameParam
)
24 LicenseType
= LICENSE_TYPE::None
;
25 sFileName
= sFileNameParam
;
27 RetrieveGeneralInfo();
30 VOID
CAvailableApplicationInfo::RefreshAppInfo()
32 if (szUrlDownload
.IsEmpty())
34 RetrieveGeneralInfo();
38 // Lazily load general info from the file
39 VOID
CAvailableApplicationInfo::RetrieveGeneralInfo()
41 Category
= m_Parser
.GetInt(L
"Category");
43 if (!GetString(L
"Name", szName
)
44 || !GetString(L
"URLDownload", szUrlDownload
))
49 GetString(L
"RegName", szRegName
);
50 GetString(L
"Version", szVersion
);
51 GetString(L
"License", szLicense
);
52 GetString(L
"Description", szDesc
);
53 GetString(L
"Size", szSize
);
54 GetString(L
"URLSite", szUrlSite
);
55 GetString(L
"CDPath", szCDPath
);
56 GetString(L
"Language", szRegName
);
57 GetString(L
"SHA1", szSHA1
);
59 RetrieveLicenseType();
61 RetrieveInstalledStatus();
64 RetrieveInstalledVersion();
68 VOID
CAvailableApplicationInfo::RetrieveInstalledStatus()
70 m_IsInstalled
= ::GetInstalledVersion(NULL
, szRegName
)
71 || ::GetInstalledVersion(NULL
, szName
);
74 VOID
CAvailableApplicationInfo::RetrieveInstalledVersion()
76 m_HasInstalledVersion
= ::GetInstalledVersion(&szInstalledVersion
, szRegName
)
77 || ::GetInstalledVersion(&szInstalledVersion
, szName
);
80 VOID
CAvailableApplicationInfo::RetrieveLanguages()
82 const WCHAR cDelimiter
= L
'|';
83 ATL::CStringW szBuffer
;
85 // TODO: Get multiline parameter
86 if (!m_Parser
.GetString(L
"Languages", szBuffer
))
88 m_HasLanguageInfo
= FALSE
;
92 // Parse parameter string
93 ATL::CStringW m_szLocale
;
95 for (INT i
= 0; szBuffer
[i
] != UNICODE_NULL
; ++i
)
97 if (szBuffer
[i
] != cDelimiter
&& szBuffer
[i
] != L
'\n')
99 m_szLocale
+= szBuffer
[i
];
103 if (StrToIntExW(m_szLocale
.GetString(), STIF_DEFAULT
, &iLCID
))
105 Languages
.Add(static_cast<LCID
>(iLCID
));
111 // For the text after delimiter
112 if (!m_szLocale
.IsEmpty())
114 if (StrToIntExW(m_szLocale
.GetString(), STIF_DEFAULT
, &iLCID
))
116 Languages
.Add(static_cast<LCID
>(iLCID
));
120 m_HasLanguageInfo
= TRUE
;
123 VOID
CAvailableApplicationInfo::RetrieveLicenseType()
125 INT IntBuffer
= m_Parser
.GetInt(L
"LicenseType");
127 if (IntBuffer
< 0 || IntBuffer
> LICENSE_TYPE::Max
)
129 LicenseType
= LICENSE_TYPE::None
;
133 LicenseType
= (LICENSE_TYPE
) IntBuffer
;
137 BOOL
CAvailableApplicationInfo::FindInLanguages(LCID what
) const
139 if (!m_HasLanguageInfo
)
144 //Find locale code in the list
145 const INT nLanguagesSize
= Languages
.GetSize();
146 for (INT i
= 0; i
< nLanguagesSize
; ++i
)
148 if (Languages
[i
] == what
)
157 BOOL
CAvailableApplicationInfo::HasLanguageInfo() const
159 return m_HasLanguageInfo
;
162 BOOL
CAvailableApplicationInfo::HasNativeLanguage() const
164 return FindInLanguages(GetUserDefaultLCID());
167 BOOL
CAvailableApplicationInfo::HasEnglishLanguage() const
169 return FindInLanguages(MAKELCID(MAKELANGID(LANG_ENGLISH
, SUBLANG_DEFAULT
), SORT_DEFAULT
));
172 BOOL
CAvailableApplicationInfo::IsInstalled() const
174 return m_IsInstalled
;
177 BOOL
CAvailableApplicationInfo::HasInstalledVersion() const
179 return m_HasInstalledVersion
;
182 BOOL
CAvailableApplicationInfo::HasUpdate() const
184 return (szInstalledVersion
.Compare(szVersion
) < 0) ? TRUE
: FALSE
;
187 VOID
CAvailableApplicationInfo::SetLastWriteTime(FILETIME
* ftTime
)
189 RtlCopyMemory(&ftCacheStamp
, ftTime
, sizeof(FILETIME
));
192 inline BOOL
CAvailableApplicationInfo::GetString(LPCWSTR lpKeyName
, ATL::CStringW
& ReturnedString
)
194 if (!m_Parser
.GetString(lpKeyName
, ReturnedString
))
196 ReturnedString
.Empty();
201 // CAvailableApplicationInfo
204 ATL::CStringW
CAvailableApps::m_szPath
;
205 ATL::CStringW
CAvailableApps::m_szCabPath
;
206 ATL::CStringW
CAvailableApps::m_szAppsPath
;
207 ATL::CStringW
CAvailableApps::m_szSearchPath
;
209 BOOL
CAvailableApps::InitializeStaticStrings()
212 if (!m_szPath
.IsEmpty())
214 // strings are filled
218 //FIXME: maybe provide a fallback?
219 if (GetStorageDirectory(m_szPath
))
221 m_szAppsPath
= m_szPath
+ L
"\\rapps\\";
222 m_szCabPath
= m_szPath
+ L
"\\rappmgr.cab";
223 m_szSearchPath
= m_szAppsPath
+ L
"*.txt";
230 CAvailableApps::CAvailableApps()
233 InitializeStaticStrings();
236 VOID
CAvailableApps::FreeCachedEntries()
238 POSITION InfoListPosition
= m_InfoList
.GetHeadPosition();
240 /* loop and deallocate all the cached app infos in the list */
241 while (InfoListPosition
)
243 CAvailableApplicationInfo
* Info
= m_InfoList
.GetNext(InfoListPosition
);
247 m_InfoList
.RemoveAll();
250 VOID
CAvailableApps::DeleteCurrentAppsDB()
252 HANDLE hFind
= INVALID_HANDLE_VALUE
;
253 WIN32_FIND_DATAW FindFileData
;
255 if (!InitializeStaticStrings())
260 hFind
= FindFirstFileW(m_szSearchPath
.GetString(), &FindFileData
);
262 if (hFind
!= INVALID_HANDLE_VALUE
)
267 szTmp
= m_szAppsPath
+ FindFileData
.cFileName
;
268 DeleteFileW(szTmp
.GetString());
269 } while (FindNextFileW(hFind
, &FindFileData
) != 0);
273 RemoveDirectoryW(m_szAppsPath
);
274 RemoveDirectoryW(m_szPath
);
277 BOOL
CAvailableApps::UpdateAppsDB()
279 HANDLE hFind
= INVALID_HANDLE_VALUE
;
280 WIN32_FIND_DATAW FindFileData
;
282 if (!InitializeStaticStrings())
287 if (!CreateDirectoryW(m_szPath
.GetString(), NULL
) && GetLastError() != ERROR_ALREADY_EXISTS
)
292 //if there are some files in the db folder - we're good
293 hFind
= FindFirstFileW(m_szSearchPath
.GetString(), &FindFileData
);
294 if (hFind
!= INVALID_HANDLE_VALUE
)
299 CDownloadManager::DownloadApplicationsDB(APPLICATION_DATABASE_URL
);
301 if (!ExtractFilesFromCab(m_szCabPath
, m_szAppsPath
))
306 DeleteFileW(m_szCabPath
.GetString());
311 BOOL
CAvailableApps::ForceUpdateAppsDB()
313 DeleteCurrentAppsDB();
314 return UpdateAppsDB();
317 BOOL
CAvailableApps::EnumAvailableApplications(INT EnumType
, AVAILENUMPROC lpEnumProc
)
320 HANDLE hFind
= INVALID_HANDLE_VALUE
;
321 WIN32_FIND_DATAW FindFileData
;
323 hFind
= FindFirstFileW(m_szSearchPath
.GetString(), &FindFileData
);
325 if (hFind
== INVALID_HANDLE_VALUE
)
333 // loop for all the cached entries
334 POSITION CurrentListPosition
= m_InfoList
.GetHeadPosition();
335 CAvailableApplicationInfo
* Info
= NULL
;
337 while (CurrentListPosition
!= NULL
)
339 POSITION LastListPosition
= CurrentListPosition
;
340 Info
= m_InfoList
.GetNext(CurrentListPosition
);
342 // do we already have this entry in cache?
343 if (Info
->sFileName
== FindFileData
.cFileName
)
345 // is it current enough, or the file has been modified since our last time here?
346 if (CompareFileTime(&FindFileData
.ftLastWriteTime
, &Info
->ftCacheStamp
) == 1)
348 // recreate our cache, this is the slow path
349 m_InfoList
.RemoveAt(LastListPosition
);
357 // speedy path, compare directly, we already have the data
363 // create a new entry
364 Info
= new CAvailableApplicationInfo(FindFileData
.cFileName
);
366 // set a timestamp for the next time
367 Info
->SetLastWriteTime(&FindFileData
.ftLastWriteTime
);
368 m_InfoList
.AddTail(Info
);
371 if (Info
->Category
== FALSE
)
374 if (EnumType
!= Info
->Category
&& EnumType
!= ENUM_ALL_AVAILABLE
)
377 Info
->RefreshAppInfo();
380 lpEnumProc(static_cast<PAPPLICATION_INFO
>(Info
), m_szAppsPath
.GetString());
382 } while (FindNextFileW(hFind
, &FindFileData
) != 0);
388 const PAPPLICATION_INFO
CAvailableApps::FindInfo(const ATL::CStringW
& szAppName
)
390 if (m_InfoList
.IsEmpty())
396 POSITION CurrentListPosition
= m_InfoList
.GetHeadPosition();
397 PAPPLICATION_INFO info
;
398 while (CurrentListPosition
!= NULL
)
400 info
= m_InfoList
.GetNext(CurrentListPosition
);
401 if (info
->szName
== szAppName
)
409 ATL::CSimpleArray
<PAPPLICATION_INFO
> CAvailableApps::FindInfoList(const ATL::CSimpleArray
<ATL::CStringW
> &arrAppsNames
)
411 ATL::CSimpleArray
<PAPPLICATION_INFO
> result
;
412 for (INT i
= 0; i
< arrAppsNames
.GetSize(); ++i
)
414 PAPPLICATION_INFO Info
= FindInfo(arrAppsNames
[i
]);
423 const ATL::CStringW
& CAvailableApps::GetFolderPath()
428 const ATL::CStringW
& CAvailableApps::GetAppPath()
433 const ATL::CStringW
& CAvailableApps::GetCabPath()
438 const LPCWSTR
CAvailableApps::GetFolderPathString()
440 return m_szPath
.GetString();
443 const LPCWSTR
CAvailableApps::GetAppPathString()
445 return m_szPath
.GetString();
448 const LPCWSTR
CAvailableApps::GetCabPathString()
450 return m_szPath
.GetString();