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)
13 // CAvailableApplicationInfo
14 CAvailableApplicationInfo::CAvailableApplicationInfo(const ATL::CStringW
& sFileNameParam
)
15 : m_Parser(sFileNameParam
)
17 LicenseType
= LICENSE_TYPE::None
;
18 sFileName
= sFileNameParam
;
20 RetrieveGeneralInfo();
23 VOID
CAvailableApplicationInfo::RefreshAppInfo()
25 if (szUrlDownload
.IsEmpty())
27 RetrieveGeneralInfo();
31 VOID
CAvailableApplicationInfo::RetrieveGeneralInfo()
33 Category
= m_Parser
.GetInt(L
"Category");
35 if (!GetString(L
"Name", szName
)
36 || !GetString(L
"URLDownload", szUrlDownload
))
41 GetString(L
"RegName", szRegName
);
42 GetString(L
"Version", szVersion
);
43 GetString(L
"License", szLicense
);
44 GetString(L
"Description", szDesc
);
45 GetString(L
"Size", szSize
);
46 GetString(L
"URLSite", szUrlSite
);
47 GetString(L
"CDPath", szCDPath
);
48 GetString(L
"Language", szRegName
);
49 GetString(L
"SHA1", szSHA1
);
51 RetrieveLicenseType();
53 RetrieveInstalledStatus();
56 RetrieveInstalledVersion();
60 VOID
CAvailableApplicationInfo::RetrieveInstalledStatus()
62 m_IsInstalled
= ::GetInstalledVersion(NULL
, szRegName
)
63 || ::GetInstalledVersion(NULL
, szName
);
66 VOID
CAvailableApplicationInfo::RetrieveInstalledVersion()
68 m_HasInstalledVersion
= ::GetInstalledVersion(&szInstalledVersion
, szRegName
)
69 || ::GetInstalledVersion(&szInstalledVersion
, szName
);
72 VOID
CAvailableApplicationInfo::RetrieveLanguages()
74 const WCHAR cDelimiter
= L
'|';
75 ATL::CStringW szBuffer
;
77 // TODO: Get multiline parameter
78 if (!m_Parser
.GetString(L
"Languages", szBuffer
))
80 m_HasLanguageInfo
= FALSE
;
84 // Parse parameter string
85 ATL::CStringW m_szLocale
;
87 for (INT i
= 0; szBuffer
[i
] != UNICODE_NULL
; ++i
)
89 if (szBuffer
[i
] != cDelimiter
&& szBuffer
[i
] != L
'\n')
91 m_szLocale
+= szBuffer
[i
];
95 if (StrToIntExW(m_szLocale
.GetString(), STIF_DEFAULT
, &iLCID
))
97 Languages
.Add(static_cast<LCID
>(iLCID
));
103 // For the text after delimiter
104 if (!m_szLocale
.IsEmpty())
106 if (StrToIntExW(m_szLocale
.GetString(), STIF_DEFAULT
, &iLCID
))
108 Languages
.Add(static_cast<LCID
>(iLCID
));
112 m_HasLanguageInfo
= TRUE
;
115 VOID
CAvailableApplicationInfo::RetrieveLicenseType()
117 INT IntBuffer
= m_Parser
.GetInt(L
"LicenseType");
119 if (IntBuffer
< 0 || IntBuffer
> LICENSE_TYPE::Max
)
121 LicenseType
= LICENSE_TYPE::None
;
125 LicenseType
= (LICENSE_TYPE
) IntBuffer
;
129 BOOL
CAvailableApplicationInfo::FindInLanguages(LCID what
) const
131 if (!m_HasLanguageInfo
)
136 //Find locale code in the list
137 const INT nLanguagesSize
= Languages
.GetSize();
138 for (INT i
= 0; i
< nLanguagesSize
; ++i
)
140 if (Languages
[i
] == what
)
149 BOOL
CAvailableApplicationInfo::HasLanguageInfo() const
151 return m_HasLanguageInfo
;
154 BOOL
CAvailableApplicationInfo::HasNativeLanguage() const
156 return FindInLanguages(GetUserDefaultLCID());
159 BOOL
CAvailableApplicationInfo::HasEnglishLanguage() const
161 return FindInLanguages(MAKELCID(MAKELANGID(LANG_ENGLISH
, SUBLANG_DEFAULT
), SORT_DEFAULT
));
164 BOOL
CAvailableApplicationInfo::IsInstalled() const
166 return m_IsInstalled
;
169 BOOL
CAvailableApplicationInfo::HasInstalledVersion() const
171 return m_HasInstalledVersion
;
174 BOOL
CAvailableApplicationInfo::HasUpdate() const
176 return (szInstalledVersion
.Compare(szVersion
) < 0) ? TRUE
: FALSE
;
179 VOID
CAvailableApplicationInfo::SetLastWriteTime(FILETIME
* ftTime
)
181 RtlCopyMemory(&ftCacheStamp
, ftTime
, sizeof(FILETIME
));
184 inline BOOL
CAvailableApplicationInfo::GetString(LPCWSTR lpKeyName
, ATL::CStringW
& ReturnedString
)
186 if (!m_Parser
.GetString(lpKeyName
, ReturnedString
))
188 ReturnedString
.Empty();
193 // CAvailableApplicationInfo
196 CAvailableApps::CAvailableApps()
199 if (GetStorageDirectory(m_szPath
))
201 m_szAppsPath
= m_szPath
+ L
"\\rapps\\";
202 m_szCabPath
= m_szPath
+ L
"\\rappmgr.cab";
203 m_szSearchPath
= m_szAppsPath
+ L
"*.txt";
207 VOID
CAvailableApps::FreeCachedEntries()
209 POSITION InfoListPosition
= m_InfoList
.GetHeadPosition();
211 /* loop and deallocate all the cached app infos in the list */
212 while (InfoListPosition
)
214 CAvailableApplicationInfo
* Info
= m_InfoList
.GetAt(InfoListPosition
);
215 m_InfoList
.RemoveHead();
218 InfoListPosition
= m_InfoList
.GetHeadPosition();
222 BOOL
CAvailableApps::DeleteCurrentAppsDB()
224 HANDLE hFind
= INVALID_HANDLE_VALUE
;
225 WIN32_FIND_DATAW FindFileData
;
228 if (m_szPath
.IsEmpty())
231 result
= result
&& DeleteFileW(m_szCabPath
.GetString());
232 hFind
= FindFirstFileW(m_szSearchPath
.GetString(), &FindFileData
);
234 if (hFind
== INVALID_HANDLE_VALUE
)
240 szTmp
= m_szPath
+ FindFileData
.cFileName
;
241 result
= result
&& DeleteFileW(szTmp
.GetString());
242 } while (FindNextFileW(hFind
, &FindFileData
) != 0);
249 BOOL
CAvailableApps::UpdateAppsDB()
251 if (!DeleteCurrentAppsDB())
254 Ñ
DownloadManager::DownloadApplicationsDB(APPLICATION_DATABASE_URL
);
256 if (m_szPath
.IsEmpty())
259 if (!ExtractFilesFromCab(m_szCabPath
, m_szAppsPath
))
267 BOOL
CAvailableApps::EnumAvailableApplications(INT EnumType
, AVAILENUMPROC lpEnumProc
)
269 HANDLE hFind
= INVALID_HANDLE_VALUE
;
270 WIN32_FIND_DATAW FindFileData
;
272 if (!CreateDirectoryW(m_szPath
.GetString(), NULL
) &&
273 GetLastError() != ERROR_ALREADY_EXISTS
)
278 hFind
= FindFirstFileW(m_szSearchPath
.GetString(), &FindFileData
);
280 if (hFind
== INVALID_HANDLE_VALUE
)
282 if (GetFileAttributesW(m_szCabPath
) == INVALID_FILE_ATTRIBUTES
)
283 Ñ
DownloadManager::DownloadApplicationsDB(APPLICATION_DATABASE_URL
);
285 ExtractFilesFromCab(m_szCabPath
, m_szAppsPath
);
286 hFind
= FindFirstFileW(m_szSearchPath
.GetString(), &FindFileData
);
288 if (hFind
== INVALID_HANDLE_VALUE
)
294 // loop for all the cached entries
295 POSITION CurrentListPosition
= m_InfoList
.GetHeadPosition();
296 CAvailableApplicationInfo
* Info
= NULL
;
298 while (CurrentListPosition
!= NULL
)
300 POSITION LastListPosition
= CurrentListPosition
;
301 Info
= m_InfoList
.GetNext(CurrentListPosition
);
303 // do we already have this entry in cache?
304 if (Info
->sFileName
== FindFileData
.cFileName
)
306 // is it current enough, or the file has been modified since our last time here?
307 if (CompareFileTime(&FindFileData
.ftLastWriteTime
, &Info
->ftCacheStamp
) == 1)
309 // recreate our cache, this is the slow path
310 m_InfoList
.RemoveAt(LastListPosition
);
318 // speedy path, compare directly, we already have the data
324 // create a new entry
325 Info
= new CAvailableApplicationInfo(FindFileData
.cFileName
);
327 // set a timestamp for the next time
328 Info
->SetLastWriteTime(&FindFileData
.ftLastWriteTime
);
329 m_InfoList
.AddTail(Info
);
332 if (Info
->Category
== FALSE
)
335 if (EnumType
!= Info
->Category
&& EnumType
!= ENUM_ALL_AVAILABLE
)
338 Info
->RefreshAppInfo();
340 if (!lpEnumProc(static_cast<PAPPLICATION_INFO
>(Info
), m_szAppsPath
.GetString()))
343 } while (FindNextFileW(hFind
, &FindFileData
) != 0);
349 const ATL::CStringW
& CAvailableApps::GetFolderPath()
354 const ATL::CStringW
& CAvailableApps::GetAppPath()
359 const ATL::CStringW
& CAvailableApps::GetCabPath()
364 const LPCWSTR
CAvailableApps::GetFolderPathString()
366 return m_szPath
.GetString();
369 const LPCWSTR
CAvailableApps::GetAppPathString()
371 return m_szPath
.GetString();
374 const LPCWSTR
CAvailableApps::GetCabPathString()
376 return m_szPath
.GetString();
381 ATL::CStringW
CConfigParser::m_szLocaleID
;
382 ATL::CStringW
CConfigParser::m_szCachedINISectionLocale
;
383 ATL::CStringW
CConfigParser::m_szCachedINISectionLocaleNeutral
;
385 CConfigParser::CConfigParser(const ATL::CStringW
& FileName
) : szConfigPath(GetINIFullPath(FileName
))
387 // we don't have cached section strings for the current system language, create them, lazy
388 CacheINILocaleLazy();
391 ATL::CStringW
CConfigParser::GetINIFullPath(const ATL::CStringW
& FileName
)
394 ATL::CStringW szBuffer
;
396 GetStorageDirectory(szDir
);
397 szBuffer
.Format(L
"%ls\\rapps\\%ls", szDir
, FileName
);
402 VOID
CConfigParser::CacheINILocaleLazy()
404 if (m_szLocaleID
.IsEmpty())
406 // TODO: Set default locale if call fails
407 // find out what is the current system lang code (e.g. "0a") and append it to SectionLocale
408 GetLocaleInfoW(GetUserDefaultLCID(), LOCALE_ILANGUAGE
,
409 m_szLocaleID
.GetBuffer(m_cchLocaleSize
), m_cchLocaleSize
);
411 m_szLocaleID
.ReleaseBuffer();
412 m_szCachedINISectionLocale
= L
"Section." + m_szLocaleID
;
414 // turn "Section.0c0a" into "Section.0a", keeping just the neutral lang part
415 m_szCachedINISectionLocaleNeutral
= m_szCachedINISectionLocale
+ m_szLocaleID
.Right(2);
419 const ATL::CStringW
& CConfigParser::GetLocale()
421 CacheINILocaleLazy();
425 INT
CConfigParser::GetLocaleSize()
427 return m_cchLocaleSize
;
430 UINT
CConfigParser::GetString(const ATL::CStringW
& KeyName
, ATL::CStringW
& ResultString
)
434 LPWSTR ResultStringBuffer
= ResultString
.GetBuffer(MAX_PATH
);
435 // 1st - find localized strings (e.g. "Section.0c0a")
436 dwResult
= GetPrivateProfileStringW(m_szCachedINISectionLocale
.GetString(),
441 szConfigPath
.GetString());
445 // 2nd - if they weren't present check for neutral sub-langs/ generic translations (e.g. "Section.0a")
446 dwResult
= GetPrivateProfileStringW(m_szCachedINISectionLocaleNeutral
.GetString(),
451 szConfigPath
.GetString());
454 // 3rd - if they weren't present fallback to standard english strings (just "Section")
455 dwResult
= GetPrivateProfileStringW(L
"Section",
460 szConfigPath
.GetString());
464 ResultString
.ReleaseBuffer();
465 return (dwResult
!= 0 ? TRUE
: FALSE
);
468 UINT
CConfigParser::GetInt(const ATL::CStringW
& KeyName
)
470 ATL::CStringW Buffer
;
472 // grab the text version of our entry
473 if (!GetString(KeyName
, Buffer
))
476 if (Buffer
.IsEmpty())
479 // convert it to an actual integer
480 int result
= StrToIntW(Buffer
.GetString());
482 return (UINT
) (result
<= 0) ? 0 : result
;